/* ============================================================
   Produkt-Ausschnitte auf workforce
   Zwei Wurzelnamen: `.mock-kette` fuer die Bilder in .kette-buehne
   und `.mock-melder` fuer die Kaesten im Hero.
   ⚠ Die Datei heisst weiter mock-kette.css, obwohl `.mock-melder` seit
   25.08.2026 auch compliance.html und tender.html tragen. Ein Umbenennen
   waere ein eigener Schritt: HEAD_CSS in apply-partials.mjs, ZENTRAL in
   check-rename.mjs und die Liste in sections.mjs muessten mit.

   NAMING.md: alles INNERHALB eines Produkt-Mockups traegt `mock-`
   und ist kein Bestandteil des Design-Systems.

   ⚠ ALLES IST UNTER `.mock-kette` GESCOPED. Grund: mock-modul.css
   belegt .mock-tabelle, .mock-zelle, .mock-chip, .mock-rail,
   .mock-person und rund 50 weitere Namen fuer die Schichtplanungs-
   Teaser. Beide Dateien liegen heute nie auf derselben Seite, aber
   sections.mjs plant ausdruecklich, mock-modul.css spaeter nach
   components.css zu ziehen — dann kollidierten sie. Das Scoping
   kostet nichts und verhindert es dauerhaft.

   ⚠ ZUR DATEN-REGEL. mock-modul.css verbietet in seinem Kopf jede
   Zahl: „Wer eine Zahl ergaenzt, macht aus dem Teaser eine Demo und
   nimmt dem Vertrieb das Gespraech weg." Diese Regel gilt weiter —
   fuer demo-modul-*.html, wofuer sie geschrieben wurde. Fuer DIESE
   Bilder hat Patrick am 19.08.2026 anders entschieden: konkret wie
   bei Tacto, mit erfundenen Zahlen und Namen. Kein Versehen, eine
   Entscheidung fuer ein anderes Artefakt.
   Was trotzdem gilt: erfundene Firmen und Rollen, keine echten
   Kunden, keine echten Personen.

   Skalierung wie in mock-modul.css: .mock-kette ist der Container,
   alles im Innern rechnet in em ueber cqw. Die Karte laeuft bewusst
   ueber den rechten und unteren Rand hinaus — der Beschnitt verbirgt
   Detail UND sagt „hier geht es weiter".
   ============================================================ */

.mock-kette{ position:absolute; inset:0; container-type:inline-size; z-index:1; }

/* ⚠ cqw NICHT auf .mock-kette selbst benutzen: ein Container kann sich
   nicht selbst abfragen. Die Einheit gehoert in die Kinder. */
.mock-kette .mock-rahmen{
  position:absolute; left:7%; top:8%; width:126%; height:98%;
  /* GEMESSEN: bei 1.45cqw (≈10px auf einer 688px-Buehne) endete der Inhalt
     rund 170px vor der Kartenunterkante — die Karte lief unten leer aus und
     sah nach Fehler aus, nicht nach Beschnitt. Mit 2.05cqw fuellt der Inhalt
     die Karte und laeuft unten wie rechts sauber unter den Schleier. */
  font-size:max(11px, 2.05cqw);
  font-family:var(--sans); color:var(--ink);
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:0 2.4em 5em -2em rgba(4,19,16,.55);
  overflow:hidden;
  display:flex; flex-direction:column;
}

/* ---- Statische Menue-Leiste (Hero-Look) ---------------------------------
   Legt die linke App-Leiste (Logo + Menue-Kaestchen, eins mint) an JEDES
   mock-kette-Panel, damit die Mockups wie das Hero-App-Fenster wirken
   („das Menue dort einsetzen wo passend", Karoline 01.09.2026). Rein additiv:
   der Inhalt rueckt per padding-left ein, die Leiste liegt als ::before davor.
   Farben im SVG hart kodiert (Marke), da eine externe Datei keine CSS-Variablen
   sieht. */
.mock-kette .mock-rahmen{ padding-left:3.6em; }
.mock-kette .mock-rahmen::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3.6em; z-index:6;
  background:var(--paper) url("../../assets/modul/mock-rail.svg") no-repeat top center;
  background-size:3.6em auto;
  border-right:1px solid var(--line-soft);
}
/* Dieselbe Leiste fuer die Pax-Use-Case-Mocks (.mock-uc / .uc-karte). */
.mock-uc .uc-karte{ position:relative; padding-left:3.6em; }
.mock-uc .uc-karte::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:3.6em; z-index:6;
  background:var(--paper) url("../../assets/modul/mock-rail.svg") no-repeat top center;
  background-size:3.6em auto;
  border-right:1px solid var(--line-soft);
}

/* =========================================================================
   .hw — EINHEITLICHES STATISCHES HERO-FENSTER (Neubau aller Modul-Mockups,
   Karoline 01.09.2026). Ein weisses App-Fenster: Leiste (Logo + Menue-
   Kaestchen, eins mint) + Topbar (Icon + Titel + Pillen + Mint-Punkt) +
   fuellender Inhaltsbereich aus Hero-Karten. Kein Ablauf, keine schwebenden
   Karten, kein Anschnitt-Glanz. Fuellt den .mod-frame (inset:30px) komplett.
   Groessen in cqw/em relativ zur Fensterbreite -> nichts schneidet ab.
   ========================================================================= */
.hw{ position:absolute; inset:0; z-index:2; display:flex; overflow:hidden;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--r-lg);
  box-shadow:0 2.4em 5em -2em rgba(4,19,16,.55);
  container-type:inline-size; font-family:var(--sans); color:var(--ink);
  line-height:1.4; }
/* ⚠ cqw NICHT auf .hw (dem Container) — ein Container kann sich nicht selbst
   abfragen, dann faellt cqw auf den Viewport zurueck (gemessen 28.8px Font auf
   1440px Fenster). Die Schriftgroesse gehoert auf ein KIND, hier .hw-main. */
/* ⚠ DECKEL BEI 14px, UND ZWAR AUS EINEM GEMESSENEN GRUND. `max(11px, 2.4cqw)`
   war nach oben offen: der Rahmen (.mod-frame in workforce.html) waechst mit dem
   Fenster mit, seine HOEHE steht aber fest bei 560px minus 30px Einzug. Gemessen
   auf workforce.html, Kasten hw#8:

     Fenster   Rahmen     Schrift   Inhalt
     1440px    526x495    13,4px    498px   passt
     1800px    692x495    17,2px    538px   43px fehlen
     1920px    748x495    19,0px    581px   83px fehlen
     2560px    748x495    19,0px    581px   83px fehlen

   Breiter heisst hier also HOEHER, weil die Schrift an der Containerbreite haengt.
   Ab 1920px schnitten 13 von 30 Kaesten ihren Inhalt ab; im Fenster
   „Einsaetze steuern" lief die Fusszeile („5 von 42 Einsaetzen / alle anzeigen")
   dabei UEBER die letzte Tabellenzeile.

   Der Deckel greift erst ab etwa 583px Rahmenbreite (14 / 0,024). Alles darunter
   ist unberuehrt, insbesondere die 11px-Untergrenze auf dem Telefon.
   Gegenprobe ueber workforce, compliance, tender, pax-ai, index bei
   390/768/1000/1280/1440/1920/2560px: 1920 und 2560 auf workforce von 13 auf 0,
   1000px auf pax-ai von 2 auf 0, sonst ueberall unveraendert — nichts wurde
   schlechter.

   ⚠ Die Ueberlaeufe bei 390px (workforce 29 Kaesten, tender 4) und bei 1000px
   auf tender haben eine ANDERE Ursache: dort liegt die Schrift schon auf der
   11px-Untergrenze. Ein Deckel hilft da nicht, das ist eine eigene Baustelle. */
.hw-main{ font-size:clamp(11px, 2.4cqw, 14px); }
.hw-rail{ flex:none; width:8.5%; min-width:42px; background:var(--paper);
  border-right:1px solid var(--line-soft); display:flex; flex-direction:column;
  align-items:center; gap:.95em; padding:1.15em 0; }
/* ⚠ background/border-radius EXPLIZIT zuruecksetzen: tender.html hat eine eigene
   .logo-Klasse mit gruenem Badge, die sonst auf das Rail-Logo durchschlaegt
   („komisch gruen hinterlegt", Karoline). */
.hw-rail .logo{ width:52%; height:auto; display:block; margin-bottom:.35em;
  background:none; border:0; border-radius:0; box-shadow:none; padding:0; }
.hw-rail i{ width:52%; aspect-ratio:1; border-radius:28%; background:var(--line-soft); }
.hw-rail i.an{ background:var(--tech-soft); }
.hw-main{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; }
.hw-bar{ flex:none; display:flex; align-items:center; gap:.6em; padding:.85em 1.15em;
  border-bottom:1px solid var(--line-soft); }
.hw-bar .tic{ width:1.7em; height:1.7em; border-radius:.42em; background:var(--tech-tint);
  color:var(--green-700); display:grid; place-items:center; flex:none; }
.hw-bar .tic svg{ width:1em; height:1em; }
.hw-bar .tic.ai{ background:var(--ai-tint); color:var(--ai-ink); }
.hw-bar .tit{ font-size:1.02em; font-weight:600; letter-spacing:-.01em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-bar .pille{ height:.5em; border-radius:99px; background:var(--line-soft); flex:none; }
.hw-bar .p1{ width:3em; margin-left:auto; } .hw-bar .p2{ width:1.9em; }
.hw-bar .dot{ width:.7em; height:.7em; border-radius:50%; background:var(--tech-tint); flex:none; }
.hw-body{ flex:1 1 auto; min-height:0; padding:1.1em 1.2em; display:flex;
  flex-direction:column; gap:.9em; }
.hw-card{ border:1px solid var(--line); border-radius:var(--r-md); background:var(--surface);
  box-shadow:0 .55em 1.3em -.9em rgba(8,40,34,.26); padding:.95em 1.05em;
  display:flex; flex-direction:column; }
.hw-card.fill{ flex:1 1 auto; min-height:0; }
.hw-chd{ display:flex; align-items:center; gap:.5em; margin-bottom:.65em; flex:none; }
.hw-cic{ width:1.55em; height:1.55em; border-radius:.4em; background:var(--tech-tint);
  color:var(--green-700); display:grid; place-items:center; flex:none; }
.hw-cic svg{ width:.92em; height:.92em; }
.hw-ct{ font-size:.9em; font-weight:600; letter-spacing:-.005em; }
.hw-chd .mock-chip{ margin-left:auto; }
.hw-row{ display:flex; align-items:center; gap:.6em; font-size:.82em; padding:.52em 0;
  border-top:1px solid var(--line-soft); min-width:0; }
.hw-row:first-child{ border-top:0; }
.hw-row .f{ color:var(--muted-readable); flex:none; }
.hw-row .v{ margin-left:auto; color:var(--ink-soft); font-weight:600; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-align:right; }
.hw-row .v.chip{ overflow:visible; }
.hw-av{ width:1.7em; height:1.7em; border-radius:50%; flex:none; display:grid;
  place-items:center; font-size:.62em; font-weight:700; background:var(--tech-tint);
  color:var(--green-700); }
.hw-skel{ display:flex; flex-direction:column; gap:.55em; padding:.15em 0; }
.hw-skel i{ height:.5em; border-radius:99px; background:var(--line-soft); }
.hw-skel i.w1{ width:82%; } .hw-skel i.w2{ width:64%; } .hw-skel i.w3{ width:48%; }
.hw-skel i.mint{ background:var(--tech-soft); }
/* margin-left:.55em statt auto: der Haken haengt fest am Chip, statt selbst nach
   rechts zu wandern. So bilden Chip+Haken eine rechtsbuendige Gruppe und die
   gleich breiten „Vorschlag"-Chips fluchten sauber untereinander. */
.hw-check{ margin-left:.55em; width:1.05em; height:1.05em; color:var(--green-600); flex:none; }
/* ---- Abwechslungsreiche Layout-Bausteine (gleiche Designsprache, andere Form) ----
   Damit nicht jeder Mock aus zwei Zeilenlisten besteht: KPI-Kacheln, Balken,
   Organigramm. Alle nutzen dieselben Tokens/Schrift/Chips. */
.hw-kpis{ display:flex; gap:.6em; }
.hw-kpi{ flex:1 1 0; min-width:0; border:1px solid var(--line); border-radius:var(--r-md);
  padding:.6em .7em; background:var(--surface); }
.hw-kpi .kl{ display:block; font-size:.72em; color:var(--muted-readable);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-kpi .kn{ display:block; font-size:1.5em; font-weight:700; letter-spacing:-.02em;
  line-height:1.1; margin-top:.1em; font-variant-numeric:tabular-nums; }
.hw-kpi .ks{ display:block; font-size:.66em; color:var(--muted); margin-top:.15em; }
/* Kennzahl mit vorangestelltem Zeichen: die Zahl allein sagt nicht, ob sie gut
   oder schlecht ist. Vorbild ist Patricks Screenshot ComPro2 (02.09.2026), wo
   Beitragsrueckstaende und abgelaufene Dokumente je ein Feld mit Zeichen und
   Zahl tragen. `.kw` ersetzt in dem Fall `.kn` als direktes Kind — wer nur eine
   Zahl braucht, nimmt weiter `.kn`. */
.hw-kpi .kw{ display:flex; align-items:center; gap:.5em; margin-top:.25em; }
.hw-kpi .kw .kn{ margin-top:0; }
.hw-kpi .kbad{ width:1.6em; height:1.6em; border-radius:.4em; flex:none;
  display:grid; place-items:center; background:var(--surface-2); color:var(--muted-readable); }
/* Dieselbe Mischung wie .mock-chip.rot weiter unten — es gibt kein --red-bg,
   und ein neuer Hex-Wert waere eine zweite Rotquelle. */
.hw-kpi .kbad.rot{ background:color-mix(in srgb, var(--red) 12%, transparent); color:var(--red); }
.hw-kpi .kbad svg{ width:.9em; height:.9em; }
.hw-bars{ display:flex; align-items:flex-end; gap:.7em; flex:1 1 auto; min-height:0; padding-top:.4em; }
.hw-barcol{ flex:1 1 0; display:flex; flex-direction:column; align-items:center; gap:.45em;
  height:100%; justify-content:flex-end; }
.hw-barcol .bar{ width:82%; border-radius:.3em .3em 0 0; background:var(--line-soft); }
.hw-barcol.hoch .bar{ background:var(--tech-soft); }
.hw.ist-tender .hw-barcol.hoch .bar{ background:var(--orange-tint); }
.hw.ist-pax .hw-barcol.hoch .bar{ background:var(--ai-tint); }
.hw-barcol .bl{ font-size:.64em; color:var(--muted-readable); white-space:nowrap; }
/* Organigramm-Baustein */
.hw-org{ display:flex; flex-direction:column; align-items:center; gap:.55em; padding:.4em 0;
  flex:1 1 auto; min-height:0; justify-content:space-evenly; }
.hw-node{ display:inline-flex; align-items:center; gap:.5em; border:1px solid var(--line);
  border-radius:var(--r-sm); background:var(--surface); padding:.6em .9em; font-size:.86em; font-weight:600;
  box-shadow:0 .4em .9em -.6em rgba(8,40,34,.25); }
.hw-node .hw-av{ font-size:.56em; }
.hw-node .nd{ display:flex; flex-direction:column; line-height:1.12; min-width:0; text-align:left; }
.hw-node .nd b{ font-size:1em; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-node .nd span{ font-size:.76em; color:var(--muted-readable); font-weight:400; }
.hw-org-reihe{ display:flex; gap:.6em; justify-content:center; flex-wrap:wrap; }
.hw-org-verb{ width:60%; height:.9em; border:1px solid var(--line-soft); border-bottom:0;
  border-radius:.4em .4em 0 0; }
/* Volle Datentabelle (wie „Externe Mitarbeiter") */
.hw-table{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.hw-th,.hw-tr{ display:grid; grid-template-columns:var(--cols,.9fr 1.3fr 1.1fr .9fr); gap:.7em; align-items:center; }
.hw-th{ font-size:.66em; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); padding:.2em 0 .7em; }
.hw-tr{ font-size:.82em; padding:.55em 0; border-top:1px solid var(--line-soft); }
.hw-tr .stark{ font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-tr .leise{ color:var(--muted-readable); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-tr .zell-av{ display:flex; align-items:center; gap:.5em; min-width:0; }
/* Ampel-Status-Raster */
.hw-ampelrow{ display:flex; align-items:center; gap:.6em; padding:.6em 0; border-top:1px solid var(--line-soft); font-size:.84em; }
.hw-ampelrow:first-of-type{ border-top:0; }
.hw-ampelrow .nm{ font-weight:600; }
.hw-dots{ margin-left:auto; display:flex; gap:.55em; }
/* ⚠ inline-block ist Pflicht, nicht Kosmetik. Der Punkt ist ein <span>, und
   ein Inline-Element ignoriert width und height. In .hw-dots faellt das nicht
   auf, weil der Elternteil ein Flex-Container ist und seine Kinder damit
   blockartig werden. Steht der Punkt aber in einer gewoehnlichen Zeile
   (.hw-row .v), rendert er als 1,6px breiter senkrechter Strich — gemessen am
   Ampelbild der Compliance-Seite. */
.hw-adot{ display:inline-block; width:.8em; height:.8em; border-radius:50%;
  border:1.6px solid var(--line); flex:none; vertical-align:middle; }
.hw-adot.gr{ background:var(--green-600); border-color:var(--green-600); }
.hw-adot.rt{ background:var(--red); border-color:var(--red); }
.hw-adot.gb{ background:#E4900F; border-color:#E4900F; }
/* Farbige Avatare (konsistent aus der Chip-Palette) fuer coolere Tabellen */
.hw-av.a2{ background:var(--blue-bg); color:var(--blue-ink); }
.hw-av.a3{ background:var(--amber-bg); color:var(--amber-ink); }
.hw-av.a4{ background:var(--ai-tint); color:var(--ai-ink); }
.hw-av.a5{ background:var(--tech-soft); color:var(--green-800); }
/* Gauge/Ring (Score) — Farbe via --gcol, Pax dreht auf Violett */
.hw-gauge{ display:flex; align-items:center; gap:1.1em; padding:.3em 0 .5em; }
.hw-ring{ position:relative; width:5.4em; height:5.4em; border-radius:50%; flex:none;
  background:conic-gradient(var(--gcol,var(--tech)) calc(var(--val,80)*1%), var(--line-soft) 0); }
.hw-ring i{ position:absolute; inset:.72em; border-radius:50%; background:var(--surface);
  display:grid; place-items:center; font-weight:700; font-size:1.2em; letter-spacing:-.02em; }
.hw-gauge .gtxt{ min-width:0; }
.hw-gauge .gtxt b{ display:block; font-size:.95em; }
.hw-gauge .gtxt span{ display:block; font-size:.8em; color:var(--muted-readable); margin-top:.15em; }
.hw.ist-pax .hw-ring{ --gcol:var(--ai); }
.hw.ist-tender .hw-ring{ --gcol:var(--orange); }
/* Progress-Balken in Tabellenzellen (coole Tabellen) */
.hw-mini{ height:.5em; border-radius:99px; background:var(--line-soft); overflow:hidden; min-width:3em; }
.hw-mini > i{ display:block; height:100%; border-radius:99px; background:var(--tech); }
/* Dokument-Vorschau (Vertrag, Lebenslauf …) — ein „Blatt" mit Skelettzeilen */
.hw-doc{ background:var(--surface); border:1px solid var(--line); border-radius:var(--r-sm);
  padding:1em 1.1em; box-shadow:0 .6em 1.4em -.9em rgba(8,40,34,.28); display:flex;
  flex-direction:column; gap:.6em; flex:1 1 auto; min-height:0; }
.hw-doc .dh{ display:flex; align-items:center; gap:.5em; }
.hw-doc .dh svg{ width:1em; height:1em; color:var(--muted-readable); }
.hw-doc .dt{ font-size:.82em; font-weight:600; }
.hw-doc .dl{ height:.5em; border-radius:99px; background:var(--line-soft); }
.hw-doc .dl.xs{ width:42%; } .hw-doc .dl.s{ width:64%; } .hw-doc .dl.m{ width:86%; } .hw-doc .dl.l{ width:100%; }
.hw-doc .dl.mint{ background:var(--tech-soft); }
.hw-doc .dgap{ flex:1 1 auto; min-height:.4em; }
.hw-doc .dsig{ display:flex; gap:1em; margin-top:.2em; }
.hw-doc .dsig .box{ flex:1 1 0; border-top:1.5px solid var(--line); padding-top:.45em;
  display:flex; align-items:center; gap:.4em; font-size:.72em; color:var(--muted-readable); }
.hw-doc .dsig .box svg{ width:1em; height:1em; color:var(--green-600); flex:none; }
/* Zwei-Spalten (Dokument + Auswertung) */
.hw-split{ display:grid; grid-template-columns:.82fr 1fr; gap:.85em; flex:1 1 auto; min-height:0; }
.hw-split > *{ min-height:0; min-width:0; }
/* ---- Mehr TÜRKIS-Akzente auf VMS + Compliance (Basis-.hw, Hero-Look) ----
   Pax (ist-pax) bleibt violett, Tender (ist-tender) orange. */
.hw:not(.ist-pax):not(.ist-tender) .hw-bar .dot{ background:var(--tech); }
.hw:not(.ist-pax):not(.ist-tender) .hw-barcol.hoch .bar{ background:var(--tech-soft); }
.hw:not(.ist-pax):not(.ist-tender) .hw-kpi{ border-top:2px solid var(--tech-soft); }
.hw:not(.ist-pax):not(.ist-tender) .hw-ring{ --gcol:var(--tech); }
.hw:not(.ist-pax):not(.ist-tender) .hw-mini > i{ background:var(--tech); }
/* Icon-Chips EINHEITLICH: Topbar-Icon (.tic) UND Karten-Icon (.hw-cic) gleich —
   sonst erscheint dasselbe Icon in zwei Toenen (Karoline). */
.hw:not(.ist-pax):not(.ist-tender) .hw-cic,
.hw:not(.ist-pax):not(.ist-tender) .hw-bar .tic,
.hw:not(.ist-pax):not(.ist-tender) .hw-node .hw-av{ background:var(--tech-soft); color:var(--green-800); }
.hw:not(.ist-pax):not(.ist-tender) .hw-doc .dl.mint{ background:var(--tech); }
/* ---- Aktives Menü-Kästchen = Punkt/Frame (Karoline) ----
   Hardcodiertes .an neutralisieren, dann das dem Frame/Feature entsprechende
   Kästchen setzen — in der Seitenfarbe. */
.hw-rail i.an{ background:var(--line-soft); }
[data-frame="0"] .hw-rail i:nth-of-type(1),
[data-frame="1"] .hw-rail i:nth-of-type(2),
[data-frame="2"] .hw-rail i:nth-of-type(3),
[data-frame="3"] .hw-rail i:nth-of-type(4),
.viz-ampel .hw-rail i:nth-of-type(1),
.viz-abruf .hw-rail i:nth-of-type(2),
.viz-rueck .hw-rail i:nth-of-type(3){ background:var(--tech-soft); }
.ht-block[data-i="0"] .hw-rail i:nth-of-type(1),
.ht-block[data-i="1"] .hw-rail i:nth-of-type(2),
.ht-block[data-i="2"] .hw-rail i:nth-of-type(3),
.ht-block[data-i="3"] .hw-rail i:nth-of-type(4){ background:var(--orange-tint); }
.viz-cv .hw-rail i:nth-of-type(1),
.viz-interview .hw-rail i:nth-of-type(2),
.viz-score .hw-rail i:nth-of-type(3),
.viz-assist .hw-rail i:nth-of-type(4){ background:var(--ai-tint); }
/* ---- Kanban-Board ---- */
.hw-board{ display:grid; grid-template-columns:repeat(3,1fr); grid-template-rows:1fr; gap:.55em; flex:1 1 auto; min-height:0; }
.hw-col{ background:var(--surface-2); border-radius:var(--r-sm); padding:.55em; display:flex; flex-direction:column; gap:.45em; min-width:0; align-self:stretch; }
.hw-col .cnd, .hw-col .hw-cand{ flex:none; }
.hw-col::after{ content:""; flex:1 1 auto; min-height:1.5em; }
.hw-col .cht{ display:flex; align-items:center; justify-content:space-between; font-size:.68em; font-weight:600; color:var(--muted-readable); padding:.1em .25em; }
.hw-col .cht .z{ font-family:var(--mono,monospace); font-size:.9em; }
.hw-cand{ background:var(--surface); border:1px solid var(--line); border-radius:.45em; padding:.42em .5em;
  display:flex; align-items:center; gap:.45em; font-size:.72em; box-shadow:0 .3em .7em -.5em rgba(8,40,34,.25); min-width:0; }
.hw-cand .nm{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-cand .cnd{ display:flex; flex-direction:column; line-height:1.15; min-width:0; }
.hw-cand .cnd b{ font-size:1em; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-cand .cnd span{ font-size:.82em; color:var(--muted-readable); }
/* Board-Spalten fuellen die Hoehe, Karten oben gesammelt */
.hw-col{ justify-content:flex-start; }
.hw-col .hw-cand{ flex:none; }
/* ---- Chat ---- */
.hw-chat{ display:flex; flex-direction:column; gap:.75em; flex:1 1 auto; min-height:0; justify-content:flex-start; padding:.5em 0; }
.hw-msg{ max-width:82%; padding:.62em .85em; border-radius:.9em; font-size:.84em; line-height:1.45; }
.hw-msg.user{ align-self:flex-end; background:var(--surface-2); border-bottom-right-radius:.25em; }
.hw-msg.bot{ align-self:flex-start; background:var(--tech-soft); color:var(--green-800); border-bottom-left-radius:.25em; }
.hw.ist-pax .hw-msg.bot{ background:var(--ai-tint); color:var(--ai-ink); }
.hw-chat .tippen{ align-self:flex-start; display:flex; gap:.25em; padding:.5em .7em; }
.hw-chat .tippen span{ width:.4em; height:.4em; border-radius:50%; background:var(--muted); opacity:.5; }
/* ---- Schicht-Kalender ---- */
.hw-cal{ display:grid; grid-template-columns:repeat(5,1fr); grid-template-rows:auto 1fr;
  gap:.5em; flex:1 1 auto; min-height:0; }
.hw-cal .ch{ font-size:.66em; text-align:center; color:var(--muted); text-transform:uppercase; letter-spacing:.04em; padding-bottom:.1em; }
.hw-cal .cell{ border:1px solid var(--line-soft); border-radius:.5em; padding:.35em; display:flex;
  flex-direction:column; gap:.35em; min-height:0; }
.hw-shift{ font-size:.64em; border-radius:.4em; padding:.4em .4em; background:var(--tech-soft);
  color:var(--green-800); flex:1 1 0; display:flex; flex-direction:column; justify-content:center;
  gap:.1em; text-align:center; line-height:1.15; }
.hw-shift b{ font-weight:600; } .hw-shift span{ opacity:.7; font-size:.9em; }
.hw-shift.warn{ background:var(--amber-bg); color:var(--amber-ink); }
.hw-shift.leer{ background:transparent; color:var(--muted); border:1px dashed var(--line); }
/* ---- Fristen/Deadline-Liste (Countdown-Badges) ---- */
.hw-frist{ display:flex; align-items:center; gap:.75em; padding:.6em 0; border-top:1px solid var(--line-soft); }
.hw-frist:first-of-type{ border-top:0; }
.hw-frist .badge{ flex:none; min-width:3em; text-align:center; border-radius:.45em; padding:.35em .3em;
  font-size:.82em; font-weight:700; background:var(--tech-tint); color:var(--green-800); line-height:1.05; }
.hw-frist .badge small{ display:block; font-size:.62em; font-weight:500; opacity:.8; }
.hw-frist .badge.warn{ background:var(--amber-bg); color:var(--amber-ink); }
.hw-frist .badge.rt{ background:color-mix(in srgb,var(--red) 13%, transparent); color:var(--red); }
.hw-frist .fr-txt{ min-width:0; flex:1 1 auto; }
.hw-frist .fr-txt b{ display:block; font-size:.84em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-frist .fr-txt span{ display:block; font-size:.74em; color:var(--muted-readable); }
/* ---- hervorgehobene Tabellenzeile (z. B. guenstigstes Angebot) ---- */
.hw-tr.top{ background:var(--tech-tint); border-radius:.4em; margin:0 -.5em; padding-left:.5em; padding-right:.5em; }
.hw.ist-tender .hw-tr.top{ background:var(--orange-tint); }
/* ---- Timeline / Checkliste ---- */
.hw-steps{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; justify-content:space-evenly; padding:.3em 0; }
.hw-step{ display:grid; grid-template-columns:auto 1fr; gap:.85em; align-items:start; position:relative; padding:.4em 0; }
.hw-step::before{ content:""; position:absolute; left:.62em; top:1.7em; height:calc(100% + .2em); width:2px; background:var(--line-soft); }
.hw-step:last-child::before{ display:none; }
.hw-step .dot{ width:1.35em; height:1.35em; border-radius:50%; display:grid; place-items:center; background:var(--tech-soft); color:var(--green-800); z-index:1; flex:none; }
.hw-step .dot svg{ width:.85em; height:.85em; }
.hw-step.offen .dot{ background:var(--line-soft); color:var(--muted); }
.hw-step .st-txt b{ display:block; font-size:.86em; font-weight:600; }
.hw-step .st-txt span{ display:block; font-size:.78em; color:var(--muted-readable); margin-top:.1em; }
/* ---- Matrix (Zeilen × Spalten) ---- */
.hw-matrix{ display:grid; gap:1px; background:var(--line-soft); border:1px solid var(--line-soft);
  border-radius:.5em; overflow:hidden; flex:0 0 auto; }
.hw-matrix > span{ background:var(--surface); padding:.6em .7em; font-size:.8em; display:flex; align-items:center; }
.hw-matrix > .mh{ background:var(--surface-2); font-weight:600; font-size:.72em; color:var(--muted-readable);
  text-transform:uppercase; letter-spacing:.03em; }
.hw-matrix > .mr{ font-weight:600; }
.hw-matrix > .mv{ justify-content:flex-end; font-variant-numeric:tabular-nums; }
.hw-matrix > .mv.hi{ color:var(--green-800); font-weight:600; }
/* Coverage-Balken im Schicht-Block (weniger „Säule", mehr Belegung) */
.hw-shift{ justify-content:flex-start !important; gap:.35em !important; padding:.5em .45em !important; }
.hw-shift .cov{ height:.35em; border-radius:99px; background:rgba(255,255,255,.55); overflow:hidden; margin-top:auto; }
.hw-shift .cov > i{ display:block; height:100%; border-radius:99px; background:currentColor; opacity:.55; }
/* ---- Belegungs-Heatmap (Schichten × Tage) ---- */
.hw-heat{ display:grid; grid-template-columns:.9fr repeat(5,1fr); gap:.4em; flex:1 1 auto; min-height:0; }
.hw-heat > span{ display:flex; align-items:center; justify-content:center; font-size:.74em; min-width:0; }
.hw-heat .hh{ color:var(--muted); text-transform:uppercase; font-size:.64em; letter-spacing:.04em; align-self:end; }
.hw-heat .rl{ justify-content:flex-start; font-weight:600; color:var(--ink-soft); font-size:.78em; }
.hw-heat .cell{ border-radius:.45em; padding:.35em; flex-direction:column; gap:.05em; font-weight:600; line-height:1.1; }
.hw-heat .cell.full{ background:var(--tech-soft); color:var(--green-800); }
.hw-heat .cell.part{ background:var(--amber-bg); color:var(--amber-ink); }
.hw-heat .cell.open{ background:color-mix(in srgb,var(--red) 13%, transparent); color:var(--red); }
.hw-heat .cell small{ font-size:.66em; font-weight:500; opacity:.85; }
/* ---- Donut/Pie-Chart ---- */
.hw-pie{ display:flex; align-items:center; gap:1.5em; flex:1 1 auto; min-height:0; padding:.6em 0; }
.hw-donut{ width:10.5em; height:10.5em; border-radius:50%; flex:none; position:relative; }
.hw-donut > i{ position:absolute; inset:2.2em; border-radius:50%; background:var(--surface);
  display:grid; place-items:center; text-align:center; }
.hw-donut > i b{ font-size:1.1em; font-weight:700; letter-spacing:-.02em; }
.hw-donut > i span{ font-size:.62em; color:var(--muted-readable); }
.hw-legend{ display:flex; flex-direction:column; gap:.55em; min-width:0; flex:1 1 auto; }
.hw-leg{ display:flex; align-items:center; gap:.55em; font-size:.82em; }
.hw-leg .sw{ width:.85em; height:.85em; border-radius:.25em; flex:none; }
.hw-leg .nm{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hw-leg .lv{ margin-left:auto; font-weight:600; font-variant-numeric:tabular-nums; }
/* Karten-Footer: sitzt unten fest (margin-top:auto), ankert die Karte, wenn der
   Inhalt kurz ist — die Mitte wird Luft statt „leerem Ende" (Karoline). */
.hw-cfoot{ margin-top:auto; padding-top:.7em; border-top:1px solid var(--line-soft);
  display:flex; align-items:center; gap:.5em; font-size:.76em; color:var(--muted-readable); }
.hw-cfoot .dots{ display:inline-flex; gap:.3em; }
.hw-cfoot .dots i{ width:.4em; height:.4em; border-radius:50%; background:var(--line); }
.hw-cfoot .act{ margin-left:auto; color:var(--green-700); font-weight:600; display:inline-flex; align-items:center; gap:.3em; }
.hw-cfoot .act svg{ width:.9em; height:.9em; }
.hw.ist-pax .hw-cfoot .act{ color:var(--ai-ink); }
.hw.ist-tender .hw-cfoot .act{ color:var(--orange); }
/* Zeilen in fuellenden Karten etwas luftiger, wenn wenige da sind */
.hw-card.fill > .hw-row{ padding-block:.62em; }
/* Ausschnitt-Variante: gleiches .hw-Design, laeuft aber rechts aus dem Rahmen
   (Karoline 01.09.2026: „Ausschnitte bleiben, Stil anpassen"). Fuer Compliance/Pax. */
.hw.ist-ausschnitt{ right:auto; width:132%; }
/* Violett-Akzent (Pax): Icon-Chips + Avatare + Topbar-Icon in AI-Ton. */
.hw.ist-pax .hw-cic, .hw.ist-pax .hw-av, .hw.ist-pax .hw-bar .tic{ background:var(--ai-tint); color:var(--ai-ink); }
.hw.ist-pax .hw-bar .dot{ background:var(--ai-tint); }
.hw.ist-pax .hw-skel i.mint{ background:var(--ai-tint); }
/* Orange-Akzent (Tender): analog zu Pax, in Orange. */
.hw.ist-tender .hw-cic, .hw.ist-tender .hw-av, .hw.ist-tender .hw-bar .tic{ background:var(--orange-tint); color:var(--orange); }
.hw.ist-tender .hw-bar .dot{ background:var(--orange-tint); }
.hw.ist-tender .hw-skel i.mint{ background:var(--orange-tint); }
/* ---- Violett-Akzent fuer EIN Fenster: `.hw.ki` (07.09.2026) --------------
   Patrick: „macht die mal im Violett, sozusagen dass da auch visualisiert
   wird, dass da KI im Einsatz ist." Gemeint war das Fenster „KI-Matching"
   im Schritt-2-Block von bausteine/so-funktionierts.html.

   Das ist kein Bruch mit DESIGN.md §4 („Violett NUR Pax AI"), sondern der
   dort ausdruecklich genannte Fall: „Violett/Orange nur, wenn eine Serie
   bewusst ‚AI' bzw. ‚Prioritaet' bedeutet" (Abschnitt Chart-Farben).

   ⚠ VORHER WAR AN DER KARTE NICHTS ZU SEHEN, WAS SIE VON DEN DREI ANDEREN
   SCHRITTEN UNTERSCHEIDET: Spitzenbalken, Icon-Chip, Topbar-Icon und das
   aktive Menue-Kaestchen trugen alle --orange-tint, den Produktakzent der
   ist-tender-Fassung. Der Balken „lief mit", er sagte nichts.

   `.ki` sitzt deshalb auf dem FENSTER (.hw) und nicht auf der Karte: ein
   halb violettes Fenster (violette Karte, oranges Fenstersymbol) liest sich
   als Versehen. Wer nur die Karte will, setzt die Klasse eine Ebene tiefer
   und passt die vier Selektoren an.

   ⚠ REIHENFOLGE: `.hw.ki .hw-barcol.hoch .bar` hat dieselbe Spezifitaet
   (0,5,0) wie `.hw.ist-tender .hw-barcol.hoch .bar` weiter oben und wirkt
   nur, weil dieser Block DAHINTER steht. Dasselbe gilt fuer .hw-cic/.tic
   gegen die ist-tender-Zeilen direkt darueber (0,4,0 gegen 0,3,0 — die
   gewinnen zwar auch von vorn, bleiben aber der Lesbarkeit wegen hier).
   Nicht nach oben verschieben.

   Zwei Balkenstufen, alles aus zentralen Tokens, kein neuer Farbwert.
   Gemessen auf --surface: --ai-mid 3,98:1 (Grafik, 3:1 verlangt),
   --ai-ink 9,66:1 (Text).
   ⚠ `.hw.ist-pax` weiter oben ist derselbe Gedanke fuer die ganze Pax-Seite.
   Wer pax-ai neu baut, nimmt `.ki` und legt keine dritte Variante an. */
.hw.ki .hw-barcol .bar{ background:var(--ai-tint); }
.hw.ki .hw-barcol.hoch .bar{ background:var(--ai-mid); }
.hw.ki .hw-barcol.hoch .bl{ color:var(--ai-ink); font-weight:600; }
.hw.ki .hw-cic, .hw.ki .hw-av, .hw.ki .hw-bar .tic{ background:var(--ai-tint); color:var(--ai-ink); }
.hw.ki .hw-bar .dot{ background:var(--ai-tint); }
/* Das aktive Menue-Kaestchen in der Schiene. Parallel zu den Zeilen bei
   „Aktives Menue-Kaestchen = Punkt/Frame" weiter oben, nur violett. */
.ht-block[data-i="1"] .hw.ki .hw-rail i:nth-of-type(2){ background:var(--ai-tint); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.orange{ background:var(--orange-tint); color:var(--orange); }

/* ---- Kopfzeile ---------------------------------------------------- */
.mock-kette .mock-kopf{
  flex:0 0 auto; display:flex; align-items:center; gap:.8em;
  padding:1.15em 1.4em; border-bottom:1px solid var(--line-soft);
}
.mock-kette .mock-titel{
  display:flex; align-items:center; gap:.55em;
  font-size:1.45em; font-weight:600; letter-spacing:-.01em; white-space:nowrap;
}
.mock-kette .mock-titel svg{ width:1.05em; height:1.05em; color:var(--green-700); }
.mock-kette .mock-kopf-rechts{ margin-left:auto; display:flex; gap:.6em; flex:none; }
.mock-kette .mock-knopf{
  font-size:.95em; font-weight:600; white-space:nowrap;
  padding:.55em 1em; border-radius:.75em;
  border:1px solid var(--line); background:var(--surface); color:var(--ink-soft);
}
.mock-kette .mock-knopf.primaer{
  background:var(--green-700); border-color:var(--green-700); color:var(--surface);
}
.mock-kette .mock-zurueck{
  width:1.5em; height:1.5em; flex:none; display:grid; place-items:center;
  color:var(--muted);
}
.mock-kette .mock-zurueck svg{ width:1em; height:1em; }

/* ---- Reiterleiste mit Zaehlern ------------------------------------ */
.mock-kette .mock-reiter{
  flex:0 0 auto; display:flex; gap:.5em; padding:1em 1.4em 0;
  min-width:0;
}
.mock-kette .mock-reiter-el{
  flex:0 0 auto; display:flex; flex-direction:column; gap:.25em;
  padding:.7em 1em; border-radius:.7em .7em 0 0;
  border:1px solid var(--line); border-bottom:0;
  background:var(--surface); white-space:nowrap;
}
.mock-kette .mock-reiter-el .r-name{ font-size:.95em; font-weight:600; color:var(--ink-soft); }
.mock-kette .mock-reiter-el .r-zahl{ font-size:.85em; color:var(--muted); }
.mock-kette .mock-reiter-el.an{ background:var(--tech-tint); border-color:var(--tech-soft); }
.mock-kette .mock-reiter-el.an .r-name{ color:var(--green-700); }

/* ---- Tabelle ------------------------------------------------------ */
.mock-kette .mock-tabelle{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column; }
.mock-kette .mock-kopfzeile,
.mock-kette .mock-zeile{
  display:grid; align-items:center; gap:1em;
  padding:.95em 1.4em; border-top:1px solid var(--line-soft);
}
.mock-kette .mock-kopfzeile{
  border-top:1px solid var(--line);
  font-size:.9em; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted);
}
.mock-kette .mock-zelle{ min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; font-size:1.05em; }
.mock-kette .mock-zelle.stark{ font-weight:600; }
.mock-kette .mock-zelle.leise{ color:var(--muted-readable); }
.mock-kette .mock-zahl{ font-variant-numeric:tabular-nums; font-weight:600; }

/* ---- Chips, Pillen, Avatare -------------------------------------- */
/* ⚠ GILT FUER BEIDE WURZELN. Der Chip ist ein geteilter Grundbaustein: die
   aufploppenden Kaesten im Hero brauchen ihn genauso wie die Kettenbilder.
   Vorher stand hier nur `.mock-kette`, und die Status standen daneben als
   nackter Text ohne Flaeche.
   `:is()` nimmt die hoechste Spezifitaet seiner Argumente, alle sind einzelne
   Klassen — also unveraendert (0,2,0), keine Kaskadenverschiebung.
   ⚠ .mock-melder KAM AM 21.08.2026 DAZU. Der Fensterstapel im Hero ist die
   dritte Wurzel, in der Chips vorkommen: auf pax-ai-neu.html markiert er die
   KI-Vorschlaege. Ohne diesen Zusatz greift KEINE Chip-Regel und die Chips
   stehen als nackter Text in der Zeile — gemessen genau so aufgefallen.
   Fuer compliance.html aendert sich nichts: deren Melder fuehrt keine Chips.
   ⚠ .mock-uc ist die vierte Wurzel, die anklickbare Bildflaeche derselben
   Seite. Sie traegt `mock-` genau deswegen: NAMING.md gibt das Praefix allem,
   was innerhalb eines Produkt-Mockups liegt, und nur so ist auf einen Blick
   klar, warum sie in dieser Liste stehen darf. */
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip{
  display:inline-flex; align-items:center; gap:.4em;
  font-size:.9em; font-weight:600; white-space:nowrap;
  padding:.35em .75em; border-radius:.6em;
  background:var(--line-soft); color:var(--muted-readable);
}
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip::before{
  content:""; width:.42em; height:.42em; border-radius:50%; background:currentColor; flex:none;
}
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.gruen{ background:var(--tech-soft); color:var(--green-800); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.gelb{ background:var(--amber-bg); color:var(--amber-ink); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.blau{ background:var(--blue-bg); color:var(--blue-ink); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.rot{ background:color-mix(in srgb, var(--red) 12%, transparent); color:var(--red); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.stumm{ background:var(--line-soft); color:var(--muted); }
/* Die fehlende Stufe: KI-Violett. Das Chip-Muster hatte gruen/gelb/blau/rot/stumm, aber
   keinen Ton fuer „das hat die KI beigetragen" — im Produkt ist genau das lila markiert.
   Gehoert zum Bauteil und nicht in eine Seite; --ai-ink ist laut DESIGN.md §4 der
   AAA-taugliche Textton auf --ai-tint. NUR Pax AI. */
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.ai{ background:var(--ai-tint); color:var(--ai-ink); }
:is(.mock-kette, .mock-melder, .mock-uc, .hw) .mock-chip.ohne-punkt::before{ display:none; }

.mock-kette .mock-pille{
  display:inline-flex; align-items:center; gap:.35em;
  font-size:.9em; font-weight:600;
  padding:.3em .65em; border-radius:.5em;
  background:var(--blue-bg); color:var(--blue-ink);
}
.mock-kette .mock-pille svg{ width:.85em; height:.85em; }

.mock-kette .mock-person{ display:flex; align-items:center; gap:.7em; min-width:0; }
.mock-kette .mock-av{
  width:1.9em; height:1.9em; flex:none; border-radius:50%;
  display:grid; place-items:center;
  font-size:.85em; font-weight:600; letter-spacing:.02em;
  background:var(--tech-tint); color:var(--green-700);
}
.mock-kette .mock-av.b{ background:var(--blue-bg); color:var(--blue-ink); }
.mock-kette .mock-av.c{ background:var(--amber-bg); color:var(--amber-ink); }

/* ---- Wizard: Schrittleiste + Formular ---------------------------- */
.mock-kette .mock-app{ flex:1 1 auto; min-height:0; display:flex; }
.mock-kette .mock-schritte{
  flex:0 0 14em; display:flex; flex-direction:column; gap:.2em;
  padding:1.2em .9em; border-right:1px solid var(--line-soft);
}
.mock-kette .mock-schritt{
  display:flex; align-items:center; gap:.7em;
  padding:.6em .7em; border-radius:.7em;
  font-size:1em; color:var(--muted-readable); white-space:nowrap;
}
.mock-kette .mock-schritt-icon{
  width:1.8em; height:1.8em; flex:none; border-radius:50%;
  border:1px solid var(--line); display:grid; place-items:center;
  color:var(--muted);
}
.mock-kette .mock-schritt-icon svg{ width:.9em; height:.9em; }
.mock-kette .mock-schritt.an{ background:var(--line-soft); color:var(--ink); font-weight:600; }
.mock-kette .mock-schritt.an .mock-schritt-icon{
  border-color:var(--green-600); color:var(--green-700); background:var(--tech-tint);
}

.mock-kette .mock-form{ flex:1 1 auto; min-width:0; padding:1.4em 1.6em; }
.mock-kette .mock-abschnitt{
  font-size:1.25em; font-weight:600; margin:0 0 .5em;
  padding-bottom:.5em; border-bottom:1px solid var(--line-soft);
}
.mock-kette .mock-abschnitt + .mock-feld{ margin-top:1em; }
.mock-kette .mock-feld{ margin-bottom:1em; }
.mock-kette .mock-label{
  display:block; font-size:.95em; color:var(--ink-soft); margin-bottom:.4em;
}
.mock-kette .mock-label i{ color:var(--red); font-style:normal; }
.mock-kette .mock-eingabe{
  display:flex; align-items:center; gap:.5em;
  height:2.6em; padding:0 .9em;
  border:1px solid var(--line); border-radius:.7em;
  background:var(--surface); font-size:1.05em; color:var(--ink);
}
.mock-kette .mock-eingabe.leer{ color:var(--muted); }
.mock-kette .mock-eingabe.hoch{ height:5em; align-items:flex-start; padding-top:.7em; }
.mock-kette .mock-eingabe .pfeil{ margin-left:auto; color:var(--muted); flex:none; }
.mock-kette .mock-eingabe .pfeil svg{ width:.9em; height:.9em; display:block; }
.mock-kette .mock-form-fuss{ display:flex; justify-content:flex-end; padding-top:.4em; }

/* ---- Sichtschutz: nach rechts und unten weicher Auslauf ----------
   Ohne das endet der Ausschnitt als harte Kante mitten in einer Zeile.
   Der Schleier gehoert IN die Karte, damit die Rundung erhalten bleibt. */
.mock-kette .mock-schleier{
  position:absolute; inset:0; pointer-events:none; z-index:5;
  /* ⚠ NUR noch der rechte Anschnitt-Verlauf. Der frühere UNTERE Verlauf
     (green-900 nach unten) legte sich bei kurzen Inhalten über die leere weiße
     Panelfläche und ergab einen grauen „Glanz"-Streifen (Karoline 01.09.2026).
     Der rechte Verlauf blendet den bewussten Rechts-Anschnitt (width:126%) sauber
     in den grünen Grund. */
  background:
    linear-gradient(to right, transparent 62%, color-mix(in srgb, var(--green-900) 62%, transparent));
}

@media (prefers-reduced-motion:reduce){
  .mock-kette .mock-rahmen{ box-shadow:none; }
}

/* ---- Spaltenraster je Tabelle ------------------------------------- */
.mock-kette .mock-t-bedarf .mock-kopfzeile,
.mock-kette .mock-t-bedarf .mock-zeile{ grid-template-columns:2.2fr 1.3fr 1fr .7fr 1fr; }
/* ⚠ Reihenfolge Titel | Status | Verteilung | Besetzt | Bewerbungen ist Absicht:
   die Buehne zeigt bei 1440px nur die ersten ~3,5 Spalten. Stand Verteilung
   hinten, war die ABC-Gruppe im Beschnitt unsichtbar — und genau die soll das
   Bild zeigen. */
.mock-kette .mock-t-bewerbung .mock-kopfzeile,
.mock-kette .mock-t-bewerbung .mock-zeile{ grid-template-columns:1.8fr 1.4fr 1.7fr 1.1fr 1fr; }

/* ============================================================
   Bausteine fuer Glied 02 (Einsatzmanagement)
   ============================================================ */

/* ---- Kennzahlenkacheln ueber der Tabelle -------------------------- */
.mock-kette .mock-kacheln{
  flex:0 0 auto; display:flex; gap:.8em; padding:1.1em 1.4em .2em;
}
.mock-kette .mock-kachel{
  /* 0 1: darf bei Platzmangel schrumpfen, statt aus dem Rahmen zu laufen und
     mitten im Wort abgeschnitten zu werden (Formatfehler „Max. Einsat…" bei
     einsatzmanagement, 70px Ueberlauf gemessen). Titel/Sub tragen Ellipsis. */
  flex:0 1 12.5em; min-width:0;
  border:1px solid var(--line); border-radius:.8em; padding:.9em 1em;
  background:var(--surface);
}
.mock-kette .mock-kachel .k-titel{
  display:block; font-size:.95em; font-weight:600; color:var(--ink-soft);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.mock-kette .mock-kachel .k-zeile{ display:flex; align-items:center; gap:.55em; margin-top:.6em; }
.mock-kette .mock-kachel .k-icon{
  width:1.6em; height:1.6em; flex:none; border-radius:.4em;
  display:grid; place-items:center; background:var(--tech-tint); color:var(--green-700);
}
.mock-kette .mock-kachel .k-icon svg{ width:.95em; height:.95em; }
.mock-kette .mock-kachel .k-icon.gelb{ background:var(--amber-bg); color:var(--amber-ink); }
.mock-kette .mock-kachel .k-zahl{
  font-size:2em; font-weight:var(--fw-head); line-height:1;
  font-variant-numeric:tabular-nums; color:var(--ink);
}
.mock-kette .mock-kachel .k-sub{
  display:block; margin-top:.5em; font-size:.85em; color:var(--muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* ---- Ampel der Dokumententabelle --------------------------------- */
.mock-kette .mock-ampel{
  display:inline-block; width:.62em; height:.62em; border-radius:50%;
  background:var(--green-600);
}
.mock-kette .mock-ampel.rot{ background:var(--red); }
/* Grau ist eine echte Stufe der CompliancePro-Ampel, nicht Deko:
   rot = AÜ-Erlaubnis fehlt, grau = Erlaubnis vorhanden, gruen = alle
   Anforderungen erfuellt. Ohne diese Stufe muesste compliance-neu.html
   den Status inline einfaerben (Regel 2). */
.mock-kette .mock-ampel.grau{ background:var(--muted); }

/* ---- Anbieterkarte der Compliance-Ampel --------------------------
   NACHBAU EINER ECHTEN PRODUKTANSICHT. Vorlage sind zwei Screenshots aus dem
   laufenden CompliancePro, die Patrick am 21.08.2026 geliefert hat
   (`Ampel.png`, 504x216). Uebernommen sind Aufbau und Wortlaut: Kopfzeile mit
   Anbieterlogo, Name, ANUE-Abzeichen und Statuspunkt, darunter drei Pruefzeilen
   (ANUE-Erlaubnis, Auskuenfte Krankenkassen, Auskuenfte Berufsgenossenschaften),
   je mit einem Ringpunkt rechts.

   ⚠ NACHGEBAUT, NICHT EINGEBUNDEN. Die Vorlage ist eine 1x-Aufnahme mit 504px
   Breite; auf der ~600px breiten Bildbuehne muesste sie hochskaliert werden und
   stuende dann unscharf neben den scharfen Nachbauten in derselben Sektion.
   Dazu kommt: Kundenname und Logo mussten weg (Patrick ausdruecklich), und die
   Flaechen sollten auf die Tokens der Website. Damit war an der Vorlage nahezu
   jeder Pixel zu ersetzen — in dem Moment ist HTML das ehrlichere Medium als ein
   Bildeditor. Derselbe Grund wie beim Schaubild der Funktionsweise.

   ⚠ DER RINGPUNKT IST EIN EIGENES BAUTEIL, nicht `.mock-ampel`. Im Produkt ist
   es ein gefuellter Punkt IN einem duennen Ring; `.mock-ampel` ist der nackte
   Punkt der Dokumententabelle. Zwei Formen, zwei Namen — sonst haette eine der
   beiden Stellen einen Modifikator, der ihre Grundform aendert. */
/* ⚠ 73% BREIT, UND DAS IST GERECHNET, NICHT GESCHAETZT. Der Rahmen haengt
   absichtlich rechts aus der Buehne (`left:7%; width:126%`), sichtbar ist also
   93/126 = 73,8% seiner Breite. Bei den Tabellen ist der Beschnitt gewollt — bei
   dieser Karte NICHT: der Statuspunkt sitzt rechts, und ein Ampelbild, dessen
   Ampel ausserhalb des Bildes liegt, zeigt nichts. Gemessen lagen die Punkte vor
   der Korrektur rund 160px hinter der Kante. */
.mock-kette .mock-anbieterliste{
  flex:1 1 auto; min-height:0; width:73%; padding:1.1em 1.4em .3em;
}
.mock-kette .mock-anbieter{
  border:1px solid var(--line); border-radius:.9em;
  background:var(--surface); overflow:hidden;
}
.mock-kette .mock-anbieter + .mock-anbieter{ margin-top:.7em; }
.mock-kette .mock-anbieter-kopf{
  display:flex; align-items:center; gap:.85em;
  padding:.7em 1.05em; background:var(--line-soft);
  border-bottom:1px solid var(--line);
}
/* Initialen statt Logo: die Vorlage trug hier das Logo des echten Kunden. Eine
   Initialenflaeche ist die Form, die Produktoberflaechen ohne Logo ohnehin
   zeigen — sie erfindet also keine Marke. */
.mock-kette .mock-anbieter-logo{
  flex:none; width:2.2em; height:2.2em; border-radius:.55em;
  display:grid; place-items:center;
  background:var(--grad-dark); color:var(--tech);
  font-size:.95em; font-weight:600; letter-spacing:.02em;
}
.mock-kette .mock-anbieter-name{
  font-size:1.05em; font-weight:600; letter-spacing:-.01em;
  min-width:0; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
}
/* ⚠ EIGENE FLAECHE FUER DAS ABZEICHEN. `.mock-chip.stumm` fuellt mit
   `--line-soft` — genau der Farbe der Kopfzeile, der Chip war unsichtbar und
   stand als nackter Text da. Auf getoentem Grund braucht er Weiss und Rand. */
.mock-kette .mock-anbieter-kopf .mock-chip{
  margin-left:auto;
  background:var(--surface); border:1px solid var(--line);
  color:var(--muted-readable);
}
.mock-kette .mock-pruefzeile{
  display:flex; align-items:center; gap:1em;
  padding:.65em 1.05em; font-size:1.05em; color:var(--ink-soft);
}
.mock-kette .mock-pruefzeile + .mock-pruefzeile{ border-top:1px solid var(--line-soft); }
.mock-kette .mock-pruefzeile > span{ margin-left:auto; flex:none; }
.mock-kette .mock-ring{
  display:block; width:.85em; height:.85em; border-radius:50%;
  box-sizing:border-box; border:.13em solid var(--green-600);
  background:radial-gradient(circle, var(--green-600) 46%, transparent 48%);
}
.mock-kette .mock-ring.rot{
  border-color:var(--red);
  background:radial-gradient(circle, var(--red) 46%, transparent 48%);
}
/* ⚠ GRAU IST HOHL, nicht gefuellt. Direkt daneben steht die Legende, und dort
   ist `.licht.grau` ein leerer Kreis mit Rand — ein gefuellter dunkler Punkt im
   Bild und ein hohler in der Legende waeren zwei Zeichen fuer denselben Zustand.
   Hohl passt ausserdem zur Bedeutung: die Pruefung ist noch nicht abgeschlossen. */
.mock-kette .mock-ring.grau{ border-color:var(--muted); background:none; }

/* ---- Kennzahlfeld „Beitragsrueckstaende" -------------------------
   Zweite Vorlage desselben Satzes (`Beitragsrückstand.png`, 762x143): ein
   umrandetes Feld mit Beschriftung und Info-Zeichen, darin eine Zeile aus
   rot getoenter Markierung und der Zahl.
   ⚠ DIE ZAHL STEHT IN DER VORLAGE AUF 0, hier auf 2. Der Kasten illustriert den
   Satz „Rueckstaende fallen auf, bevor sie zu Ihrer Haftung werden", und die
   Tabelle darunter zeigt genau zwei Faelle in Klaerung. Eine Ansicht, die 0
   gefundene Rueckstaende zeigt, widerspricht beidem. */
.mock-kette .mock-rueckstand{
  flex:0 0 auto; margin:1.1em 1.4em .2em;
  border:1px solid var(--line); border-radius:.9em; overflow:hidden;
}
.mock-kette .mock-rueckstand-kopf{
  display:flex; align-items:center; gap:.45em;
  padding:.8em 1.05em; background:var(--line-soft);
  border-bottom:1px solid var(--line);
  font-size:1em; font-weight:600; color:var(--ink);
}
.mock-kette .mock-rueckstand-kopf svg{ width:1em; height:1em; color:var(--muted); }
/* Die Vorlage zeigt IM Feld noch einen eigenen umrandeten Kasten fuer den Wert
   — nicht Deko, daran erkennt man die Ansicht wieder. */
.mock-kette .mock-rueckstand-wert{
  display:flex; align-items:center; gap:.8em;
  margin:.85em 1.05em; padding:.75em .9em;
  border:1px solid var(--line); border-radius:.7em;
}
.mock-kette .mock-rueckstand-marke{
  flex:none; width:1.9em; height:1.9em; border-radius:.5em;
  display:grid; place-items:center;
  background:color-mix(in srgb, var(--red) 12%, transparent); color:var(--red);
}
.mock-kette .mock-rueckstand-marke svg{ width:1em; height:1em; }
.mock-kette .mock-rueckstand-zahl{
  font-size:1.7em; font-weight:700; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; color:var(--ink);
}

/* ---- Upload-Flaeche der Personalakte -----------------------------
   Die gestrichelte Flaeche ist die Signatur, an der man die Aktenansicht
   sofort erkennt — deshalb steht sie oben und nicht unter der Tabelle. */
.mock-kette .mock-ablage{
  flex:0 0 auto; margin:1.1em 1.4em .3em;
  border:1px dashed var(--line); border-radius:.8em;
  padding:1.1em; text-align:center; background:var(--surface);
}
.mock-kette .mock-ablage .a-icon{ color:var(--green-600); }
.mock-kette .mock-ablage .a-icon svg{ width:1.6em; height:1.6em; display:block; margin:0 auto .4em; }
.mock-kette .mock-ablage .a-text{ font-size:1em; color:var(--ink-soft); }
.mock-kette .mock-ablage .a-text u{ color:var(--green-700); font-weight:600; }
.mock-kette .mock-ablage .a-formate{ display:block; margin-top:.3em; font-size:.85em; color:var(--muted); }

.mock-kette .mock-dateiname{ display:flex; align-items:center; gap:.5em; min-width:0; }
.mock-kette .mock-dateiname svg{ width:1em; height:1em; flex:none; color:var(--muted); }

/* ---- Spaltenraster der drei neuen Tabellen ----------------------- */
.mock-kette .mock-t-einsatz .mock-kopfzeile,
.mock-kette .mock-t-einsatz .mock-zeile{ grid-template-columns:.9fr 1.9fr 1.5fr 1.3fr 1.4fr; }
.mock-kette .mock-t-person .mock-kopfzeile,
.mock-kette .mock-t-person .mock-zeile{ grid-template-columns:1.6fr 1.5fr .9fr 1.7fr 1.4fr; }
.mock-kette .mock-t-akte .mock-kopfzeile,
.mock-kette .mock-t-akte .mock-zeile{ grid-template-columns:1.8fr 1.3fr 1.4fr .6fr 1.1fr; }
/* ============================================================
   ENTFALLEN am 25.08.2026: `.mock-screen` mit `.mock-plopp`
   ============================================================
   Der Produktscreen als Standbild im Hero von workforce.html, mit den
   fuenf aufploppenden Kaesten darauf — 163 Zeilen. Kein Abnehmer mehr:
   der Hero traegt jetzt `.mock-melder`, und workforce war die einzige
   Seite mit `.mock-screen` (Klassensuche ueber alle Seiten, nicht
   geschaetzt).
   Was aus dem Block ueberlebt hat und wo es jetzt steht: die
   Balkenreihe des Auswertungs-Kastens, als `.mock-melder .mock-fbalken`.
   Die Bilddatei assets/hero/hero-produktscreen.png bleibt im Bestand,
   sie ist nur nicht mehr verlinkt.
   ============================================================ */

/* ============================================================
   .mock-melder — die Kaesten im Hero (workforce, compliance, tender)
   ============================================================
   Vorbild: beam.ai/de/lp/hr-rpo-recruitment. Dort steht rechts im Hero
   kein Produktbild, sondern eine Folge kleiner Kaesten: IMMER NUR EINER
   ist zu sehen, und nur waehrend der Uebergabe schaut der vorherige
   gedimmt darueber hervor.

   GEMESSEN, in zwei Schritten, weil der erste in die Irre fuehrte:
   1) Die Animation ist ein Lottie
      (framerusercontent.com/assets/y1VR0Q5MLJbGSJQL8FnObZy7Oiw.json).
      Darin steht fr=60, op=540 — also 9,0 s Umlauf — bei fuenf
      Kartenebenen, und die Nullobjekte fahren im Abstand von rund 2 s
      hoch und skalieren auf 75 %.
      ⚠ AUS DIESEN KEYFRAMES HABE ICH EINEN STAPEL GELESEN, DER NACH OBEN
      WAECHST — falsch. Die Deckkraft der obersten Ebene sagt nichts
      darueber, ob der Inhalt zu sehen ist: die Kaesten stecken sechs
      Ebenen tief in Precomps, und die Sichtbarkeit entscheidet sich dort
      unten. Patrick: „aber bei beam sieht man doch immer nur eine karte
      auf einmal?" — genau so ist es.
   2) 56 Einzelbilder der laufenden Seite im Abstand von 0,25 s. Die
      Helligkeitskurve wiederholt sich exakt bei 9,00 s, und die Bilder
      zeigen fuenf Karten in dieser Reihenfolge: „Top 20 candidates
      shortlisted", „Outreach sent to candidates", „Scheduler books
      interviews", „New job posted in ATS", „Candidates evaluated against
      role criteria". Daraus:
        · 1,8 s je Karte (9,0 s / 5)
        · rund 0,4 s Einzug
        · rund 0,4 s Uebergabe, in der die alte Karte gedimmt nach oben
          abzieht — mehr als zwei Karten sind NIE gleichzeitig da
      Diese Zahlen stehen hier 1:1. Am 25.08.2026 lief es zuerst mit 3,4 s
      („sieht bloed aus"), dann als vierstufiger Stapel mit 2,0 s (nicht,
      was die Vorlage tut). Jetzt: eine Karte, 1,8 s.

   ⚠ NICHT uebernommen: bei Beam waechst der Inhalt JEDER Karte noch
   waehrend sie steht (Listenzeilen und Chips erscheinen einzeln). Das ist
   eine eigene Animation je Karte; hier steht der Inhalt sofort. Wenn das
   dazukommen soll, ist es ein eigener Schritt.

   Den Weichzeichner der Vorlage (backdrop-filter: blur(10px) auf
   rgba(250,250,250,.8)) uebernehmen wir NICHT — DESIGN.md verbietet ihn;
   unsere Flaeche ist deckend.

   ⚠ DIE REGELN LAGEN VORHER DOPPELT INLINE in compliance.html und
   tender.html, mit abweichenden Positionen und Farben. Sie stehen jetzt
   hier, EINMAL. Das ist auch der Grund, warum das Inline-CSS beider
   Seiten kleiner geworden ist statt groesser (Regel 2).

   ⚠ z-index WIRD MITANIMIERT: die abziehende Karte steht im DOM teils
   NACH der einziehenden und wuerde sie sonst ueberdecken. Grid-Kinder
   beachten z-index auch ohne position, darum reicht das.

   ⚠ NEGATIVER VERSATZ statt positivem. Mit `animation-delay: i * takt`
   und `both` gilt vor dem eigenen Start der 0-%-Zustand — alle Kaesten
   waeren beim Laden gleichzeitig vorn. Mit `(i - n) * takt` startet
   jeder mitten im Umlauf und die Reihe steht von der ersten Sekunde an
   richtig.

   ⚠ DIE ANZAHL-KLASSE IST PFLICHT, und nicht nur wegen der Keyframes.
   Buehne, Kastenrahmen und die Spalten-Fassung haengen ebenfalls an
   `:is(.melder-3, .melder-5)`. Grund: compliance-neu.html und
   pax-ai-neu.html tragen dasselbe `.mock-melder`-Markup mit EIGENEM
   Inline-CSS (Entwuerfe, die noch nicht getauscht sind). Ohne die
   Klasse als Tuerwaechter haetten sie sich hier ungefragt 2,9 em
   Innenabstand und ein Raster eingefangen — eine zentrale Datei darf
   fremde Entwuerfe nicht anfassen.

   ⚠ NEGATIVER VERSATZ statt positivem. Mit `animation-delay: i * takt`
   und `both` gilt vor dem eigenen Start der 0-%-Zustand — alle Kaesten
   waeren beim Laden gleichzeitig vorn. Mit `(i - n) * takt` startet
   jeder mitten im Umlauf und die Reihe steht von der ersten Sekunde an
   richtig.
   ============================================================ */

.mock-melder:is(.melder-3, .melder-5){
  position:relative; width:100%;
  container-type:inline-size;
  /* Alle Kaesten in EINE Zelle. Sie sind Grid-Kinder, keine absoluten
     Kaesten — so braucht keiner eine eigene Position.
     ⚠ OBEN ausgerichtet, nicht mittig, und das ist der Kern des Stapels:
     bei mittiger Ausrichtung liegen die Mitten aufeinander, und der
     gedimmte Kasten verschwindet komplett hinter einem hoeheren
     vorderen (GEMESSEN: Listenkasten 200 px gegen Meldung 105 px). Oben
     ausgerichtet schaut er als Streifen darueber hervor — genau das,
     woran man bei Beam den Stapel erkennt.
     ⚠ KEINE aspect-ratio. Die Buehne war 5/4 und damit 530 px hoch fuer
     Kaesten von 200 px — halb leer. Jetzt bestimmt der Inhalt die Hoehe,
     min-height haelt sie beim Wechsel ruhig, und .ihero .wrap
     (align-items:center) stellt die Spalte mittig zum Text. */
  display:grid; grid-template-areas:"karte"; align-items:start;
  /* ⚠ 2.8s, NICHT MEHR 1.8s. Die 1,8 s waren aus dem Lottie von beam.ai
     ausgemessen (56 Bildschirmaufnahmen, Helligkeitskurve, 9,0 s fuer fuenf
     Karten) und Patricks damalige Vorgabe war ausdruecklich „so wie beam ai von
     geschwindigkeit". Neues Feedback am 26.08.2026: „rechts sollten die Dinger
     nochmal langsamer durchflippen". 2,8 s sind 55 % mehr Standzeit je Karte;
     bei melder-5 dauert eine Runde damit 14,0 s statt 9,0 s, bei melder-3
     8,4 s statt 5,4 s.
     EINE Zahl reicht: die Prozentwerte in den Keyframes sind Anteile der ganzen
     Runde, also skaliert das Ein- und Ausblenden mit. */
  --takt:2.8s;
  /* ⚠ HIER KEINE Schriftgroesse und KEINE Hoehe in cqw. Ein Element mit
     container-type kann sich selbst nicht abfragen: cqw sucht den
     naechsten VORFAHREN mit container-type und faellt sonst auf das
     Fenster zurueck. Auf preise.html hat genau das aus 15,5 px 37,4 px
     gemacht und die Karte auf 2214 px aufgeblasen. Die Schrift steht
     deshalb am Kasten, und die Hoehe der Buehne ist die des hoechsten
     Kastens — alle liegen in derselben Rasterzelle, also traegt die
     Zeile den hoechsten, unabhaengig davon, welcher gerade zu sehen
     ist. Kein Springen beim Wechsel, ohne eine einzige Zahl. */
}

.mock-melder:is(.melder-3, .melder-5) .mock-fenster{
  /* Kopfraum fuer die abziehende Karte (-2.4em) plus etwas Luft. */
  grid-area:karte; justify-self:center; align-self:start;
  margin-top:3.2em; width:80%; transform-origin:top center;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-lg);
  box-shadow:0 1.8em 4em -1.4em rgba(4,19,16,.55), 0 .3em .9em -.4em rgba(4,19,16,.35);
  font-size:max(12px, 2.45cqw); font-family:var(--sans); color:var(--ink);
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite;
  animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt));
}

.mock-melder.melder-3 .mock-fenster{ --n:3; animation-name:melder-3; }
.mock-melder.melder-5 .mock-fenster{ --n:5; animation-name:melder-5; }

/* Je Kasten ein Drittel des Umlaufs vorn, ein Drittel dahinter, ein
   Drittel unsichtbar. Der Sprung von oben-weg nach unten-wartend
   passiert in 0,01 % — sonst waere die Rueckreise als Flug quer durch
   das Bild zu sehen.
   ⚠ Die Prozente MUESSEN je Anzahl eigene Keyframes sein: sie beziehen
   sich auf die Gesamtdauer, und die haengt an --n. Mit einem Satz fuer
   alle gaebe es entweder eine Luecke ohne Karte oder einen Zustand mit
   zwei Karten vorn. Darum genau die Anzahlen, die vorkommen: 3
   (compliance, tender) und 5 (workforce). */
@keyframes melder-3{
  /* wartet unten, unsichtbar */
  0%           { opacity:0;   transform:translateY(2.2em)  scale(.96); z-index:2; }
  /* Einzug, 0,40 s */
  7.4%         { opacity:1;   transform:translateY(0)      scale(1);   z-index:5; }
  /* steht, bis der Takt um ist */
  33.3%        { opacity:1;   transform:translateY(0)      scale(1);   z-index:5; }
  /* Uebergabe: zieht nach oben ab, waehrend die naechste einzieht */
  41%          { opacity:0;   transform:translateY(-2.4em) scale(.93); z-index:3; }
  99.9%        { opacity:0;   transform:translateY(-2.4em) scale(.93); z-index:2; }
  100%         { opacity:0;   transform:translateY(2.2em)  scale(.96); z-index:2; }
}

@keyframes melder-5{
  0%           { opacity:0;   transform:translateY(2.2em)  scale(.96); z-index:2; }
  4.4%         { opacity:1;   transform:translateY(0)      scale(1);   z-index:5; }
  20%          { opacity:1;   transform:translateY(0)      scale(1);   z-index:5; }
  24.4%        { opacity:0;   transform:translateY(-2.4em) scale(.93); z-index:3; }
  99.9%        { opacity:0;   transform:translateY(-2.4em) scale(.93); z-index:2; }
  100%         { opacity:0;   transform:translateY(2.2em)  scale(.96); z-index:2; }
}

/* ---- Innenleben der Kaesten -------------------------------------
   Wortgleich aus den beiden Seiten-Styles uebernommen. Die
   Ampel-Stufen sind die ECHTEN aus dem Produkt (Notion „GTM
   CompliancePro" §7): rot = AUE-Erlaubnis fehlt, grau = Erlaubnis
   vorhanden, gruen = alle Anforderungen erfuellt. Keine Gelb-Stufe
   erfinden, die das Produkt nicht hat. */
.mock-melder .mock-fkopf{
  display:flex; align-items:center; gap:.7em;
  padding:1em 1.25em; border-bottom:1px solid var(--line-soft);
  font-size:.95em; font-weight:600; color:var(--ink);
}
.mock-melder .mock-fkopf svg{ width:1.15em; height:1.15em; flex:none; color:var(--green-700); }
.mock-melder .mock-fzahl{
  margin-left:auto; font-family:var(--mono); font-size:.82em;
  font-weight:500; color:var(--muted); font-variant-numeric:tabular-nums;
}

.mock-melder .mock-fzeile{
  display:flex; align-items:center; gap:.8em;
  padding:.85em 1.25em; border-top:1px solid var(--line-soft); font-size:.9em;
}
.mock-melder .mock-fzeile:first-of-type{ border-top:0; }
.mock-melder .mock-fname{ font-weight:500; color:var(--ink); }
.mock-melder .mock-fort{ margin-left:auto; color:var(--muted); font-size:.92em; }
.mock-melder .mock-status{
  width:.62em; height:.62em; border-radius:50%; flex:none; background:var(--muted);
}
.mock-melder .mock-status.gruen{ background:var(--green-500); box-shadow:0 0 0 .28em var(--tech-tint); }
.mock-melder .mock-status.rot{ background:var(--red); }

.mock-melder .mock-fmeld{ display:flex; gap:.85em; padding:1.1em 1.25em; }
.mock-melder .mock-fic{
  width:1.9em; height:1.9em; border-radius:var(--r-sm);
  display:grid; place-items:center; flex:none;
}
.mock-melder .mock-fic svg{ width:1.05em; height:1.05em; }
.mock-melder .mock-fic.warn{ background:var(--amber-bg); color:var(--amber-ink); }
.mock-melder .mock-fic.ok{ background:var(--tech-tint); color:var(--green-700); }
.mock-melder .mock-fic.ki{ background:var(--ai-tint); color:var(--ai-ink); }
.mock-melder .mock-ftitel{
  display:block; font-size:.92em; font-weight:600; color:var(--ink); margin-bottom:.2em;
}
.mock-melder .mock-ftext{ display:block; font-size:.85em; line-height:1.45; color:var(--muted-readable); }
.mock-melder .mock-ftext b{ font-weight:600; color:var(--ink-soft); }
.mock-melder .mock-fenster .mock-chip{ margin-top:.35em; }

/* Balkenreihe im Auswertungs-Kasten. Aus dem entfallenen .mock-screen
   uebernommen — die Hoehen stehen in der CSS und nicht als style-Attribut je
   Balken, sonst wandern Daten ins Markup. */
.mock-melder .mock-fbalken{ display:flex; align-items:flex-end; gap:.22em; height:1.5em; margin-top:.5em; }
.mock-melder .mock-fbalken i{ width:.36em; border-radius:.1em; background:var(--tech-soft); display:block; }
.mock-melder .mock-fbalken i:nth-child(1){ height:38%; }
.mock-melder .mock-fbalken i:nth-child(2){ height:62%; }
.mock-melder .mock-fbalken i:nth-child(3){ height:48%; }
.mock-melder .mock-fbalken i:nth-child(4){ height:80%; }
.mock-melder .mock-fbalken i:nth-child(5){ height:66%; }
.mock-melder .mock-fbalken i:nth-child(6){ height:100%; background:var(--green-600); }

/* ---- Ohne Wechsel: Telefon und reduzierte Bewegung ----------------
   Beide Faelle brauchen dasselbe — KEINE Bewegung und KEIN Stapel.
   Aus dem Raster wird eine Spalte, jeder Kasten steht ganz da. Nichts
   geht verloren; genau so loeste es tender.html vorher fuer schmale
   Fenster (Zeile 710 der alten Seiten-CSS). */
@media (max-width:760px), (prefers-reduced-motion:reduce){
  .mock-melder:is(.melder-3, .melder-5){
    display:flex; flex-direction:column; gap:.75em;
    aspect-ratio:auto; align-items:stretch;
  }
  .mock-melder:is(.melder-3, .melder-5) .mock-fenster{
    width:auto; animation:none; opacity:1; transform:none; z-index:auto;
  }
}

/* ============================================================
   .zb-* — die Zoom-Fokus-Buehne im Hero
   ============================================================
   Vorbild: die Lottie der ALTEN pactos.ai,
   cdn.prod.website-files.com/675c005f5589fc9dd1f1e1e0/6798d14e0fec38a840ed95b5_Animation.json
   (344 kB, 2076x1218, 30 fps, 376 Frames = 12,5 s). Ausgelesen, nicht
   geschaetzt, und zusaetzlich 15 Frames lokal mit lottie-web gerendert:

     · Ein Nullobjekt „Personal suchen" skaliert von 180 % auf 314 % und
       faehrt dabei nach links (Frames 76-106, also 1,0 s).
     · Die herausgezoomte Karte zeigt Inhalt, den sie klein NICHT hatte:
       ein ausgefuelltes Formular, danach ein Klick auf „An A senden".
     · Ein „Black Solid" dunkelt das Dashboard dahinter ab, Keyframes
       [(76, 0), (106, 50)].

   ⚠ „Zoom out" heisst hier NICHT, dass das Bild kleiner wird. Ein Element
   kommt aus der Uebersicht nach vorne, der Rest bleibt sichtbar. Das ist
   der ganze Trick: man sieht das Teil UND das Ganze.

   ⚠ DAS ABDUNKELN IST BEWUSST NICHT UEBERNOMMEN. Im Original gibt es ein
   Zoom-Ereignis je Runde, die Deckkraft geht also einmal hoch und bleibt.
   Hier ruecken drei bis fuenf Karten nacheinander vor — daraus wurden
   fuenfmal auf und ab, gemessen 10 Helligkeitswechsel je Runde. Patrick
   am 27.08.2026: „ich finde was noch so ein bisschen stoert ist das es
   immer ausgraut wenn ein anderes element rauszoomt". Vier Fassungen
   standen zur Wahl (1x je Runde mit sechstem, leerem Takt / je Karte /
   konstant / aus), Entscheidung: **aus**. Die vordere Karte traegt sich
   allein ueber ihren Schatten, und es gibt NULL Helligkeitswechsel.
   Die Messwerte der vier Fassungen stehen in KOMPATIBILITAET.md.

   ⚠ .mock-melder BLEIBT in dieser Datei stehen, obwohl die vier
   Produktseiten es nicht mehr fuehren: compliance-neu.html und
   pax-ai-neu.html sind Entwuerfe, die noch damit gebaut sind.
   ============================================================ */

.zb-buehne{
  position:relative; container-type:size; aspect-ratio:10 / 7;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-lg); overflow:hidden; isolation:isolate;
  box-shadow:0 1.8em 4em -1.4em rgba(4,19,16,.55), 0 .3em .9em -.4em rgba(4,19,16,.35);
  font-family:var(--sans); color:var(--ink);
  /* 3,6 s je Karte. Bewusst langsamer als der Kastenwechsel von
     .mock-melder (2,8 s): hier passiert waehrend der Standzeit etwas —
     Zoom, Inhalt einblenden, Zoom zurueck. */
  --takt:3.6s;
}
.zb-buehne.zb-3{ --n:3; }   /* Runde 10,8 s */
.zb-buehne.zb-5{ --n:5; }   /* Runde 18,0 s */

/* ---- Fenster-Chrome: Leiste links, Kopfzeile oben ----------------
   Reine Struktur, keine Daten — die Regel aus mock-modul.css
   („Struktur ja, Daten nein") gilt fuer das Geruest strikt. Inhalt
   fuehren nur die Karten. */
.zb-rail{ position:absolute; left:0; top:0; bottom:0; width:8%; z-index:2;
  background:var(--paper); border-right:1px solid var(--line-soft);
  display:flex; flex-direction:column; align-items:center; gap:6%; padding-top:1.5%; }
.zb-rail .zb-logo{ width:36%; flex:none; margin-bottom:3%; }
.zb-rail .zb-logo img{ width:100%; height:auto; display:block; }
.zb-rail i{ display:block; width:46%; aspect-ratio:1; border-radius:26%; background:var(--line-soft); }
/* :first-of-type statt :first-child (das Pactos-Logo steht als span davor). */
.zb-rail i:first-of-type{ border-radius:34%; }
/* zb-3 (z. B. Compliance): dieselbe Logik wie zb-5, nur drei Karten -> die ersten
   drei Kaestchen werden nacheinander mint. Fenster 7,5 %–25,83 % = Standzeit der
   Karte in zb-karte-3. */
.zb-3 .zb-rail i:nth-of-type(-n+3){
  animation-name:zb-rail-3;
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite;
  animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt));
}
.zb-3 .zb-rail i:nth-of-type(1){ --i:0; }
.zb-3 .zb-rail i:nth-of-type(2){ --i:1; }
.zb-3 .zb-rail i:nth-of-type(3){ --i:2; }
@keyframes zb-rail-3{
  0%     { background:var(--line-soft); }
  7.5%   { background:var(--tech-soft); }
  25.83% { background:var(--tech-soft); }
  30%    { background:var(--line-soft); }
  100%   { background:var(--line-soft); }
}
/* Die Kaestchen folgen der Zoom-Animation: das Kaestchen zur gerade gezoomten
   Karte wird mint, dann wieder grau — gleiche Dauer/Delay wie .zb-karte, damit es
   synchron laeuft (Fenster 4,5 %–15,5 % = Standzeit der Karte). */
.zb-5 .zb-rail i{
  animation-name:zb-rail-5;
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite;
  animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt));
}
.zb-5 .zb-rail i:nth-of-type(1){ --i:0; }
.zb-5 .zb-rail i:nth-of-type(2){ --i:1; }
.zb-5 .zb-rail i:nth-of-type(3){ --i:2; }
.zb-5 .zb-rail i:nth-of-type(4){ --i:3; }
.zb-5 .zb-rail i:nth-of-type(5){ --i:4; }
@keyframes zb-rail-5{
  0%    { background:var(--line-soft); }
  4.5%  { background:var(--tech-soft); }
  15.5% { background:var(--tech-soft); }
  18%   { background:var(--line-soft); }
  100%  { background:var(--line-soft); }
}
.zb-bar{ position:absolute; left:8%; right:0; top:0; height:11%; z-index:2;
  border-bottom:1px solid var(--line-soft);
  display:flex; align-items:center; gap:1.4%; padding:0 2.5% 0 3%; }
.zb-bar .zb-tit{ width:22%; height:22%; border-radius:var(--r-full); background:var(--line); }
.zb-bar .zb-pille{ width:9%; height:20%; border-radius:var(--r-full); background:var(--line-soft); }
.zb-bar .zb-pille:first-of-type{ margin-left:auto; }
.zb-bar .zb-rund{ width:3.4%; aspect-ratio:1; border-radius:50%; background:var(--tech-tint); }

/* ---- Die Karten -------------------------------------------------
   WIE DIE KARTE IN DIE MITTE KOMMT, OHNE EINE ZAHL JE SEITE:
   Die Buehne ist ein Groessen-Container, also ist 1cqw = 1 % ihrer
   Breite und 1cqh = 1 % ihrer Hoehe. Jede Karte kennt nur ihre Lage in
   Prozent (--l/--t/--w/--h), ihre Mitte rechnet CSS daraus aus, und der
   Weg zur Buehnenmitte ist (50 - Mitte) in cq-Einheiten. Ohne cq
   muesste jede Karte ihren Versatz als Pixelzahl mitbringen — und bei
   jeder Fensterbreite eine andere.
   ⚠ Die Buehne kann sich selbst nicht abfragen: cqw sucht den naechsten
   VORFAHREN mit container-type. Deshalb steht keine cq-Einheit an der
   Buehne, nur an ihren Kindern (derselbe Fehler wie oben bei
   .mock-melder dokumentiert).
   ⚠ KEIN will-change. Chrome fuehrt die Transform-Animation ohnehin auf
   dem Compositor, und der Hinweis hebt jede Karte auf eine eigene
   Ebene — fuenf davon dauerhaft sind es nicht wert. Nebenwirkung, die
   viel Zeit gekostet hat: Playwrights Screencast gibt befoerderte Ebenen
   NICHT mit, der Film zeigte die Karten in Ruhegroesse. */
.zb-karte{
  position:absolute; z-index:1;
  left:calc(var(--l) * 1%); top:calc(var(--t) * 1%);
  width:calc(var(--w) * 1%); height:calc(var(--h) * 1%);
  --cx:calc(var(--l) + var(--w) / 2);
  --cy:calc(var(--t) + var(--h) / 2);
  --fokus:translate(calc((50 - var(--cx)) * 1cqw), calc((50 - var(--cy)) * 1cqh)) scale(var(--z));
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--r-md); padding:.85em .95em;
  display:flex; flex-direction:column;
  font-size:max(9px, 1.6cqw); line-height:1.4;
  transform-origin:center center;
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite;
  animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt));
}

/* Lage und Reihenfolge stehen HIER, nicht als style-Attribut je Karte.
   Damit tragen die Seiten nur Inhalt, und ein Rasterwechsel ist eine
   Aenderung an einer Stelle statt an vier Seiten.
   zb-3: zwei oben, eine mittig darunter. Bewusst keine dritte Spalte und
   keine Karte ueber die halbe Buehne — bei --z 1,7 muss w*z unter 92 und
   h*z unter 88 bleiben, sonst laeuft die vordere Karte aus dem Fenster
   (gemessen: Rand 96 px bei 1440 px Fenster). */
.zb-3 article.zb-karte:nth-of-type(1){ --i:0; --l:11; --t:14; --w:41; --h:37; --z:1.70; }
.zb-3 article.zb-karte:nth-of-type(2){ --i:1; --l:55; --t:14; --w:41; --h:37; --z:1.70; }
.zb-3 article.zb-karte:nth-of-type(3){ --i:2; --l:33; --t:57; --w:41; --h:37; --z:1.70; }
/* zb-5: drei kleine links, zwei hohe rechts. */
.zb-5 article.zb-karte:nth-of-type(1){ --i:0; --l:11; --t:14; --w:40; --h:25; --z:1.75; }
.zb-5 article.zb-karte:nth-of-type(2){ --i:1; --l:11; --t:43; --w:40; --h:25; --z:1.75; }
.zb-5 article.zb-karte:nth-of-type(3){ --i:2; --l:11; --t:72; --w:40; --h:25; --z:1.75; }
.zb-5 article.zb-karte:nth-of-type(4){ --i:3; --l:55; --t:15; --w:41; --h:37; --z:1.70; }
.zb-5 article.zb-karte:nth-of-type(5){ --i:4; --l:55; --t:56; --w:41; --h:37; --z:1.70; }

.zb-3 .zb-karte{ animation-name:zb-karte-3; }
.zb-5 .zb-karte{ animation-name:zb-karte-5; }
.zb-3 .zb-karte::after{ animation-name:zb-schatten-3; }
.zb-5 .zb-karte::after{ animation-name:zb-schatten-5; }
.zb-3 .zb-skelett{ animation-name:zb-skelett-3; }
.zb-5 .zb-skelett{ animation-name:zb-skelett-5; }
.zb-3 .zb-inhalt{ animation-name:zb-inhalt-3; }
.zb-5 .zb-inhalt{ animation-name:zb-inhalt-5; }

/* ⚠ DIE PROZENTE MUESSEN JE ANZAHL EIGENE KEYFRAMES SEIN. Sie beziehen
   sich auf die Gesamtdauer, und die haengt an --n. Die absolute
   Bewegung ist in beiden Faellen dieselbe — Zoom 0,81 s, Standzeit
   1,98 s, Rueckweg 0,45 s, dann 0,36 s Luecke bis zur naechsten Karte:
     n=3 (10,8 s):  7,5 % / 25,83 % / 30 %
     n=5 (18,0 s):  4,5 % / 15,50 % / 18 %
   Genau dieselbe Regel wie bei melder-3 / melder-5 weiter oben.

   ⚠ z-index BRAUCHT ZWEI HALTEPUNKTE, beide auf 8. Der Wert wird als
   Ganzzahl INTERPOLIERT, und zwar mit der Beschleunigungskurve des
   Zooms; var(--ease) ist bei einem Fuenftel der Strecke schon bei 97 %,
   aus 8 wurde also binnen Millisekunden 1. Erkannt an der Wirkung, nicht
   am Code: die vordere Karte sah durchsichtig aus und ihr Text war
   rechts abgeschnitten — sie lag hinter den Karten, die im Markup nach
   ihr kommen. */
@keyframes zb-karte-3{
  0%     { transform:none;         z-index:1; border-color:var(--line); }
  .33%   { z-index:8; }
  7.5%   { transform:var(--fokus); border-color:var(--tech-soft); }
  25.83% { transform:var(--fokus); border-color:var(--tech-soft); }
  30%    { transform:none;         border-color:var(--line); }
  30.33% { z-index:8; }
  31%    { z-index:1; }
  100%   { transform:none;         z-index:1; border-color:var(--line); }
}
@keyframes zb-karte-5{
  0%     { transform:none;         z-index:1; border-color:var(--line); }
  .2%    { z-index:8; }
  4.5%   { transform:var(--fokus); border-color:var(--tech-soft); }
  15.5%  { transform:var(--fokus); border-color:var(--tech-soft); }
  18%    { transform:none;         border-color:var(--line); }
  18.2%  { z-index:8; }
  18.6%  { z-index:1; }
  100%   { transform:none;         z-index:1; border-color:var(--line); }
}

/* Schatten der vorderen Karte. Ueber ein Pseudoelement und dessen
   Deckkraft, weil box-shadow selbst zu animieren gegen DESIGN.md §5
   verstiesse (nur transform und opacity).
   ⚠ Deshalb hat .zb-karte KEIN overflow:hidden — ein aeusserer Schatten
   eines Kindes wuerde am Kartenrand abgeschnitten. Der Beschnitt sitzt
   am Koerper, wo der Inhalt beim Einblenden um .5em wandert.
   Ohne Schleier traegt dieser Schatten die ganze Tiefenwirkung, darum
   etwas kraeftiger als ein Karten-Schatten sonst. */
.zb-karte::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  pointer-events:none; opacity:0;
  box-shadow:0 1.3em 3.2em -1em rgba(4,19,16,.6), 0 .25em .7em -.3em rgba(4,19,16,.34);
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite; animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt));
}
@keyframes zb-schatten-3{
  0%{ opacity:0 } 7.5%{ opacity:1 } 25.83%{ opacity:1 } 30%{ opacity:0 } 100%{ opacity:0 }
}
@keyframes zb-schatten-5{
  0%{ opacity:0 } 4.5%{ opacity:1 } 15.5%{ opacity:1 } 18%{ opacity:0 } 100%{ opacity:0 }
}

.zb-kkopf{ display:flex; align-items:center; gap:.6em; flex:none; }
.zb-kic{ width:1.75em; height:1.75em; border-radius:var(--r-sm); flex:none;
  display:grid; place-items:center; background:var(--tech-tint); color:var(--green-700); }
.zb-kic svg{ width:1em; height:1em; }
.zb-kic.warn{ background:var(--amber-bg); color:var(--amber-ink); }
/* Violett heisst „das kommt von Pax". NUR Pax AI (DESIGN.md §4). */
.zb-kic.ki{ background:var(--ai-tint); color:var(--ai-ink); }
.zb-ktitel{ font-size:.95em; font-weight:600; letter-spacing:-.005em; }
.zb-kkopf .zb-chip{ margin-left:auto; align-self:center; }
.zb-kzahl{ margin-left:auto; font-family:var(--mono); font-size:.78em;
  font-weight:500; color:var(--muted); font-variant-numeric:tabular-nums; }

/* Platzhalter und Inhalt liegen im GLEICHEN Kasten uebereinander, darum
   ein eigener Koerper mit position:relative. Sonst waere der Wechsel ein
   Hoehensprung — und Hoehen animiert man nicht. */
.zb-koerper{ position:relative; flex:1 1 auto; margin-top:.7em; overflow:hidden; }
.zb-skelett, .zb-inhalt{ position:absolute; inset:0;
  animation-duration:calc(var(--n) * var(--takt));
  animation-timing-function:var(--ease);
  animation-iteration-count:infinite; animation-fill-mode:both;
  animation-delay:calc((var(--i) - var(--n)) * var(--takt)); }

@keyframes zb-skelett-3{
  0%{ opacity:1 } 5%{ opacity:0 } 26.67%{ opacity:0 } 30%{ opacity:1 } 100%{ opacity:1 }
}
@keyframes zb-skelett-5{
  0%{ opacity:1 } 3%{ opacity:0 } 16%{ opacity:0 } 18%{ opacity:1 } 100%{ opacity:1 }
}
@keyframes zb-inhalt-3{
  0%     { opacity:0; transform:translateY(.5em); }
  3.33%  { opacity:0; transform:translateY(.5em); }
  10.83% { opacity:1; transform:none; }
  25.83% { opacity:1; transform:none; }
  29.17% { opacity:0; transform:translateY(.3em); }
  100%   { opacity:0; transform:translateY(.5em); }
}
@keyframes zb-inhalt-5{
  0%     { opacity:0; transform:translateY(.5em); }
  2%     { opacity:0; transform:translateY(.5em); }
  6.5%   { opacity:1; transform:none; }
  15.5%  { opacity:1; transform:none; }
  17.5%  { opacity:0; transform:translateY(.3em); }
  100%   { opacity:0; transform:translateY(.5em); }
}

/* ---- Der Platzhalter: „zu klein zum Lesen" ---------------------
   Warum der Inhalt erst im Fokus erscheint: weil die Vorlage es so
   macht, und weil es das Groessenproblem loest. Klein traegt die Karte
   Titel und Balken, gross ihren wirklichen Inhalt. Sonst muesste die
   Schrift schon in der Uebersicht lesbar sein — bei 40 % Buehnenbreite
   waeren das 7 px.
   Der letzte Balken ist mint: so liest sich die ruhende Karte als
   Statuszeile und nicht als Ladeanzeige. */
.zb-skelett{ display:flex; flex-direction:column; gap:.5em; }
.zb-skelett i{ display:block; height:.5em; border-radius:var(--r-full); background:var(--line-soft); }
.zb-skelett i:nth-child(1){ width:82%; }
.zb-skelett i:nth-child(2){ width:58%; }
.zb-skelett i:nth-child(3){ width:44%; }
.zb-skelett i:last-child{ width:38%; background:var(--tech-soft); }
.zb-skelett .zb-flaeche{ flex:1 1 auto; min-height:2.4em; border-radius:var(--r-sm);
  background:var(--line-soft); opacity:.55; }

/* ---- Der Inhalt: „im Fokus" ------------------------------------ */
.zb-inhalt{ display:flex; flex-direction:column; gap:.45em; justify-content:center; }
.zb-zeile{ display:flex; align-items:baseline; gap:.5em; font-size:.85em;
  border-top:1px solid var(--line-soft); padding-top:.4em; }
.zb-zeile:first-child{ border-top:0; padding-top:0; }
.zb-feld{ color:var(--muted-readable); flex:none; min-width:5.6em; }
.zb-wert{ min-width:0; overflow-wrap:anywhere; color:var(--ink-soft); font-weight:500; }
.zb-wert.leise{ color:var(--muted-readable); font-weight:400; }
.zb-rechts{ margin-left:auto; color:var(--muted-readable); }
.zb-hak{ width:.95em; height:.95em; margin-left:auto; flex:none; color:var(--green-600); }
.zb-satz{ font-size:.85em; color:var(--muted-readable); }
.zb-satz b{ font-weight:600; color:var(--ink-soft); }
.zb-fuss{ font-size:.78em; line-height:1.4; color:var(--muted); }
.zb-gross{ font-family:var(--mono); font-size:1.5em; font-weight:600;
  letter-spacing:-.02em; color:var(--ink); font-variant-numeric:tabular-nums; }
.zb-chip{ align-self:flex-start; display:inline-flex; align-items:center; gap:.4em;
  font-size:.8em; font-weight:600; padding:.3em .7em; border-radius:.6em;
  background:var(--tech-tint); color:var(--green-700); }
.zb-chip::before{ content:""; width:.42em; height:.42em; border-radius:50%; background:currentColor; }
.zb-chip.warn{ background:var(--amber-bg); color:var(--amber-ink); }
.zb-chip.ai{ background:var(--ai-tint); color:var(--ai-ink); }
.zb-chip.ohne-punkt::before{ display:none; }
.zb-zeile .zb-chip{ align-self:auto; margin-left:auto; }

/* Ampelpunkt. Die Stufen sind die ECHTEN aus dem Produkt (Notion „GTM
   CompliancePro" §7): rot = AUE-Erlaubnis fehlt, grau = Erlaubnis
   vorhanden, gruen = alle Anforderungen erfuellt. Keine Gelb-Stufe
   erfinden, die das Produkt nicht hat. */
/* align-self, weil .zb-zeile an der Schriftlinie ausrichtet: ein leerer
   Punkt saesse dort mit seiner Unterkante auf der Grundlinie. */
.zb-status{ width:.62em; height:.62em; border-radius:50%; flex:none;
  align-self:center; background:var(--muted); }
.zb-status.gruen{ background:var(--green-500); box-shadow:0 0 0 .28em var(--tech-tint); }
.zb-status.rot{ background:var(--red); }

/* Balken- und Messreihen. Die Werte stehen HIER und nicht als
   style-Attribut je Balken — sonst wandern Daten ins Markup. */
.zb-balken{ display:flex; align-items:flex-end; gap:.28em; flex:1 1 auto; min-height:2.6em; }
.zb-balken i{ flex:1 1 0; border-radius:.12em; background:var(--tech-soft); display:block; }
.zb-balken i:nth-child(1){ height:46%; }
.zb-balken i:nth-child(2){ height:72%; }
.zb-balken i:nth-child(3){ height:54%; }
.zb-balken i:nth-child(4){ height:88%; }
.zb-balken i:nth-child(5){ height:64%; }
.zb-balken i:nth-child(6){ height:100%; background:var(--green-600); }
.zb-woche{ display:flex; gap:.3em; flex:1 1 auto; min-height:2.2em; align-items:flex-end; }
.zb-woche span{ flex:1 1 0; display:flex; flex-direction:column; align-items:center; gap:.3em;
  font-size:.72em; color:var(--muted); }
.zb-woche i{ display:block; width:100%; border-radius:.12em; background:var(--tech-soft); }
.zb-woche span:nth-child(1) i{ height:1.5em; }
.zb-woche span:nth-child(2) i{ height:1.9em; }
.zb-woche span:nth-child(3) i{ height:1.7em; }
.zb-woche span:nth-child(4) i{ height:2.1em; }
.zb-woche span:nth-child(5) i{ height:1.1em; }
/* Waagerechte Messzeile mit Beschriftung (Passung, Auslastung). */
.zb-mess{ display:flex; align-items:center; gap:.6em; font-size:.82em; color:var(--muted-readable); }
.zb-mess span{ width:4.2em; flex:none; }
.zb-mess i{ display:block; height:.55em; border-radius:var(--r-full); background:var(--green-500); }
.zb-mess i.offen{ background:var(--line); }
.zb-messe{ display:flex; flex-direction:column; gap:.45em; }
.zb-messe > .zb-mess:nth-child(1) i{ width:72%; }
.zb-messe > .zb-mess:nth-child(2) i{ width:34%; }
/* Liegende Skelettbalken als Inhalt (Leitfaden-Entwurf). */
.zb-zeilen{ display:flex; flex-direction:column; gap:.5em; flex:1 1 auto; justify-content:center; }
.zb-zeilen i{ display:block; height:.5em; border-radius:var(--r-full); background:var(--line-soft); }
.zb-zeilen i.ki{ background:var(--ai-tint); }
.zb-zeilen i:nth-child(1){ width:58%; }
.zb-zeilen i:nth-child(2){ width:88%; }
.zb-zeilen i:nth-child(3){ width:74%; }
.zb-zeilen i:nth-child(4){ width:46%; }

/* ---- Ohne Bewegung: Telefon und prefers-reduced-motion ---------
   Dasselbe wie bei .mock-melder: aus der Buehne wird eine Spalte, jede
   Karte steht vollstaendig da — mit ihrem INHALT, nicht mit
   Platzhaltern. Nichts geht verloren, und es ist gleichzeitig die
   Fassung ohne JavaScript (hier spielt ohnehin kein Skript mit).
   ⚠ container-type wird zurueckgenommen und die Schrift auf vw
   umgestellt: cqw sucht sonst den naechsten Container-Vorfahren und
   landet beim Fenster — aus 11 px werden dann 37 px.
   ⚠ .zb-balken braucht HIER eine Hoehe, kein min-height: die Balken
   tragen ihre Hoehe in Prozent, und Prozent laeuft gegen eine
   auto-Hoehe ins Leere. Gemessen bei 390 px: die Reihe war leer,
   waehrend die Wochenbalken (Hoehe in em) standen. */
@media (max-width:760px), (prefers-reduced-motion:reduce){
  .zb-buehne{ container-type:normal; aspect-ratio:auto; height:auto;
    display:flex; flex-direction:column; gap:.7em; padding:.8em;
    box-shadow:0 1.2em 3em -1.2em rgba(4,19,16,.5); }
  .zb-rail, .zb-bar{ display:none; }
  /* ⚠ .zb-buehne DAVOR, nicht nur .zb-karte. Eine Medienabfrage erhoeht die
     Spezifitaet NICHT, und `animation-name` kommt aus `.zb-3 .zb-karte`
     (0,2,0) — ein blankes `.zb-karte{animation:none}` (0,1,0) haette den
     Namen also stehen gelassen. Gemessen: animationName war bei 390 px
     weiter „zb-karte-3", nur die Dauer war auf 0s zurueckgesetzt. Es sah
     richtig aus und war es nicht. */
  .zb-buehne .zb-karte{ position:static; width:auto; height:auto; transform:none;
    animation:none; z-index:auto; font-size:max(12px, 3.3vw); }
  .zb-buehne .zb-karte::after{ animation:none; opacity:0; }
  .zb-buehne .zb-skelett{ display:none; animation:none; }
  .zb-buehne .zb-inhalt{ position:static; opacity:1; transform:none; animation:none; }
  .zb-buehne .zb-koerper{ min-height:0; }
  .zb-balken{ height:3.4em; }
  .zb-woche, .zb-skelett .zb-flaeche{ min-height:3.2em; }
}

/* ============================================================
   Modul-Mockup auf den Loesungsseiten (workforce, compliance,
   tender, pax-ai): auf dem Telefon nicht in die Laenge ziehen.
   Basis ist .mod-visual{height:560px} im Kopf jeder Seite. Wird
   die Spalte schmal (unter ~560px), bleibt die feste Hoehe stehen
   und das Desktop-Dashboard wird zum hohen, schmalen Streifen mit
   viel Leerflaeche. Hier eine kompakte Kartenhoehe erzwingen; die
   hoehere Spezifitaet (.mod-grid .mod-visual, 0-2-0) schlaegt die
   Kopf-Regel unabhaengig von der Ladereihenfolge. Nur Telefon,
   damit Tablets (dort ist die Spalte breit und quadratisch, kein
   Stretch) unberuehrt bleiben. Gemessen: das Mockup fuellt sich
   ueber .hw-card.fill selbst, die Restliste laeuft unten sichtbar
   aus dem Rahmen wie ein Produktausschnitt. */
@media (max-width:560px){
  /* MOBIL: statt des live gebauten Mockups das fertige Screenshot-Bild je Modul
     zeigen — quer und vollstaendig, genau wie auf den Prozessseiten (.schau).
     Die Bilder (assets/modul/rahmen/*.jpg, 1760x1120) tragen den gruenen Rahmen
     schon in sich. Desktop bleibt das animierte Live-Mockup. Zuordnung ueber die
     Modul-id (ein .mod-visual je Modul). Begruendung: ein Hochkant-Kartenstapel
     (das Live-DOM) fuellt kein Querformat, ohne unten abzuschneiden. */
  /* Zusatzmodule (schichtplanung/zeitnachweise/compliancepro) liegen in eigenen
     Bausteinen mit `#id .mod-grid{grid-template-columns:...}` OHNE Media-Query —
     dieses (0-1-1) schlaegt die generische Stapelregel, das Grid bleibt mobil
     zweispaltig und das Mockup laeuft ueber den Rand. Mit gleicher id-Spezifitaet
     plus Vorfahr (.mod-track, => 1-2-0) auf eine Spalte zwingen. */
  .mod-track #schichtplanung .mod-grid,
  .mod-track #zeitnachweise .mod-grid,
  .mod-track #compliancepro .mod-grid,
  #schichtplanung .mod-grid, #zeitnachweise .mod-grid, #compliancepro .mod-grid{ grid-template-columns:1fr !important; }

  .mod-grid .mod-visual{ height:auto; aspect-ratio:1760 / 1120; min-height:0; }
  /* ALLE Kinder ausblenden (Frames, Schiene UND die KI-Overlays wie .km-tafel/
     .ki-flagge, die neben den Frames sitzen und sonst lila ueber dem Bild
     erscheinen). Das ::after-Bild ist ein Pseudo-Element, kein Kind — es bleibt. */
  /* `!important`, weil der KI-Film beim Scrollen einzelne Overlays (.km-tafel u.a.)
     ueber Klassen/Inline-Stile wieder einblendet — ohne `!important` gewinnt er
     und das lila „+KI-Funktion"-Panel liegt wieder ueber dem Screenshot. */
  .mod-grid .mod-visual > *{ display:none !important; }
  /* KI-Overlays (lila „+KI-Funktion"-Faehnchen + KI-Panel) NUR MOBIL sicher aus,
     falls sie nicht direkte Kinder der .mod-visual sind. Desktop unberuehrt. */
  .mod-grid .ki-flagge, .mod-grid .km-tafel{ display:none !important; }
  .mod-grid .mod-visual::after{
    content:""; position:absolute; inset:0; z-index:3;
    background:center/cover no-repeat; border-radius:inherit;
  }
  #anfragemanagement   .mod-visual::after{ background-image:url(/assets/modul/rahmen/bedarf-0.jpg); }
  #kandidatenmanagement .mod-visual::after{ background-image:url(/assets/modul/rahmen/kandidaten-0.jpg); }
  #dokumentenmanagement .mod-visual::after{ background-image:url(/assets/modul/rahmen/dokumente-0.jpg); }
  #abrechnung          .mod-visual::after{ background-image:url(/assets/modul/rahmen/abrechnung-0.jpg); }
  #compliance          .mod-visual::after{ background-image:url(/assets/modul/rahmen/pro-ampel.jpg); }
  #analysen            .mod-visual::after{ background-image:url(/assets/modul/rahmen/analysen-0.jpg); }
  #schichtplanung      .mod-visual::after{ background-image:url(/assets/modul/rahmen/schichtplanung-0.jpg); }
  #zeitnachweise       .mod-visual::after{ background-image:url(/assets/modul/rahmen/zeitnachweise-0.jpg); }
  #compliancepro       .mod-visual::after{ background-image:url(/assets/modul/rahmen/pro-abruf.jpg); }
  #kurzfristeinsaetze  .mod-visual::after{ background-image:url(/assets/modul/rahmen/schichtplanung-2.jpg); }
  #einsatzmanagement   .mod-visual::after{ background-image:url(/assets/modul/rahmen/einsatz-akte-0.jpg); }
  /* pactos-ai hat die Klasse .ist-chat mit lila Eigenhintergrund; das ::after
     kam dagegen nicht durch. Bild deshalb direkt als Hintergrund der .mod-visual
     setzen (ueberschreibt das Lila). Kinder sind schon ausgeblendet.
     ⚠ 10.09.2026 (Karoline: „der Hintergrund soll mobil ja tuerkis sein"):
     Das ganzflaechige Bild brachte seinen eigenen DUNKELGRUENEN Rahmen mit,
     waehrend die zehn anderen Modulbilder einen mintfarbenen tragen — in der
     gescrollten Reihe fiel Pax AI dadurch heraus. Jetzt wie bei den anderen:
     mintfarbener Grund auf der .mod-visual, das Bild als ::after darin.
     Verwendet wird `pax-assistent-mobil.jpg` — derselbe Screenshot ohne den
     dunklen Eigenrahmen (mittig beschnitten auf 1620x992 von 1760x1120).
     Daraus die Einrueckung: 70/1760 = 3.98 % seitlich, 64/1120 = 5.71 % oben
     und unten. Neu aufnehmen liess sich das Bild nicht, Begruendung steht in
     tools/modulbilder/rahmen.mjs.
     Der Verlauf ist woertlich der `.viz-plan`-Grund aus
     content/seiten/workforce.json, damit es exakt dieselbe Flaeche ist. */
  #pactos-ai .mod-visual{ height:auto; aspect-ratio:1760 / 1120; min-height:0;
    background:
      radial-gradient(72% 58% at 84% 4%, rgba(82,239,186,.75), transparent 58%),
      radial-gradient(82% 92% at 2% 106%, rgba(140,244,209,.9), transparent 62%),
      linear-gradient(135deg,#8CF4D1 0%,#C5FAE8 55%,#E7F8F0 100%) !important; }
  /* ⚠ `mask:none` IST HIER DER ENTSCHEIDENDE TEIL, nicht Beiwerk. Der lila
     KI-Ring wird als Donut gebaut: dasselbe ::after traegt eine
     -webkit-mask aus zwei Verlaeufen. Im Ruhezustand sind beide 0px hoch,
     die Maske also vollstaendig undurchsichtig — das Bild war gesetzt,
     geladen und sichtbar geschaltet und wurde trotzdem komplett weggemaskt.
     Gemessen: getComputedStyle(v,'::after').maskImage war
     „linear-gradient(rgb(0,0,0) 0px, rgb(0,0,0) 0px), …" bei display:block,
     opacity:1 und korrekter background-image-URL — die Kachel blieb leer
     tuerkis. `animation:none` dazu, damit `ki-umlauf` nicht weiterdreht. */
  #pactos-ai .mod-visual::after{ inset:5.71% 3.98%; border-radius:5px;
    animation:none !important; mask:none !important; -webkit-mask:none !important;
    background:url(/assets/modul/rahmen/pax-assistent-mobil.jpg) center/cover no-repeat !important; }
  /* compliance: drei Frames teilen sich die id #kernfeatures, tragen aber je eine
     eigene viz-Klasse am .mod-visual. */
  .mod-visual.viz-ampel::after{ background-image:url(/assets/modul/rahmen/pro-ampel.jpg); }
  .mod-visual.viz-abruf::after{ background-image:url(/assets/modul/rahmen/pro-abruf.jpg); }
  .mod-visual.viz-rueck::after{ background-image:url(/assets/modul/rahmen/pro-rueck.jpg); }

  /* tender: vier Schritte (ht-block data-i 0..3), mobil gestapelt — je Schritt sein
     eigenes Screenshot statt des live .hw-Mockups (grosses Menue, abgeschnitten). */
  .ht-mock > *{ display:none !important; }
  .ht-block[data-i="0"] .ht-mock{ background:url(/assets/modul/rahmen/tender-ausschreibung.jpg) center/cover no-repeat !important; }
  .ht-block[data-i="1"] .ht-mock{ background:url(/assets/modul/rahmen/tender-ki-matching.jpg) center/cover no-repeat !important; }
  .ht-block[data-i="2"] .ht-mock{ background:url(/assets/modul/rahmen/tender-angebote.jpg) center/cover no-repeat !important; }
  .ht-block[data-i="3"] .ht-mock{ background:url(/assets/modul/rahmen/tender-vergabe.jpg) center/cover no-repeat !important; }
}
