/*
 * DIE BEIDEN PANELS — Tokens und die Regeln, die auf ihnen stehen.
 *
 * Eine Datei für beide: die Konsole (/konsole) und das Panel der Inhaberin (/admin). Sie rendern
 * dieselben Klassen, also brauchen sie dasselbe System — und unterscheiden sich an genau den
 * Stellen, an denen sich ihre Benutzung unterscheidet.
 *
 * ⛔ WARUM KEIN FILAMENT-THEME-BUILD. `make:filament-theme` ERSETZT Filaments komplettes CSS,
 *    es ergänzt es nicht — und alles hier kommt ohne aus, weil UNGESCHICHTETES CSS jede
 *    `@layer` schlägt. Gemessen: Filament liefert `.fi-ta-ctn`, `.fi-badge`, `.fi-btn` in
 *    `@layer components` und `--radius-lg` in `@layer theme`; diese Datei liegt in keiner
 *    Schicht und gewinnt deshalb nach der Kaskadenregel, unabhängig von Spezifität UND von
 *    Ladereihenfolge. Deshalb steht hier auch kein einziges `!important`.
 *
 *    Ein Theme lohnt genau dann, wenn eigene Blades Tailwind-Utilities schreiben sollen. Das
 *    dürfen sie hier nicht — siehe die nächste Warnung.
 *
 * ⛔ IN EIGENEN BLADES SIND TAILWIND-UTILITIES VERBOTEN, und das ist kein Stil, sondern ein
 *    gemessener Befund: Filaments Theme wird mit `@import 'tailwindcss' source(none)` gebaut,
 *    also existieren NUR die `fi-*`-Komponentenklassen. `.flex`, `.w-full`, `.items-center`,
 *    `.px-6`, `.text-sm`, `.gap-3` — alle null Treffer im ausgelieferten CSS.
 *
 *    Was das angerichtet hat: `working-in.blade.php` und `support-banner.blade.php` tragen je
 *    neun solcher Klassen. Der Kopfbalken der Konsole hatte nie ein Flex-Layout und nie ein
 *    Innenpolster; er sah nur deshalb nach etwas aus, weil `.fi-banner` weiter unten in dieser
 *    Datei stand. Im INHABER-PANEL wurde diese Datei bis heute gar nicht geladen — der
 *    Alarmbalken «Bemuar-Support ist gerade in Ihrem Bereich angemeldet» hatte dort keinen
 *    Hintergrund, kein Polster, und «Support beenden» war ein nackter Browser-Knopf. Auf einem
 *    Bildschirm, den ein Kunde sieht, und für eine Meldung, die er nicht übersehen darf.
 *
 * ⚠️ DER DATEINAME DARF DIE ZEICHENFOLGE `konsole.` NICHT ENTHALTEN. `ConsoleFleetPagesTest`
 *    prüft, dass sie im ausgelieferten HTML nirgends vorkommt — so findet er einen nicht
 *    übersetzten Schlüssel wie `konsole.fleet.title`, der sonst als Text auf dem Bildschirm
 *    stünde. Ein `<link>` auf `…/konsole.css` liess genau diese Prüfung fehlschlagen; daher
 *    `panel-ui.css`. Die Prüfung ist grob und richtig.
 */

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   RESMUAR — DIE SCHRIFT DES PRODUKTS

   ⛔ DAS PANEL HATTE KEINE EIGENE SCHRIFT. Es lief auf Instrument Sans, weil Filaments Theme
      das mitbringt — eine gute, vollkommen unauffällige Grotesk, dieselbe, auf der zehntausend
      andere Admin-Oberflächen laufen. Ein Produkt, das an Restaurants VERKAUFT wird, sah damit
      aus wie das Werkzeug, mit dem es gebaut wurde.

   ⛔ UND DIE SCHRIFTEN LAGEN SEIT MONATEN IM REPO, UNBENUTZT. `public/assets/fonts/` enthält
      Fraunces, Archivo, Public Sans und EB Garamond — von der öffentlichen Seite mitgebracht,
      von keiner einzigen Regel je angefordert. Nachgemessen: alle drei benutzten sind echte
      Variable Fonts (fvar-Tabelle vorhanden), also gibt es die Gewichte wirklich und nicht als
      gefälschten Fettdruck.

   DIE PAARUNG, und sie ist für DIESES Produkt gewählt und nicht aus einem Katalog:

     · ARCHIVO trägt die Oberfläche. Eine Grotesk mit hoher x-Höhe und leicht schmalen Formen —
       auf einem Dienstbildschirm, der Zahlen, Uhrzeiten und Namen nebeneinanderstellt, passt
       mehr in dieselbe Zeile, ohne dass es gedrängt aussieht. Es ist ausserdem die Schrift der
       ÖFFENTLICHEN Seite dieses Hauses: Website und Panel sind damit ein Produkt und nicht zwei.

     · FRAUNCES trägt die Überschriften. Eine warme Antiqua mit optischer Grösse — sie liest sich
       nach Gastlichkeit und nicht nach Verwaltung, und genau das verkauft dieses Produkt. Sie
       steht NUR auf Titeln und Schlüsselzahlen; als Fliesstext wäre sie eine Speisekarte und
       kein Werkzeug.

   ⚠️ SELBST AUSGELIEFERT, KEIN CDN. Die Dateien liegen im eigenen `public/`; eine Schrift von
      fonts.googleapis.com wäre ein Drittanbieter im Ladepfad jeder Kundenseite und in einem
      deutschen Panel ausserdem eine Einwilligungsfrage, die niemand gestellt hat.

   ⚠️ `font-synthesis-weight: none`. Fällt eine Datei aus, soll der Ersatz seine eigenen
      Gewichte zeigen statt künstlich fett gerechneter — ein synthetischer Fettdruck sieht nach
      kaputtem Rendering aus und niemand findet die Ursache.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/*
 * ⛔ `format('woff2')`, NICHT `format('woff2')`. Diese zwei Blöcke habe ich aus
 *    `tokens.css` übernommen, und dort stand der falsche String mitsamt einer Begründung, die
 *    ihn verteidigte. `app/Site/Theme.php:89-98` sagt das Gegenteil und hat recht: eine
 *    Formatangabe, die der Browser nicht kennt, lässt ihn die GANZE Regel verwerfen — lautlos,
 *    ohne Konsolenmeldung —, und das Panel stünde in Georgia da. Kopiert ist nicht geprüft.
 */
@font-face {
    font-family: 'Archivo';
    src: url('/assets/fonts/archivo.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Fraunces';
    src: url('/assets/fonts/fraunces.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

html:root {
    /*
     * ⛔ `--font-sans` IST FILAMENTS EIGENER HEBEL, und deshalb steht er hier und nicht als
     *    `body { font-family }`. Das gebaute Theme setzt `font-family: var(--font-sans)` an
     *    Dutzenden Stellen; eine Regel am Körper hätte jede davon einzeln überstimmen müssen,
     *    und die erste vergessene wäre eine Fläche in zwei Schriften.
     */
    --font-sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

    /* Die Auszeichnungsschrift. Eigener Name, weil sie NICHT überall gilt. */
    --rm-display: 'Fraunces', Georgia, 'Times New Roman', serif;

    /*
     * ⚠️ OPTISCHE GRÖSSE UND «WONK» AUSDRÜCKLICH GESETZT. Fraunces stellt beide Achsen zur
     *    Verfügung; ohne Angabe rendert der Browser die Vorgabe und die Titel wirken auf grossen
     *    Graden zu weich. `opsz` folgt der Schriftgrösse, `WONK` bleibt aus: die schrägen
     *    Sonderformen sind für Plakate, nicht für einen Bildschirm, der acht Stunden offen ist.
     */
    --rm-display-settings: 'opsz' 36, 'SOFT' 0, 'WONK' 0;
}

/*
 * DIE TITEL DES PANELS — jede Seite, ohne dass eine einzelne sie anfordern muss.
 *
 * ⚠️ NUR TITEL UND ABSCHNITTSKÖPFE. Eine Antiqua in einer Tabellenzeile ist eine Speisekarte;
 *    hier trägt sie die Stelle, an der der Bildschirm sagt, was er ist.
 */
.fi-header-heading,
.fi-section-header-heading {
    font-family: var(--rm-display);
    font-variation-settings: var(--rm-display-settings);
    font-synthesis-weight: none;
    /* Antiqua-Grossbuchstaben stehen bei diesen Graden von Natur aus weit; ein Hauch negativer
       Laufweite bindet den Titel wieder zu einem Wort zusammen. */
    letter-spacing: -0.015em;
}

/* ═══ Filaments eigene Tokens ══════════════════════════════════════════════════════════════ */

/*
 * DIE GRAU-RAMPE UND DIE VIER RADIEN — der eine Hebel, der jede Fläche gleichzeitig trifft,
 * auch die Hunderte von Filament-Regeln, die diese Datei nie erwähnt.
 *
 * ⛔ `html:root` UND NICHT `:root`, und das ist keine Vorsicht, sondern eine Messung.
 *
 *    Filament schreibt seine Palette als INLINE-`<style>` mit gewöhnlichem `:root` in den Kopf —
 *    ungeschichtet, also gilt gegen sie nicht das Kaskadenschicht-Argument aus dem Dateikopf,
 *    sondern die normale Reihenfolge. Und die Reihenfolge ist eindeutig, gemessen auf
 *    /konsole/login:
 *
 *        Byte 1056   <link … panel-ui.css>          ← diese Datei
 *        Byte 1810   <style> :root { --gray-50: … } ← Filaments Palette, DANACH
 *
 *    Zwei ungeschichtete `:root`-Blöcke gleicher Spezifität: der SPÄTERE gewinnt. Ein
 *    `--gray-50` in einem `:root` dieser Datei wäre eine tote Zeile gewesen — sichtbar an
 *    nichts, prüfbar durch nichts, und in einem halben Jahr die Erklärung dafür, warum «die
 *    Tokens ja da sind, aber nichts machen».
 *
 *    `html:root` hat 0,1,1 gegen 0,1,0 und gewinnt damit unabhängig von der Position.
 *
 *    ⚠️ ES GILT NUR FÜR FILAMENTS PALETTE. `--radius-*` steht in `@layer theme` im kompilierten
 *       app.css; dort hätte schon ungeschichtetes `:root` genügt. Beide stehen hier zusammen,
 *       weil sie zusammen abgenommen werden — und die stärkere Regel schadet der schwächeren
 *       Anforderung nicht.
 *
 * WARUM DIESE RAMPE. Filament rendert den Dunkelmodus aus DERSELBEN Palette
 * (`@variant dark (&:where(.dark, .dark *))`), eine Rampe bedient also beide Modi. Sie ist
 * Tailwind-förmig in der Helligkeit — damit jede ungeprüfte Filament-Regel weiter stimmt — und
 * leicht kühl gefärbt: passend zur Konsole, neutral genug für das Inhaber-Panel.
 *
 * `#0E0F11` statt `#000` und `#EDEDEF` statt `#FFF`: reines Schwarz und reines Weiss
 * halationieren, der Text flimmert an den Kanten.
 */
html:root {
    --gray-50:  #F6F7F9;   /* Seitenfläche hell, deaktivierte Feldfüllung */
    --gray-100: #EDF0F3;   /* Zeilen-Hover hell */
    --gray-200: #E3E7EB;   /* Haarlinien, Tabellentrenner */
    --gray-300: #CBD2D9;   /* Trennlinien in Menüs */
    --gray-400: #98A2AD;   /* Sekundärtext DUNKEL, Icons zweiter Ordnung */
    --gray-500: #6B7683;   /* Icons, Meta hell — nie Text im Dunkelmodus (4.15 < 4.5) */
    --gray-600: #4A5460;   /* Sekundärtext hell — 7.70:1 */
    --gray-700: #343C46;   /* Rahmen dunkel */
    --gray-800: #1F252B;   /* starker Text hell */
    --gray-900: #141618;   /* Kartenfläche dunkel */
    --gray-950: #0E0F11;   /* Primärtext hell, Seitenfläche dunkel */

    /*
     * RADIEN: 6/8/12/16 — und das ist eine UMGEKEHRTE Entscheidung, die hier stehen bleiben soll.
     *
     * ⚠️ HIER STAND 3/5/6/8, mit der Begründung: «bei 36 px Zeilenhöhe lesen 8-px-Radien als
     *    Verbraucher-Software, 6 px lesen als Werkzeug». Das Argument war richtig für ein Panel,
     *    das aussehen sollte wie ein Instrument. Das Produkt ist inzwischen ein anderes: es wird
     *    an Restaurants VERKAUFT, und der Inhaber, der es zum ersten Mal sieht, vergleicht es
     *    nicht mit einem Terminal, sondern mit der Software, die er sonst bezahlt. Der Auftrag
     *    lautet ausdrücklich «professional restaurant management SaaS», Material Dashboard als
     *    Massstab — und dessen ganze Anmutung hängt an weichen Ecken über getragenen Flächen.
     *
     * ⛔ VIER ZEILEN, 167 ECKEN, und genau deshalb steht die Änderung HIER und nicht in
     *    hundertsiebenundsechzig Regeln. `--radius-lg` allein wird in Filaments Theme 107× benutzt,
     *    `-md` 20×, `-xl` 38×, `-sm` 2×. Wer das Panel wieder streng haben will, ändert diese vier
     *    Zeilen zurück — und nichts sonst.
     */
    --radius-sm: 6px;      /* Badge-Innenkanten, Kontrollkästchen — Vorbild: borderRadius.md */
    --radius-md: 8px;      /* Knöpfe, Eingabefelder            — Vorbild: borderRadius.lg */
    --radius-lg: 12px;     /* Karten, Tabellenrahmen, Dropdowns — Vorbild: borderRadius.xl */
    --radius-xl: 12px;     /* Modale, Slide-Over, schwebende Schiene */
}

/* ═══ Tokens, hell ═════════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Flächen. Fünf Stufen, weil eine Tabelle in einer Karte auf einer Seite liegt. ────── */
    /*
     * ⚠️ NICHT MEHR `--gray-50`, und der Unterschied ist klein und wirkt überall: der
     *    Referenzentwurf setzt als Seitenfläche `#f0f2f5` — etwas dunkler und kühler als die
     *    Rampe hier (#F6F7F9). Auf einer helleren Seite verschwindet der weite, weiche Schatten
     *    einer Karte fast; erst gegen dieses Grau liegt sie sichtbar darauf.
     *
     *    ⛔ NUR DIESE EINE VARIABLE, NICHT `--gray-50` SELBST. Die Rampe füllt auch deaktivierte
     *       Eingabefelder; sie mitzuziehen hiesse, ein gesperrtes Feld dunkler zu machen, weil
     *       die Seite es sein soll. Gerechnet: `--bm-txt-3` trägt hier 5.38:1 statt 5.61:1 —
     *       weiterhin über der Schwelle.
     */
    --bm-srf-0: #F0F2F5;                 /* Seitenhintergrund */
    --bm-srf-1: #FFFFFF;                 /* Karte, Tabelle */
    --bm-srf-2: #F1F3F5;                 /* Tabellenkopf, Werkzeugleiste */
    --bm-row-hover: var(--gray-100);

    /* ── Linien. Zwei, nicht fünf: eine für Trennung, eine für Begrenzung. ────────────────── */
    --bm-line-hair: var(--gray-200);     /* trennt, trägt keine Bedeutung */
    --bm-line-strong: #7E8892;           /* 3.04:1 — begrenzt BEDIENELEMENTE, WCAG 1.4.11 */

    /* ── Text. Die Kontrastwerte sind gerechnet, nicht geschätzt. ─────────────────────────── */
    --bm-txt-1: var(--gray-950);         /* 16.16:1 */
    --bm-txt-2: var(--gray-600);         /*  6.49:1 */
    --bm-txt-3: #5A646E;                 /*  5.08:1 */
    --bm-txt-disabled: #99A2AB;          /*  2.59:1 — WCAG 1.4.3 nimmt Inaktive aus */

    /*
     * ── Zustände. FÜNF Bedeutungen, nicht sieben Farben ────────────────────────────────────
     *
     * ok      = fertig, läuft, online
     * wait    = wartet auf jemanden, nichts ist falsch
     * todo    = jemand muss etwas tun, es eilt nicht
     * risk    = etwas ist kaputt oder gefährlich
     * off     = abgeschaltet, eine Entscheidung — KEINE Pille, nur Text
     * unknown = wir wissen es nicht — gestrichelt, nie farbig
     *
     * ⛔ FARBE ALLEIN TRÄGT NIE EINE AUSSAGE. Jede Zustandsfarbe hat ein Icon oder einen
     *    Textzusatz neben sich. Ein Graustufen-Screenshot ist die Probe: sehen zwei Zustände
     *    darin gleich aus, fehlt das zweite Signal.
     */
    --bm-ok-fg: #05603A;    --bm-ok-bg: #E7F6EF;    --bm-ok-line: #8ED3B6;
    --bm-wait-fg: #0B4FA8;  --bm-wait-bg: #E6F0FD;  --bm-wait-line: #A9CBF5;
    --bm-todo-fg: #7A4A00;  --bm-todo-bg: #FDF2DF;  --bm-todo-line: #F0CE93;
    --bm-risk-fg: #A4160C;  --bm-risk-bg: #FDECEA;  --bm-risk-line: #F5B5AE;
    --bm-off-fg: var(--bm-txt-3);
    --bm-unknown-fg: var(--bm-txt-3);
    --bm-unknown-line: var(--bm-line-strong);

    /* ── Fokus. Eine Farbe, ein Ring, überall derselbe. ───────────────────────────────────── */
    --bm-focus: #1D4ED8;
    --bm-focus-w: 2px;
    --bm-focus-off: 2px;

    /* ── Typo-Skala ───────────────────────────────────────────────────────────────────────── */
    --bm-t-2xs: 11px; --bm-lh-2xs: 14px;
    --bm-t-xs:  12px; --bm-lh-xs:  16px;
    --bm-t-sm:  13px; --bm-lh-sm:  18px;
    --bm-t-md:  14px; --bm-lh-md:  20px;
    --bm-t-lg:  16px; --bm-lh-lg:  24px;

    /*
     * ── Masse. `--bm-row-pad` und `--bm-hit` werden je Panel überschrieben. ────────────────
     *
     * ⚠️ `--bm-row-pad` ist das Polster INNERHALB von `.fi-ta-text`, nicht der Zelle. Filaments
     *    Zelle hat senkrecht null Polster, die 16 px sitzen eine Ebene tiefer — wer den Wert auf
     *    `.fi-ta-cell` legt, addiert statt zu ersetzen. Die ganze Rechnung steht bei der Regel.
     */
    --bm-head-h: 36px;
    --bm-head-pad: 8px;
    --bm-filterbar-h: 44px;
    --bm-row-pad: 6px;
    --bm-hit: 36px;

    /* ── Bewegung. Ausschliesslich Rückmeldung, 0–240 ms. ────────────────────────────────── */
    --bm-dur-0: 0ms; --bm-dur-1: 70ms; --bm-dur-2: 120ms;
    --bm-dur-3: 180ms; --bm-dur-4: 240ms;
    --bm-ease-out: cubic-bezier(.16, .84, .44, 1);

    /*
     * ── Höhe. Vier Stufen, und sie bedeuten etwas ──────────────────────────────────────────
     *
     * ⛔ SCHATTEN SIND HIER KEINE DEKORATION, SONDERN DIE Z-ACHSE. Bisher trennte diese Datei
     *    Flächen ausschliesslich mit Linien; das ist sparsam und richtig für ein Werkzeug, und
     *    es ist der Grund, warum das Panel neben Material Dashboard flach wirkte. Eine Karte,
     *    die auf der Seite LIEGT statt in sie eingezeichnet zu sein, ist der halbe Unterschied.
     *
     *    lift-1  ruhende Fläche — Karte, Tabelle, Abschnitt
     *    lift-2  angehoben — Karte unter dem Zeiger, Werkzeugleiste
     *    lift-3  schwebend — Dropdown, Popover
     *    lift-4  über allem — Modal, Slide-Over
     *
     * ⚠️ IM DUNKELMODUS TRÄGT EIN SCHATTEN NICHTS. Auf #141618 ist Schwarz unter Schwarz
     *    unsichtbar; dort übernimmt eine hellere Kante dieselbe Aufgabe (siehe `.dark` unten).
     *
     * ⛔ DIE WERTE SIND ABGEMESSEN, NICHT GESCHÄTZT — und die erste Fassung lag daneben.
     *
     *    Hier stand `0 2px 6px -1px`, aus dem Gedächtnis geschrieben. Nachgelesen im Theme des
     *    Referenzentwurfs (`src/assets/theme/base/boxShadows.js`) trägt dessen KARTE
     *    `0 20px 27px 0 rgba(0,0,0,.05)`: ein zehnmal weiterer Radius bei geringerer Deckkraft.
     *    Der Unterschied ist genau der zwischen «Karte mit Kante» und «Karte, die über der Seite
     *    schwebt» — und er war der Hauptgrund, warum das Ergebnis dem Vorbild noch nicht glich.
     *    Ein enger Schatten sieht aus wie ein Rahmen; ein weiter sieht aus wie Abstand.
     */
    --bm-lift-1: 0 20px 27px 0 rgba(16, 24, 40, .05);
    --bm-lift-2: 0 10px 15px -3px rgba(16, 24, 40, .10), 0 4px 6px -2px rgba(16, 24, 40, .05);
    --bm-lift-3: 0 20px 25px -5px rgba(16, 24, 40, .10), 0 10px 10px -5px rgba(16, 24, 40, .04);
    --bm-lift-4: 0 25px 50px -12px rgba(16, 24, 40, .25);

    /*
     * Die Kachel unter einem Kennzahl-Icon. Sie trägt einen eigenen, kräftigeren Schatten als
     * die Karte, auf der sie liegt — sonst schwebt sie nicht, sondern klebt.
     */
    --bm-lift-kachel: 0 4px 20px 0 rgba(16, 24, 40, .14), 0 7px 10px -5px rgba(16, 24, 40, .28);

    /* ── Rhythmus. Ein Raster von 4, damit Abstände nicht ausgedacht sind. ────────────────── */
    --bm-gap-1: 4px; --bm-gap-2: 8px; --bm-gap-3: 12px;
    --bm-gap-4: 16px; --bm-gap-5: 20px; --bm-gap-6: 24px; --bm-gap-8: 32px;
}

/* ═══ Tokens, dunkel ═══════════════════════════════════════════════════════════════════════ */

/*
 * ⛔ `.dark`, NICHT `prefers-color-scheme` — UND DAS WAR EIN ECHTER FEHLER IN DER VORFASSUNG.
 *
 *    Filaments Umschalter schreibt `localStorage['theme']` und setzt die Klasse `.dark` auf
 *    <html>; `prefers-color-scheme` wird NUR beim Wert «System» gelesen. Die alte Datei hatte
 *    zwei `@media (prefers-color-scheme: dark)`-Blöcke, also galten sie am Umschalter vorbei:
 *    Betriebssystem dunkel + Nutzerwahl «Hell» ergab ein HALB dunkles Panel — heller Rahmen von
 *    Filament, dunkle Balken von hier.
 */
.dark {
    --bm-srf-0: var(--gray-950);
    --bm-srf-1: var(--gray-900);
    --bm-srf-2: #1A1D20;
    --bm-row-hover: #1F2326;

    --bm-line-hair: #262B30;
    --bm-line-strong: #6B747D;           /* 3.05:1 */

    --bm-txt-1: #EDEDEF;                 /* 12.38:1 — nicht #FFF: reines Weiss halationiert */
    --bm-txt-2: #A9B2BB;                 /*  6.74:1 */
    --bm-txt-3: #909AA3;                 /*  5.06:1 */
    --bm-txt-disabled: #626B74;

    --bm-ok-fg: #5FD3A3;
    --bm-ok-bg: color-mix(in oklab, #5FD3A3 12%, transparent);
    --bm-ok-line: color-mix(in oklab, #5FD3A3 24%, transparent);
    --bm-wait-fg: #85B5F8;
    --bm-wait-bg: color-mix(in oklab, #85B5F8 12%, transparent);
    --bm-wait-line: color-mix(in oklab, #85B5F8 24%, transparent);
    --bm-todo-fg: #EFC067;
    --bm-todo-bg: color-mix(in oklab, #EFC067 12%, transparent);
    --bm-todo-line: color-mix(in oklab, #EFC067 24%, transparent);
    --bm-risk-fg: #FF9186;
    --bm-risk-bg: color-mix(in oklab, #FF9186 12%, transparent);
    --bm-risk-line: color-mix(in oklab, #FF9186 24%, transparent);

    --bm-focus: #8AB4FF;

    /*
     * ⛔ SCHATTEN TRAGEN IM DUNKELN NICHTS, und ein Schatten, den niemand sieht, ist eine Regel,
     *    die im Editor vollständig aussieht. Auf einer Kartenfläche von #141618 ist Schwarz unter
     *    Schwarz unsichtbar — die Z-Achse muss dort von einer HELLEREN Kante kommen. Deshalb sind
     *    diese vier Werte keine dunkleren Schatten, sondern ein Innenrand plus ein sehr weiches
     *    Aussen, das nur die Trennung zur Seitenfläche andeutet.
     */
    --bm-lift-1: inset 0 0 0 1px rgba(255, 255, 255, .04), 0 1px 2px rgba(0, 0, 0, .40);
    --bm-lift-2: inset 0 0 0 1px rgba(255, 255, 255, .06), 0 6px 14px -6px rgba(0, 0, 0, .55);
    --bm-lift-3: inset 0 0 0 1px rgba(255, 255, 255, .08), 0 14px 26px -10px rgba(0, 0, 0, .65);
    --bm-lift-4: inset 0 0 0 1px rgba(255, 255, 255, .10), 0 26px 44px -16px rgba(0, 0, 0, .72);
    --bm-lift-kachel: 0 4px 12px -2px rgba(0, 0, 0, .60);
}

/* ═══ Panel-Identität ══════════════════════════════════════════════════════════════════════ */

/*
 * DER HAKEN IST `<body class="fi-body fi-panel-{id}">`, den Filament selbst setzt. Damit ist die
 * Farbtrennung EINE Datei mit zwei Blöcken statt zwei Dateien, die auseinanderlaufen.
 *
 * ⛔ DIE TRENNUNG IST TRAGEND, nicht dekorativ: zwei Panels, die gleich aussehen, sind zwei
 *    Panels, die jemand um 23:00 verwechselt — und der verfügbare Fehler ist, das falsche
 *    Restaurant abzuschalten.
 *
 * `--bm-row-pad` ist der ganze Dichteunterschied, und er hat einen Grund je Seite: in der
 * Konsole vergleicht man Zeilen untereinander (36 px ⇒ 20 Zeilen auf 1080), im Inhaber-Panel
 * tippt man sie mit dem Daumen an, während im Haus etwas los ist (44 px).
 */
.fi-panel-operator {                     /* DIE PLATTFORM — kühl */
    --bm-ident-fg: #334155;
    --bm-ident-line: #6B7789;
    --bm-ident-bg: #E8ECF1;
    --bm-row-sel: #E8ECF1;
    --bm-row-pad: 6px;                   /* ⇒ Zeile 60 px, zweizeilige Primärspalte */
}

.fi-panel-owner {                        /* EIN HAUS — warm */
    --bm-ident-fg: #92500E;
    --bm-ident-line: #B07C22;
    --bm-ident-bg: #FBF3E4;
    --bm-row-sel: #FBF3E4;
    --bm-row-pad: 10px;                  /* ⇒ Zeile 44 px einzeilig, 68 px zweizeilig */
    --bm-hit: 44px;
}

.dark .fi-panel-operator {
    --bm-ident-fg: #9AA7B8; --bm-ident-line: #7C8798;
    --bm-ident-bg: #232A33; --bm-row-sel: #232A33;
}

.dark .fi-panel-owner {
    --bm-ident-fg: #E0A458; --bm-ident-line: #A07C36;
    --bm-ident-bg: #2B2318; --bm-row-sel: #2B2318;
}

/* ═══ Regeln ═══════════════════════════════════════════════════════════════════════════════ */

/* ── Bedienelemente sichtbar begrenzen ──────────────────────────────────────────────────────
   ⛔ ZWEI GEMESSENE VERSTÖSSE IN FILAMENTS VORGABE, und sie treffen jedes Formular des
      Produkts. Der Rahmen eines Eingabefeldes ist das Einzige, was seine Grenze zeigt:

        hell    color-mix(in oklab, var(--gray-950) 10%, transparent) ≈ #E7E8E9 → 1.23:1
        dunkel  color-mix(in oklab, var(--color-white) 20%, transparent) ≈ #414346 → 1.83:1

      WCAG 1.4.11 verlangt 3:1 für Bedienelemente. `--bm-line-strong` liefert 3.04 bzw. 3.05. */
.fi-input-wrp { --tw-ring-color: var(--bm-line-strong); }
.fi-input-wrp:not(.fi-disabled):focus-within { --tw-ring-color: var(--bm-focus); }

/* ── Ein Fokusring für alles, ohne Übergang ─────────────────────────────────────────────────
   0 ms mit Absicht: ein Fokusring, der einblendet, ist beim Durchtabben ein Nachzügler. */
.fi-body :is(a, button, [role="button"], input, select, textarea, [tabindex]):focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
    transition-duration: var(--bm-dur-0);
}

/* ── Die Gruppenüberschrift der Navigation ─────────────────────────────────────────────────
   In der Konsole ist sie die wichtigste Zeile der Seitenleiste: sie sagt, ob das Folgende die
   Plattform oder einen Kunden betrifft. */
.fi-sidebar-group-label {
    letter-spacing: .09em;
    text-transform: uppercase;
    font-size: var(--bm-t-2xs);
    font-weight: 700;
}

/* ── Die zweite Gruppe der Konsole ist ein Kunde ────────────────────────────────────────────
   ⛔ DIE LINIE IST DIE GANZE GESTALTUNG. Ab hier gehören die Daten jemand anderem.

   `nth-of-type(2)` statt einer Klasse: Filament vergibt für Navigationsgruppen keine eigene
   Kennung, und die Reihenfolge steht im Panel fest (Plattform, dann das Haus, dann dessen vier
   Regale). Bricht Filament das, verschwindet eine Linie — nicht die Bedienbarkeit.

   ⚠️ NUR IN DER KONSOLE. Das Inhaber-Panel hat diese Zweiteilung nicht; dort wäre die Linie
      eine Behauptung über eine Grenze, die es nicht gibt. */
.fi-panel-operator .fi-sidebar-nav > .fi-sidebar-group:nth-of-type(2) {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bm-line-hair);
}

.fi-panel-operator .fi-sidebar-nav > .fi-sidebar-group:nth-of-type(2) .fi-sidebar-group-label {
    color: var(--bm-ident-fg);
}

/* ── Zahlen ────────────────────────────────────────────────────────────────────────────────
   Die Flotte ist eine Spalte, die man UNTEREINANDER vergleicht. Proportionale Ziffern lassen
   «11» schmaler aussehen als «8», und genau dieser Vergleich ist der Zweck der Seite.
   `slashed-zero`, weil O und 0 in Kennungen wie `ghien-detmerode` nebeneinander vorkommen. */
.fi-ta-text,
.fi-ta-record-content,
.fi-badge,
.fi-wi-stats-overview-stat-value {
    font-variant-numeric: tabular-nums slashed-zero;
}

/* ── Der Kopfbalken «Sie arbeiten in …» ────────────────────────────────────────────────────
   Er ist kein Hinweis, er ist die Antwort auf «wessen Daten sind das». Dieselbe Identitätsfarbe
   wie die Gruppenüberschrift darunter, damit Balken und Seitenleiste als EIN Objekt gelesen
   werden.

   ⛔ DAS LAYOUT STEHT HIER UND NICHT IM BLADE. Die neun Tailwind-Klassen dort existieren nicht
      (siehe Kopf dieser Datei) — dieser Block ist das, was den Balken überhaupt zu einem Balken
      macht. Im Inhaber-Panel formatiert er zusätzlich den Support-Alarm, der bis heute
      unformatiert war. */
.fi-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    width: 100%;
    padding: .75rem 1.5rem;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-1);
    background: var(--bm-ident-bg);
    border-bottom: 1px solid var(--bm-ident-line);
}

.fi-banner strong { color: var(--bm-ident-fg); }

/* ── Tabellenzeilen ────────────────────────────────────────────────────────────────────────
   EINE Zahl trägt den Dichteunterschied, und sie steht oben bei der Panel-Identität.

   ⛔ SIE MUSS AUF `.fi-ta-text` STEHEN, NICHT AUF `.fi-ta-cell` — die Vorfassung tat das
      Zweite und bewirkte damit das GEGENTEIL ihres eigenen Kommentars. Nachgemessen an der
      Flotte, Ebene für Ebene:

        .fi-ta-cell     Filament-Vorgabe `calc(var(--spacing) * 0)` = 0
          .fi-ta-col    0
            .fi-ta-text Filament-Vorgabe `padding-block: calc(var(--spacing) * 4)` = 16/16

      Die Zelle hat von Haus aus KEIN senkrechtes Polster; die 16 px sitzen eine Ebene tiefer.
      Ein Polster auf der Zelle addiert sich also glatt zu Filaments 16 px hinzu, statt sie zu
      ersetzen: die Zeile wurde 99 px hoch, während daneben stand, das mache sie dicht.

   Die Rechnung, die jetzt gilt (Konsole, `--bm-row-pad: 6px`):

        6 + 6 (Text-Polster) + 24 (Name) + 4 (Lücke) + 20 (Rechnername) = 60 px

   ⚠️ 36 px sind mit dieser Tabelle nicht erreichbar, und das ist eine Entscheidung, keine
      Nachlässigkeit: der Wert stammte aus einer EINZEILIGEN Zelle. Die erste Spalte der Flotte
      trägt Name UND Rechnername — bei zwei Filialen desselben Hauses ist der Rechnername das
      einzige, was «Ghien Wok Detmerode» von «Ghien Wok Fallersleben» unterscheidet. Selbst bei
      Polster 0 blieben 48 px. 99 → 60 ist der ehrliche Gewinn (−39 %, aus 8 sichtbaren Zeilen
      auf 1080 px werden 12); die Information bleibt stehen. */
.fi-ta-row .fi-ta-text,
.fi-ta-row .fi-ta-actions {
    padding-block: var(--bm-row-pad);
}

/* Der Kopf trägt eine Zeile, nie zwei — er darf enger sein als der Körper (Vorgabe 14 px). */
.fi-ta-header-cell {
    padding-block: var(--bm-head-pad);
}

/* ── Grobe Zeiger ──────────────────────────────────────────────────────────────────────────
   Ein Tablet an der Theke, im Stehen, einhändig. Gilt für BEIDE Panels: die Konsole wird auch
   einmal auf einem Tablet geöffnet, und dann ist 36 px zu wenig.

   ⛔ AUF DEN PANEL-KLASSEN, NICHT AUF `:root` — die Vorfassung schrieb hierher `:root`, und das
      war eine tote Regel. `:root` ist <html>; `--bm-row-pad` wird aber eine Ebene tiefer auf
      `<body class="fi-panel-…">` neu gesetzt, und die eigene Deklaration des Körpers gewinnt für
      alles darin. Im Browser nachgemessen, indem der Wert auf <html> gesetzt wurde:

        html 13px   ·   body 9px   ·   Tabellenzelle 9px

      Die Medienabfrage hat die Tabelle nie erreicht. `--bm-hit` wäre durchgekommen, weil das
      Operator-Panel es nicht selbst deklariert — genau diese Halbwirkung macht solche Regeln so
      schwer zu bemerken. */
@media (pointer: coarse) {
    .fi-panel-operator,
    .fi-panel-owner {
        --bm-hit: 44px;
        --bm-row-pad: 10px;
    }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
 * DAS GEHÄUSE — Kopfleiste und Navigation werden EINE eingefärbte Fläche, die Arbeit liegt hell
 * darin. Ab hier sieht man auf einen Blick, in welchem Panel man ist.
 *
 * WARUM DAS NÖTIG WAR. Alles über dieser Zeile ist Substanz: Grau-Rampe, Radien, Zeilenhöhe,
 * Trefferflächen, Zustandsfarben. Richtig — und unsichtbar, weil keine einzige dieser Zahlen
 * eine FLÄCHE anfasst. Die Form der Seite war bis hier unverändert Filaments Vorgabe: eine
 * 320 px breite weisse Navigation neben einem weissen Inhalt, darüber eine weisse Kopfleiste,
 * getrennt durch nichts als einen 5 % starken Ring. Drei gleich helle Felder, die um dieselbe
 * Aufmerksamkeit konkurrieren — und die Tabelle, das eigentliche Werkzeug, verliert diesen
 * Wettbewerb bei jedem Seitenaufruf.
 *
 * Ab hier gibt es ZWEI MATERIALIEN: das Gehäuse (Kopfleiste + Schiene, ein durchgehendes L in
 * der Farbe des Panels) und die Arbeitsfläche darin. Man sucht nicht mehr, wo die Seite
 * anfängt — und die Panel-Identität hat endlich eine Fläche statt eines Wortes.
 *
 * ⛔ DAS EINE RISIKO, UND ES HAT GENAU DIESEN ORT: Filament rendert Kopfleiste und Schiene für
 *    einen WEISSEN Grund. Jedes Bedienelement darin, das ich nicht ausdrücklich umfärbe, behält
 *    seine Vorgabe `--gray-500` (#6B7683) und stünde auf dem Gehäuse bei 2.6:1 — unter jeder
 *    Schwelle, und niemand bekäme es gesagt.
 *
 *    Die Absicherung ist keine Liste, sondern eine Vererbung: `.fi-topbar` und `.fi-sidebar`
 *    setzen selbst ein helles `color`. Alles, was keine eigene Farbe mitbringt, ist damit von
 *    sich aus richtig; umgefärbt werden muss nur, was eine EIGENE Farbe deklariert. Das sind
 *    heute genau vier Dinge, alle vier in den Abzügen nachgezählt: die Marke, die
 *    Symbolknöpfe, der Themenumschalter, die Navigationsbeschriftungen. Was bleibt: wer morgen
 *    ein fünftes Element mit eigener Farbe in die Kopfleiste hängt, muss es hier eintragen.
 *
 * MESSGRUNDLAGE. Jede Zahl unten ist entweder aus dem ausgelieferten
 * `public/css/filament/filament/app.css` (Filament 5.7.5, 613 kB) abgelesen oder nach WCAG 2.x
 * in sRGB gerechnet; die Struktur stammt aus den echten Abzügen `public/_view-*.html` — drei
 * davon Konsole (`fi-panel-operator`), zwei Inhaber-Panel (`fi-panel-owner`). Wo unten «gemessen»
 * steht, steht die Fundstelle dabei.
 *
 * ⛔ REIHENFOLGE IST TRAGEND: dieser Block gehört ans DATEIENDE. Er ergänzt die Tokenschicht
 *    oben und korrigiert an zwei Stellen ihre Werte (`--bm-head-pad`, `--bm-head-h`) — weiter
 *    oben eingefügt wären die alten Werte die späteren, und der ganze Block wäre wieder
 *    unsichtbar. Er bleibt ungeschichtet und ohne `!important`: `app.css` besteht restlos aus
 *    `@layer properties/theme/base/components/utilities`, ungeschichtetes CSS schlägt das
 *    unabhängig von Spezifität UND Ladereihenfolge.
 * ═══════════════════════════════════════════════════════════════════════════════════════════ */


/* ═══ 1 · Die Breite der Schiene ═══════════════════════════════════════════════════════════ */

/*
 * 20 rem = 320 px ist Filaments Vorgabe für Anwendungen mit langen Menütexten. Das längste
 * Etikett im Produkt ist «Reservierung einrichten» (Inhaber-Panel, 23 Zeichen, im Abzug
 * `_view-gerichte.html` nachgezählt); bei 13 px Inter sind das rund 143 px.
 *
 * Bei 244 px bleiben dafür: 244 − 8 (Polster der Liste) − 10 (Polster im Knopf) − 18 (Symbol)
 * − 10 (Lücke) − 8 (Knopf) − 8 (Liste) − 15 (`scrollbar-gutter: stable`, das Filament auf
 * `.fi-sidebar-nav` setzt) = 167 px Textbreite. Es passt, und 76 px gehen an den Inhalt.
 *
 * ⛔ `html:root` UND NICHT `:root` — dieselbe Messung wie oben bei der Grau-Rampe, hier erneut
 *    nachgeschlagen in `_view-flotte.html`:
 *
 *        Byte 1038   der <link> auf panel-ui.css                       ← diese Datei
 *        Byte 4913   `--sidebar-width: 20rem` in Filaments Inline-<style>, DANACH
 *                    (im selben Block: `--default-theme-mode: system`)
 *
 *    Zwei ungeschichtete `:root` gleicher Spezifität: der SPÄTERE gewänne. `html:root` hat
 *    0,1,1 gegen 0,1,0 und gewinnt unabhängig von der Position.
 *
 *    ⚠️ Der Verbraucher existiert und ist einer:
 *       `.fi-body:not(…top-navigation):not(…collapsible…):not(…fully-collapsible…)
 *        .fi-sidebar:not(.fi-sidebar-open) { width: var(--sidebar-width) }`.
 *       Der Körper im Abzug trägt `fi-body fi-panel-operator fi-body-has-navigation
 *       fi-body-has-topbar` — keine der drei ausgeschlossenen Klassen. Die Regel greift.
 */
html:root {
    --sidebar-width: 15.25rem;           /* 244 px */
}


/* ═══ 2 · Masse des Gehäuses ═══════════════════════════════════════════════════════════════ */

/*
 * ⚠️ ZWEI KORREKTUREN AN DER TOKENSCHICHT OBEN, und beide betreffen Tokens, die dort deklariert
 *    und NIRGENDS gelesen wurden (`grep 'var(--bm-head-h)'` → 0 Treffer, `var(--bm-hit)` → 0
 *    Treffer in der Datei über dieser Zeile). Ab hier haben beide einen Verbraucher:
 *
 *      --bm-head-h    trägt die Höhe der Kopfzeile UND die Trefferfläche des Sortierknopfes.
 *                     Das war der stillste Verstoss im Produkt: `.fi-ta-header-cell-sort-btn`
 *                     hat bei Filament `padding: 0` und `width: 100%`, seine Höhe ist also die
 *                     Zeilenhöhe des Textes — rund 20 px. Sortieren ist das Verb der Flotte
 *                     («wer ist noch nicht live»), und sein Ziel war halb so hoch wie erlaubt.
 *
 *      --bm-head-pad  geht auf 0, weil die Höhe jetzt aus `--bm-head-h` kommt. Die Regel
 *                     `.fi-ta-header-cell { padding-block: var(--bm-head-pad) }` weiter oben
 *                     BLEIBT gültig und liefert jetzt 0 — kein zweiter Wert, der mit dem
 *                     ersten streitet, keine tote Zeile.
 *
 * ⛔ HIER WERDEN `--bm-row-pad` UND `--bm-hit` ABSICHTLICH NICHT ANGEFASST. Beide werden weiter
 *    oben in `@media (pointer: coarse)` auf den Panel-Klassen neu gesetzt; würde ich sie hier
 *    auf denselben Klassen erneut deklarieren, gewönne meine spätere Zeile und die
 *    Grob-Zeiger-Regel wäre still tot. Genau diese Halbwirkung ist in dieser Datei schon
 *    einmal dokumentiert worden.
 */
:root {
    --bm-topbar-h: 52px;                 /* war 64: die Kopfleiste trägt eine Zeile, nie zwei */
    --bm-rail-pad: 8px;                  /* Polster der Navigationsliste */
    --bm-rail-item-pad: 10px;            /* Polster im Menüknopf */
    --bm-rail-icon: 18px;                /* Symbolgrösse in der Schiene */
    --bm-head-pad: 0px;                  /* ⚠️ ersetzt die 8 px oben — Höhe kommt aus --bm-head-h */
    --bm-head-h: 36px;
}

.fi-panel-owner {
    --bm-topbar-h: 56px;                 /* 4 px mehr: hier trifft ein Daumen, kein Zeiger */
    --bm-head-h: 44px;
    --bm-rail-icon: 20px;
}

@media (pointer: coarse) {
    .fi-panel-operator,
    .fi-panel-owner {
        --bm-topbar-h: 56px;
        --bm-head-h: 44px;
        --bm-rail-icon: 20px;
    }
}


/* ═══ 3 · Die Farben des Gehäuses ══════════════════════════════════════════════════════════ */

/*
 * ⛔ WARUM EIGENE `--bm-rail-*`-TOKENS UND NICHT `--bm-ident-*`. Die Identitätsfarben oben sind
 *    für HELLE Flächen gerechnet und dort richtig: #334155 auf Weiss = 10.35:1, #92500E auf
 *    Weiss = 6.22:1. Auf dem hellen Gehäuse stünde #334155 bei rund 1.5:1 — unbrauchbar. Ein
 *    Gehäuse braucht eine eigene Skala, sonst wird aus «wir haben ja Tokens» eine Zeile, die
 *    nichts kann. `--bm-ident-*` bleibt unangetastet und färbt weiter den Balken «Sie arbeiten
 *    in …» und die Auswahlzeile.
 *
 * HELL — das Gehäuse ist die dunkelste Fläche des Bildschirms (alle Werte gerechnet):
 *
 *      Konsole   Gehäuse #141A22 gegen Seite #F6F7F9        16.32:1   ← der Materialwechsel
 *                Beschriftung ruhend #C6D0DA                11.19:1
 *                Symbole, Meta       #8C99A8                 6.03:1
 *                Marke, Identität    #7FB2EA                 7.88:1
 *                aktive Beschriftung #F2F5F8 auf #22303F     12.28:1
 *      Inhaber   Gehäuse #211A12 gegen Seite                 16.04:1
 *                Beschriftung ruhend #DCD2C4                11.51:1
 *                Symbole, Meta       #A3937E                 5.76:1
 *                Marke, Identität    #EDB265                 9.14:1
 *                aktive Beschriftung #F8F3EC auf #3A2C1B     12.23:1
 *
 * DUNKEL — und hier kehrt sich die Ordnung um, mit Absicht und mit einer Rechnung dahinter.
 *
 * ⛔ IM DUNKELN KANN DAS GEHÄUSE NICHT DIE DUNKELSTE FLÄCHE SEIN. Die Seite ist dort bereits
 *    #0E0F11; ein noch dunkleres Gehäuse (#07090C) steht bei 1.04:1 gegen sie — das ist kein
 *    Material, das ist ein Gerücht. Also wird das Gehäuse im Dunkelmodus die ANGEHOBENE Fläche,
 *    wie in jedem ernsthaften dunklen Werkzeug:
 *
 *      Konsole   Gehäuse #202833 gegen Seite #0E0F11          1.29:1
 *                                gegen Karte #141618          1.22:1
 *      Inhaber   Gehäuse #2F2517 gegen Seite                   1.28:1
 *                                gegen Karte                   1.21:1
 *
 *    Zum Vergleich, aus Filaments eigener dunkler Palette gerechnet: die KARTE steht dort bei
 *    1.06:1 gegen die Seite. Das Gehäuse trägt damit mehr Flächenunterschied als jedes andere
 *    Paar im Dunkelmodus — es ist im Dunkeln sichtbarer als die Karte, die niemand für
 *    unsichtbar hält. Dazu kommt die Kante (#3A4553 gegen die Seite 1.97:1).
 *
 *    Die Umkehr ist kein Bruch: das Gehäuse ist in BEIDEN Modi das andere Material. Im Hellen
 *    sinkt es in die Tinte, im Dunkeln hebt es sich heraus. Was konstant bleibt, ist die Regel
 *    «Gehäuse ≠ Seite», und sie ist in beiden Modi eine Zahl, keine Behauptung.
 *
 *      Konsole dunkel   Beschriftung #C3CDD8  9.23:1   Symbole #909CAA  5.32:1
 *                       Marke        #8FBAEE  7.38:1   aktiv   #F2F5F8 13.58:1
 *      Inhaber dunkel   Beschriftung #DBD1C3  9.96:1   Symbole #A99A85  5.47:1
 *                       Marke        #EDB265  7.98:1   aktiv   #F8F3EC 13.61:1
 *
 * ⚠️ EHRLICH GERECHNET: die Auswahlfläche des aktiven Eintrags steht nur 1.30:1 (Konsole) bzw.
 *    1.27:1 (Inhaber) gegen das Gehäuse. Das ist ZU WENIG für einen Zustand — und deshalb trägt
 *    sie ihn nicht. Der aktive Eintrag hat drei Signale: `aria-current="page"` (Filament setzt
 *    es, im Abzug nachgesehen), die 3-px-Marke in Identitätsfarbe an der Gehäusekante (7.88 /
 *    9.14:1 hell, 5.83 / 6.26:1 dunkel — WCAG 1.4.11 verlangt 3:1) und Schriftschnitt 600 gegen
 *    500. Im Graustufenausdruck bleiben Marke und Schnitt übrig. Die Fläche ist Komfort.
 */
/*
 * ⛔ DAS DUNKLE GEHÄUSE IST ZURÜCKGENOMMEN — auf ausdrücklichen Wunsch, in BEIDEN Panels.
 *
 *    Die Schiene und die Kopfleiste waren eine eingefärbte L-Fläche (Konsole kühles Schiefer,
 *    Inhaber warmes Braun). Sie war auf den ersten Blick anders — und genau darum ging es —,
 *    aber der Auftraggeber will EINE Fläche, und das ist seine Entscheidung, nicht meine.
 *
 * WAS BLEIBT, weil es nie an der Farbe hing: die 244 px schmale Schiene statt 320, die
 * 52/56 px flache Kopfleiste statt 64, die Marke in Identitätsfarbe, die 3-px-Marke am aktiven
 * Eintrag, Schriftschnitt 600 gegen 500, die Gruppenüberschriften, die Symbolgrössen und der
 * ganze Tabellenteil. Es fällt nur die Einfärbung.
 *
 * WIE, technisch: die Regeln unten lesen `--bm-rail-*`, also genügt es, die Tokens auf die
 * hellen Flächen zu zeigen. Kein Selektor wird angefasst, kein `!important` nötig, und die
 * Rücknahme ist ein Block statt zwanzig verstreuter Änderungen.
 *
 * ⚠️ DIE IDENTITÄTSFARBE BLEIBT DAS EINZIGE PANEL-SIGNAL. Ohne die Flächen unterscheiden sich
 *    Konsole und Inhaber-Panel nur noch an Marke und aktiver Marke — kühles Blau gegen warmes
 *    Bernstein. Das ist weniger als vorher, und wer um 23:00 das falsche Restaurant abschaltet,
 *    hat ab hier ein Signal weniger. Bewusst so entschieden, nicht übersehen.
 */
.fi-panel-operator,
.fi-panel-owner {
    --bm-rail-bg: var(--bm-srf-1);
    --bm-rail-line: var(--bm-line-hair);
    --bm-rail-txt-1: var(--bm-txt-1);
    --bm-rail-txt-2: var(--bm-txt-2);
    --bm-rail-txt-3: var(--bm-txt-3);
    --bm-rail-hover: var(--bm-srf-0);
    --bm-rail-sel: var(--bm-ident-bg);
}

/* Die Marke und die aktive Marke behalten die Panel-Temperatur — sie sind jetzt das einzige,
   was die beiden Panels auf einen Blick trennt. */
.fi-panel-operator {
    --bm-rail-ident: #334155;            /* kühles Schiefer, 9.14:1 auf Weiss */
}

.fi-panel-owner {
    --bm-rail-ident: #92500E;            /* warmes Bernstein, 7.88:1 auf Weiss */
}

/* ⛔ `.dark` liegt auf <html>, `fi-panel-*` auf <body> — die Verschachtelung stimmt, im Abzug
      geprüft. Im Dunkelmodus ziehen die Tokens dieselben Flächen wie der Rest des Panels; die
      Identitätsfarbe wird aufgehellt, weil #334155 auf einer dunklen Fläche 1.4:1 hätte. */
.dark .fi-panel-operator {
    --bm-rail-ident: #8FBAEE;
}

.dark .fi-panel-owner {
    --bm-rail-ident: #EDB265;
}


/* ═══ 4 · Das L: Kopfleiste und Schiene sind EINE Fläche ═══════════════════════════════════ */

/*
 * ⛔ WARUM DIE GANZE KOPFLEISTE UND NICHT NUR IHR LINKER STREIFEN. Der naheliegende Weg wäre,
 *    nur die ersten `--sidebar-width` der Kopfleiste einzufärben, damit die Schiene optisch in
 *    der Bildschirmecke beginnt. Dieser Weg ist geprüft und verworfen, aus drei Gründen, die
 *    alle im ausgelieferten Code stehen:
 *
 *      1. Er rechnet auf `--sidebar-width`. Schaltet jemand `sidebarCollapsibleOnDesktop()`
 *         ein, gilt `--collapsed-sidebar-width`, und neben einer schmalen Schiene stünde ein
 *         breiter dunkler Klotz — oben links, auf dem ersten Bildschirm, den ein Kunde sieht.
 *      2. Er behauptet eine Bildschirmecke, die es im Normalbetrieb der Konsole nicht gibt:
 *         `OperatorPanelProvider.php:304` hängt `working-in.blade.php` an
 *         `PanelsRenderHook::BODY_START`, und das Blade rendert `@if (tenant())` — also auf
 *         JEDER Konsolenseite, auf der ein Restaurant geöffnet ist, ein volle Breite hohes
 *         `.fi-banner` ÜBER der Kopfleiste. Im Inhaber-Panel tut `support-banner.blade.php`
 *         (OwnerPanelProvider.php:190) dasselbe während eines Supportbesuchs.
 *         ⚠️ Die fünf Abzüge zeigen diesen Zustand NICHT (`fi-banner`-Zähler: 0 in allen
 *            fünf) — sie wurden ohne geöffnetes Restaurant aufgenommen. Wer nur sie ansieht,
 *            hält den Sonderfall für den Normalfall.
 *      3. Er braucht eine Ausnahmekette und eine Erklärung. Diese Lösung braucht keine.
 *
 *    Die volle Kopfleiste hat keine dieser Abhängigkeiten: sie ist immer so breit wie der
 *    Bildschirm, und wenn ein Balken darüber steht, ist der Balken eben der obere Rand — er
 *    soll auffallen, das ist sein Zweck.
 *
 * ⛔ DIE 4rem SIND BEI FILAMENT HART VERDRAHTET, und ohne diese Korrektur klafft ein Spalt.
 *    Nachgeschlagen in app.css:
 *
 *        @media (min-width: 64rem) {
 *            .fi-body-has-topbar .fi-sidebar { height: calc(100dvh - 4rem); top: 4rem }
 *        }
 *
 *    Die Schiene ist dort `position: sticky`. Mit einer 52 px hohen Kopfleiste beginnt ihr
 *    Haftrechteck 12 px zu tief: zwischen Kopfleiste und Schiene stünde beim Scrollen ein
 *    12 px hoher Streifen Seitenfläche über die ganze Schienenbreite, und unten fehlten
 *    dieselben 12 px. Ein Fehler, den man nur beim Scrollen sieht und deshalb erst nach dem
 *    Ausliefern findet.
 *
 *    ⚠️ Nachgesehen, ob es eine ZWEITE Stelle gibt: `.fi-main-ctn { min-height: calc(100dvh -
 *       4rem) }` existiert, gilt aber nur für `.fi-body-has-top-navigation`,
 *       `:not(.fi-body-has-navigation)` und die einklappbaren Varianten. Unser Körper ist
 *       keine davon. Es bleibt bei dieser einen Korrektur.
 */
/*
 * ⛔ BEIM ROLLEN FUHR DER SEITENKOPF ÜBER DIE KOPFLEISTE. Der Knopf «Telefonisch aufnehmen»
 *    stand dann auf der Glocke und dem Benutzerbild — beide noch sichtbar, also lag es nicht
 *    am Hintergrund, sondern an der Stapelreihenfolge: die Leiste klebt oben, ohne über dem
 *    Inhalt zu liegen. Am Abzug gesehen; im Editor sieht man so etwas nie.
 */
.fi-topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    min-height: var(--bm-topbar-h);
    padding-inline-start: var(--bm-rail-pad);
    background-color: var(--bm-rail-bg);
    border-bottom: 1px solid var(--bm-rail-line);
    color: var(--bm-rail-txt-2);         /* ⛔ die Absicherung: alles ohne eigene Farbe erbt hell */
    box-shadow: none;                    /* löscht Filaments Schlagschatten UND Ring in einer Zeile */
}

.fi-sidebar {
    background-color: var(--bm-rail-bg);
    border-inline-end: 1px solid var(--bm-rail-line);
    color: var(--bm-rail-txt-2);
}

@media (min-width: 64rem) {
    .fi-body-has-topbar .fi-sidebar {
        top: var(--bm-topbar-h);
        height: calc(100dvh - var(--bm-topbar-h));
    }
}

/* Unter 64 rem ist die Schiene eine eingeschobene Schublade und Filament blendet die Kopfleiste
   der Schublade NICHT aus (`.fi-body-has-topbar .fi-sidebar-header { display: none }` steht bei
   Filament in `@media (min-width: 64rem)`). Dort trägt dieser Kopf die Marke — dieselbe Fläche,
   dieselbe Höhe, damit die Schublade wie das abgeschnittene Gehäuse aussieht. */
.fi-sidebar-header {
    height: var(--bm-topbar-h);
    justify-content: flex-start;
    padding-inline: calc(var(--bm-rail-pad) + var(--bm-rail-item-pad));
    background-color: var(--bm-rail-bg);
    border-bottom: 1px solid var(--bm-rail-line);
    box-shadow: none;
}

/*
 * DIE MARKE. 20 px fett ist ein Produktname auf einer Landingpage; 15 px/600 ist ein
 * Anlagenschild. Im Inhaber-Panel ist dieser Text der RESTAURANTNAME — er muss kürzbar sein,
 * sonst bricht er in der 244-px-Schublade um. Er steht in der Identitätsfarbe: der Name des
 * Hauses in der Farbe des Hauses, an der Stelle, auf die das Auge zuerst fällt.
 *
 * ⚠️ `:not(.fi-logo-light):not(.fi-logo-dark)` ist Pflicht, sobald `display` gesetzt wird:
 *    Filament schaltet Bildlogos für Hell/Dunkel über
 *    `.fi-logo.fi-logo-light:where(.dark,.dark *), .fi-logo.fi-logo-dark { display: none }`.
 *    Ein ungeschichtetes `display: block` ohne diesen Riegel zeigte BEIDE Logos, sobald jemand
 *    ein Bildlogo hinterlegt. Heute steht dort Text, morgen vielleicht nicht.
 *
 * ⚠️ Nur in Kopfleiste und Schubladenkopf. `.fi-logo` steht auch im `.fi-simple-header` der
 *    Anmeldeseite — dort auf HELLEM Grund, eine gehäusehelle Marke wäre dort unsichtbar.
 *
 * Die 10 px sind gerechnet, nicht geraten: Filament setzt `.fi-topbar-start .fi-logo
 * { margin-inline-start: 12px }`, die Kopfleiste bekommt oben 8 px Polster ⇒ Marke bei x = 18.
 * Die Symbolspalte der Schiene liegt bei 8 (Polster der Liste) + 10 (Polster im Knopf) = 18.
 * Marke, Symbole und Gruppenüberschriften stehen damit auf einer Senkrechten.
 */
:is(.fi-topbar-start, .fi-sidebar-header) .fi-logo:not(.fi-logo-light):not(.fi-logo-dark) {
    display: block;
    max-width: calc(var(--sidebar-width) - 2rem);
    margin-inline-start: var(--bm-rail-item-pad);
    overflow: hidden;
    font-size: 15px;
    line-height: 20px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--bm-rail-ident);
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Die vier Elemente mit EIGENER Farbe, die die Vererbung oben deshalb nicht erreicht. */
:is(.fi-topbar, .fi-sidebar) .fi-icon-btn {
    color: var(--bm-rail-txt-3);
}

:is(.fi-topbar, .fi-sidebar) .fi-icon-btn:hover {
    color: var(--bm-rail-txt-1);
}

.fi-topbar .fi-theme-switcher-btn:not(.fi-active) {
    color: var(--bm-rail-txt-3);
}

.fi-topbar .fi-theme-switcher-btn.fi-active {
    color: var(--bm-rail-ident);
    background-color: var(--bm-rail-sel);
}

.fi-topbar .fi-theme-switcher-btn:focus-visible {
    background-color: var(--bm-rail-hover);
}

@media (hover: hover) {
    .fi-topbar .fi-theme-switcher-btn:hover {
        background-color: var(--bm-rail-hover);
    }
}

/* Der Knopf, der die Schublade öffnet, ist am Tablet der einzige Weg in die Navigation — und er
   ist bei Filament 36 px (`.fi-icon-btn { width: calc(var(--spacing) * 9) }`). Im Stehen, mit
   dem Daumen, ist das zu klein.
   ⚠️ `width`/`height` und nicht `min-*`: `.fi-icon-btn` zentriert sein Symbol über feste Masse
      und trägt `margin: -8px`; ein Mindestmass liesse die Box wachsen, ohne dass der negative
      Aussenabstand mitrechnet. Waagerecht ist der bei diesen beiden Knöpfen von Filament ohnehin
      mit `!important` auf 0 gesetzt, senkrecht bleibt er und zentriert weiter. */
@media (pointer: coarse) {
    .fi-topbar-open-sidebar-btn,
    .fi-topbar-close-sidebar-btn {
        width: var(--bm-hit);
        height: var(--bm-hit);
    }
}


/* ═══ 5 · Die Navigation ═══════════════════════════════════════════════════════════════════ */

/*
 * Filament: Polster 24/32, Gruppenabstand 28 px, Symbole 24 px. Das ist die Rasterung einer
 * Anwendung mit sechs Menüpunkten. Das Inhaber-Panel hat neun Einträge in fünf Gruppen (im
 * Abzug `_view-gerichte.html` gezählt), die Konsole mit geöffnetem Restaurant deren Gruppen
 * zusätzlich zu ihren eigenen.
 *
 * ⛔ DER GRUPPENABSTAND SITZT NICHT AUF `.fi-sidebar-nav`. Er steht bei Filament auf
 *    `.fi-sidebar-nav-groups { row-gap: calc(var(--spacing) * 7) }` — das `<ul>`, das das
 *    einzige Kind des `<nav>` ist. Ein `row-gap` auf dem `<nav>` wäre eine tote Zeile, die
 *    aussieht, als täte sie etwas. Im Abzug nachgesehen: `nav.fi-sidebar-nav >
 *    ul.fi-sidebar-nav-groups > li.fi-sidebar-group`.
 */
.fi-sidebar-nav {
    padding-inline: var(--bm-rail-pad);
    padding-block: 10px;
}

.fi-sidebar-nav-groups {
    margin-inline: 0;                    /* Filament: -8px — sonst läge die Marke unten falsch */
    row-gap: 14px;                       /* Filament: 28px */
}

.fi-sidebar-group-items {
    row-gap: 2px;
}

/*
 * DIE GRUPPENÜBERSCHRIFT BEKOMMT HIER NUR FARBE. Grossbuchstaben, Laufweite, 11 px und 700
 * stehen weiter oben in dieser Datei und bleiben, wo sie sind. Ohne diese Zeile bliebe
 * Filaments `--gray-500` (#6B7683) stehen: 2.6:1 auf dem hellen Gehäuse, also Text weit unter
 * jeder Schwelle. `--bm-rail-txt-3` liefert 6.03:1 (Konsole) bzw. 5.76:1 (Inhaber).
 *
 * ⛔ SIE BEKOMMT AUSDRÜCKLICH NICHT DIE IDENTITÄTSFARBE, und das ist eine Korrektur an einer
 *    naheliegenden Idee. In der Konsole ist die zweite Gruppenüberschrift der RESTAURANTNAME:
 *    `ConsoleGroup.php:47` gibt `tenant()?->operatorLabel()` zurück. Wären alle
 *    Gruppenüberschriften identitätsfarbig, stünden «PLATTFORM» und «GHIEN WOK & SUSHIBAR» in
 *    exakt derselben Auszeichnung — und die einzige gesättigte Farbe des Panels beantwortete
 *    «in welchem Panel bin ich» (einmal pro Anmeldung) statt «wessen Daten sind das»
 *    (dutzendfach pro Stunde). Die zweite Frage beantwortet der Balken oben, und er tut es
 *    besser, weil er den Namen ausschreibt.
 *
 * ⚠️ ZUR REGEL «Die zweite Gruppe der Konsole ist ein Kunde» (weiter oben, Zeile 293 ff.):
 *    sie trifft nachweislich NICHTS. Ihr Kindkombinator `.fi-sidebar-nav > .fi-sidebar-group`
 *    springt eine Ebene zu kurz — dazwischen liegt `ul.fi-sidebar-nav-groups`. Ich belebe sie
 *    NICHT wieder, und zwar nicht aus Bequemlichkeit: ohne geöffnetes Restaurant hat die
 *    Konsole zwei Gruppen (eine namenlose und «Plattform»), `nth-of-type(2)` wäre dort die
 *    PLATTFORM — die Linie behauptete eine Kundengrenze, wo keine ist. Die Regel bräuchte eine
 *    Bedingung, die CSS nicht hat. Wer sie doch reparieren will, braucht
 *    `.fi-sidebar-nav-groups > .fi-sidebar-group:nth-of-type(2)` UND eine Körperklasse, die
 *    sagt, ob ein Restaurant offen ist.
 */
.fi-sidebar-group-label {
    color: var(--bm-rail-txt-3);
    line-height: 16px;
}

.fi-sidebar-group-btn {
    padding: 6px var(--bm-rail-item-pad);
    column-gap: 8px;
}

/*
 * ⛔ DIE GRUPPENZEILE BLEIBT EIN GROSSES ZIEL. Filament macht sie zum Einklapp-Schalter
 *    (`.fi-sidebar-group.fi-collapsible > .fi-sidebar-group-btn { cursor: pointer }`, und die
 *    Gruppen im Abzug tragen wirklich `fi-sidebar-group fi-collapsible`). Ein 24 px hohes Ziel
 *    zwei Pixel über einem 44 px hohen Ziel heisst am Tablet: der Daumen faltet «Täglich» zu,
 *    Bestellungen und Reservierungen verschwinden, und Filament merkt sich den Zustand. Deshalb
 *    trägt sie dieselbe Trefferfläche wie ein Menüpunkt.
 */
.fi-sidebar-group.fi-collapsible > .fi-sidebar-group-btn {
    min-height: var(--bm-hit);
}

/* `--bm-hit` ist 36 px in der Konsole (Maus), 44 px im Inhaber-Panel und auf jedem groben
   Zeiger. Der Wert wird hier zum ersten Mal in dieser Datei GELESEN — bis hierher war er
   dreimal deklariert und nirgends benutzt.
   ⚠️ Die Übergangsdauer wird bewusst NICHT angefasst: Filament hat auf `.fi-sidebar-item-btn`
      bereits `--tw-duration: 75ms`. Ein Wert von 120 ms wäre nicht «Rückmeldung statt
      Nachziehen», sondern 60 % LANGSAMER als heute. */
.fi-sidebar-item-btn {
    min-height: var(--bm-hit);
    justify-content: flex-start;
    padding: 6px var(--bm-rail-item-pad);
    column-gap: var(--bm-rail-item-pad);
    border-radius: var(--radius-md);
}

/* ⚠️ `.fi-sidebar-item-icon` hat in app.css KEINE eigene Regel (0 Treffer); die 24 px kommen
      aus `.fi-icon.fi-size-lg` mit Spezifität 0,2,0. Diese Regel hat 0,1,0 und gewinnt
      trotzdem — ungeschichtet schlägt `@layer`, unabhängig von Spezifität. */
.fi-sidebar-item-icon {
    width: var(--bm-rail-icon);
    height: var(--bm-rail-icon);
}

.fi-sidebar-item-btn > .fi-icon {
    color: var(--bm-rail-txt-3);
}

.fi-sidebar-item-label {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 500;
    color: var(--bm-rail-txt-2);
}

/*
 * ⛔ EINTRÄGE OHNE SYMBOL UND IHRE VERBINDUNGSLINIE — hier steckt ein Geometriefehler, den man
 *    erst sieht, wenn man das Symbol verkleinert hat.
 *
 *    Filament rendert symbollose Untereinträge (in der Konsole «Restaurants» und «Protokoll»)
 *    mit einem 24 px breiten Punkt-Platzhalter und zieht die Verbindungslinie über
 *    `-part-not-first { top: -50%; bottom: 50% }` bzw. `-part-not-last { top: 50%;
 *    bottom: -50% }`. Diese Prozente rechnen auf die HÖHE DES PLATZHALTERS. Die Linie reicht
 *    also genau eine halbe Platzhalterhöhe über die Box hinaus, und die zu überbrückende Lücke
 *    ist (Knopfhöhe + Zeilenabstand − Platzhalterhöhe) / 2:
 *
 *        Filament   (40 + 4 − 24) / 2 = 10   Reichweite 12   ⇒ durchgehend
 *        nur Box 18 (36 + 2 − 18) / 2 = 10   Reichweite  9   ⇒ 1 px Bruch (Konsole)
 *                   (44 + 2 − 18) / 2 = 14   Reichweite  9   ⇒ 5 px Bruch (Theke)
 *
 *    Die Linie risse also genau dort, wo sie etwas erklärt. `-100%` statt `-50%` verdoppelt die
 *    Reichweite auf 18 bzw. 20 px und deckt beide Fälle mit Reserve; der Überstand liegt unter
 *    dem Nachbarpunkt, wo ohnehin gezeichnet wird, und der erste Eintrag einer Gruppe hat kein
 *    `-not-first`, oben ragt also nichts ins Leere.
 */
.fi-sidebar-item-grouped-border {
    width: var(--bm-rail-icon);
    height: var(--bm-rail-icon);
}

.fi-sidebar-item-grouped-border-part {
    background-color: var(--bm-rail-txt-3);
}

.fi-sidebar-item-grouped-border-part-not-first {
    top: -100%;
    background-color: var(--bm-rail-line);
}

.fi-sidebar-item-grouped-border-part-not-last {
    bottom: -100%;
    background-color: var(--bm-rail-line);
}

@media (hover: hover) {
    .fi-sidebar-item.fi-sidebar-item-has-url > .fi-sidebar-item-btn:hover {
        background-color: var(--bm-rail-hover);
    }
}

.fi-sidebar-item.fi-sidebar-item-has-url > .fi-sidebar-item-btn:focus-visible {
    background-color: var(--bm-rail-hover);
}

.fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: var(--bm-rail-sel);
}

.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-sidebar-item-label {
    font-weight: 600;
    color: var(--bm-rail-txt-1);
}

/*
 * ⛔ ZWEI GETRENNTE REGELN, UND DAS IST DER GANZE PUNKT. Fasst man Symbol und Punkt-Platzhalter
 *    in EINE Selektorliste, bekommen BEIDE beide Deklarationen — das Symbol ist ein <svg> mit
 *    `fill: none; stroke: currentColor` und würde als 18x18 px grosse VOLLFLÄCHE in der
 *    Identitätsfarbe erscheinen, mit dem Strich des Glyphs in derselben Farbe darauf. Der
 *    aktive Menüpunkt zeigte dann einen farbigen Klotz statt eines Symbols, auf jeder Seite,
 *    an der Stelle, auf die das Auge zuerst fällt. `color` gehört zum Symbol,
 *    `background-color` gehört zum Punkt.
 */
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-icon {
    color: var(--bm-rail-ident);
}

.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-sidebar-item-grouped-border > .fi-sidebar-item-grouped-border-part {
    background-color: var(--bm-rail-ident);
}

/*
 * Die Marke an der Gehäusekante. `-8px` ist exakt das Polster der Navigationsliste, die Marke
 * sitzt also bündig auf x = 0. `.fi-sidebar-item-btn` ist bei Filament bereits
 * `position: relative` (nachgesehen), und `.fi-sidebar-nav` hat `overflow: hidden auto` —
 * beschnitten wird an der POLSTERKANTE, und dort liegt die Marke, nicht dahinter.
 * Ohne Übergang: sie erscheint mit der neuen Seite, sie fährt nicht ein.
 */
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn::before {
    content: "";
    position: absolute;
    inset-inline-start: calc(-1 * var(--bm-rail-pad));
    top: 50%;
    width: 3px;
    height: 16px;
    margin-top: -8px;
    background-color: var(--bm-rail-ident);
    border-start-end-radius: 2px;
    border-end-end-radius: 2px;
}


/* ═══ 6 · Der Seitenkopf ═══════════════════════════════════════════════════════════════════ */

/*
 * Filament: 30 px fett, 32 px Polster oben und unten, 32 px Abstand zum Inhalt. Das ist die
 * Überschrift eines Artikels. Hier steht darunter eine Tabelle mit 25 Zeilen, und die
 * Überschrift wiederholt nur, was im Menü links schon hervorgehoben ist — sie soll die Seite
 * beschriften, nicht anführen.
 *
 * ⛔ ABER NUR AM SCHREIBTISCH. Unter 64 rem — iPad hochkant, der Normalfall am Tresen — ist die
 *    Schiene eine Schublade und nach jeder Navigation ZU. Dann ist diese Überschrift der
 *    EINZIGE Ortshinweis auf dem Bildschirm, und sie kleiner zu machen wäre ein
 *    Schreibtisch-Argument, angewandt auf ein Gerät, das keinen Schreibtisch hat. Deshalb 22 px
 *    unter 64 rem und 20 px darüber.
 *
 * Gerechnet, was das über dem Inhalt spart: Polster 32 → 20/24 (20), Überschrift 30/36 → 20/26
 * (10), Zeilenabstand 32 → 16 (16), abzüglich der neuen Linie mit ihrem Polster (15) = 31 px
 * netto. Die Linie ist nicht gratis, und sie wird hier gegengerechnet statt verschwiegen.
 */
.fi-page-header-main-ctn {
    padding-block: 20px 24px;
    row-gap: 16px;
}

.fi-header {
    gap: 12px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--bm-line-hair);
}

.fi-header-heading {
    font-size: 22px;
    line-height: 28px;
    font-weight: 600;
    letter-spacing: -0.011em;
    color: var(--bm-txt-1);              /* 17.89:1 auf der Seitenfläche */
}

@media (min-width: 64rem) {
    .fi-header-heading {
        font-size: 20px;
        line-height: 26px;
    }
}

/* 18 px war eine Unterüberschrift. Als Zeile Kontext ist sie 13 px und tritt zurück. */
.fi-header-subheading {
    margin-top: 4px;
    max-width: 62ch;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-2);              /* 7.18:1 auf der Seitenfläche */
}

/* Der Brotkrumenpfad ist Beschilderung, kein Text. `--bm-txt-3` statt Filaments `--gray-500`,
   weil letzteres auf der Seitenfläche nur 4.62:1 trägt; dieser Wert trägt 5.63:1.
   ⚠️ `.fi-breadcrumbs ol li` und nicht `.fi-breadcrumbs-item-label` — letzteres steht zwar im
      DOM, hat aber in app.css keine einzige Regel; die Grösse kommt vom <li>. */
.fi-breadcrumbs ol li {
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-3);
}

.fi-page-content {
    row-gap: 20px;
}


/* ═══ 7 · Karten und Tabelle ═══════════════════════════════════════════════════════════════ */

/*
 * Ein 5 %-Ring PLUS zwei Schlagschatten ist der Versuch, eine Karte von einer fast gleich hellen
 * Seite abzuheben (`--radius-xl` = 8 px, `--tw-shadow: 0 1px 3px …`, `--tw-ring-color:
 * color-mix(… --gray-950 5% …)`). Neben einem eingefärbten Gehäuse braucht es das nicht mehr:
 * eine Haarlinie genügt, und sie ist an der Kante schärfer als jeder Schatten.
 *
 * ⚠️ `box-shadow: none` ist HIER richtig und bei `.fi-input-wrp` FALSCH: Tailwind legt Ring und
 *    Schatten in dieselbe Kette, und beim Eingabefeld ist der Ring die einzige sichtbare Grenze
 *    des Bedienelements (WCAG 1.4.11, 3.04:1 — siehe oben in dieser Datei). Deshalb wird er
 *    dort nicht angefasst.
 */
.fi-ta-ctn,
.fi-section:not(.fi-section-not-contained):not(.fi-aside) {
    border-radius: var(--radius-lg);
    background-color: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    box-shadow: none;
}

.fi-section .fi-section-header-heading {
    font-size: var(--bm-t-md);
    line-height: var(--bm-lh-md);
    font-weight: 600;
}

/*
 * DER TABELLENKOPF. 14 px halbfett in Textschwarz — der Kopf sah aus wie die Daten und wog
 * schwerer als sie. 11 px Grossbuchstaben mit Laufweite: eine Beschriftung, keine Zeile.
 *
 * ⚠️ DIE FLÄCHE WIRD NICHT ANGEFASST, und das ist eine Korrektur an einer bequemen Behauptung:
 *    `.fi-ta-table > thead > tr { background-color: var(--gray-50) }` steht bereits in app.css,
 *    und `--gray-50` ist weiter oben in dieser Datei auf #F6F7F9 gesetzt. Der Kopf ist also
 *    längst getönt. Ihn auf `--bm-srf-2` (#F1F3F5) zu setzen wäre ein Unterschied von unter 2 %
 *    Leuchtdichte, verkauft als Neuerung. Die echte Änderung sind Grösse, Schnitt, Laufweite
 *    und Höhe. `--bm-txt-3` auf #F6F7F9 trägt 5.63:1, dunkel 5.91:1 auf #1A1D20.
 *
 * ⛔ UND HIER BEKOMMT SORTIEREN ENDLICH EIN ZIEL. `.fi-ta-header-cell-sort-btn` hat bei
 *    Filament `padding: 0; width: 100%` — seine Höhe ist die Zeilenhöhe seines Textes. Mit
 *    `--bm-head-h` sind es 36 px in der Konsole und 44 px an der Theke. Das `height` auf der
 *    Zelle fängt die Tabellen ab, die gar keine sortierbare Spalte haben (dort gäbe es sonst
 *    keinen Knopf, der die Zeile aufspannt); `vertical-align` steht dabei, weil eine Zelle mit
 *    Polster 0 sonst nicht zwingend mittig ausrichtet.
 */
.fi-ta-header-cell {
    height: var(--bm-head-h);
    vertical-align: middle;
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--bm-txt-3);
}

.fi-ta-header-cell-sort-btn {
    min-height: var(--bm-head-h);
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
}

/*
 * ⛔ DIE ZEILE WAR NIE 60 PX. Der Kommentar weiter oben rechnet die Textzelle korrekt vor und
 *    übersieht die Aktionszelle, die ihre EIGENE Vorgabe mitbringt:
 *
 *        .fi-ta-cell:has(.fi-ta-actions) { padding-inline: 12px; padding-block: 16px }
 *
 *    Diese 16 px addieren sich zu den `--bm-row-pad`, die diese Datei auf `.fi-ta-actions`
 *    legt. Gerechnet: 16 + 6 + 22 (Verweis, 14/20 px plus 2 px Innenabstand) + 6 + 16 = 66 px.
 *    Die Aktionszelle war die höchste Zelle der Zeile, und die Zeile war 66 px hoch — genau
 *    der Fehlertyp, den diese Datei eine Ebene höher schon einmal gefunden und dokumentiert
 *    hat. Ab hier trägt die Trefferfläche des Verweises die Höhe der Aktionszelle:
 *
 *        Konsole   Textzelle 6 + 6 + 24 + 4 + 20 = 60   Aktionen 36   ⇒ Zeile 60 px
 *        Theke     Textzelle 10 + 10 + 24 + 4 + 20 = 68 Aktionen 44   ⇒ Zeile 68 px
 *
 *    Die Zeile wird also 6 px flacher — und der Zeilenverweis bekommt zum ersten Mal die
 *    Trefferfläche, die die Theke seit dem ersten Tag verlangt: 16 px hoch waren die Verweise
 *    bisher, in einem Bündel mit 12 px Abstand.
 */
.fi-ta-cell:has(.fi-ta-actions) {
    padding-block: 0;
}

.fi-ta-row .fi-ta-actions {
    padding-block: 0;                    /* ⚠️ ersetzt bewusst die Zeile weiter oben */
}

.fi-ta-row .fi-ta-actions .fi-link,
.fi-ta-row .fi-ta-actions .fi-icon-btn {
    min-height: var(--bm-hit);
}

/*
 * ⚠️ WAS HIER NICHT PASSIERT, UND WARUM. Die Zeilenverweise bleiben in Farbe und Symbol, wie
 *    sie sind. Filament gibt ihnen `.fi-link { color: var(--gray-700) }` — sie sind bereits
 *    neutral, nicht blau; wer «zwölf blaue Verweise pro Zeile» beklagt, hat in die falsche
 *    Datei gesehen. Und ihre Symbole tragen teilweise etwas, was der Text nicht trägt: der
 *    erste Verweis jeder Zeile der Flotte ist `target="_blank"` und sein Pfeil sagt genau das.
 *
 *    Das echte Problem der Flotte sind ZWÖLF Aktionen pro Zeile (im Abzug gezählt: 60 Verweise
 *    auf fünf Zeilen). Zwölf Verben nebeneinander sind ein Menü, keine Spalte. Das ist eine
 *    Inhaltsentscheidung; CSS kann sie nicht reparieren, nur verkleiden — und verkleiden ist
 *    das, was diese Datei sonst überall vermeidet. Es bleibt offen und steht in der Übergabe.
 *
 * ⚠️ ZEILENTRENNER WERDEN NICHT HINZUGEFÜGT, obwohl es naheliegt. Sie sind schon da:
 *    `:where(.fi-ta-table > tbody > :not(:last-child)) { border-bottom-width: 1px;
 *    border-color: var(--gray-200) }`. Filaments `divide-y` trennt nicht nur <thead> von
 *    <tbody>, sondern jede Zeile von der nächsten. Eine zweite Linie in derselben Farbe wäre
 *    eine Regel mit Begründung und ohne Wirkung.
 */

/* Der leere Zustand: sein Symbol sass in einem grauen Kreis. Das ist Verbrauchersoftware. */
.fi-ta-empty-state-icon-bg {
    background-color: transparent;
    padding: 0;
}


/* ═══ 8 · Marken statt Pillen ══════════════════════════════════════════════════════════════ */

/*
 * ⛔ EINE DOMAIN IST KEIN ZUSTAND. Heute tragen `bosporus.localhost` und `live` DIESELBE graue
 *    Pille — im Abzug nachgesehen: die Domain rendert `class="fi-badge fi-size-sm"`, der
 *    Zustand `class="fi-badge fi-size-sm fi-color fi-color-success …"`. Die Pille um den
 *    Datenwert erfindet eine Bedeutung, die es nicht gibt, und nimmt der echten Zustandsmarke
 *    ihre Auffälligkeit. `:not(.fi-color)` ist damit keine Vermutung, sondern die im Markup
 *    vorhandene Grenze.
 *
 * ⚠️ `:not(:has(.fi-badge-delete-btn))` schliesst die Filterchips aus («Aktive Filter · Nur
 *    kommende ×»). Die sind Bedienelemente mit einem Löschknopf darin; ihnen Fläche und
 *    Polster zu nehmen, verkleinerte ein Ziel, das ohnehin knapp ist.
 *
 * Die FARBEN der Zustände bleiben unangetastet — sie kommen aus Filaments Zustandsklassen und
 * haben oben in dieser Datei ihre Bedeutung und ihr zweites, nicht farbiges Signal.
 */
.fi-badge {
    border-radius: var(--radius-sm);
    padding-inline: 6px;
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    letter-spacing: .02em;
}

.fi-badge:not(.fi-color):not(:has(.fi-badge-delete-btn)) {
    min-width: 0;
    padding-inline: 0;
    background-color: transparent;
    box-shadow: none;
    font-size: var(--bm-t-xs);
    font-weight: 400;
    letter-spacing: 0;
    color: var(--bm-txt-2);              /* 7.18:1 hell auf Weiss, 8.44:1 dunkel auf der Karte */
}


/* ═══ 9 · Trefferflächen ═══════════════════════════════════════════════════════════════════ */

/*
 * `--bm-hit` war dreimal deklariert und nirgends gelesen. Ab hier tragen es: der Menüknopf, die
 * Gruppenzeile, der Zeilenverweis, der Sortierknopf (über `--bm-head-h`), der Knopf, das
 * Eingabefeld und der Schubladenknopf.
 *
 * ⚠️ Der Symbolknopf wird NICHT unsichtbar vergrössert. `.fi-icon-btn` trägt `margin: -8px`;
 *    zwei benachbarte Knöpfe stehen dadurch dichter beieinander, als ihre 36-px-Kästen breit
 *    sind. Unsichtbar um je 4 px vergrösserte Trefferfelder überlappten dort, und in der
 *    Überlappung gewinnt das später gemalte Geschwister — in der Blätterleiste ein Fehlgriff um
 *    eine Seite, in einer Zeile ein Fehlgriff zwischen «Support-Zugriff» und «Status ändern».
 *    Hier wächst nur, was sichtbar wächst.
 */
.fi-btn,
.fi-input-wrp {
    min-height: var(--bm-hit);
    border-radius: var(--radius-md);
}
/* ═══ Keine Tabelle rollt mehr waagerecht ══════════════════════════════════════════════════ */

/*
 * ⛔ DAS WAR DER ERSTE BEFUND EINES BENUTZERS, NICHT MEINER: unter der Flotte lag ein
 *    waagerechter Rollbalken. Gemessen bei 1440 px Fenster, fünf Restaurants:
 *
 *        Platz für die Tabelle      1.130 px
 *        Tabelle                    2.739 px
 *        davon die Aktionszelle     1.704 px   (zehn Aktionen nebeneinander)
 *        davon «Abgeschaltet»         455 px   (Merkmale als Komma-Liste)
 *
 *    «Angelegt» stand ausserhalb des Bildschirms, und für eine Statusänderung musste man erst
 *    seitwärts scrollen. Eine Übersicht, die man seitwärts lesen muss, ist keine Übersicht.
 *
 * Zwei Drittel der Breite sind im PHP gefallen (Überlaufmenü, Symbolknöpfe — siehe
 * TenantResource). Diese Regel deckt den Rest ab, und zwar für JEDE Tabelle im Produkt: eine
 * Zelle mit langem Fliesstext darf umbrechen statt die Tabelle zu dehnen.
 *
 * ⚠️ `max-width` UND `white-space: normal` zusammen — eins allein reicht nicht: ohne die Breite
 *    bricht nichts um, ohne `normal` gilt weiter Filaments `white-space: nowrap` auf der Zelle.
 *    Beides gemessen, nicht angenommen.
 */
.fi-ta-cell-features .fi-ta-text,
.fi-ta-cell-domains\.domain .fi-ta-col {
    max-width: 22rem;
    white-space: normal;
}

/*
 * Die Zelle mit den Zeilenaktionen bekommt keine Mindestbreite mehr aus ihrem Inhalt: sie ist
 * die letzte Spalte und darf schrumpfen, bevor die Daten es tun. Die Trefferflächen selbst
 * bleiben unangetastet (`--bm-hit` weiter oben) — nur der Abstand zwischen ihnen wird knapper,
 * und «Verwalten» rutscht bei Bedarf unter die zwei Symbole statt die Tabelle zu dehnen.
 */
.fi-ta-row .fi-ta-actions {
    justify-content: flex-end;
    gap: .375rem;
}

/*
 * ⚠️ KEIN `flex-wrap: wrap` — ausprobiert und wieder entfernt, weil es die Zeile SPRENGT: in der
 *    Speisekarte stehen drei beschriftete Aktionen, die in einer schmalen Zelle untereinander
 *    rutschen. Gemessen: Zeilenhöhe 73 → 145 px, also das Doppelte, um 130 px Breite zu sparen.
 *    Wo eine Zeile zu viele Aktionen hat, gehören sie in ein Überlaufmenü (siehe TenantResource),
 *    nicht in einen Umbruch.
 */

/* ═══ Ein Fenster statt zwei ═══════════════════════════════════════════════════════════════ */

/*
 * ⛔ TITEL UND TABELLE WAREN ZWEI GETRENNTE KÄSTEN — mit 16 px Luft dazwischen, und der Titel
 *    schwebte ohne Fläche darüber. Auf einem Bildschirm, der genau EIN Ding zeigt (die Liste),
 *    sind zwei Umrisse eine Behauptung: dass hier zwei Dinge stehen.
 *
 * Ab hier ist es ein Fenster: der Kopf sitzt AUF der Karte, teilt ihre Fläche und ihren Rahmen,
 * und die Haarlinie darunter trennt Titel von Werkzeugleiste — nicht Karte von Karte.
 *
 * ⚠️ NUR WENN DIE SEITE MIT EINER TABELLE ANFÄNGT. `:has(> .fi-ta)` prüft genau das; auf
 *    Formularseiten und dem Kokpit (Widgets) bleibt der Kopf, wie er ist — dort steht unter ihm
 *    kein einzelner Kasten, den er krönen könnte. Ohne diese Bedingung bekäme jede Seite einen
 *    Deckel ohne Topf.
 */
.fi-page-content:has(> .fi-ta:first-child) {
    --bm-fenster-radius: var(--radius-lg);
}

.fi-page:has(.fi-page-content > .fi-ta:first-child) .fi-header {
    margin-bottom: 0;
    padding: 14px 16px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    border-bottom: 0;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

/* Und die Karte darunter verliert ihre obere Kante, sonst stünde die Naht doppelt. */
.fi-page-content:has(> .fi-ta:first-child) .fi-ta-ctn {
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

/*
 * Der Seitentitel wird kleiner: er ist die Antwort auf «wo bin ich», nicht die Überschrift eines
 * Artikels. 20 px statt Filaments 30 px — die gewonnene Höhe geht an die Liste, und das ist die
 * Rechnung, die dieser Bildschirm gewinnt.
 */
.fi-page:has(.fi-page-content > .fi-ta:first-child) .fi-header-heading {
    font-size: 1.25rem;
    line-height: 1.75rem;
    letter-spacing: -.01em;
}

/*
 * Und die letzte Naht: `.fi-page-header-main-ctn` ist ein Flex-Behälter mit `row-gap: 16px`.
 * Solange der bleibt, sitzt zwischen Kopf und Karte eine Lücke, gegen die weder `margin-bottom: 0`
 * noch ein gemeinsamer Rahmen ankommt — gemessen: Kopf endet bei 157, Karte beginnt bei 173.
 * Auf einer Tabellenseite fällt der Abstand weg, weil Kopf und Karte dort EIN Objekt sind.
 */
.fi-page:has(.fi-page-content > .fi-ta:first-child) .fi-page-header-main-ctn {
    row-gap: 0;
}

/*
 * ⚠️ NUR WENN DIE TABELLE DAS ERSTE UND EINZIGE IST — `:first-child`, nachträglich verschärft.
 *    Der Kokpit hat über seiner Tabelle einen eigenen Abschnitt (`.fi-section`); ohne die
 *    Bedingung bekam sein Kopf einen weissen Deckel, unter dem gar nicht die Karte lag, sondern
 *    171 px Luft und ein fremder Kasten. Gemessen, nachdem genau das passiert war.
 */

/*
 * LANGE SPALTENÜBERSCHRIFTEN DÜRFEN UMBRECHEN. «Offene Anfragen» und «Inhaberin zuletzt» sind
 * zusammen 340 px, wenn sie einzeilig bleiben müssen — im Kokpit waren das die letzten 43 px,
 * die die Tabelle über den Rand geschoben haben. Zwei Zeilen im Kopf kosten 16 px Höhe EINMAL,
 * ein Rollbalken kostet jede Zeile darunter.
 */
.fi-ta-header-cell {
    white-space: normal;
}

/* ═══ DIE SERVICEZEILE ═══════════════════════════════════════════════════════════════════════
 *
 * ⛔ EINE ZEILE, KEINE KACHELREIHE. Die naheliegende Fassung dieser Auskunft sind vier
 *    abgerundete Kästen mit Symbolen — sie kostet rund 140 px Höhe für vier Zahlen, die in eine
 *    Zeile passen, und auf einem Tresen-Tablet ist diese Höhe die erste Tischreihe, die man nicht
 *    mehr sieht. Deshalb: 44 px, eine Grundlinie, kein Kasten um jede Zahl.
 *
 * ⚠️ ALLE FARBEN AUS DEN TOKENS OBEN. Ein eigener Hex-Wert hier wäre die fünfte Stelle, an der
 *    dieses Produkt entscheidet, was «gelb» heisst — und die einzige, die beim Dunkelmodus
 *    niemand mitzieht.
 */
.bm-svc {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 20px;
    min-height: 44px;
    padding: 8px 14px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--bm-fenster-radius, 8px);
    font-size: 13px;
    line-height: 1.3;
    color: var(--bm-txt-2);
}

.bm-svc__tag {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.bm-svc__wort {
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-svc__datum {
    font-size: 12px;
    color: var(--bm-txt-3);
}

/* Die Zahl führt. Grösse UND Gewicht, nicht nur eine der beiden — sonst liest sie sich wie eine
   weitere Beschriftung. */
.bm-svc__zahl {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.bm-svc__zahl strong {
    font-size: 20px;
    font-weight: 600;
    color: var(--bm-txt-1);
    /* Tabellenziffern: die Zahl ändert sich beim Nachladen, und eine springende Grundlinie in
       einer Kopfzeile liest sich als Fehler. */
    font-variant-numeric: tabular-nums;
}

.bm-svc__last {
    display: flex;
    align-items: center;
    gap: 8px;
}

.bm-svc__band {
    width: 96px;
    height: 6px;
    border-radius: 3px;
    background: var(--bm-line-hair);
    overflow: hidden;
}

.bm-svc__band > span {
    display: block;
    height: 100%;
    background: var(--bm-ok-fg);
}

/* ⛔ AB NEUNZIG PROZENT DIESELBE FARBE WIE AUF DER LEISTE DARÜBER. Beide Balken beantworten
 *    dieselbe Frage — «geht hier noch was» — und bis hierher taten sie es in zwei Sprachen: die
 *    Tagesleiste schlug bei 90 % in die Warnfarbe um, die Zeile darunter blieb bei jedem Stand
 *    grün. Ein Samstag, der auf der Leiste rot war und in der Zeile ruhig, ist genau der
 *    Widerspruch, den `PanelDesignSystemTest` an den Zustandsfarben schon einmal gefunden hat. */
.bm-svc__band > span.is-voll {
    background: var(--bm-risk-fg);
}

.bm-svc__lastwort {
    font-size: 12px;
    color: var(--bm-txt-3);
    font-variant-numeric: tabular-nums;
}

/* ⛔ DIE EINZIGE FARBE, DIE HIER LAUT SEIN DARF. «Offen» ist der einzige Zustand auf dieser Zeile,
 *    der eine Handlung verlangt; alles andere ist Rückblick. Zwei laute Farben nebeneinander
 *    heissen: keine ist laut. */
.bm-svc__offen {
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--bm-todo-bg);
    color: var(--bm-todo-fg);
    border: 1px solid var(--bm-todo-line);
    font-weight: 600;
    font-size: 12px;
}

.bm-svc__da {
    font-size: 12px;
    color: var(--bm-ok-fg);
    font-weight: 600;
}

/* Auf dem Telefon bleibt die Zeile eine Zeile, aber das Datum und das Lastwort dürfen gehen —
   die Gästezahl und die offenen Anfragen sind das, wofür man hinschaut. */
@media (max-width: 640px) {
    .bm-svc {
        gap: 6px 14px;
        padding: 8px 10px;
    }

    .bm-svc__datum,
    .bm-svc__lastwort {
        display: none;
    }
}

/* ═══ DIE ZEICHEN ════════════════════════════════════════════════════════════════════════════
 *
 * ⚠️ EINE REGEL FÜR ALLE SYMBOLE DES PANELS. Grösse aus der Schrift, Farbe aus dem Text daneben —
 *    damit ein Zeichen in einer Pille die Pillenfarbe trägt und in einem Knopf die Knopffarbe,
 *    ohne dass irgendeine Fläche eine eigene Regel dafür schreibt.
 */
.bm-zeichen {
    width: 1em;
    height: 1em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
    /* Auf der Grundlinie des Satzes, nicht darüber: ein Symbol, das oben schwebt, macht jede
       Zeile, in der es vorkommt, einen Pixel höher als ihre Nachbarn. */
    vertical-align: -0.125em;
}

/* ═══ WAS BEANTWORTET WERDEN MUSS ════════════════════════════════════════════════════════════
 *
 * ⛔ DIESE KARTEN SIND DIE AUSNAHME VON «KEINE KACHELREIHE», und der Unterschied ist nicht
 *    Geschmack, sondern Zweck. Die Servicezeile darüber trägt AUSKÜNFTE — Zahlen, die man liest
 *    und weglegt; für die kostet ein Kasten Höhe und bringt nichts. Hier steht eine
 *    ENTSCHEIDUNG: zwei Knöpfe, die eine E-Mail an einen Menschen auslösen. Die brauchen eine
 *    Trefferfläche, und eine Trefferfläche braucht Fläche.
 *
 * ⛔ UND SIE STEHEN NUR DA, WENN ES SIE GIBT. Kein leerer Kasten mit «keine offenen Anfragen» —
 *    dieselbe Regel wie an der Servicezeile, aus demselben Grund: was immer da ist, sieht
 *    niemand mehr, auch nicht an dem Samstag, an dem etwas drinsteht.
 *
 * ⚠️ DIE FARBE IST `todo`, NICHT `risk`. Eine unbeantwortete Anfrage ist keine Störung, sondern
 *    Arbeit — dieselbe Familie, die die Statuspille «Offen» im Buch schon trägt, damit derselbe
 *    Vorgang oben und unten nicht zwei Farben hat.
 */
.bm-anfr {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 12px;
}

.bm-anfr__kopf {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
    color: var(--bm-todo-fg);
}

.bm-anfr__karte {
    display: grid;
    /* Angaben links, Entscheidung rechts. Untergrenze, weil ein Knopf, der mit seiner
       Beschriftung schrumpft, bei «Ja, absagen» zweizeilig wird — und OBERGRENZE, weil `auto`
       genau das getan hat, was `auto` tut: der Satz «Um 18:00 Uhr sind 18 von 20 Plätzen frei»
       zog die Spalte auf knapp sechshundert Pixel, und ein «Zusagen» dieser Breite ist keine
       Handlung mehr, sondern eine Bande quer über den Bildschirm. Am Abzug gesehen, nicht im
       Editor. */
    grid-template-columns: minmax(0, 1fr) minmax(212px, 248px);
    gap: 4px 22px;
    padding: 13px 15px 14px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-todo-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--bm-lift-1);
}

.bm-anfr__oben {
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    margin: 0 0 2px;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-3);
}

/* ⛔ DIE EINZIGE LAUTE STELLE DER KARTE. Eine Anfrage, deren Zeit durch ist, ist kein offener
 *    Punkt mehr — da hat ein Gast auf eine Antwort gewartet, die nie kam. */
.bm-anfr__spaet {
    color: var(--bm-risk-fg);
    font-weight: 600;
}

.bm-anfr__wer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.bm-anfr__name {
    margin: 0;
    font-size: 19px;
    line-height: 24px;
    font-weight: 600;
    color: var(--bm-txt-1);
    /* Ein Name, der nicht passt, wird gekürzt und nicht umgebrochen: die Karte hält ihre Höhe,
       und die Knöpfe rechts bleiben dort, wo der Daumen sie beim zweiten Mal erwartet. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bm-anfr__fakten {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.bm-anfr__fakt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-sm);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-2);
    font-variant-numeric: tabular-nums;
}

.bm-anfr__fakt b {
    font-weight: 600;
    color: var(--bm-txt-1);
}

/* Die Nummer ist eine Wählverbindung. Sie sieht aus wie die Nachbarn und verhält sich wie ein
   Link — deshalb bekommt sie als einzige einen Hover und einen sichtbaren Fokus. */
.bm-anfr__ruf {
    text-decoration: none;
}

.bm-anfr__ruf:hover {
    background: var(--bm-row-hover);
    border-color: var(--bm-line-strong);
    color: var(--bm-txt-1);
}

.bm-anfr__ruf:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* ⛔ VIER FIGUREN STATT EINER VIER. Eine Ziffer muss gelesen und in eine Menge übersetzt werden;
 *    eine Reihe Figuren IST die Menge. Auf genau diesem Bildschirm entscheidet sie mit, ob
 *    zugesagt wird — und sie wird im Vorbeigehen gelesen, mit einem Telefon am Ohr.
 *
 * ⚠️ EINE KLASSE FÜR BEIDE FLÄCHEN — die Entscheidungskarte oben und die Spalte «Personen» im
 *    Buch darunter. Zwei Zeichnungen für dieselbe Menge wären zwei Sprachen auf einem Schirm. */
.bm-pers {
    display: inline-flex;
    gap: 2px;
}

.bm-pers > i {
    width: 5px;
    height: 11px;
    /* Kopf und Schultern aus einer Form: oben rund, unten breit auslaufend. Ein Kreis allein
       liest sich als Punkt, und Punkte zählt man nicht, man überfliegt sie. */
    border-radius: 3px 3px 1px 1px;
    background: var(--bm-txt-2);
}

/* ═══ DER BEFUND AN DER KANTE ════════════════════════════════════════════════════════════════
 *
 * ⛔ ZWEI KONSOLENLISTEN WERDEN ÜBERFLOGEN, NICHT GELESEN — die Flotte («wo fange ich heute an»)
 *    und die Merkmalsmatrix («wem haben wir etwas versprochen, das die Seite nicht zeigt»). Bei
 *    dreissig Restaurants liest niemand dreissigmal eine Pille in Spalte drei. Ein Streifen sagt
 *    im Vorbeischauen, welche Zeile etwas will; die Pille sagt dann, was.
 *
 * ⚠️ EIN NAME FÜR BEIDE. Die Klassen hiessen `bm-flotte--*`, solange es eine Seite war; eine
 *    zweite Seite mit demselben Streifen unter einem Seitennamen wäre der Anfang einer zweiten
 *    Zeichnung derselben Sache.
 *
 * ⚠️ EIN STREIFEN UND KEINE FLÄCHE. Eine eingefärbte Zeile über die volle Breite färbt auch die
 *    Zahlen darin und macht aus einer Liste ein Warnschild — bei mehreren Befunden nebeneinander
 *    ist der Bildschirm dann bunt und nichts mehr hervorgehoben. Drei Pixel an der Kante tragen
 *    dieselbe Auskunft und lassen die Tabelle eine Tabelle.
 *
 * ⚠️ `box-shadow` STATT `border-left`: eine Rahmenlinie verschiebt den Zelleninhalt um ihre
 *    Breite, und dann stehen gestreifte und ungestreifte Zeilen nicht mehr auf einer Flucht.
 *    Der Schatten liegt innen und kostet keinen Platz.
 */
/* ⛔ DER HINWEIS ÜBER DER TABELLE WAR EINE GANZE KARTE — Überschrift, Satz und ein Codeblock
 *    über die volle Breite, rund 180 px, über der Liste, für die man die Seite öffnet. Bei einem
 *    einzigen nicht gelesenen Restaurant war der Hinweis grösser als der Befund.
 *
 * ⚠️ EINE ZEILE, DIE AUF DEM TELEFON DREI WIRD. Der Befehl darf nicht abgeschnitten werden — er
 *    wird kopiert —, also bricht der Streifen um, statt seitwärts zu rollen. */
.bm-hinweis {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 14px;
    padding: 11px 14px;
    margin-bottom: 14px;
    background: var(--bm-todo-bg);
    border: 1px solid var(--bm-todo-line);
    border-radius: var(--radius-lg);
    color: var(--bm-todo-fg);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

/* Das Zeichen wächst mit der Schrift; die Regel dafür steht bei `.bm-zeichen`. Hier bekommt es
   nur etwas mehr Gewicht, weil es allein am Anfang einer Zeile steht. */
.bm-hinweis > .bm-zeichen {
    width: 18px;
    height: 18px;
}

.bm-hinweis__text {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 3px 8px;
    min-width: 0;
    flex: 1 1 340px;
}

.bm-hinweis__wort {
    font-weight: 600;
}

/* ⚠️ ZUM KOPIEREN, NICHT ZUM LESEN. `user-select: all` markiert den ganzen Befehl mit einem
   Klick — auf einem Bildschirm, dessen einzige Handlung hier «tipp das in eine Shell» ist,
   spart das den Versuch, eine Zeichenkette mit der Maus genau zu treffen. */
.bm-hinweis__befehl {
    flex: none;
    padding: 5px 10px;
    border-radius: var(--radius-sm);
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-todo-line);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-1);
    user-select: all;
}

/* ═══ DER EINMALIGE LINK ═════════════════════════════════════════════════════════════════════
 *
 * ⛔ DIE EINLADUNG EXISTIERT GENAU EINMAL und stand in demselben grauen Kasten wie ein
 *    Shell-Befehl. Die Datenbank hält nur einen Hash; wer den Link hier nicht mitnimmt, muss
 *    eine neue Einladung ausstellen und die alte entwerten. Ein Kasten zum Nachlesen ist die
 *    falsche Form für das eine Ding, das man JETZT in eine Mail kopiert.
 *
 * ⚠️ DIE MARKE «nur einmal» KOMMT AUS DEM ATTRIBUT, nicht aus der Stildatei: der Text ist
 *    übersetzt, und übersetzte Wörter gehören nicht in ein `content:`, das kein Übersetzer
 *    findet.
 */
.bm-link {
    position: relative;
    margin: 14px 0 0;
    padding: 16px 14px 14px;
    background: var(--bm-ident-soft);
    border: 1px solid var(--bm-ident-line);
    border-radius: var(--radius-lg);
}

.bm-link::before {
    content: attr(data-einmal);
    position: absolute;
    top: -9px;
    left: 12px;
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--bm-ident);
    color: var(--bm-srf-1);
    font-size: var(--bm-t-2xs);
    line-height: 16px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* ⚠️ EIN KLICK MARKIERT ALLES. Ein Einladungslink ist lang, und ihn mit der Maus genau zu
   treffen ist die Handlung, bei der man ein Zeichen verliert und es nicht merkt. */
.bm-link__wert {
    display: block;
    overflow-wrap: anywhere;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--bm-t-sm);
    line-height: 20px;
    color: var(--bm-txt-1);
    user-select: all;
}

.bm-kante--risk > td:first-child,
.bm-kante--todo > td:first-child,
.bm-kante--ok > td:first-child,
.bm-kante--unbekannt > td:first-child {
    box-shadow: inset 3px 0 0 0 currentColor;
}

.bm-kante--risk > td:first-child { color: var(--bm-risk-fg); }
.bm-kante--todo > td:first-child { color: var(--bm-todo-fg); }

/* «läuft gerade» — die Zeile, die JETZT gilt. Der Kopf dieser Stildatei legt `ok` genau darauf
   fest: fertig, läuft, online. Ein heutiges Angebot ist kein Befund und keine Aufgabe; es ist
   das, wonach man diesen Bildschirm überhaupt öffnet. */
.bm-kante--ok > td:first-child { color: var(--bm-ok-fg); }

/* Grau und nicht farbig: «noch nicht gelesen» ist kein Befund, sondern dessen Abwesenheit —
   dieselbe Regel, nach der `unknown` im ganzen Produkt gestrichelt und nie bunt ist. */
.bm-kante--unbekannt > td:first-child { color: var(--bm-line-strong); }

/* ⚠️ DER STREIFEN FÄRBT NUR SICH SELBST. `currentColor` oben erbt in die Zelle, also würde der
   Restaurantname die Befundfarbe annehmen — ein roter Name behauptet, das Restaurant sei kaputt,
   und nicht unser letzter Messwert. Der Text holt sich seine Farbe zurück. */
.bm-kante--risk > td:first-child .fi-ta-text,
.bm-kante--todo > td:first-child .fi-ta-text,
.bm-kante--ok > td:first-child .fi-ta-text,
.bm-kante--unbekannt > td:first-child .fi-ta-text {
    color: var(--bm-txt-1);
}

/* ═══ TISCHAUFSTELLER ════════════════════════════════════════════════════════════════════════
 *
 * Anleitung und Probe — unter dem Formular, nicht darin. Die Begründung steht in der Vorlage.
 */
.bm-qr {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin-top: 20px;
}

.bm-qr__probe {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    flex-wrap: wrap;
    padding: 18px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
    box-shadow: var(--bm-lift-1);
}

/* Weiss hinterlegt, immer. Ein QR-Code auf dunklem Grund ist im Dunkelmodus schlicht nicht
   lesbar — das Muster braucht seine hellen Module, und das gilt auf dem Schirm wie auf Papier. */
.bm-qr__bild {
    flex: none;
    width: 120px;
    height: 120px;
    padding: 8px;
    background: #FFFFFF;
    border-radius: var(--radius-md);
    border: 1px solid var(--bm-line-hair);
    /* Kein Weichzeichnen beim Skalieren: ein interpolierter QR-Code sieht unscharf aus und
       lässt den Wirt an der Druckdatei zweifeln, die scharf ist. */
    image-rendering: pixelated;
}

.bm-qr__ziel {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
    flex: 1 1 320px;
}

.bm-qr__wort {
    margin: 0;
    font-size: var(--bm-t-md);
    line-height: var(--bm-lh-md);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-qr__satz {
    margin: 0;
    font-size: var(--bm-t-sm);
    line-height: 19px;
    color: var(--bm-txt-2);
    max-width: 62ch;
}

.bm-qr__adresse {
    font-size: var(--bm-t-sm);
    line-height: 19px;
    font-weight: 600;
    color: var(--bm-rail-ident);
    text-decoration: underline;
    text-underline-offset: 3px;
    /* Eine Adresse bricht an jeder Stelle, sonst schiebt sie die Karte auf dem Telefon breiter
       als den Bildschirm. */
    overflow-wrap: anywhere;
}

.bm-qr__adresse:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* ⛔ NUMMERN, WEIL ES WIRKLICH EINE REIHENFOLGE IST. Herunterladen, drucken, schneiden — das
 *    passiert nacheinander und nur in dieser Richtung. Anderswo in diesem Panel wären
 *    nummerierte Marken Verzierung; hier tragen sie die einzige Auskunft, die der Text sonst
 *    umständlich ausschreiben müsste. */
.bm-qr__weg {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.bm-qr__schritt {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    font-size: var(--bm-t-md);
    line-height: 22px;
    color: var(--bm-txt-2);
}

.bm-qr__schritt b {
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-qr__nr {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--bm-ident-soft);
    border: 1px solid var(--bm-ident-line);
    color: var(--bm-ident);
    font-size: var(--bm-t-xs);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.bm-qr__hilfe {
    border-top: 1px solid var(--bm-line-hair);
    padding-top: 14px;
}

.bm-qr__hilfe > summary {
    cursor: pointer;
    font-size: var(--bm-t-sm);
    font-weight: 600;
    color: var(--bm-txt-2);
    /* Trefferfläche auch am Finger: eine Zeile Text ist 18 px hoch, ein Daumen ist es nicht. */
    padding: 6px 0;
    min-height: var(--bm-hit);
    display: flex;
    align-items: center;
}

.bm-qr__hilfe > summary:hover {
    color: var(--bm-txt-1);
}

.bm-qr__hilfe > summary:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

.bm-qr__hilfetext {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0 2px;
    font-size: var(--bm-t-sm);
    line-height: 19px;
    color: var(--bm-txt-2);
    max-width: 68ch;
}

.bm-qr__hilfetext p {
    margin: 0;
}

.bm-qr__hilfetext b {
    font-weight: 600;
    color: var(--bm-txt-1);
}

/* ═══ DAS BUCH ═══════════════════════════════════════════════════════════════════════════════
 *
 * Die Spalte «Personen» und die Zeilen, die nicht mehr stattfinden.
 */
.bm-buch__pers {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.bm-buch__perszahl {
    font-variant-numeric: tabular-nums;
    /* ⚠️ DREI ZIFFERN BREIT, nicht eine. `ch` ist bei Tabellenziffern exakt eine Ziffernbreite,
       und eine Gesellschaft von 120 Personen ist in einem Haus mit Saal keine Ausnahme — bei
       `1.2em` wanderte die Spalte genau dann, wenn die grösste Buchung des Abends darin steht. */
    min-width: 3ch;
    text-align: right;
    color: var(--bm-txt-1);
}

/* ⛔ ZURÜCKGENOMMEN, NICHT VERSTECKT. Eine Absage bleibt im Buch — sie verliert nur ihr Gewicht,
 *    damit sie nicht über den Gästen steht, die tatsächlich kommen. Warum nicht gefiltert: in
 *    ReservationResource, bei `recordClasses()`.
 *
 * ⚠️ KEINE `opacity` AUF DER ZEILE. Sie hätte auch die Statuspille und die Handlungen mit
 *    ausgeblichen — «Storniert» wäre dann das schwächste Wort in seiner eigenen Zeile, und der
 *    Knopf, mit dem man die Absage zurücknimmt, kaum noch zu sehen. Zurückgenommen wird der
 *    TEXT, und zwar über die Farbe, die das System dafür führt. */
.bm-vorbei .fi-ta-text {
    color: var(--bm-txt-3);
}

.bm-vorbei .bm-buch__perszahl {
    color: var(--bm-txt-3);
}

.bm-vorbei .bm-pers > i {
    background: var(--bm-txt-disabled);
}

/* ═══ DIE SPEISEKARTE ════════════════════════════════════════════════════════════════════════
 *
 * Das Bild am Anfang jeder Gerichtzeile — und der Platzhalter, der die Regel ist und nicht die
 * Ausnahme. Die Begründung steht in `tables/gerichtbild.blade.php`; hier nur die Masse.
 */
.bm-bild {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44 px: dieselbe Trefferhöhe wie eine Zeile am Finger, und gross genug, dass ein Teller als
       Teller erkennbar ist. Fest, nicht relativ — eine Bildspalte, die mit der Textlänge
       wandert, macht die Liste unruhig. */
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: var(--radius-md);
    /* `cover`: Fotos aus einer Küche haben jedes Seitenverhältnis, und ein verzerrter Teller
       sieht schlechter aus als ein beschnittener. */
    object-fit: cover;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
}

/* ⛔ KEIN GRAUER KASTEN. Ein Haus kommt mit vier Fotos auf sechzig Gerichte; neunundfünfzig
 *    leere Flächen sind das, woran sich eine Inhaberin erinnert. Der Anfangsbuchstabe in der
 *    Hausfarbe liest sich als Entscheidung — dieselbe Antwort, die die öffentliche Karte gibt. */
.bm-bild--leer {
    background: var(--bm-ident-soft);
    border-color: var(--bm-ident-line);
    color: var(--bm-ident);
    font-size: 17px;
    font-weight: 600;
    line-height: 1;
    /* Versalien stehen ohne Sperrung zu eng, wenn sie allein in einer Fläche sitzen. */
    letter-spacing: .02em;
}

/* Ziffern auf einer Flucht — Preise, Mengen, Zahlen in Tabellenspalten. */
.bm-zahl .fi-ta-text {
    font-variant-numeric: tabular-nums;
}

/* Der Name durchgestrichen: die eine Stelle, an der «findet nicht statt» ohne Farbe und ohne
   Wort erkennbar ist — auch im Graustufenabzug und auf dem Tablet in der Sonne.
 *
 * ⚠️ `.bm-zeile__name` KOMMT AUS DER SPALTE, NICHT VON FILAMENT. Nachgesehen im ausgelieferten
 *    `index.blade.php`: das `<td>` trägt nur, was die Spalte selbst mitgibt — es gibt keine
 *    Klasse je Spaltenname. Der Haken wird in ReservationResource per `extraCellAttributes()`
 *    gesetzt; ohne ihn zielt diese Regel ins Leere. */
.bm-vorbei .bm-zeile__name .fi-ta-text {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--bm-line-strong);
}

.bm-anfr__notiz {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    margin: 0;
    font-size: var(--bm-t-sm);
    line-height: 19px;
    color: var(--bm-txt-2);
    /* Was der Gast geschrieben hat, in Lesebreite — nicht über die ganze Karte gezogen. */
    max-width: 56ch;
}

.bm-anfr__notiz .bm-zeichen {
    margin-top: 3px;
    color: var(--bm-txt-3);
}

.bm-anfr__tun {
    display: flex;
    flex-direction: column;
    gap: 7px;
    align-self: center;
}

.bm-anfr__ja,
.bm-anfr__nein,
.bm-anfr__zurueck {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    /* 44 px auch mit feinem Zeiger: das hier ist die Handlung, für die es diesen Bildschirm
       gibt, und sie wird oft im Stehen ausgelöst. */
    min-height: max(44px, var(--bm-hit));
    padding: 0 16px;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    font-size: var(--bm-t-md);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--bm-dur-2) var(--bm-ease-out),
                border-color var(--bm-dur-2) var(--bm-ease-out);
}

/*
 * ⛔ `--bm-ok-fg` ALS FLÄCHE WAR IM DUNKELN EIN LEUCHTEN. Das Token ist eine SCHRIFTFARBE —
 *    im Dunkelmodus ein helles Mint (#5FD3A3), gedacht für Wörter auf dunklem Grund. Über
 *    zweihundert Pixel Knopf gezogen wurde daraus die hellste Fläche des ganzen Bildschirms,
 *    heller als jede Zahl daneben. Am Abzug gesehen.
 *
 *    Ein Knopf braucht einen FÜLLTON, und den führt dieses Produkt schon: dieselben zwei Grün,
 *    mit denen die Kacheln der Übersicht ihre Symbole hinterlegen. Sie sind für Flächen
 *    gerechnet und tragen Weiss in beiden Modi.
 */
.bm-anfr__ja {
    /*
     * ⚠️ BEIDE STOPPS GERECHNET, NICHT GEWÄHLT. Der erste Anlauf lief von #2E9E63 nach #17794A —
     *    hübsch, und oben trug Weiss darauf 3.39:1. Die Beschriftung ist 15 px halbfett und
     *    damit KEIN «grosser Text» im Sinne der Richtlinie: es gelten 4.5:1, nicht 3:1. Der
     *    hellste Punkt eines Verlaufs ist der, an dem der Text steht, also muss ER die Schwelle
     *    halten. #1B8050 → #146B41: 4.94:1 oben, 6.54:1 unten.
     */
    background: linear-gradient(180deg, #1B8050, #146B41);
    border-color: #146B41;
    color: #FFFFFF;
}

.bm-anfr__ja:hover {
    filter: brightness(1.08);
}

.bm-anfr__nein {
    background: transparent;
    border-color: var(--bm-line-strong);
    color: var(--bm-txt-2);
}

.bm-anfr__nein:hover {
    background: var(--bm-row-hover);
    color: var(--bm-txt-1);
}

/* Erst nach der Rückfrage trägt das Nein die Warnfarbe. Vorher wäre es ein rot leuchtender
   Knopf neben einem grünen — zwei laute Farben heissen: keine ist laut. */
.bm-anfr__nein.is-sicher {
    background: var(--bm-risk-fg);
    border-color: var(--bm-risk-fg);
    color: var(--bm-srf-1);
}

.bm-anfr__zurueck {
    background: transparent;
    border-color: transparent;
    color: var(--bm-txt-3);
    font-weight: 500;
    min-height: var(--bm-hit);
}

.bm-anfr__zurueck:hover {
    color: var(--bm-txt-1);
}

.bm-anfr__ja:focus-visible,
.bm-anfr__nein:focus-visible,
.bm-anfr__zurueck:focus-visible,
.bm-anfr__mehr:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

.bm-anfr__frage {
    margin: 0 0 1px;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    font-weight: 600;
    color: var(--bm-risk-fg);
    text-align: center;
}

.bm-anfr__frei {
    margin: 1px 0 0;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-3);
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.bm-anfr__frei b {
    font-weight: 600;
    color: var(--bm-txt-2);
}

.bm-anfr__mehr {
    align-self: flex-start;
    padding: 6px 2px;
    font-size: var(--bm-t-sm);
    color: var(--bm-todo-fg);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ⛔ AM FINGER WIRD DIE ENTSCHEIDUNG GRÖSSER, NICHT NUR DIE SCHRIFT.
 *
 *    Dieser Kasten wird auf einem Tresen-Tablet bedient, im Stehen, oft mit dem Telefon in der
 *    anderen Hand — und die beiden Knöpfe darin lösen eine E-Mail an einen fremden Menschen aus.
 *    Ein Fehlgriff hier ist nicht ein falscher Filter, sondern eine Absage an einen Gast, der
 *    zugesagt bekommen sollte. 48 px statt 44, und die Nummer wird zur vollen Trefferfläche:
 *    sie ist auf einem Tablet eine Wählverbindung und keine Beschriftung.
 */
@media (pointer: coarse) {
    .bm-anfr__ja,
    .bm-anfr__nein {
        min-height: 48px;
    }

    .bm-anfr__ruf {
        min-height: 44px;
        padding-inline: 12px;
    }

    /* Abstand zwischen Ja und Nein: nebeneinander liegende Knöpfe mit gegenteiliger Wirkung
       brauchen mehr als die 7 px, die für Zeigergeräte reichen. */
    .bm-anfr__tun {
        gap: 10px;
    }
}

/* Auf dem Telefon steht die Entscheidung unter den Angaben, nicht daneben — und die Knöpfe
   liegen nebeneinander, damit beide ohne Rollen erreichbar bleiben. */
@media (max-width: 720px) {
    .bm-anfr__karte {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
    }

    .bm-anfr__tun {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
    }

    .bm-anfr__ja,
    .bm-anfr__nein {
        flex: 1 1 46%;
    }

    .bm-anfr__frage,
    .bm-anfr__frei {
        flex: 1 1 100%;
        text-align: left;
    }
}

/* ═══ DIE TAGESLEISTE ════════════════════════════════════════════════════════════════════════
 *
 * ⛔ SIEBEN TAGE ALS FORM. Jeder Tag trägt sein eigenes Band, weil die Frage eines Wirts nicht
 *    «welcher Tag ist der 16.» lautet, sondern «wie voll wird Samstag» — und eine Balkenhöhe
 *    beantwortet die schneller als jede Zahl. Datum wählen und Auslastung lesen sind damit
 *    dieselbe Handlung statt zwei.
 */
.bm-woche {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    margin-bottom: 8px;
    padding: 6px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--bm-fenster-radius, 8px);
}

.bm-woche__tag {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    /* 44 px Trefferfläche: das hier wird auf einem Tablet mit dem Daumen bedient. */
    min-height: 44px;
    padding: 5px 2px;
    border-radius: 6px;
    text-decoration: none;
    color: var(--bm-txt-3);
    font-size: 11px;
    line-height: 1;
}

.bm-woche__tag:hover {
    background: var(--bm-row-hover);
}

.bm-woche__tag:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* Der laufende Diensttag. Farbe ALLEIN trägt das nicht — Gewicht und Fläche sagen es mit. */
.bm-woche__tag.is-heute {
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    font-weight: 600;
    box-shadow: inset 0 0 0 1px var(--bm-line-strong);
}

.bm-woche__band {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    width: 100%;
    height: 28px;
}

.bm-woche__band > span {
    display: block;
    width: 60%;
    max-width: 42px;
    border-radius: 2px;
    background: var(--bm-line-strong);
}

.bm-woche__tag.is-heute .bm-woche__band > span {
    background: var(--bm-ok-fg);
}

/* ⛔ AB NEUNZIG PROZENT EINE ANDERE FARBE, und das ist die einzige laute Stelle der Leiste: ein
 *    Tag, an dem nichts mehr geht, ist die einzige Auskunft hier, die eine Handlung auslöst. */
.bm-woche__band > span.is-voll {
    background: var(--bm-risk-fg);
}

.bm-woche__zahl {
    font-variant-numeric: tabular-nums;
    min-height: 12px;
}

@media (max-width: 640px) {
    .bm-woche__band { height: 20px; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DIE ZEITSCHIENE — der Abend als Raum

   ⛔ NICHTS HIER ERFINDET EINE FARBE. Jeder Wert kommt aus den Belegten oben: dieselben vier
      Zustandsfarben, dieselbe Grau-Rampe, dieselben Radien. Ein Bildschirm mit eigenem Rot
      bringt einem Wirt bei, dass Rot je nach Ansicht etwas anderes heisst — und dann liest er
      keins von beiden mehr.

   ⚠️ DIE POSITION DER BALKEN KOMMT AUS PHP, nicht aus CSS. `left` und `width` sind gerechnete
      Minuten mal zwei Pixel (Zeitschiene::PX_PER_MINUTE). Sie hier noch einmal auszurechnen
      hiesse, dieselbe Zahl an zwei Orten zu pflegen — genau die Bauform, die in diesem Projekt
      schon zweimal auseinandergelaufen ist (D-52, D-54).
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ⚠️ `.bm-zs__kopf` IST WEG. Der Zeitplan trägt dieselbe `.bm-sp__steuer` wie der Raumplan —
      zwei Ansichten desselben Abends sollen ihre Frage gleich stellen. */

.bm-zs__tag { display: flex; align-items: baseline; gap: 10px; }
.bm-zs__tag b { font-size: var(--bm-t-lg); line-height: var(--bm-lh-lg); color: var(--bm-txt-1); }
.bm-zs__tag span { font-size: var(--bm-t-sm); color: var(--bm-txt-2); font-variant-numeric: tabular-nums; }

.bm-zs__heute {
    font-style: normal; font-size: var(--bm-t-2xs); letter-spacing: .06em; text-transform: uppercase;
    color: var(--bm-ok-fg); background: var(--bm-ok-bg); border: 1px solid var(--bm-ok-line);
    border-radius: var(--radius-sm); padding: 1px 6px;
}

.bm-zs__nav { display: flex; gap: 6px; }

.bm-zs__knopf {
    min-width: var(--bm-hit); height: var(--bm-hit);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--bm-t-sm); color: var(--bm-txt-1);
    background: var(--bm-srf-1); border: 1px solid var(--bm-line-strong);
    border-radius: var(--radius-md); cursor: pointer;
    transition: background var(--bm-dur-2) var(--bm-ease-out);
}

.bm-zs__knopf--text { padding: 0 14px; }
.bm-zs__knopf:hover:not(:disabled) { background: var(--bm-row-hover); }
.bm-zs__knopf:disabled { color: var(--bm-txt-disabled); cursor: default; }
.bm-zs__knopf:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

.bm-zs__zu {
    display: flex; flex-direction: column; gap: 4px;
    background: var(--bm-srf-1); border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg); padding: 20px 22px;
}
.bm-zs__zu b { color: var(--bm-txt-1); font-size: var(--bm-t-md); }
.bm-zs__zu span { color: var(--bm-txt-2); font-size: var(--bm-t-sm); }

/* ── Das Gerüst: feste Spalte links, scrollendes Gleis rechts ───────────────────────────── */

/*
 * ⛔ DIE DREI MASSE STEHEN EINMAL, und die Zeilenhöhe wird daraus GERECHNET statt getippt.
 *    Vorher waren 40 px an vier Stellen abgeschrieben — Kopfzelle, Zeile, Balkenhöhe und der
 *    Versatz der Jetzt-Linie —, und eine Zeile, die je nach Überschneidung unterschiedlich hoch
 *    ist, hätte aus vier Zahlen vier Fehler gemacht.
 *
 *    `--zs-bahnen` setzt die Vorlage je Spur, für BEIDE Spalten mit derselben Zahl. Das ist der
 *    Grund, warum die feste Tischspalte und das Gleis in Deckung bleiben, obwohl sie zwei
 *    getrennte Bäume sind: sie rechnen mit demselben Wert, nicht mit demselben Zufall.
 */
.bm-zs {
    --zs-bahn-h: 34px;      /* eine Bahn: Balken plus Luft darunter */
    --zs-balken-h: 30px;
    --zs-luft: 5px;         /* oben und unten in der Zeile */
    --zs-leiste-h: 28px;

    display: grid; grid-template-columns: 132px minmax(0, 1fr);
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair); border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Die gemeinsame Höhenrechnung beider Spalten. */
.bm-zs__kopfzelle,
.bm-zs__zeile {
    height: calc(var(--zs-bahnen, 1) * var(--zs-bahn-h) + 2 * var(--zs-luft));
}

.bm-zs__spalte { border-right: 1px solid var(--bm-line-strong); background: var(--bm-srf-1); }

.bm-zs__ecke {
    height: var(--zs-leiste-h); display: flex; align-items: center; padding: 0 12px;
    font-size: var(--bm-t-2xs); letter-spacing: .08em; text-transform: uppercase;
    color: var(--bm-txt-3); background: var(--bm-srf-2);
    border-bottom: 1px solid var(--bm-line-hair);
}

/* ⚠️ `align-items: flex-start` mit einem Innenabstand statt zentriert: sobald eine Spur mehrere
      Bahnen hat, gehört die Tischnummer auf die Höhe der OBERSTEN Buchung — mittig gesetzt
      stünde sie bei drei Bahnen neben der zweiten und zeigte auf die falsche Zeile. */
.bm-zs__kopfzelle {
    display: flex; align-items: flex-start; gap: 8px;
    padding: calc(var(--zs-luft) + 6px) 12px 0;
    border-bottom: 1px solid var(--bm-line-hair);
}
.bm-zs__kopfzelle b { font-size: var(--bm-t-sm); color: var(--bm-txt-1); font-variant-numeric: tabular-nums; }

.bm-zs__plaetze {
    font-size: var(--bm-t-2xs); color: var(--bm-txt-3);
    background: var(--bm-srf-2); border-radius: var(--radius-sm); padding: 1px 5px;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* «Ohne Tisch» trägt eine kräftigere Trennlinie nach unten: sie ist keine weitere Zeile,
   sondern die Spur, die vom Tischplan getrennt gelesen werden muss. */
.bm-zs__kopfzelle.is-ohne { border-bottom-color: var(--bm-line-strong); }
.bm-zs__kopfzelle.is-ohne b { color: var(--bm-txt-2); font-style: italic; }

/*
 * ⛔ ROLLEN UND MESSEN SIND ZWEI EBENEN, und bis hierher war es eine — daher die Bildlaufleiste
 *    auf JEDEM Bildschirm.
 *
 *    Die Achse ist jetzt 100 % breit statt `laenge × 2px`, also passt ein Abend grundsätzlich in
 *    den Platz, den er bekommt. `--zs-min` ist die Untergrenze: acht Stunden auf einem 320-px-
 *    Telefon wären ein Zwei-Stunden-Balken von 80 px, in dem kein Name mehr steht. Erst UNTER
 *    dieser Dichte rollt es wieder.
 *
 * ⚠️ `--zs-min` MUSS AUF DER INNEREN EBENE STEHEN, nicht auf der rollenden. Die Prozentwerte der
 *    Balken, der Marken und der Jetzt-Linie beziehen sich auf ihren gemeinsamen Elternkasten;
 *    läge die Mindestbreite aussen, zeigte die Jetzt-Linie im Schmalfall neben die Buchung, auf
 *    die sie zeigt.
 */
.bm-zs__scroll { overflow-x: auto; overflow-y: hidden; }

.bm-zs__gleis { position: relative; min-width: var(--zs-min, 0); }

.bm-zs__leiste {
    position: relative; height: var(--zs-leiste-h);
    background: var(--bm-srf-2); border-bottom: 1px solid var(--bm-line-hair);
}

.bm-zs__marke { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--bm-line-hair); }
.bm-zs__marke.is-voll { background: var(--bm-line-strong); }

.bm-zs__marke span {
    position: absolute; left: 4px; top: 50%; transform: translateY(-50%);
    font-size: var(--bm-t-2xs); line-height: 1; color: var(--bm-txt-3);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

.bm-zs__zeile {
    position: relative;
    border-bottom: 1px solid var(--bm-line-hair);
}

/* Ein leiser Wechsel, damit das Auge über eine lange Zeile hinweg in seiner Spur bleibt. Bei
   zwölf Tischen ist «welche Zeile war das noch» sonst eine Rückfrage je Blick. */
.bm-zs__zeile:nth-child(even) { background: color-mix(in oklab, var(--bm-srf-2) 45%, transparent); }

.bm-zs__zeile.is-ohne { border-bottom-color: var(--bm-line-strong); background: var(--bm-srf-2); }

/* ⛔ DAS RASTER WAR LAUTER ALS DER ABEND. Elf Stunden sind vierundvierzig Viertelstundenlinien,
 *    gezogen durch JEDE Spur — bei zwölf Tischen über fünfhundert Striche, in die eine einzige
 *    Buchung als kleiner Streifen fällt. Der Bildschirm las sich als Millimeterpapier, auf dem
 *    zufällig etwas steht; die Balken waren der Grund, hier zu sein, und sahen aus wie das
 *    Beiwerk.
 *
 *    Drei Gewichte statt zwei: die volle Stunde trägt die Linie, die halbe hält 19:30 auffindbar,
 *    die Viertelstunde tritt so weit zurück, dass man sie erst sieht, wenn man einen Balken
 *    EINORDNET — und dafür reicht sie. Weggelassen wird sie nicht: ohne sie schwebt ein Balken
 *    über nichts, und genau das war der Grund, warum es sie gibt. */
/*
 * ⛔ DAS VIERTELSTUNDENRASTER MACHTE AUS DEM ABEND EINE TABELLENKALKULATION. Bei elf Stunden
 *    sind das vierundvierzig senkrechte Striche über zehn Zeilen — ein Gitter, das lauter ist
 *    als die vier Balken darin. Niemand liest auf dieser Schiene eine Viertelstunde ab; man
 *    liest «kurz nach sieben» und sieht dann in den Balken.
 *
 * ⚠️ DIE HALBEN BLEIBEN, weil «halb acht» eine Uhrzeit ist, die ein Haus wirklich benutzt.
 */
.bm-zs__gitter { display: none; }

.bm-zs__gitter.is-halb {
    display: block;
    position: absolute; top: 0; bottom: 0; width: 1px;
    background: var(--bm-line-hair); opacity: .35;
}

.bm-zs__gitter.is-voll { display: block; opacity: 1; }

/*
 * Der Schleier über dem, was vorbei ist. Er liegt über dem Grund und unter allem, was etwas
 * bedeutet.
 *
 * ⚠️ DIE STAPELUNG IST HIER NICHT NEBENSÄCHLICH. Der Schleier steht in der Vorlage NACH den
 *    Zeilen; ohne eigene Ordnung malte er sich also über die Balken, und eine laufende Sitzung
 *    sähe aus wie eine abgesagte. Grund (Raster) 0 · Schleier 1 · Balken 2 · Jetzt-Linie 3.
 */
.bm-zs__vergangen {
    position: absolute;
    top: var(--zs-leiste-h);
    bottom: 0;
    left: 0;
    z-index: 1;
    pointer-events: none;
    /*
     * ⚠️ KRÄFTIG GENUG, UM ETWAS ZU SAGEN. Der erste Versuch nahm `--bm-srf-0` bei 55 % — im
     *    dunklen Modus liegt dieser Ton fast auf dem Grund, der Schleier war praktisch
     *    unsichtbar und die Unterscheidung damit keine. Ein Hinweis, den man suchen muss, ist
     *    kein Hinweis.
     */
    background: color-mix(in oklab, #000 34%, transparent);
}

/* Im hellen Modus verdunkelt Schwarz zu hart; dort ist «vorbei» ein Grauschleier. */
:root:not(.dark) .bm-zs__vergangen {
    background: color-mix(in oklab, var(--gray-500, #6B7280) 20%, transparent);
}

/* Die Zahl in der festen Spalte: wie oft dieser Tisch heute gedeckt wird. Ruhig — sie beantwortet
   eine Frage im Vorbeigehen und soll den Tischnamen daneben nicht überstimmen. */
.bm-zs__belegt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--bm-ident-soft);
    border: 1px solid var(--bm-ident-line);
    color: var(--bm-ident);
    font-size: var(--bm-t-2xs);
    line-height: 1;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ── Die Balken ────────────────────────────────────────────────────────────────────────── */

/*
 * ⛔ `--zs-bahn` IST DER GANZE UNTERSCHIED ZWISCHEN ZWEI BUCHUNGEN UND EINEM UNLESBAREN STREIFEN.
 *
 *    Alle Balken einer Spur lagen auf derselben Zeile, absolut positioniert und alle bei
 *    `top: 5px`. Überschnitten sich zwei Sitzungen — bei zwei Stunden Sitzung also fast immer —
 *    druckte der zweite Name über den ersten. Gemessen auf der Spur «Ohne Tisch», der Spur, auf
 *    der in diesem Produkt die MEHRHEIT der Buchungen liegt: drei Buchungen zwischen 19:00 und
 *    20:00 ergaben einen Streifen, in dem zwei Namen buchstäblich übereinanderstanden.
 *
 *    Es sah nicht nach einem Fehler aus, sondern nach einem Balken mit merkwürdiger
 *    Beschriftung — und genau deshalb stand es so lange da.
 */
.bm-zs__balken {
    position: absolute;
    top: calc(var(--zs-luft) + var(--zs-bahn, 0) * var(--zs-bahn-h));
    height: var(--zs-balken-h);
    display: flex; align-items: center; gap: 6px;
    padding: 0 8px; border-radius: var(--radius-sm);
    border: 1px solid; overflow: hidden; cursor: default;
    /* Ohne diese Grenze schrumpft ein kurzer Aufenthalt zu einem Strich ohne Inhalt. */
    min-width: 44px;
    /* Damit der Balken selbst gefragt werden kann, ob die Uhrzeit noch hineinpasst. */
    container-type: inline-size;

    /* Über dem Schleier der Vergangenheit — was läuft, ist nicht vorbei. */
    z-index: 2;
}

.bm-zs__name {
    font-size: var(--bm-t-xs); line-height: var(--bm-lh-xs);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}

/*
 * DIE UHRZEIT IM BALKEN — aber nur, wenn sie den Namen nicht verdrängt.
 *
 * ⚠️ VORGABE IST «AUS». Ein Browser ohne Container-Abfragen zeigt damit genau das, was dieser
 *    Bildschirm vorher zeigte, statt einen abgeschnittenen Namen. Die Regel kann nur etwas
 *    hinzufügen, nichts wegnehmen.
 */
.bm-zs__uhr { display: none; }

@container (min-width: 118px) {
    .bm-zs__uhr {
        display: inline; flex: none;
        font-size: var(--bm-t-2xs); font-variant-numeric: tabular-nums;
        opacity: .75;
    }
}

.bm-zs__pers {
    margin-left: auto; flex: none;
    font-size: var(--bm-t-2xs); font-variant-numeric: tabular-nums;
    /* Ein Kreis, weil die Zahl sonst als Teil des Namens gelesen wird: «Familie Weber 4» ist
       ein Name mit einer Vier daran, der Kreis daneben sind vier Personen. */
    min-width: 16px; height: 16px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: color-mix(in oklab, currentColor 16%, transparent);
}

.bm-zs__balken.is-pending     { color: var(--bm-todo-fg); background: var(--bm-todo-bg); border-color: var(--bm-todo-line); }
.bm-zs__balken.is-confirmed   { color: var(--bm-wait-fg); background: var(--bm-wait-bg); border-color: var(--bm-wait-line); }
.bm-zs__balken.is-arrived     { color: var(--bm-ok-fg);   background: var(--bm-ok-bg);   border-color: var(--bm-ok-line); }
/*
 * ⛔ DIE ZUSTANDSFARBEN, NEU ZUGEORDNET — und die Regel steht seit jeher im Kopf dieser Datei:
 *    ok = fertig/läuft · wait = wartet auf jemanden, nichts ist falsch · todo = jemand muss etwas
 *    tun · unknown = wir wissen es nicht, gestrichelt und nie farbig.
 *
 *    Danach gemessen war die alte Zuordnung an drei von vier Stellen falsch:
 *
 *      angefragt  war «wait» — aber hier wartet niemand, hier muss die Wirtin ENTSCHEIDEN. todo.
 *      zugesagt   war «ok»   — grün, das stärkste Signal des Bildschirms, für eine ABSICHT. Das
 *                              Haus wartet auf den Gast; nichts ist falsch. wait.
 *      da         war «risk» — ein Gast, der gekommen ist und sitzt, in der Alarmfarbe. Es ist
 *                              der Zustand, auf den alles hinausläuft. ok.
 *      Warteliste war «todo» — dieselbe Farbe wie «angefragt», und die beiden sind nicht dasselbe:
 *                              bei der Warteliste ist gar nicht entschieden, OB daraus eine
 *                              Buchung wird. unknown, also gestrichelt und ohne Fläche.
 *
 * ⚠️ Um 20:30 fragt die Wirtin nicht «wem habe ich zugesagt», sondern «wer ist da». Das stärkste
 *    Signal gehört der Tatsache, nicht der Absicht — und dieselbe Zuordnung gilt in allen vier
 *    Flächen: Zeitschiene, Saalplan, Tabelle und beide Legenden. Drei Bildschirme mit zwei
 *    Vokabularen war der Befund, mit dem das angefangen hat.
 */
.bm-zs__balken.is-waitlisted  { color: var(--bm-unknown-fg); background: transparent; border-color: var(--bm-unknown-line); }

/* ⛔ «Da» trägt zusätzlich eine feste Kante links, «Wartet» eine gestrichelte Umrandung. Rot und
      Grün sind für etwa einen Mann von zwölf dieselbe Fläche, und «sitzt schon» von «kommt noch»
      zu unterscheiden ist genau die Auskunft, für die man auf diesen Bildschirm sieht. Dieselbe
      Regel wie beim Statusabzeichen im Tagesbuch: Farbe allein trägt hier keine Aussage. */
.bm-zs__balken.is-arrived { border-left-width: 3px; }
.bm-zs__balken.is-waitlisted { border-style: dashed; }

.bm-zs__jetzt {
    position: absolute; top: var(--zs-leiste-h); bottom: 0; width: 2px;
    background: var(--bm-risk-fg); pointer-events: none; z-index: 3;
}

/*
 * DIE UHRZEIT AN DER LINIE. Sie stand vorher nirgends, und die Frage «wie spät ist es auf
 * diesem Bild» wurde am Kopf der Achse nachgezählt — bei einer Linie, die zwischen zwei
 * Stundenmarken steht, ist das Schätzen.
 *
 * ⚠️ SIE SITZT IN DER LEISTE, NICHT IN DER ERSTEN ZEILE. Über der Achse ist der einzige Ort, an
 *    dem sie keinen Balken verdeckt — und ausgerechnet die Balken um die aktuelle Uhrzeit herum
 *    sind die, für die man hersieht.
 */
.bm-zs__jetztzeit {
    position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%);
    padding: 1px 5px; border-radius: var(--radius-sm);
    background: var(--bm-risk-fg); color: var(--bm-srf-1);
    font-size: var(--bm-t-2xs); line-height: var(--bm-lh-2xs); font-weight: 600;
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* ── Legende ───────────────────────────────────────────────────────────────────────────── */

.bm-zs__legende { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

.bm-zs__mini {
    font-size: var(--bm-t-2xs); border-radius: var(--radius-sm);
    padding: 2px 8px; border: 1px solid;
}

.bm-zs__mini.is-pending    { color: var(--bm-todo-fg); background: var(--bm-todo-bg); border-color: var(--bm-todo-line); }
.bm-zs__mini.is-confirmed  { color: var(--bm-wait-fg); background: var(--bm-wait-bg); border-color: var(--bm-wait-line); }
.bm-zs__mini.is-arrived    { color: var(--bm-ok-fg);   background: var(--bm-ok-bg);   border-color: var(--bm-ok-line);   border-left-width: 3px; }
.bm-zs__mini.is-waitlisted { color: var(--bm-unknown-fg); background: transparent; border-color: var(--bm-unknown-line); border-style: dashed; }

.bm-zs__hinweis { margin-left: auto; font-size: var(--bm-t-2xs); color: var(--bm-txt-3); }

@media (max-width: 720px) {
    .bm-zs { grid-template-columns: 92px minmax(0, 1fr); }
    .bm-zs__hinweis { margin-left: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DER SAAL — der Raum zu einer Minute.

   ⛔ DIE GRÖSSEN STEHEN IN `cqw`, NICHT IN PIXELN, und das ist die tragende Entscheidung dieses
      Blocks. Der Raum ist ein Grössenkontext (`container-type: size`); ein Tisch von 10 cqw ist
      immer ein Zehntel der Raumbreite — am 13-Zoll-Laptop wie am Tresen-Tablet. Mit Pixeln wäre
      ein Plan, der am grossen Bildschirm gezeichnet wurde, am kleinen ein Haufen sich
      überlappender Kästen gewesen, und niemand hätte den Zusammenhang gesehen.

   ⚠️ UNTERHALB VON 560 px WIRD GESCROLLT UND NICHT GESCHRUMPFT. Ein Saalplan, der auf ein
      Telefon passt, indem er die Tischnummern auf sechs Pixel verkleinert, passt nicht.

   ⚠️ DIE ZUSTANDSFARBEN SIND DIE DER ZEITSCHIENE — dieselben Token, dieselbe Bedeutung. Was dort
      ein grüner Balken ist, ist hier ein grüner Tisch.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/*
 * ── EINE LEISTE STATT ZWEIER BÄNDER ─────────────────────────────────────────────────────────
 *
 * ⛔ HIER STANDEN `.bm-sp__kopf` UND `.bm-sp__uhr` UNTEREINANDER, jede mit eigenem Rand,
 *    Polster und Abstand. Zusammen mit der Seitenüberschrift ergab das rund 290 Pixel, bevor
 *    der erste Tisch zu sehen war — auf einem 1080er Schirm lag die Terrasse damit unter der
 *    Kante. Am Bildschirm gemessen, nicht geschätzt.
 *
 * ⚠️ DER SCHIEBER IST DAS EINZIGE, WAS WACHSEN DARF (`flex: 1`). Alles andere ist so breit wie
 *    sein Inhalt; sonst wandern die Zähler bei jeder Zahländerung, und eine Leiste, in der
 *    Dinge springen, liest man nicht mehr nebenbei.
 */
.bm-sp__steuer {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
    padding: 8px 12px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
}

.bm-sp__steuer .bm-sp__regler { flex: 1 1 200px; width: auto; }

/* ⚠️ EIN STRICH TRENNT TAG VON MINUTE. Ohne ihn wäre die Leiste eine Reihe aus acht Dingen;
      mit ihm sind es drei Gruppen, die man einzeln ansieht. Der letzte Strich schiebt die
      Umschaltung nach rechts: sie ändert nicht, was man sieht, sondern was man tun kann. */
.bm-sp__trenner {
    width: 1px;
    align-self: stretch;
    min-height: 22px;
    background: var(--bm-line-hair);
}

.bm-sp__trenner:last-of-type { margin-left: auto; }

.bm-zs__knopf.is-an {
    color: var(--bm-ok-fg); background: var(--bm-ok-bg); border-color: var(--bm-ok-line);
}

/* ── Die Uhr: Schieber, Zahl, Zählwerk ─────────────────────────────────────────────────── */



.bm-sp__zeit { display: flex; align-items: center; gap: 10px; }

.bm-sp__zeit b {
    font-size: var(--bm-t-lg); line-height: 1; color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums; min-width: 3.4em;
}

.bm-sp__regler { width: 100%; accent-color: var(--bm-focus); cursor: pointer; }
.bm-sp__regler:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

.bm-sp__zahlen { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.bm-sp__zahl { font-size: var(--bm-t-2xs); color: var(--bm-txt-3); white-space: nowrap; }
.bm-sp__zahl b { font-size: var(--bm-t-sm); color: var(--bm-txt-1); font-variant-numeric: tabular-nums; }
.bm-sp__zahl.is-wartend b { color: var(--bm-todo-fg); }

/* ── Was in der Hand ist ───────────────────────────────────────────────────────────────── */

.bm-sp__hand {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px;
    color: var(--bm-ok-fg); background: var(--bm-ok-bg);
    border: 1px solid var(--bm-ok-line); border-radius: var(--radius-lg);
    padding: 8px 14px;
}
.bm-sp__hand b { font-size: var(--bm-t-sm); }
.bm-sp__hand span { font-size: var(--bm-t-xs); }
/* Ebenfalls ohne Deckkraft: bei .8 trug dieser Hinweis im hellen Modus 4.40:1 und lag damit
   unter der Schwelle — auf dem grünen Balken, der sagt, dass gerade ein Gast in der Hand ist. */
.bm-sp__hand-tipp { margin-left: auto; font-size: var(--bm-t-2xs); }

.bm-sp__wunsch {
    font-style: normal; font-size: var(--bm-t-2xs);
    background: color-mix(in oklab, currentColor 14%, transparent);
    border-radius: var(--radius-sm); padding: 1px 6px;
}

/* ── Das Gerüst: Raum links, Leiste rechts ─────────────────────────────────────────────── */

/*
 * ⛔ AUF DIESER SEITE IST DER KOPF SCHMALER — und nur auf dieser. Der Grundriss IST der
 *    Bildschirm: er beantwortet «welcher Tisch ist frei» mit einem Blick, und dafür muss er
 *    ganz zu sehen sein. Die Überschrift «Raumplan» steht ausserdem im selben Moment
 *    hervorgehoben in der Seitenleiste; sie darf hier leiser sein als auf einer Seite, die aus
 *    Text besteht.
 *
 * ⚠️ ÜBER `:has()` UND NICHT ÜBER EINE KLASSE AM BODY. Dieselbe Bauform steht ein paar hundert
 *    Zeilen weiter oben schon für die Tabellenseiten; eine zweite Art, dasselbe zu sagen, wäre
 *    die Stelle, an der die beiden irgendwann auseinanderlaufen.
 */
.fi-page:has(.bm-sp__steuer) .fi-page-header-main-ctn { padding-block: 8px 6px; row-gap: 6px; }
.fi-page:has(.bm-sp__steuer) .fi-page-content { row-gap: 8px; }

/*
 * ⛔ OHNE TRENNLINIE UND KLEINER — aber NICHT weg. Eine Seite ohne `<h1>` ist für einen
 *    Screenreader eine Seite ohne Namen; wer sie mit der Überschriftennavigation ansteuert,
 *    landet im Nichts. Die Zeile darunter nennt ausserdem den Wochentag und das Datum, und die
 *    Seitenleiste zeigt im selben Moment «Raumplan» hervorgehoben — das Wort ist hier also
 *    Beschilderung und nicht Information. Es darf leise sein.
 *
 * ⚠️ DIE LINIE FÄLLT WEG, WEIL DIE LEISTE DARUNTER SCHON EINE KANTE HAT. Zwei waagerechte
 *    Striche im Abstand von zehn Pixeln sind kein Aufbau, sondern ein Doppelbild.
 */
.fi-page:has(.bm-sp__steuer) .fi-header {
    padding-bottom: 0;
    border-bottom: 0;
}

.fi-page:has(.bm-sp__steuer) .fi-header-heading { font-size: 17px; line-height: 22px; }

.bm-sp { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 14px; align-items: start; }

/* Ohne Leiste daneben nimmt der Grundriss die ganze Breite — es gibt nichts, was daneben
   stünde. */
.bm-sp.is-breit { grid-template-columns: minmax(0, 1fr); }

/*
 * ── DIE MATERIALIEN DES RAUMS ──────────────────────────────────────────────────────────────
 *
 * ⛔ EINE EIGENE RAMPE, WEIL DIE ZUSTANDSFARBEN SCHON BESETZT SIND. Grün heisst «da sitzt
 *    jemand», Blau «zugesagt», Gelb «noch zu bestätigen», Rot «kaputt» — auf JEDEM Bildschirm
 *    dieses Panels. Eine Terrasse in Signalgrün wäre damit ein Tisch voller angekommener Gäste,
 *    und der Wirt hätte keine Möglichkeit, das anders zu lesen. Die Möbel bekommen deshalb
 *    Holz, Stein, Salbei und Schiefer: warme, entsättigte Töne, die neben den vier Signalfarben
 *    erkennbar KEINE Signalfarben sind. Der Raum wird farbig, ohne dass eine Farbe zweimal
 *    etwas bedeutet.
 *
 * ⛔ DER BODEN IST DUNKLER ALS DIE MÖBEL, UND DAS WAR DER EIGENTLICHE FEHLER DER VORFASSUNG:
 *    dort war der Boden `--bm-srf-1` und der freie Tisch AUCH `--bm-srf-1`. Zwei mal Weiss,
 *    getrennt durch eine Haarlinie — der Normalfall des Bildschirms, der Tisch ohne Gäste, war
 *    praktisch unsichtbar. Ein Grundriss liest sich wie ein Grundriss: heller Gegenstand auf
 *    dunklerem Grund.
 *
 * ⚠️ NICHTS DAVON IST DURCHSCHEINEND. `color-mix(… transparent)` hatte die Möbel zu Schemen
 *    gemacht: was hinter ihnen lag, schlug durch, und ein Tresen sah aus wie ein Fleck. Ein
 *    Gegenstand im Raum ist deckend — er verdeckt den Boden, weil er auf ihm steht.
 *
 * ⚠️ JEDE KANTE TRÄGT MINDESTENS 3:1 GEGEN DEN BODEN (WCAG 1.4.11, gerechnet, nicht geschätzt),
 *    und jede Beschriftung mindestens 4.5:1 gegen ihre eigene Fläche.
 */
:root {
    --bm-raum-boden:  #DED6C6;
    --bm-raum-gitter: #CDC2AC;
    --bm-raum-werk:   #D3CDBF;   /* Boden in der Bearbeitung: eine Spur kühler, damit man sieht,
                                    dass gerade gebaut und nicht bedient wird */

    --bm-raum-holz:      #FCF8F1;  --bm-raum-holz-k:     #8A6E48;  --bm-raum-holz-t:     #3F4750;
    --bm-raum-stein:     #EFE9DC;  --bm-raum-stein-k:    #7A7260;  --bm-raum-stein-t:    #4A5058;
    --bm-raum-salbei:    #E4EEDC;  --bm-raum-salbei-k:   #667D52;  --bm-raum-salbei-t:   #3B472F;
    --bm-raum-schiefer:  #E2E9F0;  --bm-raum-schiefer-k: #5F7387;  --bm-raum-schiefer-t: #3B4550;
    --bm-raum-tresen:    #C0A177;  --bm-raum-tresen-k:   #6B5230;  --bm-raum-tresen-t:   #2E2110;
}

.dark {
    --bm-raum-boden:  #100F0C;
    --bm-raum-gitter: #1E1C17;
    --bm-raum-werk:   #16150F;

    --bm-raum-holz:      #2B261D;  --bm-raum-holz-k:     #95805F;  --bm-raum-holz-t:     #D9CFBC;
    --bm-raum-stein:     #26231C;  --bm-raum-stein-k:    #847C69;  --bm-raum-stein-t:    #A8A296;
    --bm-raum-salbei:    #1F2719;  --bm-raum-salbei-k:   #748C5F;  --bm-raum-salbei-t:   #A3B096;
    --bm-raum-schiefer:  #1B2129;  --bm-raum-schiefer-k: #6C8296;  --bm-raum-schiefer-t: #9BA6B2;
    --bm-raum-tresen:    #3D2C16;  --bm-raum-tresen-k:   #AB864A;  --bm-raum-tresen-t:   #E8CFA6;
}

.bm-sp__buehne {
    overflow-x: auto;
    background: var(--bm-srf-1); border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);

    /*
     * ⛔ HIER STAND EINE HÖHENDECKELUNG, UND SIE WAR EIN FEHLER — der dritte an derselben
     *    Stelle. Die Idee war, den Grundriss auf die Bildschirmhöhe zu begrenzen, damit man
     *    nicht scrollen muss. Auf einem kurzen Fenster rechnete sie den Rahmen aber SCHMALER
     *    als die `min-width` des Raums: 500 Pixel Rahmen um 560 Pixel Plan. Ergebnis war genau
     *    das Gegenteil des Ziels — ein winziger Plan in der Mitte, links und rechts leere
     *    Fläche, und unten ein waagerechter Rollbalken, um den rechten Teil des Saals zu sehen.
     *
     *    Der Grundriss nimmt jetzt die volle Breite. Wer einen grossen Saal hat, will ihn gross
     *    sehen; scrollen ist der geringere Preis als ein Plan, auf dem man die Tischnummern
     *    nicht mehr lesen kann.
     */
    width: 100%;
}

.bm-sp__raum {
    position: relative; min-width: 560px; aspect-ratio: 3 / 2;
    container-type: size;

    /*
     * ⚠️ DAS SEITENVERHÄLTNIS BLEIBT 3:2 UND WIRD NICHT ZUR BILDSCHIRMFORM. Die Stellen der
     *    Tische sind Prozente von Breite und Höhe: ein Raum, der mal breiter und mal höher
     *    ist, verschöbe den Plan bei jedem Fenster anders. Gezeichnet wird auf einer festen
     *    Leinwand — die Deckelung sitzt am Rahmen darum (siehe `.bm-sp__buehne`).
     */
    width: 100%;
    /* Das Raster ist der Fussboden: es gibt dem Auge einen Massstab, ohne etwas zu behaupten. */
    background-color: var(--bm-raum-boden);
    background-image:
        linear-gradient(to right, var(--bm-raum-gitter) 1px, transparent 1px),
        linear-gradient(to bottom, var(--bm-raum-gitter) 1px, transparent 1px);
    background-size: 10% 15%;
}

/* ⛔ `touch-action` NUR BEIM BEARBEITEN. Es schaltet die Wischgeste des Browsers ab — nötig,
      damit ein Zug am Tisch nicht die Seite scrollt, und im DIENST genau falsch: dort ist das
      Wischen die einzige Art, auf einem Telefon den rechten Teil des Raums zu erreichen. */
.bm-sp__raum.is-bearbeiten { background-color: var(--bm-raum-werk); touch-action: none; }

.bm-sp__leer {
    position: absolute; inset: 0; margin: auto; width: min(80%, 420px); height: fit-content;
    display: flex; flex-direction: column; gap: 6px; text-align: center;
}
.bm-sp__leer b { color: var(--bm-txt-1); font-size: var(--bm-t-md); }
.bm-sp__leer span { color: var(--bm-txt-2); font-size: var(--bm-t-sm); }

/* ── Ein Tisch ─────────────────────────────────────────────────────────────────────────── */

.bm-sp__tisch {
    position: absolute; transform: translate(-50%, -50%);
    width: calc(var(--sp-b) * 1cqw); height: calc(var(--sp-h) * 1cqw);
    min-width: 44px; min-height: 34px;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 1px; padding: 2px 4px;
    /* Sichtbar, weil die Stühle ausserhalb stehen. Was vorher hier abgeschnitten wurde — ein
       langer Gastname —, bremst sich eine Regel weiter unten selbst. */
    overflow: visible;
    border: 1px solid; border-radius: var(--radius-md);
    cursor: pointer; user-select: none;
    transition: box-shadow var(--bm-dur-2) var(--bm-ease-out);
}

/* Beide Formen ausgeschrieben, auch die, die dem Grundwert entspricht: `is-eckig` steht im HTML,
   und eine Klasse, die auf keine Regel trifft, sucht der nächste Leser vergeblich. */
.bm-sp__tisch.is-eckig { border-radius: var(--radius-md); }
.bm-sp__tisch.is-rund { border-radius: 50%; }

.bm-sp__nummer {
    font-size: max(11px, 1.7cqw); line-height: 1.1; font-weight: 600;
    font-variant-numeric: tabular-nums; max-width: 100%;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.bm-sp__gast {
    font-size: max(9px, 1.3cqw); line-height: 1.1; max-width: 100%;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: .95;
}

.bm-sp__pers {
    font-size: max(9px, 1.2cqw); line-height: 1;
    padding: 1px 5px; border-radius: 999px;
    background: color-mix(in oklab, currentColor 16%, transparent);
    font-variant-numeric: tabular-nums;
}

/*
 * ⛔ DIE DECKKRAFT IST RAUS, UND SIE WAR EIN KONTRASTFEHLER. `opacity: .75` sollte diese Zeile
 *    leiser machen als den Namen darüber — gerechnet ergab das auf den drei Zustandsflächen
 *    3.83:1, 3.96:1 und 3.91:1. WCAG 1.4.3 verlangt 4.5:1 für Text dieser Grösse; die Zeile
 *    war also nicht leise, sondern zu blass zum Lesen, und zwar genau auf den Tischen, an
 *    denen etwas los ist.
 *
 * ⚠️ LEISER WIRD SIE WEITERHIN — über die GRÖSSE. 8 px gegen 9 px Gastname gegen 11 px
 *    Tischnummer ist eine Rangfolge, die man sieht, ohne dass etwas verblasst. Deckkraft auf
 *    Text ist fast immer der falsche Regler: sie nimmt Kontrast weg, nicht Gewicht.
 */
.bm-sp__gleich {
    font-size: max(8px, 1.1cqw); line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* ═══ DIE EINRICHTUNG DES RAUMS ══════════════════════════════════════════════════════════════
 *
 * ⛔ EIN RAUMPLAN AUS ZEHN GLEICHEN KÄSTEN BEANTWORTET NICHT, WELCHER TISCH GEMEINT IST. Eine
 *    Bedienung sagt «der Vierer neben der Tür» und «der Zweier am Tresen»; ohne Tür und Tresen
 *    ist der Plan eine Anordnung ohne Bezugspunkte, und man zählt beim Eindecken Kästen ab,
 *    statt hinzusehen.
 *
 * ⚠️ MÖBEL SIND KULISSE UND KEINE BEDIENELEMENTE. Im Dienst nehmen sie keine Zeigerereignisse
 *    an: sie sind da, damit man sich zurechtfindet, und nicht, damit man sie anklickt. Erst in
 *    der Bearbeitung werden sie fassbar.
 *
 * ⚠️ UND SIE LIEGEN UNTER DEN TISCHEN. Ein Tisch auf der Terrasse muss ÜBER ihr liegen — sonst
 *    verdeckt die Fläche, auf der er steht, den Tisch selbst.
 */
.bm-sp__moebel {
    position: absolute;
    transform: translate(-50%, -50%);
    width: calc(var(--sp-b) * 1cqw);
    height: calc(var(--sp-h) * 1cqw);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px 6px;
    border-radius: var(--radius-md);
    /*
     * ⛔ DECKEND, NICHT DURCHSCHEINEND. Vorher stand hier `color-mix(… 55%, transparent)`: das
     *    Möbelstück liess den Boden durch, das Raster lief mitten durch den Tresen, und was
     *    dahinterlag schlug hindurch. Am Bildschirm las das niemand als Gegenstand — es sah aus
     *    wie ein Fleck. Ein Ding, das im Raum steht, verdeckt den Boden.
     *
     * ⚠️ Zurückgenommen bleibt es trotzdem, aber über die FARBE statt über die Deckkraft: Stein
     *    ist ruhiger als jede Zustandsfarbe, also überstimmt die Kulisse die Tische auch dann
     *    nicht, wenn sie deckend ist.
     */
    border: 1.5px solid var(--bm-raum-stein-k);
    background: var(--bm-raum-stein);
    color: var(--bm-raum-stein-t);
    pointer-events: none;
    z-index: 0;
}

.bm-sp__moebelwort {
    font-size: max(9px, 1.2cqw);
    line-height: 1.1;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

/* Jede Art trägt ihre eigene Form, weil sie im Raum eine eigene Form hat: ein Tresen ist eine
   lange Kante, ein Durchgang eine Lücke, eine Terrasse eine Fläche im Freien. */
.bm-sp__moebel.is-tresen {
    border-radius: 999px;
    background: var(--bm-raum-tresen);
    border-color: var(--bm-raum-tresen-k);
    color: var(--bm-raum-tresen-t);
}

/* ⚠️ TÜR UND DURCHGANG SIND ÖFFNUNGEN und trotzdem deckend gezeichnet. Sie waren
      `background: transparent`, also buchstäblich nichts — auf dem Plan ein Loch mit einer
      Linie darum. Dass es eine Öffnung ist, sagt jetzt die KANTE (doppelt = Tür im Mauerwerk,
      gestrichelt = man geht hindurch), nicht die Abwesenheit von Farbe. */
.bm-sp__moebel.is-tuer      { border-style: double; border-width: 4px; }
.bm-sp__moebel.is-durchgang { border-style: dashed; }

/* Draussen: Salbei, nicht Signalgrün — sonst läse sich die Terrasse als «Gäste sind da». */
.bm-sp__moebel.is-terrasse {
    background: var(--bm-raum-salbei);
    border-color: var(--bm-raum-salbei-k);
    border-style: dashed;
    color: var(--bm-raum-salbei-t);
}

/* Hinter den Kulissen: Schiefer. Kühl, damit die Küche nicht wie Gastraum aussieht. */
.bm-sp__moebel.is-kueche {
    background: var(--bm-raum-schiefer);
    border-color: var(--bm-raum-schiefer-k);
    color: var(--bm-raum-schiefer-t);
}

.bm-sp__moebel.is-fassbar {
    pointer-events: auto;
    cursor: grab;
}

.bm-sp__moebel.is-fassbar:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

.bm-sp__moebel.is-zieht { cursor: grabbing; }

/* Der Fortnehmen-Knopf sitzt an der Ecke und ist nur in der Bearbeitung überhaupt gezeichnet. */
.bm-sp__weg {
    position: absolute;
    top: -9px;
    right: -9px;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid var(--bm-risk-line);
    background: var(--bm-srf-1);
    color: var(--bm-risk-fg);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
}

.bm-sp__weg:hover { background: var(--bm-risk-bg); }

.bm-sp__weg:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

.bm-sp__einrichtung {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    padding: 10px 12px;
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
    background: var(--bm-srf-2);
}

.bm-sp__einrichtungwort {
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--bm-txt-3);
}

.bm-sp__zugabe {
    display: inline-flex;
    align-items: center;
    min-height: var(--bm-hit);
    padding: 0 12px;
    border-radius: 999px;
    border: 1px solid var(--bm-line-strong);
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    font-size: var(--bm-t-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--bm-dur-2) var(--bm-ease-out);
}

.bm-sp__zugabe:hover { background: var(--bm-row-hover); }

.bm-sp__zugabe:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

.bm-sp__einrichtunghint {
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-3);
}

/* Rückgängig — sitzt in der Einrichtungsleiste und ist nur da, wenn es etwas zurückzunehmen gibt.
   Ein dauerhaft ausgegrauter Knopf ist ein Knopf, den man nach zwei Tagen nicht mehr sieht. */
.bm-sp__zurueck {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: var(--bm-hit);
    margin-left: auto;
    padding: 0 14px;
    border-radius: 999px;
    border: 1px solid var(--bm-ident-line);
    background: var(--bm-ident-soft);
    color: var(--bm-ident);
    font-size: var(--bm-t-sm);
    font-weight: 600;
    cursor: pointer;
}

/*
 * ⚠️ «VOR» SIEHT ANDERS AUS ALS «ZURÜCK», sonst greift der Daumen daneben. Zwei gleich
 *    aussehende Knöpfe nebeneinander, deren einer rückwärts und deren anderer vorwärts geht,
 *    sind auf einem Tablet ein Münzwurf. Umrandet statt gefüllt: die Rücknahme ist der Griff,
 *    den man sucht, das Wiederholen der, den man danach vielleicht braucht.
 */
.bm-sp__zurueck.is-vor {
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    border: 1px solid var(--bm-line-strong);
}

.bm-sp__zurueck:hover { filter: brightness(1.08); }

.bm-sp__zurueck:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* Die zwei Grössenknöpfe an einem Möbelstück. Sie sitzen an der unteren Kante, damit sie den
   Fortnehmen-Knopf oben rechts nicht berühren — zwei Ziele, die sich überlappen, sind eines. */
/*
 * ── DIE VIER GRIFFE AN DEN KANTEN ──────────────────────────────────────────────────────────
 *
 * ⛔ HIER STAND EIN PLUS/MINUS-PAAR, UND ES WAR DIE FALSCHE BEDIENUNG. Es änderte beide Seiten
 *    zugleich und um einen festen Betrag: die lange Tafel an der Wand liess sich damit nicht
 *    bauen, weil sie mit jedem Druck auch tiefer wurde. Ein Grundriss, in dem jedes Ding
 *    dasselbe Seitenverhältnis behält, beschreibt keinen Raum.
 *
 * ⚠️ VIER GRIFFE UND KEINER IN DER ECKE. Die Ecke ändert immer beides; wer den Tresen nur
 *    länger machen will, müsste dann aufpassen, seine Tiefe nicht mitzunehmen.
 *
 * ⚠️ SIE LIEGEN AUF DER KANTE, HALB DRAUSSEN. Ganz innen wären sie bei einem kleinen Zweier
 *    über der Tischnummer; ganz draussen träfe man sie zwischen zwei Tischen kaum. Und die
 *    Trefferfläche ist grösser als das, was man sieht — ein 8-px-Punkt ist mit dem Finger
 *    nicht zu treffen.
 */
.bm-sp__griff {
    position: absolute;
    z-index: 5;
    width: 14px;
    height: 14px;
    border-radius: 4px;
    background: var(--bm-srf-1);
    border: 2px solid var(--bm-focus);
    box-shadow: 0 1px 3px rgb(0 0 0 / .35);
}

/* Die unsichtbare Trefferfläche rundherum — sichtbar klein, greifbar gross. */
.bm-sp__griff::after {
    content: '';
    position: absolute;
    inset: -9px;
}

.bm-sp__griff.is-n { top: 0; left: 50%; transform: translate(-50%, -50%); cursor: ns-resize; }
.bm-sp__griff.is-s { top: 100%; left: 50%; transform: translate(-50%, -50%); cursor: ns-resize; }
.bm-sp__griff.is-w { left: 0; top: 50%; transform: translate(-50%, -50%); cursor: ew-resize; }
.bm-sp__griff.is-e { left: 100%; top: 50%; transform: translate(-50%, -50%); cursor: ew-resize; }

/* ⚠️ EIN MÖBELSTÜCK IST IM DIENST `pointer-events: none`; seine Griffe müssen sich das Recht
      zum Angefasstwerden also ausdrücklich zurückholen — sonst hängen sie sichtbar da und
      reagieren nicht. */
.bm-sp__moebel .bm-sp__griff { pointer-events: auto; }

/* ⛔ SCHMAL UND HOCH HEISST: DAS WORT STEHT HOCHKANT. Ein Durchgang ist 60 von 1000 Promille
 *    breit; waagerecht passte «Durchgang» dort nie hinein und wurde zu «DURC…». Ein Möbelstück,
 *    dessen Beschriftung man nicht lesen kann, ist kein Bezugspunkt — und Bezugspunkte sind der
 *    einzige Grund, warum es die Einrichtung auf diesem Plan gibt. */
.bm-sp__moebel.is-hoch .bm-sp__moebelwort {
    writing-mode: vertical-rl;
    text-orientation: mixed;
}

.bm-sp__stuhl {
    /*
     * ⛔ SIE SAHEN AUS WIE KONTROLLKÄSTCHEN. Quadratisch, mit dünner Kante, in gleichmässigem
     *    Abstand verstreut — am Bildschirm las das niemand als Möbel. Ein Stuhl ist BREITER ALS
     *    TIEF und hat eine Lehne; beides zusammen macht aus einem Quadrat ein Sitzmöbel, auch
     *    bei zehn Pixeln.
     */
    --stuhl: max(9px, 1.9cqw);

    position: absolute;
    width: var(--stuhl);
    /* Flacher als breit: die Sitzfläche von oben. */
    height: calc(var(--stuhl) * .72);

    /*
     * ⛔ DER ABSTAND IST EINE STUHLBREITE UND KEIN PROZENTSATZ DES TISCHES. Vorher war er ein
     *    Anteil des Tischkastens und fiel deshalb bei jedem Tisch anders aus: am breiten Vierer
     *    standen die Stühle weit im Raum, am schmalen klebten sie an der Kante. Der Anker liegt
     *    jetzt AUF der Kante, und `--dx/--dy` schieben um ein Vielfaches der eigenen Grösse —
     *    so wie im Raum, wo ein Stuhl immer eine Stuhlbreite vom Tisch steht.
     */
    transform: translate(
        calc(-50% + var(--dx, 0) * var(--stuhl)),
        calc(-50% + var(--dy, 0) * var(--stuhl))
    );

    /* Vorn die Sitzkante rund, hinten die Lehne kantig. */
    border-radius: 999px 999px 3px 3px;
    border: 1px solid currentColor;

    /*
     * ⛔ LEER HEISST LEER, ABER NICHT DURCHSICHTIG. Vorher: `transparent` bei `opacity: .5` —
     *    der leere Stuhl war ein Hauch, und weil an einem Vierer mit zwei Gästen die HÄLFTE der
     *    Stühle leer ist, war die Hälfte der Möbel im Raum kaum zu sehen. Der leere Stuhl ist
     *    jetzt ein heller Gegenstand mit klarer Kante; der Unterschied zu «da sitzt jemand»
     *    trägt weiter die FÜLLUNG, nur eben hell gegen dunkel statt sichtbar gegen unsichtbar.
     */
    background: var(--bm-raum-holz);
    border-color: var(--bm-raum-holz-k);
    opacity: .9;
    pointer-events: none;
}

/* ⛔ SO VIELE, WIE GÄSTE KOMMEN. An einem Vierer mit zwei Personen sind zwei Stühle gefüllt und
 *    zwei leer — «passt da noch jemand hin» ist damit beantwortet, ohne eine Zahl von einer
 *    anderen abzuziehen. Genau die Frage, für die es diesen Bildschirm gibt. */
.bm-sp__stuhl.is-besetzt {
    background: currentColor;
    opacity: 1;
}

/* ⛔ «Frei» IST KEINE BAUSTELLE MEHR. Der gestrichelte Rahmen las sich als Platzhalter — als
 *    wäre der Tisch noch nicht fertig eingetragen —, und auf einem Plan, auf dem fast immer die
 *    Mehrheit frei ist, sah damit der Normalfall unfertig aus. Eine ruhige Fläche mit klarer
 *    Kante ist ein leerer Tisch; die gestrichelte Linie bleibt der Bearbeitungsansicht, in der
 *    sie etwas bedeutet.
 *
 * ⚠️ «Frei» ist trotzdem eine Fläche und kein Loch: ein Tisch ohne Rahmen sähe aus, als fehlte er.
 */
.bm-sp__tisch.is-frei      { color: var(--bm-raum-holz-t); background: var(--bm-raum-holz); border-color: var(--bm-raum-holz-k); }
.bm-sp__tisch.is-pending   { color: var(--bm-todo-fg);  background: var(--bm-todo-bg);  border-color: var(--bm-todo-line); }
.bm-sp__tisch.is-confirmed { color: var(--bm-wait-fg);  background: var(--bm-wait-bg);  border-color: var(--bm-wait-line); }
.bm-sp__tisch.is-arrived   { color: var(--bm-ok-fg);    background: var(--bm-ok-bg);    border-color: var(--bm-ok-line);  border-width: 3px; }

/* ⛔ ZWEI BUCHUNGEN AUF EINEM TISCH sind der Befund, für den man einen Saalplan baut — und
      Farbe allein trägt ihn nicht: der doppelt vergebene Tisch bekommt einen Ring, den man auch
      dann sieht, wenn man Rot von Grün nicht unterscheiden kann. */
.bm-sp__tisch.is-doppelt { box-shadow: 0 0 0 3px var(--bm-risk-line); }

.bm-sp__tisch:hover { box-shadow: 0 0 0 2px var(--bm-focus); }
.bm-sp__tisch:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

.bm-sp__raum.is-bearbeiten .bm-sp__tisch { cursor: grab; }
.bm-sp__tisch.is-zieht { cursor: grabbing; box-shadow: 0 0 0 3px var(--bm-focus); z-index: 3; }

/* ── Die Leiste daneben ────────────────────────────────────────────────────────────────── */

.bm-sp__leiste {
    display: flex; flex-direction: column; gap: 8px;
    background: var(--bm-srf-1); border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg); padding: 12px 14px;
}

.bm-sp__ueberschrift {
    display: flex; align-items: center; gap: 8px; margin: 4px 0 2px;
    font-size: var(--bm-t-2xs); letter-spacing: .08em; text-transform: uppercase;
    color: var(--bm-txt-3);
}

.bm-sp__anzahl {
    font-size: var(--bm-t-2xs); letter-spacing: 0; color: var(--bm-txt-1);
    background: var(--bm-srf-2); border-radius: 999px; padding: 1px 7px;
    font-variant-numeric: tabular-nums;
}

.bm-sp__still { font-size: var(--bm-t-xs); line-height: var(--bm-lh-xs); color: var(--bm-txt-3); }

.bm-sp__vorrat { display: flex; flex-direction: column; gap: 6px; }

.bm-sp__buchung {
    display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
    width: 100%; text-align: left; padding: 7px 10px; cursor: pointer;
    border: 1px solid; border-radius: var(--radius-md);
    transition: box-shadow var(--bm-dur-2) var(--bm-ease-out);
}
.bm-sp__buchung b { font-size: var(--bm-t-xs); line-height: var(--bm-lh-xs); }
/* 4.79:1 war knapp bestanden und trotzdem derselbe Regler am falschen Ort: die Uhrzeit steht
   ohnehin kleiner und ungefettet unter dem Namen, sie braucht die Deckkraft nicht dazu. */
.bm-sp__buchung span { font-size: var(--bm-t-2xs); font-variant-numeric: tabular-nums; }

.bm-sp__buchung.is-pending   { color: var(--bm-todo-fg); background: var(--bm-todo-bg); border-color: var(--bm-todo-line); }
.bm-sp__buchung.is-confirmed { color: var(--bm-wait-fg); background: var(--bm-wait-bg); border-color: var(--bm-wait-line); }
.bm-sp__buchung.is-arrived   { color: var(--bm-ok-fg);   background: var(--bm-ok-bg);   border-color: var(--bm-ok-line);   border-left-width: 3px; }

.bm-sp__buchung:hover { box-shadow: 0 0 0 2px var(--bm-focus); }
.bm-sp__buchung:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

/* ⚠️ «In der Hand» trägt einen Ring UND ein verschobenes Polster — nicht nur eine andere Farbe.
      Der Zustand entscheidet, was der nächste Klick auf einen Tisch tut, und das darf nicht an
      einem Farbton hängen. */
.bm-sp__buchung.is-hand { box-shadow: 0 0 0 3px var(--bm-focus); padding-left: 14px; }

.bm-sp__chip {
    display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
    padding: 6px 10px; border-radius: var(--radius-md);
    border: 1px solid var(--bm-line-strong); background: var(--bm-srf-1); color: var(--bm-txt-2);
}
.bm-sp__chip b { font-size: var(--bm-t-xs); color: var(--bm-txt-1); font-variant-numeric: tabular-nums; }
.bm-sp__chip span { font-size: var(--bm-t-2xs); }
.bm-sp__chip em { margin-left: auto; font-style: normal; font-size: var(--bm-t-2xs); color: var(--bm-txt-3); }

button.bm-sp__chip { cursor: pointer; }
button.bm-sp__chip:hover { background: var(--bm-row-hover); }
button.bm-sp__chip:hover em { color: var(--bm-txt-1); }
button.bm-sp__chip:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

.bm-sp__chip.is-frei      { color: var(--bm-txt-2);   background: var(--bm-srf-1);   border-color: var(--bm-line-strong); border-style: dashed; }
.bm-sp__chip.is-pending   { color: var(--bm-todo-fg); background: var(--bm-todo-bg); border-color: var(--bm-todo-line); }
.bm-sp__chip.is-confirmed { color: var(--bm-wait-fg); background: var(--bm-wait-bg); border-color: var(--bm-wait-line); }
.bm-sp__chip.is-arrived   { color: var(--bm-ok-fg);   background: var(--bm-ok-bg);   border-color: var(--bm-ok-line); }

.bm-sp__zeile { display: flex; align-items: center; gap: 6px; }
.bm-sp__zeile b { font-size: var(--bm-t-xs); color: var(--bm-txt-1); font-variant-numeric: tabular-nums; min-width: 2.5em; }

.bm-sp__mini {
    font-size: var(--bm-t-2xs); color: var(--bm-txt-2); cursor: pointer;
    background: var(--bm-srf-2); border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-sm); padding: 2px 8px;
}
.bm-sp__mini:hover { background: var(--bm-row-hover); color: var(--bm-txt-1); }
.bm-sp__mini:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }
.bm-sp__mini.is-weg:hover { color: var(--bm-risk-fg); border-color: var(--bm-risk-line); }

.bm-sp__legfrei {
    font-size: var(--bm-t-2xs); color: var(--bm-txt-2);
    border: 1px dashed var(--bm-line-strong); border-radius: var(--radius-sm); padding: 2px 8px;
}

@media (max-width: 900px) {
    .bm-sp { grid-template-columns: minmax(0, 1fr); }
    .bm-sp__uhr { grid-template-columns: minmax(0, 1fr); gap: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   EIN SATZ, DER ETWAS ERKLÄRT — der leiseste Baustein des Panels.

   ⛔ DIESE REGEL FEHLTE, während die Klasse schon in zwei Vorlagen stand. «Kein Restaurant
      gewählt» wurde also mit den Vorgabewerten des Browsers gezeichnet: schwarz, in der Grösse
      eines Fliesstexts, mitten in einem Panel, dessen Hinweise sonst grau und klein sind.
      Nichts stürzte ab und nichts wurde rot — der Absatz sah im Editor gestaltet aus und war es
      nie. Ein Test hält das jetzt fest (PanelDesignSystemTest).
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

.bm-hint {
    font-size: var(--bm-t-sm); line-height: var(--bm-lh-sm); color: var(--bm-txt-2);
    background: var(--bm-srf-1); border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg); padding: 14px 18px;
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DREI BAUSTEINE, DIE JEDE PANEL-SEITE BRAUCHT — und die zwölf Vorlagen bis hierher als
   Tailwind-Utilities geschrieben haben, also gar nicht.

   ⛔ `mt-6`, `space-y-3` UND `flex gap-3` EXISTIEREN IM AUSGELIEFERTEN CSS NICHT. Nachgezählt
      im ausgelieferten Stand: null Treffer, in dieser Datei wie in Filaments app.css — der
      Grund steht im Dateikopf (`source(none)`, also nur `fi-*`). Die Folge stand auf zehn
      Einrichtungsseiten gleichzeitig: der Speichern-Knopf klebte ohne einen Pixel Abstand am
      letzten Eingabefeld, und die vier Absätze auf «Speisekarte aus PDF» — die Sätze, die
      erklären, dass der Import nichts löscht und die Allergenbuchstaben nur ein Vorschlag
      sind — standen als ein Block ohne Absatzabstand da.

      Es sah in der Vorlage vollständig gestaltet aus. Es war es nie. Dieselbe Fehlerklasse wie
      der ungestaltete Support-Balken oben, und `PanelTemplatesTest` macht sie jetzt rot.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* Die Knopfzeile unter einem Formular. Umbrechend, weil zwei Knöpfe mit langen deutschen
   Beschriftungen auf einem hochkant gehaltenen Tablet nebeneinander nicht ausgehen. */
/* ═══ DIE TATENLEISTE ════════════════════════════════════════════════════════════════════════
 *
 * ⛔ «SPEICHERN» STAND AUF ACHT SEITEN ZWEIMAL. Gemessen, nicht vermutet: `Appearance`,
 *    `Texts`, `Legal`, `Contact`, `OrderSettings`, `Startseite`, `ReservationSettings` und
 *    `MenuFromPdf` tragen alle `Action::make('save')` in den Kopfhandlungen UND einen
 *    Speichern-Knopf in ihrer Vorlage. Dieselbe Handlung, zwei Knöpfe, eine Seite.
 *
 * ⛔ UND DER NAHELIEGENDE FIX WÄRE FALSCH GEWESEN. Einen der beiden zu löschen heisst, sich
 *    zwischen zwei echten Bedürfnissen zu entscheiden: oben ist die Stelle, an der dieses Panel
 *    jede Handlung trägt — unten ist die Stelle, an der die Hand nach dreiundzwanzig
 *    Formularfeldern ankommt. `Startseite` hat 23, `Contact` 22, `Texts` 20. Wer den unteren
 *    Knopf streicht, schickt eine Wirtin nach jedem Tippfehler zweitausend Pixel nach oben.
 *
 *    Eine Regel löst beides: die Leiste KLEBT. Auf einer kurzen Seite passiert nichts — der
 *    Inhalt ist kürzer als das Fenster, die Leiste steht einfach am Ende. Auf einer langen
 *    bleibt sie am unteren Rand stehen, solange gescrollt wird. Der Knopf ist damit immer in
 *    Reichweite, und es gibt ihn trotzdem nur einmal.
 *
 * ⚠️ MIT EIGENEM GRUND UND EINER KANTE, weil Inhalt darunter durchläuft. Eine klebende Leiste
 *    ohne Fläche ist ein Knopf, durch den man Text lesen kann.
 */
.bm-tat {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 24px;

    position: sticky;
    bottom: 0;
    z-index: 5;
    /* Der negative Rand zieht die Fläche über das Polster der Seite hinaus, damit sie von Kante
       zu Kante deckt statt als schwebender Streifen mit Lücken links und rechts zu erscheinen. */
    margin-inline: calc(-1 * var(--bm-gap-4));
    padding: 12px var(--bm-gap-4);
    background: color-mix(in oklab, var(--bm-srf-0) 88%, transparent);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--bm-line-hair);
}

/* Fliesstext im Panel. Der Abstand steht ZWISCHEN den Absätzen und nicht auf ihnen, damit der
   erste und der letzte bündig mit dem Kasten abschliessen. */
.bm-fliess {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-2);
}

.bm-fliess > p + p { margin-top: 12px; }
.bm-fliess strong { color: var(--bm-txt-1); font-weight: 600; }

/* Ein einzelner leiser Satz INNERHALB eines Kastens — im Gegensatz zu `.bm-hint`, der sein
   eigener Kasten ist. Beides ineinander wäre ein Rahmen in einem Rahmen. */
.bm-satz {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DER ABEND AUF DER ÜBERSICHT — die meistgelesene Fläche des ganzen Panels, und bis hierher
   die einzige ohne eine einzige Stilregel.

   ⛔ DAS WAR KEIN SCHÖNHEITSFEHLER. Die Vorlage trug 41 Tailwind-Utilities
      (`grid gap-6 sm:grid-cols-2`, `text-sm`, `tabular-nums`, `truncate`, `ml-auto` …), und
      keine davon existiert. Was zwischen 17:00 und 22:00 auf dem Tresen-Tablet stand, war
      deshalb: eine Spalte statt zwei, Fliesstextgrösse statt 13 px, keine Trennlinien, keine
      Spaltenflucht für Uhrzeit und Personenzahl, und «offen» als grauer Text mitten im Satz
      statt als Pille am rechten Rand. Also genau die vier Dinge, wegen derer man eine Liste
      überfliegen kann statt sie zu lesen.

   DIE SPALTENFLUCHT IST DIE EIGENTLICHE ARBEIT HIER. Uhrzeit und Personenzahl bekommen eine
   feste Breite und Tabellenziffern, damit das Auge senkrecht durchläuft — eine Reservierungs-
   liste wird nicht gelesen, sie wird abgesucht («ist um sieben noch etwas frei»).
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

.bm-abend {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
}

/* Zwei Tage nebeneinander erst, wenn eine Spalte breit genug für einen Namen bleibt. Darunter
   untereinander — zwei halbe Spalten mit abgeschnittenen Namen sind schlechter als eine ganze. */
@media (min-width: 640px) {
    .bm-abend { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 28px; }
}

.bm-abend__kopf {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding-bottom: 6px;
    margin-bottom: 2px;
    border-bottom: 1px solid var(--bm-line-hair);
}

.bm-abend__wort {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-abend__summe {
    font-size: var(--bm-t-xs);
    color: var(--bm-txt-3);
    font-variant-numeric: tabular-nums;
}

.bm-abend__zeile {
    display: flex;
    align-items: baseline;
    gap: 10px;
    /* 36 px: die Zeile wird nicht angetippt, aber im Vorbeigehen gelesen. */
    min-height: 36px;
    padding: 6px 0;
    border-bottom: 1px solid var(--bm-line-hair);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

.bm-abend__zeile:last-child { border-bottom: 0; }

.bm-abend__uhr {
    flex: none;
    width: 3.4em;
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

.bm-abend__pers {
    flex: none;
    width: 2.6em;
    color: var(--bm-txt-3);
    font-variant-numeric: tabular-nums;
}

.bm-abend__gast {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--bm-txt-2);
}

/* ⛔ DIESELBE PILLE WIE IN DER SERVICEZEILE, und aus demselben Grund: «offen» ist auf diesem
      Bildschirm der einzige Zustand, der eine Handlung verlangt. Zwei laute Farben nebeneinander
      heissen, dass keine laut ist. */
.bm-abend__offen {
    flex: none;
    margin-left: auto;
    /* Zeichen und Wort auf einer Grundlinie — die Pille bleibt so hoch, wie sie war. */
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--bm-todo-bg);
    color: var(--bm-todo-fg);
    border: 1px solid var(--bm-todo-line);
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
}

.bm-abend__leer {
    padding: 8px 0;
    font-size: var(--bm-t-sm);
    color: var(--bm-txt-3);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   WAS NOCH OFFEN IST — die Hausaufgabenliste, ebenfalls ungestaltet ausgeliefert (35 tote
   Utilities). Sie ist der erste Bildschirm, den eine Inhaberin in ihrem Leben mit diesem
   Produkt sieht, und sie stand als schwarze Aufzählung in Fliesstextgrösse da.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

.bm-offen { display: flex; flex-direction: column; gap: 18px; }

.bm-offen__wort {
    margin-bottom: 8px;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
}

/* Die Farbe ist die Zweitauskunft; die Überschrift sagt dasselbe in Worten. Ein
   Graustufen-Screenshot unterscheidet die beiden Blöcke weiterhin. */
.bm-offen__wort.is-fehlt   { color: var(--bm-risk-fg); }
.bm-offen__wort.is-spaeter { color: var(--bm-todo-fg); }

.bm-offen__liste {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.bm-offen__punkt {
    display: flex;
    gap: 10px;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-2);
}

.bm-offen__zeichen { flex: none; }
.bm-offen__punkt.is-fehlt   .bm-offen__zeichen { color: var(--bm-risk-fg); }
.bm-offen__punkt.is-spaeter .bm-offen__zeichen { color: var(--bm-todo-fg); }

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   «SUPPORT BEENDEN» — der Knopf, der als nackter Browser-Knopf ausgeliefert wurde.

   ⛔ DER DATEIKOPF BEHAUPTET SEIT DER LETZTEN RUNDE, DIESER BALKEN SEI REPARIERT. Der KASTEN
      war es: `.fi-banner` weiter oben trägt Hintergrund, Polster und Flex-Layout. Der KNOPF
      darin trug weiterhin nur `rounded-lg bg-amber-600 px-3 py-1.5 text-xs font-semibold
      text-white shadow-sm` — acht Utilities, acht Nulltreffer. Auf der einen Meldung, die eine
      Inhaberin nicht übersehen darf, blieb ausgerechnet das Einzige ungestaltet, was sie
      ANKLICKEN kann.

      Halb repariert und für repariert gehalten ist teurer als offen kaputt.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

.bm-supportstopp {
    flex: none;
    padding: 6px 12px;
    border: 1px solid var(--bm-ident-fg);
    border-radius: var(--radius-md);
    background: var(--bm-ident-fg);
    color: var(--bm-srf-1);
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    font-weight: 600;
    cursor: pointer;
}

.bm-supportstopp:hover { opacity: .88; }

.bm-supportstopp:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DIE KONSOLE — derselbe Befund wie im Inhaber-Panel, nur eine Woche später gefunden.

   ⛔ 42 TOTE KLASSEN AUF SECHS BILDSCHIRMEN, gezählt gegen den ausgelieferten Stand. Die
      teuersten drei:

      · `.fi-code-block` GIBT ES NICHT. Der Name sieht aus wie eine Filament-Klasse und ist
        keine — null Treffer in Filaments app.css. Darin steht auf «Restaurants» der
        EINLADUNGSLINK: die einzige Kopie des 72-Stunden-Links, mit dem eine Inhaberin zum
        ersten Mal in ihr eigenes Panel kommt. Er wurde als nackter `<pre>` gezeichnet, ohne
        Fläche, ohne Polster und vor allem ohne das `overflow-x-auto`, das danebenstand: eine
        signierte URL läuft damit aus dem Kasten heraus, statt in ihm zu rollen.

      · DIE FREIGABE ist der folgenreichste Bildschirm dieses Produkts — hier wird das Geschäft
        eines fremden Menschen öffentlich geschaltet. Ihre drei Kennzahlen standen untereinander
        statt nebeneinander (`md:grid-cols-3` tot), die grosse Zahl war so gross wie der Satz
        darunter (`text-3xl` tot), und die beiden Listen «Vom Restaurant zu liefern» und «Bei
        uns» hatten keine Trennlinien und keine Ausrichtung (`divide-y`, `items-start` tot).

      · `text-sm` STAND FÜNFZEHNMAL DA und hat nie etwas getan. Jeder erklärende Satz der
        Konsole wurde in Fliesstextgrösse gezeichnet, direkt neben Filaments 13-px-Bausteinen.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* Ein Befehl oder eine Adresse zum Kopieren. Rollt WAAGERECHT statt umzubrechen: ein
   umgebrochener signierter Link wird beim Markieren mit einem Zeilenumbruch kopiert, und der
   Link ist dann kaputt — das ist der Unterschied zwischen unschön und unbrauchbar. */
.bm-code {
    overflow-x: auto;
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-1);
    /* Der Kasten steht direkt unter einem Absatz und trägt seinen Abstand selbst — sonst
       bräuchte jede Vorlage wieder eine eigene Randregel, und genau so fangen tote Utilities
       an. */
    white-space: pre;
}

/* Eine Aufzählung, in der jede Zeile aus einem Zustand und einem Sachverhalt besteht. */
.bm-liste { margin: 0; padding: 0; list-style: none; }

.bm-liste__punkt {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--bm-line-hair);
}

.bm-liste__punkt:last-child { border-bottom: 0; }

.bm-liste__kopf {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-liste__detail {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* Die Legende der Merkmalsmatrix. Vier Zustände, vier Zeilen, kein Abstand dazwischen nötig
   ausser dem, der sie als Zeilen lesbar hält. */
.bm-legende { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.bm-legende li { font-size: var(--bm-t-sm); line-height: var(--bm-lh-sm); color: var(--bm-txt-2); }
.bm-legende strong { color: var(--bm-txt-1); font-weight: 600; }

/* ── DIE FREIGABE ───────────────────────────────────────────────────────────────────────────
   Drei Kennzahlen nebeneinander, sobald Platz ist. Untereinander sind sie drei Kästen, durch
   die man scrollt, statt eines Befundes, den man in einem Blick hat. */
.bm-frg {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
}

@media (min-width: 768px) {
    .bm-frg { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.bm-frg__zahl {
    font-size: 30px;
    line-height: 36px;
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

/* ⛔ Die Farbe kommt zur Zahl hinzu, sie ersetzt sie nicht: «0» und «3» unterscheiden sich
      auch in einem Graustufen-Screenshot. */
.bm-frg__zahl.is-blockiert { color: var(--bm-risk-fg); }

.bm-frg__wort {
    margin-top: 2px;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

.bm-frg__zettel {
    display: block;
    margin-top: 20px;
    margin-bottom: 6px;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
    color: var(--bm-txt-1);
}

/* Das Feld zum Kopieren. Monospace, weil darin eine Liste steht, deren Einrückung Bedeutung
   trägt — und weil man an einer Proportionalschrift nicht sieht, wo eine Zeile endet. */
.bm-frg__feld {
    width: 100%;
    padding: 12px 14px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-strong);
    border-radius: var(--radius-lg);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-1);
    resize: vertical;
}

.bm-frg__feld:focus-visible {
    outline: var(--bm-focus-w) solid var(--bm-focus);
    outline-offset: var(--bm-focus-off);
}

/* Die eingeklappte Vollliste. Dichter als die beiden Arbeitslisten darüber, weil sie zum
   Nachschlagen da ist und nicht zum Abarbeiten. */
.bm-frg__pruef { margin: 0; padding: 0; list-style: none; }

.bm-frg__zeile {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--bm-line-hair);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

.bm-frg__zeile:last-child { border-bottom: 0; }

.bm-frg__zeichen { flex: none; width: 1.2em; text-align: center; }
.bm-frg__zeile.is-fehlt   .bm-frg__zeichen { color: var(--bm-risk-fg); }
.bm-frg__zeile.is-spaeter .bm-frg__zeichen { color: var(--bm-todo-fg); }
.bm-frg__zeile.is-ok      .bm-frg__zeichen { color: var(--bm-ok-fg); }

.bm-frg__was { font-weight: 600; color: var(--bm-txt-1); }

.bm-frg__wer {
    flex: none;
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    color: var(--bm-txt-3);
    border: 1px solid var(--bm-line-hair);
    border-radius: 999px;
    padding: 1px 8px;
}

/* ── «HIER ARBEITEN» VERLASSEN ──────────────────────────────────────────────────────────────
   Derselbe Fall wie «Support beenden» im Inhaber-Panel: der Balken war gestaltet, der Ausgang
   daraus nicht. `fi-link fi-size-sm` gehört Filament und trägt Farbe und Grösse; hier fehlte
   nur, dass der Link nicht schrumpft, wenn der Satz daneben lang wird. */
.bm-raus { flex: none; text-decoration: underline; }

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DIE MD2-SCHICHT — dasselbe Panel, in einem anderen Register.

   ⛔ WAS HIER PASSIERT UND WAS AUSDRÜCKLICH NICHT. Auftrag war: dieses Panel soll aussehen und
      sich anfühlen wie Material Dashboard 2, weil es an Restaurants VERKAUFT wird und der
      Inhaber es nicht mit einem Terminal vergleicht, sondern mit der Software, die er sonst
      bezahlt. Geändert wird deshalb das REGISTER: Ecken, Höhe über der Fläche, Rhythmus,
      Kennzahlkarten, Knöpfe.

      NICHT geändert wird, was in dieser Datei eine gemessene Aussage trägt:

      · die Kontrastwerte der Token — sie sind gerechnet, nicht geschätzt
      · «Farbe allein trägt nie eine Aussage» — jeder Zustand behält sein zweites Signal
      · «Marken statt Pillen» (Abschnitt 8) — Material würde hier bunte Pillen setzen; die
        Entscheidung dagegen steht mit Begründung da und bleibt
      · die Trefferflächen (`--bm-hit`) und der Dichtehebel (`--bm-row-pad`)

      Ein Referenzdesign ist ein Massstab, kein Vorgesetzter.

   ⚠️ DIESE SCHICHT STEHT AM ENDE DER DATEI, und das ist keine Bequemlichkeit: sie überschreibt
      absichtlich frühere Regeln DIESER Datei (etwa `box-shadow: none` auf Karten aus
      Abschnitt 7). Bei gleicher Spezifität gewinnt die spätere Regel. Wer hier aufräumt und die
      Schicht nach oben schiebt, dreht das Panel wieder auf flach.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · Flächen liegen auf der Seite, statt in sie eingezeichnet zu sein ────────────────── */

/*
 * ⛔ DER RAHMEN WIRD DURCHSICHTIG, NICHT ENTFERNT. Ein `border: none` würde die Karte um zwei
 *    Pixel schrumpfen lassen und jede Ausrichtung daneben um denselben Betrag verschieben —
 *    die Sorte Änderung, die man erst auf dem dritten Bildschirm sieht. Durchsichtig behält
 *    den Platz und gibt die Kante an den Schatten ab.
 *
 * ⚠️ IM DUNKELMODUS ÜBERNIMMT DIE KANTE WIEDER DER RING: `--bm-lift-*` trägt dort ein
 *    `inset 0 0 0 1px rgba(255,255,255,…)`, weil Schwarz unter Schwarz nichts trennt.
 */
.fi-ta-ctn,
.fi-section:not(.fi-section-not-contained):not(.fi-aside) {
    border-color: transparent;
    box-shadow: var(--bm-lift-1);
}

/* Eine Karte unter dem Zeiger hebt sich — nur die anklickbaren, sonst wippt die halbe Seite. */
a.fi-section:hover,
.fi-section.fi-clickable:hover {
    box-shadow: var(--bm-lift-2);
}

/*
 * MEHR LUFT IM ABSCHNITT. Material lebt von Weissraum; dieses Panel war auf Dichte getrimmt,
 * weil es an einer Theke bedient wird. Der Kompromiss: die KARTE bekommt Luft, die TABELLE
 * behält ihre Dichte — dort ist Dichte eine gemessene Verbesserung (99 px → 65 px je Zeile,
 * 8 → 12 sichtbare Zeilen auf 1080 px) und keine Sparsamkeit.
 */
.fi-section-content {
    padding: var(--bm-gap-5) var(--bm-gap-6);
}

.fi-section-header {
    padding: var(--bm-gap-5) var(--bm-gap-6) 0;
}

.fi-section-header + .fi-section-content {
    padding-top: var(--bm-gap-4);
}

/*
 * Die Überschrift einer Karte ist eine Überschrift und keine Zeile: Material setzt sie
 * halbfett und deutlich grösser als den Inhalt darunter.
 */
.fi-section .fi-section-header-heading {
    font-size: var(--bm-t-lg);
    line-height: var(--bm-lh-lg);
    letter-spacing: -.01em;
}

.fi-section .fi-section-header-description {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* Was schwebt, schwebt sichtbar. */
.fi-dropdown-panel { box-shadow: var(--bm-lift-3); }
.fi-modal-window { box-shadow: var(--bm-lift-4); }

/* ── 2 · Die Kennzahlkarte — die eine Form, an der man Material sofort erkennt ───────────── */

/*
 * ⛔ DIE KACHEL IST DAS GANZE ZEICHEN. Material Dashboard setzt über jede Kennzahl ein farbiges,
 *    abgerundetes Quadrat mit einem weissen Icon, das über die obere Kante der Karte HINAUSRAGT
 *    und einen eigenen, kräftigeren Schatten trägt. Ohne diesen Überstand ist es eine Karte mit
 *    einem Icon darin — mit ihm ist es die Karte, die man wiedererkennt.
 *
 * ⛔ SIE HÄNGT AM `->icon(…)` DER STATISTIK, nicht an einem eigenen Element: Filaments Vorlage
 *    rendert genau dann ein `<svg>` als direktes Kind von `.fi-wi-stats-overview-stat-label-ctn`.
 *    Eine Kennzahl OHNE Icon liesse hier ein 60 px breites Loch — deshalb tragen alle Statistiken
 *    dieses Projekts eines (`HeuteInZahlen`, `PlattformInZahlen`), und deshalb steht der Abstand
 *    unten an einer Regel, die das leere Loch wieder zumacht.
 *
 * ⚠️ DIE FARBE KOMMT AUS EINER KLASSE AM WURZELELEMENT (`bm-stat--ok` …), gesetzt über
 *    `->extraAttributes()`. Filaments `->color()` färbt NUR die Beschreibungszeile — es an die
 *    Kachel zu hängen hätte bedeutet, die Zustandsfarbe zweimal zu vergeben, einmal je Ort.
 */
.fi-wi-stats-overview-stat {
    position: relative;
    padding: var(--bm-gap-4);
    /* Platz, in den die Kachel hineinragen darf. Ohne ihn schneidet die Karte darüber sie ab.
       24 px = der Überstand des Vorbilds (`mt={-3}` auf der Icon-Box). */
    margin-top: 24px;
    border-radius: var(--radius-lg);
    background-color: var(--bm-srf-1);
    border: 1px solid transparent;
    box-shadow: var(--bm-lift-1);
    overflow: visible;
    transition: box-shadow var(--bm-dur-3) var(--bm-ease-out);
}

a.fi-wi-stats-overview-stat:hover { box-shadow: var(--bm-lift-2); }

.fi-wi-stats-overview-stat-content {
    display: block;
}

/*
 * Beschriftung und Zahl stehen RECHTS, neben der Kachel — Materials Anordnung, und sie hat
 * einen praktischen Grund: die Zahlen mehrerer Karten stehen damit auf einer Fluchtlinie und
 * lassen sich vergleichen, statt an unterschiedlich langen Beschriftungen zu kleben.
 */
.fi-wi-stats-overview-stat-label-ctn,
.fi-wi-stats-overview-stat-value {
    padding-left: 72px;
    text-align: right;
}

.fi-wi-stats-overview-stat-label-ctn {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    min-height: 18px;
}

.fi-wi-stats-overview-stat-label {
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--bm-txt-3);
}

.fi-wi-stats-overview-stat-value {
    margin-top: 2px;
    font-size: 26px;
    line-height: 32px;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

/* Die Kachel selbst. */
/* 64 px und −24 px Überstand: die Masse der Icon-Box des Referenzentwurfs (4rem, `mt={-3}`). */
.fi-wi-stats-overview-stat-label-ctn > svg {
    position: absolute;
    top: -24px;
    left: var(--bm-gap-4);
    width: 64px;
    height: 64px;
    padding: 17px;
    border-radius: var(--radius-lg);
    color: #FFFFFF;
    background-image: linear-gradient(195deg, var(--bm-kachel-a), var(--bm-kachel-b));
    box-shadow: var(--bm-lift-kachel);
}

/*
 * ⛔ DIE KACHELFARBEN SIND FESTE WERTE UND FOLGEN NICHT DEN ZUSTANDSTOKEN. Die Token wechseln im
 *    Dunkelmodus ins Helle, weil sie dort auf dunklem Grund als TEXT lesbar sein müssen. Die
 *    Kachel ist kein Text auf der Karte, sondern eine eingefärbte Fläche mit weisser Schrift —
 *    sie muss in beiden Modi dieselbe kräftige Farbe behalten, sonst wird aus dem grünen Quadrat
 *    im Dunkelmodus ein blasses. Weiss auf jedem dieser Werte trägt über 4.5:1.
 */
/*
 * ⚠️ HIER STANDEN ZUERST DIE ZUSTANDSFARBEN DES PANELS (#05603A …) — und das war zu dunkel. Der
 *    Referenzentwurf setzt deutlich hellere, gesättigtere Verläufe (`success #66BB6A → #43A047`,
 *    `info #49a3f1 → #1A73E8`); nachgelesen in `src/assets/theme/base/colors.js`. Neben denen
 *    sahen meine Kacheln aus wie ausgeschaltete.
 *
 * ⛔ ABER NICHT EINS ZU EINS ÜBERNOMMEN, und zwar aus einem gemessenen Grund: Weiss auf dem
 *    HELLEN Ende der Referenzverläufe trägt zu wenig. Gerechnet:
 *
 *        #49a3f1 (info)    2.70:1        #FB8C00 (warning) 2.40:1
 *        #66BB6A (success) 3.30:1        #EF5350 (error)   3.55:1
 *
 *    Für ein Icon gilt WCAG 1.4.11 mit 3:1 — zwei dieser vier fallen darunter. Ein Entwurf zu
 *    kopieren, der an dieser Stelle nachweislich zu schwach ist, wäre kein Redesign, sondern ein
 *    übernommener Fehler. Diese Werte liegen dazwischen: sichtbar heller als vorher, und jedes
 *    helle Ende trägt Weiss mit mindestens 3.2:1 (gerechnet, nicht geschätzt).
 */
.fi-wi-stats-overview-stat { --bm-kachel-a: #4A5464; --bm-kachel-b: #262C36; }
.fi-wi-stats-overview-stat.bm-stat--ok   { --bm-kachel-a: #2E9E63; --bm-kachel-b: #17794A; }  /* 3.39:1 */
.fi-wi-stats-overview-stat.bm-stat--wait { --bm-kachel-a: #2F7FE0; --bm-kachel-b: #1A5FB8; }  /* 4.01:1 */
.fi-wi-stats-overview-stat.bm-stat--todo { --bm-kachel-a: #D07B0A; --bm-kachel-b: #9A5208; }  /* 3.22:1 */
.fi-wi-stats-overview-stat.bm-stat--risk { --bm-kachel-a: #D8453A; --bm-kachel-b: #A4160C; }  /* 4.35:1 */

/*
 * ⚠️ FÄLLT DIE KACHEL WEG, FÄLLT AUCH IHR PLATZ WEG. Eine Statistik ohne `->icon()` hätte sonst
 *    60 px Leerraum links, in dem nichts steht — und das sieht nach einem fehlenden Bild aus,
 *    nicht nach einer Entscheidung. `:not(:has(> svg))` fängt genau diesen Fall.
 */
.fi-wi-stats-overview-stat-label-ctn:not(:has(> svg)),
.fi-wi-stats-overview-stat-label-ctn:not(:has(> svg)) + .fi-wi-stats-overview-stat-value {
    padding-left: 0;
}

/*
 * Die Vergleichszeile unter einem Trennstrich, der bis an die Kartenkante läuft — Materials
 * Gliederung: oben die Zahl von heute, unten der Satz, was sie bedeutet.
 */
.fi-wi-stats-overview-stat-description {
    margin: var(--bm-gap-3) calc(var(--bm-gap-4) * -1) 0;
    padding: var(--bm-gap-3) var(--bm-gap-4) 0;
    border-top: 1px solid var(--bm-line-hair);
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    color: var(--bm-txt-3);
}

.fi-wi-stats-overview-stat-description > svg {
    width: 16px;
    height: 16px;
    flex: none;
}

/*
 * ⛔ DER VERLAUF FRANSTE UNTEN AUS UND MACHTE DIE REIHE UNGLEICH HOCH.
 *
 *    Zwei Fehler auf einmal, beide erst am Abzug zu sehen: die Kurve lief bis an die Kante der
 *    Karte und schnitt dort ab, weil die Ecke rund ist und die Leinwand es nicht weiss — das
 *    sah nach einem halb geladenen Bild aus. Und weil nur ZWEI der vier Kennzahlen eine
 *    Geschichte haben (die anderen beiden sind Zustände von jetzt), standen zwei Kacheln 44 px
 *    höher als ihre Nachbarn: eine Reihe mit ausgefranstem Unterrand.
 *
 *    Jetzt ist der Vollrand eine ENTSCHEIDUNG: die Kurve sitzt als eigenes Band am Fuss der
 *    Karte, in den unteren Ecken sauber beschnitten, mit einem Hauch Ton darunter. Und die
 *    Karte reserviert die Höhe für alle vier — `margin-top: auto` schiebt das Band nach unten,
 *    `min-height` hält die Reihe auf einer Linie, auch wo keine Kurve steht.
 */
.fi-wi-stats-overview-stat {
    display: flex;
    flex-direction: column;
    min-height: 168px;
}

.fi-wi-stats-overview-stat-chart {
    margin: auto calc(-1 * var(--bm-gap-4)) calc(-1 * var(--bm-gap-4));
    height: 44px;
    overflow: hidden;
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    background: color-mix(in oklab, var(--bm-srf-2) 60%, transparent);
}

/* ── 3 · Knöpfe ─────────────────────────────────────────────────────────────────────────── */

/*
 * Material-Knöpfe sind klein, halbfett, mit Laufweite und einem Schatten, der beim Zeigen
 * wächst. Die GRÖSSE bleibt, wie sie war — `--bm-hit` ist eine Trefferfläche und keine
 * Geschmacksfrage.
 *
 * ⚠️ KEINE GROSSBUCHSTABEN. Material schreibt Knöpfe in Versalien; auf Deutsch ist das eine
 *    schlechte Idee — «Zusagen» und «Absagen» unterscheiden sich dann nur noch am ersten
 *    Buchstaben, und zusammengesetzte Wörter («Speisekarte veröffentlichen») werden in Versalien
 *    messbar langsamer gelesen. Laufweite und Schnitt tragen dieselbe Anmutung ohne den Preis.
 */
.fi-btn {
    font-weight: 600;
    letter-spacing: .01em;
    box-shadow: var(--bm-lift-1);
    transition: box-shadow var(--bm-dur-2) var(--bm-ease-out),
                transform var(--bm-dur-2) var(--bm-ease-out);
}

.fi-btn:hover { box-shadow: var(--bm-lift-2); }
.fi-btn:active { transform: translateY(1px); box-shadow: var(--bm-lift-1); }

/* Ein Textknopf ist keine Fläche und bekommt keinen Schatten. */
.fi-btn.fi-link,
.fi-btn:disabled,
.fi-btn[aria-disabled="true"] { box-shadow: none; }

.fi-btn:disabled:active,
.fi-btn[aria-disabled="true"]:active { transform: none; }

/* ── 4 · Der Seitenkopf ─────────────────────────────────────────────────────────────────── */

/*
 * Material stellt den Seitentitel gross und ruhig über den Inhalt, mit dem Brotkrumenpfad als
 * kleiner Zeile darüber. Der Pfad ist hier bereits Beschilderung (Abschnitt 6); was fehlte, war
 * das Gewicht des Titels — er wog genauso viel wie eine Kartenüberschrift.
 */
.fi-header-heading {
    font-size: 24px;
    line-height: 32px;
    font-weight: 700;
    letter-spacing: -.02em;
}

.fi-header-subheading {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* Mehr Luft zwischen den Bänken einer Seite — Materials Rhythmus, ein Vielfaches von 4. */
.fi-page-content { row-gap: var(--bm-gap-6); }

/* ── 5 · Tabelle ────────────────────────────────────────────────────────────────────────── */

/*
 * Der Kopf war schon richtig (11 px, Versalien, Laufweite — Abschnitt 7). Was fehlte, ist der
 * Abstand der Werkzeugleiste zum Inhalt und eine Zeile, die beim Zeigen antwortet.
 */
.fi-ta-header-ctn { padding-bottom: var(--bm-gap-1); }

.fi-ta-row { transition: background-color var(--bm-dur-1) var(--bm-ease-out); }

/*
 * ⚠️ DIE ERSTE UND LETZTE ZELLE BEKOMMEN DEN RADIUS DER KARTE ZURÜCK. Mit 12 px Kartenradius
 *    stösst eine Kopfzelle mit rechtem Winkel sichtbar über die Rundung hinaus — bei 6 px fiel
 *    das nicht auf, bei 12 px ist es die auffälligste Kante der Seite.
 */
.fi-ta-table > thead > tr > th:first-child { border-top-left-radius: var(--radius-lg); }
.fi-ta-table > thead > tr > th:last-child { border-top-right-radius: var(--radius-lg); }

/* ── 6 · Die Navigation im MD2-Register ─────────────────────────────────────────────────── */

/*
 * ⛔ DER AKTIVE PUNKT WIRD EINE GEFÜLLTE FLÄCHE. Vorher trug er eine getönte Fläche, ein
 *    halbfettes Etikett, ein eingefärbtes Symbol und eine 3-px-Marke an der Gehäusekante — vier
 *    leise Signale, von denen jedes einzeln kaum auffällt. Material löst dieselbe Frage mit
 *    einem Signal, das man nicht übersehen kann: der Punkt, auf dem man steht, ist ein
 *    ausgefüllter, abgerundeter Balken mit weisser Schrift und einem eigenen Schatten.
 *
 *    «The active page must be immediately recognizable» war die Anforderung, und das ist der
 *    Unterschied zwischen «man findet es, wenn man sucht» und «man sieht es beim Hinsehen».
 *
 * ⛔ DIE MARKE AN DER KANTE ENTFÄLLT DAMIT — und das nimmt der Regel «Farbe allein trägt nie
 *    eine Aussage» NICHTS weg. Der gefüllte Balken ist eine FORM, kein Farbton: im
 *    Graustufen-Screenshot bleibt er die einzige dunkle Fläche der Schiene. Die 3-px-Marke war
 *    das zweite Signal zur getönten Fläche; die Füllung ersetzt beide.
 *
 * ⚠️ KEINE KACHEL UNTER DEM SYMBOL, obwohl Material dort eine setzt. Sie bräuchte Polster, und
 *    das Polster verschiebt `--bm-rail-icon` — an dem hängt die Verbindungslinie der
 *    symbollosen Untereinträge, deren Geometrie weiter oben in dieser Datei auf den Pixel
 *    ausgerechnet ist (Reichweite 9 px gegen eine Lücke von 10 bzw. 14). Eine Kachel hier hiesse,
 *    diese Rechnung ein zweites Mal zu führen, für einen Effekt, den der gefüllte Balken bereits
 *    liefert.
 */

/*
 * ⛔ EIGENE TOKEN FÜR DIE FÜLLUNG, statt `--bm-rail-ident` zu benutzen — und der Grund ist der
 *    Dunkelmodus. Dort dreht die Identitätsfarbe ins Helle (#8FBAEE bzw. #EDB265), weil sie auf
 *    dunklem Grund als TEXT lesbar sein muss. Weisse Schrift darauf trüge etwa 1.9:1: ein
 *    aktiver Menüpunkt, den man im Dunkelmodus nicht lesen kann. Diese beiden Werte bleiben in
 *    beiden Modi dunkel; Weiss darauf trägt 6.2:1 (Theke) bzw. 9.1:1 (Konsole), gerechnet.
 */
body.fi-panel-operator { --bm-nav-sel-a: #2B3949; --bm-nav-sel-b: #47576F; }
body.fi-panel-owner { --bm-nav-sel-a: #7C440C; --bm-nav-sel-b: #B8690F; }

.fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    background-color: transparent;
    background-image: linear-gradient(195deg, var(--bm-nav-sel-a), var(--bm-nav-sel-b));
    box-shadow: var(--bm-lift-kachel);
    border-radius: var(--radius-md);
}

.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-sidebar-item-label,
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-icon {
    color: #FFFFFF;
}

/* Der Punkt-Platzhalter symbolloser Einträge liegt jetzt AUF der Füllung und braucht ihre Farbe. */
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn > .fi-sidebar-item-grouped-border > .fi-sidebar-item-grouped-border-part {
    background-color: rgba(255, 255, 255, .85);
}

/* Die Kantenmarke ist mit der Füllung überflüssig geworden — ausführlich oben. */
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn::before { content: none; }

/*
 * Gruppenüberschriften bekommen Materials Beschriftungsmass: kleiner, weiter, ruhiger — und mehr
 * Luft darüber, damit die Schiene in Blöcke zerfällt statt in eine Liste.
 */
.fi-sidebar-nav-groups { row-gap: var(--bm-gap-5); }

.fi-sidebar-group-label {
    font-size: var(--bm-t-2xs);
    letter-spacing: .09em;
}

/* Ein Menüpunkt bekommt etwas mehr Luft — Materials Rhythmus, ohne die Trefferfläche zu ändern. */
.fi-sidebar-item-btn { padding-block: var(--bm-gap-2); }

/*
 * ⚠️ DIE SCHIENE BEHÄLT DAS «L» MIT DER KOPFLEISTE. Material stellt sie als schwebende Karte mit
 *    Abstand zum Fensterrand; das sähe hier gut aus und würde die Entscheidung aus Abschnitt 4
 *    umwerfen, in der Kopfleiste und Schiene bewusst EINE Fläche sind. Die Anmutung, um die es
 *    geht, hängt am aktiven Punkt und am Rhythmus — nicht daran, ob die Schiene schwebt.
 */

/* ── 7 · Leere Zustände ─────────────────────────────────────────────────────────────────── */

/*
 * ⛔ «KEINE DATEN» IST EIN GESTALTETER ZUSTAND, KEINE LEERE SEITE. Filaments leerer Zustand ist
 *    korrekt aufgebaut und optisch still: ein kleines Symbol, zwei Zeilen, alles in derselben
 *    Grösse wie eine Tabellenzeile. Auf einem Bildschirm, der sonst getragene Karten zeigt, liest
 *    sich das wie ein Ladefehler — und «heute keine Reservierung» ist keiner, sondern eine
 *    Auskunft.
 */
.fi-ta-empty-state,
.fi-empty-state { padding-block: var(--bm-gap-8); }

.fi-ta-empty-state-icon-ctn,
.fi-empty-state-icon-ctn {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background-color: var(--bm-srf-2);
    color: var(--bm-txt-3);
    display: flex;
    align-items: center;
    justify-content: center;
}

.fi-ta-empty-state-heading,
.fi-empty-state-heading {
    font-size: var(--bm-t-lg);
    line-height: var(--bm-lh-lg);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.fi-ta-empty-state-description,
.fi-empty-state-description {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* ── 8 · Die schwebende Schiene ─────────────────────────────────────────────────────────── */

/*
 * ⛔ DIE SCHIENE WIRD EINE KARTE, DIE AUF DER SEITE LIEGT — die auffälligste Struktureigenschaft
 *    des Referenzentwurfs, und die einzige, die man auf einem Bildschirmfoto aus zehn Metern
 *    erkennt: abgerundetes Gehäuse mit Abstand zum Fensterrand, darunter die Seitenfläche.
 *
 * ⚠️ DAS «L» AUS ABSCHNITT 4 WIRD DAMIT AUFGELÖST, und das ist eine bewusste Umkehr. Die
 *    Begründung dort war richtig und bleibt lesenswert: eine volle Kopfleiste hat keine
 *    Abhängigkeit von `--sidebar-width` und keine Ausnahmekette. Sie verschwindet hier auch
 *    nicht — die Kopfleiste bleibt volle Breite, sie wird nur DURCHSICHTIG. Damit gilt jedes
 *    Argument von damals weiter (kein Rechnen auf die Schienenbreite, kein dunkler Klotz bei
 *    eingeklappter Schiene, Banner bleiben der obere Rand), und die Schiene liegt trotzdem frei.
 *
 * ⛔ AUSSCHLIESSLICH AB 64rem. Darunter ist die Schiene eine eingeschobene Schublade, die den
 *    Bildschirm von der Kante her überdeckt — eine Schublade mit 12 px Luft ringsum und
 *    abgerundeten Ecken sähe aus wie ein Fenster, das nicht ganz aufgegangen ist. Filament
 *    schaltet an derselben Grenze; alles hier steht in derselben Abfrage.
 */
@media (min-width: 64rem) {
    /*
     * Die Kopfleiste gibt ihre Fläche ab. Ohne das bliebe über der schwebenden Karte ein
     * gehäusefarbener Balken stehen, und die Karte sähe aus, als hinge sie daran.
     */
    .fi-topbar {
        background-color: transparent;
        border-bottom-color: transparent;
    }

    .fi-body-has-topbar .fi-sidebar {
        top: calc(var(--bm-topbar-h) + 12px);
        height: calc(100dvh - var(--bm-topbar-h) - 24px);
        margin-inline-start: 12px;
        border-inline-end: none;
        border-radius: var(--radius-xl);
        box-shadow: var(--bm-lift-3);
        /* Der Inhalt darf die gerundeten Ecken nicht überschiessen — die Navigationsliste
           scrollt, und ein scrollender Eintrag würde sonst über die Rundung hinauslaufen. */
        overflow: hidden;
    }

    /*
     * ⚠️ DIE SCHIENE IST JETZT SCHMALER ALS IHRE SPALTE, weil der Abstand aus ihrer eigenen
     *    Breite kommt. Das ist die kleinere Änderung: `--sidebar-width` anzufassen hiesse, jede
     *    Rechnung anzufassen, die darauf steht — unter anderem die Breitenbegrenzung der Marke
     *    weiter oben in dieser Datei.
     *
     * ⛔ UND `.fi-main` WIRD AUSDRÜCKLICH NICHT ANGEFASST. Hier stand einen Moment lang
     *    `padding-inline-start: 12px`, in der Absicht, dem Inhalt Luft zur schwebenden Schiene
     *    zu geben. Nachgesehen in app.css: `@media (min-width:64rem){ .fi-main{ padding-inline:
     *    calc(var(--spacing) * 8) } }` — also bereits 32 px auf BEIDEN Seiten. Die Zeile hätte
     *    den Abstand nicht vergrössert, sondern von 32 auf 12 px VERKLEINERT, und zwar nur
     *    links: der Inhalt wäre an die Schiene gerückt und die Seite unsymmetrisch geworden.
     */
}

/* ── 9 · Die Diagrammkarte ──────────────────────────────────────────────────────────────── */

/*
 * ⛔ WAS HIER BEWUSST NICHT ÜBERNOMMEN WIRD, und die Begründung ist wichtiger als die Regel:
 *    Material stellt seine Diagramme auf einen SATTEN FARBVERLAUF und zeichnet die Kurve weiss
 *    darauf. Das ist das Bild, an das man beim Referenzentwurf zuerst denkt — und es funktioniert
 *    dort, weil jede dieser Karten GENAU EINE Reihe zeigt.
 *
 *    Das Diagramm dieses Panels zeigt ZWEI: Umsatz als Balken und Gäste als Linie, auf zwei
 *    Achsen. Auf einem dunklen Verlauf müssten beide weiss sein — und damit wäre die eine Frage,
 *    für die man auf dieses Bild sieht («läuft der Umsatz mit den Gästen mit, oder auseinander»),
 *    nicht mehr zu beantworten. Ein Entwurf zu übernehmen, der die Aussage des Bildes löscht,
 *    ist kein Redesign.
 *
 *    Die Auswertungsseite bringt einreihige Diagramme mit; DIE bekommen den Verlauf.
 *
 * ⚠️ WAS ÜBERNOMMEN WIRD, ist der Rahmen: die Zeichenfläche liegt als eigener, abgesetzter Block
 *    IN der Karte, mit Luft ringsum — statt bündig zwischen Überschrift und Kartenrand zu kleben.
 *    Das ist Materials Gliederung, und sie kostet keine Aussage.
 */
.fi-wi-chart .fi-section-content {
    padding: var(--bm-gap-4);
}

.fi-wi-chart .fi-section-content > div:has(> canvas),
.fi-wi-chart .fi-section-content > canvas {
    padding: var(--bm-gap-3);
    border-radius: var(--radius-lg);
    background-color: var(--bm-srf-2);
}

/*
 * Die Beschreibung unter der Überschrift ist bei Material die Zeile, die das Bild EINORDNET
 * («+15 % gegenüber letzter Woche»), nicht ein zweiter Titel. Sie steht deshalb klein und ruhig.
 */
.fi-wi-chart .fi-section-header-description {
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
}

/* ── 10 · Die Tabelle im MD2-Register ───────────────────────────────────────────────────── */

/*
 * Materials Tabelle hat KEINE senkrechten Linien und nur sehr leise waagerechte: die Spalten
 * werden von der Ausrichtung getragen, nicht von einem Gitter. Das ist auch der Unterschied
 * zwischen «Datenblatt» und «Übersicht» — und dieses Panel zeigt Übersichten.
 *
 * ⛔ DAS POLSTER BLEIBT, WO ES IST. `--bm-row-pad` sitzt in `.fi-ta-text` und NICHT auf der
 *    Zelle; die Rechnung dazu steht weiter oben und ist im Browser nachgemessen (99 px → 65 px).
 *    Wer hier `padding` auf `.fi-ta-cell` legt, addiert statt zu ersetzen und macht die Zeile
 *    wieder hoch — ein Test hält genau das fest.
 */
.fi-ta-table > tbody > tr:last-child > td { border-bottom: none; }

/*
 * Die Werkzeugleiste über der Tabelle — Suche, Filter, Aktionen. Bei Material ist das eine
 * eigene Zeile mit Luft, nicht ein Streifen, der am Tabellenkopf klebt.
 */
.fi-ta-header-ctn {
    padding-inline: var(--bm-gap-5);
    padding-block: var(--bm-gap-4) var(--bm-gap-3);
}

.fi-ta-search-field .fi-input-wrp { border-radius: var(--radius-md); }

/*
 * Die Blätterleiste. Filaments Knöpfe sind rechteckig aneinandergereiht; Material setzt runde,
 * einzeln stehende Ziele — und das ist am Tablet auch der bessere Daumen-Fall, weil zwischen
 * zwei Zielen wieder Fläche liegt, auf der man NICHT trifft.
 */
.fi-pagination { padding: var(--bm-gap-3) var(--bm-gap-5); }

.fi-pagination-items { gap: var(--bm-gap-1); }

.fi-pagination-item .fi-btn,
.fi-pagination-item-btn {
    min-width: var(--bm-hit);
    border-radius: var(--radius-md);
    box-shadow: none;
}

.fi-pagination-item .fi-btn:hover,
.fi-pagination-item-btn:hover { box-shadow: var(--bm-lift-1); }

/*
 * ⛔ UNTER 64rem ROLLT DIE TABELLE WAAGERECHT, UND SIE DARF ES. Weiter oben in dieser Datei
 *    steht ein Abschnitt «Keine Tabelle rollt mehr waagerecht» — der gilt für die SEITE, nicht
 *    für die Tabelle: was dort verhindert wird, ist ein Seitenkörper, der insgesamt verrutscht.
 *    Eine Tabelle mit acht Spalten auf einem Telefon MUSS rollen; die Alternative wäre, Spalten
 *    unsichtbar zu machen, die jemand braucht.
 *
 * ⚠️ ABER SIE ROLLT IN IHREM EIGENEN KASTEN, mit sichtbarer Kante — sonst sieht ein
 *    abgeschnittener Wert wie ein fehlender aus.
 */
@media (max-width: 63.99rem) {
    .fi-ta-ctn { overflow-x: auto; }
    .fi-ta-table { min-width: 640px; }
}

/* ── 11 · Die Marke zieht in den Kopf der Schiene ───────────────────────────────────────── */

/*
 * ⛔ IM VORBILD STEHT DER NAME OBEN IN DER SCHIENE, mit einer Trennlinie darunter — nicht in der
 *    Kopfleiste. Das ist kein Geschmack: die schwebende Schiene ist eine Karte, und eine Karte
 *    ohne Kopf sieht abgeschnitten aus. Ausserdem ist der Name im Inhaber-Panel der
 *    RESTAURANTNAME, also die Antwort auf «wessen Daten sehe ich» — die gehört an den Anfang der
 *    Navigation und nicht neben den Suchknopf.
 *
 * ⚠️ FILAMENT BLENDET DIESEN KOPF AB 64rem AUS. Nachgesehen im ausgelieferten app.css:
 *    `@media (min-width:64rem){ .fi-body-has-topbar .fi-sidebar-header{ … display:none } }`.
 *    Auf dem Telefon ist er dagegen sichtbar und trägt die Marke bereits — dort ändert sich
 *    nichts, deshalb steht alles hier in derselben Abfrage.
 *
 * ⛔ UND DIE MARKE IN DER KOPFLEISTE MUSS DAFÜR WEG, sonst steht der Restaurantname zweimal auf
 *    dem Bildschirm. Die Regel dafür braucht 0,5,0 Spezifität: die Anzeige-Regel weiter oben
 *    (`:is(.fi-topbar-start, .fi-sidebar-header) .fi-logo:not(…):not(…)`) trägt 0,4,0, und ein
 *    schlichtes `.fi-topbar-start .fi-logo { display: none }` hätte gegen sie verloren — eine
 *    tote Zeile, die im Editor richtig aussieht.
 */
@media (min-width: 64rem) {
    .fi-body-has-topbar .fi-sidebar-header {
        display: flex;
        border-bottom: 1px solid var(--bm-rail-line);
    }

    .fi-topbar .fi-topbar-start .fi-logo:not(.fi-logo-light):not(.fi-logo-dark) {
        display: none;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DER PASS — drei Bahnen statt neun Spalten

   ⛔ WAS HIER ERSETZT WIRD UND WARUM. Die Bestellungen standen als Tabelle: Abholzeit, Nummer,
      Name, Telefon, Bestellung, Summe, Anmerkung, Status — und rechts drei gleich grosse
      Textknöpfe «Annehmen · Abholbereit · Ablehne». Neun Spalten beantworten «zeig mir alles»;
      am Pass wird aber gefragt «was muss ich JETZT tun», und das ist keine Spalte, sondern ein
      ZUSTAND. Der Lebenszyklus hat genau drei offene: neu, in der Küche, abholbereit. Also drei
      Bahnen, und in jeder Karte ein Knopf, der grösser ist als die anderen.

   ⛔ KEINE EINZIGE NEUE FARBE. `--bm-todo/wait/ok/risk` tragen im ganzen Produkt dieselbe
      Bedeutung — der Abend, das Tagesbuch, die Flotte lesen sie gleich. Ein Pass mit eigenem
      Rot brächte einer Wirtin bei, dass Rot je nach Bildschirm etwas anderes heisst, und dann
      liest sie keins von beiden mehr. Was hier NEU ist, ist die Rangfolge: Grösse, Abstand und
      Gewicht, nicht der Farbkreis.

   ⚠️ DIESER BLOCK STEHT FÜR SICH. Keine Regel hier fasst `.fi-*` oder einen anderen `bm-`-Block
      an — die übrigen Bildschirme des Panels sehen unverändert aus, und das ist Bedingung.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── Die Kopfzeile ──────────────────────────────────────────────────────────────────────────
   EINE ZEILE, KEINE KACHELREIHE. Dieselbe Begründung wie über dem Tagesbuch: vier abgerundete
   Kästen kosten 140 px für vier Zahlen, und diese Höhe ist am Pass die erste Kartenreihe. */
.bm-pass__kopf {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 22px;
    padding: 10px 16px;
    margin-bottom: 14px;
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
}

.bm-pass__zahl {
    display: flex;
    align-items: baseline;
    gap: 7px;
    padding-left: 10px;
    border-left: 3px solid var(--bm-line-hair);
}

.bm-pass__zahl b {
    font-size: 22px;
    line-height: 26px;
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

.bm-pass__zahl span {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-3);
}

/* Die Kante trägt die Bedeutung, nicht die Zahl: eine eingefärbte Ziffer neben einer grauen
   liest sich als «diese ist wichtiger», und das stimmt nicht — wichtig ist, WELCHER Zustand. */
.bm-pass__zahl.is-todo { border-left-color: var(--bm-todo-fg); }
.bm-pass__zahl.is-wait { border-left-color: var(--bm-wait-fg); }
.bm-pass__zahl.is-ok   { border-left-color: var(--bm-ok-fg); }

/* ⛔ DER EINZIGE ALARM IM RAUM. Er erscheint nur, wenn `ChaseOrders` auch läuten würde — und
      genau deshalb darf er laut sein. Ein Balken, der immer da ist, ist Tapete. */
.bm-pass__alarm {
    flex: 1 1 320px;
    padding: 8px 12px;
    border-radius: var(--radius-md);
    background: var(--bm-risk-bg);
    border: 1px solid var(--bm-risk-line);
    color: var(--bm-risk-fg);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

.bm-pass__alarm strong { font-weight: 600; }

.bm-pass__archiv {
    margin-left: auto;
    font-size: var(--bm-t-sm);
    color: var(--bm-txt-2);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.bm-pass__archiv:hover { color: var(--bm-txt-1); }
.bm-pass__archiv:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

/* ── Das Board ──────────────────────────────────────────────────────────────────────────────
   ⛔ DREI SPALTEN ERST AB 1100 px, und darunter UNTEREINANDER statt schmaler. Drei Bahnen auf
      einem Tablet quer sind je 300 px — eine Karte, in der «Gebratene Auberginen mit Walnüssen»
      dreimal umbricht. Gestapelt behält jede Bahn ihre Überschrift und ihre Reihenfolge, und
      «Neu» steht oben: auf einem Telefon ist genau das die Frage. */
.bm-pass__board {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

@media (min-width: 1100px) {
    .bm-pass__board { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.bm-pass__bahn {
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Ein Deckstreifen je Bahn: die Farbe steht am Kopf und wiederholt sich nicht auf jeder Karte.
   Wiederholte Farbe hört auf, ein Signal zu sein. */
.bm-pass__bahn.is-todo { border-top: 3px solid var(--bm-todo-fg); }
.bm-pass__bahn.is-wait { border-top: 3px solid var(--bm-wait-fg); }
.bm-pass__bahn.is-ok   { border-top: 3px solid var(--bm-ok-fg); }

.bm-pass__bahnkopf {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    padding: 11px 14px;
    background: var(--bm-srf-2);
    border-bottom: 1px solid var(--bm-line-hair);
}

.bm-pass__bahnkopf b {
    font-size: var(--bm-t-md);
    line-height: var(--bm-lh-md);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-pass__anzahl {
    font-style: normal;
    min-width: 22px;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    color: var(--bm-txt-2);
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.bm-pass__hinweis {
    flex: 1 1 100%;
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    color: var(--bm-txt-3);
}

.bm-pass__stapel {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
}

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

.bm-pass__karte {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 13px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-strong);
    border-radius: var(--radius-md);
}

/* ⛔ DIE ÜBERFÄLLIGE KARTE IST DAS EINZIGE, WAS AUS DEM RASTER TRITT. Eine Bestellung, deren
      Vorbereitungszeit nicht mehr reicht, war auf der alten Tabelle von jeder anderen «Neu»
      nicht zu unterscheiden — obwohl das Tablet für sie ein zweites Mal geläutet hat. */
.bm-pass__karte.is-spaet {
    border-color: var(--bm-risk-line);
    box-shadow: inset 3px 0 0 0 var(--bm-risk-fg);
}

.bm-pass__zeile {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
}

/* Die Abholzeit führt: sie ist die Frist, gegen die alles andere auf der Karte gelesen wird. */
.bm-pass__uhr {
    font-size: 19px;
    line-height: 24px;
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

.bm-pass__rest {
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
    font-variant-numeric: tabular-nums;
    color: var(--bm-txt-3);
}

.bm-pass__rest.is-bald  { color: var(--bm-todo-fg); font-weight: 600; }
.bm-pass__rest.is-spaet { color: var(--bm-risk-fg); font-weight: 600; }
.bm-pass__rest.is-ruhig { color: var(--bm-txt-3); }

/* Wird am Tresen vorgelesen: gesperrt und in Tabellenziffern, damit «3UXM7Q» beim ersten
   Versuch stimmt. */
.bm-pass__code {
    margin-left: auto;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--bm-t-xs);
    letter-spacing: .06em;
    color: var(--bm-txt-2);
    background: var(--bm-srf-2);
    border-radius: var(--radius-sm);
    padding: 2px 7px;
    user-select: all;
}

.bm-pass__gast {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 3px 10px;
}

.bm-pass__gast b {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
    color: var(--bm-txt-1);
}

/* Ein Anruf ist die Antwort auf die Hälfte aller Fragen an diesem Bildschirm — auf einem
   Tablet wählt dieser Link, statt eine Nummer zum Abtippen zu sein. */
.bm-pass__tel {
    font-size: var(--bm-t-xs);
    color: var(--bm-txt-2);
    font-variant-numeric: tabular-nums;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.bm-pass__tel:hover { color: var(--bm-txt-1); }
.bm-pass__tel:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

/* ── Das Essen ──────────────────────────────────────────────────────────────────────────── */

.bm-pass__essen {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
    padding: 7px 0;
    list-style: none;
    border-top: 1px solid var(--bm-line-hair);
    border-bottom: 1px solid var(--bm-line-hair);
}

.bm-pass__essen li {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

/* Feste Breite, damit die Mengen untereinander fluchten — eine Karte wird nicht gelesen,
   sie wird abgesucht. */
.bm-pass__menge {
    flex: none;
    min-width: 2.2em;
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

.bm-pass__was {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--bm-txt-2);
}

.bm-pass__preis {
    flex: none;
    font-style: normal;
    font-size: var(--bm-t-xs);
    color: var(--bm-txt-3);
    font-variant-numeric: tabular-nums;
}

.bm-pass__summe {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    font-size: var(--bm-t-xs);
    color: var(--bm-txt-3);
}

.bm-pass__summe b {
    font-size: var(--bm-t-md);
    font-weight: 600;
    color: var(--bm-txt-1);
    font-variant-numeric: tabular-nums;
}

/*
 * ⛔ DER WUNSCH DES GASTES BEKOMMT EINE EIGENE FLÄCHE. In der Tabelle hiess diese Spalte
 *    «Anmerkung» und stand grau zwischen Summe und Status. Darin steht «ohne Salz» — und darin
 *    steht «Nussallergie». Das ist die eine Zeile auf dieser Karte, deren Übersehen jemandem
 *    schadet.
 */
.bm-pass__wunsch {
    padding: 7px 10px;
    border-radius: var(--radius-sm);
    background: var(--bm-todo-bg);
    border: 1px solid var(--bm-todo-line);
    color: var(--bm-todo-fg);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

/* Die eigene Notiz des Hauses — leiser als der Wunsch des Gastes, weil sie niemandem schadet,
   wenn sie einmal übersehen wird. */
.bm-pass__intern {
    padding: 6px 10px;
    border-left: 2px solid var(--bm-line-strong);
    color: var(--bm-txt-3);
    font-size: var(--bm-t-xs);
    line-height: var(--bm-lh-xs);
}

/* ── Die Knöpfe ─────────────────────────────────────────────────────────────────────────── */

.bm-pass__tat {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 2px;
}

/*
 * ⛔ 44 px HOCH, WEIL DAS HIER MIT DER SEITE EINES DAUMENS BEDIENT WIRD. Die alte Tabelle hatte
 *    an dieser Stelle drei Textlinks von 16 px Höhe, nebeneinander, in derselben Farbe wie der
 *    vierte, der eine Bestellung ABLEHNT.
 */
.bm-pass__knopf {
    flex: 0 1 auto;
    min-height: 40px;
    padding: 0 13px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    border: 1px solid var(--bm-line-strong);
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    cursor: pointer;
    transition: background var(--bm-dur-2) var(--bm-ease-out);
}

.bm-pass__knopf:hover { background: var(--bm-row-hover); }
.bm-pass__knopf:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

/*
 * DER SCHRITT, DEN MAN IN NEUN VON ZEHN FÄLLEN WILL. Er wächst über die ganze verbleibende
 * Breite und trägt als Einziger eine Fläche — daran ist er ohne Lesen zu erkennen, und darum
 * geht es: am Pass wird getippt, bevor gelesen wurde.
 */
.bm-pass__knopf.is-haupt {
    flex: 1 1 auto;
    min-height: 44px;
    font-weight: 600;
    color: var(--bm-srf-1);
    background: var(--bm-ok-fg);
    border-color: var(--bm-ok-fg);
}

.bm-pass__knopf.is-haupt:hover { opacity: .9; background: var(--bm-ok-fg); }

/* Ablehnen bleibt ein Umriss, kein Block: es ist die einzige Handlung hier mit einer Person am
   anderen Ende, und sie soll nicht so aussehen wie der Knopf, den man im Vorbeigehen trifft. */
.bm-pass__knopf.is-risk {
    color: var(--bm-risk-fg);
    border-color: var(--bm-risk-line);
    background: var(--bm-srf-1);
}

.bm-pass__knopf.is-risk:hover { background: var(--bm-risk-bg); }

.bm-pass__knopf.is-still {
    color: var(--bm-txt-3);
    border-color: var(--bm-line-hair);
}

/*
 * ── «FERTIG IN …» ──────────────────────────────────────────────────────────────────────────
 *
 * ⛔ EINE EIGENE ZEILE UNTER DEN HANDGRIFFEN, UND DAS IST DER GANZE ENTWURF DIESER REGEL. Die
 *    vier Knöpfe darüber SCHIEBEN die Bestellung weiter; diese hier ändert nur, was der Gast auf
 *    seiner Belegseite liest. Beides in dieselbe Reihe zu legen ergäbe acht gleich aussehende
 *    Knöpfe nebeneinander — genau der Fehler, den der Absatz über `is-haupt` beschreibt und den
 *    die alte Bestelltabelle gemacht hat.
 *
 * ⚠️ DIE HAARLINIE OBEN TRENNT ZWEI BEDEUTUNGEN, nicht zwei Blöcke. Ohne sie liest das Auge acht
 *    Knöpfe als eine Gruppe, und dann ist die Reihenfolge der einzige Unterschied — auf einem
 *    Tablet, das mit der Seite eines Daumens bedient wird, ist das keiner.
 */
.bm-pass__zusage {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--bm-line-hair);
}

/*
 * Das Wort trägt die Einheit, damit die Knöpfe sie nicht viermal wiederholen müssen: «Fertig in
 * · 15 Min. · 30 Min. …» liest sich als ein Satz, «15 Minuten fertig» als vier Fragmente.
 */
.bm-pass__zusage-wort {
    color: var(--bm-txt-3);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

/*
 * ⛔ WAS SCHON VERSPROCHEN WURDE, STEHT DA. Zwei Tablets am selben Pass sind der Normalfall;
 *    ohne diese Angabe drückt der Zweite noch einmal und der Gast bekommt eine dritte Uhrzeit.
 *
 * ⚠️ `--bm-wait-fg`, DIE FARBE DES ERWARTETEN, und nicht die des Erledigten: eine Zusage ist eine
 *    Aussage über gleich, nicht über jetzt. Und wie überall hier trägt die Farbe die Aussage
 *    nicht allein — das Wort «gesagt:» steht davor, damit ein Graustufen-Screenshot dasselbe
 *    sagt wie der Bildschirm.
 */
.bm-pass__zusage-steht {
    margin-left: auto;
    color: var(--bm-wait-fg);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    font-weight: 600;
}

/* Die Rückfrage und der Notizblock — beides liegt IN der Karte. */
.bm-pass__rueck {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px;
    border-radius: var(--radius-sm);
    background: var(--bm-srf-2);
    border: 1px solid var(--bm-line-hair);
}

.bm-pass__feld {
    width: 100%;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--bm-line-strong);
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    resize: vertical;
}

.bm-pass__feld:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }

/* ── Leer, und erledigt ─────────────────────────────────────────────────────────────────── */

/*
 * ⚠️ EIN LEERSATZ JE BAHN, und keiner heisst «keine Einträge». Eine leere «Neu» ist eine gute
 *    Nachricht, eine leere «Abholbereit» eine neutrale — ein gemeinsamer Vorgabesatz hätte drei
 *    verschiedene Auskünfte zu einer grauen Zeile eingeebnet.
 */
.bm-pass__leer {
    padding: 18px 12px;
    text-align: center;
    color: var(--bm-txt-3);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    border: 1px dashed var(--bm-line-hair);
    border-radius: var(--radius-sm);
}

.bm-pass__fertig {
    margin-top: 14px;
    background: var(--bm-srf-1);
    border: 1px solid var(--bm-line-hair);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.bm-pass__fertig .bm-pass__essen {
    border: 0;
    padding: 6px 14px 12px;
    gap: 0;
}

.bm-pass__fertigzeile {
    display: flex;
    align-items: baseline;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px solid var(--bm-line-hair);
}

.bm-pass__fertigzeile:last-child { border-bottom: 0; }

/* In der erledigten Zeile führt nichts mehr — die Uhrzeit ist hier Beleg, nicht Frist. */
.bm-pass__fertigzeile .bm-pass__uhr { font-size: var(--bm-t-sm); line-height: var(--bm-lh-sm); color: var(--bm-txt-3); }
.bm-pass__fertigzeile .bm-pass__code { margin-left: 0; }

/*
 * ⛔ DAS WORT STEHT NEBEN DER FARBE. Grau für abgeholt, rot für abgelehnt, rot für storniert —
 *    in Graustufen wären die letzten beiden dieselbe Pille, und «wir haben abgesagt» von «der
 *    Gast hat abgesagt» zu unterscheiden ist genau die Auskunft, für die diese Zeile da ist.
 */
.bm-pass__marke {
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid var(--bm-risk-line);
    background: var(--bm-risk-bg);
    color: var(--bm-risk-fg);
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
    white-space: nowrap;
}

.bm-pass__fertigzeile .bm-pass__marke { margin-left: auto; }

/*
 * ⛔ DER VERLAUF VOR DER GRENZE — «seit 25 Min. unbeantwortet».
 *
 *    `.bm-pass__marke` daneben ist der SCHALTER: rot, wenn die Vorbereitungszeit nicht mehr
 *    reicht. Bis dahin sah eine Bestellung, die seit einer halben Stunde liegt, aus wie eine,
 *    die gerade hereinkam. Am Pass wird nicht gelesen, sondern geschaut; die alternde Karte muss
 *    auffallen, BEVOR sie rot wird, sonst ist das Rot die erste Nachricht.
 *
 * ⚠️ DESHALB KEINE PILLE UND KEINE FLÄCHE. Sie sähe aus wie die rote Marke, nur in einer anderen
 *    Farbe — und dann wäre die Farbe der einzige Unterschied zwischen «wird knapp» und «ist zu
 *    spät». Eine stille Zeile in `--bm-wait-fg` ist das, was sie ist: eine Auskunft, keine
 *    Warnung. Der Alarm bleibt der Marke allein.
 */
.bm-pass__wartet {
    color: var(--bm-wait-fg);
    font-size: var(--bm-t-2xs);
    line-height: var(--bm-lh-2xs);
    font-weight: 600;
}

/*
 * ── «KÜCHE HÄNGT?» ─────────────────────────────────────────────────────────────────────────
 *
 * Ein Handgriff für den ganzen Abend, in der Kopfzeile, weil er nicht EINE Bestellung meint.
 *
 * ⚠️ AUSDRÜCKLICH STILL. Direkt darüber steht der einzige Alarm dieses Bildschirms; ein zweiter
 *    farbiger Block daneben würde ihn halbieren. Was hier passiert, ist keine Warnung, sondern
 *    eine Handlung — sie sieht deshalb aus wie ein Knopf und nicht wie eine Meldung.
 */
.bm-pass__haengt {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

.bm-pass__haengt-wort {
    color: var(--bm-txt-3);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

.bm-pass__marke.is-picked_up {
    border-color: var(--bm-line-hair);
    background: var(--bm-srf-2);
    color: var(--bm-txt-3);
}

.bm-pass__marke.is-cancelled {
    border-color: var(--bm-line-strong);
    background: var(--bm-srf-2);
    color: var(--bm-txt-2);
}

.bm-pass__marke.is-declined {
    border-color: var(--bm-risk-line);
    background: var(--bm-risk-bg);
    color: var(--bm-risk-fg);
}

/* Auf dem Telefon bleibt die Karte eine Karte, aber der Hauptknopf nimmt die ganze Zeile:
   mit einer Hand, im Stehen, ist ein Knopf über die volle Breite der einzige, den man trifft. */
@media (max-width: 560px) {
    .bm-pass__kopf { gap: 8px 14px; padding: 10px 12px; }
    .bm-pass__archiv { margin-left: 0; }
    .bm-pass__knopf.is-haupt { flex: 1 1 100%; }
}

/*
 * ⛔ «NOCH NIE EINE BESTELLUNG» IST NICHT «GERADE NICHTS OFFEN». Drei leere Bahnen sagen einer
 *    gerade freigeschalteten Küche dreimal, dass nichts ansteht, und kein einziges Mal, dass das
 *    der erwartete Zustand ist. Dieselbe Unterscheidung trifft die Tabelle in ihrem Leertext.
 */
.bm-pass__erstesmal {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 20px 22px;
    margin-bottom: 14px;
    background: var(--bm-srf-1);
    border: 1px dashed var(--bm-line-strong);
    border-radius: var(--radius-lg);
}

.bm-pass__erstesmal b {
    font-size: var(--bm-t-md);
    line-height: var(--bm-lh-md);
    font-weight: 600;
    color: var(--bm-txt-1);
}

.bm-pass__erstesmal span {
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
    color: var(--bm-txt-2);
    max-width: 62ch;
}

/*
 * DER GESPERRTE KNOPF WÄHREND DER ANTWORT. Er darf nicht verschwinden und nicht springen —
 * am Pass wäre beides ein Knopf, den der Daumen im selben Moment verfehlt.
 */
.bm-pass__knopf:disabled {
    opacity: .55;
    cursor: progress;
}

.bm-pass__knopf.is-haupt:disabled { background: var(--bm-ok-fg); }

/* ═══════════════════════════════════════════════════════════════════════════════════════════
 * RESMUAR ALS APP — die eine Zeile, die das Panel auf den Startbildschirm anbietet
 * ═══════════════════════════════════════════════════════════════════════════════════════════
 *
 * ⛔ EINE ZEILE UND KEIN BANNER. Darüber liegt der Support-Balken — die eine Meldung dieses
 *    Panels, die eine Inhaberin nicht übersehen darf. Ein zweiter auffälliger Kasten daneben
 *    halbiert ihn, und zwar dauerhaft, weil dieser hier bei jedem Besuch wiederkäme.
 *
 * ⚠️ SIE ERSCHEINT NUR, WENN DAS TELEFON SAGT, DASS ES GEHT. Das `hidden` steht in der Vorlage
 *    und wird von `app-install.js` erst nach `beforeinstallprompt` aufgehoben. Auf einem
 *    Schreibtischrechner und in der bereits installierten App sieht sie niemand.
 */
.bm-app {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    background: var(--bm-srf-2);
    border-bottom: 1px solid var(--bm-line-hair);
    color: var(--bm-txt-2);
    font-size: var(--bm-t-sm);
    line-height: var(--bm-lh-sm);
}

.bm-app__wort { flex: 1 1 16rem; }
.bm-app__wort b { color: var(--bm-txt-1); }

/*
 * Der Knopf trägt eine Fläche, weil er die einzige Handlung dieser Zeile ist — und 40 px, weil
 * er auf demselben Telefon angetippt wird, um das es geht.
 */
.bm-app__knopf {
    flex: 0 0 auto;
    min-height: 40px;
    padding: 0 16px;
    display: inline-flex;
    align-items: center;
    border-radius: var(--radius-md);
    border: 1px solid var(--bm-line-strong);
    background: var(--bm-srf-1);
    color: var(--bm-txt-1);
    font-size: var(--bm-t-sm);
    font-weight: 600;
    cursor: pointer;
}

.bm-app__knopf:hover { background: var(--bm-row-hover); }
.bm-app__knopf:focus-visible { outline: var(--bm-focus-w) solid var(--bm-focus); outline-offset: var(--bm-focus-off); }
