/* Operian OS — SEITEN auf iPhone und iPad: Leiste, Pille, App-Übersicht
 * ============================================================================
 *
 * Vorgabe Betreiber (2026-09-30, Screenshots iOS-Homescreen + App-Umschalter):
 * VILO blättert auf App-Shell-Geräten (Klasse `compact` und `medium`) wie iOS.
 *
 *   Seite 1        die BÜHNE: Widgets, Dock, darüber die Pille („Suchen",
 *                  beim Wischen die Seiten-Punkte)
 *   Seite 2 …      jede offene App, in der Reihenfolge des Öffnens
 *   unten in Apps  die LEISTE (schwebendes Flüssigglas): Home · Punkte · Fenster-Symbol;
 *                  seitlich wischen = Seite wechseln, hochwischen = Bühne (schnell)
 *                  oder Übersicht (halten)
 *   Übersicht      alle offenen Apps als Karten — die Karten SIND die Fenster,
 *                  ihre iframes leben weiter
 *
 * Logik, Gesten, Zustand: assets/kernel.js, Block „Seiten". Fenstergeometrie
 * (Karten, Einfrieren, z-Klammer, Titelleiste): app-shell-geometry.css — dort
 * bleibt der eine Eigentümer. HIER steht die Präsentation dessen, was der Kernel
 * selbst anlegt, drei Regeln, die vorher nur das Telefon HOCHKANT kannte, und eine
 * gegen Chromiums Zurück-Geste.
 *
 * Desktop (`wide`, kein data-vilo-appshell) sieht keine einzige Regel dieser
 * Datei; der Kernel legt dort nichts an. Keine Schatten (Stilregel).
 * ==========================================================================*/


/* ── 1 · Drei Regeln, die für ALLE App-Shell-Geräte gelten ────────────────────
 * Bis hierher lagen sie in mobile-shell.css unter `@media (max-width: 600px)` —
 * also nur für das Telefon im HOCHFORMAT. Mit den Seiten gelten sie für das
 * Telefon quer und für das iPad genauso; zwei Kopien je Gerät wären zwei
 * Besitzer für dieselbe Aussage. */

/* (a) Der Dock steht über dem Home-Indicator — derselbe Bodenabstand, mit dem
       `--vilo-dock-reserve` (app-shell-geometry.css) rechnet. Die Pille sitzt über
       dieser Reserve; stünde der Dock anders, läge sie auf ihm. */
html[data-vilo-appshell] div[class*="bottom-4"][class*="justify-center"] {
  bottom: max(16px, calc(env(safe-area-inset-bottom) + 8px)) !important;
}

/* (b) In einer App gibt es keinen Dock — an seiner Stelle steht die Leiste. Neu auf
       dem iPad (Vorgabe: iPad wie iPhone) und auf dem Telefon quer, wo er sonst über
       der Leiste läge. `visibility` mit Verzögerung, damit VoiceOver den unsichtbaren
       Dock nicht mehr ansteuert. !important schlägt den Framer-Inline-Transform. */
html[data-vilo-appshell="app"] div[class*="bottom-4"][class*="justify-center"] {
  opacity: 0 !important;
  transform: translateY(140%) !important;
  pointer-events: none !important;
  visibility: hidden;
  transition: transform .24s ease, opacity .24s ease, visibility 0s linear .24s;
}

/* (c) Eine Seite hat keine Ränder zum Ziehen. Die Griffe des Bundles (8 px, direkte
       Kinder der Fensterwurzel) schluckten auf dem iPad an allen Kanten Berührungen,
       ohne dass sich etwas bewegen konnte — die Geometrie gehört der Shell. */
html[data-vilo-appshell] .window-shadow > div[class*="cursor-ns-resize"],
html[data-vilo-appshell] .window-shadow > div[class*="cursor-ew-resize"],
html[data-vilo-appshell] .window-shadow > div[class*="cursor-nwse-resize"],
html[data-vilo-appshell] .window-shadow > div[class*="cursor-nesw-resize"] {
  display: none !important;
  pointer-events: none !important;
}

/* (d) Seitlich gehört die Seite dem Kernel — auch IN einer App. Seit der App-Inhalt
       wischt (Block „Seiten", blRahmenTouch), läuft ein waagerechter Wisch in einem
       Dokument, das seitlich nichts zu rollen hat, als Überrollen durch bis zur
       Shell; Chromium machte daraus seine Zurück-Navigation (gemessen: die Shell
       verliess sich selbst, mitten im Seitenwechsel). Dieselbe Regel wie auf den
       Schreibtischen des Desktops (schreibtische.css). */
html[data-vilo-appshell],
html[data-vilo-appshell] body {
  overscroll-behavior-x: none;
}

/* Auf der Bühne steht kein App-Name in der Topleiste. Ein vom Kernel verborgenes
   Fenster bleibt für React „aktiv" (menubar-desktop.css nennt die Grenze), sein Name
   stünde sonst über den Widgets — auf der Bühne ist aber keine App vorne. */
html[data-vilo-appshell="launcher"] div[class*="z-[9999]"] > div:first-child > span.text-white\/80.text-xs.font-semibold.px-2 {
  display: none;
}


/* ── 2 · Wo ein Finger wischen darf ────────────────────────────────────────────
 * Senkrecht rollt der Browser (die Widget-Liste des Telefons), waagerecht gehört
 * die Bewegung dem Kernel — die Achse entscheidet der Browser selbst. Über den
 * Widget-Karten sagt es `.vilo-dw{touch-action:pan-y}` aus dwCss (kernel.js). */
html[data-vilo-appshell] .desktop-bg-click {
  touch-action: pan-y;
}
html[data-vilo-class="compact"] .vilo-dw-layer {
  touch-action: pan-y;
}
/* Das Dock der Bühne ist eine Wisch-Fläche wie die Pille (kernel.js, Block „Seiten"):
 * hochziehen öffnet die Übersicht, seitlich blättert es. Nimmt der Browser den Zug als
 * Bildlauf, meldet er `pointercancel`, und die Geste wäre weg — also keiner. Ein Tipp bleibt
 * ein Tipp, der lange Druck des Dock-Bearbeitens ebenso. */
html[data-vilo-appshell="launcher"] .glass-dock.rounded-3xl {
  touch-action: none;
}


/* ── 3 · Die Bühne gleitet ─────────────────────────────────────────────────────
 * Während einer Fahrt (`data-vilo-bl-buehne` am <html>) ist die Bühne im Bild,
 * auch wenn der Modus schon „app" sagt: die Widget-Ebene wäre sonst verborgen
 * (dwCss) und der Dock ausgeblendet ((b) oben). Der Kernel bewegt sie über
 * `translate` — die Einzel-Eigenschaft, damit der Transform der Ebene (Mitte und
 * Faktor auf dem Telefon) unberührt bleibt. */
html[data-vilo-appshell][data-vilo-bl-buehne] .vilo-dw-layer {
  visibility: visible !important;
  translate: var(--vilo-bl-versatz, 0px) 0;
}
html[data-vilo-appshell][data-vilo-bl-buehne="seite"] div[class*="bottom-4"][class*="justify-center"] {
  visibility: visible !important;
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  pointer-events: none !important;
  translate: var(--vilo-bl-versatz, 0px) 0;
}
/* Die Pille gehört zur Bühne und gleitet mit ihr — sonst blendete sie am alten Platz aus,
   während Widgets und Dock schon zur Seite fahren. */
html[data-vilo-appshell][data-vilo-bl-buehne="seite"]:not([data-vilo-dw]):not([data-vilo-dock-edit]) .vilo-bl-pille {
  opacity: 1;
  visibility: visible;
  pointer-events: none;
  transition: none;
  translate: var(--vilo-bl-versatz, 0px) 0;
}
/* Einen Frame lang nach einer Fahrt: der Dock springt auf seinen Ruhezustand, statt
   seine Ausblendung sichtbar an der alten Stelle nachzuspielen. */
html[data-vilo-bl-still] div[class*="bottom-4"][class*="justify-center"],
html[data-vilo-bl-still] .vilo-bl-pille {
  transition: none !important;
}


/* ── 4 · Die Leiste (in Apps): schwebendes Flüssigglas, drei Elemente ──────────
 * Vorgabe Betreiber (2026-10-13, Vorbild die Leiste unten in Safari): „anstatt dieser
 * drei Punkte … den Fenster-Icon in die Größe packen, die Punkte größer darstellen,
 * statt + direkt zum Home-Bildschirm mit den KPI-Widgets. Aktuell ist das sehr klein
 * und umständlich — man nutzt immer die Apple-Home-Funktion, und im Browser-Modus
 * kann man nicht richtig swipen (Raumplan: dort ist es schwierig, zurückzuswipen)."
 *
 *   links    rund, 48 px   Startbildschirm — Seite 1, die Bühne mit den Widgets (EIN Tipp,
 *                          statt zurückzuwischen: im Raumplan nimmt die Karte den Finger)
 *   Mitte    Pille, 48 px  die Seiten als Punkte, 10 px statt 6; die aktive eine Kapsel.
 *                          Jeder Punkt IST ein Knopf; wischen darüber blättert weiter
 *   rechts   rund, 48 px   „Geöffnete Apps" (das Fenster-Symbol, in der Grösse des Knopfs)
 *
 * DAS GLAS IST DAS DER WIDGETS UND DER TAB-LEISTE (`_fluessigglas.js`, `_fluent.css` 30h),
 * nicht ein drittes: Weichzeichner 18 px · Sättigung 1.9 · Helligkeit 1.08, darüber der helle
 * Verlauf (16 → 6 → 3 → 8 % Weiß), die Nacht (Nachtblau 28 → 38 %) und die Lichtkante als
 * 1-px-Ring. Die Nacht ist hier wie dort die Lesbarkeit: gegen das hellste Zehntel des
 * Farbbands hält ein weisses Symbol an der hellsten Stelle 5.1:1, ohne sie 3.4:1.
 *
 * DIE LEISTE HAT KEINEN GRUND MEHR. Sie war eine deckende Platte in der Farbe des Fensters
 * (hell tagsüber, dunkel abends) und setzte es nach unten fort; jetzt stehen drei Flächen auf
 * der Bühne, wo das Fenster endet. Das Glas hängt deshalb NICHT am Erscheinungsbild: wie
 * die Pille über dem Dock gehört es zur Bühne, und die ist in beiden Modi dunkel.
 *
 * Die Höhe bleibt Reserve der Fenster (`--vilo-leiste`, app-shell-geometry.css): 48 px
 * Knopf plus je 8 px Luft. Eine Leiste, die den Inhalt überdeckte, wäre der Fehler, den die
 * Bodenreserve schon einmal behoben hat. Bedienbar ist die ganze Zeile (Wischen), gezeichnet
 * sind drei Flächen; die Safe-Area unter ihr gehört dem System. */
.vilo-bl-leiste {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9989;
  height: calc(var(--vilo-leiste, 64px) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  box-sizing: border-box;
  background: transparent;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, visibility 0s linear .2s;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
}
html[data-vilo-appshell="app"]:not([data-vilo-bl-wechsler]) .vilo-bl-leiste {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .2s ease, visibility 0s linear 0s;
}
html:not([data-vilo-appshell]) .vilo-bl-leiste {
  display: none;
}
/* Ein App-Blatt liegt über allem (kernel.js, Block „Blatt"): die Leiste tritt ab, solange
   es offen ist. Gleich spezifisch wie die Zeige-Regel darüber und später — gewinnt. */
html[data-vilo-appshell="app"][data-vilo-blatt] .vilo-bl-leiste {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.vilo-bl-flaeche {
  position: relative;
  height: var(--vilo-leiste, 64px);
  box-sizing: border-box;
  padding: 0 max(16px, env(safe-area-inset-right, 0px)) 0 max(16px, env(safe-area-inset-left, 0px));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
/* Das Material: eine Regel für alle drei Flächen. Ohne `backdrop-filter` bleibt die deckende
   Platte (fail-closed) — ein durchsichtiger Grund ohne Weichzeichner stünde ungefiltert auf
   einem beliebigen Bild. Die inneren Lichtkanten sind Licht, keine Elevation (Stilregel). */
.vilo-bl-home,
.vilo-bl-punkte,
.vilo-bl-uebersicht {
  position: relative;
  box-sizing: border-box;
  height: 48px;
  margin: 0;
  padding: 0;
  border: 0;
  background: #1a1c2e;
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .15s ease;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .vilo-bl-home,
  .vilo-bl-punkte,
  .vilo-bl-uebersicht {
    /* Von oben nach unten: die Nacht, dann der helle Verlauf. */
    background:
      linear-gradient(180deg, rgba(10, 30, 90, .28), rgba(10, 30, 90, .38)),
      linear-gradient(160deg, rgba(255, 255, 255, .16) 0%, rgba(255, 255, 255, .06) 40%,
                              rgba(255, 255, 255, .03) 70%, rgba(255, 255, 255, .08) 100%);
    box-shadow: inset 0 1.5px 1px rgba(255, 255, 255, .55), inset 0 -1px 1px rgba(255, 255, 255, .18),
                inset 0 0 0 .5px rgba(255, 255, 255, .18), inset 0 0 16px rgba(255, 255, 255, .07);
    -webkit-backdrop-filter: blur(18px) saturate(1.9) brightness(1.08);
    backdrop-filter: blur(18px) saturate(1.9) brightness(1.08);
  }
}
/* Die Lichtkante: ein Ring aus einem Verlauf (hell oben links, hell unten rechts, dazwischen
   fast nichts), über die Maske ausgestanzt. Der Weichzeichner macht jede Fläche zu einem
   eigenen Stapel — `z-index: -1` hält den Ring über ihrem Grund und unter ihrem Inhalt. */
.vilo-bl-home::before,
.vilo-bl-punkte::before,
.vilo-bl-uebersicht::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(140deg, rgba(255, 255, 255, .85) 0%, rgba(255, 255, 255, .18) 22%,
                              rgba(255, 255, 255, .02) 50%, rgba(255, 255, 255, .12) 75%,
                              rgba(255, 255, 255, .6) 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  pointer-events: none;
}
.vilo-bl-home,
.vilo-bl-uebersicht {
  flex: none;
  width: 48px;
  border-radius: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.vilo-bl-home:active,
.vilo-bl-uebersicht:active {
  transform: scale(.94);
}
.vilo-bl-home svg,
.vilo-bl-uebersicht svg {
  width: 24px;
  height: 24px;
  display: block;
  /* Der Textschatten der Widgets, auf das Symbol übertragen — Licht, keine Elevation. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 40, .25));
}
/* Die Seiten als Punkte: 28×48 je Punkt unter dem Finger (WCAG 2.5.8: 24 px), gezeichnet sind
   10 px, der aktive als Kapsel. Jeder Punkt IST ein Knopf — auch der inaktive braucht 3:1
   (WCAG 1.4.11), gerechnet gegen die hellste Stelle des Glases (app-seiten-wechsler.test.js). */
.vilo-bl-punkte {
  flex: 0 1 auto;
  min-width: 132px;
  max-width: 100%;
  border-radius: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  cursor: default;
}
.vilo-bl-punkt {
  flex: none;
  width: 28px;
  height: 48px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Ab acht Seiten rücken die Punkte zusammen, statt die Pille über ihre Nachbarn zu schieben. */
.vilo-bl-punkte[data-viele] {
  min-width: 0;
  padding: 0 4px;
}
.vilo-bl-punkte[data-viele] .vilo-bl-punkt {
  width: 20px;
}
.vilo-bl-punkt::before {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .7);
  transition: width .2s ease, background-color .2s ease;
}
.vilo-bl-punkt[aria-current="page"]::before {
  width: 28px;
  background: #fff;
}
.vilo-bl-punkte[data-viele] .vilo-bl-punkt[aria-current="page"]::before {
  width: 20px;
}
.vilo-bl-home:focus-visible,
.vilo-bl-punkt:focus-visible,
.vilo-bl-uebersicht:focus-visible {
  outline: 2px solid #8b5cf6;
  outline-offset: 2px;
  border-radius: 24px;
}
@media (hover: hover) {
  .vilo-bl-home:hover,
  .vilo-bl-uebersicht:hover {
    transform: scale(1.04);
  }
}
/* Die Uhr (Wear OS, 225 px, RUND): drei Flächen von 48 px passen nicht in den Kreis, und die
   Höhe wäre die halbe Fläche der App. Dort bleibt die frühere schlichte Leiste aus 32 px
   (`--vilo-leiste` springt in app-shell-geometry.css mit): Home, Punkte und Fenster-Symbol als
   eine Gruppe in der Mitte, wo ein runder Schirm am breitesten ist, ohne Glas. Entschieden an
   der gemessenen Breite, nie am Gerät: unter 300 px ist jede Fläche eine Uhr. */
@media (max-width: 300px) {
  .vilo-bl-flaeche {
    padding: 0;
    gap: 0;
    justify-content: center;
  }
  .vilo-bl-home,
  .vilo-bl-punkte,
  .vilo-bl-uebersicht {
    height: 32px;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .vilo-bl-home::before,
  .vilo-bl-punkte::before,
  .vilo-bl-uebersicht::before {
    display: none;
  }
  .vilo-bl-home,
  .vilo-bl-uebersicht {
    width: 32px;
  }
  .vilo-bl-punkte {
    min-width: 0;
    padding: 0;
  }
  .vilo-bl-punkt {
    width: 24px;
    height: 32px;
  }
  .vilo-bl-home svg,
  .vilo-bl-uebersicht svg {
    width: 20px;
    height: 20px;
  }
}
.vilo-bl-ansage {
  position: fixed;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}


/* ── 5 · Die Pille (auf der Bühne) ─────────────────────────────────────────────
 * Über dem Dock, mittig in der Bühne (Kind von `.desktop-bg.relative`, damit sie
 * mittig bleibt, wenn die Assistenten-Bahn die Bühne schmälert). In Ruhe „Suchen",
 * beim Wischen der Bühne die Seiten-Punkte.
 *
 * MATERIAL UND GRÖSSE SIND DIE DES DOCKS, NICHT DIE DER SUCHE (Vorgabe Betreiber,
 * 2026-10-02, Vergleich mit dem iPhone: „ein zu starker Bruch — kleiner und im selben
 * Hell wie die Bar"). Hier stand die dunkle Glaszeile der Suche (`brightness(0.14)`):
 * eine schwarze Pille direkt über einer hellen Glas-Pille, zwei Materialien für EINE
 * Fläche. Jetzt trägt sie den Grund des Docks (dock-glass.css: 12 % Weiß, Kante .14 —
 * ohne dessen inneres Licht, diese Datei setzt keinen Schatten) über dem Filter des Bundles für `.glass-dock` (blur 50 · saturate
 * 200 %), 28 px hoch, 13 px Schrift in vollem Weiß. Gemessen auf dem Farbband
 * (390×844, Chromium): hellster Pixel des Glases rgb(40,107,218), Weiß darauf 4.99:1
 * — mit 92 % Weiß wären es 4.49:1 gewesen, also knapp unter AA. Der Preis ist benannt
 * und derselbe wie am iPhone: über einem hellen eigenen Bild ist das Wort leise. Ein Hauch Textschatten hält es
 * lesbar (Licht und Schrift, keine Elevation — dieselbe Abwägung wie bei den Widgets).
 * Ohne `backdrop-filter` bleibt die deckende Platte. */
.vilo-bl-pille {
  position: absolute;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: max-content;
  bottom: calc(var(--vilo-dock-reserve, 112px) + 4px);
  height: 28px;
  box-sizing: border-box;
  padding: 0 12px;
  border-radius: 14px;
  z-index: 9989;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, .14);
  background: #1a1c22;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .28);
  font: 600 13px/1 -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  cursor: pointer;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .vilo-bl-pille {
    background: rgba(255, 255, 255, .12);
    -webkit-backdrop-filter: blur(50px) saturate(200%);
    backdrop-filter: blur(50px) saturate(200%);
  }
}
html[data-vilo-appshell="launcher"]:not([data-vilo-bl-wechsler]):not([data-vilo-dw]):not([data-vilo-dock-edit]) .vilo-bl-pille {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .2s ease, visibility 0s linear 0s;
}
html:not([data-vilo-appshell]) .vilo-bl-pille {
  display: none;
}
/* 28 px gezeichnet, 44 px unter dem Finger. */
.vilo-bl-pille::after {
  content: "";
  position: absolute;
  inset: -8px -4px;
}
.vilo-bl-pille:focus-visible {
  outline: 2px solid #8b5cf6;
  outline-offset: 2px;
}
.vilo-bl-suche {
  display: flex;
  align-items: center;
  gap: 5px;
}
.vilo-bl-suche svg {
  width: 12px;
  height: 12px;
  display: block;
}
.vilo-bl-pdots {
  display: none;
  align-items: center;
  gap: 8px;
}
html[data-vilo-bl-pille="punkte"] .vilo-bl-suche {
  display: none;
}
html[data-vilo-bl-pille="punkte"] .vilo-bl-pdots {
  display: flex;
}
.vilo-bl-pdots > i {
  display: block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .4);
}
.vilo-bl-pdots > i[data-aktiv] {
  background: #fff;
}


/* ── 6 · Die App-Übersicht ─────────────────────────────────────────────────────
 * HINTER den Karten (z 5, in der Bühne): ein abgedunkelter, weichgezeichneter Grund.
 * VOR den Karten (z 9993, in <body>): je Karte ein Platz mit Symbol und Name darüber
 * (ein Tipp darauf öffnet wie ein Tipp auf die Karte), dem Knopf „… öffnen" auf der
 * Karte und „… schließen" (nur bei Fokus sichtbar — der Weg für Tastatur und
 * VoiceOver; mit dem Finger schliesst Hochwischen).
 * Plätze und Karten rechnen mit DENSELBEN Variablen (app-shell-geometry.css). */
.vilo-bl-grund {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(8, 8, 12, .72);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .25s ease, visibility 0s linear .25s;
}
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .vilo-bl-grund {
    background: rgba(8, 8, 12, .5);
    -webkit-backdrop-filter: blur(24px) saturate(160%) brightness(.6);
    backdrop-filter: blur(24px) saturate(160%) brightness(.6);
  }
}
html[data-vilo-bl-grund] .vilo-bl-grund {
  opacity: 1;
  visibility: visible;
  transition: opacity .25s ease, visibility 0s linear 0s;
}
html[data-vilo-bl-zieht] .vilo-bl-grund {
  transition: none;
}
.vilo-bl-wechsler {
  position: fixed;
  inset: 0;
  z-index: 9993;
  display: none;
  overflow: hidden;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
html[data-vilo-bl-wechsler] .vilo-bl-wechsler {
  display: block;
}
.vilo-bl-platz {
  position: absolute;
  left: calc((var(--vilo-bl-vw) - var(--vilo-bl-kb)) / 2);
  top: var(--vilo-bl-ky);
  width: var(--vilo-bl-kb);
  height: var(--vilo-bl-kh);
  translate: calc(var(--vilo-bl-i, 0) * var(--vilo-bl-schritt) - var(--vilo-bl-x, 0px) + var(--vilo-bl-dx, 0px)) var(--vilo-bl-dy, 0px);
  transition: translate .3s cubic-bezier(.32, .72, 0, 1), opacity .2s ease;
}
/* Eine maximierte Seite (Raumplan) behält auch als Karte ihre Vollbild-Oberkante — der Platz
   davor rechnet dann mit DERSELBEN Kante, sonst läge er 22 px neben seiner Karte. Die Werte
   müssen am Platz selbst neu stehen: eine Variable mit var() darin wird dort aufgelöst, wo sie
   steht (am <html>), nicht dort, wo sie gelesen wird. */
.vilo-bl-platz[data-voll] {
  --vilo-bl-fh: calc(var(--vilo-bl-vh) - var(--vilo-topbar-voll) - var(--vilo-bottom-reserve));
  --vilo-bl-kh: calc(var(--vilo-bl-s) * var(--vilo-bl-fh));
  --vilo-bl-ky: calc(var(--vilo-topbar-voll) + var(--vilo-bl-fh) * (1 - var(--vilo-bl-s)) / 2);
}
html[data-vilo-bl-zieht] .vilo-bl-platz,
.vilo-bl-platz[data-vilo-bl-sofort] {
  transition: none;
}
/* Hochgewischt: der Platz fliegt mit seiner Karte (app-shell-geometry.css, dieselbe Formel). */
.vilo-bl-platz[data-vilo-bl-weg] {
  translate: calc(var(--vilo-bl-i, 0) * var(--vilo-bl-schritt) - var(--vilo-bl-x, 0px) + var(--vilo-bl-dx, 0px)) calc(-1 * var(--vilo-bl-vh));
  opacity: 0;
  pointer-events: none;
  transition: translate .3s cubic-bezier(.32, .72, 0, 1), opacity .25s ease;
}
html[data-vilo-bl-wechsler="zu"] .vilo-bl-platz {
  opacity: 0;
}
.vilo-bl-kartenknopf {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: transparent;
  cursor: pointer;
}
.vilo-bl-kartenknopf:focus-visible {
  outline: 3px solid #8b5cf6;
  outline-offset: 3px;
}
.vilo-bl-kopf {
  position: absolute;
  left: 0;
  right: 48px;
  bottom: calc(100% + 10px);
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
}
.vilo-bl-kopf > .vilo-bl-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vilo-bl-zu {
  position: absolute;
  right: 0;
  bottom: calc(100% + 1px);
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 22px;
  background: transparent;
  color: #fff;
  font: 400 26px/1 -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
}
.vilo-bl-zu svg {
  width: 18px;
  height: 18px;
  display: block;
  margin: 0 auto;
}
/* Unsichtbar UND nicht treffbar, solange er keinen Fokus hat: sonst fing ein Tipp neben der
   Karte („zurück zur Bühne") einen Knopf ab, den niemand sieht, und schloss eine App. Mit Fokus
   (Tabulator, VoiceOver) ist er da und bedienbar. */
.vilo-bl-zu:focus {
  pointer-events: auto;
}
.vilo-bl-zu:focus-visible {
  opacity: 1;
  outline: 2px solid #8b5cf6;
  outline-offset: -2px;
}
.vilo-bl-leer {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, .8);
  font-size: 15px;
  font-weight: 600;
  pointer-events: none;
}
.vilo-bl-wechsler[data-leer] .vilo-bl-leer {
  display: flex;
}

/* Solange die Übersicht offen ist, gehört der Schirm ihr: Topleiste, Dock, Pille und
   Leiste treten ab (Pille/Leiste über ihre eigenen Regeln oben). */
html[data-vilo-bl-wechsler] div[class*="z-[9999]"].glass-dock {
  visibility: hidden !important;
}
html[data-vilo-bl-wechsler] div[class*="bottom-4"][class*="justify-center"] {
  visibility: hidden !important;
  opacity: 0 !important;
  pointer-events: none !important;
}


/* ── 7 · Weniger Bewegung ──────────────────────────────────────────────────────
 * Der Kernel fährt dann gar nicht erst (Endzustand sofort); die Übergänge der
 * Übersicht entfallen hier. Das Fingerfolgen bleibt — es ist direkte Bedienung. */
@media (prefers-reduced-motion: reduce) {
  .vilo-bl-leiste,
  .vilo-bl-pille,
  .vilo-bl-grund,
  .vilo-bl-platz,
  .vilo-bl-home,
  .vilo-bl-punkte,
  .vilo-bl-uebersicht,
  .vilo-bl-punkt::before {
    transition: none !important;
  }
}


/* ── 8 · Der weiche Rand unter der Widget-Liste (Telefon) ──────────────────────
 * Vorgabe Betreiber (2026-10-02, Vergleich mit dem iPhone): die Karte, die unten
 * an die Kante der Rollfläche stößt, soll „mit einem Verlauf verschwinden" statt
 * hart abgeschnitten zu werden.
 *
 * DIE NAHELIEGENDE ANTWORT BRICHT DAS GLAS, UND DAS IST GEMESSEN. Eine Maske auf
 * `.vilo-dw-layer` macht die Ebene zur „Backdrop Root" (Filter Effects 2): der
 * Weichzeichner jeder Glaskarte darin liest danach nur noch die Ebene, also nichts —
 * in Chromium stand das Farbband scharf hinter den Kennzahlen. Dasselbe gilt für
 * `opacity` und `clip-path` an der Ebene oder an einer Kachel.
 *
 * Gebaut ist deshalb der Rand-Effekt des iPhones: ein Streifen ÜBER der Unterkante,
 * der selbst weichzeichnet und seine Stärke über eine eigene Maske nach unten
 * aufbaut. Die eigene Maske ist erlaubt — sie gehört dem Element mit dem Filter,
 * nicht einem Vorfahren der Karten. Die Karte löst sich darin auf, und ihre harte
 * Kante liegt im stärksten Teil des Weichzeichners. Er reicht 24 px unter die Kante,
 * sonst schnitte der Streifen die verwischte Kante wieder ab.
 *
 * Nur wenn die Liste wirklich darunter durchläuft (`data-vilo-dw-ueber`, gesetzt vom
 * Kernel in dwFussSetzen). Ohne `:has()` oder `backdrop-filter` gibt es ihn nicht —
 * der Zustand von vorher. Schichten: Ebene z 2, Rand z 3, Fenster ab 11, Pille 9989. */
html[data-vilo-class="compact"] .desktop-bg.relative:has(> .vilo-dw-layer[data-vilo-dw-ueber])::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--vilo-buehne-reserve, 156px) - 24px);
  height: 120px;
  z-index: 3;
  pointer-events: none;
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 80%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 80%);
  visibility: hidden;
}
/* Sichtbar, wo die Ebene es ist: auf der Bühne und während sie gleitet (mit ihr). */
html[data-vilo-class="compact"][data-vilo-appshell="launcher"] .desktop-bg.relative:has(> .vilo-dw-layer[data-vilo-dw-ueber])::before,
html[data-vilo-class="compact"][data-vilo-bl-buehne] .desktop-bg.relative:has(> .vilo-dw-layer[data-vilo-dw-ueber])::before {
  visibility: visible;
}
html[data-vilo-class="compact"][data-vilo-bl-buehne] .desktop-bg.relative::before {
  translate: var(--vilo-bl-versatz, 0px) 0;
}


/* ── 9 · Das Dock des Telefons: höchstens vier Kacheln, groß, im 8er-Raster ─────
 * Vorgabe Betreiber (2026-10-02, „iPhone genau dasselbe", Nachzug „die vier Icons
 * größer, damit weniger Abstand dazwischen ist — halte dich an 8 Grid"): eine Reihe aus
 * höchstens vier Kacheln. WELCHE vier, entscheidet die Anordnung (Kernel,
 * `DOCK_TELEFON_MAX`, ein Anker wie der Franchise-Fächer belegt einen der vier Plätze);
 * hier steht nur die Form. Die Rollfläche aus mobile-shell.css M1.3 bleibt als
 * Rückfall, falls je mehr als vier stehen (`max-width: 100%` dort).
 *
 * JEDE ZAHL LIEGT IM 8ER-RASTER: Kachel 64 · Abstand 16 · Rand 16 · Radius 16 bzw. 32.
 * Die erste Fassung verteilte vier 60-px-Kacheln gleichmäßig über eine fast
 * schirmbreite Pille (`space-evenly`) — der Abstand war dann der Rest (gemessen 28 px
 * auf 390), also keine Zahl, sondern ein Zufall der Breite. Jetzt umschließt die Pille
 * ihre Kacheln und steht mittig: 4 × 64 + 3 × 16 + 2 × 16 = 336 px. Gerechnet wird von der
 * KANTE aus: 1 Kante + 15 Polster = 16 auf jeder Seite.
 *
 * Wird das zu breit, wird die KACHEL kleiner, nie der Abstand — in Rasterstufen:
 * 64 ab 368 px Fensterbreite (336 + 2 × 16 Rand des Docks), 56 darunter (304 px), 48
 * unter 336 px (272 px, passt auf 320). Gemessen: 390 → 336, 360 → 304, 320 → 272.
 *
 * Die Höhe: oben ebenso 16; unten 10 (Fokuspunkt des Bundles) +
 * 5 Polster + 1 Kante ebenfalls 16. Zusammen 16 + 64 + 16 = 96 px — genau
 * `--vilo-dock-reserve`. Die Such-Pille rückt deshalb 8 px über das Dock (statt 4 über
 * eine Reserve, die das Dock nicht füllte) und endet 8 px unter der Widget-Ebene. Gilt
 * nur für `compact`; iPad und Desktop sind unverändert. */
html[data-vilo-class="compact"] div[class*="bottom-4"][class*="justify-center"] > div {
  width: auto;
}
html[data-vilo-class="compact"] .glass-dock.rounded-3xl {
  --vilo-dock-icon: 64px;
  width: max-content;
  box-sizing: border-box;
  justify-content: center;
  gap: 16px;
  padding: 15px 15px 5px;
  border-radius: 32px;
}
html[data-vilo-class="compact"] .glass-dock.rounded-3xl .dock-item > div.w-14.rounded-2xl {
  width: var(--vilo-dock-icon);
  height: var(--vilo-dock-icon);
  border-radius: 16px;
}
html[data-vilo-class="compact"] .glass-dock.rounded-3xl .dock-item > div.w-14.rounded-2xl svg {
  width: 32px;
  height: 32px;
}
/* Das Namensschild über einer Kachel (Bundle: `absolute -top-12 … whitespace-nowrap`,
 * nur bei `group-hover`) gibt es auf dem Telefon nicht: ohne Zeiger kein Hover, und die
 * Pille schneidet es ohnehin ab (overflow aus M1.3). Unsichtbar trug es trotzdem zur
 * Breite bei — gemessen auf 320 px ein Pixel Überlauf, also eine Pille, die sich um
 * einen Pixel rollen liess. */
html[data-vilo-class="compact"] .glass-dock.rounded-3xl .dock-item > div.absolute.whitespace-nowrap {
  display: none;
}
@media (max-width: 367px) {
  html[data-vilo-class="compact"] .glass-dock.rounded-3xl { --vilo-dock-icon: 56px; }
  html[data-vilo-class="compact"] .glass-dock.rounded-3xl .dock-item > div.w-14.rounded-2xl svg {
    width: 24px;
    height: 24px;
  }
}
@media (max-width: 335px) {
  html[data-vilo-class="compact"] .glass-dock.rounded-3xl { --vilo-dock-icon: 48px; }
}
html[data-vilo-class="compact"] .vilo-bl-pille {
  bottom: calc(var(--vilo-dock-reserve, 112px) + 8px);
}


/* ── 10 · Der Hintergrund steht still ──────────────────────────────────────────
 * Befund Betreiber am eigenen iPhone (2026-10-03): Wischen dauert über drei
 * Sekunden, „es liegt am Hintergrund, was animiert ist". Die Motive des Bundles
 * (Ozean, Sonnenuntergang, Prisma …) sind zwei Verlaufsebenen mit `filter: blur(60px)`
 * bzw. `blur(80px)`, die endlos skalieren, verschieben, drehen und überblenden
 * (`prismShift`/`prismShift2`, 12–20 s). Damit ändert sich der Grund unter JEDEM
 * Glas der Bühne (Dock, Pille, Widget-Karten, der Grund hinter einer Glas-App) in
 * jedem Bild, und WebKit rechnet jeden dieser Weichzeichner jedes Bild neu — auch
 * dann, wenn nichts gewischt wird.
 *
 * Angehalten wird, nicht entfernt: `paused` friert die Ebene in dem Bild ein, mit dem
 * sie begonnen hat, das Motiv sieht also aus wie im ersten Augenblick, nur ruhig.
 * Das Farbband (Vorgabe) und jedes eigene Bild bewegen sich ohnehin nicht. Der
 * Desktop behält die Bewegung — dort kam kein Befund. */
html[data-vilo-appshell] .wp-layer-1,
html[data-vilo-appshell] .wp-layer-2,
html[data-vilo-appshell] .prism-layer-1,
html[data-vilo-appshell] .prism-layer-2 {
  animation-play-state: paused !important;
}
