/* ============================================================================
   glass.css — Liquid-Glass DESIGN-TOKENS (Single Source of Truth)
   Plan 37 / Stufe 4 Runde 1 · BP-1 (Tokens-Ebene, additiv NEBEN hlidskjalf.css).

   Diese Datei ist AUSSCHLIESSLICH die Tokens-Ebene: `:root` (light) + die
   `[data-theme="dark"]`-Spiegelung. Komponenten-Stile (Sidebar, Content-Karte,
   Nav, Tabellen …) folgen in BP-3/BP-4 in templates/glass/* und referenzieren
   NUR diese Custom Properties. Keine Hartcodierung von Farben/Abstaenden/Radien/
   Typo ausserhalb der Token-Bloecke — Marke NUR aus --brand-primary/--brand-accent,
   alle Ableitungen via color-mix(). Dark = gespiegelte Tokens im SELBEN System.

   Deckungsgleich mit:
     - Referenz-Mockup id 6 (plan 34, dashboard-liquid-glass) Z.14-74
     - Vorlage `liquid-glass` §2 (vorlage:1, active v2)

   ----------------------------------------------------------------------------
   A10 — VORLAGE-DRIFT-STEMPEL (maschinenlesbar, KEIN Marken-String).
   Der folgende Pin traegt den content_hash der vorlage:1-active-Version, gegen
   den zur Bauzeit die Token-Werte destilliert wurden. Ein KONKRETER Drift-Test
   (backend/tests/test_glass_tokens.py::test_vorlage_pin_matches_active_hash)
   liest diesen Pin und vergleicht ihn gegen die LIVE Asgard-API
   (GET /v1/vorlagen/1 -> active version content_hash) und SCHLAEGT FEHL bei
   Mismatch. Bei einer Vorlage-Aktualisierung: Tokens neu abgleichen, dann diesen
   Pin auf den neuen active-hash setzen.

   @vorlage-pin vorlage:1 active content_hash sha256:a0f2a2dd036e504c1a6a73590028fa591f6c05c96a3fc986d41f68f186f1682a
   ========================================================================== */

:root{
  /* -- Marke (im Umbau aus White-Label injiziert; hier fixe Demo-Marke) -- */
  --brand-primary:#2563eb;
  --brand-accent:#1d4ed8;
  --brand-primary-soft:color-mix(in srgb, var(--brand-primary) 12%, transparent);
  --brand-primary-tint:color-mix(in srgb, var(--brand-primary) 8%, white);
  --brand-gradient:linear-gradient(180deg, var(--brand-primary), var(--brand-accent));

  /* -- Neutrale Ink-Skala (Text/Linien) --
     A18 (BP-8, journal 349): ink-300/ink-400 gegen den Vorlage-§2-Beispiel-Hex (#a7a7b2/#84848f)
     ABGEDUNKELT bis >= 4.5:1 Normaltext-Kontrast auf dem Worst-Case-Glas (Opazitaets-Boden .55
     ueber dem dunkelsten gesampelten Ambient (194,210,243) -> bg (228,235,250)). Bewusster Drift
     zu §2 (§5-DoD AA hat Vorrang, Vorlagen-Anwende-Doktrin); Messwerte: ink-300 4.66:1,
     ink-400 4.95:1. */
  --ink-900:#0b0b0f; --ink-700:#2b2b31; --ink-500:#5b5b66;
  --ink-400:#63636d; --ink-300:#676771;
  --line:rgba(20,20,30,.08);

  /* -- Status (Rot NUR fuer echte Gefahr) -- */
  --ok:#059669; --warn:#b45309; --danger:#dc2626;
  --ok-soft:color-mix(in srgb, var(--ok) 14%, transparent);
  --danger-soft:color-mix(in srgb, var(--danger) 14%, transparent);

  /* -- A18 (BP-8 + Vollsweep) AA-Text-Varianten: Brand/OK/Warn/Danger als KLEINER Text auf Glas.
     --brand-primary/--ok/--warn/--danger bleiben die vividen Flaechen-/Fuell-/Rand-Farben (aktive
     Nav auf WEISS 5.17:1, Fortschritt, Chrome, Badge-Raender, *-soft-Banner-Fuellungen). Sitzt eine
     Marken-/Statusfarbe dagegen als Normaltext AUF Glas — und besonders auf ihrem eigenen -soft-
     GETOENTEN Glas (Banner/Pill) —, verlangt AA >= 4.5:1. Diese Varianten sind gegen den WORST-CASE
     (Ton ueber Glas am Opazitaets-Boden) gepruft: brand-text 4.91:1 (auf brand-soft), ok-text
     5.33:1 (auf ok-soft), warn-text 5.23:1 (auf warn-soft), danger-text 5.08:1 (auf danger-soft).
     --on-danger = Vordergrund AUF einem SOLIDEN --danger-Button (Light: weiss, 4.83:1). --focus-ring
     = Fokus-INDIKATOR (Non-Text >= 3:1); Light = Marke, Dark aufgehellt (siehe [data-theme=dark]). */
  --brand-text:#1b4fce;
  --ok-text:#05623e;
  --warn-text:#8a3f07;
  --danger-text:#a81717;
  --on-danger:white;
  --focus-ring:var(--brand-primary);

  /* -- Glas-Ebene (nur Nav-/Steuerebene) -- */
  --glass-bg:rgba(255,255,255,.55);
  --glass-bg-strong:rgba(255,255,255,.72);
  --glass-brd:rgba(255,255,255,.65);
  --glass-blur:blur(30px) saturate(1.8);
  --glass-shadow:0 20px 50px -20px rgba(20,25,60,.35), 0 4px 12px -6px rgba(20,25,60,.18);
  --track:rgba(20,20,30,.08);

  /* -- Ambient-Hintergrund (§2.5) -- */
  --amb-base:#eef1f6;
  --amb-c1:color-mix(in srgb, var(--brand-primary) 22%, transparent);
  --amb-c2:color-mix(in srgb, var(--brand-accent) 16%, transparent);
  --amb-c3:rgba(255,255,255,.7);

  /* -- Radien / Raster / Typo (§2.4) -- */
  --radius:22px; --radius-sm:14px; --radius-xs:11px;
  --font:-apple-system,BlinkMacSystemFont,"SF Pro Text","Inter","Segoe UI",Roboto,sans-serif;

  /* -- 4-px-Raster (Vorlage §2.4) -- */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s8:32px;

  /* ------------------------------------------------------------------------
     A9 — GLAS-PANEL-OPAZITAETS-BODEN (BUILD-Anteil, Voraussetzung Stage-6-WCAG).
     Untergrenze der Deckkraft JEDES text-tragenden Glas-Panels. Kein Glas-BG-
     Token, unter dem Text sitzt, darf eine kleinere Alpha haben als dieser Boden;
     der Invariant-Test erzwingt das. Zusammen mit dem @supports-Fallback unten
     (voll deckende Unterlage, wenn backdrop-filter fehlt) sitzt Text nie auf
     purem backdrop-filter ohne kontrastsichere Unterlage.
     ---------------------------------------------------------------------- */
  --glass-opacity-floor:.55;
}

/* -- Dark: gespiegelte Tokens, invertierte Ink, dunkle Glas-Werte -- */
[data-theme="dark"]{
  /* A18 (BP-8 + Vollsweep): ink-300 gegen §2-Beispiel-Hex (#5c5e6d) AUFGEHELLT bis >= 4.5:1 auf dem
     Worst-Case-Dunkelglas (Boden .55 ueber dem hellsten gesampelten Ambient (22,48,106) -> bg
     (28,40,74)); ink-300 4.57:1. ink-400 (§2 #7f8191, 3.75:1 am strengen Boden) aufgehellt auf
     #9a9cac (5.31:1) — stellt zugleich die monotone Reihenfolge ink-300 < ink-400 < ink-500 wieder
     her (behebt die BP-8-Skalen-Kompression). */
  --ink-900:#f4f5f8; --ink-700:#d5d7e0; --ink-500:#a2a4b3;
  --ink-400:#9a9cac; --ink-300:#8e90a0;
  --line:rgba(255,255,255,.10);

  --ok:#34d399; --warn:#fbbf24; --danger:#f87171;
  --ok-soft:color-mix(in srgb, var(--ok) 18%, transparent);
  --danger-soft:color-mix(in srgb, var(--danger) 20%, transparent);

  /* A18 AA-Text-Varianten (dunkles Glas): brand-text aufgehellt (5.14:1 auf brand-soft); ok-text =
     vivides #34d399 (5.19:1 auf ok-soft); warn-text = #fbbf24 (warn ist in Dark schon AA, 5.88:1 auf
     warn-soft); danger-text aufgehellt auf #fb8a8a (4.70:1 auf danger-soft20). --on-danger = dunkler
     Vordergrund auf dem SOLIDEN Dark-Danger-Button #f87171 (weiss waere nur 2.77:1; #2b0808 = 6.65:1).
     focus-ring aufgehellt bis >= 3:1 Non-Text (Dark-Fokusring war 2.92:1); 5.26:1. */
  --brand-text:#7aa2f7;
  --ok-text:#34d399;
  --warn-text:#fbbf24;
  --danger-text:#fb8a8a;
  --on-danger:#2b0808;
  --focus-ring:#6f9bf2;

  --glass-bg:rgba(32,34,48,.55);
  --glass-bg-strong:rgba(26,28,40,.68);
  --glass-brd:rgba(255,255,255,.14);
  --glass-shadow:0 24px 60px -20px rgba(0,0,0,.6), 0 4px 14px -6px rgba(0,0,0,.5);
  --track:rgba(255,255,255,.10);

  --amb-base:#0c0e16;
  --amb-c1:color-mix(in srgb, var(--brand-primary) 40%, transparent);
  --amb-c2:color-mix(in srgb, var(--brand-accent) 34%, transparent);
  --amb-c3:rgba(90,120,200,.20);
}

/* ============================================================================
   W1 (P11) + A9 — DECKENDE FALLBACK-UNTERLAGE ohne backdrop-filter.
   Fehlt backdrop-filter, gibt es keine Blur-Unterlage: die Glas-BG-Token werden
   auf VOLL DECKENDE Werte umdefiniert, damit Text stets auf einer kontrast-
   sicheren Unterlage sitzt (A9). Diese Werte sind AUSSCHLIESSLICH aus --amb-base
   via color-mix() abgeleitet — KEIN Farb-Hardcode (die Mockup-Dark-Hardcodes
   #191b28 / #15171f werden bewusst NICHT uebernommen). Nur die BG-Token werden
   angefasst; Blur/Schatten/Rand bleiben unveraendert.
   ========================================================================== */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  :root{
    --glass-bg:color-mix(in srgb, var(--amb-base) 12%, white);
    --glass-bg-strong:color-mix(in srgb, var(--amb-base) 6%, white);
  }
  [data-theme="dark"]{
    --glass-bg:color-mix(in srgb, var(--amb-base) 95%, white);
    --glass-bg-strong:color-mix(in srgb, var(--amb-base) 96%, white);
  }
}

/* ============================================================================
   P3 (Loki L1) — JS-FREIER Default-Theme via prefers-color-scheme (Plan 37 BP-3).
   Ohne JS (der manuelle Umschalter kommt erst in BP-5/glass.js) folgt das Token-
   Set der OS-Praeferenz: bei `dark` werden die [data-theme="dark"]-Werte auf :root
   gespiegelt, damit die Seite bei DEAKTIVIERTEM JS lesbar UND themengerecht
   gestylt bleibt (ein JS-Fehler kann die Seite nie ungestylt/unlesbar machen).
   BP-5 realisiert die angekuendigte "nachgelagerte Regel": der Umschalter setzt
   data-theme explizit auf <html>, und dieser Media-Block ist auf
   `:root:not([data-theme])` verengt — die OS-Praeferenz greift also NUR solange
   keine explizite Wahl gesetzt ist. So gewinnt eine ausdrueckliche Hell-Wahl auch
   auf einem Dark-OS (sonst ueberschriebe dieser Block das :root-Hell). A11-konform:
   die Farb-Literale stehen ausschliesslich im `:root`-basierten Token-Selektor.
   ========================================================================== */
@media (prefers-color-scheme: dark){
  :root:not([data-theme]){
    /* A18 (BP-8): spiegelt die AA-Haertung des [data-theme=dark]-Blocks fuer den OS-Dark-Default
       (kein explizites data-theme) — sonst griffe hier der dunkle §2-Hex/der Light-brand-text. */
    --ink-900:#f4f5f8; --ink-700:#d5d7e0; --ink-500:#a2a4b3;
    --ink-400:#9a9cac; --ink-300:#8e90a0;
    --line:rgba(255,255,255,.10);

    --ok:#34d399; --warn:#fbbf24; --danger:#f87171;
    --ok-soft:color-mix(in srgb, var(--ok) 18%, transparent);
    --danger-soft:color-mix(in srgb, var(--danger) 20%, transparent);

    --brand-text:#7aa2f7;
    --ok-text:#34d399;
    --warn-text:#fbbf24;
    --danger-text:#fb8a8a;
    --on-danger:#2b0808;
    --focus-ring:#6f9bf2;

    --glass-bg:rgba(32,34,48,.55);
    --glass-bg-strong:rgba(26,28,40,.68);
    --glass-brd:rgba(255,255,255,.14);
    --glass-shadow:0 24px 60px -20px rgba(0,0,0,.6), 0 4px 14px -6px rgba(0,0,0,.5);
    --track:rgba(255,255,255,.10);

    --amb-base:#0c0e16;
    --amb-c1:color-mix(in srgb, var(--brand-primary) 40%, transparent);
    --amb-c2:color-mix(in srgb, var(--brand-accent) 34%, transparent);
    --amb-c3:rgba(90,120,200,.20);
  }
}
/* A9/W1 fuer den JS-freien Dark-Default OHNE backdrop-filter: voll deckende
   Unterlage aus --amb-base (kein Text auf halbtransparentem Glas ohne Blur). */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  @media (prefers-color-scheme: dark){
    :root:not([data-theme]){
      --glass-bg:color-mix(in srgb, var(--amb-base) 95%, white);
      --glass-bg-strong:color-mix(in srgb, var(--amb-base) 96%, white);
    }
  }
}

/* ============================================================================
   Glas-SHELL — Basis-Komponenten des glass/base.html-Geruests (Plan 37 BP-3).
   NUR Custom-Property-Referenzen + color-mix() (KEINE Farb-Literale ausserhalb
   der Token-Bloecke, A11). Hier steht ausschliesslich die Shell (Body/Ambient/
   Masthead/Nav/Konto/Content-Karte/Banner) + die Durchstich-Tabelle (lagebrett);
   der Per-View-Reskin (Buttons/Formulare/dichte Daten/Zustaende) folgt in BP-4.
   ========================================================================== */
*{ box-sizing:border-box; }
body{
  margin:0;
  font-family:var(--font);
  color:var(--ink-900);
  background:var(--amb-base);
  min-height:100vh;
}
/* ---------------------------------------------------------------------------
   BP-3b — Ambient-Verlauf hinter dem Glas (Vorlage §2.5). Fixiert, z-index:-1 hinter
   allem; NUR Token-/color-mix()-Referenzen (A11). Kein Vorfahr von .content (Sibling).
   --------------------------------------------------------------------------- */
.ambient{
  position:fixed; inset:0; z-index:-1; background:var(--amb-base);
  background-image:
    radial-gradient(60% 55% at 18% 12%, var(--amb-c1), transparent 60%),
    radial-gradient(52% 50% at 88% 22%, var(--amb-c2), transparent 62%),
    radial-gradient(46% 44% at 66% 96%, var(--amb-c3), transparent 60%);
}

/* ---------------------------------------------------------------------------
   BP-3b — Schwebende einklappbare Glas-SIDEBAR (K-G2/§4.1, Operator-Entscheid).
   L3 (Loki): dies ist das EINZIGE position:fixed-Glas-Panel — der backdrop-filter
   sitzt auf ihm SELBST (fixiert) und auf den Blatt-Flaechen (Sektionen/Dialoge/
   Konto-Popover), NIE auf einem Vorfahren der Content-Karte. Damit entsteht ueber
   dem Content-Teilbaum KEIN backdrop-filter-Containing-Block, der position:fixed-
   Nachfahren (Modals/Popover/Sticky) einfaengt; solche fliehen korrekt zum Viewport.
   Der Content scrollt unabhaengig (Body-Scroll) — die fixierte Sidebar bleibt stehen.
   --------------------------------------------------------------------------- */
.sidebar{
  position:fixed; left:var(--s4); top:var(--s4); bottom:var(--s4); z-index:30;
  width:248px; display:flex; flex-direction:column;
  padding:var(--s4); border-radius:var(--radius);
  background:var(--glass-bg); border:1px solid var(--glass-brd);
  box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
}

/* Brand-Block oben (Logo-Marke + Titel + Nav-Collapse). */
.brand{ display:flex; align-items:center; gap:var(--s3); padding:var(--s1) var(--s1) var(--s4); }
.brand-logo{
  width:38px; height:38px; flex:0 0 38px; border-radius:var(--radius-xs);
  background:var(--brand-gradient); color:white; display:grid; place-items:center;
}
.brand-text{ display:flex; flex-direction:column; min-width:0; }
.brand-name{ font-weight:700; letter-spacing:-.2px; }
.brand-sub{
  color:var(--ink-300); font-size:.7em; font-weight:600; text-transform:uppercase;
  letter-spacing:.06em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* Hauptnavigation — vertikal; scrollt bei Bedarf (die 12 Ziele passen sonst nicht in
   die volle Hoehe), waehrend Brand oben und Konto/Theme unten stehen bleiben. */
.mainnav{
  display:flex; flex-direction:column; gap:var(--s1);
  flex:1 1 auto; min-height:0; overflow-y:auto; overflow-x:hidden;
  margin:0 calc(-1 * var(--s1)); padding:0 var(--s1);
}
.mainnav a{
  display:flex; align-items:center; gap:var(--s3);
  padding:var(--s2) var(--s3); border-radius:var(--radius-xs);
  color:var(--ink-700); text-decoration:none; font-weight:550; white-space:nowrap;
}
.mainnav a .nav-ico{ flex:0 0 19px; color:var(--ink-400); }
.mainnav a:hover{ background:var(--glass-bg); color:var(--ink-900); }
.mainnav a:hover .nav-ico{ color:var(--ink-700); }
/* Aktives Item = weisse/Marken-Flaeche (Mockup id 6). `white` ist ein Keyword, kein
   Farb-Literal (A11); der Schatten kommt aus dem Token. */
.mainnav a.active{ background:white; color:var(--brand-primary); box-shadow:var(--glass-shadow); }
.mainnav a.active .nav-ico{ color:var(--brand-primary); }

/* Sidebar-Fuss: Theme-Umschalter + Konto-Popover. */
.sidebar-foot{ display:flex; flex-direction:column; gap:var(--s2); margin-top:var(--s3); }

/* Konto-Popover (native <details>, JS-frei) — oeffnet nach OBEN ueber der Konto-Leiste,
   verankert an der fixierten Sidebar (position:absolute, NICHT fixed -> kein neuer CB-Bedarf). */
.account{ position:relative; }
.account > summary{
  display:flex; align-items:center; gap:var(--s3); cursor:pointer; list-style:none;
  padding:var(--s2); border-radius:var(--radius-sm);
  border:1px solid var(--line); background:color-mix(in srgb, var(--glass-brd) 30%, transparent);
}
.account > summary::-webkit-details-marker{ display:none; }
.account .avatar{
  width:32px; height:32px; flex:0 0 32px; border-radius:50%;
  background:var(--brand-gradient); color:white; display:grid; place-items:center;
}
.account-who{ display:flex; flex-direction:column; min-width:0; }
.account-who b{ font-size:.82em; font-weight:650; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.account-who span{ font-size:.72em; color:var(--ink-400); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.account .chevron{ margin-left:auto; color:var(--ink-400); transition:transform .18s ease; }
.account[open] .chevron{ transform:rotate(180deg); }
.account-panel{
  position:absolute; left:0; right:0; bottom:calc(100% + var(--s2)); z-index:10;
  display:flex; flex-direction:column; gap:var(--s1);
  padding:var(--s2); border-radius:var(--radius-sm);
  background:var(--glass-bg-strong); border:1px solid var(--glass-brd);
  box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
}
.account-panel .navlink{
  padding:var(--s2) var(--s3); border-radius:var(--radius-xs);
  color:var(--ink-700); text-decoration:none; font-size:.9em;
}
.account-panel .navlink:hover{ background:var(--glass-bg); color:var(--brand-text); }
.account-panel .navlink.active{ background:var(--brand-primary-soft); color:var(--brand-text); }
.logout-form{ margin:0; }
.account-panel .logout{
  font:inherit; cursor:pointer; width:100%; text-align:left;
  padding:var(--s2) var(--s3); border-radius:var(--radius-xs);
  border:1px solid var(--glass-brd); background:var(--glass-bg); color:var(--ink-700);
}
.account-panel .logout:hover{ border-color:var(--danger); color:var(--danger-text); }
/* M2/W1 — sichtbarer, markenkonsistenter Fokusring auf JEDEM interaktiven Element
   (Shell-Default; BP-4 belegt ihn per-View feiner nach). */
:focus-visible{ outline:2px solid var(--brand-primary); outline-offset:2px; }
/* A18 (BP-8, journal 349): in DARK erreicht der brand-primary-Fokusindikator vs Glas nur 2.92:1
   (< 3:1 Non-Text). Die BASIS-Regel oben bleibt --brand-primary (Light 4.31:1, unveraendert); in
   beiden Dunkel-Scopes wird NUR die Indikator-FARBE auf --focus-ring (5.26:1) gehoben. Der globale
   Outline hier; der Feld-Fokus-RAND (input/textarea/login) steht bei seiner Basis-Regel weiter
   unten (K-G10) — die hoehere Spezifitaet des [data-theme]-Scopes gewinnt unabhaengig von der
   Quellreihenfolge. */
[data-theme="dark"] :focus-visible{ outline-color:var(--focus-ring); }
@media (prefers-color-scheme: dark){
  :root:not([data-theme]) :focus-visible{ outline-color:var(--focus-ring); }
}
/* Content-Karte rechts NEBEN der fixierten Sidebar (Reflow). KEIN backdrop-filter/transform
   auf diesem Wrapper (L3) — die Glas-Flaechen sind die inneren <section>/Dialoge (Blaetter),
   sodass ein position:fixed-Nachfahre im Content NICHT gefangen wird. Body-Scroll = unabhaengig. */
.content{ margin-left:calc(248px + var(--s4) + var(--s4)); padding:var(--s6); min-height:100vh; }
.content > section{
  background:var(--glass-bg-strong);
  border:1px solid var(--glass-brd);
  border-radius:var(--radius);
  box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:var(--glass-blur);
  backdrop-filter:var(--glass-blur);
  padding:var(--s6);
}
.banner{ padding:var(--s3) var(--s4); border-radius:var(--radius-sm); margin-bottom:var(--s4); }
.banner-error{ background:var(--danger-soft); color:var(--danger-text); }
h1{ margin-top:0; }
.intro{ color:var(--ink-500); }
/* Plan 37 · IA-Folge-Quickfix 1a — dichte Tabellen bleiben in ihrer Content-Karte.
   Beleg des Ueberlaufs: Lagebrett-Tabelle 1035px in 1023px Innenraum. Ursache: das
   auto-Table-Layout blaeht Spalten am Inhalt (lange Plan-/Stage-Texte) auf, bis die
   Tabelle die Karte sprengt. `table-layout:fixed` bindet die Tabelle an width:100% ihres
   Containers (die Spalten teilen die Breite) -> sie ueberschreitet NIE die Karte, auf
   KEINER Glas-Innenseite; kein Seiten-/Karten-Horizontalscroll. Reine Layout-Eigenschaft,
   kein Farb-/Token-Eingriff (A11 unberuehrt). */
table.grid{ width:100%; border-collapse:collapse; table-layout:fixed; }
table.grid th, table.grid td{
  padding:var(--s2) var(--s3);
  border-bottom:1px solid var(--line);
  text-align:left;
  /* Lange Freitexte brechen IN der Zelle um statt sie zu sprengen (kein Ellipsis: die
     glass/-Templates sind gegen die ALT-Ebene byte-eingefroren — test_glass_views
     test_content_context_equal_alt_vs_glass -, ein `title=`-Attribut fuers volle Wort
     ist dort nicht ergaenzbar; Umbruch zeigt den vollen Text ohne Markup-Eingriff). */
  overflow-wrap:anywhere; word-break:break-word;
}
table.grid th{ color:var(--ink-500); font-weight:600; }
table.grid td.num{ text-align:right; font-variant-numeric:tabular-nums; }
/* routines ist die EINZIGE Grid-Tabelle mit Formular-/Steuerzellen (.ctl). Dort bleibt die
   inhaltsbasierte auto-Breite, damit die Arm-/Control-Formulare NICHT gestaucht werden
   (Usability, decision 0028). Ist :has() nicht verfuegbar, greift der harte Feld-Riegel
   unten und verhindert trotzdem jeden Ueberlauf. */
table.grid:has(.ctl){ table-layout:auto; }
/* Harter Riegel: ein Formularfeld ueberschreitet nie seine Zelle (faengt den :has-losen
   Fallback UND jede kuenftige Feld-in-Zelle ab). */
table.grid input, table.grid select, table.grid textarea{ max-width:100%; box-sizing:border-box; }
.bar{ width:120px; height:var(--s2); border:none; border-radius:var(--radius-xs); background:var(--track); }
.bar-label{ margin-left:var(--s2); color:var(--ink-500); font-size:.85em; }
.empty{ color:var(--ink-400); }

/* ============================================================================
   BP-4 — PER-VIEW KOMPONENTEN-EBENE (Plan 37 Stufe 4 Runde 1).
   Restyled ALLE erreichbaren Datenflaechen- + Direkt-Site-Views (templates/glass/*)
   auf denselben Klassen/ids wie die ALT-Vorlagen (mechanischer Reskin — kein neues
   Markup). NUR Custom-Property-/color-mix()-Referenzen + die Keywords white/black/
   transparent — KEINE Farb-Literale ausserhalb der Token-Bloecke (A11). Gliederung nach
   den verbindlichen Guidelines der Vorlage `liquid-glass` §3: Buttons (K-G9), Formulare
   (K-G10) + M2-Fokusring, dichte Daten (K-G11), Zustaende (K-G12), Vektor-Icons (K-G8).
   ========================================================================== */

/* -- Fliesstext-Links + Ueberschriften -------------------------------------
   A18 (BP-8): Content-Links sind Normaltext AUF Glas -> die AA-Text-Variante --brand-text
   (>= 4.5:1), nicht die vivide Flaechen-Marke --brand-primary. */
.content a{ color:var(--brand-text); text-decoration:none; }
.content a:hover{ text-decoration:underline; }
h2{ margin:var(--s5) 0 var(--s2); font-size:1.1em; }
.actions{ margin:var(--s3) 0; }
.note,.login-note{ color:var(--ink-500); font-size:.85em; margin-top:var(--s4); line-height:1.5; }

/* ---------------------------------------------------------------------------
   K-G9 — Buttons. Ghost-Grundstil fuer JEDEN Button/Aktionslink in der Content-
   Karte; die Haupt-Absende-Aktion einer Form wird zum Marken-Gradient-Primaerbutton;
   Danger-Aktionen tragen die Gefahr-Farbe (Rot NUR fuer echte Gefahr, §3.6).
   --------------------------------------------------------------------------- */
.content button,.content .navlink{
  font:inherit; cursor:pointer; line-height:1; display:inline-flex; align-items:center;
  gap:var(--s2); padding:var(--s2) var(--s4); border:1px solid var(--glass-brd);
  border-radius:var(--radius-xs); background:var(--glass-bg); color:var(--ink-700);
  text-decoration:none;
}
.content button:hover,.content .navlink:hover{ border-color:var(--brand-primary); color:var(--brand-text); }
.filters button[type="submit"],.write-form button[type="submit"],
.login-form button[type="submit"],.backup-form button[type="submit"],
.tokens-form button[type="submit"],.modal-actions button[type="submit"]{
  border:none; background:var(--brand-gradient); color:white; font-weight:600;
}
.modal-actions button[type="submit"]:hover{ color:white; filter:brightness(1.06); }
button.danger,.modal-actions button.danger,.ctl-btn.danger{
  border-color:color-mix(in srgb, var(--danger) 45%, transparent); color:var(--danger-text);
}
/* A18 (Vollsweep): SOLIDER Danger-Button — Vordergrund via --on-danger (Light weiss 4.83:1; Dark
   #f87171-Fuellung traegt weiss nur 2.77:1 -> dunkler Vordergrund 6.65:1). */
.modal-actions button.danger{ border:none; background:var(--danger); color:var(--on-danger); }
.ctl button{ padding:var(--s1) var(--s3); font-size:.85em; }
.ctl-btn{ padding:var(--s1) var(--s3); font-size:.85em; }
.icon-btn{ padding:var(--s2); justify-content:center; }
/* K-G8 — Vektor-Icons erben currentColor (0 Emoji); der Chevron dreht per aria-expanded. */
.chevron{ flex:none; color:var(--ink-400); transition:transform .18s ease; }
[aria-expanded="true"] .chevron{ transform:rotate(90deg); }

/* ---------------------------------------------------------------------------
   K-G10 — Formulare. Ein Feldstil (helle Glas-Unterlage, 1px Linie, Radius);
   Labels als eigene Zeile ueber dem Feld (kein schwebendes Material-Label). M2:
   Fokus = Marken-Rand + Soft-Ring (sichtbar auf JEDEM Feld; der globale
   :focus-visible-Outline oben deckt zusaetzlich alle uebrigen interaktiven Elemente).
   --------------------------------------------------------------------------- */
.filters{ display:flex; gap:var(--s4); align-items:flex-end; flex-wrap:wrap; margin-bottom:var(--s4); }
.filters label{ display:flex; flex-direction:column; gap:var(--s1); color:var(--ink-500); font-size:.85em; }
.write-form,.login-form,.tokens-form,.backup-form{ display:flex; flex-direction:column; gap:var(--s2); max-width:42rem; }
.write-form label,.login-form label,.tokens-form label,.backup-form label,.onboarding-fields label{
  display:flex; flex-direction:column; gap:var(--s1); color:var(--ink-500); font-size:.85em;
}
.pwchange{ max-width:26rem; }
.content input,.content select,.content textarea{
  font:inherit; color:var(--ink-900); padding:var(--s2) var(--s3);
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--glass-bg-strong) 82%, white);
}
.content textarea{ resize:vertical; }
/* A18 (Vollsweep): Placeholder NICHT dem Browser-Default (~54% von ink-900, kann < 4.5:1 fallen)
   ueberlassen — AA-festes --ink-500 (Light 5.59 / Dark 5.84:1 auf Worst-Case-Glas) mit voller
   Opazitaet. Felder tragen zusaetzlich echte Labels; der Placeholder ist nie der einzige Name. */
.content input::placeholder,.content textarea::placeholder{ color:var(--ink-500); opacity:1; }
.content input:focus-visible,.content select:focus-visible,.content textarea:focus-visible{
  outline:none; border-color:var(--brand-primary);
  box-shadow:0 0 0 var(--s1) var(--brand-primary-soft);
}
/* A18 (BP-8): in DARK ersetzt der Feld-Fokus den Outline durch den Marken-RAND — dieser Rand ist
   der Fokusindikator und muss >= 3:1 Non-Text halten; brand-primary vs Dunkelglas nur 2.92:1, also
   auf --focus-ring (5.26:1) gehoben. Die box-shadow-Glow (brand-primary-soft) bleibt dekorativ. */
[data-theme="dark"] .content input:focus-visible,
[data-theme="dark"] .content select:focus-visible,
[data-theme="dark"] .content textarea:focus-visible{ border-color:var(--focus-ring); }
@media (prefers-color-scheme: dark){
  :root:not([data-theme]) .content input:focus-visible,
  :root:not([data-theme]) .content select:focus-visible,
  :root:not([data-theme]) .content textarea:focus-visible{ border-color:var(--focus-ring); }
}
details summary{ cursor:pointer; }

/* ---------------------------------------------------------------------------
   K-G11 — Dichte Daten. Caption-Koepfe (uppercase), Zeilen-Hover, Chips/Pills,
   Fortschrittsbalken mit Marken-Fuellung, Baum/Timeline/Detail-Listen, KPI-Zeile.
   --------------------------------------------------------------------------- */
table.grid th{ text-transform:uppercase; font-size:.72em; letter-spacing:.04em; color:var(--ink-300); }
table.grid tbody tr:hover{ background:var(--glass-bg); }
/* Fortschritt: native <progress class="bar"> (BP-2) — Appearance reset + Marken-Fuellung. */
.bar{ -webkit-appearance:none; -moz-appearance:none; appearance:none; overflow:hidden; vertical-align:middle; }
.bar::-webkit-progress-bar{ background:var(--track); border-radius:var(--radius-xs); }
.bar::-webkit-progress-value{ background:var(--brand-gradient); border-radius:var(--radius-xs); }
.bar::-moz-progress-bar{ background:var(--brand-primary); border-radius:var(--radius-xs); }
.bar.overall{ width:16rem; height:var(--s3); }
.plan-overall{ display:flex; gap:var(--s3); align-items:center; flex-wrap:wrap; margin:var(--s2) 0 var(--s4); }
.step-owner{ color:var(--ink-400); font-size:.85em; }
.tree{ list-style:none; margin:var(--s2) 0; padding-left:0; }
.tree .tree{ margin:var(--s2) 0 var(--s2) var(--s5); padding-left:var(--s3); border-left:1px solid var(--line); }
.tree-node{ margin:var(--s2) 0; }
.tree-row{ display:flex; gap:var(--s2); align-items:baseline; flex-wrap:wrap; }
.tree-id{ color:var(--ink-400); font-size:.85em; }
.tree-title{ font-weight:600; }
.tree-body{ color:var(--ink-500); margin:var(--s1) 0; white-space:pre-wrap; }
.timeline{ list-style:none; margin:var(--s2) 0; padding-left:0; }
.timeline-entry{ display:flex; gap:var(--s3); align-items:baseline; flex-wrap:wrap; padding:var(--s2) 0; border-bottom:1px solid var(--line); }
.timeline-entry .ts{ color:var(--ink-400); font-size:.85em; font-variant-numeric:tabular-nums; white-space:nowrap; }
.entry-content{ white-space:pre-wrap; }
dl.detail{ display:grid; grid-template-columns:auto 1fr; gap:var(--s1) var(--s4); margin:var(--s3) 0; }
dl.detail dt{ color:var(--ink-500); font-weight:600; }
dl.detail dd{ margin:0; }
article.entry-body{ white-space:pre-wrap; word-break:break-word; line-height:1.6; margin:var(--s3) 0; }
pre.vorlage-body{
  white-space:pre-wrap; word-break:break-word; background:var(--glass-bg-strong);
  border:1px solid var(--line); border-radius:var(--radius-sm); padding:var(--s4);
  margin:var(--s2) 0 var(--s4); font-family:inherit; line-height:1.5; overflow-x:auto;
}
.breadcrumb{ display:flex; gap:var(--s2); align-items:center; flex-wrap:wrap; margin:var(--s3) 0; color:var(--ink-500); }
.breadcrumb .sep{ color:var(--ink-300); }
.breadcrumb .crumb-current{ font-weight:600; color:var(--ink-700); }

/* Chips / Pills / Badges (dichte Auszeichnungen). */
.pill,.badge,.status-badge{
  display:inline-block; padding:var(--s1) var(--s3); border-radius:999px;
  font-size:.75em; border:1px solid var(--line);
}
.badge,.status-badge{ text-transform:uppercase; letter-spacing:.03em; }
/* A18 (BP-8): Pill-/Badge-TEXT auf Glas -> AA-Text-Varianten (--brand-text/--ok-text); die
   Fuellungen/Raender (--brand-primary-soft/--ok-soft/color-mix(--ok…)) bleiben die vivide Marke. */
.pill{ background:var(--brand-primary-soft); color:var(--brand-text); border-color:transparent; }
.pill.on{ color:var(--ok-text); background:var(--ok-soft); border-color:transparent; }
.pill.off{ color:var(--ink-400); background:transparent; border-color:var(--line); }

/* ---------------------------------------------------------------------------
   K-G12 — Zustaende. Status-Farben (Gruen/Gelb/Rot NUR fuer Status), Info-Banner,
   Leerzustaende. Rot bleibt der echten Gefahr vorbehalten (§3.6).
   --------------------------------------------------------------------------- */
.badge.status-open{ color:var(--ink-500); }  /* AA-Text: ink-500 (war ink-400) — 5.61:1 (L) / 5.85:1 (D) auf Worst-Case-Glas */
.badge.status-in_progress{ color:var(--warn-text); border-color:color-mix(in srgb, var(--warn) 45%, transparent); }
.badge.status-done{ color:var(--ok-text); border-color:color-mix(in srgb, var(--ok) 45%, transparent); }
.badge.badge-stale,.badge.status-vorlage-draft{ color:var(--warn-text); border-color:color-mix(in srgb, var(--warn) 45%, transparent); }
.badge.status-vorlage-active{ color:var(--ok-text); border-color:color-mix(in srgb, var(--ok) 45%, transparent); }
.badge.status-vorlage-deprecated{ color:var(--ink-400); }
.badge.status-vorlage-retired{ color:var(--ink-400); text-decoration:line-through; }
.status-badge.status-active{ color:var(--ok-text); border-color:color-mix(in srgb, var(--ok) 45%, transparent); }
.status-badge.status-inactive{ color:var(--ink-400); }
.banner-ok{ background:var(--ok-soft); color:var(--ok-text); }
.banner-warn{ background:color-mix(in srgb, var(--warn) 14%, transparent); color:var(--warn-text); }

/* ---------------------------------------------------------------------------
   Onboarding-Guide + Server-Uebersicht + Dialoge (tokens-View, K-G11/K-G12).
   Aufklappbare Karten (details/accordion), pre-Code-Bloecke, Aktions-Modals.
   --------------------------------------------------------------------------- */
.onboarding-guide,.create-server,.server-row,.mint-result{
  border:1px solid var(--glass-brd); border-radius:var(--radius-sm);
  background:var(--glass-bg); margin:var(--s4) 0;
}
.onboarding-head,.server-head{
  display:flex; gap:var(--s3); align-items:center; flex-wrap:wrap; cursor:pointer;
  user-select:none; padding:var(--s3) var(--s4);
}
.onboarding-title,.server-name{ font-weight:600; }
.onboarding-hint,.server-desc{ color:var(--ink-400); font-size:.85em; }
.onboarding-hint{ margin-left:auto; }
.onboarding-body,.server-body{ padding:0 var(--s4) var(--s4); }
.onboarding-body{ border-top:1px solid var(--line); }
.onboarding-lead{ color:var(--ink-500); }
.onboarding-steps{ display:flex; flex-direction:column; gap:var(--s4); margin:var(--s3) 0 0; padding-left:var(--s5); }
.onboarding-steps .step-title{ font-weight:600; }
.onboarding-steps .step-note{ display:block; color:var(--ink-400); font-size:.85em; margin-top:var(--s2); }
.onboarding-cmd{ display:flex; gap:var(--s2); align-items:flex-start; margin-top:var(--s2); }
.onboarding-cmd pre{
  flex:1; margin:0; padding:var(--s2) var(--s3); background:var(--glass-bg-strong);
  border:1px solid var(--line); border-radius:var(--radius-sm); overflow-x:auto;
}
.onboarding-cmd code,pre code{ font-family:monospace; font-size:.85em; white-space:pre; }
.onboarding-fields{ display:flex; flex-direction:column; gap:var(--s1); margin-top:var(--s2); max-width:32rem; }
.create-server{ padding:var(--s3) var(--s4); }
.server-list{ list-style:none; margin:var(--s3) 0; padding:0; }
.server-controls{ margin-left:auto; display:flex; gap:var(--s2); align-items:center; }
.agent-tokens{ border-collapse:collapse; width:100%; margin-top:var(--s3); }
.agent-tokens th,.agent-tokens td{ text-align:left; padding:var(--s1) var(--s3); border-bottom:1px solid var(--line); font-size:.9em; }
.agent-tokens th{ color:var(--ink-500); font-weight:600; text-transform:none; letter-spacing:normal; }
.mint-result{ padding:var(--s4); }
.mint-meta{ color:var(--ink-500); font-size:.9em; margin:0 0 var(--s2); }
.wire-token{ display:flex; flex-direction:column; gap:var(--s1); margin-bottom:var(--s2); }
.wire-token input,.wire-token textarea{ font-family:monospace; }
.wire-token textarea{ width:100%; }
.bundle-copy{ display:flex; gap:var(--s2); align-items:flex-start; }
.bundle-copy textarea{ flex:1; }
dialog.action-modal,dialog.result-modal{
  border:1px solid var(--glass-brd); border-radius:var(--radius); color:var(--ink-900);
  background:var(--glass-bg-strong); box-shadow:var(--glass-shadow); padding:var(--s6);
  max-width:40rem; width:90%;
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
}
dialog::backdrop{ background:color-mix(in srgb, var(--ink-900) 55%, transparent); }
dialog form{ display:flex; flex-direction:column; gap:var(--s2); }
.modal-actions{ display:flex; gap:var(--s3); margin:var(--s4) 0 0; padding:0; list-style:none; }

/* ---------------------------------------------------------------------------
   Mockup-/Vorlage-Vorschau: Tabs + Chrome-Rahmen um das sandboxed iframe.
   Der Chrome (Label + Meta) ist Eltern-DOM (A5) — reines Restyling, keine Struktur.
   --------------------------------------------------------------------------- */
.mockup-tabs{ list-style:none; margin:var(--s3) 0 var(--s4); padding:0; display:flex; flex-direction:column; gap:var(--s2); }
.content a.mockup-tab{
  display:inline-flex; gap:var(--s2); align-items:baseline; padding:var(--s2) var(--s3);
  border:1px solid var(--line); border-radius:var(--radius-sm); text-decoration:none; color:var(--ink-700);
}
.content a.mockup-tab.active{ border-color:var(--brand-primary); color:var(--brand-text); }
.mockup-tab-title{ font-weight:600; }
.mockup-tab-meta{ color:var(--ink-400); font-size:.85em; margin-left:var(--s2); }
.mockup-chrome{ border:2px solid var(--brand-primary); border-radius:var(--radius-sm); overflow:hidden; margin:var(--s3) 0 var(--s4); }
.mockup-chrome-label{
  background:var(--brand-primary); color:white; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; padding:var(--s2) var(--s4);
}
.mockup-meta{ display:flex; gap:var(--s2); align-items:baseline; flex-wrap:wrap; margin:var(--s2) var(--s4); }
.mockup-desync{ margin:var(--s2) var(--s4); }
.mockup-frame{ display:block; width:100%; height:70vh; border:0; background:white; }

/* ============================================================================
   BP-5 — SHELL-INTERAKTIVITAET (Plan 37 Stufe 4 Runde 1): Theme-Umschalter +
   Nav-Collapse. Das VERHALTEN lebt in der externen, deferten static/glass.js
   (A17: kein Inline-JS; die CSP hat kein script-src). Hier ausschliesslich die
   Praesentation: die JS-only-Sichtbarkeit der Steuerelemente, die Icon+Label-
   Hauptnavigation und der eingeklappte Icon-Rail-Zustand. KEINE Farb-Literale
   (A11) — nur Token-/color-mix()-Referenzen + currentColor + display/layout.
   ========================================================================== */

/* Enhancement-Sichtbarkeit: die Steuerelemente erscheinen NUR bei aktivem JS
   (glass.js setzt html[data-js="on"]). Ohne JS bleiben sie unsichtbar, statt als
   funktionslose Schaltflaeche dazustehen (A17: Toggle/Collapse sind Enhancement;
   der No-JS-Pfad ist die volle beschriftete Navigation + prefers-color-scheme). */
.js-only{ display:none; }
html[data-js="on"] .js-only{ display:flex; }

/* Icon-Schaltflaechen der Sidebar-Werkzeuge (Nav-Collapse + Theme) — Ghost-Stil,
   K-G8-Vektor-Icons erben currentColor. */
.ctl-icon{
  font:inherit; cursor:pointer; align-items:center; justify-content:center; gap:var(--s2);
  line-height:1; padding:var(--s2) var(--s3); border:1px solid var(--glass-brd);
  border-radius:var(--radius-xs); background:var(--glass-bg); color:var(--ink-700);
}
.ctl-icon:hover{ border-color:var(--brand-primary); color:var(--brand-text); }
.ctl-icon svg{ flex:none; }
/* Plan 37 · IA-Folge-Quickfix 1b — globale Icon-Absicherung. Ein Inline-SVG OHNE eigene
   Groessenangabe soll nie als Riesen-Icon rendern -> 16px-Default. Bewusst auf UNbemasste
   SVGs verengt (:not([width]):not([height])): ALLE 32 heutigen Icons tragen explizite
   width=/height=-Attribute (19/18/22/16) — ein nacktes `svg{width;height}` wuerde diese
   Praesentationsattribute ueberschreiben (CSS schlaegt Attribute) und Nav-/Brand-/Toggle-
   Icons verzerren/schrumpfen. So bleiben bemasste Icons EXAKT wie sie sind (die
   spezifischeren Regeln „ueberschreiben" per Attribut weiterhin), und nur kuenftige
   unbemasste Inline-SVGs werden gekappt. Reine Groesse, kein Farb-/Token-Eingriff. */
svg:not([width]):not([height]){ width:16px; height:16px; }
/* Der Nav-Collapse sitzt rechts im Brand-Block; der Theme-Umschalter fuellt den Fuss. */
.brand .nav-collapse{ flex:0 0 auto; margin-left:auto; padding:var(--s1) var(--s2); }
.sidebar-foot .theme-toggle{ width:100%; }

/* Der Theme-Umschalter zeigt das Symbol des AKTUELLEN Modus (Sonne=hell, Mond=dunkel);
   die Beschriftung nennt die Aktion. Der Icon-Swap folgt data-theme (glass.js setzt es). */
.theme-toggle .i-moon{ display:none; }
[data-theme="dark"] .theme-toggle .i-sun{ display:none; }
[data-theme="dark"] .theme-toggle .i-moon{ display:inline; }

/* Eingeklappt = Icon-Rail (BP-3b jetzt VERTIKAL): die Sidebar schrumpft auf eine schmale
   Rail, der Content rueckt nach. NICHT adaptiv (kein Drag/Radial/Mausrad — das ist Runde 2). */
html[data-nav-collapsed="true"] .sidebar{ width:64px; }
html[data-nav-collapsed="true"] .content{ margin-left:calc(64px + var(--s4) + var(--s4)); }

/* Eingeklappt: NUR die Beschriftungen der HAUPTNAVIGATION entfallen visuell. Die Labels
   werden sr-only versteckt statt entfernt -> der zugaengliche Name des Links bleibt erhalten. */
html[data-nav-collapsed="true"] .mainnav .navlabel{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
/* Konsistente Icon-Rail: Brand-Titel + Konto-Text ebenfalls sr-only; Icons zentriert. */
html[data-nav-collapsed="true"] .brand-text,
html[data-nav-collapsed="true"] .account-who{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
html[data-nav-collapsed="true"] .mainnav a,
html[data-nav-collapsed="true"] .account > summary{ justify-content:center; }
html[data-nav-collapsed="true"] .account .chevron{ display:none; }
html[data-nav-collapsed="true"] .brand{ justify-content:center; }

/* ============================================================================
   BP-6 — /login (eigenstaendige Glas-Seite OHNE Nav-Shell, Plan 37 Stufe 4 Runde 1).
   Die Login-Seite erweitert bewusst NICHT glass/base.html (keine Sidebar vor dem
   Login) — daher greift die `.content`-scoped Feld-/Button-Basis (K-G9/K-G10) hier
   NICHT. Dieser Block gibt der zentrierten Glas-Login-Karte dieselbe Feld-/Button-
   Praesentation, ausschliesslich aus Tokens/color-mix() + den Keywords (A11 —
   KEINE Farb-Literale ausserhalb der Token-Bloecke). Die Form-Layout-/Label-/
   Submit-Gradient-/Note-Regeln (.login-form*, .login-note) stehen bereits in der
   BP-4-Ebene oben und werden hier wiederverwendet.
   ========================================================================== */
.login-page{ display:grid; place-items:center; padding:var(--s6); }
.login-card{
  width:100%; max-width:23rem; padding:var(--s8);
  background:var(--glass-bg-strong); border:1px solid var(--glass-brd);
  border-radius:var(--radius); box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
}
.login-card .login-brand{ display:flex; flex-direction:column; gap:var(--s1); margin-bottom:var(--s5); }
.login-card h1{ margin:0 0 var(--s4); font-size:1.15em; }
/* K-G10 — Passwortfeld: dieselbe helle Glas-Unterlage/Linie/Radius wie `.content input`,
   nur hier explizit fuer die shell-lose Login-Karte wiederholt. */
.login-card input[type="password"]{
  font:inherit; color:var(--ink-900); padding:var(--s2) var(--s3);
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:color-mix(in srgb, var(--glass-bg-strong) 82%, white);
}
/* M2 — sichtbarer Marken-Fokusring am Feld (Ersatz fuer den unterdrueckten Outline). */
.login-card input[type="password"]:focus-visible{
  outline:none; border-color:var(--brand-primary);
  box-shadow:0 0 0 var(--s1) var(--brand-primary-soft);
}
/* A18 (BP-8): Dark-Fokusrand des Login-Feldes auf --focus-ring (>= 3:1) — wie die Content-Felder. */
[data-theme="dark"] .login-card input[type="password"]:focus-visible{ border-color:var(--focus-ring); }
@media (prefers-color-scheme: dark){
  :root:not([data-theme]) .login-card input[type="password"]:focus-visible{ border-color:var(--focus-ring); }
}
/* K-G9 — Submit-Basis (Padding/Radius/Cursor); die Marken-Gradient-Fuellung erbt der
   Button aus der `.login-form button[type="submit"]`-Regel der BP-4-Ebene oben. */
.login-card button[type="submit"]{
  font:inherit; cursor:pointer; line-height:1;
  padding:var(--s2) var(--s4); border-radius:var(--radius-xs); margin-top:var(--s2);
}
.login-card button[type="submit"]:hover{ filter:brightness(1.06); }
html[data-nav-collapsed="true"] .brand .nav-collapse{ margin-left:0; }

/* ============================================================================
   Plan 42 §3.2/§4 — PLÄNE-FINDER (drei Spalten aus freistehenden Karten) + die
   wiederverwendbaren Bausteine (Chip / Karte / Filter-Chip-Leiste / Status-Punkt).
   AUSSCHLIESSLICH bestehende Tokens/color-mix() + die Keywords (A11) — KEINE neuen
   Farben. Die Status-Farben spiegeln 1:1 die bestehenden .badge.status-*-Regeln
   (dieselben BP-8-AA-gehaerteten Tokens: done->ok-text, in_progress->warn-text,
   open->ink-500 als TEXT (AA >=4.5:1; der offene Status-PUNKT bleibt ink-400, Non-Text 3:1);
   Gefahr->danger). Interaktion rein server-seitig (Links), CSP unberuehrt.
   ========================================================================== */

/* Der Finder fuellt die Content-Karten-Hoehe; die Spalten scrollen INTERN statt die
   Seite (§3.2). .content traegt padding:s6 -> der Finder ist genau 1 Viewport minus
   Padding hoch, also entsteht KEIN Seiten-Scroll. */
.finder{ display:flex; flex-direction:column; gap:var(--s4); height:calc(100vh - 2 * var(--s6)); min-height:0; }
.finder-head{ display:flex; align-items:center; gap:var(--s4); flex-wrap:wrap; }
.finder-head h1{ margin:0; }

/* Filter-Chip-Leiste (Sofortfilter mit Zaehlern statt Dropdown + Button). */
.filter-chips{ display:flex; gap:var(--s2); flex-wrap:wrap; }
.chip{
  display:inline-flex; align-items:center; gap:var(--s2);
  padding:var(--s1) var(--s3); border-radius:999px; font-size:.8em;
  border:1px solid var(--line); color:var(--ink-700);
  background:var(--glass-bg); white-space:nowrap;
}
.chip-count{ color:var(--ink-500); font-variant-numeric:tabular-nums; font-size:.9em; }  /* AA-Text: ink-500 (war ink-400) */
/* Filter-Chips sind Links -> die .content-a-Basis (brand-text/underline) ueberschreiben. */
.content a.chip--filter{ color:var(--ink-700); text-decoration:none; }
.content a.chip--filter:hover{ border-color:var(--brand-primary); color:var(--brand-text); text-decoration:none; }
/* Aktiver Filter-Chip: DECKENDES glass-bg-strong (nicht das 12%-transparente brand-soft — das
   faellt ueber dem Ambient auf 3.95:1); brand-text darauf = 6.15:1 (L) / 6.22:1 (D). Marken-Rand
   + brand-text + aria-current machen den Aktiv-Zustand eindeutig. */
.content a.chip--filter.is-active{ background:var(--glass-bg-strong); border-color:var(--brand-primary); color:var(--brand-text); }
.content a.chip--filter.is-active .chip-count{ color:var(--brand-text); }

/* Drei transparente Spalten. minmax(0,1fr) bindet jede Spalte an den Innenraum ->
   sie ueberschreiten NIE die Content-Breite (kein Horizontalscroll); jede Spalte
   scrollt intern. */
.finder-cols{
  display:grid; grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:var(--s4); align-items:stretch; flex:1 1 auto; min-height:0;
}
.finder-col{ display:flex; flex-direction:column; min-height:0; min-width:0; }
/* Caption/Empties sitzen DIREKT auf dem Ambient (transparente Spalten, keine Glas-Unterlage) —
   dort erreichen ink-300/ink-400 die 4.5:1 nicht (Worst-Case-Ambient); daher ink-700 (>=8.7:1
   beide Themes). NUR im Finder gescopt, damit das globale .empty (auf Glas) unberuehrt bleibt. */
.col-caption{
  margin:0 0 var(--s2); color:var(--ink-700); font-size:.72em; font-weight:600;
  text-transform:uppercase; letter-spacing:.06em;
}
.col-scroll{ flex:1 1 auto; min-height:0; overflow-y:auto; padding-right:var(--s1); }
.finder .empty{ color:var(--ink-700); }

/* Freistehende Karte — das Grundfeld (schwebt einzeln ueber dem Ambient-Hintergrund). */
.card{
  display:block; padding:var(--s3) var(--s4); margin-bottom:var(--s3);
  border-radius:var(--radius-sm); background:var(--glass-bg);
  border:1px solid var(--glass-brd); box-shadow:var(--glass-shadow);
  -webkit-backdrop-filter:var(--glass-blur); backdrop-filter:var(--glass-blur);
}
/* Karten-Links: .content-a-Basis (brand-text/underline) neutralisieren -> Karte, kein Link-Text. */
.content a.card{ color:var(--ink-900); text-decoration:none; transition:border-color .15s ease; }
.content a.card:hover{ border-color:var(--brand-primary); text-decoration:none; }
.content a.card.is-active{ border-color:var(--brand-primary); background:var(--brand-primary-soft); }

/* Spalte 1 — Plan-Karte: Titel 2-Zeilen-Clamp + Meta-Chips (#Nr, Server). */
.plan-card-title{
  display:-webkit-box; -webkit-line-clamp:2; line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden; font-weight:600; line-height:1.3;
}
.card-meta{ display:flex; gap:var(--s2); margin-top:var(--s2); flex-wrap:wrap; }
.chip--num{ color:var(--ink-500); font-variant-numeric:tabular-nums; }
.chip--server{ color:var(--ink-500); }

/* Spalte 2 — Kontext-Karte (Plan-Titel, Server, Fortschritt) + Schritt-Karten. */
.context-card{ display:flex; flex-direction:column; gap:var(--s2); background:var(--glass-bg-strong); }
.context-title{ font-weight:700; line-height:1.3; }
.context-meta{ color:var(--ink-500); font-size:.85em; }
.context-progress{ display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap; }
.context-detail{ align-self:flex-start; margin-top:var(--s1); }

.step-card{ display:flex; align-items:center; gap:var(--s2); }
.step-card-id{ color:var(--ink-500); font-size:.82em; font-variant-numeric:tabular-nums; flex:none; }  /* AA-Text: ink-500 (war ink-400) */
.step-card-title{ font-weight:550; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; flex:1 1 auto; min-width:0; }
.step-card.depth-1{ margin-left:var(--s4); }
.step-card.depth-2{ margin-left:calc(2 * var(--s4)); }
.step-card.depth-3{ margin-left:calc(3 * var(--s4)); }
.step-card.depth-4{ margin-left:calc(4 * var(--s4)); }
.step-card.is-next{ border-color:color-mix(in srgb, var(--brand-primary) 45%, transparent); }
.chip--next{ color:var(--brand-text); background:var(--brand-primary-soft); border-color:transparent; flex:none; }

/* Status-Punkt (erledigt/laeuft/offen) — dieselben Statusfarben wie die .badge.status-*,
   AUSSER dem offenen Punkt: als Nicht-Text-Icon genuegt ihm die 3:1-Schwelle, daher bleibt er
   ink-400 (4.97:1 L / 5.32:1 D auf Worst-Case-Glas), waehrend der TEXT (.badge/.status-chip
   .status-open) auf ink-500 gehoben ist (AA >=4.5:1 Normaltext). */
.status-dot{ flex:none; display:inline-flex; align-items:center; justify-content:center; }
.status-dot.dot-done{ color:var(--ok-text); }
.status-dot.dot-progress{ color:var(--warn-text); }
.status-dot.dot-open{ color:var(--ink-400); }

/* Status-Chip (Baustein) — spiegelt die .badge.status-*-Farbregeln (AA-gehaertet). */
.status-chip{ text-transform:uppercase; letter-spacing:.03em; font-size:.7em; }
.status-chip.status-open{ color:var(--ink-500); }  /* AA-Text: ink-500 (war ink-400), wie .badge.status-open */
.status-chip.status-in_progress{ color:var(--warn-text); border-color:color-mix(in srgb, var(--warn) 45%, transparent); }
.status-chip.status-done{ color:var(--ok-text); border-color:color-mix(in srgb, var(--ok) 45%, transparent); }

/* Spalte 3 — Schritt-Detail: der Kartenrahmen STEHT, der lange Text scrollt IM Feld (§3.2). */
.finder-col.is-detail .col-scroll{ overflow-y:hidden; }
.step-detail{ display:flex; flex-direction:column; max-height:100%; background:var(--glass-bg-strong); }
.step-detail-head{ display:flex; align-items:center; gap:var(--s2); flex:none; }
.step-detail-id{ color:var(--ink-400); font-variant-numeric:tabular-nums; }
.step-detail-title{ margin:var(--s2) 0; font-size:1.05em; flex:none; }
.step-detail-owner{ color:var(--ink-500); font-size:.85em; margin:var(--s1) 0; flex:none; }
.step-detail-body{ white-space:pre-wrap; word-break:break-word; line-height:1.6; color:var(--ink-700); overflow-y:auto; min-height:0; flex:1 1 auto; }

/* Gefahr-Signal „HARTER STOPP" — danger-soft-Fuellung + danger-text (AA-gehaertet, §3.6). */
.hard-stop{
  display:flex; align-items:center; gap:var(--s2); margin:var(--s2) 0; flex:none;
  padding:var(--s2) var(--s3); border-radius:var(--radius-sm);
  background:var(--danger-soft); color:var(--danger-text); font-weight:600;
}
.hard-stop svg{ flex:none; }

/* Schmaler Viewport: Spalten stapeln, die Seite scrollt normal (kein H-Scroll). */
@media (max-width: 900px){
  .finder{ height:auto; }
  .finder-cols{ grid-template-columns:1fr; }
  .col-scroll,.finder-col.is-detail .col-scroll{ overflow-y:visible; }
  .step-detail{ max-height:none; }
  .step-detail-body{ overflow-y:visible; }
}

/* ============================================================================
   A19 (BP-7) — DRUCK: erzwingt das HELLE Token-Set. Ein Dark-Theme-Ausdruck ist auf
   Papier unlesbar (heller Text auf weissem Blatt). Dieser @media-print-Block
   re-deklariert die hellen Ink-/Linien-Token auf JEDEM dunkel-erzeugenden Scope —
   der expliziten [data-theme="dark"]-Wahl UND dem OS-Dark-Default
   :root:not([data-theme]) —, sodass der Ausdruck IMMER hell ist (beide Scopes stehen
   NACH ihren Quellregeln und gewinnen bei gleicher Spezifitaet). Zusaetzlich: die
   fixierte Glas-Sidebar und alle JS-only-Steuerungen (Theme/Collapse — im Druck
   sinnlos) werden ausgeblendet, der Content fuellt die volle Seitenbreite, und die
   druck-feindliche Glas-/Ambient-Chrome (backdrop-filter/Ambient-Wash/Schatten)
   entfaellt. A11: Farb-Literale stehen AUSSCHLIESSLICH in den :root-/[data-theme]-
   Token-Bloecken; ausserhalb nur var()/die Keywords `white`/`none`.
   ========================================================================== */
@media print{
  /* Explizite Dunkel-Wahl -> zurueck auf die hellen Ink-/Linien-Literale (A18-gehaertete Werte). */
  [data-theme="dark"]{
    --ink-900:#0b0b0f; --ink-700:#2b2b31; --ink-500:#5b5b66;
    --ink-400:#63636d; --ink-300:#676771;
    --line:rgba(20,20,30,.16);
  }
  /* OS-Dark-Default ohne explizite Wahl -> ebenfalls hell drucken. */
  :root:not([data-theme]){
    --ink-900:#0b0b0f; --ink-700:#2b2b31; --ink-500:#5b5b66;
    --ink-400:#63636d; --ink-300:#676771;
    --line:rgba(20,20,30,.16);
  }
  /* Weisses Papier, dunkle Schrift; die druck-feindliche Ambient-/Glas-Chrome entfaellt. */
  body{ background:white; color:var(--ink-900); }
  .ambient{ display:none !important; }
  .sidebar{ display:none !important; }
  .js-only{ display:none !important; }
  .content{ margin-left:0 !important; }
  section, dialog, .account-panel, .login-card, .card{
    background:white !important; box-shadow:none !important;
    -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
  }
  /* Der Pläne-Finder scrollt im Druck nicht intern — volle Hoehe, alle Spalten sichtbar. */
  .finder{ height:auto !important; }
  .col-scroll,.finder-col.is-detail .col-scroll,.step-detail-body{ overflow:visible !important; }
}
