/* Die Oberflaeche in einer Datei.
 *
 * DER PRODUKTNAME STEHT HIER ABSICHTLICH NICHT. Er steht in
 * `agent.web.marke` und sonst nirgends - ein Strukturtest in
 * tests/test_web_oberflaeche.py liest dieses Stilblatt und alle
 * Vorlagen und verlangt genau das.
 *
 * KEIN BAUSCHRITT, KEINE BIBLIOTHEK, KEIN CDN. Handgeschrieben, Schriften
 * aus static/schrift. Kein Verweis auf fonts.googleapis.com, nirgends.
 *
 * ====================================================================
 * ZWEI EBENEN, UND NUR DIE ZWEITE DARF BENUTZT WERDEN
 * ====================================================================
 *
 * Ebene 1 sind ROHFARBEN. Sie stehen ausschliesslich im Block `:root`
 * weiter unten, in `light-dark()`-Paaren, und sonst NIRGENDS.
 *
 * Ebene 2 sind BEDEUTUNGSNAMEN: --grund, --flaeche, --text,
 * --text-leise, --linie, --akzent-text, --akzent-flaeche, --frage,
 * --grenze, --erfolg. Jedes Bauteil weiter unten benutzt nur diese. Ein
 * Strukturtest faellt, sobald unterhalb des Zeichenblocks ein Hex-Wert
 * oder ein rgb/rgba auftaucht.
 *
 * WARUM DAS NICHT KOSMETIK IST: dieselbe Rohfarbe kann in zwei Themen
 * nicht dieselbe Rolle spielen, und zwar nachweislich.
 *
 *   #3A30F9 (Indigo) traegt auf Paper als Text  6.9:1  - brauchbar.
 *   #3A30F9 (Indigo) traegt auf Night  2.8:1  - unbrauchbar.
 *   #7C8CF5 (indigo-300) traegt auf Night  6.5:1  - brauchbar.
 *   #7C8CF5 (indigo-300) traegt auf Weiss  3.0:1  - unbrauchbar.
 * (Werte aus docs/marke/DESIGN.md, Abschnitt 3; gerechnet in den Tests.)
 *
 * Wer ein Bauteil auf `--signal` setzt, hat es damit in EINEM der beiden
 * Themen kaputt gemacht, und zwar in dem, den er gerade nicht ansieht.
 * Wer es auf `--akzent-text` setzt, bekommt in beiden den Wert, der dort
 * traegt.
 *
 * ====================================================================
 * DREI THEMEN, ZWEI DAVON FUER DIE ARBEIT
 * ====================================================================
 *
 * HELL ist die Vorgabe der Arbeitsbildschirme: weisser Grund, ruhig,
 * dicht, sachlich. Ein Werkzeug fuer ein Unternehmen.
 *
 * DUNKEL ist vollwertig und kein umgedrehtes Hell: neutrales, sehr
 * dunkles Grau mit leicht kuehlem Stich (Night). AUSDRUECKLICH NICHT der
 * Markengrund - das blaustichige Midnight acht Stunden lang ermuedet, und
 * der Markengrund gehoert der Anmeldung.
 *
 * DIE ANMELDUNG hat ihr eigenes Thema und folgt der Wahl nicht. Sie ist
 * immer dunkel und traegt den Markengrund; vor der Anmeldung gibt es
 * auch keinen Benutzer, an dem eine Wahl haengen koennte. Sie wird ueber
 * `[data-buehne="anmeldung"]` erreicht.
 *
 * WIE UMGESCHALTET WIRD, OHNE DASS DIE REGELN DOPPELT DASTEHEN:
 * `light-dark()` enthaelt beide Werte in EINER Angabe, und
 * `color-scheme` entscheidet, welcher gilt. Ohne Attribut steht dort
 * `light dark`, und damit entscheidet `prefers-color-scheme` - genau
 * das ist "dem System folgen". Ein Attribut setzt `color-scheme` fest.
 * Es gibt also weder eine doppelte Medienabfrage noch eine zweite
 * Wertetabelle.
 *
 * DAS ATTRIBUT SCHREIBT DER SERVER. Kein Skript faerbt nach dem Laden
 * um - jede solche Loesung blitzt einmal im falschen Thema auf, weil sie
 * erst nach dem ersten Bild laeuft.
 *
 * ====================================================================
 * VIER REGELN, DIE DAS GANZE ZUSAMMENHALTEN
 * ====================================================================
 *
 * 1. Pro Bildschirm genau EIN gefuellter Knopf in --akzent-knopf. Alles
 *    andere ist zweit oder flach.
 * 2. Jede Zahl, jede Artikelnummer und jeder Betrag steht mit
 *    gleich breiten Ziffern (`tabular-nums` am `body`, Archivo hat sie
 *    mit `tnum`; `.zahl` sagt es zusaetzlich). Gleiche Ziffernbreite heisst, dass Spalten
 *    untereinander stehen und ein falscher Betrag als
 *    Laengenunterschied auffaellt.
 * 3. Farbe sagt nie etwas allein. Neben jedem farbigen Merkmal steht ein
 *    Wort - fuer den Sachbearbeiter mit Rot-Gruen-Schwaeche, fuer den
 *    Ausdruck in Graustufen, fuer den Bildschirm im Gegenlicht.
 * 4. Der Fokus ist immer sichtbar, in BEIDEN Themen. Auf Weiss ist der
 *    klassische Fehler ein heller Ring auf hellem Grund; deshalb traegt
 *    der Ring hier die Akzentfarbe des jeweiligen Themas und einen
 *    Trennring in der Grundfarbe.
 *
 * ====================================================================
 * ERHEBUNG: AUF WEISS EIN SCHATTEN, AUF DUNKEL EINE KANTE
 * ====================================================================
 *
 * Ein Schatten auf Schwarz ist unsichtbar, eine helle Kante auf Weiss
 * ist es auch. `--huelle-schatten` und `--huelle-glanz` sind deshalb
 * beide Themenwerte: im hellen Thema traegt der Schatten, im dunklen
 * die Kante. Dasselbe Bauteil, derselbe Eindruck, andere Mittel.
 */

/* --------------------------------------------------------------------
 * Schrift. Sie liegt bei uns (static/schrift), nichts wird zur Laufzeit
 * von Google geholt - Begruendung in schrift/LIZENZ.md.
 *
 * ARCHIVO FUER ALLES, AUCH FUER ZAHLEN, wie die Designsprache der Marke
 * es will (docs/marke/DESIGN.md, Abschnitt 5). Zwei Breiten derselben
 * Familie: 100 % fuer Text, 125 % (`font-stretch`) nur fuer
 * Ueberschriften. Die Wortmarke ist KEINE Schrift, sondern eine Datei
 * (static/marke/).
 *
 * Archivo hat proportionale Standardziffern; gleich breit werden sie mit
 * `tnum`, das der `body` fuer alles setzt (Regel 2 oben). Gemessen an
 * genau diesen Dateien in befunde/archivo_befund.json.
 *
 * Die `unicode-range` je Teilmenge steht so da, wie @fontsource sie
 * nennt. Der Browser laedt die Erweiterung erst, wenn ein Zeichen daraus
 * auf der Seite steht.
 * ----------------------------------------------------------------- */

@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-400-latin-ext.woff2") format("woff2");
  font-weight: 400;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-500-latin.woff2") format("woff2");
  font-weight: 500;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-500-latin-ext.woff2") format("woff2");
  font-weight: 500;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-600-latin.woff2") format("woff2");
  font-weight: 600;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-600-latin-ext.woff2") format("woff2");
  font-weight: 600;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-700-latin.woff2") format("woff2");
  font-weight: 700;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-700-latin-ext.woff2") format("woff2");
  font-weight: 700;
  font-stretch: 100%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-breit-700-latin.woff2") format("woff2");
  font-weight: 700;
  font-stretch: 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-breit-700-latin-ext.woff2") format("woff2");
  font-weight: 700;
  font-stretch: 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-breit-800-latin.woff2") format("woff2");
  font-weight: 800;
  font-stretch: 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Archivo";
  src: url("schrift/archivo-breit-800-latin-ext.woff2") format("woff2");
  font-weight: 800;
  font-stretch: 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ====================================================================
 * DIE ZEICHEN. Die einzige Stelle mit Rohfarben.
 *
 * DIE WERTE KOMMEN AUS DER DESIGNSPRACHE DER MARKE: die Tokens des
 * Brand-Kits (docs/marke/tokens.json) und, wo das Kit fuer eine
 * Arbeitsflaeche nichts sagt, das Mockup der Auftragspruefung
 * (docs/marke/auftrag-pruefen.html: kuehles Hellgrau als Grund, weisse
 * Panels, Schatten mit Indigo-Stich, Bernstein fuer "bitte ansehen").
 * Welches Zeichen woher kommt, steht in tests/test_farben.py und wird
 * dort gegen beide Dateien geprueft.
 *
 * AUSSERHALB DER BEIDEN stehen nur Grenze (Rot) und Erfolg (Gruen):
 * CLAUDE.md verlangt Rot fuer die gerissene Grenze, und "gebucht" ist ein
 * anderer Zustand als "bereit".
 *
 * HELL IST DIE VORGABE (05.10.2026). Jede Angabe ist ein
 * `light-dark(hell, dunkel)`-Paar; ohne Attribut gilt `light`. Die Lichter
 * der Bewegung sind feste Werte: Licht braucht in jedem Thema Dunkelheit,
 * es sitzt immer im dunklen Squircle des App-Icons.
 *
 * Die Kontraste stehen nicht hier, sondern werden in
 * tests/test_web_oberflaeche.py und tests/test_farben.py GERECHNET.
 * ================================================================= */

:root {
  /* HELL OHNE WAHL. `data-thema="system"` oeffnet `light dark`. */
  color-scheme: light;

  /* --- Flaechen. Der Grund ist das kuehle Hellgrau des Mockups, die
   * Datenkarten deckend weiss (Glas nur auf der Huelle, CLAUDE.md). */
  --grund: light-dark(#eceef3, #090b0c);
  --flaeche: light-dark(#ffffff, #0f1117);
  --flaeche-erhoben: light-dark(#f4f5f7, #171a21);
  --flaeche-kopf: light-dark(#fcfcfb, #171a21);
  --flaeche-vertieft: light-dark(#ffffff, #171a21);
  /* Die "raised"-Flaeche des Mockups: ein Hauch, auf Weiss wie auf Dunkel. */
  --flaeche-zart: light-dark(rgba(8, 9, 11, 0.03), rgba(255, 255, 255, 0.035));

  /* --- Text. Onyx/Snow, darunter "soft" und "muted" des Mockups. */
  --text: light-dark(#08090b, #f9f9f9);
  --text-zweit: light-dark(#3f4655, #b4bccb);
  --text-leise: light-dark(#5b6477, #8a95a8);

  /* --- Linien: Onyx bzw. Weiss mit wenig Deckkraft (Glasrand). */
  --linie: light-dark(rgba(8, 9, 11, 0.08), rgba(255, 255, 255, 0.08));
  --linie-zart: light-dark(rgba(8, 9, 11, 0.06), rgba(255, 255, 255, 0.06));
  --linie-hauch: light-dark(rgba(8, 9, 11, 0.045), rgba(255, 255, 255, 0.045));
  --linie-stark: light-dark(rgba(8, 9, 11, 0.15), rgba(255, 255, 255, 0.14));

  /* --- Akzent: Handlung. EIN Akzent, Indigo. Als Schrift auf Dunkel das
   * helle Indigo des Mockups. */
  --akzent-text: light-dark(#3a30f9, #9dabfa);
  --akzent-flaeche: light-dark(rgba(58, 48, 249, 0.1), rgba(58, 48, 249, 0.2));
  --akzent-kante: light-dark(rgba(58, 48, 249, 0.18), rgba(124, 140, 245, 0.26));
  --akzent-knopf: light-dark(#3a30f9, #3a30f9);
  --akzent-knopf-hover: light-dark(#2f25cf, #4b42ff);
  --akzent-knopf-text: light-dark(#ffffff, #ffffff);

  /* --- Frage: "bitte ansehen". Das Bernstein des Mockups (warn). */
  --frage: light-dark(#704700, #f3c46b);
  --frage-flaeche: light-dark(#fff3d9, rgba(243, 196, 107, 0.1));
  --frage-kante: light-dark(#e8c06a, rgba(243, 196, 107, 0.32));

  /* --- Hinweis: etwas zu wissen, nichts zu tun (info des Mockups). */
  --hinweis: light-dark(#231da6, #9dabfa);
  --hinweis-flaeche: light-dark(rgba(58, 48, 249, 0.06), rgba(124, 140, 245, 0.1));
  --hinweis-kante: light-dark(rgba(58, 48, 249, 0.18), rgba(124, 140, 245, 0.26));

  /* --- Grenze: es ist etwas blockiert. Ausserhalb von Kit und Mockup. */
  --grenze: light-dark(#9f1c14, #f7b2ab);
  --grenze-flaeche: light-dark(#fde8e6, #3b1512);
  --grenze-kante: light-dark(rgba(159, 28, 20, 0.3), rgba(247, 178, 171, 0.38));

  /* --- Texterkennung: die Zeichen sind geraten (Lavender des Bandes). */
  --ocr: light-dark(#19177a, #a4aaf9);
  --ocr-flaeche: light-dark(rgba(130, 116, 248, 0.12), rgba(130, 116, 248, 0.2));

  /* --- Bereit: nichts spricht gegen die Freigabe - Indigo, die Handlung. */
  --bereit: light-dark(#3a30f9, #9dabfa);
  --bereit-flaeche: light-dark(rgba(58, 48, 249, 0.1), rgba(58, 48, 249, 0.2));

  /* --- Erfolg: es ist erledigt (gebucht). Ausserhalb von Kit und Mockup. */
  --erfolg: light-dark(#186b4a, #4fc48c);
  --erfolg-flaeche: light-dark(rgba(24, 107, 74, 0.09), rgba(79, 196, 140, 0.14));
  --erfolg-kante: light-dark(rgba(24, 107, 74, 0.3), rgba(79, 196, 140, 0.38));

  /* --- Eine markierte Zeile (die Freigabe): indigo-50 bzw. indigo-900. */
  --zeile-markiert: light-dark(#eef1ff, #14144f);

  /* --- DIE LEISTE. Ein schwebendes Glaspanel wie im Mockup: hell auf
   * Hell, dunkel auf Dunkel. Sie ist Huelle und traegt keine Daten. */
  --leiste: light-dark(rgba(255, 255, 255, 0.6), rgba(17, 19, 33, 0.56));
  --leiste-text: light-dark(#08090b, #f9f9f9);
  --leiste-zweit: light-dark(#3f4655, #b4bccb);
  --leiste-leise: light-dark(#5b6477, #8a95a8);
  --leiste-aktiv: light-dark(rgba(58, 48, 249, 0.1), rgba(58, 48, 249, 0.2));
  --leiste-kante: light-dark(rgba(8, 9, 11, 0.08), rgba(255, 255, 255, 0.08));
  --leiste-akzent: light-dark(#3a30f9, #9dabfa);
  --leiste-lauf: light-dark(#186b4a, #4fc48c);
  --leiste-fokus: light-dark(#3a30f9, #7c8cf5);

  /* --- Die Huelle: was schwebt (Leiste, Vorschlagslisten, Dialoge, die
   * Entscheidungsleiste). Die Glaswerte des Mockups. */
  --huelle: light-dark(rgba(255, 255, 255, 0.6), rgba(17, 19, 33, 0.56));
  --huelle-stark: light-dark(rgba(255, 255, 255, 0.74), rgba(15, 17, 30, 0.7));
  --huelle-deckend: light-dark(#ffffff, #171a21);
  --huelle-kante: light-dark(rgba(8, 9, 11, 0.08), rgba(255, 255, 255, 0.08));

  /* --- ERHEBUNG. Auf Weiss der weiche Schatten mit Indigo-Stich (Navy des
   * Kits) und eine weisse Innenkante; auf Dunkel die hellere Kante und ein
   * tiefer Schatten. NUR DIE FARBEN sind Themenwerte - `light-dark()` nimmt
   * keine ganzen Schatten (nachgemessen 24.09.2026, Chromium 152). */
  --huelle-glanz: light-dark(rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.06));
  --schatten-farbe: light-dark(rgba(21, 23, 95, 0.08), rgba(0, 0, 0, 0.3));
  --schatten-hoch-farbe: light-dark(rgba(21, 23, 95, 0.35), rgba(0, 0, 0, 0.65));
  --huelle-schatten: 0 1px 2px var(--schatten-farbe);
  --huelle-schatten-hoch: 0 24px 60px -28px var(--schatten-hoch-farbe);
  --karte-schatten:
    inset 0 1px 0 var(--huelle-glanz),
    0 1px 2px var(--schatten-farbe),
    0 24px 60px -28px var(--schatten-hoch-farbe);

  /* --- Der Fokusring. Das Kit will indigo-300; auf Weiss traegt der nur
   * knapp 3:1, dort deshalb Indigo selbst. */
  --fokus: light-dark(#3a30f9, #7c8cf5);
  --fokus-schein: light-dark(rgba(58, 48, 249, 0.18), rgba(124, 140, 245, 0.26));

  /* --- Das Leuchten: Hauptknopf (`--glow-accent`) und der Signaturpunkt. */
  --knopf-schein: light-dark(rgba(58, 48, 249, 0.35), rgba(58, 48, 249, 0.6));
  --knopf-schein-kante: rgba(164, 170, 249, 0.14);
  --punkt-schein: rgba(58, 48, 249, 0.55);

  /* --- Der Verlauf des Akzents (`--grad-accent`, Sky -> Indigo -> Royal):
   * Fortschritt, Mandantenzeichen. */
  --verlauf-a: #7aa9ff;
  --verlauf-b: #3a30f9;
  --verlauf-c: #231da6;

  /* --- DIE FENSTERKNOEPFE DES KI-FENSTERS in der Art von macOS
   * (Schliessen, Minimieren, Vergroessern; Wunsch vom 05.10.2026). Feste
   * Werte, in beiden Themen gleich, wie am Mac. Farbig nur, solange das
   * Fenster vorn ist - sonst grau (stil.css, `.ampel-knopf`). */
  --ampel-rot: #ff5f57;
  --ampel-gelb: #febc2e;
  --ampel-gruen: #28c840;
  --ampel-zeichen: rgba(8, 9, 11, 0.55);

  /* --- DIE LICHTER DER BEWEGUNG: Werte der Bibliothek caselli-motion.js
   * (ihre Konstante `CSS`), fest und nicht themenabhaengig. Seit dem
   * 05.10.2026 ohne eigene Buehne: die Animationen laufen auf dem Grund
   * des Themas (`--licht-mischung`). */
  --licht-hof: rgba(58, 48, 249, 0.6);
  --licht-hof-rand: rgba(122, 169, 255, 0.18);
  /* Der Geist des Zeichens auf hellem Grund (caselli-motion.css): indigo-300,
   * bei der Deckkraft der Bibliothek ein heller Lavendelton. */
  --licht-geist: #7c8cf5;
  --licht-schimmer: #8a95a8;
  --licht-schimmer-hell: #eef3ff;
  --licht-bereit: #a9b8fc;
  --licht-bereit-flaeche: rgba(58, 48, 249, 0.22);
  --licht-ring: #7c8cf5;
  --licht-tinte: #f9f9f9;
  --licht-tinte-hell: #08090b;
  --licht-endung: #8a95a8;
  --licht-punkt: #3a30f9;
  --licht-icon: #08090b;
  --licht-icon-kante: rgba(255, 255, 255, 0.08);
  --licht-icon-schatten: rgba(8, 9, 11, 0.6);
  --licht-icon-hof: rgba(118, 133, 219, 0.95);
  --licht-icon-hof-rand: rgba(164, 170, 249, 0.4);

  /* --- Schrift ---------------------------------------------------- */
  --schrift: "Archivo", "Helvetica Neue", Arial, sans-serif;
  /* UEBERSCHRIFTEN IN DER NORMALEN BREITE (Entscheidung 21.10.2026: die breite 800er Fassung
   * wirkte wie jede KI-Oberflaeche). Dieselbe Familie, nur ruhiger. Die breite Fassung (125 %,
   * wie die Wortmarke) bleibt dem Auftritt der Anmeldung (`--schrift-breite-marke`): dort wirbt
   * die Marke, auf der Arbeitsflaeche wird gelesen. */
  --schrift-breite-titel: 100%;
  --schrift-breite-marke: 125%;
  /* ECHTE FESTBREITE, und nur wo sie gebraucht wird: ein Schluesselabdruck
   * und der Bestelltext mit seinen Spalten aus der PDF. Der Systemstapel
   * und keine Datei - eine Monospace-Webschrift gibt es nicht. */
  --schrift-fest: ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Abstaende: nur diese sieben. Ein Zwischenwert ist ein Wert, den
   * niemand wiederfindet. */
  --a1: 4px;
  --a2: 8px;
  --a3: 12px;
  --a4: 16px;
  --a5: 24px;
  --a6: 32px;
  --a7: 48px;

  /* Radien aus dem Mockup: 10 fuer Felder, 14 fuer Kaesten in Karten,
   * 20 fuer kleine Panels, 24 fuer Karten und die Leiste, Pillen fuer
   * Knoepfe und Merkmale. */
  --radius: 10px;
  --radius-mittel: 14px;
  --radius-gross: 20px;
  --radius-karte: 24px;
  --radius-pille: 999px;

  /* Die Hoehe des Kopfes im Inhaltsbereich (Name der Ansicht, Satz,
   * Suche). Er klebt oben, und ein Sprungziel darf nicht unter ihm
   * landen - siehe `.quellzeile`. */
  --kopfhoehe: 68px;

  /* Die Leiste: 256 px breit, schwebend mit 16 px Abstand zum Rand; unter
   * 1100 px eine Zeichenspalte. */
  --leistenbreite: 256px;
  --leistenbreite-schmal: 64px;
  --rand: 16px;
  /* Was die mitlaufende Karte "Original" ausser der Seite braucht - Kopf, Satz, Reiter, Satz zur
   * Quelle, Pfeile, "Text der Bestellung" (Beta-Rueckmeldung 07.10.2026). Misst freigabe.js je
   * Vorgang; dies ist der Wert vor der ersten Messung (gemessen an 5211: 299 px). */
  --karte-rahmen: 19rem;

  /* Bewegung aus dem Kit: 160 ms fuer Hover, 320 ms fuer Oberflaeche,
   * `--kurve-aus` zum Einblenden, `--kurve-falt` fuer Wechsel. */
  --zeit-kurz: 160ms;
  --zeit-mittel: 320ms;
  --kurve-aus: cubic-bezier(0.2, 0.8, 0.2, 1);
  --kurve-falt: cubic-bezier(0.65, 0, 0.35, 1);

  /* Das Feld, in dem das Zeichen denkt (`.denkzeile`): 1,4-mal so breit
   * wie das Zeichen und quadratisch - Platz fuer die Lichtspur, ohne
   * Flaeche (keine dunkle Kachel mehr, Rueckmeldung 05.10.2026). Der Chat
   * baut die Spalte seines Absenders aus demselben Faktor (`--absender`):
   * Feld und Spalte decken sich, das Zeichen steht vor, waehrend und nach
   * dem Denken an derselben Stelle. */
  --denkfeld-faktor: 1.4;
}

/* ====================================================================
 * RUECKFALL FUER BROWSER OHNE `light-dark()`
 *
 * MINDESTVERSIONEN (aus MDNs browser-compat-data nachgesehen, nicht
 * geschaetzt): Chrome und Edge 123, Firefox 120, Safari 17.5. Was
 * darunter liegt, bekommt diesen Block. Steht so auch in der README.
 *
 * WARUM EIN ZWEITER WERT VOR DEM light-dark() NICHT HILFT: bei einer
 * EIGENEN Eigenschaft geht beides beim Parsen durch - der Wert ist fuer
 * `--x` nur ein Tokenstrom. Der Fehler faellt erst beim EINSETZEN an,
 * und dann gilt nicht "nimm den vorigen Wert", sondern die benutzende
 * Eigenschaft wird ungueltig zur Rechenzeit. Nachgemessen, mit einer
 * erfundenen Funktion in einem Zeichen:
 *
 *   background-color  ->  transparent   (Anfangswert, NICHT geerbt)
 *   color             ->  geerbt vom Elternteil
 *   border-color      ->  currentColor, also ebenfalls geerbt
 *
 * DIE FLAECHE GEHT ALSO VERLOREN, DIE SCHRIFT NICHT. Weil in diesem
 * Stilblatt auch jede Schriftfarbe aus einem Zeichen kommt, faellt sie
 * mit und landet auf geerbtem Schwarz: der Ausfall ist "schwarz auf
 * weiss mit schwarzen Haarlinien", nicht "unsichtbar".
 *
 * DAS IST KEINE EIGENSCHAFT DIESES BLOCKS, SONDERN EINE ABHAENGIGKEIT.
 * Sie haelt nur, solange KEINE Schriftfarbe als Literal dasteht. Stuende
 * irgendwo `color: #fff`, bliebe die Schrift hell und saesse auf einer
 * Flaeche, die es nicht mehr gibt - und das waere dann wirklich
 * unsichtbar. Gehalten wird das von
 * `test_kein_bauteil_benutzt_eine_rohfarbe`; wer jene Regel lockert,
 * verschlechtert stillschweigend diesen Rueckfall, ohne es zu merken,
 * weil sein eigener Browser neu ist. Derselbe Satz steht in CLAUDE.md
 * unter "Die Oberflaeche: was festliegt" und am Test selbst.
 *
 * WARUM DIE ZEICHEN UND NICHT DIE BAUTEILE: eine Liste von Bauteilen mit
 * gefaerbter Flaeche veraltet, sobald jemand eine Plakette dazuschreibt -
 * und dann fehlt genau die neue. Die Zeichen sind die Ebene, auf der sich
 * nichts vergessen laesst: wer ein Zeichen benutzt, ist gedeckt.
 * `test_der_rueckfall_deckt_jede_gefaerbte_flaeche` prueft beides - dass
 * jedes Zeichen hier steht UND dass sein Wert die helle Haelfte des
 * Paares oben ist, damit die beiden nicht auseinanderlaufen.
 *
 * AUSGELIEFERT WIRD DAS HELLE THEMA - es ist ohnehin die Vorgabe. Die
 * festen Zeichen oben (Licht) brauchen keinen Rueckfall; die Lichtbuehne
 * steht trotzdem hier, damit die Pruefung jeder gefaerbten Flaeche nicht
 * zwischen festen und gepaarten Zeichen unterscheiden muss.
 * ================================================================= */

@supports not (color: light-dark(white, black)) {
  :root {
    --grund: #eceef3;
    --flaeche: #ffffff;
    --flaeche-erhoben: #f4f5f7;
    --flaeche-kopf: #fcfcfb;
    --flaeche-vertieft: #ffffff;
    --flaeche-zart: rgba(8, 9, 11, 0.03);
    --text: #08090b;
    --text-zweit: #3f4655;
    --text-leise: #5b6477;
    --linie: rgba(8, 9, 11, 0.08);
    --linie-zart: rgba(8, 9, 11, 0.06);
    --linie-hauch: rgba(8, 9, 11, 0.045);
    --linie-stark: rgba(8, 9, 11, 0.15);
    --akzent-text: #3a30f9;
    --akzent-flaeche: rgba(58, 48, 249, 0.1);
    --akzent-kante: rgba(58, 48, 249, 0.18);
    --akzent-knopf: #3a30f9;
    --akzent-knopf-hover: #2f25cf;
    --akzent-knopf-text: #ffffff;
    --frage: #704700;
    --frage-flaeche: #fff3d9;
    --frage-kante: #e8c06a;
    --hinweis: #231da6;
    --hinweis-flaeche: rgba(58, 48, 249, 0.06);
    --hinweis-kante: rgba(58, 48, 249, 0.18);
    --grenze: #9f1c14;
    --grenze-flaeche: #fde8e6;
    --grenze-kante: rgba(159, 28, 20, 0.3);
    --ocr: #19177a;
    --ocr-flaeche: rgba(130, 116, 248, 0.12);
    --bereit: #3a30f9;
    --bereit-flaeche: rgba(58, 48, 249, 0.1);
    --erfolg: #186b4a;
    --erfolg-flaeche: rgba(24, 107, 74, 0.09);
    --erfolg-kante: rgba(24, 107, 74, 0.3);
    --zeile-markiert: #eef1ff;
    --leiste: rgba(255, 255, 255, 0.6);
    --leiste-text: #08090b;
    --leiste-zweit: #3f4655;
    --leiste-leise: #5b6477;
    --leiste-aktiv: rgba(58, 48, 249, 0.1);
    --leiste-kante: rgba(8, 9, 11, 0.08);
    --leiste-akzent: #3a30f9;
    --leiste-lauf: #186b4a;
    --leiste-fokus: #3a30f9;
    --huelle: rgba(255, 255, 255, 0.6);
    --huelle-stark: rgba(255, 255, 255, 0.74);
    --huelle-deckend: #ffffff;
    --huelle-kante: rgba(8, 9, 11, 0.08);
    --huelle-glanz: rgba(255, 255, 255, 0.9);
    --schatten-farbe: rgba(21, 23, 95, 0.08);
    --schatten-hoch-farbe: rgba(21, 23, 95, 0.35);
    --fokus: #3a30f9;
    --fokus-schein: rgba(58, 48, 249, 0.18);
    --knopf-schein: rgba(58, 48, 249, 0.35);
    /* Die Fensterknoepfe haben feste Werte und braeuchten den Rueckfall
     * nicht; sie stehen hier, damit der Rueckfall vollstaendig bleibt. */
    --ampel-rot: #ff5f57;
    --ampel-gelb: #febc2e;
    --ampel-gruen: #28c840;
  }
}

/* Die Wahl des Benutzers. Der Server schreibt das Attribut auf <html>;
 * ohne Attribut bleibt es hell (oben). */
:root[data-thema="hell"] {
  color-scheme: light;
}

:root[data-thema="dunkel"] {
  color-scheme: dark;
}

:root[data-thema="system"] {
  color-scheme: light dark;
}

/* WIE DAS LICHT DER BEWEGUNG AUF DEN GRUND FAELLT (caselli-motion.js
 * zeichnet Kometen und Blitze auf eine Leinwand, `.cm-fx`). Auf Dunkel
 * `screen`, wie im Kit: Licht hellt den Grund auf. Auf Hell `multiply`:
 * dieselben Farben dunkeln den Grund ab und werden zur Spur in Indigo -
 * mit `screen` waere Licht auf Weiss unsichtbar. Seit dem 05.10.2026
 * laufen die Animationen im hellen Thema auf hellem Grund und nicht mehr
 * in einem schwarzen Kasten (Rueckmeldung: zu dunkel, „irgendwas faul").
 * Kein Farbwert, deshalb kein Zeichen im Zeichenblock und kein
 * light-dark()-Paar - die Mischart ist ein Schluesselwort. */
:root {
  --licht-mischung: multiply;
}

:root[data-thema="dunkel"] {
  --licht-mischung: screen;
}

@media (prefers-color-scheme: dark) {
  :root[data-thema="system"] {
    --licht-mischung: screen;
  }
}

/* ====================================================================
 * DIE ANMELDUNG. Eigenes Thema, folgt der Wahl NICHT - und ist hell.
 *
 * Seit dem 05.10.2026 hell wie der Rest: der kuehle Grund des Mockups,
 * dazu EIN Bloom in der hellen Fassung des Kits (Glow und Sky, `--bloom`
 * unter `[data-theme="light"]`), rechts hinter der Karte. Vor der
 * Anmeldung gibt es keinen Benutzer, also keine Wahl - auch eine dunkle
 * Wahl des Letzten faerbt sie nicht.
 *
 * LEISER TEXT IN gray-600 (#4C5363) und nicht im "muted" des Mockups: an
 * der hellsten Stelle des Blooms truege der nur 3,6:1 (gerechnet in
 * tests/test_web_oberflaeche.py).
 *
 * Die Werte sind FESTE Werte und keine light-dark()-Paare - dieses Thema
 * hat nur eine Fassung.
 * ================================================================= */

:root[data-buehne="anmeldung"] {
  color-scheme: light;

  --grund: #eceef3;
  --flaeche: #ffffff;
  --flaeche-erhoben: #f4f5f7;
  --flaeche-kopf: #fcfcfb;
  --flaeche-vertieft: #ffffff;

  --text: #08090b;
  --text-zweit: #3f4655;
  --text-leise: #4c5363;

  --linie: rgba(8, 9, 11, 0.08);
  --linie-stark: rgba(8, 9, 11, 0.15);

  --akzent-text: #3a30f9;
  --akzent-flaeche: rgba(58, 48, 249, 0.1);
  --akzent-kante: rgba(58, 48, 249, 0.18);
  --akzent-knopf: #3a30f9;
  --akzent-knopf-hover: #2f25cf;
  --akzent-knopf-text: #ffffff;

  --frage: #704700;
  --frage-flaeche: #fff3d9;
  --frage-kante: #e8c06a;

  --grenze: #9f1c14;
  --grenze-flaeche: #fde8e6;
  --grenze-kante: rgba(159, 28, 20, 0.3);

  --erfolg: #186b4a;
  --erfolg-flaeche: rgba(24, 107, 74, 0.09);
  --erfolg-kante: rgba(24, 107, 74, 0.3);

  --huelle: rgba(255, 255, 255, 0.6);
  --huelle-stark: rgba(255, 255, 255, 0.74);
  --huelle-deckend: #ffffff;
  --huelle-kante: rgba(8, 9, 11, 0.08);
  --huelle-glanz: rgba(255, 255, 255, 0.9);
  --schatten-farbe: rgba(21, 23, 95, 0.08);
  --schatten-hoch-farbe: rgba(21, 23, 95, 0.35);

  --fokus: #3a30f9;
  --fokus-schein: rgba(58, 48, 249, 0.18);
  --knopf-schein: rgba(58, 48, 249, 0.35);

  /* Der Bloom der hellen Kit-Fassung: Glow und Sky. */
  --licht-indigo: rgba(164, 170, 249, 0.45);
  --licht-sky: rgba(122, 169, 255, 0.22);
  --licht-aus: rgba(164, 170, 249, 0);
  --marke-beta: #3a30f9;
  --profil-tief: #231da6;
}

/* ====================================================================
 * GRUNDLAGE
 * ================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* Die SEITE scrollt, und zwar immer mit demselben Balken. Ohne dies
   * springt der ganze Aufbau um die Balkenbreite, sobald eine Liste
   * laenger wird als das Fenster - und beim Filtern springt er zurueck. */
  scrollbar-gutter: stable;
}

/* `tabular-nums` FUER ALLES (Regel 2): Archivo hat proportionale
 * Standardziffern. Eine Zahl ohne `.zahl` stuende sonst schief unter der
 * naechsten - und eine falsche Stelle fiele nicht mehr als
 * Laengenunterschied auf. */
body {
  margin: 0;
  min-height: 100vh;
  background: var(--grund);
  color: var(--text);
  font-family: var(--schrift);
  font-size: 15px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Kontrollkaestchen und Auswahlknoepfe des Browsers in der Akzentfarbe. */
  accent-color: var(--akzent-knopf);
}

/* UEBERSCHRIFTEN IN DER BREITEN FASSUNG (125 %), wie die Wortmarke - das
 * Kit will fuer Display 800, fuer H2 700. Auf der Arbeitsflaeche kleiner
 * als im Kit: hier wird gelesen, nicht geworben. */
h1 {
  font-size: 24px;
  font-weight: 700;
  font-stretch: var(--schrift-breite-titel);
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 var(--a2);
  overflow-wrap: break-word;
  hyphens: auto;
}

h2 {
  font-size: 18px;
  font-weight: 600;
  font-stretch: var(--schrift-breite-titel);
  letter-spacing: -0.01em;
  margin: 0 0 var(--a3);
}

h3 {
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 var(--a2);
}

p {
  margin: 0 0 var(--a3);
}

a {
  color: var(--akzent-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* REGEL 4: DER FOKUS IST IMMER SICHTBAR - IN BEIDEN THEMEN.
 *
 * DER KLASSISCHE FEHLER AUF WEISS ist ein heller Ring auf hellem Grund.
 * Deshalb traegt der Ring die Akzentfarbe DES JEWEILIGEN THEMAS (hell
 * Indigo, dunkel indigo-300) und dazu einen Trennring in der Grundfarbe,
 * damit er auch direkt auf einer farbigen Flaeche noch abgesetzt ist. Das
 * Kit will 2 px Ring mit 3 px Abstand.
 *
 * Niemals `outline: none` ohne Ersatz. */
:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 3px;
  box-shadow:
    0 0 0 2px var(--grund),
    0 0 0 6px var(--fokus-schein);
  border-radius: var(--radius);
}

::selection {
  background: var(--akzent-flaeche);
  color: var(--text);
}

.nurlesbar {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ====================================================================
 * DAS MATERIAL
 *
 * `.huelle` ist Glas und gehoert auf das, was SCHWEBT: Vorschlagslisten,
 * Dialoge, Ueberlagerungen - und die Anmeldekarte auf dem Markengrund.
 * Die Kopfleiste gibt es seit dem UI-Umbau nicht mehr; der Entwurf ist
 * flach.
 * Unter die DATEN gehoert deckende Flaeche: `.karte`, `.karte-daten`.
 *
 * DAS GESETZ BLEIBT: Glas auf der Huelle, niemals auf den Daten.
 *
 * AUF WEISS IST DIE MACHART EINE ANDERE. Stark durchscheinend wird auf
 * hellem Grund grau und schmutzig; der Eindruck kommt hier aus einer
 * echten Haarlinie und einem sehr weichen Schatten, nicht aus
 * Transparenz. Die Saettigung leicht anzuheben hilft, Unschaerfe kaum -
 * deshalb `saturate()` mit nur wenig `blur()`.
 * ================================================================= */

.huelle {
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-gross);
  background: var(--huelle);
  -webkit-backdrop-filter: saturate(160%) blur(8px);
  backdrop-filter: saturate(160%) blur(8px);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    var(--huelle-schatten);
}

/* Kennt der Browser kein backdrop-filter, bekommt die Huelle eine ruhige
 * DECKENDE Fuellung - und bleibt vollstaendig bedienbar. Andersherum
 * gebaut waere der kaputte Fall der Standardfall, und zwar lautlos. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .huelle {
    background: var(--huelle-deckend);
  }
}


/* ====================================================================
 * DER RAHMEN UND DIE LEISTE
 *
 * Links die Leiste, rechts der Arbeitsbereich - auf jeder Seite hinter
 * der Anmeldung (`rahmen.html`). Aufbau und Masse nach dem Mockup der
 * Auftragspruefung (docs/marke/auftrag-pruefen.html): die Leiste ist ein
 * schwebendes Glaspanel mit 16 px Abstand zum Rand, oben Wortmarke, Beta
 * und Mandantenkarte, darunter die Abschnitte, unten Dienstlage und Konto.
 *
 * DIE LEISTE KLEBT UND SCROLLT FUER SICH. `position: sticky` im Raster
 * des Rahmens, so hoch wie das Fenster: die Seite rechts scrollt, die
 * Leiste bleibt. Ist sie hoeher als das Fenster, scrollen nur ihre
 * Abschnitte (`.leiste-abschnitte`); Marke, Dienstlage und Konto bleiben.
 *
 * GLAS, WEIL SIE HUELLE IST. Auf ihr stehen keine Daten - Glas auf der
 * Huelle, niemals auf den Daten (CLAUDE.md).
 * ================================================================= */

/* DER RAHMEN SCHWEBT: 16 px Abstand zum Fensterrand und zwischen Leiste
 * und Inhalt, wie im Mockup. Der Grund (kuehles Hellgrau) traegt beide. */
.rahmen {
  display: grid;
  grid-template-columns: var(--leistenbreite) minmax(0, 1fr);
  gap: var(--rand);
  min-height: 100vh;
  padding: var(--rand);
}

/* AUF DEM TELEFON 8 px: bei 375 px blieben dem Inhalt neben der
 * Zeichenspalte mit 16 px Rand nur 263 px (gemessen, Regel 33). */
@media (max-width: 40em) {
  .rahmen {
    --rand: 8px;
  }
}

.arbeitsbereich {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* DIE LEISTE: ein Glaspanel (Huelle, keine Daten), 24 px Radius, die
 * weisse Innenkante und der Schatten mit Indigo-Stich. Sie klebt und ist
 * so hoch wie das Fenster abzueglich des Randes. */
.leiste {
  position: sticky;
  top: var(--rand);
  height: calc(100vh - 2 * var(--rand));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px 14px 14px;
  border: 1px solid var(--leiste-kante);
  border-radius: var(--radius-karte);
  background: var(--leiste);
  box-shadow: var(--karte-schatten);
  color: var(--leiste-text);
}

/* KEIN WEICHZEICHNER (Rueckmeldung 27.10.2026, "flüssig"): die Leiste steht neben dem Inhalt,
 * hinter ihr liegt nur der einfarbige Seitengrund - eine Truebung ueber 24 px auf voller
 * Fensterhoehe zeigte dort nichts und kostete in jedem Bild. Die halbe Deckkraft ueber dem Grund
 * ergibt dieselbe Farbe. */

.leiste :focus-visible {
  outline-color: var(--leiste-fokus);
  box-shadow: none;
}

.zeichen {
  display: block;
  flex: none;
}

/* --- Die Wortmarke und die Beta-Marke: Anmeldung und Leiste. Die
 * Wortmarke ist eine Datei (static/marke/), kein Text - Brand-Kit,
 * Regel 3. Hell das helle Lockup, Dunkel das dunkle. */

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

.wortmarke {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  border-radius: var(--radius);
}

.wortmarke img {
  display: block;
  height: auto;
}

.wortmarke-bild {
  position: relative;
  display: block;
}

.logo-dunkel {
  display: none;
}

:root[data-thema="dunkel"] .logo-hell {
  display: none;
}

:root[data-thema="dunkel"] .logo-dunkel {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root[data-thema="system"] .logo-hell {
    display: none;
  }

  :root[data-thema="system"] .logo-dunkel {
    display: block;
  }
}

/* DAS BEWEGTE LOCKUP (bewegung.js, `navLogo` aus caselli-motion.js)
 * ersetzt das Bild nur im Aussehen: das Bild bleibt im Baum und traegt
 * den Namen fuer den Screenreader, die Buehne ist `aria-hidden`. */
.wortmarke-bild.bewegt > img {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* DIE BETA-MARKE: eine Pille in der Akzentfarbe, Versalien mit Laufweite
 * (das Label des Kits, wie im Mockup). Sie ist eine Zusage und keine
 * Zierde - klein, aber nicht zu uebersehen. */
.beta-marke {
  display: inline-block;
  padding: 3px 8px;
  border-radius: var(--radius-pille);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  line-height: 1.3;
  white-space: nowrap;
}

/* --- Kopf: Wortmarke mit Beta und Einklappknopf, darunter der Mandant -- */

.leiste-kopf {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.leiste .marke {
  min-height: 36px;
  padding: 0 52px 0 6px;
}

.leiste .wortmarke-bild,
.leiste .wortmarke-bild img {
  width: 101px;
}

/* DER KNOPF ZUM CHAT, "Frag Caselli" (Auftrag 21.10.2026), an der Stelle, an der die
 * Mandantkarte stand. DECKEND mit Haarlinie wie jede Karte; in Ruhe neutral, die Glasblase des
 * Chatbots ist das Einzige mit Farbe. Beim Hover fuellt sich der Knopf mit dem
 * Akzentverlauf des Logos (Sky -> Indigo, `--verlauf-a/b`): ein Lichtwisch in 30 Grad Richtung
 * von links, der Pfeil schiebt sich ein - ohne Schein darunter. Der Punkt rechts ist die
 * Signatur der Marke (rund, Indigo) und pulsiert, solange Caselli antwortet. */
.leiste-chat {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 8px 14px 8px 8px;
  overflow: hidden;
  border: 1px solid var(--leiste-kante);
  border-radius: var(--radius-mittel);
  background: var(--flaeche-erhoben);
  color: var(--leiste-text);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  isolation: isolate;
  transition:
    border-color var(--zeit-kurz) var(--kurve-aus),
    box-shadow var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

.leiste-chat::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background: linear-gradient(120deg, var(--verlauf-a), var(--verlauf-b) 70%);
  opacity: 0;
  transform: translateX(-24%) skewX(-30deg);
  transition:
    opacity var(--zeit-kurz) var(--kurve-aus),
    transform 420ms var(--kurve-aus);
}

.leiste-chat:hover,
.leiste-chat:focus-visible {
  border-color: transparent;
  box-shadow: var(--karte-schatten);
  color: var(--akzent-knopf-text);
  transform: translateY(-1px);
}

.leiste-chat:hover::before,
.leiste-chat:focus-visible::before {
  opacity: 1;
  transform: translateX(0) skewX(0);
}

.leiste-chat:active {
  transform: translateY(0);
}

/* DAS ZEICHEN DES CHATS: die Glasblase aus dem Chatbot-Kit (Auftrag 26.10.2026), als Datei und
 * unveraendert (`marke/caselli-bot-icon.svg`). Ohne Kachel, Rand und Schatten und ohne eigene
 * Bewegung - die Regeln des Kits (1, 2, 5: kein Drehen, kein Wackeln). Ein Hintergrundbild wie
 * `.marke-zeichen`, so braucht keine Vorlage die Adresse. 30 px: das Kit nennt 28 bis 36 fuer
 * Kopfzeilen, und unter 24 px gar nicht. */
.leiste-chat-zeichen {
  display: inline-block;
  flex: none;
  width: 30px;
  height: 30px;
  background: url("marke/caselli-bot-icon.svg") center / contain no-repeat;
}

.leiste-chat-wort {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leiste-chat-pfeil {
  display: inline-flex;
  flex: none;
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

.leiste-chat:hover .leiste-chat-pfeil,
.leiste-chat:focus-visible .leiste-chat-pfeil {
  opacity: 1;
  transform: translateX(0);
}

.leiste-chat-punkt {
  position: absolute;
  top: 9px;
  right: 10px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--akzent-knopf);
  opacity: 0;
}

.leiste-chat:hover .leiste-chat-punkt,
.leiste-chat:focus-visible .leiste-chat-punkt {
  background: var(--akzent-knopf-text);
}

.rahmen:has(#chat-bereich[data-stand="wartet"]) .leiste-chat-punkt {
  opacity: 1;
  animation: dienst-puls 1.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .leiste-chat,
  .leiste-chat::before,
  .leiste-chat-pfeil {
    transition: none;
  }

  .leiste-chat:hover,
  .leiste-chat:focus-visible {
    transform: none;
  }

  .rahmen:has(#chat-bereich[data-stand="wartet"]) .leiste-chat-punkt {
    animation: none;
  }
}

/* --- Die Abschnitte und ihre Eintraege ------------------------------- */

.leiste-lage {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
  gap: 16px;
}

/* Der Teil, der scrollt, wenn die Leiste hoeher ist als das Fenster. */
.leiste-abschnitte {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 20px;
  min-height: 0;
  margin: 0 -6px;
  padding: 0 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--linie-stark) transparent;
}

.leistenabschnitt {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.leistenabschnitt-titel {
  padding: 0 12px 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--leiste-leise);
}

/* Ein Eintrag: 40 px hoch, Pille mit 12 px Radius (Mockup). Leise in der
 * zweiten Schriftfarbe, beim Darueberfahren der Hauch der Akzentflaeche. */
.leisteneintrag {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 40px;
  padding: 0 12px;
  border-radius: 12px;
  color: var(--leiste-zweit);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus);
}

.leisteneintrag:hover {
  background: var(--flaeche-zart);
  color: var(--leiste-text);
}

/* Der aktive Eintrag. Regel 3: die Flaeche sagt es nicht allein - die
 * Schrift wird kraeftiger, und `aria-current` sagt es dem Screenreader. */
.leisteneintrag[aria-current="page"] {
  background: var(--leiste-aktiv);
  box-shadow: inset 0 0 0 1px var(--akzent-kante);
  color: var(--leiste-text);
  font-weight: 600;
}

.leisteneintrag-wort {
  flex-grow: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leisteneintrag-zahl {
  font-size: 12px;
  color: var(--leiste-leise);
  white-space: nowrap;
}

/* Die Zahl am aktiven Eintrag: eine gefuellte Indigo-Pille (Mockup). */
.leisteneintrag[aria-current="page"] .leisteneintrag-zahl {
  display: grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 7px;
  border-radius: var(--radius-pille);
  background: var(--akzent-knopf);
  color: var(--akzent-knopf-text);
  font-weight: 700;
  box-shadow: 0 4px 12px -4px var(--knopf-schein);
}

/* NIEDRIGE FENSTER: bei 900 px Hoehe passen drei Abschnitte gerade nicht
 * ganz (gemessen am Chat-Pruefstand, 25 px zu viel), und der aktive
 * Eintrag unten verschwand hinter der Dienstlage. Unter 900 px ruecken die
 * Eintraege zusammen, bevor der Teil scrollen muss. */
@media (max-height: 900px) {
  .leiste-abschnitte {
    gap: 12px;
  }

  .leisteneintrag {
    min-height: 34px;
  }

  .leistenabschnitt-titel {
    padding-bottom: 4px;
  }
}

/* --- Die Dienstlage, unten: eine kleine Karte, Punkt und Satz ---------
 *
 * OHNE ZEICHEN DER MARKE (Rueckmeldung 05.10.2026: zu viele Logos). Der
 * Punkt sagt den Zustand, der Satz die Auskunft; in der Zeichenspalte
 * bleibt nur der Punkt (leiste-schmal.css), der Satz steht im `title`. */

.dienstkasten {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex: none;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--leiste-kante);
  border-radius: 16px;
  background: var(--flaeche-zart);
}

/* Der Punkt steht auf der Hoehe der ersten Zeile. */
.dienstkasten > .dienstpunkt {
  margin-top: 5px;
}

.dienstkasten-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.dienstkasten-kopf {
  font-size: 13px;
  font-weight: 600;
}

.dienstkasten-zeile {
  font-size: 12px;
  line-height: 1.4;
  color: var(--leiste-leise);
}

/* Hohl heisst "steht" oder "keiner", gefuellt "laeuft", mit Puls
 * "arbeitet gerade" (`anzeige.betriebsaussage`). */
.dienstpunkt {
  width: 7px;
  height: 7px;
  flex: none;
  border: 1.5px solid var(--frage-kante);
  border-radius: 999px;
}

.dienstpunkt-laeuft,
.dienstpunkt-arbeitet {
  border-color: var(--leiste-lauf);
  background: var(--leiste-lauf);
}

.dienstpunkt-arbeitet {
  animation: dienst-puls 1.9s ease-in-out infinite;
}

/* "Verarbeitung steht": gefuellt in Bernstein - es muss jemand hinsehen,
 * aber es brennt nicht (Mockup). */
.dienstpunkt-steht {
  border-color: var(--frage);
  background: var(--frage);
}

/* --- Unten: der Kontobereich und sein Menue (Block B) -------------- */

.leiste-fuss {
  position: relative;
  display: flex;
  flex-direction: column;
}

/* DER AUSLOESER auf der Leiste: Initialen, Name, Adresse, Pfeil. */
.konto-knopf {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-width: 0;
  padding: 8px 8px 8px 6px;
  border: 0;
  border-radius: var(--radius-mittel);
  background: none;
  color: var(--leiste-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  list-style: none;
  transition: background-color var(--zeit-kurz) var(--kurve-aus);
}

.konto-knopf::-webkit-details-marker {
  display: none;
}

.konto-knopf:hover,
.konto-knopf[aria-expanded="true"],
.konto-ersatz[open] > .konto-knopf {
  background: var(--flaeche-zart);
}

/* Die Initialen im Kreis: der schnellste Weg zu sehen, dass man
 * angemeldet ist und als wer. */
.profilzeichen {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: none;
  border: 1px solid var(--linie-stark);
  border-radius: 999px;
  background: var(--flaeche-zart);
  color: var(--leiste-text);
  font-size: 13px;
  font-weight: 700;
}

.profiltext {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}

/* LANGE NAMEN UND ADRESSEN: Auslassung; der volle Wert steht im `title`
 * des Ausloesers und im Menue. */
.profilname,
.kontomail {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profilname {
  font-size: 14px;
  font-weight: 600;
}

.kontomail {
  font-size: 12px;
  color: var(--leiste-leise);
}

.konto-pfeil {
  flex: none;
  color: var(--leiste-leise);
}

/* DER ERSATZ OHNE POPOVER bleibt verborgen, wo es Popover gibt. */
.konto-ersatz {
  display: none;
}

/* DAS MENUE SCHWEBT UEBER DEM INHALT: Glas auf der Huelle (`.huelle`),
 * erhoben durch den Schatten auf Hell und die hellere Kante auf Dunkel
 * (`--huelle-kante`, `--huelle-glanz`). Am unteren Rand der Leiste
 * ausgerichtet, nach rechts; die Breite der Leiste steht in
 * `--leistenbreite` (schmal: leiste-schmal.css).
 *
 * NUR `:popover-open` BEKOMMT EIN `display`. Ein `display` an
 * `.kontomenue` selbst schluege die Regel des Browsers, die ein
 * geschlossenes Popover verbirgt - das Menue stuende immer offen. */
.kontomenue {
  position: fixed;
  inset: auto auto var(--rand) calc(var(--leistenbreite) + 2 * var(--rand) + 8px);
  width: 280px;
  max-height: calc(100vh - 24px);
  margin: 0;
  padding: var(--a3);
  overflow-y: auto;
  color: var(--text);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    var(--huelle-schatten-hoch);
}

.kontomenue:popover-open {
  display: flex;
  flex-direction: column;
  gap: var(--a3);
}

/* Das Menue liegt im Baum IN der Leiste, schwebt aber ueber hellem oder
 * dunklem Grund - der Fokusring der Leiste (indigo-300 fuer Midnight)
 * waere dort zu blass. */
.kontomenue :focus-visible {
  outline-color: var(--fokus);
  box-shadow: 0 0 0 6px var(--fokus-schein);
}

.kontomenue-kopf {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.kontomenue .profilzeichen {
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.kontomenue-wer {
  display: flex;
  flex-direction: column;
  min-width: 0;
  margin: 0;
  line-height: 1.35;
}

.kontomenue-name {
  font-weight: 600;
}

/* Im Menue steht die Adresse GANZ da - hier ist der Ort, sie zu lesen. */
.kontomenue-mail {
  font-size: 13px;
  color: var(--text-zweit);
  overflow-wrap: anywhere;
}

.kontomenue-angaben {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 2px var(--a3);
  margin: 0;
  font-size: 13px;
}

.kontomenue-angaben dt {
  color: var(--text-zweit);
}

.kontomenue-angaben dd {
  margin: 0;
}

.kontomenue-eintraege {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.kontomenue-eintrag {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 34px;
  padding: 0 var(--a2);
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.kontomenue-eintrag:hover {
  background: var(--akzent-flaeche);
}

.kontomenue-titel {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-zweit);
}

/* Die Themenwahl: drei Knoepfe, ein Formular, der Wert aus dem Knopf. */
.themenwahl {
  display: flex;
  flex-direction: column;
  gap: var(--a1);
  margin: 0;
}

.themenknoepfe {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--linie);
  border-radius: 8px;
}

.themenknopf {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 30px;
  padding: 0 6px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-zweit);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.themenknopf:hover {
  background: var(--akzent-flaeche);
  color: var(--text);
}

/* Der gewaehlte. `aria-pressed` ist hier richtig - das sind Knoepfe und
 * keine Verweise. Regel 3: Flaeche, Schriftfarbe UND ein Strich unten. */
.themenknopf[aria-pressed="true"] {
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  box-shadow: inset 0 -2px 0 var(--akzent-text);
}

.kontomenue-trenner {
  width: 100%;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--linie);
}

.abmeldeformular {
  margin: 0;
}

/* OHNE POPOVER (Firefox 120 bis 124): der Ausloeser ist ein `<summary>`,
 * und das Menue steht offen, solange `<details>` offen ist - fest
 * positioniert, damit die Leiste (`overflow: hidden`) es nicht
 * abschneidet. Esc und Pfeiltasten gibt dort konto.js. */
@supports not selector(:popover-open) {
  #konto-knopf {
    display: none;
  }

  .konto-ersatz {
    display: block;
  }

  .kontomenue {
    display: none;
  }

  .konto-ersatz[open] ~ .kontomenue {
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: var(--a3);
  }
}

/* --- Mein Konto ------------------------------------------------------ */

.kontodaten {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--a2) var(--a4);
  margin: 0 0 var(--a3);
}

.kontodaten dt {
  color: var(--text-zweit);
}

.kontodaten dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* --- Die Baender oben im Arbeitsbereich ------------------------------ */

/* DIE BAENDER STEHEN AN DER KANTE DES INHALTS: der Rahmen haelt schon
 * 16 px zum Fenster und zur Leiste (`--rand`), der Inhalt nur noch die
 * 4 px des Mockup-Kopfs. Mit den alten 28 px stand ein Band eingerueckt
 * neben Karten, die buendig stehen. */
.arbeitsbereich > .mandantenband {
  margin: 0 4px var(--a4);
}

/* DAS STOERBAND ist eine Meldung im Inhaltsbereich: derselbe seitliche
 * Abstand wie der Seitenkopf, Luft nach unten, und es scrollt mit dem
 * Inhalt (es klebt nicht - der Listenkopf darunter klebt). */
.baender > .meldung {
  margin: 0 4px var(--a4);
}

/* ====================================================================
 * INHALT, KARTEN, KNOEPFE, FELDER, PLAKETTEN
 * ================================================================= */

/* DER INHALT NEBEN DER SCHWEBENDEN LEISTE (Mockup): oben 10 px Luft
 * ueber dem Kopf, seitlich 4 px, damit die Ueberschrift mit der
 * Kartenkante steht. Den Abstand zum Fenster haelt der Rahmen. */
.inhalt {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 10px 4px var(--a7);
}

/* ====================================================================
 * DIE VERWALTUNG ALS BEREICH (Rueckmeldung 27.10.2026)
 *
 * Links die Bereiche (Allgemein, Benutzer, Postfaecher, ...), rechts die Seite. Die Navigation
 * liegt auf dem Seitengrund, ohne Karte - sie ist Huelle, keine Daten; markiert wie die Leiste
 * (Flaeche, Kante, kraeftigere Schrift, `aria-current`). Schmal (nach der Breite des Inhalts,
 * nicht des Fensters: die Leiste kann ein- und ausgeklappt sein) steht sie als Zeile ueber der
 * Seite und rollt seitwaerts.
 * ================================================================= */
.inhalt:has(> .bereichsrahmen) {
  container: inhalt / inline-size;
}

.bereichsrahmen {
  display: grid;
  grid-template-columns: 12.5rem minmax(0, 1fr);
  gap: 32px;
  align-items: start;
}

.bereichsnavigation {
  position: sticky;
  top: var(--rand);
  padding-top: 6px;
}

.bereichsnavigation-titel {
  margin: 0 0 var(--a2) 12px;
  color: var(--text-leise);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.bereichsliste {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.bereichseintrag {
  align-items: center;
  min-height: 38px;
  padding: 0 12px;
  border-radius: 12px;
  color: var(--text-zweit);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--zeit-kurz) var(--kurve-aus);
}

.bereichseintrag:hover {
  background: var(--flaeche-zart);
  color: var(--text);
}

.bereichseintrag[aria-current="page"] {
  background: var(--leiste-aktiv);
  box-shadow: inset 0 0 0 1px var(--akzent-kante);
  color: var(--text);
  font-weight: 600;
}

.bereichseintrag-zeichen {
  color: var(--text-leise);
}

.bereichseintrag[aria-current="page"] .bereichseintrag-zeichen {
  color: var(--akzent-text);
}

.bereichsinhalt {
  min-width: 0;
}

/* „Zuletzt“ auf der Schalttafel: zwei Zeitpunkte untereinander, das Wort leise davor. */
.zuletztzeile {
  display: flex;
  gap: 6px;
  align-items: baseline;
  white-space: nowrap;
}

/* EINE KARTE IM BEREICH: ihre Ueberschrift wiederholte die der Seite ("Benutzer." ueber
 * "Benutzer"). Sie bleibt fuer den Screenreader; sichtbar steht nur ihr Knopf, rechts. Wo ein
 * Bereich mehrere Karten hat ("Wissen", "Allgemein" beim Betreiber), tragen sie ihre Namen. */
.bereichsinhalt > .karte:only-of-type > .kartenkopf {
  justify-content: flex-end;
}

.bereichsinhalt > .karte:only-of-type > .kartenkopf > h2 {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.bereichsinhalt > .karte:only-of-type > .kartenkopf:not(:has(> :not(h2))) {
  margin-bottom: 0;
}

/* DIE REITERZEILE OBEN (Schalttafel): ihre Tabellen brauchen die ganze Breite. Dieselbe Gestalt
 * wie die schmale Fassung unten. */
.bereichsrahmen-oben {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--a4);
}

.bereichsrahmen-oben .bereichsnavigation {
  position: static;
  padding-top: 0;
}

.bereichsrahmen-oben .bereichsnavigation-titel {
  display: none;
}

.bereichsrahmen-oben .bereichsliste {
  display: flex;
  gap: 4px;
  overflow-x: auto;
}

.betriebstabelle th[scope="row"] {
  text-align: left;
  font-weight: 500;
}

@container inhalt (max-width: 52rem) {
  .bereichsrahmen {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--a4);
  }

  .bereichsnavigation {
    position: static;
    padding-top: 0;
  }

  .bereichsnavigation-titel {
    display: none;
  }

  .bereichsliste {
    display: flex;
    gap: 4px;
    overflow-x: auto;
  }
}

/* DER SEITENKOPF DES MOCKUPS: links Ueberschrift und Unterzeile, rechts
 * die Knoepfe der Seite, unten buendig. */
.seitenkopf {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--a3) var(--a4);
  margin-bottom: 20px;
}

/* `min-width: 0`: sonst wird der Textblock so breit wie sein laengstes
 * Wort - in der breiten Fassung ist "Verpackungseinheiten" bei 375 px
 * breiter als das Fenster (gemessen, Regel 33). */
.seitenkopf > * {
  min-width: 0;
}

/* DIE HEADLINE-SIGNATUR DES KITS AUF JEDER SEITE: breite Archivo 800,
 * eng gesetzt, dahinter der RUNDE Indigo-Punkt mit seinem Leuchten statt
 * eines Satzzeichens. Der Punkt ist ein `::after` ohne Text - fuer den
 * Screenreader bleibt die Ueberschrift, was sie ist. Die Groesse waechst
 * mit dem Fenster: 26 px auf dem Telefon, 36 px am Arbeitsplatz (das
 * Mockup setzt 38 px; auf der Freigabe kostet jede Zeile Positionen). */
.seitenkopf h1,
.freigabekopf h1 {
  margin: 0;
  font-size: clamp(26px, 1.6vw + 13px, 36px);
  font-weight: 700;
  font-stretch: var(--schrift-breite-titel);
  letter-spacing: -0.025em;
  line-height: 1.08;
}

.seitenkopf h1::after,
.freigabekopf h1::after,
.listenkopf h1::after {
  content: "";
  display: inline-block;
  width: 0.18em;
  height: 0.18em;
  margin-left: 0.06em;
  border-radius: 50%;
  background: var(--akzent-knopf);
}

.seitenkopf .unterzeile {
  margin: 10px 0 0;
  font-size: 14px;
  color: var(--text-zweit);
}

/* DIE KARTE DES MOCKUPS: 24 px Radius, Haarlinie, der Schatten mit
 * Indigo-Stich und die helle Innenkante oben. Deckend und nie Glas: auf
 * ihr stehen Daten. Auf Dunkel traegt die Innenkante die Erhebung. */
.karte {
  padding: var(--a5);
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius-karte);
  box-shadow: var(--karte-schatten);
}

.karte + .karte {
  margin-top: var(--a4);
}

.karte-schmal {
  max-width: 520px;
  margin: var(--a7) auto;
}

/* Die Datenkarte. Dieselbe Kante, kein Innenabstand - die Tabelle
 * fuellt sie ganz aus. */
.karte-daten {
  padding: 0;
  overflow: hidden;
}

/* --- Knoepfe. Regel 1: genau EIN gefuellter je Bildschirm. -------- */

.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--a2);
  min-height: 36px;
  padding: var(--a2) var(--a4);
  border: 1px solid transparent;
  border-radius: var(--radius-pille);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.15;
  text-align: center;
  cursor: pointer;
  background: none;
  color: inherit;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    border-color var(--zeit-kurz) var(--kurve-aus),
    box-shadow var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

a.knopf {
  text-decoration: none;
}

/* Der Primaerknopf des Kits: Pille, Indigo, Weiss 600, ein weiches
 * Leuchten (`--glow-accent`). Hover: hellerer Ton und 1 px nach oben.
 * Das Leuchten ist der Grund, warum es genau EINEN je Bildschirm gibt. */
.knopf-haupt {
  background: var(--akzent-knopf);
  border-color: var(--akzent-knopf);
  color: var(--akzent-knopf-text);
  box-shadow:
    inset 0 0 0 1px var(--knopf-schein-kante),
    0 10px 28px -12px var(--knopf-schein);
}

.knopf-haupt:hover {
  background: var(--akzent-knopf-hover);
  border-color: var(--akzent-knopf-hover);
  transform: translateY(-1px);
}

.knopf-haupt:active {
  transform: none;
}

.knopf-zweit {
  background: var(--flaeche);
  border-color: var(--linie-stark);
  color: var(--text);
}

.knopf-zweit:hover {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
}

.knopf-gefaehrlich {
  background: none;
  border-color: var(--grenze-kante);
  color: var(--grenze);
}

.knopf-gefaehrlich:hover {
  background: var(--grenze-flaeche);
}

.knopf-flach {
  background: none;
  border-color: transparent;
  color: var(--text-zweit);
  padding: var(--a2) var(--a3);
}

.knopf-flach:hover {
  background: var(--flaeche-erhoben);
  color: var(--text);
}

/* EIN GESPERRTER KNOPF TRAEGT EINE NACHRICHT, also muss er lesbar sein.
 *
 * Vorher stand hier `opacity: 0.45`. Das blasst Schrift UND Flaeche
 * gemeinsam aus, und der Abstand zwischen beiden faellt mit - auf dem
 * Freigabebildschirm steht auf genau diesem Knopf "Freigabe gesperrt: 1
 * Grenze gerissen", also die Auskunft, warum hier nichts weitergeht.
 * WCAG nimmt abgeschaltete Bedienelemente von der Kontrastpflicht aus;
 * das gilt fuer einen Knopf, auf dem nichts steht, was man wissen muss.
 * Dieser hier ist keiner.
 *
 * Deckende, ruhige Flaeche mit `--text-zweit`: ein Paar, das in beiden
 * Themen gemessen ist. Dass der Knopf nicht geht, sagen Cursor, Kante
 * und die fehlende Signalfarbe - und der Satz auf ihm. */
.knopf[disabled] {
  cursor: not-allowed;
  background: var(--flaeche-erhoben);
  border-color: var(--linie);
  color: var(--text-zweit);
  box-shadow: none;
}

.knopfleiste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  justify-content: flex-end;
}

/* --- Felder ------------------------------------------------------- */

.feld {
  display: block;
  margin-bottom: var(--a4);
}

.feld > label > span,
.feld > span {
  display: block;
  margin-bottom: var(--a1);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-zweit);
}

.textfeld,
.zahlenfeld {
  width: 100%;
  min-height: 38px;
  padding: var(--a2) var(--a3);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche-vertieft);
  color: var(--text);
  font-family: var(--schrift);
  font-size: 15px;
}

/* Regel 2: jede Zahl mit gleich breiten Ziffern, rechtsbuendig - so
 * stehen Kommastellen untereinander. */
.zahlenfeld {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.textfeld::placeholder,
.zahlenfeld::placeholder {
  color: var(--text-leise);
  opacity: 1;
}

.textfeld:focus,
.zahlenfeld:focus {
  border-color: var(--fokus);
  outline: none;
  box-shadow:
    0 0 0 2px var(--grund),
    0 0 0 5px var(--fokus-schein);
}

select.textfeld {
  appearance: none;
  background-color: var(--flaeche-vertieft);
}

/* --- Plaketten. Regel 3: das Wort steht IM Merkmal. --------------- */

.merkmal {
  display: inline-flex;
  align-items: center;
  gap: var(--a1);
  padding: 2px var(--a2);
  border: 1px solid var(--linie);
  border-radius: var(--radius-pille);
  background: var(--flaeche-erhoben);
  color: var(--text-zweit);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}

.merkmal-signal {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.merkmal-frage {
  border-color: var(--frage-kante);
  background: var(--frage-flaeche);
  color: var(--frage);
}

.merkmal-grenze {
  border-color: var(--grenze-kante);
  background: var(--grenze-flaeche);
  color: var(--grenze);
}

.merkmal-erfolg {
  border-color: var(--erfolg-kante);
  background: var(--erfolg-flaeche);
  color: var(--erfolg);
}

/* Etwas zu wissen, nichts zu tun: Bestand knapp, Preis weicht ab. */
.merkmal-hinweis {
  border-color: var(--hinweis-flaeche);
  background: var(--hinweis-flaeche);
  color: var(--hinweis);
}

.merkmal-bereit {
  border-color: var(--bereit-flaeche);
  background: var(--bereit-flaeche);
  color: var(--bereit);
}

/* RUHIGE OBERFLAECHE (A.3): eine Ursache, die keine Farbe braucht -
 * Rueckfragen, Eskaliert, Kein Kunde, Keine Bestellung, Zeichen geraten,
 * und jeder entschiedene Zustand. Haarlinie, deckende Flaeche, Symbol und
 * Wort; die Form traegt, was vorher die Farbe trug. */
.merkmal-neutral {
  border-color: var(--linie);
  background: var(--flaeche);
  color: var(--text-zweit);
}

/* Etwas zu wissen, nichts zu tun: kein Kasten, nur kleiner grauer Text.
 * Steht nur da, wenn eine Zeile sonst nichts zu sagen hat. */
.merkmal-leise {
  border-color: transparent;
  background: transparent;
  color: var(--text-leise);
  font-weight: 400;
}

.merkmal > .zeichen {
  flex: none;
}

/* Das "+n": was die Zeile ausserdem weiss, im `title`. Leise, aber in
 * der Schriftfarbe, die sich lesen laesst (Kontrast gemessen). */
.merkmal-mehr {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--a1);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-leise);
  cursor: help;
  white-space: nowrap;
}

.merkmal .zahl {
  font-weight: 500;
}

/* ====================================================================
 * DIE TABELLE. DER ARBEITSPLATZ.
 *
 * KEIN GLAS, NIRGENDS - das Gesetz. Haarlinien zwischen den Zeilen,
 * kein Kasten um jede Zelle.
 * ================================================================= */

/* Der Rahmen, in dem eine breite Tabelle seitwaerts scrollt. Die Leiste
 * ist duenn und bleibt sichtbar: wer schmal arbeitet, soll sehen, dass es
 * rechts weitergeht. `position: relative`, weil auch absolut gesetzte
 * Kinder (der Satz fuer Screenreader im Tabellenkopf) im Rahmen bleiben
 * muessen - sonst ragten sie aus der Seite und machten sie auf dem
 * Telefon 663 statt 375 px breit (gemessen 05.10.2026). */
.tabellenrahmen {
  position: relative;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--linie-stark) transparent;
}

.tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.tabelle thead th {
  padding: var(--a2) var(--a3);
  background: var(--flaeche-kopf);
  border-bottom: 1px solid var(--linie-stark);
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-zweit);
  white-space: nowrap;
}

.tabelle th.rechts {
  text-align: right;
}

.tabelle td {
  padding: var(--a2) var(--a3);
  border-bottom: 1px solid var(--linie);
  vertical-align: top;
  line-height: 1.35;
}

.tabelle tbody tr:last-child td {
  border-bottom: none;
}

/* DIE GANZE ZEILE IST DER LINK.
 *
 * `position: relative` auf der Zeile, und der Link spannt sich mit einem
 * `::after` darueber. Das ist der einzige Weg, der ein ECHTES `<a href>`
 * behaelt: mit der Tastatur erreichbar, mit der mittleren Maustaste in
 * einem neuen Tab zu oeffnen, und ohne eine Zeile JavaScript.
 *
 * WAS ES KOSTET (OFFENE_PUNKTE, Punkt 143): die aufgespannte Flaeche
 * faengt auch das Markieren mit der Maus. */
.tabelle tbody tr {
  position: relative;
}

.zeilenlink {
  display: block;
  color: inherit;
  text-decoration: none;
}

.zeilenlink::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 2px;
}

.tabelle tbody tr:hover td {
  background: var(--flaeche-erhoben);
}

.zeilenlink:hover .kunde-name {
  color: var(--akzent-text);
}

/* Der Fokus umschliesst die GANZE Zeile und nicht nur das Wort in der
 * Kundenspalte - er zeigt damit genau das, was ein Druck auf die
 * Eingabetaste treffen wuerde. */
.zeilenlink:focus-visible {
  outline: none;
  box-shadow: none;
}

.zeilenlink:focus-visible::after {
  outline: 2px solid var(--fokus);
  outline-offset: -2px;
  background: var(--akzent-flaeche);
}

/* Regel 2: jede Zahl mit gleicher Ziffernbreite. Archivo hat sie mit
 * `tnum` (gemessen in befunde/archivo_befund.json); `tabular-nums` steht
 * schon am `body` und hier noch einmal. Keine eigene Schrift, keine eigene
 * Groesse - die Zahl steht so gross wie der Satz um sie herum. */
.tabelle .zahl,
.zahl {
  font-variant-numeric: tabular-nums;
}

/* Rechtsbuendig NUR bei Mengen und Betraegen. Eine Artikelnummer ist eine
 * Kennung und keine Groesse. */
.rechts {
  text-align: right;
}

/* Ein Schluesselabdruck: Zeichen fuer Zeichen verglichen, also in echter
 * Festbreite. Nur hier und am Bestelltext, siehe `--schrift-fest`. */
.festbreite {
  font-family: var(--schrift-fest);
  font-variant-numeric: tabular-nums;
}

.leise {
  color: var(--text-leise);
  font-size: 12px;
}

.kunde-name {
  display: block;
  font-weight: 500;
  font-size: 14px;
}

.zweitzeile {
  display: block;
  margin-top: 1px;
  color: var(--text-leise);
  font-size: 11px;
}

.eingang {
  white-space: nowrap;
}

/* Die Anlasskennung wird abgeschnitten und nicht weggelassen: sie ist
 * die Message-ID, mit der ein Sachbearbeiter die Mail in seinem
 * Postfach wiederfindet. Vollstaendig steht sie im `title`. */
.kennung {
  display: block;
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Der Wert. Die Zeile darunter sagt, WAS fuer eine Zahl das ist -
 * unsere Schaetzung oder der Belegwert aus dem ERP. Ohne sie stuenden
 * zwei verschiedene Dinge in einer Spalte und saehen gleich aus
 * (CLAUDE.md, Regel 17). */
.wert {
  display: block;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* ====================================================================
 * DIE VORGANGSLISTE. Posteingangsstil nach dem Entwurf.
 *
 * Kopf mit Name der Ansicht, Satz und Suche; darunter der Kasten, der
 * sich alle zehn Sekunden selbst tauscht. Die Tabelle bleibt eine
 * Tabelle (Spaltenkoepfe fuer den Screenreader, rechtsbuendige Zahlen),
 * gezeichnet wie das Raster des Entwurfs: Punkt, Kunde und Betreff,
 * Stand, Pos., Wert netto, Eingang.
 *
 * DER KOPF KLEBT, und zwar am FENSTER: der Arbeitsbereich ist kein
 * eigener Scrollkasten, also bezieht sich `position: sticky` auf das
 * Fenster (Regel 33, Beleg 3 - der klebende Tabellenkopf vom 22.09.2026
 * klebte am falschen Kasten). Im Browser nachgemessen.
 * ================================================================= */

.inhalt-liste {
  max-width: none;
  padding: 0;
}

/* DER LISTENKOPF SCHWEBT (Mockup, Kopfleiste): ein Glaspanel wie die
 * Leiste, mit derselben Kante oben (`--rand`), sodass beide als ein
 * Rahmen um die Daten stehen. Glas ist hier erlaubt - der Kopf ist
 * Huelle und schwebt, auf ihm stehen Name, Satz und Suche, keine Daten.
 * Die Zeilen der Tabelle laufen beim Scrollen darunter durch. */
.listenkopf {
  position: sticky;
  top: var(--rand);
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: var(--kopfhoehe);
  padding: 10px 12px 10px 24px;
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-karte);
  background: var(--huelle-stark);
  box-shadow: var(--karte-schatten);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
}

.listenkopf h1 {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  font-stretch: var(--schrift-breite-titel);
  letter-spacing: -0.02em;
  line-height: 1.1;
  white-space: nowrap;
}

.listensatz {
  margin: 0;
  overflow: hidden;
  font-size: 13.5px;
  color: var(--text-leise);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.suche {
  position: relative;
  flex: 0 1 340px;
  min-width: 180px;
  margin: 0 0 0 auto;
}

/* Auf dem Telefon eine eigene Zeile ueber die ganze Breite: neben der
 * Ueberschrift ist kein Platz fuer 180 px (gemessen bei 375 px). */
@media (max-width: 40em) {
  .listenkopf {
    flex-wrap: wrap;
    gap: 6px 12px;
    padding: 14px 14px 14px 18px;
    border-radius: var(--radius-gross);
  }

  .listenkopf h1 {
    font-size: 22px;
  }

  .suche {
    flex: 1 1 100%;
    min-width: 0;
    margin: 4px 0 0;
  }
}

.suchzeichen {
  position: absolute;
  top: 50%;
  left: 16px;
  display: flex;
  color: var(--text-leise);
  transform: translateY(-50%);
  pointer-events: none;
}

/* DAS SUCHFELD ALS PILLE (Mockup: runde Knoepfe im Kopf, 44 px): deckend
 * auf dem Glas, damit der Text darin vollen Kontrast hat. */
.suchfeld {
  width: 100%;
  height: 44px;
  padding: 0 16px 0 42px;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-pille);
  background: var(--flaeche);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  transition:
    border-color var(--zeit-kurz) var(--kurve-aus),
    box-shadow var(--zeit-kurz) var(--kurve-aus);
}

.suchfeld::placeholder {
  color: var(--text-leise);
  opacity: 1;
}

.suchfeld:focus {
  border-color: var(--fokus);
  outline: none;
  box-shadow:
    0 0 0 2px var(--flaeche),
    0 0 0 5px var(--fokus-schein);
}

.listenbereich {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 0 var(--a6);
}

.listenbereich > .meldung {
  margin: 0;
}

.tabellenkasten {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tabellenkasten > .meldung {
  margin: 0;
}

.listenmeta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--a1) var(--a3);
  font-size: 13px;
  color: var(--text-leise);
}

/* Die Blaetterzeile unter der Tabelle (Punkt 204.4) - nur, wenn die
 * Ansicht nicht auf eine Seite passt. Leise wie die Listenmeta; die
 * Verweise sind gewoehnliche Verweise. */
.blaetterzeile {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: var(--a1) var(--a3);
  font-size: 13px;
  color: var(--text-leise);
}

/* --- Die Tabelle ---------------------------------------------------- */

.liste {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

/* AUF DEM TELEFON SCROLLT DIE LISTE IN IHRER KARTE. Die festen Spalten
 * brauchen mit Innenabstand zusammen 654 px; bei 375 px blieb fuer Kunde
 * und Betreff nichts (gemessen, Regel 33). Die Tabelle behaelt deshalb
 * 860 px, gut 200 davon fuer den Namen; die Karte scrollt waagrecht, die
 * Seite nicht. */
@media (max-width: 40em) {
  .karte-daten {
    overflow-x: auto;
  }

  .liste {
    min-width: 860px;
  }
}

/* Die Spalten wie im Entwurf (14 / Rest / 300 / 52 / 120 / 56 px), dazu
 * je 18 px Abstand links und 20 px Rand aussen. */
.spalte-punkt {
  width: 34px;
}

.spalte-stand {
  width: 318px;
}

.spalte-pos {
  width: 70px;
}

.spalte-wert {
  width: 138px;
}

.spalte-eingang {
  width: 94px;
}

/* DER KOPF, LEISE (A.5): keine eigene Flaeche mehr, nur die zarte Linie
 * darunter. Er sagt, was in den Spalten steht - er ist kein Balken. Die
 * Masse bleiben die des Entwurfs (10 px oben und unten). */
.liste th {
  padding: 10px 0 10px 18px;
  border-bottom: 1px solid var(--linie-zart);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-align: left;
  color: var(--text-leise);
  white-space: nowrap;
}

/* Zeilen im Mass des Entwurfs (mindestens 64 px, 12 px innen). Die Luft
 * kommt daher, dass keine Zeile mehr umbricht - hoechstens zwei Merkmale
 * und ein "+n" passen in die Spalte -, nicht aus groesseren Massen. Die
 * Trennlinie ist die zarteste, die es gibt. */
.liste td {
  height: 64px;
  padding: 12px 0 12px 18px;
  border-top: 1px solid var(--linie-hauch);
  vertical-align: middle;
}

.liste tbody tr:first-child td {
  border-top: none;
}

.liste th:first-child,
.liste td:first-child {
  padding-left: 20px;
}

.liste th:last-child,
.liste td:last-child {
  padding-right: 20px;
}

.liste .rechts {
  text-align: right;
}

/* DIE GANZE ZEILE IST DER VERWEIS - `.zeilenlink` spannt sich per
 * `::after` ueber sie, und dafuer braucht die Zeile eine Position. */
.listenzeile {
  position: relative;
}

.listenzeile:hover td {
  background: var(--flaeche-kopf);
}

/* Der Punkt vorn: DREI Zustaende und nicht mehr jede Art (A.4) - muss
 * jemand ran, ist es bereit, ist es erledigt. Nur zum Ueberfliegen; er
 * ist `aria-hidden`, das Wort steht im Stand. */
.listenpunkt {
  display: block;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  background: var(--linie);
}

.punkt-ran {
  background: var(--frage);
}

.punkt-bereit {
  background: var(--bereit);
}

.punkt-erledigt {
  background: var(--linie-stark);
}

.listenkunde {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.liste .kunde-name {
  overflow: hidden;
  font-size: 14.5px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kunde-fehlt {
  color: var(--text-zweit);
  font-weight: 500;
}

.herkunft {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--text-leise);
}

.betreff {
  display: block;
  margin-top: 3px;
  overflow: hidden;
  font-size: 13px;
  color: var(--text-leise);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.betreff-geloescht {
  font-style: italic;
}

.standfeld {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

/* Die Merkmale der Liste: Pillen wie im Entwurf, deckend gefuellt. Ein
 * neutrales ("Grenzen nicht geprueft") behaelt seine Haarlinie, damit es
 * nicht wie leerer Raum aussieht. */
.liste .merkmal {
  height: 24px;
  padding: 0 9px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}

/* Die GEFAERBTEN verlieren ihre Kante - die Flaeche traegt. Die neutrale
 * behaelt ihre Haarlinie, sonst saehe sie aus wie leerer Raum. */
.liste .merkmal-grenze,
.liste .merkmal-bereit {
  border-color: transparent;
}

.liste .merkmal-leise {
  height: auto;
  padding: 0;
  font-weight: 400;
}

.liste .wert {
  font-size: 14px;
  font-weight: 600;
}

.liste .zweitzeile {
  margin-top: 1px;
  font-size: 11.5px;
}

.liste .eingang {
  font-size: 13px;
  color: var(--text-leise);
  white-space: nowrap;
}

/* ====================================================================
 * TASTENKAPPEN
 * ================================================================= */

.tastenkappe {
  display: inline-block;
  min-width: 20px;
  padding: 1px var(--a1);
  border: 1px solid var(--linie-stark);
  border-bottom-width: 2px;
  border-radius: var(--a1);
  background: var(--flaeche-vertieft);
  font-size: 12px;
  color: var(--text-zweit);
  text-align: center;
}

/* ====================================================================
 * DIE BEWEGUNG DES DIENSTES (der Punkt in der Leiste, `.dienstpunkt-arbeitet`)
 *
 * DIE BEWEGUNG HAENGT AN EINEM ECHTEN ZUSTAND und laeuft nur, solange
 * der Herzschlag der Dienstsperre lebt. Eine Animation, die immer
 * laeuft, waere Dekoration und keine Auskunft.
 *
 * Regel 3: die Bewegung sagt nie etwas allein. Neben dem Punkt steht
 * immer der Satz, und ohne Bewegung bleibt der Satz stehen.
 * ================================================================= */

@keyframes dienst-puls {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.3;
  }
}

/* ====================================================================
 * MELDUNGEN - ein Bauteil fuer alles (`_meldung.html`).
 *
 * VIER ARTEN, JE EIN FARBPAAR: `--m-farbe` fuer Rand und Symbol,
 * `--m-flaeche` fuer die Toenung. Beides sind Bedeutungsnamen; Rohfarben
 * stehen nur in den Zeichenbloecken.
 *
 * EINE KARTE IM INHALT, nie randlos: Radius wie die Karten, duenner Rand
 * in der Farbe der Art, Flaeche leicht getoent. DECKEND AUF ZWEI EBENEN:
 * die Toenung liegt ueber `--flaeche`, denn Erfolg und Fehler sind im
 * dunklen Thema rgba - allein bestimmte der Grund darunter die Flaeche.
 *
 * DIE SCHRIFT IST `--text` UND NICHT DIE FARBE DER ART: der Satz muss
 * gelesen werden. Die Art tragen Rand, Symbol (Form!) und das Wort vor
 * der Kopfzeile. Kontrast gemessen, siehe Bericht zur Rueckmeldung nach
 * Teil 3 (Text 4,5:1, Rand und Symbol 3:1).
 *
 * "UNBEKANNT" (Regel 4) ist eine Warnung und kein Fehler: rot hiesse
 * "fehlgeschlagen", und genau das ist ein unbekannter Ausgang nicht.
 * ================================================================= */

.meldung {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--a1) var(--a3);
  margin: 0 0 var(--a4);
  padding: var(--a3) var(--a4);
  border: 1px solid var(--m-farbe);
  border-radius: var(--radius-gross);
  background: linear-gradient(var(--m-flaeche), var(--m-flaeche)), var(--flaeche);
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
}

.meldung > p {
  grid-column: 2;
  margin: 0;
}

.meldung-zeichen {
  grid-row: 1 / span 3;
  color: var(--m-farbe);
  padding-top: 1px;
}

.meldung-kopf {
  font-weight: 600;
}

/* ALS UEBERSCHRIFT (leerer Zustand, E.3) sieht der Kopf aus wie immer:
 * die Gliederung ist fuer Screenreader, nicht fuer das Auge. */
h2.meldung-kopf {
  grid-column: 2;
  margin: 0;
  font-size: inherit;
  line-height: inherit;
}

/* Eine Anlasskennung oder Adresse im Satz bricht um, statt die Karte
 * breiter zu machen als den Inhalt. */
.meldung-satz,
.meldung-kopf {
  overflow-wrap: anywhere;
}

.meldung-handlung a {
  font-weight: 500;
}

.meldung-info {
  --m-farbe: var(--hinweis);
  --m-flaeche: var(--hinweis-flaeche);
}

.meldung-erfolg {
  --m-farbe: var(--erfolg);
  --m-flaeche: var(--erfolg-flaeche);
}

.meldung-warnung {
  --m-farbe: var(--frage);
  --m-flaeche: var(--frage-flaeche);
}

.meldung-fehler {
  --m-farbe: var(--grenze);
  --m-flaeche: var(--grenze-flaeche);
}

.htmx-request .laedt,
.htmx-request.laedt {
  opacity: 0.55;
  transition: opacity var(--zeit-kurz) ease-in;
}

/* HTMX' eigene Anzeigestile. Sie stehen HIER, weil `includeIndicatorStyles`
 * aus ist (grund.html): HTMX fuegte sie sonst als <style>-Element ein, und
 * das verbietet die CSP (`style-src 'self'`). Wortgleich mit der Vorgabe
 * von HTMX 2.0.8, damit ein `hx-indicator` sich verhaelt wie dokumentiert. */
.htmx-indicator {
  opacity: 0;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
  transition: opacity 200ms ease-in;
}

/* ====================================================================
 * DIE ANMELDUNG. Der eine Bildschirm, der glaenzen darf.
 *
 * Ihre Farben stehen oben in `[data-buehne="anmeldung"]`; hier steht nur
 * der Aufbau. Sie folgt der Themenwahl NICHT - siehe dort.
 * ================================================================= */

.anmeldeseite {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--a7);
  max-width: 1180px;
  margin: 0 auto;
  padding: var(--a7) var(--a5);
}

/* DER BLOOM. Ein weiches Indigo-Licht auf Paper, wie `--grad-bloom` des
 * Kits: rechts, hinter der Karte, nie hinter dem Logo. Er steht still - das
 * Kit verbietet eigene Lichtanimationen, und Bewegung neben einem
 * Passwortfeld sagte den ganzen Tag lang nichts. */
.szene {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(55% 65% at 78% 52%, var(--licht-indigo), var(--licht-aus) 70%),
    radial-gradient(35% 40% at 68% 38%, var(--licht-sky), var(--licht-aus) 70%);
}

.buehne {
  position: relative;
  z-index: 1;
}

.buehne-marke {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--a3);
  margin-bottom: var(--a6);
}

.buehne-lockup {
  display: block;
  width: 248px;
  height: auto;
}

.buehne-marke .beta-marke {
  font-size: 11px;
  color: var(--marke-beta);
}

/* DIE HEADLINE-SIGNATUR des Kits: breite Archivo 800, die Ergaenzung
 * leise, am Ende ein runder Indigo-Punkt (`.signaturpunkt`). */
.buehne-zeile {
  margin: 0 0 var(--a6);
  max-width: 18ch;
  font-size: 40px;
  font-weight: 800;
  font-stretch: var(--schrift-breite-marke);
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--text);
}

.buehne-zeile .leise {
  font-size: inherit;
  font-weight: inherit;
  color: var(--text-leise);
}

/* Ein Kreis und nicht das eckige Satzzeichen der Schrift (Kit, Abschnitt
 * 5). Auf der Grundlinie, Groesse aus der Schrift. */
.signaturpunkt {
  display: inline-block;
  width: 0.18em;
  height: 0.18em;
  margin-left: 0.06em;
  border-radius: 50%;
  background: var(--akzent-knopf);
  vertical-align: baseline;
}

/* WAS BETA HIER BEDEUTET, im Klartext und nicht als Sternchen. Der
 * Kasten ist leise und traegt links eine Kante in der Akzentfarbe: er
 * ist kein Warnhinweis und keine Werbung, sondern eine Zusage. */
.buehne-beta {
  max-width: 48ch;
  padding: var(--a4);
  border: 1px solid var(--huelle-kante);
  border-left: 2px solid var(--akzent-kante);
  border-radius: var(--radius-mittel);
  background: var(--huelle);
  -webkit-backdrop-filter: saturate(160%) blur(8px);
  backdrop-filter: saturate(160%) blur(8px);
  box-shadow: inset 0 1px 0 var(--huelle-glanz);
}

.buehne-beta .marke-zeile {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin-bottom: var(--a2);
}

.buehne-beta p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text-zweit);
}

.anmeldekarte {
  position: relative;
  z-index: 1;
  overflow: hidden;
  width: 100%;
  max-width: 440px;
  justify-self: end;
  padding: var(--a6);
  background: var(--huelle);
  -webkit-backdrop-filter: saturate(160%) blur(10px);
  backdrop-filter: saturate(160%) blur(10px);
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-karte);
  box-shadow: var(--karte-schatten);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .buehne-beta,
  .anmeldekarte {
    background: var(--huelle-deckend);
  }
}

.anmeldekarte h1 {
  font-size: 24px;
  margin-bottom: var(--a5);
}

.anmeldekarte .feld:last-of-type {
  margin-bottom: var(--a5);
}

.anmeldekarte .knopf-haupt {
  width: 100%;
  min-height: 44px;
  font-size: 15px;
}

.anmelde-fussnote {
  margin: var(--a4) 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-leise);
}

@media (max-width: 900px) {
  .anmeldeseite {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--a6);
    align-content: center;
  }

  .buehne-lockup {
    width: 180px;
  }

  .buehne-zeile {
    font-size: 28px;
    margin-bottom: var(--a5);
  }

  .anmeldekarte {
    justify-self: stretch;
    max-width: none;
    padding: var(--a5);
  }
}

/* ====================================================================
 * DER FREIGABEBILDSCHIRM (UI-Umbau Teil 2, docs/entwurf/Freigabe.dc.html)
 *
 * Kopf, Metazeile, links das Original, rechts die Positionen, unten eine
 * Entscheidungsleiste, die am Fenster klebt. Deckend und mit Haarlinie,
 * wie alles, was im Seitenfluss steht; Glas tragen nur die Vorschlagsliste
 * der Artikelsuche und das Ablehnfeld - beides schwebt.
 *
 * DIE BREITE (A.10): an 1280 x 800 stehen Original und Positionen
 * NEBENEINANDER. Dafuer klappt die Leiste auf dieser Seite schon unter
 * 1440 px zur Zeichenspalte (grund.html, `schmal_ab`; leiste-schmal.css).
 * Die Zahlen unten sind am Vorfuehrstand gemessen - wer am Aufbau
 * aendert, misst neu (Regel 33).
 * ================================================================= */

.inhalt-freigabe {
  max-width: 1680px;
  padding-bottom: var(--a5);
}

/* KARTEN UEBER DEM RASTER (Hinweise aus dem ERP, Zuordnung, nicht
 * gebucht) halten Abstand zum Raster darunter. Vorher klebte die
 * Statuskarte am Original und an den Positionen (Bildschirmfoto vom
 * 05.10.2026): `.karte + .karte` greift nur zwischen zwei Karten, das
 * Raster ist keine. Zwischen zwei Karten fallen die Abstaende zusammen. */
.inhalt-freigabe > .karte {
  margin-bottom: var(--a4);
}

/* --- Kopf ----------------------------------------------------------- */

/* DER KOPF DES MOCKUPS, OHNE DIE VORLAGE UMZUBAUEN: oben der Pfad
 * zurueck in die Ansicht, darunter der Kunde gross mit dem Punkt, darunter
 * die Merkmale. Rechts, unten buendig, die Stelle und die runden
 * Blaetterknoepfe. Die Reihenfolge im Markup (und damit fuer Screenreader
 * und Tastatur) bleibt: zurueck, Kunde, Merkmale, Stelle, Blaettern.
 * Trenner und Luecke braucht das Raster nicht. */
.freigabekopf {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-areas:
    "zurueck zurueck stelle blaettern"
    "titel titel stelle blaettern"
    "stand angaben stelle blaettern";
  align-items: end;
  gap: 8px 12px;
  margin-bottom: var(--a4);
}

.kopf-zurueck {
  grid-area: zurueck;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 10px 0 4px;
  margin-left: -4px;
  border-radius: var(--radius-pille);
  color: var(--text-leise);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus);
}

.kopf-zurueck:hover {
  background: var(--flaeche-zart);
  color: var(--text);
}

.kopf-trenner,
.kopf-luecke {
  display: none;
}

.freigabekopf h1 {
  grid-area: titel;
  min-width: 0;
}

.freigabekopf .standfeld {
  grid-area: stand;
}

.kopf-stelle {
  grid-area: stelle;
  align-self: end;
  padding-bottom: 13px;
  font-size: 13px;
  color: var(--text-leise);
  white-space: nowrap;
}

.kopf-blaettern {
  grid-area: blaettern;
  align-self: end;
  display: flex;
  gap: 8px;
}

/* DIE RUNDEN GLASKNOEPFE DES MOCKUPS (44 px): sie schweben ueber dem
 * Grund wie die Leiste, auf ihnen steht nur ein Pfeil. */
.blaetterknopf {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-pille);
  background: var(--huelle);
  color: var(--text-zweit);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    border-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

a.blaetterknopf:hover {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  transform: translateY(-1px);
}

.blaetterknopf-aus {
  color: var(--text-leise);
  opacity: 0.55;
}

/* Auf dem Telefon: Pfad, Stelle und Knoepfe in der ersten Zeile, der
 * Kunde darunter ueber die volle Breite. */
@media (max-width: 40em) {
  .freigabekopf {
    grid-template-areas:
      "zurueck zurueck stelle blaettern"
      "titel titel titel titel"
      "stand stand stand stand"
      "angaben angaben angaben angaben";
    align-items: center;
  }

  .kopf-stelle {
    align-self: center;
    padding-bottom: 0;
  }

  .kopf-blaettern {
    align-self: center;
  }

  .blaetterknopf {
    width: 40px;
    height: 40px;
  }
}

/* DIE ANGABEN ZUR NACHRICHT (Rueckmeldung 26.10.2026): statt einer Metazeile
 * unter dem Kunden ein kleiner Knopf neben den Merkmalen, der eine Tafel
 * aufklappt. Die Tafel schwebt ueber dem Inhalt - DECKEND und nicht Glas:
 * in ihr stehen Betreff und Absender, also Text des Kunden. Erhebung wie
 * jedes Schwebende: auf Weiss Schatten, auf Dunkel die hellere Kante. */
/* Absender und Knopf in einer Zeile neben den Merkmalen; schmal bricht der
 * Absender um, der Knopf bleibt ganz. */
.kopfzusatz {
  grid-area: angaben;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  min-width: 0;
}

.kopf-absender {
  min-width: 0;
  font-size: 13px;
  color: var(--text-leise);
  overflow-wrap: anywhere;
}

.kopf-absender-wert {
  color: var(--text-zweit);
  font-weight: 500;
}

.kopfangaben {
  flex: none;
}

/* DIE KLAPPTAFEL: ein `details`, dessen Knopf eine Pille ist und dessen
 * Inhalt ueber der Seite schwebt (Angaben im Kopf, ERP-Pruefungen). Ohne
 * Skript schliesst sie nur der Knopf; mit Skript auch Esc und ein Klick
 * daneben (tastatur.js, freigabe.js). */
.klapptafel {
  position: relative;
}

.klapptafel > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  padding: 0 10px 0 8px;
  border: 1px solid var(--linie);
  border-radius: var(--radius-pille);
  background: var(--flaeche);
  color: var(--text-zweit);
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  list-style: none;
  cursor: pointer;
  transition:
    border-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus);
}

.klapptafel > summary::-webkit-details-marker {
  display: none;
}

.klapptafel > summary:hover,
.klapptafel[open] > summary {
  border-color: var(--linie-stark);
  color: var(--text);
}

.klapptafel-inhalt {
  position: absolute;
  z-index: 40;
  top: calc(100% + 8px);
  left: 0;
  width: max-content;
  max-width: min(34rem, calc(100vw - 2 * var(--rand)));
  padding: var(--a4) var(--a5);
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-gross);
  background: var(--huelle-deckend);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    var(--huelle-schatten),
    var(--huelle-schatten-hoch);
}

.kopfangaben-liste {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 8px 18px;
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
}

.kopfangaben-liste dt {
  color: var(--text-zweit);
}

.kopfangaben-liste dd {
  min-width: 0;
  margin: 0;
  color: var(--text);
  overflow-wrap: anywhere;
}

.kopfangaben-herkunft {
  display: inline-flex;
  align-items: center;
  gap: var(--a1);
}

.kopfangaben-kennung {
  font-size: 11.5px;
  color: var(--text-zweit);
}

@media (prefers-reduced-motion: reduce) {
  .klapptafel > summary {
    transition: none;
  }
}

/* --- Das Raster ------------------------------------------------------
 *
 * ZWEI SPALTEN, und das Original weicht zuerst: sein Text bricht um
 * (`pre-wrap`), die Tabelle nicht. Das Formular ist im Raster unsichtbar
 * (`display: contents`), damit Positionen, Pruefungen und Leiste im
 * selben Raster stehen wie das Original, das nicht im Formular liegt.
 *
 * DIE POSITIONSSPALTE HAT EIN MINDESTMASS, das Original nicht so sehr:
 * GEMESSEN am 24.09.2026 (Vorfuehrstand, Chromium, 1280 x 800): die
 * breiteste Positionstabelle braucht 651 px min-content. 680 px mit Luft.
 * Darunter scrollte die Tabelle waagerecht, und rechts steht der Preis.
 *
 * UNTEREINANDER UNTER 1120 PX FENSTERBREITE: 300 px Original, 20 px
 * Abstand, 680 px Positionen, 56 px Rand und 64 px Zeichenspalte. */
.freigabe {
  display: grid;
  grid-template-columns: minmax(300px, 380px) minmax(680px, 1fr);
  gap: var(--a4) 20px;
  align-items: start;
}

/* DIE SPALTE DES ORIGINALS IST SO HOCH WIE DIE POSITIONEN, die Karte darin nur so hoch, wie sie
 * braucht (Beta-Rueckmeldung 07.10.2026: "die linke Spalte ist einfach zu lang"; bis dahin, seit
 * 05.10., wuchs die Karte selbst mit). In der Spalte laeuft die Karte mit - bis zu ihrem Ende. */
.freigabe > .originalspalte,
.freigabeformular > .karte.positionen {
  align-self: stretch;
}

.karte.original {
  display: flex;
  flex-direction: column;
}

.karte.original > .legende {
  margin-top: auto;
}

.freigabeformular {
  display: contents;
}

.freigabe > .karte + .karte,
.freigabeformular > .karte + .karte {
  margin-top: 0;
}

.freigabe-unten,
.entscheidungsleiste {
  grid-column: 1 / -1;
}

@media (max-width: 1119px) {
  .freigabe {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* DIE KARTE LAEUFT MIT, SO HOCH WIE IHR INHALT (Beta-Rueckmeldung 07.10.2026, dritte Fassung).
 * Erst klebte die Karte und scrollte fuer sich (Scrollleiste, kein Abstand zur Leiste), dann war
 * sie so hoch wie die Positionen und nur das Blatt lief in ihr mit ("die Spalte ist einfach zu
 * lang"). Jetzt ist sie nur so hoch, wie sie braucht, klebt als Ganzes am Fenster und bleibt am
 * Ende ihrer Spalte (so hoch wie die Positionen) stehen - so sieht man sie mitlaufen. Damit sie
 * ganz zu sehen ist, ist die Seite hoechstens so hoch wie das Fenster abzueglich dessen, was die
 * Karte ausser der Seite braucht (`--karte-rahmen`, im Browser gemessen von freigabe.js). Seit
 * 27.10.2026 klebt die Entscheidungsleiste nicht mehr unten am Fenster - fuer sie bleibt kein
 * Platz mehr frei. Ist der Text aufgeklappt, ist die Karte hoeher als das Fenster: dann laeuft sie
 * nicht mit, und die Seite scrollt wie jede. */
@media (min-width: 1120px) {
  .originalspalte > .karte.original {
    position: sticky;
    top: var(--rand);
  }

  .originalspalte > .karte.original:has(.textklappe[open]) {
    position: static;
  }

  .originalspalte > .karte.original .seitenbuehne {
    width: fit-content;
    max-width: 100%;
    margin-inline: auto;
  }

  .originalspalte > .karte.original .originalseite img {
    width: auto;
    max-width: 100%;
    max-height: calc(100dvh - 2 * var(--rand) - var(--karte-rahmen));
  }
}

/* Solange das Bild laedt, hat die Buehne die Breite der Spalte - sonst schrumpfte sie auf den Satz
 * "Seite wird geladen" (im Browser gesehen: ein schmaler Streifen). Wie jede Regel zum Ladezustand
 * nur mit Skript (tests/test_ladeflaeche.py). */
@media (scripting: enabled) and (min-width: 1120px) {
  .originalspalte > .karte.original .seitenbuehne[data-bild="laedt"] {
    width: 100%;
  }
}

/* Angedockt ist die Seite einspaltig (KI-Fenster rechts): dort klebt nichts - die Karte laege
 * sonst ueber den Positionen. */
.chat-schwebt[data-chatfenster="geteilt"] .originalspalte > .karte.original {
  position: static;
}

.chat-schwebt[data-chatfenster="geteilt"] .originalspalte > .karte.original .originalseite img {
  max-height: none;
}

.karte.original,
.karte.positionen {
  padding: 0;
}

/* DER KOPF EINES BLATTS (Mockup): 16 px oben und unten, 20 px seitlich,
 * der Titel 16 px fett, darunter die Haarlinie. */
.blattkopf {
  display: flex;
  align-items: center;
  gap: var(--a3);
  padding: 16px 20px;
  border-bottom: 1px solid var(--linie);
}

.blattkopf h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
}

/* --- Das Original: Reiter und Zeilen --------------------------------- */

/* DER EINZUG KOMMT HIER HER, weil die Karte keine Polsterung hat. Mit
 * zwei Klassen, damit er gegen `.leiser-hinweis` gewinnt, egal wo die im
 * Stilblatt steht - vorher klebte der Satz mit der Bueroklammer am Rand,
 * weil die spaetere Regel mit gleichem Gewicht den Rand auf 0 setzte. */
.original > .original-satz {
  margin: var(--a3) var(--a4) 0;
}

/* --- Der leise Hinweis (Ruhige Oberflaeche, B.1) ----------------------
 * Was sichtbar bleiben muss, aber keinen Kasten braucht: Symbol und Satz,
 * an der Stelle, zu der er gehoert. Die Schrift in der zweiten Stufe, damit
 * er sich lesen laesst; das Symbol leiser. */
.leiser-hinweis {
  margin: 0 0 var(--a3);
  font-size: 13px;
  color: var(--text-zweit);
}

.leiser-hinweis-zeichen {
  color: var(--text-leise);
}

/* --- Symbol und Satz in einer Zeile: EINE Gestalt ----------------------
 * Leiser Hinweis, Hinweis an der Position, Rueckfrage: vorn das Symbol,
 * dahinter EIN Textkasten. Abstand zwischen beiden und Ausrichtung stehen
 * NUR hier; die Bauteile setzen Schrift und Farbe. Der Symbolkasten ist
 * so hoch wie die erste Zeile (`1.45em` zur `line-height: 1.45`) und
 * mittet das Symbol darin - so steht es bei jeder Schriftgroesse auf der
 * ersten Zeile, auch wenn der Satz umbricht. Den Abstand zum RAND gibt
 * der Behaelter, nicht die Zeile. Gehalten von `test_freigabe_ruhe.py`. */
.symbolzeile {
  display: flex;
  align-items: flex-start;
  gap: var(--a2);
  line-height: 1.45;
}

.symbolzeile-zeichen {
  display: inline-flex;
  flex: none;
  align-items: center;
  height: 1.45em;
}

.kopfhinweis {
  margin-top: calc(-1 * var(--a2));
}

/* JEDER KNOPF STEHT VOR SEINEM BLATT; die Beschriftungen reihen sich
 * oben auf (Reihenfolge 0), die Blaetter darunter (Reihenfolge 1, volle
 * Breite). Sichtbar ist das Blatt hinter dem gewaehlten Knopf. Ohne
 * Skript, ohne Neuladen. */
.reiter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  padding: var(--a3) var(--a4) 0;
}

.reiterknopf {
  display: inline-flex;
  align-items: center;
  gap: var(--a1);
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  color: var(--text-leise);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.reiterwahl:checked + .reiterknopf {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-weight: 600;
}

.reiterwahl:focus-visible + .reiterknopf {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
}

.reiter-zahl {
  font-weight: 600;
}

.reiterblatt {
  display: none;
  order: 1;
  flex: 0 0 calc(100% + 2 * var(--a4));
  margin: 0 calc(-1 * var(--a4));
  padding-top: var(--a2);
}

.reiterwahl:checked + .reiterknopf + .reiterblatt {
  display: block;
}

/* Ohne Skript: ein Sprung auf eine Zeile in einem anderen Blatt zeigt
 * dieses Blatt mit (wo `:has` gezeichnet wird). Mit Skript waehlt
 * freigabe.js den Reiter vorher. */
.reiterblatt:has(:target) {
  display: block;
}

.reiter-grund {
  margin: 0 var(--a4) var(--a2);
}

.quelltext {
  list-style: none;
  margin: 0;
  padding: var(--a2) 0;
  font-size: 13.5px;
}

/* DAS SPRUNGZIEL darf nicht unter der Kante landen: etwas Luft oben. */
/* DIE MARKEN IN EINER FESTEN SPALTE, rechtsbuendig: "Pos. 1" steht in
 * jeder Zeile an derselben Stelle und nicht dort, wo der Text zufaellig
 * aufhoert. Zwei Marken brechen in der Spalte um. */
.quellzeile {
  scroll-margin-top: var(--a6);
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 4.5rem;
  gap: var(--a2);
  align-items: baseline;
  padding: 3px 14px 3px 0;
}

.zeilennummer {
  color: var(--text-leise);
  text-align: right;
  font-size: 11.5px;
}

/* Der Bestelltext in der Schrift der Seite, mit erhaltenen Leerzeichen.
 * FESTBREITE NUR FUER TEXT AUS DER TEXTERKENNUNG (`.quelltext-fest`):
 * dort zaehlt jedes Zeichen einzeln (1 gegen l, 0 gegen O). Der Preis:
 * Spalten, die ein Kunde mit Leerzeichen ausgerichtet hat, stehen in der
 * Seitenschrift nicht mehr genau untereinander. */
.zeileninhalt {
  white-space: pre-wrap;
  word-break: break-word;
}

.quelltext-fest .zeileninhalt {
  font-family: var(--schrift-fest);
  font-size: 12.5px;
}

/* GRAU: aus dieser Zeile wurde keine Position. Die Legende sagt es in
 * Worten, und jede Zeile traegt es fuer Screenreader. */
.quellzeile.ohne-position .zeileninhalt {
  color: var(--text-leise);
}

.zeilenmarken {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--a1);
}

/* DER GANZE TEXT, aufklappbar ohne Skript. Ein leiser Verweis und kein
 * Knopf: er aendert nichts, er zeigt nur mehr. Die Zahl der nicht
 * uebernommenen Zeilen steht auf ihm. */
.ganzer-text {
  border-top: 1px solid var(--linie);
}

.ganzer-text > summary {
  padding: var(--a2) var(--a4);
  font-size: 12.5px;
  color: var(--akzent-text);
  cursor: pointer;
}

.ganzer-text[open] > summary {
  border-bottom: 1px solid var(--linie);
}

.zeilenmarke {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-size: 11px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.zeilenmarke-frage {
  background: var(--frage-flaeche);
  color: var(--frage);
}

/* ZEIGT JEMAND AUF EINE POSITION, leuchten ihre Zeilen - und umgekehrt
 * (freigabe.js). Eine ruhige Flaeche, der Text bleibt, wie er ist. */
.quellzeile.leuchtet,
.quellzeile:target {
  background: var(--zeile-markiert);
}

.quellzeile:target .zeileninhalt {
  font-weight: 600;
}

.legende {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin: 0;
  padding: var(--a2) var(--a4) var(--a3);
  border-top: 1px solid var(--linie);
  font-size: 12px;
  color: var(--text-leise);
}

.legende-muster {
  font-family: var(--schrift-fest);
  color: var(--text-leise);
}

/* --- Die Positionen --------------------------------------------------- */

.positionstabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

.positionstabelle col.spalte-lfd {
  width: 44px;
}

.positionstabelle col.spalte-menge {
  width: 128px;
}

.positionstabelle col.spalte-preis,
.positionstabelle col.spalte-summe {
  width: 92px;
}

.positionstabelle col.spalte-herkunft {
  width: 64px;
}

.positionstabelle col.spalte-weg {
  width: 96px;
}

.positionstabelle thead th {
  padding: 9px var(--a2);
  background: var(--flaeche-kopf);
  border-bottom: 1px solid var(--linie);
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-leise);
}

.positionstabelle thead th:first-child {
  padding-left: var(--a4);
}

.positionstabelle th.rechts {
  text-align: right;
}

.positionstabelle td {
  padding: 10px var(--a2) 6px;
  vertical-align: top;
}

.positionszeile > td {
  border-top: 1px solid var(--linie-zart);
}

.positionstabelle tbody .positionszeile:first-child > td {
  border-top: none;
}

.positionszeile > td.lfd {
  padding-left: var(--a4);
  color: var(--text-leise);
}

.positionszeile.leuchtet > td,
.fragenzeile.leuchtet > td,
.hinweiszeile.leuchtet > td,
.positionszeile:target > td {
  background: var(--zeile-markiert);
}

.artikelzelle .bezeichnung {
  display: block;
  margin-top: var(--a1);
  font-weight: 500;
  overflow-wrap: anywhere;
}

.positionstabelle .artikelfeld {
  width: 9.5rem;
  min-height: 32px;
  padding: var(--a1) var(--a2);
  font-size: 13px;
}

.mengenzelle {
  white-space: nowrap;
}

.positionstabelle .mengenfeld {
  width: 5rem;
  min-height: 32px;
  padding: var(--a1) var(--a2);
}

.einheit {
  margin-left: var(--a1);
  font-size: 13px;
  color: var(--text-zweit);
}

.summenzelle {
  font-weight: 600;
}

.herkunftsverweis {
  color: var(--akzent-text);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* ENTFERNEN: ein kleiner beschrifteter Knopf, der ein Haken ist. Ohne
 * Skript, ohne Neuladen; die Zeile streicht sich durch, wo `:has`
 * gezeichnet wird - und der Haken selbst bleibt sichtbar gesetzt. */
.entfernen {
  display: inline-flex;
  align-items: center;
  gap: var(--a1);
  padding: 2px var(--a2);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  font-size: 12px;
  color: var(--text-zweit);
  cursor: pointer;
  white-space: nowrap;
}

.entfernen:has(:checked) {
  border-color: var(--grenze-kante);
  background: var(--grenze-flaeche);
  color: var(--grenze);
}

.positionszeile:has(.entfernen :checked) > td:not(.wegzelle) {
  text-decoration: line-through;
  color: var(--text-leise);
}

.unzugeordnet .nicht-zugeordnet {
  display: block;
  color: var(--frage);
  font-size: 12px;
  font-weight: 600;
}

.fragenzeile > td,
.hinweiszeile > td,
.meldungszeile > td {
  padding: 0 var(--a4) var(--a3);
}

.meldungszeile .meldung,
.hinzufuegen-meldung {
  margin: 0;
}

.hinzufuegen-meldung {
  margin: var(--a3) var(--a4) 0;
}

/* --- Rueckfragen und Hinweise unter ihrer Position --------------------- */

/* OHNE GELBE FLAECHE (Ruhige Oberflaeche, B.3): eine linke Randlinie in
 * der Farbe der Frage und das Symbol tragen sie. Die Flaeche bleibt die der
 * Tabelle - die Frage steht auf den Daten, und Daten stehen auf ruhiger,
 * deckender Flaeche. */
.positionsfrage {
  padding: 6px var(--a3) 8px;
  border-left: 3px solid var(--frage);
  font-size: 13px;
}

.positionsfrage + .positionsfrage {
  margin-top: var(--a2);
}

.frage-satz {
  margin: 0 0 var(--a2);
  color: var(--text);
}

/* Was das Modell sagt (Fix-Runde GP2, Pakete 1 und 4): leise, eingerueckt,
   nie im Meldungsbauteil und nie als Erfolg. Nur Bedeutungsnamen. */
.modellhinweis {
  margin: 0 0 var(--a2);
  padding-left: var(--a2);
  border-left: 1px solid var(--linie);
  color: var(--text-leise);
  font-size: 13px;
  overflow-wrap: anywhere;
}

/* DIE LUPE (Nachtlauf Teil F): die Zeile einer Rueckfrage aus dem Original,
 * auf die Spaltenbreite vergroessert. RUHIG: keine Farbe, eine Haarlinie -
 * sie zeigt, sie mahnt nicht. Der Ausschnitt selbst ist ein `viewBox` (SVG-
 * Attribut), hier steht nur die Flaeche. Das Papier bleibt Papier, auch im
 * dunklen Thema: es ist das Original. */
.lupe {
  margin: 0 0 var(--a2);
  max-width: 44rem;
}

.lupe-bild {
  display: block;
  width: 100%;
  height: auto;
  max-height: 8rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  background: var(--flaeche);
}

.lupe figcaption {
  margin-top: 2px;
  font-size: 12px;
}

.modellhinweis-marke {
  font-style: italic;
}

.frage-marke {
  font-weight: 700;
  color: var(--frage);
}

.frage-zeichen {
  color: var(--frage);
}

/* --- Die Frage zum Einklappen (Beta-Rueckmeldung 06.10.2026) ------------
 *
 * Jede Frage ist ein `details`: der Satz ist die Zeile, die man auf- und
 * zuklappt. Eine SPERRE steht offen da und behaelt die Farbe der Frage -
 * dort muss jemand handeln. Ein HINWEIS steht eingeklappt und neutral,
 * mit Haarlinie statt Farbe ("Farbe nur, wo jemand handeln muss"); ein
 * verworfener ist noch leiser und bleibt stehen. Das Zeichen am Ende der
 * Zeile zeigt, dass sie sich oeffnen laesst. */
.frageklappe > summary {
  list-style: none;
  cursor: pointer;
}

.frageklappe > summary::-webkit-details-marker {
  display: none;
}

.frageklappe > summary::after {
  content: "▸";
  margin-left: auto;
  padding-left: var(--a2);
  color: var(--text-leise);
}

.frageklappe[open] > summary::after {
  content: "▾";
}

.frageklappe:not([open]) > .frage-satz {
  margin-bottom: 0;
}

.positionsfrage:has(> .frageklappe.hinweis) {
  border-left-color: var(--linie-stark);
}

.frageklappe.hinweis .frage-marke,
.frageklappe.hinweis .frage-zeichen {
  color: var(--text-leise);
}

.frageklappe.verworfen > summary {
  color: var(--text-leise);
}

.frage-verworfen {
  font-size: 12px;
  white-space: nowrap;
}

.frage-vorsatz {
  margin: 0 0 var(--a2);
  font-size: 12px;
}

.frage-aktion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2);
  margin: var(--a2) 0 0;
  font-size: 12px;
}

.frage-verwerfen-knopf,
.frage-erledigt-knopf {
  white-space: nowrap;
}

/* ERLEDIGT (Beta-Rueckmeldung 07.10.2026): eine geklaerte Sperre - hier muss niemand mehr
 * handeln, also ohne Farbe und eingeklappt. */
.frageklappe.erledigt > summary,
.frageklappe.erledigt .frage-marke,
.frageklappe.erledigt .frage-zeichen {
  color: var(--text-leise);
}

/* GEKLAERT ALS KURZE ZEILE (Rueckmeldung 27.10.2026, "clean"): Haken, Wort, wer, wann - ohne
 * Randlinie und ohne eigenen Kasten, damit die Position darueber wie jede andere aussieht. Die
 * Frage selbst steht erst aufgeklappt da, in der Zweitfarbe. */
.positionsfrage:has(> .frageklappe.erledigt) {
  padding-block: 0 4px;
  border-left-color: transparent;
}

.frage-geklaert {
  font-size: 12.5px;
}

.frageklappe.erledigt .frage-marke {
  font-weight: 600;
}

.frage-geklaert-frage {
  margin: 4px 0 var(--a2);
  color: var(--text-zweit);
}

/* „KEINE POSITION“ hat keine Zeile mehr darueber (die ist verborgen): ihre kurze Zeile steht mit
 * eigener Haarlinie da, sonst saehe sie aus wie ein Teil der Position davor. */
.fragenzeile:has(.frageklappe.keine-position) > td {
  padding-top: var(--a2);
  border-top: 1px solid var(--linie);
}

/* DIE HINWEISGRUPPE: eingeklappt, mit Zahl im Kopf - niemand soll denken,
 * es gaebe nichts. Deckend auf der Karte, eine Haarlinie darueber. */
.hinweisgruppe > summary {
  list-style: none;
  cursor: pointer;
}

.hinweisgruppe > summary::-webkit-details-marker {
  display: none;
}

.hinweisgruppe-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--a2);
  font-size: 13px;
}

.hinweisgruppe-kopf::after {
  content: "▸";
  margin-left: auto;
  color: var(--text-leise);
}

.hinweisgruppe[open] > .hinweisgruppe-kopf::after {
  content: "▾";
}

.hinweisgruppe-titel {
  font-size: 14px;
  font-weight: 700;
}

.hinweisgruppe[open] > .hinweisgruppe-kopf {
  margin-bottom: var(--a2);
}

/* ZWISCHENSTAND SPEICHERN in der Entscheidungsleiste, mit Namen und Zeit
 * daneben (Beta-Rueckmeldung 06.10.2026). Flach: gefuellt bleibt nur
 * "Freigeben". */
.zwischenstand-zeile {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2);
}

.zwischenstand-satz {
  font-size: 12px;
}

/* DER SATZ OBEN: was in diesem Vorgang los ist. Kein Bauteil und keine
 * Farbe - eine Zeile Text unter dem Kopf, gross genug, um sie zuerst zu
 * lesen. */
.lagesatz {
  margin: 0 0 var(--a4);
  max-width: 60rem;
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.45;
}

.antwortknoepfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  margin-bottom: var(--a2);
}

.knopf-klein {
  min-height: 30px;
  padding: var(--a1) var(--a3);
  font-size: 13px;
}

.antwortknopf {
  border-color: var(--frage-kante);
  background: var(--flaeche);
  color: var(--text);
}

.antwortknopf:hover {
  background: var(--flaeche-erhoben);
}

.antwortknopf[aria-pressed="true"] {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.antwortknopf-bezeichnung {
  color: var(--text-zweit);
  font-weight: 400;
}

/* Der Unterschied eines Kandidaten (Nachtlauf Teil C): kraeftig, vor der
   Bezeichnung - er ist das, wonach der Sachbearbeiter waehlt. */
.antwortknopf-merkmal {
  font-weight: 600;
}

/* Der Vorschlag zu einer Zuordnung (Rueckfragen-Auftrag, A2): warum der Kandidat vorn steht - ein
   leiser Satz ueber den Knoepfen, dann je Kandidat eine Zeile darunter. Nur Bedeutungsnamen; die
   Farbe bleibt bei Text und Text-zweit, nichts wird gefaerbt (Ruhige Oberflaeche). */
.vorschlag-grund {
  margin: 0 0 var(--a2);
  color: var(--text-zweit);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.vorschlag-marke {
  font-weight: 600;
  color: var(--text);
}

.begruendungen {
  margin: 0 0 var(--a2);
  padding: 0;
  list-style: none;
  color: var(--text-leise);
  font-size: 12px;
}

.begruendung {
  margin: 0;
  overflow-wrap: anywhere;
}

.antwortfelder {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--a2) var(--a3);
}

.antwortfelder .feld,
.ergaenzungszeile .feld {
  margin-bottom: 0;
  min-width: 0;
}

.feld-antwort {
  flex: 1 1 16rem;
}

.feld-artikel {
  flex: 1 1 14rem;
}

.feld-menge {
  flex: 0 0 7rem;
}

.positionsfrage .textfeld,
.positionsfrage .zahlenfeld {
  min-height: 32px;
  background: var(--flaeche);
  font-size: 13px;
}

/* EINE ZEILE, GRAU, MIT SYMBOL (B.2) - keine Flaeche. Nur "Preis weicht
 * ab" und "Bestand knapp" faerben Symbol und Wort (`HINWEIS_FARBIG`). */
.positionshinweis {
  padding: 2px 0;
  font-size: 12.5px;
  color: var(--text-leise);
}

.positionshinweis p {
  margin: 0;
}

.hinweis-marke {
  font-weight: 600;
  color: var(--text-zweit);
}

.positionshinweis-farbig .hinweis-zeichen,
.positionshinweis-farbig .hinweis-marke {
  color: var(--hinweis);
}

/* MEHRZEILIGER HINWEIS (Briefkopf, Fax-Runde 27.09.2026): der Satz als
 * summary in derselben Zeile wie ein einzeiliger Hinweis, die Zeilen
 * darunter eingerueckt auf die Hoehe des Textes, ohne Kasten. */
.hinweis-zeilen > summary {
  cursor: pointer;
}

.hinweis-zeilenliste {
  margin: var(--a1) 0 0;
  padding: 0 0 0 calc(14px + var(--a2));
  list-style: none;
}

/* --- Position hinzufuegen, Fragen zum Vorgang ------------------------ */

.hinzufuegen {
  padding: var(--a3) var(--a4);
  border-top: 1px solid var(--linie);
}

.hinzufuegen > summary {
  list-style: none;
}

.hinzufuegen > summary::-webkit-details-marker {
  display: none;
}

.knopf-gestrichelt {
  min-height: 32px;
  padding: 0 10px;
  border: 1px dashed var(--linie-stark);
  color: var(--akzent-text);
  font-size: 13px;
  font-weight: 600;
}

.hinzufuegen[open] > summary {
  margin-bottom: var(--a3);
}

.ergaenzungszeile {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--a3);
}

.vorgangsfragen {
  padding: var(--a3) var(--a4);
  border-top: 1px solid var(--linie);
}

.vorgangsfragen h3 {
  margin: 0 0 var(--a2);
  font-size: 14px;
}

.vorgangsfragen .positionshinweis + .positionshinweis {
  margin-top: var(--a2);
}

/* --- Die Artikelsuche: die Vorschlagsliste SCHWEBT, deckend ----------
 *
 * Sie legt sich ueber die Tabelle, statt sie beim ersten Vorschlag um ihre
 * Hoehe zu verschieben. SEIT DER BETA-RUECKMELDUNG (06.10.2026) DECKEND und
 * nicht mehr Glas (Punkt 201.3): auf ihr stehen Artikelnummer und Bestand,
 * und durch 60 % Deckkraft schien die Rueckfrage darunter durch. Erhebung
 * auf Weiss: Schatten. */
.artikelsuche {
  position: relative;
}

.vorschlagsrahmen {
  position: absolute;
  top: calc(100% + var(--a1));
  left: 0;
  z-index: 30;
  width: max-content;
  min-width: 100%;
  max-width: 30rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--huelle-schatten-hoch);
}

/* EINE OFFENE LISTE LIEGT UEBER DER NAECHSTEN ZEILE. Der Inhalt jeder
 * Zeile ueber die ganze Breite klebt (`position: sticky`, unten) und ist
 * damit eine eigene Stapelebene: die spaetere Rueckfrage malte ueber die
 * Liste der frueheren, ab dem dritten Vorschlag (Beta-Rueckmeldung,
 * Bild 1). Hoeher als die Liste, unter dem schwebenden Chatknopf (40). */
.artikelsuche:has(.vorschlagsrahmen:not(:empty)) {
  z-index: 35;
}

.vorschlagsrahmen:empty {
  display: none;
}

.vorschlagsrahmen > .leise {
  margin: 0;
  padding: var(--a2) var(--a3);
}

.artikelvorschlaege {
  list-style: none;
  margin: 0;
  padding: var(--a1) 0;
  max-height: 16rem;
  overflow-y: auto;
}

.artikelvorschlaege li + li {
  border-top: 1px solid var(--linie-zart);
}

.vorschlag {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--a3);
  align-items: baseline;
  width: 100%;
  text-align: left;
  border: 0;
  background: none;
  padding: var(--a2) var(--a3);
  font: inherit;
  font-size: 13px;
  color: inherit;
  cursor: pointer;
}

.vorschlag:hover,
.vorschlag:focus-visible {
  background: var(--akzent-flaeche);
}

.vorschlag-bezeichnung {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --- Unter dem Raster: Grenzuebergang, Pruefungen, Spur --------------- */

.freigabe-unten {
  display: grid;
  gap: var(--a3);
}

.freigabe-unten > .karte + .karte {
  margin-top: 0;
}

/* Die Pruefungen sind eine Tabelle mit Wert und Grenze je Zeile; auf dem
 * Telefon scrollt sie IN ihrer Karte und nicht die ganze Seite. Hier
 * schwebt nichts, was der Rand abschneiden koennte. */
@media (max-width: 40em) {
  .freigabe-unten > .karte {
    overflow-x: auto;
  }
}

/* DIE AUFKLAPPER DES MOCKUPS: 60 px hoch, der Titel links, rechts ein
 * Pfeil, der sich beim Oeffnen dreht. Das Aufklappzeichen des Browsers
 * ersetzt der Pfeil - ohne ihn saehe niemand, dass hier etwas aufgeht. */
.aufklapper {
  padding: 0 20px;
}

.aufklapper > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 60px;
  cursor: pointer;
  list-style: none;
}

.aufklapper > summary::-webkit-details-marker {
  display: none;
}

.aufklapper > summary::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 6px 0 auto;
  border-right: 1.8px solid var(--text-leise);
  border-bottom: 1.8px solid var(--text-leise);
  rotate: 45deg;
  transition: rotate var(--zeit-kurz) var(--kurve-aus);
}

.aufklapper[open] > summary::after {
  rotate: 225deg;
}

.aufklapper > summary h2 {
  margin: 0;
  font-size: 16px;
}

.aufklapper[open] {
  padding-bottom: 20px;
}

.aufklapper[open] > summary {
  margin-bottom: 4px;
}

.grenzuebergang {
  padding: 16px 20px;
  border-color: var(--grenze-kante);
  font-size: 14px;
}

.grenzuebergang summary {
  cursor: pointer;
  color: var(--grenze);
  font-weight: 600;
}

/* DECKEND UND NICHT AUS GLAS: hier stehen der gemessene Wert und seine
 * Grenze, also Daten. */
.grenzliste {
  margin: var(--a3) 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--a2);
}

.grenzliste li {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  align-items: baseline;
}

.entscheidungsspur {
  margin: 0;
  padding-left: var(--a5);
  font-size: 14px;
}

.entscheidungsspur > li + li {
  margin-top: var(--a3);
}

/* --- Die Entscheidungsleiste: am Ende der Seite, unter der Zeitleiste ----
 *
 * DIE LEISTE DES MOCKUPS: 24 px Radius, links die Summe gross in der breiten
 * Fassung, darunter die Pruefmerkmale, rechts die Knoepfe als Pillen.
 * DECKEND, NICHT GLAS: sie traegt die Summe, also Daten.
 *
 * SIE KLEBT NICHT MEHR (Rueckmeldung 27.10.2026, abends: "der Schatten sieht verbuggt aus" und
 * "der Container soll nicht mitscrollen, einfach unten, direkt unter der Zeitleiste"). Vorher
 * klebte sie unten am Fenster, zuerst weiss auf weissen Karten (sah aus wie ein Fehler), dann in
 * einem Bett aus Seitengrund mit Verlauf darueber. Jetzt ist sie eine Karte am Ende der Seite:
 * dieselbe Erhebung wie jede Karte, auf Dunkel die Kante (`--linie-stark`). Wer freigibt, hat
 * Positionen, Pruefungen und Zeitleiste davor gelesen. */
.entscheidungsleiste {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  padding: 14px 14px 14px 24px;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-karte);
  background: var(--flaeche);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    var(--karte-schatten);
}

/* PLATZ FUER DEN SCHWEBENDEN CHAT-KNOPF: er steht unten rechts am Fenster (24 px Abstand, 48 px
 * hoch); ganz unten angekommen laege er sonst auf „Freigeben“. Mit dem Abstand der Seite (48 px)
 * steht die Leiste dann 88 px ueber dem Rand - ueber dem Knopf. */
.chat-schwebt .entscheidungsleiste {
  margin-bottom: 40px;
}

.entscheid-summe {
  display: flex;
  flex: 1 1 22rem;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  min-width: 0;
}

.summenzahl {
  font-size: 26px;
  font-weight: 700;
  font-stretch: var(--schrift-breite-titel);
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.summenzusatz {
  font-size: 13px;
  font-weight: 400;
}

.pruefmerkmale {
  display: flex;
  flex: 1 1 100%;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 2px 0 0;
  padding: 0;
  list-style: none;
  font-size: 12.5px;
  color: var(--text-leise);
}

.pruefmerkmal {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.pruef-gehalten .zeichen {
  color: var(--bereit);
}

.pruef-gerissen {
  color: var(--grenze);
  font-weight: 600;
}

.pruef-vermerkt {
  color: var(--hinweis);
}

.pruef-offen {
  color: var(--frage);
}

.entscheid-knoepfe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--a2);
}

.entscheid-knoepfe .meldung {
  margin: 0;
}

/* EIN MASS FUER JEDEN KNOPF DER LEISTE: Ablehnen, Ablegen und Freigeben
 * gleich hoch, gleiche Schrift, gleiches Innenmass. Welcher Knopf zaehlt,
 * sagt die Fuellung (`knopf-haupt` gegen `knopf-zweit`), nicht die Groesse
 * - ein kleinerer Ablehnen-Knopf sah aus wie ein Nebenschauplatz und nicht
 * wie die zweite Entscheidung. Gehalten von `test_freigabe_ruhe.py`. */
.entscheidknopf {
  min-height: 44px;
  padding: 0 22px;
  font-size: 14px;
}

.entscheid-verweis {
  font-size: 13px;
  color: var(--grenze);
}

/* ABLEHNEN: die Felder schweben ueber der Leiste - ein Ueberlagerndes,
 * also Glas (`.huelle`). Ein `details`, ohne Skript. */
.ablehnen {
  position: relative;
}

.ablehnen > summary {
  list-style: none;
}

.ablehnen > summary::-webkit-details-marker {
  display: none;
}

.ablehnen-feld {
  position: absolute;
  right: 0;
  bottom: calc(100% + var(--a3));
  z-index: 30;
  width: 22rem;
  max-width: calc(100vw - 2 * var(--a4));
  padding: var(--a4);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    var(--huelle-schatten-hoch);
}

.ablehnen-feld p {
  margin: 0 0 var(--a3);
}

.tastenhilfe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a3) var(--a4);
  justify-content: center;
  margin-top: var(--a3);
}

.tastenhilfe > span {
  white-space: nowrap;
}

/* Unter 700 px stehen Knoepfe links - gilt fuer jede Seite, nicht nur
 * diese; stand schon vor dem Umbau in diesem Abschnitt. */
@media (max-width: 700px) {
  .knopfleiste {
    justify-content: flex-start;
  }
}

/* ====================================================================
 * DIE BEWEGUNG DER MARKE (caselli-motion.js, eingesetzt von bewegung.js)
 *
 * AUF HELLEM GRUND, OHNE SCHWARZEN KASTEN (Rueckmeldung 05.10.2026: die
 * Zeichen im Onyx-Quadrat waren „richtig dunkel", im Chat kaum zu
 * sehen). Das Kit setzt Licht in eine dunkle Flaeche; wir lassen es im
 * hellen Thema auf dem hellen Grund laufen und mischen die Leinwand dort
 * mit `multiply` statt `screen` (`--licht-mischung`, oben bei der
 * Themenwahl): aus Licht wird eine Spur in Indigo. Das Zeichen selbst ist
 * fuer hellen Grund gemacht - so steht es im Lockup der Leiste.
 *
 * ZWEI FORMEN: das nackte Zeichen (`.marke-zeichen`, Absender im Chat,
 * Knopf des KI-Fensters) und die helle Kachel (`.app-icon`, Statuskarte,
 * leerer Chat, Ankunft des KI-Entwurfs) mit Haarlinie und einem Hauch
 * Indigo darunter.
 *
 * OHNE SKRIPT steht das Zeichen still, und jede Denkzeile ist leer und
 * damit unsichtbar (`:empty`). Der Wartesatz steht ohnehin als Text da
 * und traegt die Ansage.
 * ================================================================= */

/* DAS NACKTE ZEICHEN. Ein Hintergrundbild und kein `<img>`: so braucht
 * keine Vorlage die Adresse, und laeuft eine Bewegung an seiner Stelle,
 * blendet `.bewegt` das stehende Zeichen aus. */
.marke-zeichen {
  --zeichen: 24px;
  display: inline-block;
  flex: none;
  width: var(--zeichen);
  aspect-ratio: 212 / 240;
  background: url("marke/caselli-mark.svg") center / contain no-repeat;
}

/* DIE KACHEL. Weiss mit Haarlinie im hellen Thema, die Flaeche des
 * Themas im dunklen; darunter ein Hauch Indigo (`--punkt-schein`, wie der
 * Punkt hinter den Ueberschriften). */
.app-icon {
  --icon: 52px;
  position: relative;
  display: grid;
  flex: none;
  place-items: center;
  width: var(--icon);
  height: var(--icon);
  border-radius: 26%;
  background: var(--flaeche);
  box-shadow: 0 0 0 1px var(--linie);
}

.app-icon::before {
  content: "";
  width: 51%;
  aspect-ratio: 212 / 240;
  background: url("marke/caselli-mark.svg") center / contain no-repeat;
}

/* Laeuft eine Bewegung in der Kachel, zeichnet sie das Zeichen selbst. */
.app-icon.bewegt::before {
  display: none;
}

.app-icon .cm-stage {
  min-height: 0;
}

.app-icon .cm-glow {
  display: none;
}

/* --- Die Denkzeile: Caselli denkt, mitten im Gespraech ---------------
 *
 * DIE ZEILE BAUT DIE BIBLIOTHEK (`thinking`), das Stilblatt legt sie quer:
 * links das Zeichen, rechts der Satz, der schimmert und wechselt („liest
 * im ERP nach", „prüft die Antwort"). Aus dem Satz wird am Ende die Pille
 * „Geprüft" - NUR, wenn der Server sagt, dass die Antwort die Pruefung
 * bestanden hat (bewegung.js, test_bewegung.py).
 *
 * AUF DEM GRUND DES THEMAS, OHNE KACHEL (Rueckmeldung 05.10.2026, dritte
 * Runde: die dunkle Kachel hinter dem denkenden Zeichen „sieht komisch
 * aus"). Im hellen Thema zeichnet die Bibliothek die Spur als satte Tinte
 * mit Mindestdicke (caselli-motion.js, Punkt 5), im dunklen als Licht wie
 * im Kit - die Leinwand folgt `--licht-mischung` des Themas. Ist das
 * Denken ausgelaufen, steht das Zeichen in Farbe da: es ist der Absender
 * der Antwort. */
.denkzeile {
  display: flex;
  align-items: center;
  min-height: 0;
  max-height: 8rem;
  transition:
    opacity var(--zeit-mittel) var(--kurve-aus),
    max-height var(--zeit-mittel) var(--kurve-falt),
    margin var(--zeit-mittel) var(--kurve-falt);
}

.denkzeile:empty {
  display: none;
}

.denkzeile .cm-stage {
  place-items: center start;
  width: auto;
  min-height: 0;
}

/* Der Hof der Bibliothek bleibt aus: die Buehne umfasst Zeichen UND Satz,
 * sein Licht saesse mitten zwischen beiden. */
.denkzeile .cm-glow {
  display: none;
}

.denkzeile .cm-think {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* DAS DENKFELD: das Zeichen mit Rand, `--denkfeld-faktor` mal so breit
 * wie das Zeichen und quadratisch (Zeichen 212 : 240) - Luft fuer die
 * Spur, ohne Flaeche. Der Rand steht immer, vor, waehrend und nach dem
 * Denken: das Zeichen wandert nicht, und die Antwort daneben rutscht
 * nicht nach - im Chat ist die Spalte des Absenders genau so breit
 * (`--absender`). */
.denkzeile .cm-mark {
  box-sizing: content-box;
  padding:
    calc(var(--cm-size) * (var(--denkfeld-faktor) - 240 / 212) / 2)
    calc(var(--cm-size) * (var(--denkfeld-faktor) - 1) / 2);
}

.denkzeile .cm-status {
  justify-items: start;
  font-size: 14px;
  font-weight: 500;
}

/* Der Satz nur, solange gedacht wird bzw. das Denken auslaeuft - danach
 * steht neben dem Zeichen die Antwort. */
.denkzeile:not(.bewegt) .cm-status {
  display: none;
}

/* Der Schimmer auf Weiss: leise Schrift, durch die ein Akzentlicht
 * laeuft. Die Bibliothek schiebt nur die Hintergrundlage. */
.denkzeile .cm-shimmer {
  background-image: linear-gradient(
    90deg,
    var(--text-leise) 0%,
    var(--text-leise) 38%,
    var(--akzent-text) 50%,
    var(--text-leise) 62%,
    var(--text-leise) 100%
  );
}

.denkzeile .cm-ready {
  gap: 6px;
  padding: 2px 10px 2px 8px;
  border-radius: var(--radius-pille);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.6;
  text-transform: uppercase;
}

/* DER ABSENDER DER JUENGSTEN ANTWORT: steht keine Bewegung darin (frisch
 * geladen, ohne Skript, oder nach dem Auslaufen), zeigt die Denkzeile das
 * stehende Zeichen - genau so gross und an genau der Stelle, an der das
 * bewegte zuletzt stand: mitten in einem Feld so gross wie das Denkfeld.
 * Der Wechsel ist deshalb nicht zu sehen. */
.chatantwort > .denkzeile:empty {
  display: block;
  flex: none;
}

.chatantwort > .denkzeile:empty::before {
  content: "";
  display: block;
  width: var(--absender);
  aspect-ratio: 1;
  background: url("marke/caselli-mark.svg") center / var(--absender-zeichen) auto no-repeat;
}

/* Die Warteseite des KI-Entwurfs: dieselbe Zeile, der Satz groesser.
 * Sie laesst die Seite zu, bevor das Denken auslaeuft (HX-Redirect). */
.denkzeile-gross .cm-status {
  font-size: 16px;
  font-weight: 600;
}

/* Mit laufender Zeile ist der Wartesatz doppelt - fuer das Auge. Fuer den
 * Screenreader bleibt er die Ansage (die Zeile ist `aria-hidden`), und
 * der Verweis „Neu laden" braucht nur, wer kein Skript hat. Im Chat steht
 * die Zeile im juengsten Eintrag und nicht neben dem Satz, daher `:has`;
 * ein Browser ohne `:has` zeigt den Satz eben doppelt. */
.chatbereich:has(.denkzeile:not(:empty)) .chatwarten,
.denkzeile:not(:empty) ~ .kientwurf-warten {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.chatbereich:has(.denkzeile:not(:empty)) .chatnachsehen,
.denkzeile:not(:empty) ~ .kientwurf-nachsehen {
  display: none;
}

/* DIE ANTWORT WARTET, BIS DAS DENKEN AUSGELAUFEN IST (Rueckmeldung
 * 05.10.2026: sie stand schon da, waehrend das Zeichen noch lief). Solange
 * die Denkzeile vor ihr laeuft (`.bewegt`), ist die Blase verborgen;
 * bewegung.js nimmt `.bewegt` weg, wenn `finish()` fertig ist - oder
 * sofort, wenn die Antwort NICHT geprueft ist (kein „Geprüft", dann auch
 * kein Warten). Ohne Skript traegt keine Zeile `.bewegt`. */
.chatantwort:has(> .denkzeile.bewegt) > .chatblase {
  display: none;
}

/* Erscheint sie, gleitet sie herein (`.kommt` setzt bewegung.js) - nur
 * dann, und nicht bei jedem Nachsehen: der Bereich wird waehrend des
 * Wartens jede Sekunde neu eingesetzt, eine Einblendung an jeder Blase
 * flackerte (Rueckmeldung 05.10.2026). */
.chatantwort.kommt > .chatblase {
  animation: antwort-kommt 420ms var(--kurve-aus);
}

/* Das bewegte Lockup der Leiste: so gross wie das Bild darunter. */
.wortmarke-buehne {
  display: block;
  width: 101px;
}

/* --- Ein Seitenwechsel, der laenger als 300 ms dauert ----------------
 *
 * Oben ueber dem Inhalt schwebt eine Glaspille (Huelle, keine Daten) mit
 * dem Zeichen, in dem die Lichtspur laeuft, und dem Satz „Wird geladen".
 * Ist die Seite da, schliesst sich die Spur und das Zeichen wird Farbe -
 * ohne Wort und ohne Haken: ein geladener Bildschirm ist keine Pruefung.
 * Der Inhalt darunter tritt waehrend des Wartens leicht zurueck. Die Pille
 * nimmt keine Klicks an und steht mittig ueber dem INHALT, neben der
 * Leiste (schmal: leiste-schmal.css). */
.ladeschicht {
  position: fixed;
  z-index: 60;
  top: calc(var(--rand) + 14px);
  left: calc(50% + (var(--leistenbreite) + var(--rand)) / 2);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px 7px 12px;
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-pille);
  background: var(--huelle-stark);
  box-shadow: var(--karte-schatten);
  -webkit-backdrop-filter: blur(24px) saturate(150%);
  backdrop-filter: blur(24px) saturate(150%);
  color: var(--text-zweit);
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  pointer-events: none;
  translate: -50% -8px;
  transition:
    opacity var(--zeit-mittel) var(--kurve-aus),
    translate var(--zeit-mittel) var(--kurve-aus);
}

.ladeschicht.sichtbar {
  opacity: 1;
  translate: -50% 0;
}

.ladeschicht-zeichen {
  display: grid;
  place-items: center;
  width: 22px;
  height: 26px;
}

.ladeschicht-zeichen .cm-stage {
  min-height: 0;
}

/* Der Uebergang gehoert hierher und nicht zum Rahmen: er ist Teil des
 * Ladens, und ohne Skript wechselt nie eine Klasse. */
.arbeitsbereich {
  transition: opacity var(--zeit-mittel) var(--kurve-aus);
}

.laedt-seite .arbeitsbereich {
  opacity: 0.62;
}

/* ====================================================================
 * BEWEGUNG AUS.
 *
 * Wer Bewegung abgeschaltet hat, bekommt KEINE - und erkennt jeden
 * Zustand trotzdem: der Puls bleibt stehen und faerbt weiter, der Satz
 * daneben steht ohnehin da. Im Stillstand sieht jeder Bildschirm FERTIG
 * aus und nicht halbfertig.
 *
 * EINE Regel fuer alles und keine je Bauteil - eine spaeter ergaenzte
 * Bewegung, die hier vergessen wird, laeuft sonst als einzige weiter.
 *
 * DIE LOGO-ANIMATIONEN (caselli-motion.js) laufen ueber die Web
 * Animations API und nicht ueber CSS; diese Regel erreicht sie nicht.
 * Die Bibliothek fragt `prefers-reduced-motion` selbst ab: Einmal-
 * Animationen zeigen sofort ihr Endbild, Lader pulsieren nur in der
 * Helligkeit, `finish()` blendet direkt um (docs/marke/MOTION.md).
 * ================================================================= */

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

/* ====================================================================
 * DIE VERWALTUNG
 *
 * KEIN GLAS AUF DEN DATEN. Server, Ports, Grenzen und Abdruecke sitzen
 * auf ruhiger, deckender Flaeche mit vollem Kontrast - genau wie die
 * Artikelnummer auf dem Freigabebildschirm. Glas traegt hier nur, was
 * wirklich schwebt: die Kopfleiste, und die hat ihre Regeln schon.
 *
 * DAS MANDANTENBAND IST DIE AUSNAHME BEI DER FARBE und keine bei der
 * Trueb: es ist deckend wie alles andere, aber es traegt eine Faerbung,
 * weil es eine Warnung ist. Wer nicht sieht, bei welchem Mandanten er
 * ist, aendert irgendwann eine Wertgrenze beim falschen.
 * ================================================================= */

/* --- Das Mandantenband ------------------------------------------- */

.mandantenband {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a3);
  margin-bottom: var(--a5);
  padding: var(--a3) var(--a4);
  border: 1px solid var(--frage-kante);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--frage-flaeche);
  font-size: 14px;
}

.mandantenband-wort {
  color: var(--text-zweit);
}

.mandantenband-kennung {
  font-weight: 500;
  font-size: 15px;
  color: var(--text);
}

.mandantenband-einblick {
  font-size: 14px;
  white-space: nowrap;
}

/* Der Ausgang steht rechts und traegt kein Gewicht. Er ist der Weg
 * zurueck und nicht die Handlung dieses Bildschirms. */
.mandantenband-ende {
  margin-left: auto;
}

/* --- Karten mit Kopfzeile ----------------------------------------- */

/* Die Ueberschrift links, der Bearbeiten-Knopf rechts. Immer dieselbe
 * Stelle: wer auf drei Karten dreimal suchen muss, liest keine davon
 * mehr ganz. */
.kartenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--a3);
  margin-bottom: var(--a4);
}

.kartenkopf h2,
.kartenkopf h3 {
  margin: 0;
}

.kartenkopf .knopfleiste {
  justify-content: flex-end;
  align-items: center;
}

/* Ein Postfach oder ein Zugang INNERHALB einer Karte. Haarlinie oben
 * statt eigener Kante: zwei geschachtelte Kaesten mit Schatten sehen
 * aus wie ein Fehler im Layout. */
.untereinheit + .untereinheit {
  margin-top: var(--a5);
  padding-top: var(--a5);
  border-top: 1px solid var(--linie);
}

.untereinheit .kartenkopf {
  margin-bottom: var(--a3);
}

/* --- Werteliste: Bezeichnung links, Wert rechts ------------------- */

/* EINE ECHTE `dl` UND KEINE TABELLE. Das ist Auszeichnung und nicht
 * Geschmack: ein Screenreader liest "Tagesbudget: nicht gesetzt" als
 * Paar, eine Tabelle mit zwei Spalten liest er als Tabelle mit zwei
 * Spalten. */
.werteliste {
  margin: 0;
  display: grid;
  gap: 0;
}

.wertzeile {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--a4);
  padding: var(--a2) 0;
  border-top: 1px solid var(--linie);
  align-items: baseline;
}

.wertzeile:first-child {
  border-top: none;
}

.wertzeile dt {
  color: var(--text-zweit);
  font-size: 14px;
}

.wertzeile dd {
  margin: 0;
  color: var(--text);
}

/* Bei schmalem Fenster untereinander. 220px Bezeichnung plus ein
 * Hostname passen unter 600px nicht nebeneinander, und dann bricht der
 * Wert mitten in der Adresse um. */
@media (max-width: 640px) {
  .wertzeile {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--a1);
  }

  .wertzeile dd {
    overflow-wrap: anywhere;
  }

  /* Ein Merkmal mit Satz ("nicht gesetzt - es gilt der Vorgabewert")
   * bricht hier um, statt aus der Karte zu laufen. */
  .wertzeile dd .merkmal {
    white-space: normal;
  }
}

/* --- Die gefaehrliche Zeile --------------------------------------- */

/* Entfernen steht UNTEN und abgesetzt, nicht neben "Speichern". Ein
 * Knopf, der etwas wegnimmt, gehoert nicht in Reichweite des Daumens,
 * der gerade speichern wollte. */
.gefahrzeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a3);
  margin-top: var(--a4);
  padding-top: var(--a3);
  border-top: 1px solid var(--linie);
  font-size: 13px;
  color: var(--text-leise);
}

/* --- Haken -------------------------------------------------------- */

.haken {
  display: flex;
  align-items: flex-start;
  gap: var(--a3);
  margin-bottom: var(--a4);
  font-size: 14px;
  line-height: 1.45;
  color: var(--text);
  cursor: pointer;
}

.haken input {
  margin: 2px 0 0;
  width: 16px;
  height: 16px;
  flex: none;
  accent-color: var(--akzent-knopf);
}

/* Der Schalter, der eine Schwaechung einschaltet, sieht danach aus -
 * und zwar bevor jemand ihn setzt, nicht erst danach. */
.haken-gefaehrlich {
  padding: var(--a3);
  border: 1px solid var(--grenze-kante);
  border-radius: var(--radius);
  background: var(--grenze-flaeche);
  color: var(--text);
}

.haken-gefaehrlich input {
  accent-color: var(--grenze);
}

/* --- Feldhinweis und Nurlesen ------------------------------------- */

/* Der Satz unter einem Feld, der sagt, was LEER bedeutet. Er ist der
 * Unterschied zwischen "nicht gesetzt" und "vergessen" (Regel 22).
 *
 * ER MUSS DIE FELDBESCHRIFTUNG AUSDRUECKLICH ZURUECKNEHMEN. Eine
 * Beschriftung ist ein WORT und steht klein, fett und in Versalien; ein
 * Hinweis ist ein SATZ. `.feld > label > span` trifft beide, weil beide
 * ein `span` im selben Feld sind - ohne die drei Zeilen unten stand
 * "LEER LASSEN HEISST: UNVERAENDERT. ZUM ENTFERNEN GIBT ES EINEN
 * EIGENEN KNOPF" in Grossbuchstaben auf dem Bildschirm. Im Browser
 * gesehen (Regel 33); im HTML war davon nichts zu sehen. */
.feldhinweis,
.feld > label > span.feldhinweis,
.feld > span.feldhinweis {
  display: block;
  margin-top: var(--a1);
  margin-bottom: 0;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  line-height: 1.45;
  color: var(--text-leise);
}

/* Ein Wert, der feststeht. KEIN abgeschaltetes Eingabefeld: ein
 * ausgegrautes Feld sieht aus, als waere es kaputt, und ein Mensch
 * klickt dreimal hinein, bevor er es glaubt. */
.nurlesen {
  display: block;
  padding: var(--a2) 0;
  color: var(--text);
  font-size: 15px;
}

/* --- Hinweisliste ------------------------------------------------- */

.hinweisliste {
  margin: var(--a4) 0;
  padding-left: var(--a5);
  color: var(--text-zweit);
  font-size: 14px;
  line-height: 1.6;
}

.hinweisliste li + li {
  margin-top: var(--a1);
}

/* --- Das Einmalpasswort ------------------------------------------- */

/* Gross und mit Abstand zwischen den Zeichen. Es wird
 * VORGELESEN oder abgetippt - beides geht mit 14px Fliesstext schlecht.
 * Die Vierergruppen kommen aus dem Wert selbst und nicht aus dem Stil:
 * was jemand markiert und kopiert, muss dasselbe sein, was er eintippt. */
.einmalwert {
  margin: var(--a4) 0;
  padding: var(--a4);
  border: 1px solid var(--akzent-kante);
  border-radius: var(--radius);
  background: var(--akzent-flaeche);
  color: var(--text);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-align: center;
  user-select: all;
}

/* --- Die Lagezeile der Schalttafel -------------------------------- */

/* Eine Zeile statt einer Karte mit Ueberschrift: sie beantwortet EINE
 * Frage, und eine Ueberschrift ueber einem Satz ist eine Zeile zu viel. */
.lagezeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a3);
  margin-bottom: var(--a4);
  padding: var(--a3) var(--a4);
  font-size: 14px;
  color: var(--text-zweit);
}

.lagezeile .knopf {
  margin-left: auto;
}

/* --- Die Betriebstabelle ------------------------------------------ */

/* Acht Spalten, und jede traegt etwas anderes. `vertical-align: top`
 * statt der Vorgabe: in einer Zelle mit zwei Zeilen soll die erste auf
 * Hoehe der ersten Zeile der Nachbarzelle stehen und nicht in der
 * Mitte. */
.betriebstabelle td {
  vertical-align: top;
}

.postfachzeile {
  display: flex;
  align-items: center;
  gap: var(--a2);
  white-space: nowrap;
}

.postfachzeile + .postfachzeile {
  margin-top: var(--a1);
}

/* Vorgaenge am Deckel (Block A): das Formular in der letzten Spalte. Zwei
 * Felder und ein Knopf nebeneinander, die Beschriftung bleibt ueber dem
 * Feld. Die Zahl ist schmal - hoechstens zwei Ziffern. */
.deckelformular {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--a2);
}

.deckelformular .feld {
  margin: 0;
}

.deckelformular input[type="number"] {
  width: 6em;
}

/* Die Preistabelle (Block B): Modell, Tag, zwei Betraege und die Quelle in
 * einer umbrechenden Zeile; die Quelle bekommt den Rest der Breite. */
.preisformular {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--a3);
}

.preisformular .feld {
  margin: 0;
}

.preisquelle {
  flex: 1 1 18em;
}

/* Die Denkstufe je Modell (Vorbereitung Handtest): eine Zeile je Modell,
 * das Formular wie das Preisformular, der Zustand als Satz darunter. */
.denkstufenliste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--a3);
}

/* --- Nutzung und Kosten (Block C) -------------------------------- */

/* Die Wahl des Zeitraums: gewoehnliche Verweise als Knoepfe. Der gewaehlte
 * traegt `aria-current="page"` - und GENAU DAS zeichnet diese Regel
 * (Regel 33: ein Attribut, das das Stilblatt nicht anspricht, sieht
 * niemand). */
.zeitraumwahl {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  margin-bottom: var(--a4);
}

.zeitraumwahl [aria-current="page"] {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-weight: 600;
}

.nutzungssumme {
  margin-bottom: var(--a4);
}

.nutzungszahlen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a3) var(--a5);
  margin: 0;
}

.nutzungszahlen dt {
  font-size: 13px;
  color: var(--text-zweit);
}

.nutzungszahlen dd {
  margin: 0;
  font-size: 18px;
}

/* Vierzehn Spalten bei 1440 px (gemessen: 1543 px Tabelle in 1136 px
 * Rahmen, solange auch die Koepfe einzeilig standen). Die ZAHLEN bleiben
 * auf einer Zeile, die KOEPFE brechen um - sonst lagen Budget und Deckel,
 * an denen die Farbe haengt, rechts ausserhalb des Rahmens. */
.nutzungstabelle td {
  white-space: nowrap;
}

.nutzungstabelle thead th {
  white-space: normal;
  vertical-align: bottom;
}

/* Die Tarifzelle der Testabrechnung ist Text und keine Zahl: sie darf
 * umbrechen (gemessen: 1035 px Tabelle in 976 px Rahmen bei 1280 px,
 * solange sie einzeilig stand). */
.nutzungstabelle td.tarifzelle {
  white-space: normal;
  min-width: 12em;
}

/* Der Mandant als Zeilenkopf: links wie jede erste Spalte, nicht mittig
 * (die Vorgabe fuer <th>). */
.nutzungstabelle tbody th {
  text-align: left;
  font-weight: 500;
}

/* Die drei Faelle, in denen jemand handeln muss - Farbe kommt aus
 * `.merkmal-frage`, diese Klassen sind der Anker fuer Test und Auge. */
.budget-knapp,
.deckel-erreicht,
.preis-fehlt {
  white-space: nowrap;
}

.deckel-erreicht {
  text-decoration: none;
}

/* Ein Tag, an dem Aufrufe ohne Preis liefen: seine Hoehe ist nur die
 * Untergrenze. Gestrichelte Kante statt einer zweiten Farbe. */
.balken-ohne-preis {
  stroke: var(--frage);
  stroke-width: 1.5;
  stroke-dasharray: 3 2;
}

/* --- Testabrechnung (Block D) ------------------------------------- */

/* Ein Knopf in einem Meldungssatz: auf eigener Zeile, ohne Rand. */
.inline-formular {
  margin: var(--a2) 0 0;
}

/* Die Druckansicht: ein Blatt, ohne Leiste. Auf dem Bildschirm mittig,
 * auf Papier randlos - der Drucker setzt seinen eigenen Rand. */
.druckseite {
  max-width: 60rem;
  margin: 0 auto;
  padding: var(--a5);
  background: var(--grund);
  color: var(--text);
}

.druckhinweis {
  margin: 0 0 var(--a3);
  padding: var(--a2) var(--a3);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
}

@media print {
  .druckseite {
    max-width: none;
    padding: 0;
  }
}

/* ====================================================================
 * STOERUNGEN: die Stoerungsseite. Das Band ueber der Liste ist eine
 * Warnung des Meldungsbauteils (siehe MELDUNGEN).
 * ==================================================================== */

.stoerungskarte {
  margin-bottom: var(--a3);
}

.stoerungskarte .handlung {
  margin: var(--a3) 0 0;
  color: var(--text);
}

.stoerungskarte .zustaendig {
  margin: var(--a2) 0 0;
  color: var(--text-zweit);
  font-size: 14px;
}

.mandantenlage .stoerungskarte {
  margin-top: var(--a3);
  margin-bottom: 0;
}

.abschnitt {
  margin: var(--a5) 0 var(--a3);
}

/* DAS ORIGINAL NEBEN DEM ERKANNTEN TEXT (Punkt 185).
 *
 * Deckend und mit Haarlinie, nie Glas: das Bild IST der Bestellinhalt,
 * und Bestellinhalt sitzt auf ruhiger Flaeche mit vollem Kontrast. Die
 * Breite folgt der Spalte; Hoehe aus dem Seitenverhaeltnis. Klein
 * gehalten - der Umbau der Oberflaeche kommt in der naechsten Runde. */
.originalseiten {
  display: grid;
  gap: var(--a3);
  margin: var(--a3) var(--a4) var(--a3);
}

.originalseite {
  margin: 0;
}

/* BLAETTERN (Beta-Rueckmeldung 07.10.2026): ohne Skript keine Pfeile - dann stehen alle Seiten
 * untereinander. Mit Skript siehe `@media (scripting: enabled)` unten. */
.seitenblaettern {
  display: none;
}

.seitenpfeil {
  min-width: 2.25rem;
  justify-content: center;
}

.textklappe {
  margin: 0 var(--a4) var(--a3);
}

.textklappe > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text-leise);
}

/* Die Legende ("Grau: nicht als Position übernommen") gehoert zum Text: steht im gewaehlten Blatt
 * der Text eingeklappt, steht sie nicht unten an der Karte. */
.karte.original:has(.reiterwahl:checked + .reiterknopf + .reiterblatt .textklappe:not([open]))
  > .legende {
  display: none;
}

/* DIE SEITE IST EIN VERWEIS AUF DAS GROSSE BILD (Block C.4). Die Buehne
 * haelt Bild und Rahmenebene zusammen: die Ebene liegt absolut darueber
 * und ist genau so gross wie das Bild. */
.seitenverweis {
  display: block;
  color: inherit;
  cursor: zoom-in;
}

.seitenbuehne {
  position: relative;
  display: block;
}

.originalseite img,
.grossansicht img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  background: var(--flaeche);
}

/* DIE RAHMENEBENE (Block C.3): SVG mit Attributen, gestreckt auf das Bild.
 * Sie faengt keinen Klick - der gehoert dem Verweis darunter -, ausser an
 * einem unsicheren Wort, dessen `title` sich zeigen soll. */
.seitenrahmen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

.zeilenrahmen {
  fill: transparent;
  stroke: none;
}

/* ZEIGT JEMAND AUF EINE POSITION, leuchtet ihr Rahmen auf dem Blatt -
 * dieselbe Farbe wie ihre Zeile im Text (freigabe.js). */
.zeilenrahmen.leuchtet {
  fill: var(--zeile-markiert);
  fill-opacity: 0.55;
  stroke: var(--frage);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

/* DAUERHAFT MARKIERT: ein Wort der Texterkennung unter der Schwelle. Die
 * Farbe der Texterkennung ("Zeichen geraten"), deckend genug, um auf
 * jedem Blatt aufzufallen, durchsichtig genug, um die Ziffer darunter
 * lesen zu lassen. */
.unsicheres-wort {
  fill: var(--ocr-flaeche);
  fill-opacity: 0.45;
  stroke: var(--ocr);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  pointer-events: auto;
}

.unsicher-legende {
  color: var(--ocr);
  font-weight: 600;
}

/* DAS GROSSE BILD IM DIALOG. Ein Dialog schwebt - aber sein Inhalt ist das
 * Original, also Daten: deckende Flaeche, Glas nur als Rand. Esc schliesst
 * ihn (der Browser), und `tastatur.js` geht dann NICHT zur Liste. */
.grossansicht {
  width: min(1100px, calc(100vw - 2 * var(--a5)));
  max-height: calc(100vh - 2 * var(--a5));
  padding: var(--a3);
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-gross);
  background: var(--flaeche);
  color: var(--text);
  box-shadow: var(--huelle-schatten-hoch);
  overflow: auto;
}

.grossansicht::backdrop {
  background: var(--schatten-hoch-farbe);
}

.grossansicht-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--a3);
  margin-bottom: var(--a3);
}

.grossansicht-titel {
  font-weight: 600;
}

.grossansicht-buehne {
  display: block;
}

.seitenhinweis {
  white-space: nowrap;
}

/* --- Die Ladeflaeche des Seitenbilds (Ruhige Oberflaeche, Block C) -----
 *
 * WIE EIN FENSTER, DAS LAEDT (Rueckmeldung 05.10.2026, Vorbild: der Lader
 * von Proton): ueber der Seite liegt eine Glasflaeche, darauf gross das
 * Zeichen mit der Lichtspur und darunter „Seite wird geladen…". Ist das
 * Bild da, steht es unscharf HINTER dem Glas, die Spur schliesst sich und
 * das Zeichen wird Farbe; dann blendet das Glas aus, und die Seite steht
 * scharf da. Kein „Fertig" und kein Haken - ein geladenes Bild ist keine
 * Pruefung (CLAUDE.md). Scheitert es, ein Satz mit Grund und „Nochmal
 * laden" (freigabe.js), keine Markierungen.
 *
 * GLAS IST HIER ERLAUBT: die Flaeche ist eine Ueberlagerung, und solange
 * sie liegt, gibt es darunter nichts zu lesen (CLAUDE.md, Glas nur auf
 * Schwebendem).
 *
 * OHNE SKRIPT GILT NICHTS DAVON: der Zustand `data-bild` kommt zwar vom
 * Server, aber jede Regel, die ihn liest, steht in
 * `@media (scripting: enabled)`. Kennt ein Browser diese Abfrage nicht,
 * bleibt es beim Bisherigen - Bild und Markierungen wie immer. Gesehen in
 * Chromium; Safari und Firefox stehen in OFFENE_PUNKTE (Regel 30). */
.seitenlader {
  display: none;
}

@media (scripting: enabled) {
  /* EINE SEITE ZUR ZEIT: die aktuelle traegt `data-aktuell` (erst vom Server, dann von
   * freigabe.js); darunter die Pfeile. */
  .originalseiten > .originalseite:not([data-aktuell]) {
    display: none;
  }

  .seitenblaettern {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--a3);
    font-size: 13px;
  }

  .seitenbuehne {
    isolation: isolate;
  }

  .seitenbuehne img,
  .seitenbuehne .seitenrahmen {
    transition: opacity 150ms ease-out;
  }

  /* Ohne gemessenes Seitenverhaeltnis hat das Bild vor dem Laden keine
   * Hoehe; die Flaeche braucht trotzdem eine, sonst gibt es nichts zu
   * sehen. */
  .seitenbuehne[data-bild="laedt"] {
    min-height: 16rem;
  }

  /* Das Glas liegt, solange geladen wird UND solange das Zeichen danach
   * auslaeuft (`.laeuft-aus`, bewegung.js). */
  .seitenbuehne[data-bild="laedt"] .seitenlader,
  .seitenbuehne.laeuft-aus .seitenlader {
    display: grid;
  }

  /* NOTFALLS NACH ZWOELF SEKUNDEN SICHTBAR: faengt den einen Fall, den
   * keine andere Schicht faengt - Skripte sind an, aber freigabe.js lief
   * nicht (nicht geladen, Fehler davor). Dann bliebe das Original sonst
   * fuer immer verborgen, und „Seite wird geladen" waere eine Luege. Das
   * Glas geht zur selben Zeit. Laeuft das Skript, ist der Zustand laengst
   * „da" oder „fehlt". */
  .seitenbuehne[data-bild="laedt"] img,
  .seitenbuehne[data-bild="laedt"] .seitenrahmen {
    opacity: 0;
    animation: seitenbild-notfalls 1ms 12s forwards;
  }

  .seitenbuehne[data-bild="laedt"] .seitenlader {
    animation: seitenlader-notfalls 1ms 12s forwards;
  }

  .seitenbuehne[data-bild="fehlt"] img,
  .seitenbuehne[data-bild="fehlt"] .seitenrahmen,
  .seitenbuehne[data-bild="fehlt"] .seitenlader {
    display: none;
  }
}

.seitenlader {
  position: absolute;
  inset: 0;
  z-index: 2;
  place-items: center;
  align-content: center;
  gap: 18px;
  padding: 24px 16px;
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-mittel);
  background: var(--huelle-stark);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  transition: opacity 320ms var(--kurve-aus);
}

/* Das Glas blendet aus, wenn das Zeichen fertig ist (bewegung.js). */
.seitenlader.verblasst {
  opacity: 0;
}

/* Der Lader selbst: das Zeichen mit der Lichtspur, gross wie bei Proton
 * und ohne Kachel. bewegung.js setzt ihn nach 300 ms ein. */
.ladebuehne {
  display: grid;
  place-items: center;
}

.ladebuehne .cm-stage {
  min-height: 0;
}

.seitenlader-satz {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-zweit);
}

/* DIE DREI PUNKTE laufen hinter dem Satz an („…"), wie im Vorbild. Ein
 * Auslassungszeichen, das sich in vier Stufen aufdeckt - ohne Skript. */
.seitenlader-satz::after {
  content: "\2026";
  display: inline-block;
  width: 0;
  overflow: hidden;
  vertical-align: bottom;
  animation: seitenlader-punkte 1.6s steps(4, jump-none) infinite;
}

/* Laeuft das Zeichen aus, ist nichts mehr zu laden. */
.laeuft-aus .seitenlader-satz {
  opacity: 0;
  transition: opacity 200ms ease-out;
}

@keyframes seitenlader-punkte {
  to {
    width: 1em;
  }
}

@keyframes seitenbild-notfalls {
  to {
    opacity: 1;
  }
}

@keyframes seitenlader-notfalls {
  to {
    visibility: hidden;
  }
}

/* STATISCH BEI „BEWEGUNG REDUZIEREN": die drei Punkte stehen ganz da. */
@media (prefers-reduced-motion: reduce) {
  .seitenlader-satz::after {
    width: auto;
    animation: none;
  }
}

/* ====================================================================
 * DIE UEBERSICHT (Ruhige Oberflaeche, Block D; neu geordnet 26.10.2026)
 *
 * Deckend mit Haarlinie, kein Glas (festgelegt in CLAUDE.md, "Die
 * Oberflaeche"). Oben die Lagezeile, dann der ARBEITSSTAND als EINE Karte
 * mit vier Feldern hinter Haarlinien - nicht mehr ein Raster gleicher
 * Kacheln mit einer Luecke am Ende (Rueckmeldung 26.10.2026: "sieht
 * hingeklatscht aus"). Darunter, nur fuer den Verwalter, das Team: links
 * das Diagramm, rechts die Zahlen als Liste. Rot nur die gerissenen
 * Grenzen, sobald es eine gibt - Farbe nur, wo jemand handeln muss. Eine
 * Kachel ohne Wert traegt einen Satz, nicht leiser: er ist die Auskunft.
 *
 * DIE BREITE KOMMT VOM KASTEN, nicht vom Fenster (`container-type`): mit
 * eingeklappter oder voller Leiste ist der Platz ein anderer.
 * ================================================================= */

.lagekasten {
  display: flex;
  flex-direction: column;
  gap: var(--a4);
  container-type: inline-size;
}

.lagekasten .karte {
  margin: 0;
}

.kachel {
  display: flex;
  flex-direction: column;
  gap: var(--a1);
  padding: var(--a4);
}

.kachel-titel {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-zweit);
}

.kachel-titel a {
  color: inherit;
  text-decoration: none;
}

.kachel-wert {
  margin: 0;
  font-size: 28px;
  font-weight: 600;
  line-height: 1.15;
  color: var(--text);
}

.kachel-grenze .kachel-wert {
  color: var(--grenze);
}

.kachel-satz {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-zweit);
}

.kachel-leer {
  font-size: 14px;
}

/* --- Die Lagezeile: Verarbeitung links, Stand rechts ------------------ */

.lagezeile-uebersicht {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--a2) var(--a4);
}

.kachel-dienst {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px var(--a3);
  padding: 0;
}

.kachel-zustand {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

/* Der Punkt der Leiste steht dort auf Midnight; auf dem hellen Grund
 * braucht er die Farben der Flaeche. Hohl heisst weiter "steht". */
.kachel .dienstpunkt {
  width: 8px;
  height: 8px;
  border-color: var(--text-zweit);
}

.kachel .dienstpunkt-laeuft,
.kachel .dienstpunkt-arbeitet {
  border-color: var(--erfolg);
  background: var(--erfolg);
}

.lage-stand {
  margin: 0;
  font-size: 13px;
  color: var(--text-zweit);
}

/* --- Der Arbeitsstand: eine Karte, vier Felder ------------------------ */

.arbeitsstand {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: 0;
  overflow: hidden;
}

.kachel-feld {
  position: relative;
  min-height: 9rem;
  padding: var(--a5);
  transition: background-color var(--zeit-kurz) var(--kurve-aus);
}

.kachel-feld + .kachel-feld {
  border-left: 1px solid var(--linie);
}

.kachel-feld .kachel-wert {
  margin-top: var(--a2);
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.kachel-feld .kachel-leer {
  margin-top: auto;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--text);
}

/* DAS GANZE FELD IST DER VERWEIS: der Verweis im Titel spannt sich ueber
 * das Feld. Ohne Skript, und die Tastatur erreicht ihn wie jeden Verweis. */
.kachel-verweis .kachel-titel a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.kachel-verweis:hover {
  background: var(--flaeche-zart);
}

.kachel-pfeil {
  position: absolute;
  top: var(--a5);
  right: var(--a4);
  display: inline-flex;
  color: var(--text-leise);
  opacity: 0;
  transform: translateX(-4px);
  transition:
    opacity var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

.kachel-verweis:hover .kachel-pfeil,
.kachel-verweis:focus-within .kachel-pfeil {
  opacity: 1;
  transform: none;
}

@container (max-width: 52rem) {
  .arbeitsstand {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .kachel-feld + .kachel-feld {
    border-left: 0;
  }

  .kachel-feld:nth-child(even) {
    border-left: 1px solid var(--linie);
  }

  .kachel-feld:nth-child(n + 3) {
    border-top: 1px solid var(--linie);
  }
}

@container (max-width: 30rem) {
  .arbeitsstand {
    grid-template-columns: minmax(0, 1fr);
  }

  .kachel-feld:nth-child(even) {
    border-left: 0;
  }

  .kachel-feld + .kachel-feld {
    border-top: 1px solid var(--linie);
  }

  .kachel-feld {
    min-height: 0;
  }
}

/* --- Das Team: nur fuer den Verwalter ---------------------------------- */

.teamteil {
  display: flex;
  flex-direction: column;
  gap: var(--a3);
  margin-top: var(--a3);
}

.teamkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--a1) var(--a3);
}

.teamkopf h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
}

.teamkopf-satz {
  margin: 0;
  font-size: 13px;
  color: var(--text-zweit);
}

.teamraster {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  gap: var(--a4);
  align-items: stretch;
}

@container (max-width: 52rem) {
  .teamraster {
    grid-template-columns: minmax(0, 1fr);
  }
}

.teamzahlen {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--a2) var(--a5);
}

.kachel-zeile {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px var(--a4);
  padding: var(--a4) 0;
}

.kachel-zeile + .kachel-zeile {
  border-top: 1px solid var(--linie);
}

.kachel-zeile .kachel-titel {
  grid-column: 1;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.kachel-zeile .kachel-wert {
  grid-column: 2;
  grid-row: 1 / span 2;
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: right;
}

.kachel-zeile .kachel-satz {
  grid-column: 1;
}

.kachel-zeile .kachel-leer {
  grid-column: 1 / -1;
  font-size: 13px;
}

/* --- Das Diagramm: SVG vom Server, Farben ueber Klassen (CSP) -------- */

.diagrammkarte {
  display: flex;
  flex-direction: column;
  padding: var(--a5);
}

.diagramm {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--a3);
}

.diagramm-leer {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--a2);
  min-height: 9rem;
  color: var(--text-leise);
  text-align: center;
}

.balken {
  fill: var(--bereit);
}

.achse-linie {
  stroke: var(--linie-stark);
  stroke-width: 1;
}

.achse-hilfslinie {
  stroke: var(--linie-zart);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

.achse-wert,
.achse-tag {
  fill: var(--text-leise);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .kachel-feld,
  .kachel-pfeil {
    transition: none;
  }
}

.seitenfehler {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2) var(--a3);
  margin: var(--a2) 0 0;
  font-size: 13px;
  color: var(--text-zweit);
}

/* ====================================================================
 * SCHMALE FENSTER: UNTER 1100 PX EINE ZEICHENSPALTE
 *
 * Die Leiste wird 64 px breit und zeigt nur noch Zeichen. OHNE SKRIPT -
 * eine Medienabfrage, kein Schalter, kein gespeicherter Zustand. DIE
 * REGELN STEHEN IN `leiste-schmal.css`, und die Bedingung am Verweis in
 * grund.html: so gilt derselbe Block unter 1100 px und auf dem
 * Freigabebildschirm schon unter 1440 px, ohne zweite Abschrift.
 *
 * DIE WORTE BLEIBEN IM BAUM: versteckt wie `.nurlesbar`, nicht mit
 * `display: none`. Ein Screenreader liest die Leiste unveraendert; wer
 * sieht, bekommt Wort und Zahl als `title` am Verweis (und `aria-label`
 * traegt sie ohnehin). Zahlen und Satz der Dienstlage stehen dort mit.
 *
 * Handy ist kein Ziel der Beta. Gemessen wurde ohne waagrechtes Scrollen
 * bei 1280x800, 1440x900 und 1920x1080 und in der Zeichenspalte bei
 * 1099 und 1024 px (Regel 33; neu messen, wer hier etwas aendert).
 * ================================================================= */

.leiste .wortmarke-kurz {
  display: none;
}

/* =================================================================
 * KUNDE ZUORDNEN (UI-Umbau Teil 3, Block A)
 *
 * Eine Karte im Seitenfluss: deckend mit Haarlinie, kein Glas (siehe
 * CLAUDE.md, "Glas nur auf dem, was schwebt"). Glas trägt nur die
 * Vorschlagsliste darunter - sie schwebt, wie bei der Artikelsuche.
 * Die Vormerkung trägt links die Kante der Hinweisfarbe: ein Zustand,
 * der von selbst weitergeht, und kein Fehler.
 * ================================================================= */

.zuordnung {
  display: grid;
  gap: var(--a2);
  margin: 0 0 var(--a4);
  padding: var(--a4) var(--a5);
}

.zuordnung h2 {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin: 0;
  font-size: 15px;
}

.zuordnung p {
  margin: 0;
}

.zuordnung-vorgemerkt {
  border-left: 3px solid var(--hinweis);
}

.zuordnungsformular {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2) var(--a3);
}

.zuordnung-beschriftung {
  font-weight: 500;
}

.zuordnungsformular .kundensuche {
  flex: 1 1 18rem;
  max-width: 26rem;
}

.zuordnungsformular .kundensuche .artikelfeld {
  width: 100%;
}

.zuordnung-merken {
  flex-basis: 100%;
}

/* ====================================================================
 * SEITENWECHSEL OHNE NEULADEN (UI-Umbau Teil 3, Block E)
 *
 * KEIN STANDBILD-UEBERGANG MEHR (Rueckmeldung 05.10.2026: der Wechsel
 * „laggt", „die Animation haengt"). Vorher rief HTMX
 * `document.startViewTransition`: der Browser fror die alte Seite als Bild
 * ein und blendete sie ueber die neue. Solange stand jede Bewegung still,
 * die Leiste zeigte alten UND neuen Eintrag markiert, und beide Seiten
 * lagen halbtransparent uebereinander. Jetzt tauscht HTMX sofort; die
 * Leiste wechselt den Eintrag in einem Bild.
 *
 * NUR DER NEUE INHALT BLENDET EIN, 180 ms mit der Auslaufkurve des Kits.
 * `.seite-kommt` setzt navigation.js an <html>, BEVOR der neue
 * Arbeitsbereich eingesetzt wird - ein Selbstabruf setzt sie nie.
 * NUR DECKKRAFT, KEINE VERSCHIEBUNG: eine Transformation machte den
 * Arbeitsbereich fuer die Dauer zum Bezug aller festen Elemente darin
 * (KI-Fenster, Knopf), sie sprangen. `prefers-reduced-motion` nimmt die
 * Einblendung mit der Regel fuer alle Bewegung weg.
 * ================================================================= */

@keyframes seite-kommt {
  from {
    opacity: 0.35;
  }
}

.seite-kommt .arbeitsbereich {
  animation: seite-kommt 180ms var(--kurve-aus);
}

/* Nach dem Wechsel liegt der Fokus auf der Ueberschrift (navigation.js),
 * damit ein Screenreader die neue Seite ansagt und Tab im Inhalt beginnt.
 * Eine Ueberschrift ist kein Bedienelement; ein Ring um sie saehe aus
 * wie eine Auswahl, die man treffen koennte. */
#inhalt h1[tabindex="-1"]:focus {
  outline: none;
}

/* --- Die Leiste einklappen (E.8) ----------------------------------- */

/* Weicher Wechsel der Spaltenbreite, unter 200 ms. Bei "Bewegung
 * reduzieren" setzt die Regel oben die Dauer auf null. */
.rahmen {
  transition: grid-template-columns 180ms ease-out;
}

.leiste-kopf {
  position: relative;
}

.leistenwahl {
  position: absolute;
  top: 0;
  right: 0;
  margin: 0;
}

.leistenwahl-knopf {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--leiste-kante);
  border-radius: var(--radius);
  background: none;
  color: var(--leiste-leise);
  cursor: pointer;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus);
}

.leistenwahl-knopf:hover {
  background: var(--flaeche-zart);
  color: var(--leiste-text);
}

/* Unter 1100 px gibt es nur die Symbolspalte - einklappen hiesse nichts.
 * Die Wahl bleibt gespeichert und gilt wieder, sobald das Fenster breiter
 * ist. */
@media (max-width: 1099px) {
  .leistenwahl {
    display: none;
  }
}

/* --- Wer bearbeitet gerade? (Block A) --------------------------------- */

/* DAS KUERZEL AN DER ZEILE DER LISTE. Ruhig: Haarlinie, deckende Flaeche,
 * keine Farbe (Farbe nur, wo jemand handeln muss - und hier muss niemand
 * etwas tun, er soll es nur wissen). Wer und seit wann steht im `title`. */
.bearbeiter {
  display: inline-flex;
  align-items: center;
  padding: 1px 6px;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: var(--flaeche);
  color: var(--text-zweit);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* NACH DER 409: WAS SIE EINGETIPPT HATTEN. Eine deckende Karte unter der
 * Meldung, Begriff links und Wert rechts - getrennt von den gesperrten
 * Feldern, die zeigen, was gebucht ist. */
.nicht-gebucht h2 {
  margin: 0;
  font-size: 15px;
}

.nicht-gebucht-liste {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--a1) var(--a3);
  margin: var(--a2) 0 0;
}

.nicht-gebucht-liste dt {
  color: var(--text-zweit);
}

.nicht-gebucht-liste dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* ====================================================================
 * DER RUECKFRAGE-ENTWURF (Auftrag Innendienst, Block C). Nur
 * Bedeutungsnamen, keine Rohfarben. Ein gesperrter VERWEIS ("Zu lang,
 * bitte kopieren") sieht aus wie ein gesperrter Knopf - dieselbe
 * Flaeche, dieselbe lesbare Schrift wie `.knopf[disabled]`.
 * ================================================================= */

.knopf[aria-disabled="true"] {
  cursor: not-allowed;
  background: var(--flaeche-erhoben);
  border-color: var(--linie);
  color: var(--text-zweit);
  box-shadow: none;
}

/* Die Zeile unter den Positionen (Rueckfrage vorbereiten bzw. „Keine
 * Frage fuer den Kunden"): mit demselben Rand wie „Position hinzufuegen" -
 * das Blatt selbst hat keinen, die Tabelle reicht bis an seine Kante.
 * Ohne ihn klebte der Satz an der linken Kante der Karte. */
.rueckfrage-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2);
  margin: 0;
  padding: 0 var(--a4) var(--a3);
}

.rueckfrage-zeile [hidden] { display: none; }
.kundenfrage-wahl {
  display: flex;
  align-items: flex-start;
  gap: var(--a2);
  margin: var(--a2) 0;
}

.rueckfrage-entwurf {
  display: grid;
  gap: var(--a3);
}

.rueckfrage-text {
  min-height: 18em;
  line-height: 1.5;
  resize: vertical;
}

.rueckfrage-knoepfe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--a2);
}

/* `hidden` am Hinweis "Zu lang, bitte kopieren": `.feldhinweis` setzt `display: block` und
   ueberstimmt sonst das Attribut - im Browser gesehen, im HTML war er versteckt (Regel 33). */
.rueckfrage-knoepfe [hidden] {
  display: none;
}

/* Der KI-Entwurf (Auftrag KI-Entwurf, B). DIE WARTESEITE: die Denkzeile
   mit dem App-Icon, darunter der Satz (fuer den Screenreader die Ansage).
   Der Punkt pulsiert nur ohne Skript - mit laufender Denkzeile ist der
   Satz fuer das Auge versteckt. Neutral: hier muss niemand handeln. */
.kientwurf-karte {
  display: grid;
  gap: var(--a4);
  padding: 22px 24px;
}

.denkzeile-gross .cm-status {
  font-size: 16px;
  font-weight: 600;
}

.kientwurf-warten {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin: 0;
}

.kientwurf-punkt {
  flex: none;
  width: 0.6em;
  height: 0.6em;
  border-radius: 50%;
  background: var(--text-zweit);
  animation: dienst-puls 1.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .kientwurf-punkt {
    animation: none;
  }
}

/* DIE ANKUNFT AM GEPRUEFTEN KI-ENTWURF: das App-Icon und daneben, was
   geprueft ist - wie die Statuskarte der Freigabe, im Seitenkopf. */
.kientwurf-status {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 14px;
}

.kientwurf-status .statustitel {
  margin: 0;
  font-size: 15px;
}

.kientwurf-status .statuszeile {
  max-width: 62rem;
}

.kientwurf-wahl {
  margin: var(--a3) 0;
}

.kientwurf-wahl form {
  margin: 0;
}

/* DIE ZEITLEISTE EINES VORGANGS (Auftrag Innendienst, D) ALS ZEITSTRAHL,
 * der von oben nach unten laeuft (Rueckmeldung 05.10.2026). Links die
 * Zeit - das Datum nur am ersten Ereignis eines Tages -, in der Mitte der
 * Strahl mit einem Punkt je Ereignis, rechts was geschah.
 *
 * DER PUNKT SAGT, WIE GENAU DIE ZEIT IST: voll - mit Uhrzeit
 * festgehalten; Ring - nur der Lauf ist festgehalten („im Lauf von");
 * gestrichelt - gar nicht festgehalten (Regel 22). Der Text daneben sagt
 * dasselbe in Worten. Farbe traegt keiner: in der Zeitleiste muss niemand
 * handeln.
 *
 * Beim Aufklappen laufen die Ereignisse nacheinander ein, der Strahl
 * waechst mit. Auf schmalem Schirm steht die Zeit ueber dem Ereignis. */
.zeitleiste {
  --zl-zeit: 132px;
  --zl-spalte: 30px;
  display: grid;
  margin: 0 0 var(--a4);
  padding: 6px 0 0;
  list-style: none;
}

.zeitleiste > li {
  position: relative;
  display: grid;
  grid-template-columns: var(--zl-zeit) var(--zl-spalte) minmax(0, 1fr);
  align-items: start;
  padding-bottom: 22px;
}

.zeitleiste > li:last-child {
  padding-bottom: 6px;
}

/* DER STRAHL: von diesem Punkt bis zum naechsten, durch die Mitte der
 * Spalte; am letzten Ereignis endet er. */
.zeitleiste > li::before {
  content: "";
  position: absolute;
  top: 18px;
  bottom: -2px;
  left: calc(var(--zl-zeit) + var(--zl-spalte) / 2 - 1px);
  width: 2px;
  border-radius: 1px;
  background: var(--linie);
  transform-origin: 50% 0;
}

.zeitleiste > li:last-child::before {
  display: none;
}

.zeitleiste-zeit {
  display: grid;
  justify-items: end;
  padding: 2px 6px 0 0;
  color: var(--text-zweit);
  font-size: 13px;
  line-height: 1.35;
  white-space: nowrap;
}

.zeitleiste-datum {
  color: var(--text);
  font-weight: 600;
}

.zeitleiste-punkt {
  justify-self: center;
  box-sizing: border-box;
  width: 12px;
  height: 12px;
  margin-top: 5px;
  border: 2px solid var(--text-zweit);
  border-radius: 50%;
  background: var(--text-zweit);
  box-shadow: 0 0 0 4px var(--flaeche);
}

.zeitleiste > li[data-zeitangabe="im_lauf"] .zeitleiste-punkt {
  background: var(--flaeche);
}

.zeitleiste > li[data-zeitangabe="keine"] .zeitleiste-punkt {
  border-style: dashed;
  border-color: var(--linie-stark);
  background: var(--flaeche);
}

.zeitleiste-was {
  display: grid;
  gap: 2px;
  min-width: 0;
  padding: 1px 0 0 8px;
  font-size: 14px;
  line-height: 1.4;
}

.zeitleiste-was .leise {
  display: block;
  font-size: 13px;
}

/* NACHEINANDER EINLAUFEN, sobald die Zeitleiste aufgeklappt wird: jedes
 * Ereignis 50 ms nach dem vorigen, ab dem zwoelften alle zugleich. */
.aufklapper[open] .zeitleiste > li {
  animation: zl-ereignis 360ms var(--kurve-aus) both;
}

.aufklapper[open] .zeitleiste > li::before {
  animation: zl-strahl 420ms var(--kurve-aus) both;
}

.zeitleiste > li:nth-child(2),
.zeitleiste > li:nth-child(2)::before {
  animation-delay: 50ms;
}

.zeitleiste > li:nth-child(3),
.zeitleiste > li:nth-child(3)::before {
  animation-delay: 100ms;
}

.zeitleiste > li:nth-child(4),
.zeitleiste > li:nth-child(4)::before {
  animation-delay: 150ms;
}

.zeitleiste > li:nth-child(5),
.zeitleiste > li:nth-child(5)::before {
  animation-delay: 200ms;
}

.zeitleiste > li:nth-child(6),
.zeitleiste > li:nth-child(6)::before {
  animation-delay: 250ms;
}

.zeitleiste > li:nth-child(7),
.zeitleiste > li:nth-child(7)::before {
  animation-delay: 300ms;
}

.zeitleiste > li:nth-child(8),
.zeitleiste > li:nth-child(8)::before {
  animation-delay: 350ms;
}

.zeitleiste > li:nth-child(9),
.zeitleiste > li:nth-child(9)::before {
  animation-delay: 400ms;
}

.zeitleiste > li:nth-child(10),
.zeitleiste > li:nth-child(10)::before {
  animation-delay: 450ms;
}

.zeitleiste > li:nth-child(n + 11),
.zeitleiste > li:nth-child(n + 11)::before {
  animation-delay: 500ms;
}

@keyframes zl-ereignis {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}

@keyframes zl-strahl {
  from {
    transform: scaleY(0);
  }
}

@media (max-width: 40em) {
  .zeitleiste > li {
    grid-template-columns: var(--zl-spalte) minmax(0, 1fr);
  }

  .zeitleiste > li::before {
    left: calc(var(--zl-spalte) / 2 - 1px);
  }

  .zeitleiste-zeit {
    grid-column: 2;
    grid-row: 1;
    justify-items: start;
    padding: 2px 0 2px 8px;
  }

  .zeitleiste-punkt {
    grid-column: 1;
    grid-row: 1;
  }

  .zeitleiste-was {
    grid-column: 2;
  }
}

/* DIE HINWEISE AUS DEM ERP ALS SCHMALE ZEILE (Rueckmeldung 26.10.2026: die
 * Statuskarte mit App-Icon war hoeher als ihr Inhalt). Eine Zeile: Zeichen,
 * Titel, Pille, Stand, rechts die Pruefungen als Klapptafel und der Knopf.
 * Darunter nur, was es gibt. Deckend: auf der Karte stehen Daten aus dem
 * ERP. */
.erp-hinweise {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px 10px 16px;
}

.statuskopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.erp-zeichen {
  display: inline-flex;
  flex: none;
  color: var(--text-zweit);
}

/* Titel, Pille und Stand in EINER Zeile; schmal brechen sie um. */
.statustext {
  display: flex;
  flex: 1 1 260px;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  min-width: 0;
}

.statustext h2 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

.statustitel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

/* DIE PILLE DES MOCKUPS („FERTIG"): Versalien, Laufweite, Akzent. Sie
 * steht nur da, wenn jede Pruefung lief (`_erp_hinweise.html`). Die
 * zaehlende Pille fuer offene Pruefungen ist neutral - nicht geprueft
 * heisst nicht, dass jemand handeln muss (Farbe nur, wo jemand handeln
 * muss). */
.statuspille {
  padding: 2px 8px;
  border-radius: var(--radius-pille);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
}

.statuspille-offen {
  background: var(--flaeche-erhoben);
  box-shadow: inset 0 0 0 1px var(--linie-stark);
  color: var(--text-zweit);
}

.statuszeile {
  margin: 0;
  font-size: 13px;
  color: var(--text-leise);
}

.statusknopf {
  margin: 0;
}

.statushinweis {
  margin: 0;
  padding-left: 28px;
  font-size: 13px;
}

.erp-hinweisliste {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 10px 0 2px;
  border-top: 1px solid var(--linie);
  list-style: none;
}

.erp-hinweis {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
}

.erp-hinweis-text {
  min-width: 0;
}

.erp-hinweis-text p {
  margin: 0 0 2px;
}

/* DAS RUNDE ZEICHEN VOR EINEM HINWEIS: Akzent fuer einen Fakt, Bernstein
 * fuer eine interne Frage - die verhindert Bereit, hier muss jemand
 * handeln. */
.hinweispunkt {
  display: grid;
  flex: none;
  place-items: center;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.erp-hinweis-frage .hinweispunkt {
  background: var(--frage-flaeche);
  box-shadow: inset 0 0 0 1px var(--frage-kante);
  color: var(--frage);
}

.erp-antwort {
  display: flex;
  flex-wrap: wrap;
  gap: var(--a2);
  margin-top: var(--a2);
}

.statusdetails .klapptafel-inhalt {
  right: 0;
  left: auto;
  width: min(34rem, calc(100vw - 2 * var(--rand)));
}

.pruefliste {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 20px;
  margin: 0;
  padding: 0;
  font-size: 13px;
  color: var(--text-zweit);
  list-style: none;
}

@media (max-width: 40em) {
  .pruefliste {
    grid-template-columns: minmax(0, 1fr);
  }
}

.pruefliste > li {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.pruefpunkt {
  display: grid;
  flex: none;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.pruefung-offen .pruefpunkt {
  background: var(--flaeche-erhoben);
  box-shadow: inset 0 0 0 1px var(--linie-stark);
  color: var(--text-leise);
}

/* WAS DAS ERP ZU EINER POSITION SAGT, IN EINER ZEILE (Rueckmeldung 26.10.2026): leise, mit
 * Mittelpunkten getrennt, die Belegnummer nur im `title`. */
.erp-bestand {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 8px;
  margin: 0;
  font-size: 12.5px;
  color: var(--text-zweit);
}

.erp-bestand-zeichen {
  display: inline-flex;
  color: var(--text-leise);
}

.erp-bestand-teil + .erp-bestand-teil::before {
  content: "·";
  margin-right: 8px;
  color: var(--text-leise);
}

/* Mitdenken an der Position: der verspaetete Termin hat Wort und Kante. */
.erp-termin {
  border-inline-start: 3px solid var(--frage-kante);
  background: var(--frage-flaeche);
  padding: var(--a2);
  font-weight: 600;
}

.erp-angebot {
  margin: var(--a2) var(--a4);
}

/* DIE POSITIONEN BLEIBEN EINE TABELLE, auch schmal - auf dem Telefon wie
 * im geteilten Fenster (Rueckmeldung 05.10.2026: untereinander gestapelt
 * sah es „komisch" aus, und die Seite wurde „viel zu lang"). Ist die
 * Karte schmaler als die Tabelle, scrollt die Tabelle seitwaerts in ihrem
 * Rahmen (`.tabellenrahmen`), die Seite nicht. Sie behaelt 660 px: die
 * breiteste braucht 651 px min-content (gemessen 24.09.2026), und die
 * schmalste Karte auf dem Desktop misst innen 678 px (Spalte 680 px minus
 * Rahmenlinien) - dort scrollt nichts. Schwelle und Mindestbreite sind
 * dieselbe Zahl (test_chatfenster.py).
 *
 * NUR SCHMAL IST DER RAHMEN EIN SCROLLBEREICH. Ein Scrollbereich
 * beschneidet auch nach unten - die Vorschlagsliste unter einem
 * Artikelfeld der letzten Zeile verschwaende darin. Breit haengt sie
 * deshalb frei wie zuvor; schmal steht sie fest im Fenster unter ihrem
 * Feld (`.vorschlagsrahmen-fest`, tastatur.js).
 *
 * DIE ZEILEN UEBER DIE GANZE BREITE (Rueckfrage, Hinweis, Meldung) laufen
 * beim Scrollen nicht aus dem Bild: ihr Inhalt klebt links im Rahmen und
 * ist so breit wie dessen sichtbarer Teil (`100cqw`) - sonst stuende eine
 * Rueckfrage mit ihrem Antwortfeld zur Haelfte jenseits des Rands. */
.karte.positionen {
  container: positionen / inline-size;
}

.positionsrahmen {
  container: positionsrahmen / inline-size;
  overflow-x: visible;
}

.positionstabelle {
  min-width: 660px;
}

/* KLEBEN NUR, WO DER RAHMEN SCROLLT (Rueckmeldung 27.10.2026, "flüssig"): jede klebende Zelle
 * ist im Browser eine eigene Ebene, die beim Scrollen mitgefuehrt wird - breit klebten zehn und
 * mehr davon an nichts. Breit sind sie nur gesetzt (`relative`): eine Stapelebene je Zeile, wie
 * es die offene Vorschlagsliste braucht (test_vorschlagsliste.py). DIE REIHENFOLGE TRAEGT: die
 * Abfrage steht NACH der Grundregel, sonst gewaenne `relative` bei gleicher Spezifitaet. */
.positionsrahmen td[colspan] > * {
  position: relative;
  box-sizing: border-box;
  max-width: calc(100cqw - 32px);
}

@container positionen (max-width: 659.98px) {
  .positionsrahmen {
    overflow-x: auto;
  }

  .positionsrahmen td[colspan] > * {
    position: sticky;
    left: 16px;
  }
}

.positionsrahmen td[colspan] > :has(.vorschlagsrahmen:not(:empty)) {
  z-index: 35;
}

.vorschlagsrahmen.vorschlagsrahmen-fest {
  position: fixed;
  top: var(--vorschlag-oben);
  left: var(--vorschlag-links);
  min-width: var(--vorschlag-breite);
  max-width: min(30rem, calc(100vw - 16px));
}

/* ====================================================================
 * DER ERP-CHAT ALS GESPRAECH (Redesign nach Mockup, 05.10.2026)
 *
 * Die Frage rechts als Blase in der Akzentflaeche, die Antwort links mit
 * dem Zeichen als Absender - deckend, voller Kontrast, nie Glas: in ihr
 * stehen Daten. Waehrend des Wartens denkt Caselli in der Denkzeile genau
 * dort, wo gleich die Antwort steht. Unten Vorschlaege als Chips und das
 * Eingabefeld als Pille mit dem Sendeknopf darin. Auf "Fragen" steht der
 * Chat als Karte; im Vorgang ist er ein Fenster (unten, `.chatfenster`).
 * ================================================================= */

/* AUF „FRAGEN" IST DIE KARTE DER BEHAELTER, im Vorgang das Fenster -
 * beide heissen `chat`: dieselben Regeln nach der eigenen Breite (unten),
 * schmal ohne Untertitel, breit in einer lesbaren Spalte. Vorher lief das
 * Eingabefeld auf breiten Schirmen ueber die ganze Breite (Rueckmeldung
 * 05.10.2026). */
/* DIE FRAGEN-SEITE ALS CHAT (Beta-Rueckmeldung 06.10.2026): vorher wuchs die
 * Seite mit jeder Frage. Jetzt wie das KI-Fenster: feste Hoehe, das
 * Gespraech rollt in der Karte, der Fuss mit dem Feld klebt unten und ist
 * deckend. Mindestens 26rem, sonst bis knapp an den Fensterrand (unter dem
 * Seitenkopf). Mitgerollt wird in chatfenster.js (`rumpf()`). */
.chatkarte {
  container: chat / inline-size;
  margin-top: var(--a4);
  display: flex;
  flex-direction: column;
  height: max(26rem, calc(100dvh - 15rem));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-bottom: 0;
  scrollbar-width: thin;
}

.chatkarte .chatbereich {
  flex: 1 0 auto;
}

.chatkarte .chatfuss {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin-top: auto;
  padding: 12px 0 var(--a5);
  border-top: 1px solid var(--linie);
  background: var(--flaeche);
}

.chatbereich {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.chatverlauf {
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chateintrag {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

.chat-wer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 4px;
  color: var(--text-leise);
  font-size: 12px;
  font-weight: 600;
}

/* DIE FRAGE: rechts, in der Akzentflaeche, die Ecke unten rechts spitz -
 * wie jede Blase, die vom Sprecher kommt. Keine gefuellte Farbe: Indigo
 * voll traegt nur der eine Knopf je Bildschirm. */
.chatfrage {
  align-self: flex-end;
  max-width: min(78%, 40rem);
  padding: 10px 16px 12px;
  border-radius: 20px 20px 6px 20px;
  background: var(--akzent-flaeche);
  overflow-wrap: anywhere;
}

.chatfrage .chat-wer {
  justify-content: flex-end;
}

.chatfrage-text {
  margin: 0;
  font-weight: 500;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* DIE ANTWORT: links der Absender (an der juengsten das Zeichen, das eben
 * noch gedacht hat; an aelteren ein leerer Platz gleicher Breite),
 * daneben die Blase. Keine Einblendung beim Einsetzen: das Nachsehen setzt
 * den ganzen Bereich jede Sekunde neu ein (siehe `.kommt`).
 *
 * DIE SPALTE DES ABSENDERS ist so breit wie das Feld, in dem das Zeichen
 * denkt (`--denkfeld-faktor`). `--absender-zeichen` ist die Groesse, in
 * der die Denkzeile das Zeichen zeichnet - dieselbe Zahl steht als
 * `data-groesse` in _chat.html (test_bewegung.py haelt beide gleich). */
.chatantwort {
  --absender-zeichen: 32px;
  --absender: calc(var(--absender-zeichen) * var(--denkfeld-faktor));
  display: flex;
  align-items: flex-start;
  gap: 12px;
  max-width: min(100%, 52rem);
  min-width: 0;
}

/* DIE WARTEZEILE: nur die Denkzeile, mittig zu ihrem Satz - sie steht dort,
 * wo gleich die Antwort steht. */
.chatantwort-wartet {
  align-items: center;
  min-height: var(--absender);
}

.chatblase {
  flex: 1 1 auto;
  min-width: 0;
  padding: 12px 16px 14px;
  border: 1px solid var(--linie);
  border-radius: 6px 20px 20px 20px;
  background: var(--flaeche);
  box-shadow: 0 1px 2px var(--schatten-farbe);
  color: var(--text);
}

.chatantwort-keine_daten .chatblase {
  color: var(--text-zweit);
}

.chatantwort-verworfen .chatblase,
.chatantwort-stoerung .chatblase {
  border-color: var(--frage-kante);
}

@keyframes antwort-kommt {
  from {
    opacity: 0;
    translate: 0 8px;
  }

  to {
    opacity: 1;
    translate: 0 0;
  }
}

.chattext {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* EINE FREIE ANTWORT (Auftrag 21.10.2026): Absaetze, Listen, fett und Code -
 * `web.textdarstellung`. Der Text steht ruhig, mit Luft zwischen den Absaetzen. */
.chattext-frei {
  white-space: normal;
}

.chattext-frei > p {
  margin: 0;
}

.chattext-frei > p + p,
.chattext-frei > p + ul,
.chattext-frei > p + ol,
.chattext-frei > ul + p,
.chattext-frei > ol + p {
  margin-top: 10px;
}

.chattext-frei ul,
.chattext-frei ol {
  margin: 0;
  padding-left: 22px;
}

.chattext-frei li + li {
  margin-top: 4px;
}

.chattext-frei code {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--flaeche-zart);
  font-size: 0.92em;
}

/* WOHER SIE KOMMT: eine freie Antwort sagt leise, dass sie nicht aus den Daten ist. */
.chatherkunft {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--text-zweit);
}

/* RUECKFALL AUS DEM HANDBUCH: der Abschnitt im Wortlaut unter dem festen Satz,
 * abgesetzt mit einer Haarlinie, darunter sein Chip wie bei einer Antwort. */
.chatabschnitt {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--linie);
}

/* DIE QUELLEN ALS CHIPS: das ERP-Zeichen, das Werkzeug, die Belege. */
.chatquellen {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  font-size: 12px;
  color: var(--text-zweit);
}

/* Ein langer Chip bricht wie Text um: das Zeichen bleibt vorn in der
 * ersten Zeile, die Ecken bleiben Ecken. Einzeilig ist er 28 px hoch, der
 * Radius von 14 px macht ihn dort zur Pille (Rueckmeldung 05.10.2026:
 * schmal stand das Zeichen allein in einer Zeile, und der Chip wurde
 * zur Ellipse). */
.chatquellen li {
  max-width: 100%;
  padding: 4px 10px;
  border: 1px solid var(--linie);
  border-radius: var(--radius-mittel);
  background: var(--flaeche-erhoben);
  line-height: 18px;
  overflow-wrap: anywhere;
}

.chatquellen .zeichen {
  display: inline-block;
  margin-right: 4px;
  vertical-align: -2px;
}

.chattabelle-rahmen {
  max-height: 22rem;
  margin-top: 10px;
  overflow: auto;
  border: 1px solid var(--linie);
  border-radius: var(--radius-mittel);
  background: var(--flaeche);
}

.chattabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}

.chattabelle th,
.chattabelle td {
  padding: 6px 12px;
  border-bottom: 1px solid var(--linie-hauch);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
}

.chattabelle th[scope="rowgroup"] {
  background: var(--flaeche-erhoben);
  font-weight: 600;
}

.chattabelle th[scope="row"] {
  width: 40%;
  color: var(--text-zweit);
  font-weight: 400;
}

/* DER LEERE CHAT: zwei Saetze in der Du-Form, linksbuendig, ohne Kachel und ohne Mitte
 * (Auftrag 21.10.2026 - das war das Muster jedes KI-Chats). */
.chatleer {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 20px 16px 8px;
}

.chatleer-titel {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.chatleer-satz {
  margin: 0;
  color: var(--text-zweit);
  font-size: 14px;
}

.chatwarten {
  display: flex;
  align-items: center;
  gap: var(--a2);
  margin: 0;
  color: var(--text-zweit);
  font-size: 14px;
}

/* DER FUSS: Vorschlaege, Eingabefeld, Hinweis - mit Luft dazwischen.
 * Vorher klebten auf „Fragen" die Chips am Feld und der Hinweis darunter
 * (Rueckmeldung 05.10.2026). Im Fenster klebt der Fuss zudem unten
 * (`.chat-schwebt .chatfenster .chatfuss`). */
.chatfuss {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* DIE VORSCHLAEGE ALS CHIPS. */
.chatvorschlaege {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.chatchip {
  min-height: 34px;
  padding: 6px 14px;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-pille);
  background: var(--flaeche);
  color: var(--text-zweit);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    border-color var(--zeit-kurz) var(--kurve-aus),
    color var(--zeit-kurz) var(--kurve-aus);
}

.chatchip:hover {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

.chatchip[disabled] {
  cursor: progress;
  opacity: 0.6;
}

/* DAS EINGABEFELD ALS PILLE, der Sendeknopf darin. Der Fokus legt den
 * Ring um die ganze Pille, nicht nur um das Feld. Seit der Beta-Rueckmeldung
 * ein Textfeld, das mit dem Text waechst: einzeilig eine Pille (Radius =
 * halbe Hoehe), mehrzeilig ein abgerundeter Kasten, der Knopf unten. */
.chatformular {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 5px 5px 5px 20px;
  border: 1px solid var(--linie-stark);
  border-radius: 26px;
  background: var(--flaeche);
  box-shadow: 0 1px 2px var(--schatten-farbe);
  transition:
    border-color var(--zeit-kurz) var(--kurve-aus),
    box-shadow var(--zeit-kurz) var(--kurve-aus);
}

.chatformular:focus-within {
  border-color: var(--fokus);
  box-shadow:
    0 0 0 2px var(--flaeche),
    0 0 0 5px var(--fokus-schein);
}

.chatfeld {
  flex: 1 1 auto;
  min-width: 0;
  box-sizing: border-box;
  height: 40px;
  max-height: 160px;
  padding: 9px 0;
  overflow-y: auto;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 15px;
  line-height: 22px;
  resize: none;
  overflow-wrap: anywhere;
}

.chatfeld::placeholder {
  color: var(--text-leise);
  opacity: 1;
}

.chatfeld:focus,
.chatfeld:focus-visible {
  outline: none;
  box-shadow: none;
}

.chatsenden {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px 0 18px;
  border: 0;
  border-radius: var(--radius-pille);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition:
    background-color var(--zeit-kurz) var(--kurve-aus),
    transform var(--zeit-kurz) var(--kurve-aus);
}

.chatsenden:hover {
  background: var(--akzent-kante);
  transform: translateY(-1px);
}

.chatsenden[disabled] {
  cursor: progress;
  opacity: 0.6;
  transform: none;
}

/* Der Knopf "Rückfrage an Kunden vorbereiten": Zeichen vorn, wie jeder Knopf
 * mit Zeichen (Beta-Rueckmeldung 06.10.2026: er war zu klein). */
.rueckfrage-knopf {
  gap: 8px;
}

/* DIE RUECKFRAGE AN DEN KUNDEN IM FENSTER (Beta-Rueckmeldung 06.10.2026):
 * als neue Nachricht unten im Verlauf, vor dem Eingabefeld (Rueckmeldung
 * 08.10.2026), deckend mit Haarlinie, unsichtbar solange leer. Die Karten
 * der Entwurfsseite stehen darin ohne eigenen Schatten. */
.ki-entwurf-bereich {
  margin: 16px 0;
  padding: 12px;
  border: 1px solid var(--linie);
  border-radius: var(--radius-mittel);
  background: var(--flaeche);
}

.ki-entwurf-bereich:has(#ki-entwurf:empty) {
  display: none;
}

.ki-entwurf-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.ki-entwurf-titel {
  font-size: 14px;
  font-weight: 700;
}

.ki-entwurf-bereich .karte {
  padding: 12px;
  box-shadow: none;
}

/* „Antwort stoppen" ueber dem Feld, nur waehrend einer Antwort. Zweitknopf:
 * gefuellt bleibt nur „Freigeben". Das Zeichen ist ein Quadrat wie auf jeder
 * Stopptaste. */
.chatstopp {
  display: flex;
  justify-content: center;
}

.chatstopp-knopf {
  gap: 8px;
}

.chatstopp-zeichen {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: currentColor;
}

.chathinweis {
  margin: 0;
  color: var(--text-leise);
  font-size: 12px;
  text-align: center;
}

@media (max-width: 40em) {
  .chatfrage {
    max-width: 92%;
  }

  .chatsenden > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .chatsenden {
    width: 40px;
    padding: 0;
    justify-content: center;
  }
}

/* ====================================================================
 * DAS KI-FENSTER IM VORGANG (Rueckmeldung 05.10.2026)
 *
 * Ein schwebender Knopf rechts unten, jederzeit erreichbar, oeffnet ein
 * Fenster, das sich wie ein Programm verhaelt: an der Titelleiste ziehen,
 * an den rechten Rand ziehen (dann steht es geteilt NEBEN dem Vorgang),
 * vergroessern, minimieren, schliessen - die drei Knoepfe in der Art von
 * macOS. Die Lage traegt <html> (`data-chatfenster`, `--chat-*`, gesetzt
 * von chatfenster.js): ein Seitenwechsel tauscht den Arbeitsbereich, und
 * das Fenster des naechsten Vorgangs steht sofort an derselben Stelle.
 *
 * DATEN AUF DECKENDER FLAECHE: das Fenster ist weiss bzw. die Flaeche des
 * Themas; nur die Titelleiste ist Huelle.
 *
 * DER INHALT RICHTET SICH NACH DER BREITE DES FENSTERS, nicht nach der des
 * Browsers (`container: chatfenster`): ein schmales Fenster kuerzt den
 * Untertitel und legt die Vorschlaege in eine Reihe, ein grosses fuehrt
 * das Gespraech in einer lesbaren Spalte.
 *
 * OHNE SKRIPT (keine Klasse `.chat-schwebt` an <html>) ist es die Karte
 * unter Original und Positionen wie bisher, offen; Fensterknoepfe, Knopf
 * und Griffe gibt es dann nicht.
 * ================================================================= */

.chatfenster {
  margin-top: var(--a4);
}

.chatfenster-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin-bottom: 18px;
}

.chatfenster-kopf h2 {
  margin: 0;
  font-size: 16px;
}

.chatfenster-satz {
  font-size: 13px;
  color: var(--text-leise);
}

.ampel,
.fensterknopf,
.chatknopf,
.chatfenster-kante,
.andockvorschau {
  display: none;
}

.chatantwort-platz {
  flex: none;
  width: var(--absender);
}

/* DIE HUELLE (Chatfenster auf jeder Seite ausser Vorgang und "Fragen"): sie laedt ihren
 * Inhalt per HTMX beim Oeffnen. Ohne Skript (keine Klasse `.chat-schwebt` an <html>, die setzt
 * nur chatfenster.js) waere sie eine leere Karte mit einem Satz, der nie weicht - dort fuehrt der
 * Verweis der Leiste auf die Seite "Fragen". */
html:not(.chat-schwebt) .chatfenster-huelle {
  display: none;
}

.chatlaedt {
  margin: 0;
  padding: var(--a4);
  color: var(--text-zweit);
}

/* --- Der schwebende Knopf ------------------------------------------- */

/* UEBER DER ENTSCHEIDUNGSLEISTE, damit er nie auf „Freigeben" liegt:
 * ihre Hoehe misst chatfenster.js (`--chat-unten`), sie haengt davon ab,
 * wie viele Pruefmerkmale umbrechen. Huelle, weil er schwebt - aber DECKEND
 * (Rueckmeldung 27.10.2026, "flüssig"): er liegt fest ueber dem Inhalt, der
 * unter ihm durchscrollt, und eine Truebung darunter muesste in jedem Bild
 * neu gerechnet werden. */
.chat-schwebt .chatknopf {
  position: fixed;
  z-index: 40;
  right: calc(var(--rand) + 8px);
  bottom: var(--chat-unten, calc(var(--rand) + 120px));
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 20px 0 14px;
  border: 1px solid var(--huelle-kante);
  border-radius: var(--radius-pille);
  background: var(--huelle-deckend);
  box-shadow: var(--karte-schatten);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  touch-action: none;
  transition:
    transform var(--zeit-kurz) var(--kurve-aus),
    box-shadow var(--zeit-kurz) var(--kurve-aus);
  animation: knopf-auf 320ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

.chat-schwebt .chatknopf:hover {
  transform: translateY(-2px);
  box-shadow: var(--karte-schatten);
}

/* VERSCHOBEN steht er, wo man ihn hingezogen hat (Rueckmeldung
 * 05.10.2026; chatfenster.js setzt `data-knopf` und die Lage). Beim
 * Ziehen haelt er still: kein Heben, kein Uebergang - die Hand fuehrt. */
.chat-schwebt[data-knopf="frei"] .chatknopf {
  top: var(--knopf-y);
  right: auto;
  bottom: auto;
  left: var(--knopf-x);
}

.knopf-zieht .chatknopf,
.knopf-zieht .chatknopf:hover {
  cursor: grabbing;
  transform: none;
  transition: none;
}

/* Fuer die Messung, aus welcher Richtung das Fenster kommt und wohin es
 * geht: einen Augenblick da, aber unsichtbar und ohne Einblendung. */
.chat-schwebt.knopf-messen .chatknopf {
  display: inline-flex;
  visibility: hidden;
  animation: none;
}

.chatknopf .marke-zeichen {
  --zeichen: 22px;
}

/* Wartet eine Frage, waehrend das Fenster zu ist, pulsiert ein Punkt. */
.chatknopf-punkt {
  display: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--akzent-knopf);
  box-shadow: 0 0 10px var(--punkt-schein);
  animation: dienst-puls 1.4s ease-in-out infinite;
}

.arbeitsbereich:has(#chat-bereich[data-stand="wartet"]) .chatknopf-punkt {
  display: block;
}

/* Offen, geteilt oder gross: das Fenster ist da, der Knopf nicht. */
[data-chatfenster] .chatknopf {
  display: none;
}

/* Der Knopf ploppt auf - auch dort, wo eben das Fenster hineingesaugt
 * wurde: es wird zum Knopf. */
@keyframes knopf-auf {
  from {
    opacity: 0;
    transform: scale(0.6);
  }
}

/* --- Das Fenster ------------------------------------------------------ */

/* MINDESTENS 420 PX HOCH (chatfenster.js klemmt genauso): der Fuss mit
 * Vorschlaegen, Feld und Hinweis braucht schmal gut 180 px, und darueber
 * soll noch ein Stueck Gespraech zu lesen sein. Bei 340 px blieben ihm
 * rund 100. */
.chat-schwebt .chatfenster {
  container: chat / inline-size;
  position: fixed;
  z-index: 45;
  left: var(--chat-x, auto);
  top: var(--chat-y, auto);
  width: var(--chat-b, 420px);
  height: var(--chat-h, 560px);
  min-width: 320px;
  min-height: min(420px, calc(100vh - 2 * var(--rand)));
  max-width: calc(100vw - 2 * var(--rand));
  max-height: calc(100vh - 2 * var(--rand));
  display: none;
  flex-direction: column;
  margin: 0;
  padding: 0;
  overflow: hidden;
  resize: both;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-gross);
  background: var(--flaeche);
  box-shadow:
    inset 0 1px 0 var(--huelle-glanz),
    0 8px 24px -12px var(--schatten-hoch-farbe),
    0 36px 90px -30px var(--schatten-hoch-farbe);
}

/* Ohne Bewegung, wenn es schon offen war (Seitenwechsel, Neuladen);
 * bewegt wird es nur, wenn jemand es oeffnet oder schliesst (unten). */
.chat-schwebt[data-chatfenster] .chatfenster {
  display: flex;
}

/* DIE TITELLEISTE: Griff zum Ziehen, Doppelklick vergroessert (wie am
 * Mac). Gezogen wird erst ab vier Pixeln Weg (chatfenster.js) - ein Klick,
 * der den Knopf knapp verfehlt, verschiebt nichts. */
.chat-schwebt .chatfenster-kopf {
  flex: none;
  flex-wrap: nowrap;
  gap: 12px;
  min-height: 50px;
  margin: 0;
  padding: 0 10px 0 16px;
  border-bottom: 1px solid var(--linie);
  background: var(--flaeche-zart);
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.chat-zieht .chatfenster-kopf {
  cursor: grabbing;
}

/* Der Titel kuerzt nie; was nicht passt, kuerzt der Satz daneben. */
.chat-schwebt .chatfenster-kopf h2 {
  flex: none;
  font-size: 14px;
  white-space: nowrap;
}

.chat-schwebt .chatfenster-satz {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* DIE DREI KNOEPFE in der Art von macOS: Schliessen, Minimieren,
 * Vergroessern. Grau, solange das Fenster nicht vorn ist; farbig, sobald
 * der Zeiger darauf liegt oder der Fokus darin steht. Das Zeichen im
 * Knopf zeigt sich erst beim Darueberfahren, wie am Mac.
 *
 * DIE TREFFERFLAECHE IST GROESSER ALS DER PUNKT (Rueckmeldung 05.10.2026:
 * schwer zu treffen): jeder Knopf fasst 26 x 30 px - die Punkte stehen so
 * dicht, dass sich die Flaechen beruehren, aber nicht ueberdecken. Ueber
 * dem ganzen Feld der drei Knoepfe zieht der Zeiger nicht. */
.chat-schwebt .ampel {
  display: flex;
  flex: none;
  align-items: center;
  gap: 0;
  margin: 0 2px 0 -6px;
  cursor: default;
}

.ampel-knopf {
  position: relative;
  display: grid;
  place-items: center;
  width: 26px;
  height: 30px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ampel-zeichen);
  cursor: pointer;
}

.ampel-knopf::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--linie-stark);
  translate: -50% -50%;
  transition: background-color var(--zeit-kurz) var(--kurve-aus);
}

/* Das Zeichen ist 9 px klein; der Strich des Zeichensatzes (1,8 von 24)
 * waere darin ein Haar. */
.ampel-knopf .zeichen {
  position: relative;
  opacity: 0;
  stroke-width: 3.4;
}

.chatfenster:hover .ampel-zu::before,
.chatfenster:focus-within .ampel-zu::before {
  background: var(--ampel-rot);
}

.chatfenster:hover .ampel-klein::before,
.chatfenster:focus-within .ampel-klein::before {
  background: var(--ampel-gelb);
}

.chatfenster:hover .ampel-gross::before,
.chatfenster:focus-within .ampel-gross::before {
  background: var(--ampel-gruen);
}

.ampel:hover .zeichen,
.ampel-knopf:focus-visible .zeichen {
  opacity: 1;
}

.ampel-knopf:focus-visible {
  outline-offset: -2px;
  box-shadow: none;
}

/* Rechts in der Leiste: neben den Vorgang stellen bzw. wieder loesen. */
.chat-schwebt .fensterknopf {
  display: grid;
  flex: none;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-left: auto;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: none;
  color: var(--text-zweit);
  cursor: pointer;
}

.chat-schwebt .fensterknopf:hover,
.fensterknopf[aria-pressed="true"] {
  border-color: var(--akzent-kante);
  background: var(--akzent-flaeche);
  color: var(--akzent-text);
}

/* DER INHALT SCROLLT, die Titelleiste nicht. Unten klebt der Fuss
 * (Vorschlaege, Eingabefeld, Hinweis), deckend und mit Haarlinie: das
 * Gespraech laeuft darunter weg, das Eingabefeld behaelt seine Kante.
 * Vorher deckte eine Flaeche UEBER dem Feld dessen Rand ab - man sah das
 * Feld nicht (Rueckmeldung 05.10.2026). */
.chat-schwebt .chatfenster-rumpf {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 18px 16px 0;
  scrollbar-width: thin;
}

.chat-schwebt .chatfenster .chatbereich {
  flex: 1 0 auto;
}

.chat-schwebt .chatfenster .chatverlauf,
.chat-schwebt .chatfenster .chatleer {
  flex: 1 0 auto;
}

.chat-schwebt .chatfenster .chatfuss {
  position: sticky;
  bottom: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0 -16px;
  padding: 12px 16px;
  border-top: 1px solid var(--linie);
  background: var(--flaeche);
}

/* DIE VORSCHLAEGE ALS EINE REIHE, die sich seitlich schieben laesst: im
 * Fenster nehmen sie sonst dem Gespraech die halbe Hoehe. */
.chat-schwebt .chatfenster .chatvorschlaege {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.chat-schwebt .chatfenster .chatchip {
  flex: none;
  white-space: nowrap;
}

.chat-schwebt .chatfenster .chathinweis {
  font-size: 11.5px;
}

/* Schmal (das Fenster, nicht der Browser): kein Untertitel, die Frage
 * breiter, der Sendeknopf nur als Pfeil. Der Platz des Absenders bleibt
 * auch hier an jeder Antwort: fiele er an aelteren weg, spraenge die
 * vorige Antwort beim Absenden nach links, sobald das Zeichen zur neuen
 * Frage wandert (Rueckmeldung 05.10.2026: „flackert"). */
@container chat (max-width: 460px) {
  .chatfenster-satz {
    display: none;
  }

  .chatfrage {
    max-width: 90%;
  }

  .chatsenden > span {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .chatsenden {
    width: 40px;
    padding: 0;
    justify-content: center;
  }
}

/* Breit (vergroessert oder weit aufgezogen): das Gespraech in einer
 * lesbaren Spalte, die Vorschlaege duerfen wieder umbrechen. */
@container chat (min-width: 760px) {
  .chatbereich {
    width: min(100%, 780px);
    margin-inline: auto;
  }

  .chatvorschlaege {
    flex-wrap: wrap;
    overflow-x: visible;
  }
}

/* OEFFNEN UND SCHLIESSEN: weich, ohne Kunststueck (Rueckmeldung
 * 05.10.2026, letzte Runde: das Einsaugen war „zu kompliziert", gewuenscht
 * ist „einfach ein schoener Uebergang"). Beim Oeffnen waechst das Fenster
 * in 340 ms aus der Ecke, die dem Knopf am naechsten liegt, und blendet
 * dabei auf; beim Schliessen und Minimieren zieht es sich in 200 ms dorthin
 * zurueck und blendet aus, danach ploppt der Knopf auf. Den Ursprung misst
 * chatfenster.js (`--ursprung-x`, `--ursprung-y`) - auch fuer einen
 * verschobenen Knopf. Nur Deckkraft und Masstab, nichts wird beschnitten.
 * Die Regeln tragen `[data-chatfenster]`, damit sie auch das geteilte
 * Fenster treffen (dort steht sonst `animation: none`). */
.chat-schwebt[data-chatfenster] .chatfenster.fenster-kommt {
  transform-origin: var(--ursprung-x, 100%) var(--ursprung-y, 100%);
  animation: fenster-oeffnen 340ms cubic-bezier(0.16, 1, 0.3, 1);
}

.chat-schwebt[data-chatfenster] .chatfenster.fenster-geht {
  transform-origin: var(--ursprung-x, 100%) var(--ursprung-y, 100%);
  animation: fenster-schliessen 200ms cubic-bezier(0.4, 0, 1, 1) forwards;
  pointer-events: none;
}

@keyframes fenster-oeffnen {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.92);
  }
}

@keyframes fenster-schliessen {
  to {
    opacity: 0;
    transform: translateY(8px) scale(0.92);
  }
}

/* --- Geteilt: rechts die KI, links der Vorgang ------------------------- */

.chat-schwebt[data-chatfenster="geteilt"] .rahmen:has(.chatfenster) {
  padding-right: calc(var(--chat-teil, 420px) + 2 * var(--rand));
}

.chat-schwebt[data-chatfenster="geteilt"] .chatfenster {
  top: var(--rand);
  right: var(--rand);
  bottom: var(--rand);
  left: auto;
  width: var(--chat-teil, 420px);
  height: auto;
  max-height: none;
  resize: none;
  border-radius: var(--radius-karte);
  animation: none;
}

/* DIE KANTE ZWISCHEN BEIDEN: ziehen aendert die Breite der KI. */
.chat-schwebt[data-chatfenster="geteilt"] .chatfenster-kante {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 2;
  display: block;
  width: 10px;
  cursor: col-resize;
  touch-action: none;
}

.chat-schwebt[data-chatfenster="geteilt"] .chatfenster-kante:hover,
.chat-kante-zieht .chatfenster-kante {
  background: linear-gradient(90deg, var(--akzent-kante), transparent);
}

/* Neben der KI ist fuer Original und Positionen nebeneinander zu wenig
 * Platz - sie stehen untereinander, bis das Fenster sehr breit ist. Wird
 * es auch dafuer zu schmal, scrollt die Positionstabelle in ihrem Rahmen
 * seitwaerts (`.positionsrahmen`). */
@media (max-width: 1799px) {
  .chat-schwebt[data-chatfenster="geteilt"] .freigabe {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* DIE VORSCHAU BEIM ZIEHEN an den rechten Rand: so wird es stehen. */
.chat-schwebt .andockvorschau {
  position: fixed;
  z-index: 44;
  top: var(--rand);
  right: var(--rand);
  bottom: var(--rand);
  display: block;
  width: var(--chat-teil, 420px);
  border: 2px solid var(--akzent-kante);
  border-radius: var(--radius-karte);
  background: var(--huelle);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--zeit-kurz) var(--kurve-aus);
}

.chat-andocken .andockvorschau {
  opacity: 1;
}

/* --- Gross: ueber den ganzen Inhalt, die Leiste bleibt ------------------ */

.chat-schwebt[data-chatfenster="gross"] .chatfenster {
  top: var(--rand);
  right: var(--rand);
  bottom: var(--rand);
  left: calc(var(--leistenbreite) + 2 * var(--rand));
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  resize: none;
  border-radius: var(--radius-karte);
}

/* --- Auf dem Telefon: jedes offene Fenster fuellt den Schirm ---------- */

@media (max-width: 40em) {
  .chat-schwebt .chatknopf {
    bottom: calc(var(--rand) + 8px);
  }

  .chat-schwebt .chatknopf-wort {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .chat-schwebt .chatknopf {
    padding: 0 14px;
  }

  /* Die Entscheidungsleiste steht hier am Ende der Seite und nicht
   * klebend; ohne Luft darunter laege der Knopf am Seitenende auf
   * „Freigeben". So scrollt sie ueber ihn hinaus. */
  .chat-schwebt .rahmen:has(.chatknopf) {
    padding-bottom: calc(var(--rand) + 80px);
  }

  .chat-schwebt[data-chatfenster] .chatfenster {
    inset: 8px;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    resize: none;
  }

  .chat-schwebt[data-chatfenster="geteilt"] .rahmen:has(.chatfenster) {
    padding-right: var(--rand);
  }

  .chat-schwebt .fensterknopf,
  .chat-schwebt .ampel-gross {
    display: none;
  }
}

/* FIRMENWISSEN (Einarbeitung 06.10., Block C): die Eintraege eines Hauses als Liste in einer
 * deckenden Karte, jeder mit Haarlinie dazwischen. Der Text behaelt seine Zeilenumbrueche
 * (reiner Text, keine Formatierung) und bricht lange Woerter, statt die Seite zu verbreitern. */
.firmenwissen-liste {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.firmenwissen-eintrag {
  padding: 14px 0;
  border-top: 1px solid var(--linie);
}

.firmenwissen-eintrag h3 {
  margin: 0;
  font-size: 1rem;
}

.firmenwissen-text {
  margin: 6px 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
