/* Operian OS — Der Anmeldeschirm ist eine LISTE, kein Kachelband (Vorgabe Betreiber).
 *
 * Befund des Betreibers am eigenen Schirm, mit Entwurf („Anmeldung"): der
 * Sperrbildschirm zeigte eine dunkle Bühne mit der Wortmarke und einer waagerechten
 * Reihe runder Kacheln. Das ist die Form, die ein PRIVATGERÄT mit drei Konten
 * braucht. Ein Betrieb hat achtzehn, und wer morgens anfängt, sucht EINEN Namen —
 * dafür ist eine Liste die Form: eine Zeile je Mensch, untereinander, mit Namen,
 * Rolle und einem Knopf, der sagt, was passiert.
 *
 * ═══ ES IST DERSELBE SCHIRM, NUR ANDERS GESETZT ═══
 *
 * Kein Bundle-Eingriff, und ausdrücklich auch kein Nachbau: die Konten-Reihe, die
 * Kacheln, die PIN-Ansicht und die Wortmarke sind WEITERHIN die Elemente des
 * eingefrorenen Bundles. Diese Datei setzt sie nur neu — der Lock-Root wird ein
 * Raster, die Reihe eine Spalte, die Kachel eine Zeile. Geklickt wird deshalb
 * unverändert die Kachel selbst; PIN-Prüfung, Auswahl und Anmeldung bleiben Sache
 * des Bundles, und `assets/lock-suche.js` filtert weiter dieselben Kacheln.
 *
 * DER HEBEL IST `display: contents` AM WRAPPER. Der Lock-Root trägt genau EIN Kind
 * (den Framer-Motion-Wrapper), und darin liegen Wortmarke und Reihe. Ein Raster
 * erreicht nur seine direkten Kinder — mit `display: contents` werden Wortmarke und
 * Reihe SELBST zu Rasterkindern, ohne dass ein einziger Knoten den Besitzer
 * wechselt. Der Preis ist benannt: ein Element ohne Box trägt keine Transformation,
 * die Einfahr-Animation des Wrappers (`scale(.9)`, `opacity`) entfällt also. Auf
 * einem Anmeldeschirm ist das kein Verlust — die Kacheln bringen ihre eigene mit.
 *
 * ═══ DIE LAGE STEHT IM RASTER, NICHT IN DER REIHENFOLGE ═══
 *
 * Die Chrome-Teile (Leiste, Kartenrahmen, Kopf, Fuss) hängt `lock-anmeldung.js` als
 * weitere Kinder in den Lock-Root — also mitten in eine React-Kinderliste. Ein
 * fremder Knoten überlebt dort zwar jedes Rendern, WANDERT dabei aber an eine
 * Stelle, die niemand bestimmt hat (dieselbe Lehre wie bei der Suchfläche, die
 * deshalb im <body> liegt). Genau deshalb steht hier ein `grid-template-areas`:
 * die Lage kommt aus dem NAMEN der Fläche, nicht aus der Position im Markup. React
 * darf umsortieren, so oft es will — der Schirm sieht danach gleich aus.
 *
 * ═══ FEST HELL, wie das Küchen-Board fest dunkel ist ═══
 *
 * Der Anmeldeschirm dimmt nicht mit dem Erscheinungsbild mit. Er ist die Fläche,
 * an der jemand um 6 Uhr in einer hellen Küche und um 23 Uhr im abgedunkelten
 * Gastraum denselben Namen trifft; ein Schirm, der zweimal am Tag seine Farbe
 * wechselt, wird an einer von beiden Stellen falsch gelesen. Ein Dunkel-Block
 * existiert bewusst NICHT: halb gebaut wäre er die schlechtere Antwort.
 *
 * ═══ WAS DER ENTWURF ZEIGT UND HIER FEHLT (jedes mit Grund) ═══
 *
 *   „IM DIENST" / „NICHT IM DIENST" als Gruppen, die Spalte BEREICH, die SCHICHT
 *   („11:00–20:00"), „ZULETZT gestern" und die Reiter mit Zählern
 *      — Am Anmeldeschirm ist NIEMAND angemeldet. `/api/employees` liefert dort
 *        Name, Rolle, Initialen, Farbe und `hasPin` — mehr nicht; wer eingestempelt
 *        ist, weiss erst `/api/time/team/today`, und das verlangt `time.team.read`,
 *        also eine Anmeldung. Eine Schicht, ein Bereich oder ein „im Dienst" an
 *        dieser Stelle wären erfunden — dieselbe Sorte Behauptung wie ein
 *        erfundener Steuersatz, nur auf dem Schirm, den jeder Mensch im Betrieb
 *        jeden Morgen liest. Wer sie will, braucht zuerst eine Quelle
 *        (gerätegebundener Endpunkt + Rechte-Entscheidung), nicht eine Spalte.
 *   Die volle Markenfläche am „Anmelden" jeder Zeile
 *      — Achtzehn Primärknöpfe untereinander führen nicht, sie lärmen (dieselbe
 *        Abwägung wie bei den Karten des Tagesreviews). Der Knopf ist ruhig und
 *        wird zur Marke, sobald die Zeile unter dem Zeiger liegt: die Zeile, auf
 *        der man steht, IST die Aktion.
 *   Der violette Symbolkasten links in der Leiste
 *      — Dort steht die Wortmarke des Bundles. Ein zweites Markenzeichen daneben
 *        wäre eine zweite Quelle für dieselbe Aussage.
 *   „PIN vergessen" als Verweis
 *      — Er führte nirgendwohin: eine PIN entsteht bei der Aktivierung und wird
 *        über „Einladung erneut senden" neu gesetzt (Manager-Weg). Ein Verweis,
 *        der nichts öffnet, ist der Fail-open aus CONTRIBUTING.md §4; der Fuss
 *        sagt deshalb den Satz, der wahr ist.
 *
 * ═══ DIE TÖNE DES ENTWURFS, MIT EINER GEMESSENEN ABWEICHUNG ═══
 *
 * Der Entwurf setzt `#8b5cf6` als Fläche unter weisse Schrift. Das hält 4.23:1 und
 * liegt unter AA — genau der Befund, den `_fluent.css` für Team Control schon
 * führt. Als Fläche, die TEXT trägt (der Knopf unter dem Zeiger), steht deshalb
 * `#7c3aed` (5.70:1). `#8b5cf6` bleibt, wo die Marke als FARBE wirkt und keinen
 * Text trägt: Kachel-Kreis (weisses Symbol darauf, 4.23:1 — Grafik, 3:1), Kante
 * der aktiven Zeile, Fokusring.
 *
 * Gepinnt durch mockups/tests/lock-anmeldung.test.js.
 */

/* ── Die Zahlen stehen EINMAL ───────────────────────────────────────────────────
 *
 * Sie sind hier nicht Bequemlichkeit, sondern tragend: die Suchfläche liegt im
 * <body> (siehe lock-suche.css) und wird von diesen Zahlen in den Kartenkopf
 * gerechnet. Kopfhöhe und Feldposition MÜSSEN aus derselben Rechnung kommen —
 * zwei getrennt gepflegte Zahlen laufen auseinander, und dann liegt das Feld
 * halb über der ersten Zeile.
 *
 *   Kopfhöhe   = 2 × Kopfpolster + Feldhöhe + Lücke + Standzeile = 14+14+32+4+16 = 80
 *   Feld-Oben  = Leiste + Seitenpolster + Kopfpolster           = 48+14+14       = 76
 *
 * Titel und Feld stehen NEBENEINANDER (wie im Entwurf); die Standzeile („3 von 20
 * Konten") hängt unter dem Feld, weil sie zu ihm gehört — sie ist die Antwort auf
 * das, was dort getippt wurde. Der Kopf hält ihr die Höhe frei, auch solange sie
 * leer ist: eine Zeile, die beim ersten Tastendruck entsteht und den Kopf wachsen
 * liesse, schöbe die erste Person der Liste unter den Zeiger.
 */
html[data-vilo-anmeldung] {
  --vlan-leiste-h: 48px;
  --vlan-max: 1040px;
  --vlan-pad-x: 16px;
  --vlan-pad-y: 14px;
  --vlan-kopf-pad: 14px;
  --vlan-titel-h: 26px;
  --vlan-feld-h: 32px;
  --vlan-feld-breite: 300px;
  --vlan-feld-luecke: 4px;
  --vlan-stand-h: 16px;
  --vlan-kopf-h: 80px;

  --vlan-grund: #f5f5f5;
  --vlan-flaeche: #ffffff;
  --vlan-zone: #fafafa;
  --vlan-kante: #e0e0e0;
  --vlan-kante-fein: #ebebeb;
  --vlan-kante-stark: #d1d1d1;
  --vlan-text: #242424;
  --vlan-text-leise: #616161;
  --vlan-marke: #8b5cf6;        /* Marke als FARBE — trägt nie Text */
  --vlan-marke-text: #7c3aed;   /* Marke als FLÄCHE unter weisser Schrift (5.70:1) */
  --vlan-marke-tint: #ede9fe;
  --vlan-zeile-hover: #faf8ff;
  --vlan-schrift: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}

/* ── Der Lock-Root wird die Seite ──────────────────────────────────────────────
 *
 * `overflow: hidden` ist Absicht: gerollt wird AUSSCHLIESSLICH in der Liste. Rollte
 * zusätzlich der Root, wanderte der Kartenkopf mit — und mit ihm die Naht zur
 * Suchfläche, die als `position: fixed` am Viewport klebt. Eine Fläche, die
 * scrollt, und eine, die nicht scrollt, dürfen nicht dieselbe Kante teilen.
 */
html[data-vilo-anmeldung] .desktop-bg.justify-center {
  display: grid;
  grid-template-columns: 1fr min(var(--vlan-max), calc(100% - 2 * var(--vlan-pad-x))) 1fr;
  grid-template-rows: var(--vlan-leiste-h) var(--vlan-pad-y) var(--vlan-kopf-h) minmax(0, 1fr) auto var(--vlan-pad-x);
  grid-template-areas:
    'leiste leiste leiste'
    '.      .      .'
    '.      kopf   .'
    '.      liste  .'
    '.      fuss   .'
    '.      .      .';
  align-items: stretch;
  padding: 0;
  overflow: hidden;
  background: var(--vlan-grund);
  color: var(--vlan-text);
  font-family: var(--vlan-schrift);
}

/* Der Wrapper gibt seine Box ab, damit Wortmarke und Reihe selbst Rasterkinder
   werden (Dateikopf). Die Bestandsregeln, die ihn als Box behandeln
   (lock-konten.css, mobile-shell.css M2: `width:100%`, `min-height:100%`,
   `justify-content:center`), müssen dabei zurückgenommen werden — sie träfen
   sonst auch die Chrome-Teile dieses Zuschnitts, die ebenfalls `> div` sind. */
html[data-vilo-anmeldung] .desktop-bg.justify-center > div {
  width: auto;
  min-height: 0;
  margin: 0;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center > div.flex.flex-col.items-center {
  display: contents;
}

/* ── Die Leiste ───────────────────────────────────────────────────────────────
 *
 * Sie trägt zwei Flächen im selben Rasterfeld: die Wortmarke (ein Kind des Bundles,
 * links) und diese Leiste. Zwei Elemente in einem Feld überlagern sich — genau das
 * ist hier gewollt und der einzige Weg, ein Bundle-Element neben eigenen Text zu
 * setzen, ohne es zu verschieben. Das Polster links hält ihr den Platz frei.
 */
html[data-vilo-anmeldung] .vlan-leiste {
  grid-area: leiste;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  min-width: 0;
  /* ZWEI RESERVEN, und die grössere gewinnt — rechts stehen zwei verschiedene Dinge,
     die beide nichts wegdrücken.

     Die WORTMARKE steht in der Mitte der Leiste (Vorgabe Betreiber) und liegt im
     selben Rasterfeld wie dieser Text; ohne Reserve schöbe ein langer Betriebsname
     sich unter sie — genau bei den Betrieben mit langem Namen, also dort, wo es
     niemandem auffällt, der einen kurzen hat. GEMESSEN (Chromium): die Wortmarke ist
     bei 26 px Schrift 43.6 px breit, ihre Hälfte also 22; mit 12 px Luft endet der
     Text 34 px vor der Mitte.

     „Betrieb wechseln" ist der zweite: ein `fixed`-Knopf, 148 px breit (er trägt
     seinen Stil inline aus index.html), 16 px vor der Kante — zusammen 164 px. Die
     erste Fassung reservierte 146; eine Zahl, die aus dem Kopf stammte und um genau
     die zwei Pixel danebenlag, die man nicht sieht.

     Auf jeder Breite ab ~260 px ist die Mitte die grössere der beiden; `max()` hält
     trotzdem beide, damit die Zusage nicht an einer Fensterbreite hängt. */
  padding: 0 max(164px, calc(50% + 34px)) 0 var(--vlan-pad-x);
  background: var(--vlan-flaeche);
  border-bottom: 1px solid var(--vlan-kante);
}

/* In der PIN-Ansicht baut das Bundle die Wortmarke ab — dann gibt es nichts
   freizuhalten, und der Titel stünde sonst allein in der Mitte der Leiste. */
html[data-vilo-anmeldung='pin'] .vlan-leiste {
  padding-left: var(--vlan-pad-x);
  /* In der PIN-Ansicht blendet index.html den Knopf aus — dort gibt es nichts
     freizuhalten. */
  padding-right: var(--vlan-pad-x);
}

html[data-vilo-anmeldung] .vlan-leiste__titel {
  flex: 0 0 auto;
  font-size: 16px;
  font-weight: 600;
  color: var(--vlan-text);
}

html[data-vilo-anmeldung] .vlan-leiste__betrieb {
  min-width: 0;
  font-size: 13px;
  color: var(--vlan-text-leise);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Die Wortmarke des Bundles: dasselbe Element, nur klein und links in der Leiste.
   `text-5xl` (48px) und der Bodenabstand `mb-12` gehören der dunklen Bühne. */
html[data-vilo-anmeldung] .desktop-bg.justify-center > div > div.mb-12 {
  grid-area: leiste;
  /* MITTE DER LEISTE (Vorgabe Betreiber) — nicht Mitte der Karte: das Rasterfeld
     `leiste` spannt alle drei Spalten, die Marke sitzt also mittig im Fenster, wie
     in der Kopfzeile jeder anderen Anmeldefläche. Der Text links weicht ihr über die
     Reserve an `.vlan-leiste` aus; `justify-self` gibt der Marke dabei ihre
     Inhaltsbreite, sie deckt also nichts ab, was neben ihr steht. */
  justify-self: center;
  align-self: center;
  z-index: 2;
  /* MITTIG, SOLANGE ES PASST — dieselbe Abwägung wie `safe center` in
     lock-konten.css: die Mitte ist die Zusage, eine Überlappung darf sie nicht
     kosten. „Betrieb wechseln" ist `fixed` und drückt nichts weg (164 px samt
     Kante); unter 381 px Fensterbreite läge die Marke unter ihm. GERECHNET, nicht
     geraten: die Marke misst schmal 36.9 px (22 px Schrift), ihre Hälfte 18.5; mit
     8 px Luft berühren sich beide bei 2 · (18.5 + 164 + 8) = 381 px. Ein Rand
     rechts verschiebt die Mitte um seine HALBE Breite, also ist er genau die
     Differenz. Über 381 px ist er 0 und die Marke steht exakt in der Fenstermitte
     (gemessen: 756 / 1512, 512 / 1024, 195 / 390). */
  margin: 0 max(0px, calc(381px - 100vw)) 0 0;
  padding: 0;
  text-align: left;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center > div > div.mb-12 h1 {
  font-size: 26px;
  line-height: 1;
  /* Die Wortmarke steht auf weiss — der Verlauf des Bundles läuft nach weiss aus
     und wäre hier zur Hälfte unsichtbar. Gefüllt wird deshalb mit der Textfarbe;
     `-webkit-text-fill-color` ist nötig, weil `bg-clip-text` sie sonst schlägt. */
  background: none;
  color: var(--vlan-text);
  -webkit-text-fill-color: var(--vlan-text);
}

/* ── Die Karte ───────────────────────────────────────────────────────────────── */

html[data-vilo-anmeldung] .vlan-rahmen {
  grid-column: 2;
  grid-row: 3 / 6;
  z-index: 0;
  background: var(--vlan-flaeche);
  border: 1px solid var(--vlan-kante);
  border-radius: 8px;
}

/* Das Polster rechts hält dem Feld seinen Platz frei — es liegt als `fixed`-Fläche
   darüber und kann den Titel nicht wegdrücken. Ohne die Reserve schöbe ein langer
   Titel sich darunter, statt zu kürzen. */
html[data-vilo-anmeldung] .vlan-kopf {
  grid-area: kopf;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: var(--vlan-kopf-pad) calc(var(--vlan-feld-breite) + 2 * var(--vlan-pad-x)) var(--vlan-kopf-pad) var(--vlan-pad-x);
  border-bottom: 1px solid var(--vlan-kante);
}

html[data-vilo-anmeldung] .vlan-kopf__titel {
  margin: 0;
  min-width: 0;
  height: var(--vlan-titel-h);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -.01em;
  line-height: var(--vlan-titel-h);
  color: var(--vlan-text);
}

/* In der PIN-Ansicht gibt es nichts mehr zu suchen: dort steht EIN Mensch, und die
   Frage „wer arbeitet gerade" ist beantwortet. Geschaltet wird am Attribut, nicht
   über `:has()` — der Zustand ist ohnehin gemessen (lock-anmeldung.js), und eine
   Engine ohne `:has()` bekäme sonst eine Überschrift über dem Ziffernblock. */
html[data-vilo-anmeldung='pin'] .vlan-kopf {
  display: none;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center {
  grid-template-rows: var(--vlan-leiste-h) var(--vlan-pad-y) 0 minmax(0, 1fr) auto var(--vlan-pad-x);
}

html[data-vilo-anmeldung] .vlan-fuss {
  grid-area: fuss;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0;
  padding: 10px var(--vlan-pad-x);
  border-top: 1px solid var(--vlan-kante);
  border-radius: 0 0 8px 8px;
  background: var(--vlan-zone);
  color: var(--vlan-text-leise);
  font-size: 12.5px;
}

/* ── Die Reihe wird die Liste ─────────────────────────────────────────────────
 *
 * Dieselbe `.flex.gap-8`, die auf der dunklen Bühne waagerecht stand. `overflow-y`
 * gehört hier ausdrücklich hierher und nicht zu lock-konten.css: DORT ist die Reihe
 * eine wischbare Kette (waagerechter Scroller), hier ist sie die einzige rollende
 * Fläche der Seite. Beide Eigentümer schreiben denselben Knoten, aber nie
 * denselben Zustand — dieser Zuschnitt ist strikt spezifischer und gilt nur, solange
 * das Attribut steht.
 */
html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 {
  grid-area: liste;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /* `justify-content` gehört sonst lock-konten.css (dort `safe center` für die
     waagerechte Kette). In der Spalte zeigt dieselbe Eigenschaft in die SENKRECHTE,
     und „zentriert" hiesse dort: vier Personen stehen mitten in einer leeren Karte,
     und beim fünften springt die Liste. Eine Liste beginnt oben. */
  justify-content: flex-start;
  gap: 0;
  width: auto;
  max-width: none;
  padding: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* ── Die Kachel wird die Zeile ───────────────────────────────────────────────
 *
 * Vier Angaben, drei davon aus dem Bundle: Symbolkreis · Name · Rolle — und rechts
 * der Knopf, den das `::after` malt. Er ist KEIN zweites Bedienelement: die ganze
 * Zeile IST der Knopf des Bundles, und ein echter <button> darin wäre ein
 * verschachteltes Bedienelement. Er sagt nur, was ein Klick auf die Zeile tut.
 */
html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  align-items: center;
  /* `gap-3` (12px) gehört der Kachel auf der dunklen Bühne — im Raster dieser Zeile
     träfe es AUCH die Naht zwischen Name und Rolle und machte aus zwei Zeilen einen
     Block mit Loch. Getrennt gesetzt: waagerecht 10, senkrecht 0. */
  column-gap: 10px;
  row-gap: 0;
  width: 100%;
  padding: 9px var(--vlan-pad-x);
  border: 0;
  border-bottom: 1px solid var(--vlan-kante-fein);
  border-left: 3px solid transparent;
  border-radius: 0;
  background: transparent;
  text-align: left;
  transition: background .12s, border-left-color .12s;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button:hover {
  background: var(--vlan-zeile-hover);
  border-left-color: var(--vlan-marke);
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button:focus-visible {
  outline: 2px solid var(--vlan-marke);
  outline-offset: -2px;
  background: var(--vlan-zeile-hover);
}

/* Der Symbolkreis: aus 80 px auf der Bühne werden 32 px in der Zeile. Er trägt das
   Lucide-Symbol des Bundles (weiss auf Marke, 4.23:1 — Grafik, kein Text). Die
   Initialen des Entwurfs stünden hier NICHT: sie liegen in `__VILO_STAFF`, und sie
   von dort zu holen hiesse, neben dem, was in der Zeile steht, eine zweite
   Namensquelle zu führen (dieselbe Zusage wie in lock-suche.js). */
html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button > div {
  width: 32px;
  height: 32px;
  background: var(--vlan-marke);
  border-radius: 999px;
  box-shadow: none;
  transform: none;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button svg {
  width: 17px;
  height: 17px;
  color: #fff;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button > span {
  grid-column: 2;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Name (erste Beschriftung) und Rolle (zweite) stehen im Bundle als zwei Spans
   nebeneinander; hier stapeln sie in derselben Spalte. */
html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button > span:nth-of-type(1) {
  grid-row: 1;
  align-self: end;
  font-size: 14px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--vlan-text);
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button > span:nth-of-type(2) {
  grid-row: 2;
  align-self: start;
  font-size: 12px;
  line-height: 1.35;
  color: var(--vlan-text-leise);
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button > div {
  grid-row: 1 / 3;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button::after {
  content: 'Anmelden';
  grid-column: 3;
  grid-row: 1 / 3;
  display: flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--vlan-kante-stark);
  border-radius: 4px;
  background: var(--vlan-flaeche);
  color: var(--vlan-text);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button:hover::after,
html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button:focus-visible::after {
  border-color: var(--vlan-marke-text);
  background: var(--vlan-marke-text);
  color: #fff;
}

/* ── Die Suchfläche zieht in den Kartenkopf ───────────────────────────────────
 *
 * Sie bleibt, wo lock-suche.js sie hängt: im <body>. Das ist dort eine gepinnte
 * Zusage (der Filter greift nur, solange die Fläche WIRKLICH als Kind des <body>
 * steht — ein Merker darf seine Fläche nie überleben), und sie hier umzuhängen
 * hiesse, genau diesen Riegel zu lösen. Stattdessen rechnet dieser Zuschnitt sie
 * an ihren Platz: dieselben Variablen, aus denen oben die Kopfhöhe entsteht.
 *
 * Das trägt nur, weil in diesem Zuschnitt NICHTS ausser der Liste rollt (s. o.) —
 * eine `fixed`-Fläche über einem scrollenden Kopf wanderte sonst von ihm weg.
 */
html[data-vilo-anmeldung] .vilo-lock-suche {
  left: auto;
  right: max(calc(var(--vlan-pad-x) * 2), calc((100vw - var(--vlan-max)) / 2 + var(--vlan-pad-x)));
  top: calc(var(--vlan-leiste-h) + var(--vlan-pad-y) + var(--vlan-kopf-pad));
  bottom: auto;
  transform: none;
  width: min(var(--vlan-feld-breite), calc(100vw - 2 * var(--vlan-pad-x)));
  /* `column` statt `column-reverse`: die Standzeile gehört UNTER das Feld, nicht
     darüber. Auf der dunklen Bühne war es umgekehrt richtig (sie wuchs nach oben,
     weg von „Betrieb wechseln"); hier hält der Kopf ihr die Höhe ohnehin frei. */
  flex-direction: column;
  align-items: stretch;
  gap: var(--vlan-feld-luecke);
  z-index: 3;
}

html[data-vilo-anmeldung] .vilo-lock-suche__feld {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--vlan-feld-h);
  padding: 0 4px 0 10px;
  border-radius: 4px;
  border: 1px solid var(--vlan-kante-stark);
  background: var(--vlan-flaeche);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

html[data-vilo-anmeldung] .vilo-lock-suche__feld:focus-within {
  border-color: var(--vlan-marke-text);
  outline: 2px solid var(--vlan-marke);
  outline-offset: 1px;
}

html[data-vilo-anmeldung] .vilo-lock-suche__lupe {
  width: 14px;
  height: 14px;
  color: var(--vlan-text-leise);
}

html[data-vilo-anmeldung] .vilo-lock-suche input {
  color: var(--vlan-text);
  font-size: 13.5px;
}

html[data-vilo-anmeldung] .vilo-lock-suche input::placeholder {
  color: #9e9e9e;
}

html[data-vilo-anmeldung] .vilo-lock-suche__leeren {
  width: 28px;
  height: 28px;
  border-radius: 4px;
  background: transparent;
  color: var(--vlan-text-leise);
  font-size: 12px;
}

html[data-vilo-anmeldung] .vilo-lock-suche__leeren:hover {
  background: var(--vlan-kante-fein);
  color: var(--vlan-text);
}

html[data-vilo-anmeldung] .vilo-lock-suche__leeren:focus-visible {
  outline: 2px solid var(--vlan-marke);
  outline-offset: 1px;
}

html[data-vilo-anmeldung] .vilo-lock-suche__stand {
  flex: 0 0 auto;
  height: var(--vlan-stand-h);
  color: var(--vlan-text-leise);
  font-size: 12px;
  line-height: var(--vlan-stand-h);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

html[data-vilo-anmeldung] .vilo-lock-suche__stand[data-leer='1'] {
  color: #8a2331;
}

/* Das Telefon reserviert in lock-suche.css den Boden für die fixe Fläche. In
   diesem Zuschnitt liegt sie im Kopf, und der Boden gehört der Liste. */
@media (max-width: 600px), (max-height: 500px) and (max-width: 932px) {
  html[data-vilo-anmeldung]:has(> body > .vilo-lock-suche) .desktop-bg.justify-center,
  html[data-vilo-anmeldung] .desktop-bg.justify-center {
    padding: 0;
    overflow: hidden;
  }
}

/* ── „Betrieb wechseln" steht oben rechts in der Leiste ───────────────────────
 *
 * Der Knopf gehört index.html und ist dort `position: fixed` mit Inline-Stil — auf
 * dem dunklen Grund weisse Schrift auf 6 % Weiss. Auf dieser hellen Fläche wäre er
 * praktisch unsichtbar; er MUSS also mitgenommen werden, und weil er inline
 * gestylt ist, geht das nur mit `!important`. Verschoben wird er nicht im Markup,
 * nur in der Lage — es bleibt derselbe Knopf mit demselben Verhalten.
 */
html[data-vilo-anmeldung] #vilo-switch-betrieb {
  top: 10px !important;
  right: var(--vlan-pad-x) !important;
  bottom: auto !important;
  left: auto !important;
  transform: none !important;
  z-index: 3 !important;
  height: 28px;
  padding: 0 12px !important;
  border: 1px solid var(--vlan-kante-stark) !important;
  border-radius: 4px !important;
  background: var(--vlan-flaeche) !important;
  color: var(--vlan-text) !important;
  font: 600 12.5px/1 var(--vlan-schrift) !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}

html[data-vilo-anmeldung] #vilo-switch-betrieb:hover {
  background: var(--vlan-grund) !important;
}

/* ── Die PIN-Ansicht: dieselbe Karte, derselbe Ziffernblock ──────────────────
 *
 * Auch hier wird nichts nachgebaut: Avatar, Name, Rolle, Punkte, Fehlerzeile und
 * die zwölf Tasten sind die Elemente des Bundles. Die Beschriftungen bleiben seine
 * („Zurück", „⌫") — ein Text, den dieser Zuschnitt überschriebe, wäre eine zweite
 * Wahrheit über dieselbe Taste.
 */
html[data-vilo-anmeldung] .desktop-bg.justify-center > div > div.flex.flex-col.items-center {
  grid-area: liste;
  z-index: 1;
  justify-content: center;
  padding: 20px var(--vlan-pad-x) 24px;
  overflow: auto;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .w-24.h-24.rounded-full {
  width: 56px;
  height: 56px;
  margin-bottom: 10px;
  background: var(--vlan-marke);
  box-shadow: none;
  --tw-ring-color: transparent;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .w-24.h-24.rounded-full svg {
  width: 26px;
  height: 26px;
  color: #fff;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-lg {
  color: var(--vlan-text);
  font-size: 18px;
  font-weight: 600;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-sm.mb-8 {
  margin-bottom: 20px;
  color: var(--vlan-text-leise);
  font-size: 13px;
}

/* ── DIE PUNKTE: WEISS AUF WEISS WÄRE EINE PIN OHNE RÜCKMELDUNG ──────────────
 *
 * Der eine Fall dieses Zuschnitts, in dem Umfärben nicht genügt. Das Bundle setzt
 * die Füllung INLINE (Framer-Motion animiert `backgroundColor`): gefüllt 90 %
 * Weiss, leer 15 % Weiss, falsch rot, richtig grün. Auf der dunklen Bühne ist das
 * richtig — auf der weissen Karte sind gefüllt und leer BEIDE weiss, und wer tippt,
 * sieht nicht, wie viele Ziffern schon stehen. Eine Anmeldung ohne diese Rückmeldung
 * ist unbedienbar, nicht nur hässlich.
 *
 * Gegen einen Inline-Stil hilft `!important` — aber eine feste Farbe nähme dem Punkt
 * GENAU DIE AUSSAGE, um die es geht: welcher der vier steht schon. Der Zustand lebt
 * ausschliesslich in dieser einen Zahl, und eine zweite Quelle dafür gibt es nicht
 * (das Bundle schreibt keine Klasse, kein Attribut, nichts).
 *
 * Also wird die Farbe UMGEDREHT statt ersetzt: `invert(1)` macht aus jedem hellen
 * Ton einen dunklen, `hue-rotate(180deg)` gibt den Buntton zurück, den die Umkehrung
 * gedreht hat. Die Aussage bleibt damit die des Bundles — Weiss bleibt „gefüllt",
 * Rot bleibt „falsch" —, nur lesbar auf hellem Grund. Gemessen (Chromium, gegen die
 * weisse Karte):
 *
 *   leer     rgba(255,255,255,.15) → #d9d9d9   (1.41:1 gegen Weiss — der helle Punkt
 *                                               des Entwurfs: reine Form, ohne Aussage)
 *   gefüllt  rgba(255,255,255,.90) → #191919   (17.58:1 — der Punkt, der etwas sagt)
 *   falsch   rgba(239, 68, 68,.90) → #ff8080   (2.43:1 — Wiederholung, nicht Träger:
 *                                               den Befund trägt die Karte „Falscher
 *                                               PIN" darunter mit 8.16:1)
 *   richtig  rgba( 52,211,153,.90) → #198551   (4.65:1, grün bleibt grün)
 *
 * Gemessen wurde am gerenderten Pixel (Chromium), nicht gerechnet: `hue-rotate` ist
 * eine Matrix-Näherung, und was sie aus einem invertierten Rot macht, sagt einem
 * keine Formel im Kopf.
 *
 * Deshalb steht hier auch KEINE Kante: eine eigene würde mitgedreht, und ein Wert,
 * der im Quelltext dunkel steht, um hell zu erscheinen, ist die Sorte Zahl, die beim
 * nächsten Umbau jemand „korrigiert". Die 15 % des Bundles ergeben umgedreht ohnehin
 * genau den hellen Punkt, den der Entwurf zeichnet.
 */
html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .flex.gap-4.mb-8 {
  gap: 12px;
  margin-bottom: 20px;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .flex.gap-4.mb-8 > div {
  width: 13px;
  height: 13px;
  filter: invert(1) hue-rotate(180deg);
}

/* „Falscher PIN": aus roter Schrift auf dunkel wird Fluents `danger`-Karte — Text
   #8a2331 auf #fdf3f4 hält 8.16:1 (gemessen). Sie ist der TRÄGER des Befunds; die
   roten Punkte darüber sind seine Wiederholung. Weiss wäre hier so falsch wie auf
   Marigold. */
html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-red-400 {
  margin-bottom: 16px;
  padding: 4px 10px;
  border: 1px solid #f1c7cd;
  border-radius: 3px;
  background: #fdf3f4;
  color: #8a2331;
  font-size: 12.5px;
  font-weight: 600;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .grid.grid-cols-3.gap-3 {
  gap: 10px;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn {
  width: 64px;
  height: 52px;
  border: 1px solid var(--vlan-kante-stark);
  border-radius: 4px;
  background: var(--vlan-flaeche);
  color: var(--vlan-text);
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn:hover {
  border-color: #b69bfb;
  background: var(--vlan-marke-tint);
  color: #4c1d95;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn:focus-visible {
  outline: 2px solid var(--vlan-marke);
  outline-offset: 2px;
}

/* Die zwei Tasten ohne Ziffer („Zurück", „⌫") sind im Bundle leiser gesetzt
   (`bg-white/5`, `text-white/50`) — sie bleiben es auch hier: eine Taste, die
   etwas zurücknimmt, steht nicht so laut da wie eine, die etwas eingibt. */
html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn.text-sm,
html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn:not(.text-xl) {
  border-color: transparent;
  background: transparent;
  color: #424242;
  font-size: 13px;
  font-weight: 600;
}

html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn:not(.text-xl):hover {
  border-color: transparent;
  background: var(--vlan-kante-fein);
  color: var(--vlan-text);
}

/* Der Demo-PIN-Hinweis des Bundles (nur im Demo-Zweig, `user.pin`) stünde hier in
   20 % Weiss auf weiss. Er bleibt lesbar, statt unsichtbar zu verschwinden. */
html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-xs {
  color: var(--vlan-text-leise);
}

/* ── Schmal ──────────────────────────────────────────────────────────────────
 *
 * Eine Liste braucht keinen eigenen Zuschnitt fürs Telefon — sie stapelt schon.
 * Zurückgenommen wird nur, was Platz kostet: Seitenpolster, Kopfhöhe (Titel und
 * Feld rücken zusammen) und die Ziffernblock-Breite.
 */
@media (max-width: 600px) {
  html[data-vilo-anmeldung] {
    --vlan-pad-x: 10px;
    --vlan-pad-y: 8px;
    --vlan-kopf-pad: 10px;
    --vlan-titel-h: 24px;
    --vlan-feld-h: 36px;
    --vlan-feld-luecke: 8px;
    /* 10 + 24 + 8 + 36 + 4 + 16 + 10 = 108 */
    --vlan-kopf-h: 108px;
  }

  /* Der Titel der Leiste entfällt — „Anmeldung" steht als Frage ohnehin im Kopf der
     Karte, und die Leiste trägt schmal das, was nur SIE sagen kann: welcher Betrieb
     an diesem Gerät hängt. Beides nebeneinander ginge auf 390 px nicht aus; gekürzt
     wäre der Betriebsname die falsche Hälfte. */
  html[data-vilo-anmeldung] .vlan-leiste__titel {
    display: none;
  }

  /* In der PIN-Ansicht baut das Bundle die Wortmarke ab und index.html den Knopf —
     dort ist die Leiste leer, und der Titel passt wieder hinein. */
  html[data-vilo-anmeldung='pin'] .vlan-leiste__titel {
    display: block;
  }

  /* Neben einem Titel bliebe dem Feld auf 390 px keine lesbare Breite — es steht
     deshalb UNTER ihm, über die volle Kartenbreite. */
  html[data-vilo-anmeldung] .vlan-kopf {
    align-items: flex-start;
    padding-right: var(--vlan-pad-x);
  }

  html[data-vilo-anmeldung] .vilo-lock-suche {
    left: max(calc(var(--vlan-pad-x) * 2), calc((100vw - var(--vlan-max)) / 2 + var(--vlan-pad-x)));
    right: max(calc(var(--vlan-pad-x) * 2), calc((100vw - var(--vlan-max)) / 2 + var(--vlan-pad-x)));
    top: calc(var(--vlan-leiste-h) + var(--vlan-pad-y) + var(--vlan-kopf-pad) + var(--vlan-titel-h) + var(--vlan-feld-luecke));
    width: auto;
  }

  /* Schmal steht die Marke ebenso in der Mitte; links bleibt das gewöhnliche Polster,
     die Reserve zur Mitte trägt die Grundregel (bei 22 px Schrift misst die Marke
     36.9 px, ihre Hälfte 18.5 — die 34 px der Grundregel decken sie mit). */

  html[data-vilo-anmeldung] .desktop-bg.justify-center > div > div.mb-12 h1 {
    font-size: 22px;
  }

  html[data-vilo-anmeldung] .desktop-bg.justify-center .flex.gap-8 > button {
    padding: 9px 10px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn {
    width: 60px;
    height: 48px;
  }
}

/* ── Niedriges Querformat: der Ziffernblock muss OHNE Rollen erreichbar sein ──
 *
 * Die Medienbedingung ist WORTGLEICH die von mobile-shell.css M2 — liefen die
 * beiden auseinander, gäbe es einen Bereich dazwischen mit diesem Zuschnitt und
 * ohne seine Kompaktierung.
 *
 * Gerechnet (844 × 390, gemessen nachgeprüft): 390 Höhe minus Leiste 48, minus
 * Polster 2 × 8 = 326 für die Karte. Der Block braucht Avatar 44 + 4 + Name 20 +
 * Rolle 16 + Punkte 11 + 10 + Ziffernblock (4 × 44 + 3 × 6 = 194) = 299. Die
 * Tasten bleiben dabei auf der 44-px-Mindestgrösse — enger wird hier nichts.
 *
 * Der FUSS entfällt in dieser einen Lage: „Anmeldung mit persönlichem 4-stelligen
 * PIN." erklärt einen Ziffernblock, der bereits offen ist, und kostet die Zeile,
 * die der untersten Tastenreihe fehlt. In der LISTE bleibt er auch quer stehen —
 * dort ist er die einzige Stelle, die sagt, was nach dem Tippen auf eine Zeile
 * passiert.
 */
@media (orientation: landscape) and (max-height: 500px) and (max-width: 932px) {
  html[data-vilo-anmeldung='pin'] {
    --vlan-pad-y: 8px;
    --vlan-pad-x: 12px;
  }

  html[data-vilo-anmeldung='pin'] .vlan-fuss {
    display: none;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center > div > div.flex.flex-col.items-center {
    padding: 8px var(--vlan-pad-x);
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .w-24.h-24.rounded-full {
    width: 44px;
    height: 44px;
    margin-bottom: 4px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .w-24.h-24.rounded-full svg {
    width: 20px;
    height: 20px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-lg {
    font-size: 15px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-sm.mb-8 {
    margin-bottom: 6px;
    font-size: 12px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .flex.gap-4.mb-8 {
    gap: 10px;
    margin-bottom: 10px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .flex.gap-4.mb-8 > div {
    width: 11px;
    height: 11px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center p.text-red-400 {
    margin-bottom: 6px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .grid.grid-cols-3.gap-3 {
    gap: 6px;
  }

  html[data-vilo-anmeldung='pin'] .desktop-bg.justify-center .numpad-btn {
    width: 56px;
    height: 44px;
  }
}
