/*
 |-----------------------------------------------------------------------
 | Zusatz fuer das Altsystem
 |-----------------------------------------------------------------------
 |
 | public/css/kommandozentrale/{base,app}.css sind wortgleiche Kopien aus
 | dem Frontend und werden hier nicht angefasst. Diese Datei traegt nur,
 | was im Frontend die Vue-Bauteile erledigen und was es im Blade-Markup
 | zusaetzlich gibt. Jede Regel hier braucht einen Grund darueber.
 */

/* ── Grundlage, die im Frontend Tailwind stellt ───────────────────────
   base.css und app.css sind fuer das neue Frontend geschrieben, und dort
   liegt Tailwinds Preflight darunter. Im Altsystem gibt es das auf diesen
   Seiten nicht — ohne diesen Block rechnet der Browser jede Breite in
   content-box, und jede Ueberschrift bekommt ihren Standardabstand
   zurueck. Das Ergebnis waeren Kacheln, die um ihre Polsterung zu breit
   sind, und Abstaende, die der Entwurf nie hatte.

   Uebernommen ist nur, worauf das Design sich wirklich stuetzt — kein
   vollstaendiger Reset. Wer hier etwas ergaenzt, prueft vorher, ob es das
   von JavaScript erzeugte Bootstrap-Markup weiter unten stoert.

   Zwei Zeilen in base.css bleiben ausserdem wirkungslos, weil sie
   Tailwind-Direktiven sind, die nur der Build aufloest:
     base.css:207  html, body, #__nuxt { @apply h-full }
     base.css:252  span[role="alert"] { @apply text-bad }
   Beides steht deshalb hier ausgeschrieben. */

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

html, body {height:100%}

/* Der Randabstand des Browsers um <body> — acht Pixel, die im Frontend
   Tailwinds Preflight nullt. Ohne diese Zeile steht die ganze Schale in
   einem Rahmen, und .b-shell/.lg mit min-height:100dvh ergeben zusammen
   mit dem Rand eine Seite, die sich scrollen laesst, obwohl sie passt. */
body {margin:0}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd {margin:0}

/* Der Entwurf setzt Groesse und Gewicht je Flaeche selbst. Ohne diese
   Zeile traegt ein blankes <h4> die Browservorgabe und springt heraus. */
h1, h2, h3, h4, h5, h6 {font-size:inherit; font-weight:inherit}

img, svg, video, canvas {display:block}
img, video {max-width:100%; height:auto}

/* Verweise tragen im Entwurf ihre Farbe und ihre Unterlaengung selbst
   (.b-lnk, .b-btn, .kz-liste). Ohne diese Zeile faerbt der Browser jeden
   uebrigen <a> blau und unterstreicht ihn — in der Nachrichtenliste traf
   das Titel und Zeitangabe, die dort gar keine Verweise sein sollen. So
   haelt es auch Tailwinds Preflight, unter dem das Frontend laeuft.
   Fliesstext aus dem Editor bekommt seine Verweise unten zurueck. */
a {color:inherit; text-decoration:inherit}

/* Der wichtigste Teil: Browser geben <button> von sich aus 1px 6px
   Polsterung. Mit border-box frisst die den Platz im Element auf — ein
   Symbolknopf von 15px Breite behielt dadurch 3px fuer sein Symbol, und
   die Pfeile im Strukturbaum waren unsichtbar. Klassenregeln des Entwurfs
   setzen ihre eigene Polsterung und gewinnen hier ohnehin. */
button, input, optgroup, select, textarea {margin:0; padding:0}

span[role="alert"] {color:var(--st-bad)}

/* ── Sichtbarkeit ────────────────────────────────────────────────────
   Im Frontend haengt jeder Dialog an v-if und ist gar nicht im Dokument.
   Hier steht er im Markup und wird ueber [hidden] geschaltet — das muss
   gegen display:flex/grid der Entwurfsregeln gewinnen. */
[hidden] {display:none !important}

/* ── Knoepfe in der Seitenleiste ─────────────────────────────────────
   Der Entwurf kennt in .b-nav nur <a>. Zwei Eintraege sind hier aber
   Knoepfe, weil sie keinen eigenen Ort haben, sondern einen Dialog
   oeffnen (Rechner, Modulsuche). Sie sollen gleich aussehen. */
.b-nav button {
    display:flex; align-items:center; gap:9px; width:100%;
    text-align:left; color:var(--c-rail-ink-2); font-size:13px;
    padding:6px 8px; border-radius:6px;
    transition:background .18s, color .18s;
}
.b-nav button:hover {background:var(--c-rail-hover); color:var(--c-rail-ink)}
.b-nav button svg {width:15px; height:15px; opacity:.75; flex-shrink:0}

@media (max-width:1023px) {
    /* Auf Tablettbreite zeigt die Leiste nur Symbole (app.css:780).
       Dieselbe Regel fuer die Knoepfe. */
    .b-nav button {justify-content:center}
    .b-nav button .lbl {display:none}
}

/* ── Wartungshinweis ─────────────────────────────────────────────────
   navbar.blade.php:6-29 hat ihn als Bootstrap-Alarm ueber der Leiste
   gezeigt. Er bleibt ganz oben, bekommt aber die Form des Entwurfs.
   Der Text kommt aus der Wartungsverwaltung und darf HTML enthalten. */
.kz-wartung {
    display:flex; align-items:flex-start; gap:9px;
    padding:9px 18px; font-size:12.5px; line-height:1.5;
    background:var(--st-warn-bg); color:var(--st-warn);
    border-bottom:1px solid var(--c-line);
}
.kz-wartung svg {width:15px; height:15px; flex-shrink:0; margin-top:1px}
.kz-wartung a {color:inherit}
.kz-wartung.danger  {background:var(--st-bad-bg);  color:var(--st-bad)}
.kz-wartung.success {background:var(--st-ok-bg);   color:var(--st-ok)}

/* ── Modulsuche und Rechnerliste ─────────────────────────────────────
   Zwei Listen in Dialogen, gleicher Aufbau: Symbol, Name, Zusatz. */
.kz-liste {display:grid; gap:2px; max-height:52vh; overflow-y:auto}
.kz-liste a {
    display:flex; align-items:center; gap:10px;
    padding:9px 10px; border-radius:8px;
    text-decoration:none; color:var(--c-ink); font-size:13px;
    transition:background .18s;
}
.kz-liste a:hover {background:var(--c-tint)}
.kz-liste a svg {width:15px; height:15px; color:var(--c-ink-3); flex-shrink:0}
.kz-liste a .t {min-width:0}
.kz-liste a .t b {display:block; font-weight:600}
.kz-liste a .t span {display:block; font-size:11px; color:var(--c-ink-3)}
.kz-liste a .ext {margin-left:auto; color:var(--c-ink-3); flex-shrink:0}

/* ── Suchfeld in einem Dialog ────────────────────────────────────────
   Der Entwurf hat .inp fuer Formularfelder; hier eine schmale Fassung
   fuer die eine Zeile ueber einer Liste. */
.kz-suche {display:flex; align-items:center; gap:8px; margin-bottom:10px}
.kz-suche input {
    flex:1; min-width:0; height:38px; padding:0 11px;
    border:1px solid var(--c-line); border-radius:8px;
    background:var(--c-surface); color:var(--c-ink); font-size:13px;
}
.kz-suche input:focus {outline:none; border-color:var(--c-accent)}

/* ── Markup, das JavaScript zur Laufzeit erzeugt ─────────────────────
   Diese Klassen stehen in keiner Blade-Datei: dashboard.js schreibt sie
   in die Ziehharmonika der vergangenen ABWs, in die ABW-Tabellen und in
   die Statusabzeichen des Eventkalenders. Wir fassen dieses JavaScript
   nicht an — also holt das CSS es ab. Wer die betreffenden Stellen in
   dashboard.js eines Tages umschreibt, kann diesen Block loeschen.
   Fundstellen: populatePastABWAccordion (543-585), populateABWTable
   (526-541), Event-Antwort (791-846). */

.d-none {display:none !important}
.collapse:not(.show) {display:none}

.accordion-item {border:1px solid var(--c-line); border-radius:10px; overflow:hidden; margin-bottom:8px}
.accordion-header {margin:0}
.accordion-button {
    width:100%; text-align:left; display:flex; align-items:center; gap:8px;
    padding:10px 13px; font-size:13px; font-weight:600; color:var(--c-ink);
    background:var(--c-surface-2); transition:background .18s;
}
.accordion-button:hover {background:var(--c-tint)}
.accordion-button::after {
    content:''; margin-left:auto; width:7px; height:7px; flex-shrink:0;
    border-right:1.5px solid var(--c-ink-3); border-bottom:1.5px solid var(--c-ink-3);
    transform:rotate(45deg); transition:transform .18s;
}
.accordion-button.collapsed::after {transform:rotate(-45deg)}
.accordion-body {padding:0}

/* Die erzeugten Tabellen tragen Bootstrap-Klassen. Sie sollen aussehen
   wie .b-t aus dem Entwurf, ohne dass wir den Erzeuger anfassen. */
.table {width:100%; border-collapse:collapse; font-size:12.5px}
.table thead th {
    text-align:left; font-family:"IBM Plex Mono",monospace; font-size:10px;
    letter-spacing:.09em; text-transform:uppercase; color:var(--c-ink-3);
    font-weight:500; padding:9px 12px; border-bottom:1px solid var(--c-line);
    background:var(--c-surface-2); white-space:nowrap;
}
.table tbody td {padding:9px 12px; border-bottom:1px solid var(--c-line-2, var(--c-line)); vertical-align:top}
.table tbody tr:last-child td {border-bottom:0}
.table-striped tbody tr:nth-child(odd) {background:var(--c-surface-2)}
.table .text-center {text-align:center; color:var(--c-ink-3)}
.bg-light {background:var(--c-surface-2)}

/* Abzeichen: dieselben Toene wie .chip im Entwurf. badge-dark ist im
   Bestand der neutrale Zustand "Ausstehend". */
.badge {
    display:inline-flex; align-items:center; gap:5px; padding:2px 8px;
    border-radius:99px; font-size:11px; font-weight:600;
    background:var(--c-tint); color:var(--c-ink-2);
}
.badge-success {background:var(--st-ok-bg);   color:var(--st-ok)}
.badge-warning {background:var(--st-warn-bg); color:var(--st-warn)}
.badge-danger  {background:var(--st-bad-bg);  color:var(--st-bad)}
.badge-dark    {background:var(--c-tint);     color:var(--c-ink-2)}

/* ── Neuvertraege ─────────────────────────────────────────────────────
   Der Block haengt an seiner DOM-Form: fetchNewContracts
   (Modules/Dashboard/Resources/assets/js/app.js:406-489) greift mit
   .parent(), .prev() und .children() darauf zu und nimmt sechs Zellen je
   Kennzahl an. Die Form bleibt deshalb, wie sie ist — aber sie wird nicht
   mehr gezeigt: das Bestandsskript nimmt den Zellen einzeln .d-none ab,
   nie dem Behaelter. Sichtbar ist stattdessen #kz-neuvertraege, das
   kommandozentrale-dashboard.js daraus fuellt. Ohne diesen Speicher
   liefen die drei Abrufe ins Leere. */
.kz-vertraege {display:none}


/* ── Dashboard ────────────────────────────────────────────────────────
   Die wenigen Stellen, an denen das Dashboard mehr braucht als der
   Entwurfsbaukasten hergibt. */

/* Die Ungelesen-Marke hinter einem Nachrichtentitel ist ein .chip „neu"
   (Dashboard-Kachel und Dialog „Alle Nachrichten"). Klasse und data-msgid
   bleiben, weil messageRead()/markAsRead (dashboard.js 1166-1190) sie
   ueber einen Cookie aus- und einblenden. */

/* .kz-zwei, .kz-abgesetzt, .kz-weg und .kz-rekord stehen nicht mehr hier,
   sondern im Entwurfsbaukasten (kommandozentrale/app.css): das Frontend
   braucht sie genauso. Sie dort zu pflegen ist der einzige Weg, der die
   beiden Systeme zusammenhaelt — siehe HERKUNFT.md. */

/* Anklickbare Zeilen und Titel in einer Kennzahlenliste — die beiden
   ABW-Zeilen oeffnen je einen Dialog. Der Hinweis darauf ist die
   gestrichelte Unterlaengung, nicht eine eigene Kachel: die Zeile soll
   sich in die Liste einreihen und nicht aus ihr herausfallen. */
.kz-klick {cursor:pointer}
li.kz-klick:hover .t b,
b.kz-klick:hover {color:var(--c-accent)}
.kz-klick b,
b.kz-klick {text-decoration:underline; text-decoration-style:dotted; text-underline-offset:3px}

/* Die Werkzeuge der Fuehrungskraft: eine Zeile Verweise unter den
   Kennzahlen, abgesetzt wie im Entwurf. */
.kz-werkzeuge {
    display:flex; flex-wrap:wrap; gap:8px 14px;
    margin-top:13px; padding-top:12px; border-top:1px solid var(--c-line);
}
/* „Onboarding" und sein Abzeichen gehoeren zusammen und duerfen nicht
   zwischen zwei Zeilen zerfallen. */
.kz-werkzeuge > a {white-space:nowrap}
.kz-werkzeuge .pill {white-space:nowrap}

/* Eventkalender: eine Flaeche je Event, umgeschaltet per Vor/Zurueck.

   Der Text kommt aus dem Einladungs-Editor und ist mitunter eine ganze
   Mail — mit Tagesablauf, Grussformel und Signatur. Ungedeckelt zieht
   eine solche Einladung die Zeile auf ueber tausend Pixel und die
   Nachbarflaeche mit sich. Er bekommt deshalb eine Hoehe und scrollt
   darin; wer alles lesen will, oeffnet „Alle Events". Am unteren Rand
   liegt ein Verlauf, damit man sieht, dass da noch etwas kommt. */
.kz-event-text {
    position:relative; font-size:12.5px; line-height:1.55; color:var(--c-ink-2);
    margin-top:6px; max-height:220px; overflow-y:auto; overscroll-behavior:contain;
    padding-right:4px;
}
.kz-event-text p {margin:0 0 6px}
.kz-event-text :last-child {margin-bottom:0}
.kz-event-text img {max-width:100%; height:auto}
.kz-event-huelle {position:relative}
.kz-event-huelle::after {
    content:""; position:absolute; left:0; right:0; bottom:0; height:26px;
    pointer-events:none; background:linear-gradient(transparent, var(--c-surface));
}

/* Die Antwortknoepfe bekommen .active vom Bestands-JS (es greift ueber
   button[data-event]) — das ist der Zustand "so hast du geantwortet".

   Die Regel lautete hier fuer beide Knoepfe color:var(--c-accent). Das
   passt zu „Absagen", der als .ghost durchsichtig ist. „Anmelden" ist
   aber ein gefuellter Knopf mit background:var(--c-accent): nach der
   Zusage stand dort die Akzentfarbe auf der Akzentfarbe, also blaue
   Schrift auf blauem Grund. Beschriftung und Haken verschwanden — in
   beiden Farbschemata, denn --c-accent und --c-accent-ink laufen dort
   jeweils gemeinsam um.

   Darum getrennt: der durchsichtige Knopf faerbt Rand und Schrift, der
   gefuellte behaelt seine helle Schrift und bekommt stattdessen einen
   Ring. Beide bleiben lesbar und sind als gewaehlt zu erkennen. */
.b-btn.ghost.event.active {border-color:var(--c-accent); color:var(--c-accent)}
.b-btn.ghost.event.active svg {color:var(--c-accent)}

.b-btn.event.active:not(.ghost) {
    box-shadow:var(--sh), inset 0 0 0 2px var(--c-accent-ink);
}

/* Fliesstext einer Nachricht im Dialog. Der Inhalt kommt aus dem
   Nachrichteneditor und bringt eigene Absaetze und Listen mit. */
/* Im Fliesstext aus dem Editor sind Verweise echte Verweise und sollen
   als solche zu erkennen sein — hier also zurueck, was der Reset oben
   allen <a> genommen hat. */
.kz-event-text a, .kz-fliess a {color:var(--c-accent); text-decoration:underline}

.kz-fliess {font-size:13px; line-height:1.6; color:var(--c-ink-2)}
.kz-fliess p {margin:0 0 8px}
.kz-fliess ul, .kz-fliess ol {margin:0 0 8px; padding-left:20px}
.kz-fliess a {color:var(--c-accent)}


/* ── Betraege verdecken: was das Auge alles trifft ────────────────────
   Im Frontend blendet der eine Schalter alle Betraege des Dashboards
   aus, nicht nur die der einen Flaeche: die Volumenspalten der
   Challenges, den Mandantenumsatz und die Rekorde. Genauso hier.

   Die Zellen der Challenge-Tabellen kann das Blade nicht auszeichnen —
   dashboard.js baut die Zeilen. Sie werden deshalb ueber ihre
   Spaltennummer getroffen. Die Reihenfolge der Spalten steht im
   Tabellenkopf gleich darueber; wer sie aendert, aendert auch das hier.

     Dubai/Trainee/SB   5-7   Volumen staerkster · insgesamt · nutzbar
     Teamleiter/BM      5,6   Teamvolumen · geplantes TV
                        10-13 Trend TV · EGV-Plan · realisiert · Trend */
.zahlen-aus .geld,
.zahlen-aus #topDubaiTable    td:nth-child(n+5):nth-child(-n+7),
.zahlen-aus #topTraineeTable  td:nth-child(n+5):nth-child(-n+7),
.zahlen-aus #topSBTable       td:nth-child(n+5):nth-child(-n+7),
.zahlen-aus #topTeamLeadTable td:nth-child(5),
.zahlen-aus #topTeamLeadTable td:nth-child(6),
.zahlen-aus #topTeamLeadTable td:nth-child(n+10):nth-child(-n+13),
.zahlen-aus #topBMTable       td:nth-child(5),
.zahlen-aus #topBMTable       td:nth-child(6),
.zahlen-aus #topBMTable       td:nth-child(n+10):nth-child(-n+13) {
    position:relative; color:transparent; user-select:none;
}
.zahlen-aus .geld::after,
.zahlen-aus #topDubaiTable    td:nth-child(n+5):nth-child(-n+7)::after,
.zahlen-aus #topTraineeTable  td:nth-child(n+5):nth-child(-n+7)::after,
.zahlen-aus #topSBTable       td:nth-child(n+5):nth-child(-n+7)::after,
.zahlen-aus #topTeamLeadTable td:nth-child(5)::after,
.zahlen-aus #topTeamLeadTable td:nth-child(6)::after,
.zahlen-aus #topTeamLeadTable td:nth-child(n+10):nth-child(-n+13)::after,
.zahlen-aus #topBMTable       td:nth-child(5)::after,
.zahlen-aus #topBMTable       td:nth-child(6)::after,
.zahlen-aus #topBMTable       td:nth-child(n+10):nth-child(-n+13)::after {
    content:"•••";
    position:absolute; inset:0;
    display:flex; align-items:center; justify-content:center;
    color:var(--c-ink-3); letter-spacing:.14em; font-weight:600;
}

/* Ein Diagramm hat keinen Text zum Maskieren — es wird unscharf. */
.zahlen-aus .geld-bild {filter:blur(9px); opacity:.45; pointer-events:none}

/* ── Fremdtexte im Dunkelmodus ────────────────────────────────────────
   Eventtexte und Nachrichten kommen aus dem Editor und bringen eigene
   Farben als style-Attribut mit — meist schwarz, weil sie fuer weisses
   Papier geschrieben wurden. Auf dunklem Grund sind sie damit
   unsichtbar; gemessen waren es 1,2:1.

   Ein style-Attribut schlaegt jede Klassenregel, deshalb hier !important
   — und nur im Dunkelmodus, damit eine bewusst gesetzte Farbe im Hellen
   erhalten bleibt. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .kz-event-text [style*="color"],
    :root:not([data-theme="light"]) .kz-fliess [style*="color"],
    :root:not([data-theme="light"]) .kz-event-text font[color],
    :root:not([data-theme="light"]) .kz-fliess font[color] {
        color: var(--c-ink-2) !important;
    }
    :root:not([data-theme="light"]) .kz-event-text [style*="background"],
    :root:not([data-theme="light"]) .kz-fliess [style*="background"] {
        background: transparent !important;
    }
}
:root[data-theme="dark"] .kz-event-text [style*="color"],
:root[data-theme="dark"] .kz-fliess [style*="color"],
:root[data-theme="dark"] .kz-event-text font[color],
:root[data-theme="dark"] .kz-fliess font[color] {
    color: var(--c-ink-2) !important;
}
:root[data-theme="dark"] .kz-event-text [style*="background"],
:root[data-theme="dark"] .kz-fliess [style*="background"] {
    background: transparent !important;
}


/* ── Struktur-Atlas ───────────────────────────────────────────────────
   Der Entwurfsbaukasten (kommandozentrale/app.css) bringt alle Formen des
   Atlas mit: .at-org, .at-node, .at-tree, .at-pyr, .at-gauge. Was hier
   steht, ist das, was im Frontend eine Tailwind-Klasse erledigt und was
   es nur im Blade-Markup gibt.

   Die frühere Datei public/css/kommandozentrale-atlas.css — die Vorlage
   struktur-atlas_3.html mit ihren eigenen Namen, unter .atlas gekapselt —
   ist damit weg. Zwei Formensätze für einen Bildschirm waren genau die
   Doppelung, die der Umbau beenden soll. */

/* Die Stufe als Farbe. Im Frontend kommt sie über bg-pos-* aus Tailwind;
   hier trägt das Kürzel ein data-Merkmal, weil das Markup aus dem Skript
   entsteht und ein Merkmal weniger fehleranfällig ist als vier Klassen.
   Die Farbe trägt nie allein: das Kürzel steht daneben. */
.at-node .pos[data-t="lead"],    .at-trow .pos[data-t="lead"]    {background:var(--t-lead);    color:var(--t-lead-ink)}
.at-node .pos[data-t="senior"],  .at-trow .pos[data-t="senior"]  {background:var(--t-senior);  color:var(--t-senior-ink)}
.at-node .pos[data-t="junior"],  .at-trow .pos[data-t="junior"]  {background:var(--t-junior);  color:var(--t-junior-ink)}
.at-node .pos[data-t="trainee"], .at-trow .pos[data-t="trainee"] {background:var(--t-trainee); color:var(--t-trainee-ink)}

/* Der Name auf einer Karte ist ein Knopf — er stellt die Person in die
   Mitte. Aussehen soll er wie der Text daneben. */
.at-node b button {
    display:block; width:100%; text-align:left; font:inherit; color:inherit;
    cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.at-node b button:hover {color:var(--c-accent)}
.at-node b span {display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}

/* Eine Teamreihe darf umbrechen: sechs Karten zu 152px passen nicht in
   jede Breite, und eine Reihe, die seitlich hinausläuft, ist unlesbar. */
.at-row {flex-wrap:wrap}

/* Der Weg von der Wurzel bis zur Person in der Mitte. Die Stelle, an der
   man steht, ist fett und kein Knopf. */
#at-pfad {display:flex; align-items:center; gap:5px; flex-wrap:wrap; min-width:0}
#at-pfad button {font:inherit; color:var(--c-ink-2); cursor:pointer; max-width:160px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
#at-pfad button:hover {color:var(--c-accent)}
#at-pfad b {max-width:180px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
#at-pfad svg {width:11px; height:11px; color:var(--c-ink-3); flex-shrink:0}

/* Die vier Knöpfe rechts in der Werkzeugleiste. */
.at-werkzeuge {margin-left:auto; display:flex; align-items:center; gap:8px; flex-shrink:0; flex-wrap:wrap}
.at-werkzeuge .b-btn {white-space:nowrap}

/* Beiläufige Angabe in einer Filterleiste — Blickweite und Anzahl. */
.fils-note {margin-left:auto; font-size:11.5px; color:var(--c-ink-3); white-space:nowrap}

/* Auswertung und 6 × 6: mehrere Flächen untereinander. .at-view ist
   display:contents, der Abstand muss also von hier kommen. */
.at-stapel {display:grid; gap:12px}

/* Die weiteren Wurzeln als Knopfreihe. */
.at-wurzelliste {display:flex; flex-wrap:wrap; gap:8px}

/* Die Balken neben dem Ring dürfen den Rest der Breite nehmen. */
.at-gauge-balken {flex:1; min-width:200px}

/* Während eine andere Blickweite geholt wird. */
[aria-busy="true"] {opacity:.55; transition:opacity .18s}

/* Die Trefferliste unter dem Suchfeld — aus der Kundenvorlage
   übernommen: bei achtzig Treffern ist „der erste" eine willkürliche
   Wahl, wer sucht soll auswählen können. */
.at-search {position:relative}
.at-liste {
    position:absolute; top:calc(100% + 6px); left:0; right:0; min-width:260px;
    max-height:320px; overflow-y:auto; z-index:40;
    background:var(--c-surface); border:1px solid var(--c-line); border-radius:10px;
    box-shadow:var(--sh-lift); padding:4px;
}
.at-liste button {
    display:flex; align-items:center; gap:9px; width:100%; text-align:left;
    padding:7px 9px; border-radius:7px; font:inherit; font-size:12.5px;
    color:var(--c-ink); cursor:pointer;
}
.at-liste button:hover, .at-liste button:focus-visible {background:var(--c-tint)}
.at-liste .pos {
    display:inline-flex; align-items:center; height:16px; padding:0 6px; border-radius:4px;
    font-family:"IBM Plex Mono",monospace; font-size:9.5px; font-weight:600; flex-shrink:0;
}
.at-liste .pos[data-t="lead"]    {background:var(--t-lead);    color:var(--t-lead-ink)}
.at-liste .pos[data-t="senior"]  {background:var(--t-senior);  color:var(--t-senior-ink)}
.at-liste .pos[data-t="junior"]  {background:var(--t-junior);  color:var(--t-junior-ink)}
.at-liste .pos[data-t="trainee"] {background:var(--t-trainee); color:var(--t-trainee-ink)}
.at-liste .nm {min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.at-liste .lv {margin-left:auto; font-family:"IBM Plex Mono",monospace; font-size:10.5px;
    color:var(--c-ink-3); flex-shrink:0}
.at-liste .mehr {padding:7px 9px; font-size:11px; color:var(--c-ink-3)}

/* ── Meckerbox ────────────────────────────────────────────────────────
   Der Editor (Quill) bringt sein eigenes Stylesheet mit; hier steht nur,
   was ihn in die Umgebung des Entwurfs einpasst. */
.kz-editor .b-lbl {display:block; margin-bottom:5px}
.kz-editor #standalone-container {border:1px solid var(--c-line); border-radius:8px; overflow:hidden}
.kz-editor .ql-toolbar.ql-snow {border:0; border-bottom:1px solid var(--c-line); background:var(--c-surface-2)}
.kz-editor .ql-container.ql-snow {border:0; font:inherit; font-size:13px; color:var(--c-ink)}
.kz-editor .ql-editor {min-height:160px; max-height:320px}
.kz-editor .ql-editor.ql-blank::before {color:var(--c-ink-3); font-style:normal}
.kz-editor .ql-snow .ql-stroke {stroke:var(--c-ink-2)}
.kz-editor .ql-snow .ql-fill {fill:var(--c-ink-2)}
.kz-editor .ql-snow .ql-active .ql-stroke {stroke:var(--c-accent)}
.kz-editor .ql-snow .ql-active .ql-fill {fill:var(--c-accent)}

/* Ein Kommentar. Im Bestand stand die Farbe fest im style-Attribut
   (rgba(21,41,66,.95) auf Weiss) — im Dunkelmodus dieselbe dunkle Flaeche
   auf dunklem Grund. Hier tragen die Merkmale des Designs. */
.kz-kommentar {
    border:1px solid var(--c-line); border-radius:9px; background:var(--c-surface-2);
    padding:10px 12px; margin-bottom:8px;
}
.kz-kommentar .text {font-size:12.5px; line-height:1.55; color:var(--c-ink); white-space:pre-wrap}
.kz-kommentar .fuss {
    display:flex; align-items:center; gap:9px; flex-wrap:wrap;
    margin-top:8px; padding-top:7px; border-top:1px solid var(--c-line);
    font-size:11px; color:var(--c-ink-3);
}
.kz-kommentar .wann {font-family:"IBM Plex Mono",monospace}
.kz-kommentar .fuss .b-lnk {margin-left:auto}

/* Eine Zeile „hier steht nichts" innerhalb eines Dialogs. */
.b-empty-zeile {font-size:12.5px; color:var(--c-ink-3); padding:10px 0}

/* Ein Kontrollkästchen mit Beschriftung — der Baukasten hat Felder und
   Auswahllisten, aber keinen Haken. */
.kz-haken {display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--c-ink-2); cursor:pointer}
.kz-haken input {width:15px; height:15px; accent-color:var(--c-accent); flex-shrink:0}

/* Die Wiederholung setzt sich vom Rest des Formulars ab: sie ist eine
   eigene Entscheidung, keine weitere Angabe. */
.kz-wiederholung {margin-top:14px; padding-top:13px; border-top:1px solid var(--c-line); display:grid; gap:11px}

/* flatpickr legt ein zweites, sichtbares Feld neben das echte. Es soll
   aussehen wie jedes andere Feld des Entwurfs. */
.b-form input.form-control[readonly], .b-form .flatpickr-input {cursor:pointer}
.flatpickr-input.form-control.input {font:inherit}

/* ──────────────────────────────────────────────────────────────────────
   Protokolle

   Bauteile, die der Entwurf nicht kennt, weil das Modul dort nicht
   vorkommt. Sie halten sich an dessen Tokens und Maße.
   ────────────────────────────────────────────────────────────────────── */

/* Wachsende Textfelder (kommandozentrale-protokoll.js setzt die Hoehe):
   kein Griff, kein Scrollen im Feld. Gilt fuer alle, die das Skript
   fuehrt — in .b-form wie in .prot-zusatz. */
[data-prot-wachsen] {resize:none;overflow:hidden;min-height:38px;line-height:1.55}

/* Ein Zusatzfeld ist ein Paar aus Bezeichnung und Inhalt. Im Bestand
   trugen beide denselben name und kosteten damit Daten. */
.prot-zusatz {display:grid;grid-template-columns:minmax(0,220px) minmax(0,1fr);gap:10px;
    padding:11px 0;border-bottom:1px solid var(--c-line)}
.prot-zusatz:last-child {border-bottom:0;padding-bottom:0}
.prot-zusatz label {display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--c-ink-2);min-width:0}
.prot-zusatz input, .prot-zusatz textarea {font:inherit;font-size:12.5px;line-height:1.55;
    padding:7px 9px;border:1px solid var(--c-line);border-radius:7px;background:var(--c-surface);
    color:var(--c-ink);width:100%;min-width:0}
.prot-zusatz textarea {resize:none;overflow:hidden;line-height:1.55;padding:9px 11px;border-radius:9px;min-height:38px}
@media (max-width:767px) {.prot-zusatz {grid-template-columns:minmax(0,1fr)}}

/* Protokolltext in der Ansicht. Er enthält Zeilenumbrüche aus nl2br und
   soll die Breite einer Lesezeile nicht überschreiten. */
.prot-text {margin:0;font-size:13px;line-height:1.6;color:var(--c-ink);max-width:78ch;
    overflow-wrap:anywhere}

/* Titel mit Schlosssymbol: beide in einer Zeile, das Schloss rueckt
   nicht darunter. */
.prot-titel {display:inline-flex;align-items:center;gap:6px}
.prot-titel svg {width:12px;height:12px;color:var(--c-ink-3);flex-shrink:0}

/* ──────────────────────────────────────────────────────────────────────
   Struktur-Atlas — Seitenfeld, 6 × 6, Deckelkarte, Kräftefeld-Treffer
   Nach der Kundenvorlage struktur-atlas_3.html (renderSidePanel,
   sixsixCoreHtml, buildOrgNode), gesetzt in den Tokens des Entwurfs.
   ────────────────────────────────────────────────────────────────────── */

/* Fläche links, Seitenfeld rechts; auf dem Handy untereinander. */
.at-mit-seite {display:grid; grid-template-columns:minmax(0,1fr) 260px; align-items:stretch}
.at-mit-seite .at-canvas {border-right:1px solid var(--c-line)}
@media (max-width:900px) {.at-mit-seite {grid-template-columns:minmax(0,1fr)}
    .at-mit-seite .at-canvas {border-right:0}}

.at-seite {padding:14px; background:var(--c-surface); border-top:1px solid var(--c-line);
    border-bottom:1px solid var(--c-line); font-size:12.5px; min-width:0}
.at-seite-kopf {display:flex; align-items:center; gap:10px; margin-bottom:12px}
.at-seite-kopf .wer {min-width:0}
.at-seite-kopf .wer b {display:block; font-size:14px; font-weight:600; line-height:1.3;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.at-seite-kopf .wer span {font-size:11.5px; color:var(--c-ink-3)}

/* Stufenfarben für Avatar, Punkt und Platzkreis — dieselben Tokens wie
   die Positionsmarken (.at-node .pos[data-t]). */
.at-avatar, .ss-slot .sc, .ss-row .sc, .at-ebenen .dot, .ss-chip .dot {background:var(--t-trainee); color:var(--t-trainee-ink)}
[data-t="lead"].at-avatar,   .ss-slot .sc[data-t="lead"],   .ss-row .sc[data-t="lead"],   .at-ebenen .dot[data-t="lead"],   .ss-chip .dot[data-t="lead"]   {background:var(--t-lead);   color:var(--t-lead-ink)}
[data-t="senior"].at-avatar, .ss-slot .sc[data-t="senior"], .ss-row .sc[data-t="senior"], .at-ebenen .dot[data-t="senior"], .ss-chip .dot[data-t="senior"] {background:var(--t-senior); color:var(--t-senior-ink)}
[data-t="junior"].at-avatar, .ss-slot .sc[data-t="junior"], .ss-row .sc[data-t="junior"], .at-ebenen .dot[data-t="junior"], .ss-chip .dot[data-t="junior"] {background:var(--t-junior); color:var(--t-junior-ink)}

.at-avatar {width:38px; height:38px; border-radius:50%; display:flex; align-items:center;
    justify-content:center; font-weight:700; font-size:13px; flex-shrink:0}

.at-kpis {display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; margin-bottom:14px}
.at-kpis .kpi {background:var(--c-surface-2); border-radius:8px; padding:9px 8px; text-align:center; min-width:0}
.at-kpis .kpi b {display:block; font-size:17px; font-weight:600; color:var(--c-ink)}
.at-kpis .kpi span {display:block; font-size:10px; color:var(--c-ink-3); text-transform:uppercase;
    letter-spacing:.04em; margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

.at-ebenen .row {display:flex; align-items:center; gap:8px; padding:5px 0; border-bottom:1px solid var(--c-line)}
.at-ebenen .row:last-child {border-bottom:0}
.at-ebenen .dot {width:8px; height:8px; border-radius:50%; flex-shrink:0; display:block}
.at-ebenen .lbl {flex:1; color:var(--c-ink-2); min-width:0}
.at-ebenen .val {font-weight:600; color:var(--c-ink)}

/* 6 × 6 — sechs Plätze */
.ss-slots {display:flex; flex-wrap:wrap; gap:14px}
.ss-slot {width:96px; display:flex; flex-direction:column; align-items:center; text-align:center; gap:5px;
    background:none; border:0; padding:0; font:inherit; color:inherit}
.ss-slot .sc {width:50px; height:50px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    font-weight:700; font-size:14px; border:0; cursor:default; font-family:inherit}
.ss-slot button.sc {cursor:pointer}
.ss-slot button.sc:hover {box-shadow:0 0 0 3px var(--c-accent-soft)}
.ss-slot .sn {font-size:11.5px; font-weight:600; color:var(--c-ink); line-height:1.25; overflow-wrap:anywhere}
.ss-slot .sp {font-size:10px; color:var(--c-ink-3)}
.ss-slot.leer .sc {background:none; border:2px dashed var(--c-line); color:var(--c-ink-3); font-size:20px; font-weight:400}
.ss-slot.leer .sn {color:var(--c-ink-3); font-weight:500}
.ss-slot.bonus {cursor:pointer}
.ss-slot.bonus .sc {background:var(--c-accent); color:var(--c-accent-ink); box-shadow:0 0 0 3px var(--c-accent-soft)}
.ss-slot.bonus .sn {color:var(--c-accent)}
.ss-slot.bonus .sp {text-decoration:underline; text-underline-offset:2px}
.ss-slot.bonus.offen .sc {box-shadow:0 0 0 3px var(--c-accent)}
.ss-bonus {display:flex; flex-wrap:wrap; gap:6px; padding-top:12px; margin-top:12px; border-top:1px dashed var(--c-line)}
.ss-chip {display:inline-flex; align-items:center; gap:6px; padding:4px 9px; border-radius:99px;
    border:1px solid var(--c-line); background:var(--c-surface); font:inherit; font-size:11.5px; color:var(--c-ink); cursor:pointer}
.ss-chip:hover {border-color:var(--c-accent); color:var(--c-accent)}
.ss-chip .dot {width:8px; height:8px; border-radius:50%; display:block}
.unit.voll {color:var(--st-ok)}

/* 6 × 6 — 1. indirekte Ebene: sechs Zeilen mit Punktreihe */
.ss-indirekt {display:flex; flex-direction:column; gap:7px}
.ss-row {display:flex; align-items:center; gap:12px; background:var(--c-surface-2); border-radius:9px; padding:8px 12px}
.ss-row .sc {width:30px; height:30px; border-radius:50%; display:flex; align-items:center; justify-content:center;
    font-weight:700; font-size:10px; flex-shrink:0}
.ss-row.leer .sc {background:none; border:2px dashed var(--c-line); color:var(--c-ink-3)}
.ss-row .who {flex:1; min-width:0; line-height:1.3}
.ss-row .who b {display:block; font-size:12.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.ss-row .who span {font-size:11px; color:var(--c-ink-3)}
.ss-row.leer .who b {color:var(--c-ink-3); font-weight:500}
.ss-dots {display:flex; gap:4px; flex-shrink:0}
.ss-dots i {width:10px; height:10px; border-radius:50%; display:block; background:var(--c-tint); border:1px solid var(--c-line)}
.ss-dots i.voll {background:var(--s1); border-color:var(--s1)}
.ss-row .cnt {min-width:52px; text-align:right; font-weight:600; flex-shrink:0}
@media (max-width:640px) {.ss-row {flex-wrap:wrap} .ss-row .who {flex-basis:100%; order:-1}}


/* Eventkalender: eine Zeile Auszug in der Kachel, der Volltext im Dialog.
   Die feste Hoehe mit Scrollkasten (.kz-event-huelle) braucht die Kachel
   damit nicht mehr; im Dialog scrollt der Text bei Bedarf selbst. */
.kz-event-auszug {font-size:12.5px; color:var(--c-ink-2); margin:6px 0 0; line-height:1.55;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.kz-event-dialog {max-height:60vh; overflow:auto; padding-right:6px; margin-top:10px;
    font-size:13px; line-height:1.6; color:var(--c-ink)}

/* ──────────────────────────────────────────────────────────────────────
   Struktur-Atlas — Leinwand, Baum in Spalten, Kräftefeld
   Übernommen aus der Kundenvorlage struktur-atlas_3.html, in den Tokens
   des Entwurfs. Die Verbinder sind CSS am Zweig — kein Messen, kein
   Kreuzen: jeder Zweig steht als Spalte unter seiner Karte.
   ────────────────────────────────────────────────────────────────────── */

.at-leinwand {position:relative; overflow:hidden; cursor:grab; touch-action:none;
    background:radial-gradient(circle at 30% 20%, var(--c-surface-2), var(--c-canvas) 60%)}
.at-leinwand.zieht {cursor:grabbing; user-select:none}
.at-inhalt {position:absolute; top:40px; left:40px; transform-origin:0 0; will-change:transform}
#at-force-svg {position:absolute; inset:0; width:100%; height:100%; cursor:grab}
#at-force-svg:active {cursor:grabbing}

.at-badge {position:absolute; top:12px; right:14px; z-index:10; font-family:"IBM Plex Mono",monospace; font-size:11px;
    background:var(--c-ink); color:var(--c-surface); padding:5px 11px; border-radius:999px}
.at-note {position:absolute; top:12px; left:14px; z-index:10; max-width:260px; margin:0; font-size:11.5px; line-height:1.45;
    color:var(--c-ink-2); background:var(--c-surface); border:1px solid var(--c-line); border-radius:10px; padding:8px 12px; box-shadow:var(--sh)}
.at-note:empty {display:none}

.at-ctrl {position:absolute; bottom:14px; left:14px; z-index:10; display:flex; align-items:center; gap:4px;
    background:var(--c-surface); border:1px solid var(--c-line); border-radius:999px; padding:4px 6px; box-shadow:var(--sh)}
.at-ctrl .b-ib {width:28px; height:28px; border-radius:999px; font-size:15px; font-weight:600}
.at-ctrl .unit {min-width:44px; text-align:center; font-family:"IBM Plex Mono",monospace}
.at-slider {width:90px; accent-color:var(--c-accent); cursor:pointer; margin:0 2px}

.at-minimap {position:absolute; bottom:14px; right:14px; z-index:10; width:150px; height:110px; overflow:hidden;
    background:var(--c-surface-2); border:1px solid var(--c-line); border-radius:10px; box-shadow:var(--sh)}
.at-minimap::before {content:"ORIENTIERUNG"; position:absolute; top:3px; left:6px; z-index:1; font-family:"IBM Plex Mono",monospace;
    font-size:7px; letter-spacing:.08em; color:var(--c-ink-3)}
.at-minimap .mm-dot {position:absolute; width:5px; height:5px; margin:-2.5px; border-radius:50%; display:block;
    box-shadow:0 0 0 1px var(--c-surface-2)}
.at-minimap .mm-view {position:absolute; border:1.5px solid var(--c-accent); background:var(--c-accent-soft); border-radius:2px; opacity:.8}
@media (max-width:640px) {.at-minimap {display:none}}

/* Baum in Spalten */
.obranch {display:flex; flex-direction:column; align-items:center; position:relative}
.ochildren {display:flex; gap:20px; padding-top:30px; position:relative}
.ochildren::before {content:""; position:absolute; top:0; left:50%; width:0; height:30px; border-left:1.5px solid var(--c-ink-3); transform:translateX(-1px)}
.ochildren > .obranch {padding-top:30px}
.ochildren > .obranch::before {content:""; position:absolute; top:0; left:50%; width:0; height:30px; border-left:1.5px solid var(--c-ink-3); transform:translateX(-1px)}
.ochildren > .obranch:not(:only-child)::after {content:""; position:absolute; top:0; height:0; border-top:1.5px solid var(--c-ink-3)}
.ochildren > .obranch:first-child:not(:only-child)::after {left:50%; right:0}
.ochildren > .obranch:last-child:not(:only-child)::after {left:0; right:50%}
.ochildren > .obranch:not(:first-child):not(:last-child)::after {left:0; right:0}

.ocard {position:relative; z-index:2; min-width:156px; max-width:220px; padding:9px 14px 12px; text-align:center; white-space:nowrap;
    background:var(--c-surface); border:1px solid var(--c-line); border-top:3px solid var(--t-trainee); border-radius:10px; box-shadow:var(--sh)}
.ocard[data-t="lead"]   {border-top-color:var(--t-lead)}
.ocard[data-t="senior"] {border-top-color:var(--t-senior)}
.ocard[data-t="junior"] {border-top-color:var(--t-junior)}
.ocard.root {box-shadow:var(--sh-lift); border-color:var(--c-ink-3)}
.ocard.hit {border-color:var(--c-accent); box-shadow:0 0 0 2px var(--c-accent-soft), var(--sh)}
.ocard .pos {display:inline-flex; align-items:center; height:16px; padding:0 6px; border-radius:4px; font-family:"IBM Plex Mono",monospace;
    font-size:9.5px; font-weight:600; letter-spacing:.04em; background:var(--t-trainee); color:var(--t-trainee-ink)}
.ocard .pos[data-t="lead"]   {background:var(--t-lead);   color:var(--t-lead-ink)}
.ocard .pos[data-t="senior"] {background:var(--t-senior); color:var(--t-senior-ink)}
.ocard .pos[data-t="junior"] {background:var(--t-junior); color:var(--t-junior-ink)}
.ocard .name {font-size:12.5px; font-weight:700; color:var(--c-ink); margin-top:6px; line-height:1.3}
.ocard .name button {font:inherit; color:inherit; background:none; border:0; padding:0; cursor:pointer}
.ocard .name button:hover {color:var(--c-accent)}
.ocard .meta {font-family:"IBM Plex Mono",monospace; font-size:9.5px; color:var(--c-ink-3); margin-top:5px}
.otoggle {position:absolute; bottom:-10px; left:50%; transform:translateX(-50%); z-index:3; width:20px; height:20px; border-radius:50%;
    display:flex; align-items:center; justify-content:center; cursor:pointer; font:inherit; font-size:10px; font-weight:700; line-height:1;
    background:var(--c-surface); border:1px solid var(--c-ink-3); color:var(--c-ink-2)}
.otoggle:hover {border-color:var(--c-accent); color:var(--c-accent)}
.otoggle[aria-expanded="true"] {background:var(--c-accent); border-color:var(--c-accent); color:var(--c-accent-ink)}
.ocard.more {display:flex; flex-direction:column; align-items:center; justify-content:center; min-height:56px; border-style:dashed;
    border-top-color:var(--c-line); color:var(--c-accent); cursor:pointer; font:inherit}
.ocard.more b {font-size:15px; font-weight:700}
.ocard.more .pos {background:none; color:var(--c-accent); font-size:10px}
.ocard.more:hover {border-color:var(--c-accent); background:var(--c-accent-soft)}

/* Kräftefeld (d3) */
.knode circle {cursor:grab}
.knode.ghost circle {cursor:pointer; stroke-dasharray:4 3}
.knode text {font-family:"IBM Plex Sans",sans-serif; pointer-events:none}
.knode text.abk {font-family:"IBM Plex Mono",monospace; font-size:9px; fill:var(--c-ink-3)}
.knode.hit circle {stroke:var(--c-accent); stroke-width:3px}
.klink {stroke:var(--c-ink-3); stroke-opacity:.55; stroke-width:1.4px}

/* Protokolle — Ergaenzungen aus der Pruefung */

/* Ein Stapel Rahmen untereinander (statt Inline-Grid an drei Stellen). */
.prot-stapel {display:grid;gap:12px;min-width:0}
/* Knoepfe untereinander, volle Breite — Details-Karte und Passwortseite. */
.acts.spalte {margin-top:12px;flex-direction:column;align-items:stretch}
.acts.spalte .ghostbtn {height:44px}                 /* gleiche Hoehe wie .sub */
.prot-schmal {width:300px;max-width:100%}
/* Ein einspaltiges Formular fester Breite (Artwahl, Feld hinzufuegen). */
.b-form.prot-einspaltig {grid-template-columns:minmax(0,420px)}
@media (max-width:767px) {.b-form.prot-einspaltig {grid-template-columns:minmax(0,1fr)}}

/* Feldkatalog: die Eingaben liegen in Tabellenzellen, nicht in .b-form,
   und waren damit ungestylte Browser-Felder — 132 px in einer 465-px-
   Zelle, Namen abgeschnitten, im Dunkelmodus in Browserfarben. */
#prot-feld-tabelle input {width:100%;min-width:0;font:inherit;font-size:12px;padding:5px 8px;
    border:1px solid var(--c-line);border-radius:7px;background:var(--c-surface);color:var(--c-ink)}
#prot-feld-tabelle input:focus-visible {outline:2px solid var(--c-accent);outline-offset:1px}
#prot-feld-tabelle input[disabled] {color:var(--c-ink-3);background:var(--c-surface-2)}
#prot-feld-tabelle td {padding-top:6px;padding-bottom:6px}

/* ── Befunde der UI-Pruefung ───────────────────────────────────────────
   app.css:40 macht `.tip` zur schwebenden Sprechblase (absolut, unsichtbar,
   ohne Zeiger). Die Formularhinweise des Entwurfs heissen ebenfalls `.tip`
   und waren darum in jedem Blade-Formular unsichtbar. Hier gilt wieder,
   was app.css:590 fuer `.b-form .tip` meint: eine ruhige Zeile unter dem
   Feld. */
.b-form .tip, .fld .tip {position:static;opacity:1;pointer-events:auto;transform:none;
    background:none;border:0;padding:0;box-shadow:none;white-space:normal;
    font-size:10.5px;color:var(--c-ink-3);line-height:1.45;margin-top:2px}

/* Loeschen als Link — der Entwurf kennt `.b-lnk.bad`, das Blade nutzte
   eine Inline-Farbe. */
.b-lnk.bad {color:var(--st-bad)}
.b-lnk.bad:hover {color:var(--st-bad)}

/* Der Kopfhinweis ueber breiten Tabellen stand als Inline-Stil im Blade. */
.ph-hint {display:flex;align-items:center;gap:7px;border-bottom:1px solid var(--c-line);
    padding:8px 14px;font-size:11.5px;color:var(--c-ink-3);margin:0}

/* flatpickr im dunklen Schema: der Kalender bringt eigene Farben mit und
   blieb weiss auf dunklem Grund. Die Tokens der Seite gelten auch dort. */
.flatpickr-calendar {background:var(--c-surface);color:var(--c-ink);border:1px solid var(--c-line);
    box-shadow:0 8px 24px rgba(0,0,0,.14);font:inherit}
.flatpickr-calendar.arrowTop:before, .flatpickr-calendar.arrowTop:after {border-bottom-color:var(--c-line)}
.flatpickr-months .flatpickr-month, .flatpickr-current-month,
.flatpickr-months .flatpickr-prev-month, .flatpickr-months .flatpickr-next-month {color:var(--c-ink);fill:var(--c-ink)}
.flatpickr-current-month .flatpickr-monthDropdown-months {background:var(--c-surface);color:var(--c-ink)}
span.flatpickr-weekday {color:var(--c-ink-3)}
.flatpickr-day {color:var(--c-ink)}
.flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay, .flatpickr-day.flatpickr-disabled {color:var(--c-ink-3);opacity:.45}
.flatpickr-day:hover, .flatpickr-day.today:hover {background:var(--c-surface-2);border-color:var(--c-line)}
.flatpickr-day.today {border-color:var(--c-accent)}
.flatpickr-day.selected, .flatpickr-day.selected:hover {background:var(--c-accent);border-color:var(--c-accent);color:#fff}

/* Meckerbox — Dialog „Eintrag ansehen" nach dem Entwurf (Dialoge.vue). */
.mb-text {margin-top:14px;font-size:13px;line-height:1.65;color:var(--c-ink-2)}
.mb-text p {margin:0 0 8px}
.mb-kom-titel {margin:18px 0 8px;font-size:13.5px;font-weight:600}
.mb-kommentare .b-sl li .t > span {white-space:pre-wrap}

/* ── Reiter als Verweise ──────────────────────────────────────────────
   Der Entwurf schaltet Ansichten eines Moduls ueber eine .b-seg im Kopf.
   Wo die Ansichten eigene Seiten sind (Protokolle, Benachrichtigungen),
   sind die Knoepfe Verweise — gleiche Form, anderes Element. */
.b-seg a {font-size:11.5px;font-weight:600;padding:4px 10px;color:var(--c-ink-3);text-decoration:none;
    border-radius:7px;display:inline-flex;align-items:center;gap:6px;min-height:28px;white-space:nowrap;
    transition:background .18s,color .18s}
.b-seg a:hover {color:var(--c-ink)}
.b-seg a[aria-current="page"] {background:var(--c-surface);color:var(--c-ink);box-shadow:var(--sh)}

/* ── Rechner ──────────────────────────────────────────────────────────── */
.kz-rechner-suche {min-width:240px}
.kz-rechner-suche input {flex:1;min-width:0;border:0;background:transparent;color:var(--c-ink);font:inherit;
    font-size:12px;outline:none}
.kz-rechner .b-dc {border-style:solid;text-decoration:none;color:inherit;gap:8px}
.kz-rechner .b-dc:hover {border-color:var(--c-accent);background:var(--c-surface)}
.kz-rechner .b-dc .t .ext {margin-left:auto;color:var(--c-ink-3);width:14px;height:14px;flex-shrink:0}
.kz-rechner .b-dc .txt {font-size:11.5px;line-height:1.55;color:var(--c-ink-2)}
.kz-rechner .b-dc .chips {display:flex;flex-wrap:wrap;gap:5px;margin-top:auto}
.kz-rechner .b-empty {grid-column:1 / -1}

/* ── Protokoll lesen ──────────────────────────────────────────────────
   Jedes Feld ein Block mit Ueberschrift und lesbarer Zeilenlaenge — die
   Beschriftung-Wert-Zeilen quetschten lange Antworten in eine Spalte. */
.prot-lesen {display:flex;flex-direction:column}
.prot-lesen .feld {padding:14px 0;border-bottom:1px solid var(--c-line)}
.prot-lesen .feld:first-child {padding-top:0}
.prot-lesen .feld:last-child {border-bottom:0;padding-bottom:0}
.prot-lesen .feld .kopf {display:flex;align-items:baseline;gap:8px;margin-bottom:6px}
.prot-lesen .feld h4 {font-size:13.5px;font-weight:600;letter-spacing:-.005em}
.prot-lesen .feld .kopf .unit {font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.06em;
    text-transform:uppercase;color:var(--c-ink-3)}
.prot-lesen .feld .text {font-size:13.5px;line-height:1.7;color:var(--c-ink-2);white-space:pre-wrap;
    overflow-wrap:anywhere;max-width:78ch}
.prot-lesen .feld.leer .text {color:var(--c-ink-3);font-style:italic}
.prot-seite {position:sticky;top:12px;align-self:start}
@media (max-width:1023px) {.prot-seite {position:static}}

/* ── Meckerbox: Flaeche „Ein Anliegen ansehen" ───────────────────────── */
.mb-wahl select {border:0;background:transparent;color:var(--c-ink);font:inherit;font-size:12px;font-weight:600;
    outline:none;max-width:260px;text-overflow:ellipsis;cursor:pointer}
.mb-ans-text {font-size:13.5px;line-height:1.7;color:var(--c-ink-2);max-width:78ch}
.mb-ans-text p {margin:0 0 8px}
.mb-ans-text img {max-width:100%;height:auto;border-radius:6px}
.mb-ans-text ul, .mb-ans-text ol {padding-left:20px;margin:0 0 8px}
.mb-kommentare .b-sl li .t > span {white-space:pre-wrap}
/* .b-dc und .b-empty setzen display:flex mit derselben Spezifitaet wie
   [hidden] — das Attribut muss ausdruecklich gewinnen. */
.kz-rechner .b-dc[hidden], .kz-rechner [data-kz-leer][hidden] {display:none}

/* ── Dashboard-Dialoge ────────────────────────────────────────────────
   Die Akkordeons der vergangenen ABWs baut dashboard.js im Bestandsmarkup;
   hier bekommen sie die Form von .acc aus dem Entwurf: flach, Trennlinien
   statt Rahmen, der Zaehler rechts in Mono. */
.kz-acc .accordion-item {border:0;border-bottom:1px solid var(--c-line);border-radius:0;margin:0;overflow:visible}
.kz-acc .accordion-item:last-child {border-bottom:0}
.kz-acc .accordion-button {padding:11px 18px;font-size:13px;font-weight:600;background:transparent}
.kz-acc .accordion-button:hover {background:var(--c-tint)}
.kz-acc .accordion-body {border-top:1px solid var(--c-line);background:var(--c-surface-2)}
.kz-acc .accordion-body .table {font-size:12px}
.kz-acc .accordion-body .table thead th {background:transparent}
.kz-acc:empty::before {content:"Wird geladen…";display:block;padding:18px;font-size:12.5px;color:var(--c-ink-3)}
.dbody.flush .ph-hint {margin:0}
.b-news .chip.message_read {font-size:10px;padding:1px 7px 1px 5px}
#dlgUsErinnerung .b-sl {margin-top:12px}

/* ── Umsatzschmiede ──────────────────────────────────────────────────── */
.kz-datum input[type="date"] {border:0;background:transparent;color:var(--c-ink);font:inherit;font-size:12px;
    outline:none;padding:0;min-width:0}
#us-tn-tabelle select {font:inherit;font-size:12px;padding:4px 8px;border:1px solid var(--c-line);border-radius:7px;
    background:var(--c-surface);color:var(--c-ink);min-width:150px}
#us-tn-tabelle select:focus-visible {outline:2px solid var(--c-accent);outline-offset:1px}

/* ── PraeLux KI ───────────────────────────────────────────────────────
   Die Chat-Seite (Modules/Ki), im Aufbau an ChatGPT/Claude angelehnt:
   links ein einklappbarer Verlauf, rechts eine mittig begrenzte Spalte
   mit Nachrichten und einer schwebenden Eingabe. Eigenstaendige Bauteile
   (ki-*), keine Wiederverwendung von .b-msg/.b-compose: die Sprechblase
   nur fuer eigene Nachrichten, die KI-Antwort steht ohne Blase in voller
   Spaltenbreite — .b-msg legt beides auf dasselbe Muster fest.

   Hoehe: die Seite fuellt genau, was die Schale ihr laesst — siehe
   body.kz-voll weiter unten. Hier stand einmal
   min-height:calc(100dvh - 52px - 44px) mit geschaetzten Werten fuer
   Kopf- und Fusszeile; jede Abweichung liess das ganze Fenster rollen
   und die Eingabezeile nach oben wegwandern.

   Innen rollt nur .ki-strom und .ki-verlauf-liste; jedes Flex-Kind auf
   dem Weg dahin braucht min-height:0, sonst waechst der Rahmen mit dem
   Inhalt statt selbst zu rollen — die uebliche Flexbox-Falle bei
   verschachteltem overflow:auto. */
.ki-seite {display:flex;height:100%;min-height:0;
    background:var(--c-surface);border:1px solid var(--c-line);border-radius:12px;box-shadow:var(--sh-lift);overflow:hidden}

/* ── Verlauf ── */
.ki-verlauf {width:240px;flex-shrink:0;display:flex;flex-direction:column;min-height:0;background:var(--c-surface-2);
    border-right:1px solid var(--c-line);transition:width .18s ease,opacity .12s ease,border-color .18s ease}
.ki-seite.zu .ki-verlauf {width:0;opacity:0;visibility:hidden;border-color:transparent;pointer-events:none}
.ki-verlauf-kopf {padding:12px}
.ki-verlauf-kopf .b-btn {width:100%}
.ki-verlauf-liste {flex:1;min-height:0;overflow-y:auto;padding:0 8px}
.ki-gruppe + .ki-gruppe {margin-top:10px}
.ki-gruppen-titel {padding:10px 8px 4px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--c-ink-3)}
.ki-liste {list-style:none;margin:0;padding:0}
.ki-eintrag {display:flex;align-items:center;gap:2px}
.ki-eintrag .t {flex:1;min-width:0;display:block;padding:8px 8px;border-radius:7px;font-size:12.5px;line-height:1.4;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:inherit;transition:background .15s}
.ki-eintrag .t:hover {background:var(--c-tint)}
.ki-eintrag[aria-current="page"] .t {background:var(--c-accent-soft);color:var(--c-accent);font-weight:600}
.ki-loeschen-knopf {flex-shrink:0;width:26px;height:26px;border-radius:6px;display:grid;place-items:center;color:var(--c-ink-3);
    opacity:0;transition:opacity .15s,background .15s,color .15s}
.ki-loeschen-knopf svg {width:13px;height:13px}
.ki-loeschen-knopf:hover {background:var(--st-bad-bg);color:var(--st-bad)}
.ki-eintrag:hover .ki-loeschen-knopf, .ki-eintrag:focus-within .ki-loeschen-knopf {opacity:1}
.ki-verlauf-fuss {padding:10px 14px 12px}
.ki-hinweis {font-size:12.5px;color:var(--c-ink-2);line-height:1.5;padding:0 14px}
.ki-hinweis.klein {font-size:11.5px;color:var(--c-ink-3)}
.ki-scrim {display:none}

/* ── Nachrichten ── */
.ki-haupt {flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;background:var(--c-surface)}
.ki-strom {flex:1;min-height:0;overflow-y:auto;position:relative;scroll-behavior:smooth}
.ki-spalte {max-width:760px;margin:0 auto;padding:24px 16px;display:flex;flex-direction:column;gap:18px}

.ki-begruessung {padding:48px 8px 8px;text-align:left}
.ki-begruessung h2 {font-size:24px;font-weight:600;letter-spacing:-.012em}
.ki-begruessung > p {margin-top:8px;font-size:13.5px;color:var(--c-ink-2);line-height:1.55;max-width:56ch}
.ki-karten {display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-top:22px}
.ki-karte {display:flex;align-items:center;gap:10px;text-align:left;padding:13px 14px;border:1px solid var(--c-line);
    border-radius:11px;background:var(--c-surface-2);font-size:13px;color:var(--c-ink-2);transition:border-color .15s,background .15s}
.ki-karte:hover {border-color:var(--c-accent);background:var(--c-surface)}
.ki-karte svg {width:16px;height:16px;flex-shrink:0;color:var(--c-accent)}

.ki-n {display:flex;flex-direction:column}
.ki-n.nutzer {align-items:flex-end}
.ki-blase {max-width:80%;background:var(--c-accent-soft);border-radius:16px;padding:9px 14px;font-size:14px;line-height:1.5}
.ki-n.ki {width:100%}
.ki-kopf {display:flex;align-items:center;gap:8px;margin-bottom:6px}
.ki-kopf .plmark {width:22px;height:22px}
.ki-kopf b {font-size:13px;font-weight:600}
.ki-kopf time {font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--c-ink-3)}
.ki-werkzeuge {display:flex;flex-wrap:wrap;gap:6px;margin:0 0 8px 30px}
.ki-werkzeuge:empty {display:none;margin:0}
.ki-werkzeug {display:inline-flex;align-items:center;gap:4px;font-family:"IBM Plex Mono",monospace;font-size:10.5px;
    padding:2px 8px;border-radius:5px;background:var(--c-tint);color:var(--c-ink-2)}
.ki-werkzeug.laeuft {color:var(--c-accent)}
.ki-werkzeug.laeuft::before {content:"";width:6px;height:6px;border-radius:99px;background:currentColor;animation:ki-puls 1s infinite}
.ki-werkzeug.abgelehnt {background:var(--st-warn-bg);color:var(--st-warn)}
.ki-werkzeug.fehler {background:var(--st-bad-bg);color:var(--st-bad)}
/* Kein Einzug: der Fliesstext beginnt an derselben Kante wie die
   Eingabezeile darunter und die Nutzerblase darueber. Eingerueckt
   unter den Namen wirkte die Spalte gegenueber der Eingabe verschoben. */
.ki-prosa {font-size:14.5px;line-height:1.65}
.ki-prosa.wartet::after {content:"▍";animation:ki-puls .8s infinite;color:var(--c-ink-3)}
.ki-prosa table {width:100%;border-collapse:collapse;margin:8px 0;font-size:13px}
.ki-prosa th, .ki-prosa td {border-bottom:1px solid var(--c-line);padding:5px 8px;text-align:left;font-variant-numeric:tabular-nums}
.ki-prosa th {font-weight:600;color:var(--c-ink-2)}
.ki-prosa ul, .ki-prosa ol {margin:4px 0 4px 20px}
.ki-prosa p + p {margin-top:8px}
/* Verweise im Fliesstext: der Reset in dieser Datei nimmt jedem <a>
   Farbe und Unterlaengung, ein Link waere sonst nicht als solcher zu
   erkennen. Der Renderer laesst nur eigene Adressen und https zu. */
.ki-prosa a {color:var(--c-accent);text-decoration:underline;text-underline-offset:2px}
.ki-prosa a:hover {filter:brightness(1.15)}
.ki-prosa code {font-family:"IBM Plex Mono",monospace;font-size:12.5px;background:var(--c-tint);padding:0 4px;border-radius:4px}
.ki-prosa.ki-fehler {color:var(--st-bad)}
.ki-abbruch {color:var(--c-ink-3);font-size:11.5px}
@keyframes ki-puls {0%,100% {opacity:1} 50% {opacity:.25}}

.ki-nachunten-wrap {position:sticky;bottom:12px;display:flex;justify-content:center;pointer-events:none}
.ki-nachunten {pointer-events:auto;width:34px;height:34px;border-radius:99px;display:grid;place-items:center;
    background:var(--c-surface);border:1px solid var(--c-line);box-shadow:var(--sh-lift);color:var(--c-ink-2)}
.ki-nachunten:hover {color:var(--c-ink)}

/* ── Eingabe ── */
.ki-eingabe {position:sticky;bottom:0;background:var(--c-canvas);padding:12px 16px 16px;border-top:1px solid var(--c-line)}
/* Dieselbe Rechenart wie .ki-spalte (760 inkl. 16px Polsterung je
   Seite), damit Eingabefeld und Nachrichten exakt buendig stehen. */
.ki-eingabe form {max-width:760px;margin:0 auto;padding:0 16px}
.ki-box {display:flex;align-items:flex-end;gap:8px;border:1px solid var(--c-line);border-radius:18px;
    background:var(--c-surface);box-shadow:var(--sh-lift);padding:10px 10px 10px 14px}
.ki-box textarea {flex:1;border:0;background:transparent;resize:none;font:inherit;font-size:14px;line-height:1.5;
    max-height:200px;padding:5px 0;outline:none}
.ki-box textarea::placeholder {color:var(--c-ink-3)}
.ki-rund {flex-shrink:0;width:36px;height:36px;border-radius:99px;display:grid;place-items:center;transition:filter .15s,background .15s}
.ki-rund.akzent {background:var(--c-accent);color:var(--c-accent-ink)}
.ki-rund.akzent:hover {filter:brightness(1.08)}
.ki-rund.akzent[disabled] {opacity:.5;cursor:default}
.ki-rund.ghost {background:var(--c-tint);color:var(--c-ink-2)}
.ki-rund.ghost:hover {color:var(--c-ink)}
.ki-stopp-ico {width:11px;height:11px;border-radius:3px;background:currentColor}
.ki-eingabe .ki-hinweis {margin-top:9px;text-align:center;padding:0}

/* Unter 1024px startet der Verlauf eingeklappt (Standardwert kommt aus
   dem Inline-Skript oben), bleibt aber bis 767px dieselbe einklappbare
   Spalte wie auf dem Desktop — sie nimmt Platz weg statt ueber den Inhalt
   zu schweben. Erst ab 767px wird daraus ein Overlay. */
@media (max-width:767px) {
    .ki-seite {border-radius:0;border-left:0;border-right:0}
    /* .ki-seite.zu .ki-verlauf steht mit in der Regel, sonst gewinnt die
       Grundregel oben (dieselbe Spezifitaet, aber frueher im Text) und
       setzt width:0 — auf dem Handy soll die Breite bleiben, sichtbar
       ist die Leiste hier allein ueber transform gesteuert. */
    .ki-verlauf, .ki-seite.zu .ki-verlauf {
        width:280px;opacity:1;pointer-events:auto;border-color:var(--c-line);
        position:fixed;inset:0 auto 0 0;z-index:70;
        transform:translateX(-100%);transition:transform .2s ease;box-shadow:var(--sh-dlg)
    }
    .ki-seite:not(.zu) .ki-verlauf {transform:translateX(0)}
    .ki-seite:not(.zu) .ki-scrim {display:block;position:fixed;inset:0;z-index:60;background:var(--c-scrim)}
    .ki-karten {grid-template-columns:minmax(0,1fr)}
    .ki-begruessung {padding-top:28px}
}

/* ── Fehlerseite: Kopf auf Hoehe der Modulkopfzeile ───────────────────
   .err-top in app.css ist ein Block mit 14px Polsterung, und der
   Logo-Verweis darin ist inline-flex — er steht auf der Grundlinie der
   Zeile und traegt deren Unterlaenge mit. Zusammen ergibt das rund 68px
   Kopf, wo die Modulkopfzeile (.b-top) 52px hat. Als Flex-Container mit
   denselben Massen wie .b-top schliesst der Kopf buendig an das Raster
   der uebrigen Seiten an. */
.err-top {display:flex;align-items:center;min-height:52px;padding:8px 18px}

/* ── Beizeile einer Rangliste ─────────────────────────────────────────
   app.css gibt .b-rank die Zeile, den Balken und den Wert — aber keine
   Beizeile darunter. Die Standorte brauchen sie: am Balken steht der
   Umsatz, darunter Partnerzahl und Schnitt. Masse wie .b-prog .meta,
   damit beide Ranglisten gleich klingen. */
.b-rank .meta {font-size:11.5px; color:var(--c-ink-3)}

/* ── Trainee-Medaille in der Primaeranalyse ───────────────────────────
   Die Positionsspalte haengt bei Trainees eine Medaille an den Text. Die
   Regel stand im <style>-Block von components/table.blade.php, der mit
   der Migration entfallen ist; die Masse sind von dort uebernommen,
   damit die Zelle aussieht wie bisher. float:right stammt aus der
   Tabulator-Zelle und gehoert mit ihr ueberdacht, sobald die Tabelle des
   Entwurfs sie ersetzt. */
.medal {display:inline-block; width:20px; float:right}

/* ── Eingabe in einem Filterchip ──────────────────────────────────────
   app.css kleidet nur .b-fil select ein, nicht die Eingabe. Die
   Monatswahl der Leistungsfaehigkeit ist aber ein <input type="month">
   — ohne diese Regel traegt es seinen eigenen Rahmen mitten im Chip. */
.b-fil input {font:inherit; font-size:12px; border:0; background:transparent;
               color:var(--c-ink); outline:none; max-width:150px; padding:0}
.b-fil input::-webkit-calendar-picker-indicator {cursor:pointer; opacity:.55}
.b-fil input::-webkit-calendar-picker-indicator:hover {opacity:1}

/* ── Vorschlagsliste unter einem Eingabefeld ──────────────────────────
   Die Umsatzplanung sucht den Vertriebspartner tippend; ein <select>
   kann das bei dreistelliger Partnerzahl nicht. Die Liste haengt unter
   dem Feld und muss ueber den Dialoginhalt reichen, ohne ihn zu
   verschieben — also absolut im umgebenden <label>. */
.kz-vorschlag {position:absolute; top:100%; left:0; right:0; z-index:5; margin-top:4px;
               max-height:220px; overflow-y:auto; background:var(--c-surface);
               border:1px solid var(--c-line); border-radius:9px; box-shadow:var(--sh-lift)}
.kz-vorschlag button {display:block; width:100%; text-align:left; font:inherit; font-size:12.5px;
                      padding:7px 11px; border:0; background:transparent; color:var(--c-ink); cursor:pointer}
.kz-vorschlag button + button {border-top:1px solid var(--c-line)}
.kz-vorschlag button:hover,
.kz-vorschlag button[aria-selected="true"] {background:var(--c-accent-soft); color:var(--c-accent)}

/* ── Fehlerzustand im Formularraster ──────────────────────────────────
   .b-form baut jedes Feld als <label> mit eigener Eingabe, nicht als
   .fld mit .inp darin. Die Regel .fld.bad .inp aus app.css greift dort
   also nicht, und eine abgewiesene Eingabe bliebe unmarkiert — der
   Nutzer erfuehre nur, dass irgendetwas nicht stimmt. */
.b-form label.bad > input,
.b-form label.bad > select,
.b-form label.bad > textarea {border-color:var(--st-bad)}
.b-form label.bad > span:first-child {color:var(--st-bad)}

/* ── Bezeichner im Fliesstext ─────────────────────────────────────────
   Routen, Feldnamen und fremde Dienste stehen im Entwurfssatz in IBM
   Plex Mono, damit sie sich vom Satz abheben. app.css kennt die Familie
   nur ueber .fig, und das traegt zusaetzlich Tabellenziffern und engere
   Laufweite — fuer Namen ist das falsch. */
.mono {font-family:"IBM Plex Mono", ui-monospace, monospace; font-size:.92em}

/* ── Erfolgsmeldung der Anmeldeseiten ─────────────────────────────────
   app.css kennt .al, .al.warn und .al.bad — .al.ok fehlt dort, obwohl
   index.blade.php und passwords/forgot.blade.php es benutzen. Ohne diese
   Regel steht die Meldung „Link ist unterwegs“ ohne Flaeche und in der
   Textfarbe der Seite, also ununterscheidbar von normalem Text. */
.al.ok {background:var(--st-ok-bg); color:var(--st-ok)}

/* ── Codefeld des zweiten Faktors ─────────────────────────────────────
   Ein sechsstelliger Zifferncode wird abgelesen und verglichen, nicht
   gelesen. Tabellenziffern und weiter Zeichenabstand machen die Stellen
   einzeln greifbar; der Entwurf erreicht denselben Zweck mit sechs
   Kaestchen, die hier aus Gruenden der Code-Uebernahme entfallen.
   letter-spacing ruecht den Text optisch nach links — der gleich grosse
   Einzug rechts gleicht das aus. */
.kz-code {
    font-family:"IBM Plex Mono", ui-monospace, monospace;
    font-variant-numeric:tabular-nums;
    font-size:19px;
    letter-spacing:.34em;
    padding-right:.34em;
}
.kz-code::placeholder {letter-spacing:.34em; color:var(--c-ink-3); opacity:.55}

/* ═════════════════════════════════════════════════════════════════════
   ONBOARDING — die oeffentliche Vertragsstrecke
   =====================================================================
   Modules/Dashboard/Resources/views/onboard.blade.php, Entwurfssatz
   Teil 1, Bildschirm 1b. Die Bestaetigungsschritte benutzen die Schale
   der Anmeldung (.lg), die schon in app.css steht; alles hier ist der
   Vertragsschritt und sein Schrittanzeiger. Der Bestand brachte dafuer
   420 Zeilen .onboard__* mit eigenen Farben mit — die entfallen, diese
   Regeln arbeiten mit den Tokens der Schale.
   ═════════════════════════════════════════════════════════════════════ */

/* ── Schrittanzeiger ──────────────────────────────────────────────────
   Drei Stationen mit Verbindungslinie. Die Linie sitzt auf Hoehe der
   Kreise, nicht der Beschriftung — daher der Ausgleich unten. */
.ob-steps {display:flex; align-items:center; gap:0; margin-top:22px}
.ob-steps .st {display:flex; flex-direction:column; align-items:center; gap:7px; flex-shrink:0}
.ob-steps .st i {width:34px; height:34px; border-radius:99px; display:grid; place-items:center;
    border:1.5px solid var(--c-line); background:var(--c-surface); color:var(--c-ink-3);
    font-style:normal; font-family:"IBM Plex Mono",monospace; font-size:12.5px; font-weight:600}
.ob-steps .st i svg {width:15px; height:15px; stroke-width:2.4}
.ob-steps .st b {font-size:11px; font-weight:600; color:var(--c-ink-3); white-space:nowrap}
.ob-steps .st.done i {background:var(--st-ok); border-color:var(--st-ok); color:#fff}
.ob-steps .st.done b {color:var(--c-ink-2)}
.ob-steps .st.now i {border-color:var(--c-accent); color:var(--c-accent);
    box-shadow:0 0 0 3px var(--c-accent-soft)}
.ob-steps .st.now b {color:var(--c-ink)}
.ob-steps .ln {flex:1; height:1.5px; background:var(--c-line); margin:0 6px 22px; min-width:18px}
.ob-steps .ln.done {background:var(--st-ok)}

/* Auf schmalen Geraeten tragen die Kreise allein; die Namen wuerden die
   Zeile sprengen, und der aktuelle Schritt steht als Ueberschrift
   ohnehin darueber. */
@media (max-width:519px) {
    .ob-steps .st b {display:none}
    .ob-steps .ln {margin-bottom:0}
}

/* ── Der Vertragsschritt als eigene Seite ─────────────────────────────
   Kein .lg mehr: hier gibt es nichts zu erzaehlen, sondern ein Dokument
   zu lesen. Der Kopf traegt nur noch Marke und Schrittanzeiger. */
.ob-seite {min-height:100dvh; background:var(--c-canvas); display:flex; flex-direction:column}
.ob-kopf {display:flex; align-items:center; gap:24px; flex-wrap:wrap;
    padding:14px 22px; background:var(--c-surface); border-bottom:1px solid var(--c-line)}
.ob-kopf .ob-steps {margin-top:0; margin-left:auto; max-width:420px; flex:1; min-width:210px}

/* Links das Dokument, rechts die Zustimmung. Auf schmal untereinander —
   das Dokument bleibt lesbar, es wird nur kuerzer. */
.ob-vertrag {display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:14px;
    padding:22px; align-items:start}
@media (max-width:1023px) {
    .ob-vertrag {grid-template-columns:minmax(0,1fr) 300px}
}
@media (max-width:767px) {
    .ob-vertrag {grid-template-columns:1fr; padding:16px}
    .ob-kopf {padding:12px 16px}
}

/* ── Das Dokument ─────────────────────────────────────────────────────
   .blatt haelt im Entwurf eine Attrappe; hier stehen die vom PDF
   gezeichneten Seiten darin. Deshalb eine feste Hoehe mit eigenem
   Rollbereich: der Vertrag soll im Dokumentfenster gerollt werden und
   nicht die ganze Seite unter der Zustimmung wegziehen. */
.ob-doc {background:var(--c-surface); border:1px solid var(--c-line); border-radius:10px;
    overflow:hidden; display:flex; flex-direction:column}
.ob-doc .dk {display:flex; align-items:center; gap:9px; padding:11px 14px;
    border-bottom:1px solid var(--c-line)}
.ob-doc .dk h4 {font-size:13.5px; font-weight:600}
.ob-doc .dk > svg {width:15px; height:15px; color:var(--c-ink-3)}
.ob-doc .dk .r {margin-left:auto; display:flex; align-items:center; gap:8px}
.ob-doc .blatt {padding:18px; background:var(--c-surface-2); overflow-y:auto;
    height:min(72dvh, 760px); display:grid; gap:12px; align-content:start; justify-items:center}
.ob-doc .dp {display:flex; align-items:center; gap:10px; padding:10px 14px;
    border-top:1px solid var(--c-line); font-size:11.5px; color:var(--c-ink-3)}
.ob-doc .dp svg {width:13px; height:13px; flex-shrink:0}
.ob-doc .dp .fig {font-family:"IBM Plex Mono",monospace; white-space:nowrap}
@media (max-width:767px) {
    .ob-doc .blatt {height:min(58dvh, 520px)}
    .ob-doc .dp span:last-child {display:none}
}

/* Die gezeichneten Seiten. Die Breite kommt aus dem Massstab in
   kommandozentrale-onboard.js; max-width haelt sie im Rahmen, ohne dass
   die Zeichenflaeche kleiner gerechnet werden muesste. */
.ob-seitenbild {max-width:100%; height:auto; border-radius:4px; box-shadow:var(--sh);
    background:#fff}

/* ── Die Zustimmung ───────────────────────────────────────────────────
   Steht neben dem Dokument und nicht darunter: wer unterschreibt, soll
   sehen koennen, was. */
.ob-zust {background:var(--c-surface); border:1px solid var(--c-line); border-radius:10px;
    padding:16px 16px 17px; display:flex; flex-direction:column; gap:13px; position:sticky; top:22px}
.ob-zust h4 {font-size:13.5px; font-weight:600}
.ob-zust .lede {font-size:12.5px; color:var(--c-ink-2); line-height:1.5}
.ob-zust .haken {display:grid; gap:11px}
.ob-zust .hint {font-size:11.5px; color:var(--c-ink-3); line-height:1.5}
@media (max-width:767px) {
    .ob-zust {position:static}
}

/* Die Unterschriftsstelle — kein Bild, sondern die Ankuendigung, dass
   gleich eines entsteht. Der Name darunter steht wie auf Papier. */
.ob-sign {border:1.5px dashed var(--c-line); border-radius:9px; background:var(--c-surface-2);
    padding:16px 14px 11px; display:grid; gap:8px; justify-items:center; text-align:center}
.ob-sign .zug {font-family:"Segoe Script","Bradley Hand",cursive; font-size:25px;
    color:var(--c-ink); line-height:1.1}
.ob-sign .nm {font-size:11px; color:var(--c-ink-3); border-top:1px solid var(--c-line);
    padding-top:7px; width:100%}

/* Das Feld im Dialog, in dem wirklich unterschrieben wird. touch-action
   muss aus, sonst rollt die Geste die Seite statt zu zeichnen. */
.ob-pad {border:1.5px dashed var(--c-line); border-radius:9px; background:var(--c-surface-2);
    padding:10px; display:grid; gap:7px; justify-items:center}
.ob-pad canvas {width:100%; height:180px; touch-action:none; background:var(--c-surface);
    border-radius:6px; cursor:crosshair}
.ob-pad .nm {font-size:11px; color:var(--c-ink-3); border-top:1px solid var(--c-line);
    padding-top:6px; width:100%; text-align:center}

/* ── Der Abschluss ────────────────────────────────────────────────────
   Kein Formular mehr, nur noch was passiert ist und was als Naechstes
   kommt. Im Bestand fuehrte die Unterschrift ohne ein Wort auf
   praelux.de. */
.ob-fertig {display:grid; place-items:center; padding:52px 24px; text-align:center;
    background:var(--c-surface); margin:22px; border:1px solid var(--c-line); border-radius:12px}
.ob-fertig .ring {width:62px; height:62px; border-radius:99px; display:grid; place-items:center;
    background:var(--st-ok-bg); color:var(--st-ok); margin-bottom:17px}
.ob-fertig .ring svg {width:28px; height:28px; stroke-width:2.2}
.ob-fertig h3 {font-size:21px; font-weight:600; letter-spacing:-.016em}
.ob-fertig .lede {font-size:13.5px; color:var(--c-ink-2); margin-top:8px; max-width:48ch;
    line-height:1.6}
.ob-fertig .weiter {display:grid; gap:9px; margin-top:22px; width:100%; max-width:430px;
    text-align:left}
.ob-fertig .weiter .z {display:flex; align-items:flex-start; gap:10px; padding:11px 13px;
    border:1px solid var(--c-line); border-radius:9px; background:var(--c-surface-2);
    font-size:12.5px; line-height:1.5; color:var(--c-ink-2)}
.ob-fertig .weiter .z svg {width:15px; height:15px; color:var(--c-ink-3); flex-shrink:0;
    margin-top:2px}
.ob-fertig .weiter .z b {color:var(--c-ink); display:block}
.ob-fertig .acts {display:flex; gap:9px; margin-top:22px; flex-wrap:wrap; justify-content:center}
@media (max-width:767px) {
    .ob-fertig {padding:34px 20px; margin:16px}
}

/* ── Aktionen in einer Tabellenzelle ──────────────────────────────────
   Mehrere Knoepfe in einer Zelle, davon zwei in eigenen <form>-Elementen
   (Laravel braucht fuer POST und DELETE je eines). Ohne diese Regel
   stapelt der Block-Level-Kontext der Formulare sie untereinander. */
.b-tacts {display:flex; align-items:center; gap:4px; flex-wrap:nowrap}
.b-tacts form {display:contents}

/* ── Beisatz unter einer Feldgruppe ───────────────────────────────────
   app.css kennt .b-form .tip am einzelnen Feld, aber keinen Satz unter
   der ganzen Gruppe. Die Groessengrenze des Bildes gehoert aber zum
   Feld, nicht ins Etikett. */
.b-hint {font-size:11px; color:var(--c-ink-3); margin-top:6px; line-height:1.45}

/* ── Quill im Dialog ──────────────────────────────────────────────────
   Der Editor bringt sein eigenes Kleid mit (quill.snow.css) — Bootstrap-
   Masse und eckige Kanten. Diese Regeln setzen nur den Rahmen auf die
   Form der Schale; drinnen bleibt Quill, wie es ist. Dieselbe Loesung
   wie in Dashboard/news.blade.php, nur dort ohne Dialog.
   Die Mindesthoehe stand im Bestand als style="min-height:180px". */
.pn-editor {border:1px solid var(--c-line); border-radius:7px; overflow:hidden;
    background:var(--c-surface); margin-top:11px}
.pn-editor .ql-toolbar.ql-snow {border:0; border-bottom:1px solid var(--c-line);
    background:var(--c-surface-2)}
.pn-editor .ql-container.ql-snow {border:0; font:inherit; font-size:12.5px}
.pn-editor .ql-editor {min-height:180px; color:var(--c-ink)}
.pn-editor .ql-editor.ql-blank::before {color:var(--c-ink-3); font-style:normal}

/* Ein <select multiple> im .b-form: app.css gibt jedem select 7px
   Innenabstand und volle Breite, laesst aber die Hoehe am size-Attribut
   haengen — mit Innenabstand ergibt das eine abgeschnittene letzte
   Zeile. */
.b-form select[multiple] {padding:4px; min-height:9.5em}

/* ── PDF-Vorschau im Dialog ───────────────────────────────────────────
   Der Bestand gab dem Rahmen style="width:100%;height:80vh". 80vh ist
   auf dem Handy mehr, als der Dialog hoch sein darf; dvh rechnet die
   eingeblendete Adressleiste mit, und der Dialog begrenzt zusaetzlich. */
.pdf-rahmen {display:block; width:100%; height:min(72dvh, 760px); border:0;
    background:var(--c-surface-2)}

/* ── Dateiauswahl in einem .inp ───────────────────────────────────────
   app.css kleidet .inp input fuer Text ein: volle Hoehe, Schriftgroesse
   14. Eine Dateiauswahl bringt einen eigenen Knopf mit, der darin
   randlos klebt — diese Regel gibt ihm die Form der Schale. */
.inp input[type="file"] {font-size:12.5px; padding:0}
.inp input[type="file"]::file-selector-button {font:inherit; font-size:12px; font-weight:600;
    margin-right:10px; padding:5px 11px; border:1px solid var(--c-line); border-radius:7px;
    background:var(--c-surface-2); color:var(--c-ink-2); cursor:pointer}
.inp input[type="file"]::file-selector-button:hover {border-color:var(--c-ink-3); color:var(--c-ink)}

/* ── Textbausteine des Wartungsbanners ────────────────────────────────
   .b-kv setzt die Beschriftungsspalte in Kapitaelchen. Diese Bausteine
   sind aber Platzhalter: {not_in_login} unterscheidet Gross und Klein,
   und {NOT_IN_LOGIN} waere schlicht falsch. */
.wa-bausteine .k {text-transform:none; color:var(--c-accent); font-size:11.5px}

/* ── Nummerierte Schrittliste in einem Dialog ─────────────────────────
   Die Rueckfrage zum Offboarding zaehlt auf, was der Vorgang anfasst.
   base.css setzt list-style auf none (Meyer-Reset), also traegt die
   Nummer ein Zaehler. */
.ob-schritte {counter-reset:schritt; display:grid; gap:7px}
.ob-schritte li {counter-increment:schritt; display:flex; align-items:flex-start; gap:9px;
    font-size:12.5px; line-height:1.5; color:var(--c-ink-2)}
.ob-schritte li::before {content:counter(schritt); flex-shrink:0; width:19px; height:19px;
    border-radius:99px; display:grid; place-items:center; background:var(--c-tint);
    color:var(--c-ink-3); font-family:"IBM Plex Mono",monospace; font-size:10.5px;
    font-weight:600; margin-top:1px}

/* ═════════════════════════════════════════════════════════════════════
   EINSTELLUNGEN · KONTO
   =====================================================================
   Modules/Settings/Resources/views/index.blade.php. Der Bestand brachte
   hier einen <style>-Block fuer sechs Eingabekaestchen mit; die
   Codeeingabe ist jetzt wie ueberall ein Feld mit .kz-code.
   ═════════════════════════════════════════════════════════════════════ */

/* Eine Zeile Knoepfe unter einem Textblock. .b-pf hat dafuer schon
   flex-wrap, aber innerhalb von .b-pb gibt es nichts Vergleichbares. */
.se-akt {display:flex; gap:9px; flex-wrap:wrap; margin-top:14px}

/* Fliesstext in einem Panel. app.css kleidet <p> nur innerhalb von
   .b-empty und .dlg ein. */
.se-text {font-size:12.5px; line-height:1.6; color:var(--c-ink-2); max-width:70ch}

/* ── Die Unterseiten und ihre Bedingungen ─────────────────────────────
   Wie .b-sl des Entwurfs: je Zeile links Name und Regel, rechts ein Weg
   dorthin. Nicht sichtbare Eintraege bleiben stehen — gerade sie sind
   die Auskunft, die im Bestand fehlte. */
.se-liste {display:flex; flex-direction:column}
.se-liste li {display:flex; align-items:center; gap:12px; padding:10px 0;
    border-bottom:1px solid var(--c-line)}
.se-liste li:last-child {border-bottom:0}
.se-liste .t {display:flex; flex-direction:column; gap:2px; min-width:0; flex:1}
.se-liste .t b {font-size:12.5px; font-weight:600; color:var(--c-ink)}
.se-liste .t span {font-size:11.5px; color:var(--c-ink-3); line-height:1.45}
.se-liste li.aus .t b {color:var(--c-ink-3)}
.se-liste li > :last-child {flex-shrink:0}

/* ── Die vier Passwortregeln ──────────────────────────────────────────
   Der Bestand setzte je Regel ein Font-Awesome-Symbol und tauschte es
   beim Tippen aus. Hier traegt das ::before das Zeichen, und .ok
   faerbt es — ohne Symbolschrift und ohne DOM-Umbau. */
.se-regeln {display:grid; gap:5px; margin-top:4px}
.se-regeln li {display:flex; align-items:center; gap:8px; font-size:11.5px;
    color:var(--c-ink-3); transition:color .18s}
.se-regeln li::before {content:"○"; font-size:13px; line-height:1; flex-shrink:0}
.se-regeln li.ok {color:var(--st-ok)}
.se-regeln li.ok::before {content:"●"}

/* ── Zwei-Faktor: QR-Code und Schluessel ──────────────────────────────
   Der Server liefert den QR-Code als data:-Bild. Weisser Grund, weil ein
   QR-Code im dunklen Modus sonst nicht lesbar ist. */
.mfa-qr {display:grid; place-items:center; padding:14px; background:#fff;
    border:1px solid var(--c-line); border-radius:10px; margin-bottom:13px}
.mfa-qr img {width:100%; max-width:210px; height:auto; display:block}
.mfa-secret {text-align:center; font-weight:600; letter-spacing:.08em;
    word-break:break-all; font-size:12.5px; color:var(--c-ink);
    background:var(--c-surface-2); border:1px solid var(--c-line);
    border-radius:7px; padding:9px 11px; margin:6px 0 4px}

/* ── Wettkampf: Live-Ansicht ──────────────────────────────────────────
   Die Bausteine der Flaeche (.b-score, .b-cd, .b-race, .b-tl, .b-sl)
   stehen alle schon in app.css. Hier fehlen nur zwei Kleinigkeiten. */

/* Die im Bestand gespeicherte Teamfarbe ist ein freier Hexwert. Sie
   faerbt nicht mehr die Ueberschrift — auf dunklem Grund fiel ein Teil
   davon aus —, steht aber als Tupfer daneben, damit wiedererkennbar
   bleibt, welches Team gemeint ist. */
.wk-farbe {display:inline-block; width:12px; height:12px; border-radius:4px;
    border:1px solid var(--c-line); flex-shrink:0}

/* Ein Satz in einem Panelkoerper, wo sonst eine Flaeche stuende. */
.wk-hinweis {font-size:12.5px; line-height:1.55; color:var(--c-ink-3)}

/* Die Standanzeige im Kopf wird rot, wenn das Nachladen scheitert — auf
   einem Bildschirm an der Wand faellt ein eingefrorener Stand sonst
   niemandem auf. */
.b-fil.bad {color:var(--st-bad); border-color:var(--st-bad)}

/* ── Wettkampf-Editor: Zuordnung per Klick ────────────────────────────
   app.css gibt .b-pool li ein cursor:grab — dort wurde gezogen. Hier
   verschiebt ein Klick, und der Knopf fuellt die Zeile, damit die ganze
   Breite ein Ziel ist und nicht nur der Text. */
.b-pool li {cursor:default}
.wk-move {flex:1; min-width:0; text-align:left; font:inherit; font-size:12px;
    color:var(--c-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.wk-move:hover {color:var(--c-accent)}
.wk-move-ic {flex-shrink:0; font-family:"IBM Plex Mono",monospace; font-size:13px;
    color:var(--c-ink-3); line-height:1}
.b-pool li:hover .wk-move-ic {color:var(--c-accent)}

/* ── Monatsverdienst ──────────────────────────────────────────────────
   Der Verdienst traegt seine Zustandsfarbe, weil auf dieser Seite genau
   das die Frage ist: ueber oder unter dem Ziel der Ebene. Im Bestand
   stand die Farbe als Inline-Stil aus einer JS-Funktion im gerenderten
   DataTables-Markup; als Klasse ist es dasselbe, nur nachlesbar. */
.mv-wert.mv-ok  {color:var(--st-ok)}
.mv-wert.mv-bad {color:var(--st-bad)}

/* Eine ganze Zeile faellt auf, wenn ein Nachwuchspartner sein Ziel
   uebertroffen hat — oder wenn er seit zwei Monaten ohne BWS ist. Beides
   gab es im Bestand als text-success/text-danger von Bootstrap. */
.mv-stark td {background:var(--st-ok-bg)}
.mv-lahm  td {background:var(--st-bad-bg)}

/* ── Termintafel ──────────────────────────────────────────────────────
   Die Tafel ist .b-tt aus dem Entwurf (app.css): Namens- und Klappspalte
   bleiben beim Querscrollen stehen, je Termin eine Marke mit Kuerzel
   (.tp). Hier steht nur, was das Altsystem darueber hinaus braucht. */

/* Fuenf Ebenen statt der zwei des Entwurfs: die Tiefe als Einzug. Der
   Name wird gekuerzt statt die Spalte aufzublaehen; der volle Name steht
   im title der Zelle. */
.tt-tafel .b-tt tr td.nm {padding-left:calc(10px + var(--tt-ebene, 0) * 12px); max-width:240px;
    overflow:hidden; text-overflow:ellipsis}
.tt-tafel .b-tt tr.vm td.nm {font-size:12px; color:var(--c-ink)}
.tt-anzahl {margin-left:6px; font-family:"IBM Plex Mono",monospace; font-size:10px; font-weight:500;
    color:var(--c-ink-3)}

/* Die Tageskoepfe: in der Monatsansicht Verweise in die Woche, in der
   Wochenansicht nur Text — beide sehen aus wie die Knoepfe des Entwurfs. */
.b-tt thead th a, .b-tt thead th .tt-kopftag {display:block; padding:5px 3px; font-family:"IBM Plex Mono",monospace;
    font-size:10px; color:var(--c-ink-3); line-height:1.25; text-decoration:none}
.b-tt thead th a:hover {color:var(--c-ink); background:var(--c-tint)}
.b-tt thead th.today a, .b-tt thead th.today .tt-kopftag {color:var(--c-accent); font-weight:600}

/* Zugeklappt zeigt der Pfeil nach rechts. */
.b-tt td.cv button.tt-zu svg {transform:rotate(-90deg)}
.b-tt td.cv button svg {transition:transform .15s}

/* Eine Marke ist ein Knopf: mit der Tastatur erreichbar und auf dem
   Telefon antippbar. */
button.tp {border:0; cursor:pointer}
button.tp:focus-visible {outline:2px solid var(--c-accent); outline-offset:1px}
.b-tt td.d {min-width:34px}
.at-legend .tt-legende-heute {margin-left:auto; color:var(--c-ink-3)}

/* Telefon: die Namensspalte nahm vorher gut drei Viertel der Breite, es
   blieben zwei Tage sichtbar. Jetzt 124 px Name, dann sieben Tage. Die
   Marken werden groesser, damit sie sich treffen lassen. */
@media (max-width:767px){
    .b-tt th.nm, .b-tt td.nm {min-width:124px; max-width:124px; width:124px}
    .b-tt th.cv, .b-tt td.cv {left:124px}
    .tt-tafel .b-tt tr td.nm {padding-left:calc(8px + var(--tt-ebene, 0) * 7px); max-width:124px}
    .b-tt td.d {min-width:30px; height:34px}
    .b-tt .tp {min-width:24px; height:20px; font-size:10px}
    .at-legend .tt-legende-heute {margin-left:0}

    /* Drei Kennzahlen in einer Reihe statt drei Karten uebereinander —
       sonst war der erste Bildschirm voll, bevor die Tafel begann. */
    .g3.tt-kennzahlen {grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px}
    .tt-kennzahlen .b-kpi {padding:9px 10px}
    .tt-kennzahlen .b-kpi .k {font-size:10.5px; line-height:1.3}
    .tt-kennzahlen .b-kpi .v b {font-size:14px; white-space:nowrap}
    .tt-kennzahlen .b-kpi .foot {display:none}
}

.tt-aktionen {display:flex; gap:9px; flex-wrap:wrap; margin-bottom:14px}
.tt-loeschen {color:var(--st-bad); margin-top:14px}
.tt-lese {display:grid; grid-template-columns:auto 1fr; gap:5px 12px; margin:0}
.tt-lese dt {color:var(--c-ink-3)}
.tt-lese dd {margin:0; color:var(--c-ink)}

/* ── Reiterleiste der Einstellungen ───────────────────────────────────
   Bis zu elf Verweise. .b-seg kann das nicht: es hat overflow:hidden und
   flex-shrink:0, die hinteren Eintraege wurden abgeschnitten — auf jedem
   Bildschirm, nicht nur auf dem Telefon. Hier dasselbe Aussehen, aber
   seitlich schiebbar, und die Leiste gibt nach, statt den Kopf zu
   sprengen. */
.se-reiter {
    display:flex; align-items:stretch; min-width:0; flex:1 1 auto;
    border:1px solid var(--c-line); border-radius:6px;
    background:var(--c-surface-2);
    overflow-x:auto; overflow-y:hidden;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
    scroll-snap-type:x proximity;
}
.se-reiter::-webkit-scrollbar {display:none}
.se-reiter a {
    flex:0 0 auto; scroll-snap-align:start; white-space:nowrap;
    display:inline-flex; align-items:center;
    font-size:11.5px; font-weight:600; padding:4px 10px; min-height:28px;
    color:var(--c-ink-3); text-decoration:none;
    transition:background .18s, color .18s;
}
.se-reiter a:hover {color:var(--c-ink)}
.se-reiter a[aria-current="page"] {background:var(--c-surface); color:var(--c-ink); box-shadow:var(--sh)}
.se-reiter a:focus-visible {outline:2px solid var(--c-accent); outline-offset:-2px}

/* ── .b-seg mit vielen Eintraegen ─────────────────────────────────────
   Im Entwurf traegt .b-seg zwei bis vier Schalter, darum overflow:hidden
   und flex-shrink:0. In den Blade-Ansichten sind es mehr: Vpstatistik und
   Struktur-Atlas je sechs, Administration acht, Monatsverdienst sechs.
   Ab etwa 1000px Fensterbreite passten sie nicht mehr in den Kopf — was
   nicht passte, wurde abgeschnitten, ohne Hinweis und ohne Scrollbalken.

   Statt abzuschneiden laesst die Leiste sich nun seitlich schieben und
   darf schmaler werden als ihr Inhalt. Aussehen und Rundung bleiben, denn
   overflow-x:auto beschneidet ebenso am Radius. app.css bleibt unberuehrt. */
.b-seg {
    overflow-x:auto; overflow-y:hidden;
    min-width:0; flex-shrink:1;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
}
.b-seg::-webkit-scrollbar {display:none}
.b-seg button, .b-seg a {flex:0 0 auto; white-space:nowrap}

/* ── Ganzseitige Ansichten (kz-voll) ──────────────────────────────────
   Fuer Seiten, bei denen nur ein Bereich rollen soll — die KI-
   Unterhaltung. Zuvor rechnete .ki-seite mit min-height:calc(100dvh -
   52px - 44px), also mit geschaetzten Hoehen fuer Kopf- und Fusszeile.
   Jede Abweichung schob die Seite ueber den Rand: eine umgebrochene
   Kopfzeile, ein Laufband, die Reiterleiste am Telefonrand. Dann rollte
   das ganze Fenster und die Eingabezeile wanderte mit nach oben weg.

   Hier wird nichts mehr geschaetzt. Die Schale ist genau so hoch wie das
   Sichtfenster, der Inhaltsbereich nimmt sich den Rest, und gerollt wird
   ausschliesslich innen. 100dvh statt 100vh, damit die einfahrende
   Adressleiste auf dem Telefon nicht ueber den Rand schiebt. */
body.kz-voll {height:100dvh; overflow:hidden}
body.kz-voll .b-shell {height:100dvh; min-height:0}
body.kz-voll .b-main {min-height:0; overflow:hidden}

/* Der Inhaltsbereich fuellt, was Kopf-, Fusszeile und Telefonleisten
   uebrig lassen — ohne zu wissen, wie hoch die sind. min-height:0 ist
   die uebliche Flexbox-Bedingung, sonst waechst das Kind mit dem Inhalt
   statt selbst zu rollen. */
body.kz-voll .b-body {flex:1 1 auto; min-height:0; overflow:hidden; padding-bottom:14px}
body.kz-voll .b-body > * {min-height:0}

/* Die Fusszeile traegt auf einer ganzseitigen Ansicht nichts bei und
   nimmt Hoehe. Auf dem Telefon bleibt die Reiterleiste unten sichtbar. */
body.kz-voll .b-foot {display:none}

/* ── Termine: Auswertung ──────────────────────────────────────────────
   Der Filter im Bestand war eine Vue-Anwendung mit vue-multiselect und
   SlimSelect. Hier reichen ein Formular, Auswahlfelder und Haekchen. */
.ev-form {display:flex; flex-direction:column; gap:16px}
.ev-raster {display:grid; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr)); gap:12px; align-items:start}
.ev-gruppe {border:1px solid var(--c-line); border-radius:8px; padding:9px 11px 11px; min-width:0}
.ev-gruppe legend {font-size:10.5px; font-weight:600; color:var(--c-ink-3);
    text-transform:uppercase; letter-spacing:.06em; padding:0 4px}
.ev-hkchen {display:flex; align-items:center; gap:7px; padding:3px 0; font-size:12.5px; color:var(--c-ink-2); cursor:pointer}
.ev-hkchen input {flex-shrink:0}
.ev-hkchen:hover {color:var(--c-ink)}
.ev-akt {display:flex; gap:9px; flex-wrap:wrap}

/* Ein Balken hinter der Zahl statt eines Diagramms daneben: dieselbe
   Aussage, keine zweite Datenhaltung und keine Bibliothek. Er liegt
   hinter dem Text, nicht davor, damit die Zahl lesbar bleibt. */
.ev-balken {position:absolute; left:4px; right:4px; bottom:3px; height:3px;
    border-radius:2px; background:var(--c-tint); overflow:hidden}
.ev-balken::after {content:""; position:absolute; left:0; top:0; bottom:0;
    width:var(--ev-anteil, 0%); background:var(--c-accent); opacity:.55}
.b-t td:has(> .ev-balken) {position:relative; padding-bottom:9px}

/* ── Personalentwicklung ──────────────────────────────────────────────
   Filter, Fortschrittsbalken und die Karten der Ausbildungswochenenden.
   Im Bestand kamen diese Stile aus Tailwind-Klassen im Vue-Markup. */
.pe-filter {display:flex; flex-direction:column; gap:11px}
.pe-zeitraum {display:grid; grid-template-columns:repeat(auto-fit, minmax(130px, 1fr)); gap:9px}
.pe-akt {display:flex; gap:9px; flex-wrap:wrap}

/* Der Fortschritt je Stufe. Im Bestand drei ineinandergelegte divs mit
   absoluter Lage; hier ein Element mit einem ::after als Fuellung. Die
   Farben sind die des Bestands: blau, gelb, gruen. */
.pe-balken {display:inline-block; position:relative; vertical-align:middle;
    width:54px; height:6px; border-radius:99px; background:var(--c-tint); overflow:hidden}
.pe-balken::after {content:""; position:absolute; left:0; top:0; bottom:0; width:var(--pe-anteil, 0%)}
.pe-l1::after {background:#3B82F6}
.pe-l2::after {background:#EAB308}
.pe-l3::after {background:#22C55E}
/* Die Zahl neben dem Balken. Der Bestand zeigte nur den Balken — ohne
   Beschriftung liess sich nicht ablesen, ob 40 oder 60 Prozent. */
.pe-zahl {margin-left:6px; font-size:10.5px; color:var(--c-ink-3)}

.pe-dateien {display:flex; gap:9px; flex-wrap:wrap; align-items:center}

/* Der Ereignis-Dialog der Personalentwicklung. */
.pe-stufen {display:grid; gap:7px}
.pe-stufe {display:flex; align-items:center; gap:10px; font-size:12.5px; color:var(--c-ink-2)}
.pe-stufe > span:first-child {min-width:64px}
.pe-stufe .pe-balken {flex:1; width:auto; max-width:240px}
.pe-ereignisse {list-style:none; margin:0; padding:0; display:grid; gap:4px}
.pe-ereignisse li {display:flex; align-items:baseline; gap:9px; font-size:12.5px;
    padding:4px 0; border-bottom:1px solid var(--c-line)}
.pe-ereignisse li:last-child {border-bottom:0}
.pe-ereignisse li b {flex:1; font-weight:600; color:var(--c-ink)}
.pe-ereignisse li span {font-family:"IBM Plex Mono",monospace; font-size:11px}
.pe-e-an span {color:var(--st-ok)}
.pe-e-aus b {color:var(--c-ink-3); font-weight:400}
.pe-e-aus span {color:var(--c-ink-3)}

/* Seitenwechsel unter langen Tabellen. */
.pe-blaettern {display:flex; align-items:center; gap:12px; flex-wrap:wrap;
    padding:10px 14px 2px; font-size:11.5px}
.pe-blaettern .ghostbtn[aria-disabled="true"] {opacity:.45; pointer-events:none}

/* Die Eingabefelder im Bearbeiten-Dialog der Personalentwicklung. */
.pe-ereignisfelder {display:grid; grid-template-columns:repeat(auto-fit, minmax(230px, 1fr)); gap:10px}
.pe-stufenkopf {margin-top:14px}
.pe-eingabe {display:flex; align-items:center; gap:8px}
.pe-eingabe > input, .pe-eingabe > select {flex:1; min-width:0}

/* ── Excel-Abgleich ───────────────────────────────────────────────────
   Je Zelle zwei Werte: oben aus der Datei, darunter aus dem System. Wo
   sie nicht uebereinstimmen, wird die Zelle markiert — im Bestand war
   das rote Schrift in einer Karte je Treffer. */
.az-abgleich td {vertical-align:top}
.az-abgleich .az-x, .az-abgleich .az-s {display:block; white-space:nowrap}
.az-abgleich .az-s {color:var(--c-ink-3); font-size:11px; margin-top:2px}
.az-abgleich td.az-anders {background:var(--st-bad-bg)}
.az-abgleich td.az-anders .az-x, .az-abgleich td.az-anders .az-s {color:var(--st-bad)}
.az-abgleich .az-akt {white-space:nowrap}
.az-abgleich .az-akt .b-lnk + .b-lnk {margin-left:10px}

/* ── Neuer Kundenprozess ──────────────────────────────────────────────
   Die Schrittanzeige im Kopf ist Anzeige, kein Reiter: weiter geht es
   nur ueber die Knoepfe unten, weil jeder Schritt den vorigen braucht. */
.az-schritte {list-style:none; margin:0; padding:0; display:flex; gap:6px; flex-wrap:wrap}
.az-schritte li {font-size:11.5px; font-weight:600; padding:3px 10px; border-radius:99px;
    border:1px solid var(--c-line); color:var(--c-ink-3); white-space:nowrap}
.az-schritte li.done {color:var(--st-ok); border-color:var(--st-ok-fill); background:var(--st-ok-bg)}
.az-schritte li[aria-current="step"] {color:var(--c-accent); border-color:var(--c-accent); background:var(--c-accent-soft)}

.az-lede {font-size:13px; color:var(--c-ink-2); margin:0 0 12px}
.b-pf .az-akt {margin-left:auto; display:flex; gap:8px; flex-wrap:wrap; align-items:center}

/* Kundensuche: Treffer als Liste von Knoepfen unter dem Feld. */
.az-suche {display:grid; gap:6px; margin-bottom:16px; max-width:560px}
.az-suche .hint {font-size:12px; margin:0}
.az-treffer {list-style:none; margin:0; padding:0; border:1px solid var(--c-line); border-radius:9px;
    background:var(--c-surface); max-height:280px; overflow-y:auto}
.az-treffer li + li {border-top:1px solid var(--c-line)}
.az-treffer button {display:flex; flex-direction:column; gap:1px; width:100%; text-align:left; padding:8px 11px}
.az-treffer button:hover, .az-treffer button:focus-visible {background:var(--c-tint); outline:none}
.az-treffer b {font-size:13px; font-weight:600; color:var(--c-ink)}
.az-treffer span {font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--c-ink-3)}
.az-suche .b-note .b-lnk {margin-left:6px}

/* Eine Karte je Vertrag statt der Tabelle des Entwurfs: dreizehn Spalten
   Eingabefelder passen auf kein Handy, und auch am 13-Zoll-Schirm musste
   man seitwaerts rollen. */
.az-vertraege {display:grid; gap:12px}
.az-vertrag {border:1px solid var(--c-line); border-radius:10px; padding:10px 14px 14px; margin:0; min-width:0}
.az-vertrag legend {display:flex; align-items:center; gap:8px; padding:0 4px; font-size:12px;
    font-weight:600; color:var(--c-ink-2)}
.az-vertrag legend .b-ib {width:26px; height:26px}
.az-vertrag .b-form {margin-top:4px}
.az-vertrag .b-form input[hidden] {display:none}
.b-form label.cb.az-cb {flex-direction:row; align-items:center; align-self:end; min-height:34px; font-size:12.5px}
.b-form .az-abschluss {grid-column:1/-1; display:flex; align-items:center; gap:8px 18px; flex-wrap:wrap;
    padding-top:8px; border-top:1px dashed var(--c-line)}
.b-form .az-abschluss label.cb {flex-direction:row; align-items:center; font-size:12.5px}
.az-abschluss-titel {font-size:11.5px; color:var(--c-ink-2); margin-right:4px}
.cb input[type="radio"] + i {border-radius:50%}
.az-bws {display:flex; gap:6px}
.az-bws input {flex:1}
.az-bws .ghostbtn.sm {height:auto}

/* Datei waehlen: das Feld liegt unsichtbar im Knopf, so bleibt es per
   Tastatur erreichbar und die Beschriftung zeigt den Dateinamen. */
.az-datei {position:relative; overflow:hidden; cursor:pointer; max-width:100%; justify-content:flex-start}
.az-datei span {overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0}
.az-datei input[type="file"] {position:absolute; inset:0; opacity:0; cursor:pointer; width:100%}
.az-datei:focus-within {outline:2px solid var(--c-accent); outline-offset:2px}
.b-dc .need {cursor:pointer; border:0}
.b-dc.az-nicht {border-style:solid; border-color:var(--st-warn-fill); background:var(--st-warn-bg)}
.b-dc.az-nicht .need {background:var(--st-warn-fill); color:#fff}
.b-dc.az-ziel {border-color:var(--c-accent); background:var(--c-accent-soft)}
.b-dc .az-datei {width:100%}

#az-n-fortschritt {width:160px; height:8px}
.az-bausteine {display:flex; gap:6px; flex-wrap:wrap}
.az-bausteine .chip {cursor:pointer; font-family:"IBM Plex Mono",monospace; font-size:11.5px; padding:4px 10px}
.az-bausteine .chip[disabled] {opacity:.45; cursor:default}
/* .b-form label ist eine Spalte; Datei-Knopf und Auswahlkaestchen sind
   ebenfalls <label> und brauchen die Zeile. */
.b-form label.az-datei {flex-direction:row; align-items:center; gap:7px; color:var(--c-ink-2); font-size:12px}
.b-form label.az-datei input[type="file"] {padding:0; border:0}

/* ── Chipleiste am Telefon ────────────────────────────────────────────
   .ph-chips nimmt Kopffilter und Kopfknoepfe auf und laeuft seitlich.
   Zwei Dinge fehlten: nichts darf darin schrumpfen — die .b-seg, die
   weiter oben schrumpfen darf, fiel hier auf 2 px zusammen, ihre
   Eintraege lagen ueber den Nachbarn — und nichts soll auf Zeilenhoehe
   gestreckt werden; der Monatsname wurde dadurch zur hohen Pille. */
.ph-chips {align-items:center}
.ph-chips > * {flex-shrink:0}
.ph-chips .b-seg {overflow:visible}
/* ── Kundenprozesse: VP-Dialog ────────────────────────────────────────
   Vertriebspartner, Nachbearbeitung und „Fehlende Dokumente
   nachgereicht?" (Modules/Aza2/Resources/views/kz/vaza/vp.blade.php). */

/* Kunde · Art · Gesellschaft im Kopf, neben dem Titel. Die .x liegt oben
   rechts ueber dem Kopf; darum Platz rechts frei halten. */
.az-vp-wer {font-size:12px; color:var(--c-ink-3); min-width:0; overflow-wrap:anywhere}
#dlgAzVp .dhead, #dlgAzPp .dhead, #dlgAzFd .dhead {padding-right:52px}

#dlgAzVp .dbody, #dlgAzPp .dbody {display:grid; gap:12px}
/* Die Panels sind Kinder der .dbody; ohne eigenes Raster klebten Tabelle
   und Ueberschrift aneinander. */
#dlgAzVp [data-kz-panel] {display:grid; gap:10px; min-width:0}
#dlgAzVp [data-kz-panel][hidden] {display:none}
/* Rasterkinder wachsen sonst auf die Breite ihres Inhalts, und die .b-tw
   darin kann nicht mehr selbst rollen — die Tabelle ragte dann ueber den
   Dialogrand hinaus. */
#dlgAzVp .dbody > *, #dlgAzVp [data-kz-panel] > *, #dlgAzPp .dbody > * {min-width:0}
#dlgAzVp .b-lbl {margin-bottom:0}
.az-vp-form {grid-template-columns:minmax(0,1fr)}
.az-vp-form textarea {resize:vertical}

/* Reiter ohne Bemerkungen: gesperrt, aber lesbar mit Hinweis (title). */
.az-vp-reiter .b-seg {display:inline-flex}
.az-vp-reiter .b-seg button[disabled] {opacity:.45; cursor:help}

/* Vertragsliste: Nummer mit Art darunter, wie .b-t td.nm .u. */
#dlgAzVp .b-t th[scope="row"] {font-family:inherit; font-size:12.5px; letter-spacing:0; text-transform:none;
    color:var(--c-ink); background:transparent; position:static; font-weight:600; white-space:normal}
.az-vp-art {display:block; font-size:11px; color:var(--c-ink-3); font-weight:400}
#dlgAzVp th .pill {margin-top:3px}

/* Unterlagen: Knopf und Name in einer Zeile, der Name kuerzt sich. */
.az-vp-dok td {vertical-align:middle}
.az-vp-dok td:nth-child(2) {white-space:normal}
.az-vp-wahl {font-size:12px; color:var(--c-ink-3); margin-left:6px; overflow-wrap:anywhere}
.az-vp-dok tr.az-gewaehlt .az-vp-wahl {color:var(--c-ink); font-weight:600}
.az-vp-dok tr.az-vp-vertragsdatei th, .az-vp-dok tr.az-vp-vertragsdatei td {border-top:1px dashed var(--c-line)}
.az-vp-dok td.r .ghostbtn.sm {display:inline-flex}
.az-vp-weg {color:var(--st-bad)}
/* Bemerkungen und Dateinamen sind Fliesstext, nicht einzeilig wie der
   Rest der .b-t. */
.az-vp-bem td.az-umbruch {white-space:normal; min-width:14ch; max-width:40ch; overflow-wrap:anywhere}

/* Nachbearbeitung: neue Nachricht oben, darunter Nachrichten | Anhaenge. */
.az-pp-neu {display:grid; gap:8px}
.az-pp-neu .b-form {grid-template-columns:minmax(0,1fr)}
.az-pp-akt {display:flex; align-items:center; gap:8px 12px; flex-wrap:wrap}
.az-pp-akt .hint {font-size:11.5px; flex:1 1 16ch}
.az-pp-akt .sub.sm {margin-left:auto}
.az-pp-spalten {display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px;
    border-top:1px solid var(--c-line); padding-top:12px}
.az-pp-spalten .hint {font-size:12px; margin:0}
.az-pp-liste, .az-pp-anhaenge {list-style:none; margin:0; padding:0; display:grid; gap:8px}
/* Nachrichten koennen lang werden; der Dialog soll nicht endlos wachsen. */
.az-pp-liste {max-height:360px; overflow-y:auto}
.az-pp-liste li {border:1px solid var(--c-line); border-radius:8px; padding:8px 10px; background:var(--c-surface-2);
    font-size:12.5px; line-height:1.5}
.az-pp-liste li b {font-weight:600; color:var(--c-ink)}
.az-pp-liste li .mut {margin-left:8px; font-size:11px}
.az-pp-liste li p {margin:2px 0 0; white-space:pre-wrap; overflow-wrap:anywhere; color:var(--c-ink-2)}
.az-pp-anhaenge li {display:flex; align-items:center; gap:8px; min-width:0}
.az-pp-anhaenge .b-lnk {min-width:0; overflow-wrap:anywhere; flex:1}
.az-pp-weg {color:var(--c-ink-3)}
/* Zweiter Klick loescht: der Knopf muss das deutlich sagen. */
.az-pp-weg.az-scharf {color:#fff; background:var(--st-bad); border-color:var(--st-bad)}
#dlgAzPp .dfoot, #dlgAzFd .dfoot {flex-wrap:wrap}
.az-pp-abschluss {display:flex; gap:8px; flex-wrap:wrap}
#dlgAzPp .dfoot .r {align-items:center}

/* .b-t nimmt der letzten Zeile nur den td-Rand; die Zeilenkoepfe hier
   sind th und behielten ihn sonst. */
#dlgAzVp .b-t tbody tr:last-child th {border-bottom:0}
/* „Vertragsabschluss mit Vertragsdatei" darf umbrechen, sonst rollt die
   zweispaltige Liste auf dem Handy seitwaerts. */
.az-vp-vtr td {white-space:normal}

@media (max-width: 640px) {
    .az-pp-spalten {grid-template-columns:minmax(0,1fr)}
    /* app.css gibt jeder .b-t auf dem Handy 600 px Mindestbreite (zum
       Seitwaertsrollen). Die zwei kleinen Tabellen hier passen ohne. */
    .b-t.az-vp-vtr, .b-t.az-vp-dok {min-width:0}
    /* Unterlagen als Karten-Zeilen: Titel oben, darunter Stand und Knopf.
       Drei Spalten mit Dateinamen passen nicht auf 390 px. */
    .az-vp-dok, .az-vp-dok tbody {display:block}
    .az-vp-dok thead {position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%)}
    .az-vp-dok tr {display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center;
        border-bottom:1px solid var(--c-line)}
    .az-vp-dok tbody tr:last-child {border-bottom:0}
    .az-vp-dok tr > th {grid-column:1/-1; border-bottom:0; padding-bottom:2px}
    .az-vp-dok tr > td {border-bottom:0; min-width:0}
    .az-vp-dok tr.az-vp-vertragsdatei {border-top:1px dashed var(--c-line)}
    .az-vp-dok tr.az-vp-vertragsdatei th, .az-vp-dok tr.az-vp-vertragsdatei td {border-top:0}
    #dlgAzPp .dfoot .r, #dlgAzVp .dfoot .r {margin-left:0; flex-wrap:wrap}
}
/* ── Kundenprozesse: Kunde und Umsatzvergleich ────────────────────────
   Dialoge aus Modules/Aza2/Resources/views/kz/vaza/kunde.blade.php:
   Kundeninformationen (.az-vk), Umsatzvergleich (.az-vu), Legende (.az-vl)
   und die Zeilentoene der Gastseite (.az-v-ton-*).                     */

/* .dlgwrap ist ein Raster mit einer auto-Spur; die waechst mit dem
   breitesten Inhalt. Eine Tabelle mit nowrap-Zellen machte den Dialog bei
   390px breiter als den Schirm, statt in .b-tw zu rollen. */
#dlgAzVKunde, #dlgAzVUmsatz, #dlgAzVLegende {grid-template-columns:minmax(0,1fr)}

.az-vk > .al, .az-vk > .b-note {margin-bottom:12px}
.az-vk-abstand {margin-top:18px}
/* Lange E-Mail-Adressen haben keine Trennstelle und schoeben die Wertspalte
   (minmax(min-content,1fr) in .b-kv .row) sonst aus dem Dialog. */
.az-vk-umbruch {overflow-wrap:anywhere}
.az-vk-kommentar {white-space:pre-line}
.az-vk-adresse {font-style:normal; font-size:12.5px; line-height:1.6; color:var(--c-ink)}

.az-vk-pw {display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.az-vk-pw[hidden] {display:none}
/* .b-form ist ein dreispaltiges Raster; hier nur Feld und zwei Knoepfe in
   einer Zeile. */
.az-vk-pw.b-form {display:flex}
.az-vk-pw.b-form input {width:auto; flex:1 1 140px; max-width:220px}
.az-vk-rueckfrage {margin-top:8px}
.az-vk-rueckfrage[hidden] {display:none}
.az-vk-akt {display:flex; gap:8px; flex-wrap:wrap; margin-top:8px}

/* .b-lbl setzt Mono und Versalien; der Knopf darin soll aussehen wie jeder andere. */
.b-lbl .az-vk-bearbeiten {margin-left:auto; text-transform:none; letter-spacing:0;
    font-family:"IBM Plex Sans","Segoe UI",system-ui,sans-serif}
.b-lbl .az-vk-bearbeiten[aria-pressed="true"] {border-color:var(--c-accent); color:var(--c-accent)}

/* Die Wahlfelder sind <div>, nicht <label> (siehe Blade) — dieselbe Spalte
   wie .b-form label, und die Trefferliste haengt darunter. */
.b-form .az-vk-wahl {display:flex; flex-direction:column; gap:4px; font-size:11.5px; color:var(--c-ink-2);
    min-width:0; position:relative}
.b-form .az-vk-wahl input[aria-invalid="true"] {border-color:var(--st-bad)}
.az-vk-wahl-fehler {color:var(--st-bad)}
/* Ueber dem Rest des Dialogs statt ihn zu verschieben. */
.az-vk-wahl .az-treffer {position:absolute; top:100%; left:0; right:0; z-index:5; margin-top:2px;
    max-height:220px; box-shadow:var(--sh-lift)}
.az-vk-wahl .az-treffer li {padding:7px 11px; font-size:12.5px; color:var(--c-ink); cursor:pointer}
.az-vk-wahl .az-treffer li:hover, .az-vk-wahl .az-treffer li.an {background:var(--c-tint)}

/* Umsatzvergleich */
.az-vu-laden {display:flex; align-items:center; justify-content:center; gap:8px; padding:40px 0;
    font-size:13px; color:var(--c-ink-2)}
.az-vu-laden[hidden] {display:none}
.az-vu-dreh {width:16px; height:16px; animation:az-vu-dreh 1s linear infinite}
@keyframes az-vu-dreh {to {transform:rotate(360deg)}}
@media (prefers-reduced-motion: reduce) {.az-vu-dreh {animation:none}}
.az-vu-erneut {margin-left:10px; display:inline-flex}
.az-vu-zeitraum {grid-template-columns:repeat(4,minmax(0,1fr)) auto; align-items:end;
    padding-bottom:14px; margin-bottom:14px; border-bottom:1px solid var(--c-line)}
.az-vu-laden-knopf {display:flex}
.az-vu-laden-knopf .sub.sm {height:34px}
.az-vu-ungueltig {grid-column:1/-1; color:var(--st-bad); font-style:normal}
.az-vu-ungueltig[hidden] {display:none}
.az-vu-leer {text-align:center; padding:24px 0; font-size:13px}
.az-vu-leer[hidden] {display:none}
.az-vu-leiste {display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:10px}
/* Die Monatsleiste nimmt den Rest der Zeile und schiebt seitlich
   (siehe „.b-seg mit vielen Eintraegen"). */
.az-vu-leiste .b-seg {flex:1 1 240px}
.az-vu-leiste .b-seg[hidden] {display:none}
.az-vu-blaettern {display:flex; align-items:center; gap:4px; font-size:12px; white-space:nowrap}
.az-vu-blaettern[hidden] {display:none}
.az-vu-blaettern .b-ib[disabled] {opacity:.35; cursor:default}
.az-vu-excel {margin-left:auto}
.az-vu-kappung {margin:-4px 0 10px; font-size:11.5px}
.az-vu-monat {align-items:center; margin-top:4px}
.az-vu-monat .ic {width:12px; height:12px}
/* Die Tabelle rollt im Dialog, der Kopf bleibt stehen. */
.az-vu .b-tw {max-height:min(60vh,560px); overflow-y:auto}
.az-vu .b-t td.fig {font-variant-numeric:tabular-nums; white-space:nowrap}

@media (max-width: 720px) {
    .az-vu-zeitraum {grid-template-columns:repeat(2,minmax(0,1fr))}
    .az-vu-laden-knopf {grid-column:1/-1}
    .az-vu-laden-knopf .sub.sm {width:100%}
    .az-vu-excel {margin-left:0}
}

/* Zeilentoene der Uebersicht (Rot, Gelb, Blau, Lila, Tuerkis wie im Vue:
   aza-table-danger, -warning, -info, -qm-rejected, table-info). Die
   Gastseite setzt sie an Zeilen, die Legende an ihre Farbfelder. */
.az-v-ton-rot {background:var(--st-bad-bg)}
.az-v-ton-gelb {background:var(--st-warn-bg)}
.az-v-ton-blau {background:#E3EDFB}
.az-v-ton-lila {background:var(--tr-qm)}
.az-v-ton-tuerkis {background:#DDF3F4}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .az-v-ton-blau {background:rgba(91,147,240,.18)}
    :root:not([data-theme="light"]) .az-v-ton-tuerkis {background:rgba(45,190,200,.16)}
}
:root[data-theme="dark"] .az-v-ton-blau {background:rgba(91,147,240,.18)}
:root[data-theme="dark"] .az-v-ton-tuerkis {background:rgba(45,190,200,.16)}

/* Legende */
.az-vl .b-tw + .b-lbl {margin-top:18px}
/* Die Legende ist Fliesstext: Zeilen umbrechen statt seitwaerts rollen,
   auch unter 768px, wo app.css jeder .b-t 600px Mindestbreite und eine
   klebende erste Spalte von 146px gibt. */
.az-vl .b-t {min-width:0}
.az-vl .b-t td {white-space:normal}
.az-vl .b-t th:first-child, .az-vl .b-t td:first-child {width:92px; min-width:0; white-space:nowrap; position:static; box-shadow:none}
.az-v-muster {display:inline-block; width:34px; height:16px; border-radius:4px; border:1px solid var(--c-line);
    vertical-align:middle}
.az-vl-sym {display:inline-flex; align-items:center; gap:4px; color:var(--c-ink-2)}
.az-vl-sym .ic, .az-vl-knopf .ic {width:14px; height:14px}
.az-vl-sym.info {color:var(--c-accent)}
.az-vl-sym.ok {color:var(--st-ok)}
/* Nachbildung des Schattens, den .b-tw.scroll an einer breiten Tabelle zeigt. */
.az-vl-schatten {width:34px; height:16px; border:1px solid var(--c-line); border-radius:4px;
    box-shadow:inset -15px 0 12px -15px rgba(11,32,56,.3)}
.az-vl-knopf {display:inline-flex; align-items:center; gap:1px; height:26px; padding:0 7px; border-radius:7px;
    border:1px solid var(--c-line); color:var(--c-ink-2); background:var(--c-surface)}
.az-vl-knopf.ok {background:var(--st-ok-bg); color:var(--st-ok); border-color:var(--st-ok-fill)}
.az-vl-knopf.warn {background:var(--st-warn-bg); color:var(--st-warn); border-color:var(--st-warn-fill)}
.az-vl-knopf.bad {background:var(--st-bad-bg); color:var(--st-bad); border-color:var(--st-bad-fill)}
.az-vl-knopf.info {background:var(--c-accent-soft); color:var(--c-accent); border-color:var(--c-accent)}
/* ── Kundenprozesse: VU-Dialog ────────────────────────────────────────
   Modules/Aza2/Resources/views/kz/vaza/vu.blade.php — VU-Ansicht und
   VU-Kommentare. Alles unter .az-vu / .az-vk bzw. am Dialog selbst. */

/* .dlgwrap.fixed ist ein Raster, die .dlg sein einziges Element. Ohne
   min-width:0 gibt die breiteste Tabelle (VP-Bemerkungen, nowrap) dem
   Raster ihre Mindestbreite vor, und der Dialog ragt bei 390 px ueber
   den Rand — gemessen: 1.038 px statt 362 px. Mit 0 bleibt er in der
   Spalte, und die Tabelle rollt in ihrem .b-tw. */
#dlgAzVu > .dlg, #dlgAzVuKommentare > .dlg {min-width:0}

/* Fuenf Reiter passen am Handy nicht nebeneinander; .b-seg bricht nicht
   um. Die Leiste rollt dann seitlich statt die Seite zu verbreitern. */
.az-vu-reiter {max-width:100%; width:max-content; overflow-x:auto; margin-bottom:14px}
.az-vu-reiter button {white-space:nowrap; flex-shrink:0}
.az-vu > .al {margin-bottom:12px}
.az-vu-abstand {margin-top:18px}
/* Die Tabellen des Dialogs haben zwei bis fuenf Spalten Text; nowrap
   (app.css) machte die zweispaltige Unterlagentabelle am Handy 600 px
   breit, die rechte Spalte lag dann ausserhalb. Hier darf umbrechen. */
.az-vu .b-t th, .az-vu .b-t td {white-space:normal}
/* Unter 768 px gibt app.css jeder .b-t 600 px Mindestbreite und eine
   klebende erste Spalte. Die beiden zweispaltigen Tabellen der
   Vertragsdateien passen auch so auf das Handy. */
.az-vu .b-t.az-vu-schmal {min-width:0}

/* Kopfzeile: Kunde · Art · Status. .unit ist Grossschrift in Mono und
   bricht sonst nicht; ein langer Kundenname soll umbrechen duerfen. */
.dhead .az-vu-kopf {white-space:normal; padding-right:34px; min-width:0}

/* Listen ohne Aufzaehlungszeichen: base.css setzt sie fuer ul nicht
   zurueck, im Bild standen sonst Punkte vor jeder Karte. */
.az-vu-liste, .az-vu-bedingungen, .az-vk-liste {list-style:none; margin:0; padding:0}
.az-vu-liste {display:grid; gap:4px; font-size:12.5px; color:var(--c-ink-2)}
.az-vu-liste b {font-weight:600; color:var(--c-ink)}

/* Fehlende Dokumente sind oft mehrere Zeilen lang. */
.az-vu .b-form textarea {resize:vertical; min-height:70px}
.az-vu-hinweis {display:flex; gap:7px; align-items:flex-start; font-size:11.5px; color:var(--c-ink-3); margin:0}
.az-vu-hinweis svg {width:13px; height:13px; flex-shrink:0; margin-top:2px}
.az-vu-fehlend {display:flex; align-items:center; gap:8px 14px; flex-wrap:wrap; font-size:12.5px; color:var(--c-ink-2)}
.az-vu-akt {margin-left:auto; display:flex; gap:8px; flex-wrap:wrap; align-items:center}

/* Freigabe: eine Zeile je Unterlage, Frage links, Stand rechts. */
.az-vu-bedingungen {display:grid}
.az-vu-bedingungen li {display:flex; align-items:center; gap:8px 14px; flex-wrap:wrap; padding:9px 0;
    border-bottom:1px solid var(--c-line); font-size:13px; color:var(--c-ink)}
.az-vu-bedingungen li:last-child {border-bottom:0}
.az-vu-bedingungen li > .pill, .az-vu-bedingungen li > .ghostbtn {margin-left:auto}
.az-vu-pw-eingabe {display:flex; gap:6px; flex-wrap:wrap; align-items:center}
.az-vu-pw-eingabe input {font:inherit; font-size:12.5px; padding:5px 9px; border:1px solid var(--c-line);
    border-radius:7px; background:var(--c-surface); color:var(--c-ink); width:140px; max-width:100%}

/* Downloads: ein Knopf je Datei. Dateinamen sind lang (Gesellschaft,
   Nummer, Kundenname) — gekuerzt statt die Zeile zu sprengen. */
.az-vu-downloads {display:flex; flex-wrap:wrap; gap:8px}
.az-vu-downloads .az-vu-datei {max-width:100%; justify-content:flex-start}
.az-vu-downloads .az-vu-datei span {overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0}
.az-vu-downloads p {margin:0; font-size:12.5px}

/* Bemerkung und Dateiliste sind Freitext; .b-t td bricht sonst nie um,
   und sechs Dateinamen hintereinander machten die Tabelle 2.000 px breit. */
.az-vu-bem td.az-vu-umbruch {white-space:normal; min-width:200px; overflow-wrap:anywhere}
.az-vu-bem-knopf.az-vu-angenommen {color:var(--st-ok); border-color:var(--st-ok-fill)}
.az-vu-bem-knopf.az-vu-abgelehnt {color:var(--st-bad); border-color:var(--st-bad-fill)}

/* Rueckfrage: zwischen Inhalt und Fuss, damit sie neben den Knoepfen
   steht, die sie ausgeloest haben. */
.az-vu-frage {margin:0 18px 12px; align-items:center; flex-wrap:wrap}
.az-vu-frage > span:first-of-type {flex:1 1 240px}

/* Fuss: Loeschen links, Schliessen rechts; am Handy stapeln. */
.az-vu-fuss {flex-wrap:wrap}
.az-vu-gefahr {color:var(--st-bad)}
.az-vu-gefahr:hover {border-color:var(--st-bad); color:var(--st-bad)}
@media (max-width:640px) {
    .az-vu-fuss .r {margin-left:0; width:100%; justify-content:flex-end; flex-wrap:wrap}
}

/* VU-Kommentare: eine Karte je Nachricht, Loeschen oben rechts. */
.az-vk-neu {grid-template-columns:minmax(0,1fr)}
.az-vk-liste {display:grid; gap:8px}
.az-vk-liste li {border:1px solid var(--c-line); border-radius:9px; padding:9px 12px; background:var(--c-surface-2)}
.az-vk-kopf {display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:12px}
.az-vk-kopf b {font-weight:600; color:var(--c-ink)}
.az-vk-kopf .b-ib {margin-left:auto; width:28px; height:28px}
.az-vk-liste p {margin:4px 0 0; font-size:13px; color:var(--c-ink); white-space:pre-wrap; overflow-wrap:anywhere}
.az-vk-leer {font-size:12.5px; margin:0}

/* ── Kundenprozesse: Hauptseite ───────────────────────────────────────
   Je Monat ein Block (.az-v-mblock). Der Kopf ist ein Raster mit
   denselben Spalten wie die Beschriftung ueber der Liste, damit die
   Werte wie in einer Tabelle untereinander stehen. Am Telefon faellt die
   Beschriftungszeile weg; jeder Wert traegt dann seine eigene (.az-v-wl). */
.az-v-hinweise {display:flex; gap:9px; flex-wrap:wrap; margin-bottom:14px}
.az-v-hinweise .b-note {flex:1 1 280px}
.az-v-filter {display:flex; flex-direction:column; gap:12px}
.az-v-monat {display:flex; gap:6px}
.az-v-monat > * {flex:1; min-width:0}
.az-v-akt {display:flex; gap:9px; flex-wrap:wrap; align-items:center}
.az-v-erweitert > summary {cursor:pointer; font-size:12.5px; font-weight:600; color:var(--c-ink-2);
    display:flex; align-items:center; gap:8px; padding:4px 0}
.az-v-erweitert[open] > summary {margin-bottom:10px}
.az-v-arten {border:1px solid var(--c-line); border-radius:8px; padding:8px 10px; margin:0; min-width:0}
.az-v-arten legend {font-size:11.5px; color:var(--c-ink-2); padding:0 4px}
.az-v-artenliste {display:grid; grid-template-columns:repeat(auto-fill, minmax(210px, 1fr)); gap:4px 12px;
    max-height:180px; overflow-y:auto}
.b-form .az-v-arten label.cb {flex-direction:row; align-items:center; font-size:12px}
.b-form fieldset.full {grid-column:1/-1}
.az-v-werkzeuge {gap:8px}
.az-v-werkzeuge .az-datei {width:auto}
.az-v-excel {display:contents}

.az-v-kopf {row-gap:8px}
.az-v-schalter {flex-wrap:wrap}
.az-v-schalter .b-seg button {display:inline-flex; align-items:center; gap:5px}
.az-v-statusfilter {display:flex; align-items:center; gap:6px; flex-wrap:wrap; padding:9px 14px;
    border-bottom:1px solid var(--c-line)}
.az-v-statusfilter .b-lbl {margin:0 4px 0 0}
.az-v-statusfilter .chip {cursor:pointer; padding:3px 9px; font-size:11.5px}
.az-v-statusfilter .chip[aria-pressed="true"] {background:var(--c-accent-soft); border-color:var(--c-accent); color:var(--c-accent)}

.az-v-raster {display:grid; grid-template-columns:minmax(150px, 1.4fr) repeat(10, minmax(0, 1fr)); gap:0 8px;
    align-items:center; padding:7px 14px}
.az-v-raster .az-v-w {text-align:right; font-size:12px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.az-v-rasterkopf {font-family:"IBM Plex Mono",monospace; font-size:10px; letter-spacing:.06em; text-transform:uppercase;
    color:var(--c-ink-3); background:var(--c-surface-2); border-bottom:1px solid var(--c-line)}
.az-v-rasterkopf .az-v-w {font-size:10px}
.az-v-wl {display:none}
.az-v-mblock {border-bottom:1px solid var(--c-line)}
.az-v-mkopf {cursor:pointer}
.az-v-mkopf:hover {background:var(--c-tint)}
.az-v-mblock.auf > .az-v-mkopf {background:var(--c-surface-2)}
.az-v-mknopf {display:inline-flex; align-items:center; gap:7px; font:inherit; font-size:12.5px; color:var(--c-ink); text-align:left}
.az-v-mknopf svg {width:13px; height:13px; color:var(--c-ink-3)}
.az-v-mkoerper {padding:4px 14px 14px; background:var(--c-surface)}
.az-v-summe {background:var(--c-surface-2); font-weight:600}
.az-v-summe .az-v-mname {font-size:12px}
.az-v-leer {font-size:12.5px; color:var(--c-ink-3); padding:10px 0; margin:0}

/* Marken (Warnung, Erinnerung) und Knoepfe je Vertrag. */
.az-v-marke {display:inline-grid; place-items:center; width:20px; height:20px; border-radius:5px; vertical-align:middle}
.az-v-marke svg {width:13px; height:13px}
.az-v-marke.info {color:var(--c-accent)}
.az-v-marke.ok {color:var(--st-ok)}
.az-v-marke.warn {color:var(--st-warn)}
button.az-v-marke {cursor:pointer}
button.az-v-marke:hover {background:var(--c-tint)}
.az-v-marken {white-space:nowrap; width:1%}
.az-v-aktionen {display:flex; gap:3px; justify-content:flex-end; flex-wrap:nowrap}
.az-v-akt-zelle {width:1%; text-align:right}
.az-v-knopf {width:30px; height:30px; border:1px solid var(--c-line); background:var(--c-surface)}
.az-v-knopf.ok {color:var(--st-ok)}
.az-v-knopf.warn {color:var(--st-warn)}
.az-v-knopf.bad {color:var(--st-bad)}
.az-v-knopf.info {color:var(--c-accent)}
.az-v-knopf .az-v-zahl {position:absolute; top:-5px; right:-5px; min-width:15px; height:15px; padding:0 3px;
    border-radius:99px; background:var(--st-ok); color:#fff; font-size:9.5px; font-weight:700; line-height:15px}
.az-v-knopf svg + svg {margin-left:-8px}
td.nm .b-ib {width:24px; height:24px; margin-left:4px; vertical-align:middle}
.az-v-zusatz {display:block; font-style:italic; color:var(--c-ink-2); font-size:11px}
.az-v-delta {display:block; font-size:11px}
.az-v-delta.minus {color:var(--st-bad)}
.az-v-delta.plus {color:var(--st-ok)}
.b-t td.c {text-align:center}
.az-v-einheit {text-transform:none; letter-spacing:0}

/* Vorgaenge eines Monats: Rasterzeilen (siehe kundenansicht() im Skript). */
.az-v-vorgaenge {border:1px solid var(--c-line); border-radius:8px; overflow:hidden; margin-top:6px}
.az-v-vraster {display:grid; grid-template-columns:52px 36px 104px minmax(0,1.3fr) minmax(0,1fr) 130px 40px;
    gap:0 10px; align-items:center; padding:6px 10px; border-bottom:1px solid var(--c-line); font-size:12.5px}
.az-v-vkopf {font-family:"IBM Plex Mono",monospace; font-size:10px; letter-spacing:.06em; text-transform:uppercase;
    color:var(--c-ink-3); background:var(--c-surface-2)}
.az-v-vorgang {cursor:pointer}
.az-v-vorgang:hover {filter:brightness(.98)}
.az-v-v-ku {display:flex; align-items:center; gap:6px; min-width:0}
.az-v-v-ku b {font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.az-v-v-ku .b-ib {width:24px; height:24px; flex-shrink:0}
.az-v-v-vp {overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--c-ink-2)}
.az-v-v-bw {text-align:right}
.az-v-v-bt {text-align:right}
.az-v-vraster .az-v-wl {display:none}
.az-v-vinnen {padding:8px 10px 12px 34px; border-bottom:1px solid var(--c-line); background:var(--c-surface)}
@media (max-width:767px){
    .az-v-vkopf {display:none}
    .az-v-vraster {grid-template-columns:24px minmax(0,1fr) auto auto;
        grid-template-areas:"nr ku bw bt" "m dt dt dt" "m vp vp vp"; gap:2px 8px}
    .az-v-v-nr {grid-area:nr} .az-v-v-ku {grid-area:ku} .az-v-v-bw {grid-area:bw} .az-v-v-bt {grid-area:bt}
    .az-v-v-dt {grid-area:dt; font-size:11.5px; color:var(--c-ink-2)} .az-v-v-vp {grid-area:vp; font-size:11.5px}
    .az-v-v-m {grid-area:m}
    .az-v-vraster .az-v-wl {display:inline; font-style:normal; color:var(--c-ink-3)}
    .az-v-vinnen {padding:6px 0 10px}
}
.az-v-zebra > td {background:var(--c-surface-2)}
.b-t tr.az-v-ton-rot > td, .b-t tr.az-v-ton-gelb > td, .b-t tr.az-v-ton-blau > td,
.b-t tr.az-v-ton-lila > td, .b-t tr.az-v-ton-tuerkis > td {background:inherit}
.az-v-blink {animation:az-v-blink 1.4s ease 2}
@keyframes az-v-blink {50% {box-shadow:inset 0 0 0 2px var(--c-accent)}}
@media (prefers-reduced-motion:reduce) {.az-v-blink {animation:none; box-shadow:inset 0 0 0 2px var(--c-accent)}}

/* Klappen fuer Ueberfaellige und Nachbearbeitungen. */
.az-v-klappe > summary {cursor:pointer; list-style:none}
.az-v-klappe > summary::-webkit-details-marker {display:none}
.az-v-klappe:not([open]) > summary {border-bottom:0}
.az-v-klappe > summary::after {content:""; margin-left:auto; width:8px; height:8px; border-right:1.5px solid var(--c-ink-3);
    border-bottom:1.5px solid var(--c-ink-3); transform:rotate(45deg); transition:transform .15s}
.az-v-klappe[open] > summary::after {transform:rotate(-135deg)}
.az-v-odmonat {border:1px solid var(--c-line); border-radius:8px; margin-top:8px}
.az-v-odmonat > summary {cursor:pointer; padding:8px 12px; font-size:12.5px}

/* Bis 1023 px passen zehn Wertespalten nicht nebeneinander: der Monat
   steht oben, die Werte darunter beschriftet in einem Raster. */
@media (max-width:1023px){
    .az-v-rasterkopf {display:none}
    .az-v-raster {grid-template-columns:repeat(5, minmax(0, 1fr)); gap:6px 10px}
    .az-v-raster .az-v-mname {grid-column:1/-1}
    .az-v-raster .az-v-w {text-align:left; display:flex; flex-direction:column; gap:1px}
    .az-v-wl {display:block; font-style:normal; font-family:"IBM Plex Mono",monospace; font-size:9.5px;
        letter-spacing:.04em; text-transform:uppercase; color:var(--c-ink-3); overflow:hidden; text-overflow:ellipsis}
}
@media (max-width:767px){
    .az-v-raster {grid-template-columns:repeat(3, minmax(0, 1fr))}
    .az-v-mkoerper {padding:4px 10px 12px}
    .az-v-vertraege > td.az-v-innen {padding-left:8px}
}

/* Huellen der Kopfteile (kz/topbar): ohne eigenen Kasten, ihre Kinder
   sind Flex-Elemente der Kopfzeile bzw. der Chipleiste. */
.kz-kopfteil {display:contents}
.ph-chips > .kz-kopfteil > * {flex-shrink:0}
.ph-chips:empty {display:none}
.az-v-erste {white-space:normal; min-width:150px}
.az-v-kopfzeile {display:flex; align-items:center; gap:4px}
.az-v-nr {font-size:10.5px; color:var(--c-ink-3); min-width:14px}
.az-v-benennung {display:block; font-weight:500}
/* Die klebende erste Spalte (app.css, Telefon) traegt sonst die Flaeche
   der Tabelle statt des Zeilentons. */
.b-t tr[class*="az-v-ton-"] > td:first-child, .b-t tr.az-v-zebra > td:first-child {background-color:inherit}
@media (max-width:767px){
    /* Von und Bis nebeneinander liessen am Telefon nur „202" vom Jahr uebrig. */
    .b-form.az-v-zeitraum {grid-template-columns:minmax(0,1fr)}
}

/* ── VP Statistik (Entwurf Kommandozentrale, Bildschirm 5) ─────────── */
/* Die Zahlen neben dem Befoerderungsbalken: im Entwurf als Inline-Stile
   gesetzt, hier einmal benannt. */
.vp-lab {font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--c-ink-3)}
.vp-wert {font-size:21px;font-weight:600;margin-top:4px}
.vp-satz {font-size:12px;color:var(--c-ink-2);margin-top:10px;line-height:1.5}
.vp-satz b {color:var(--c-ink)}
/* Stornoquote bzw. Anteil hinter der Zahl, kleiner als die Zahl selbst. */
.vp-q {font-size:11px}
/* Summenzeile: im Entwurf mit der Flaeche des Tabellenkopfs abgesetzt.
   Die klebende erste Spalte (Telefon) soll denselben Ton tragen. */
.b-t tr.vp-gesamt, .b-t tr.vp-gesamt > td:first-child {background:var(--c-surface-2)}
/* Kompakt/Detailliert laedt die Seite neu (?detailed=true) — deshalb
   Verweise statt Knoepfe, im Kleid von .b-seg button. */
.b-seg .vp-segl {font-size:11.5px;font-weight:600;padding:4px 10px;color:var(--c-ink-3);text-decoration:none;
    display:flex;align-items:center;min-height:28px;white-space:nowrap;transition:background .18s,color .18s}
.b-seg .vp-segl:hover {color:var(--c-ink)}
.b-seg .vp-segl[aria-pressed="true"] {background:var(--c-surface);color:var(--c-ink);box-shadow:var(--sh)}
/* Zwei Flaechen nebeneinander, am Telefon untereinander. */
.vp-abrchart {display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}
.vp-abrchart h4 {font-size:12.5px;font-weight:600}
.vp-abrkopf {display:flex;align-items:baseline;gap:8px;margin-bottom:4px}
.vp-abrkopf .u {font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--c-ink-3)}
.vp-abrkopf .fig {margin-left:auto;font-size:14px;font-weight:600}
@media (max-width:767px){ .vp-abrchart {grid-template-columns:minmax(0,1fr)} }
/* Die Spartentafel steht im schmalen Drittel: umbrechende Spaltenkoepfe
   („Verdienst / nach SR") lassen die Spalte Anteil ohne Seitwaertsrollen
   sichtbar. */
.b-t.vp-sp th {white-space:normal;vertical-align:bottom}
/* Dasselbe fuer lange Namen („Verbundene Wohngebaeudeversicherung"). */
.b-t.vp-sp td:first-child {white-space:normal;hyphens:auto;-webkit-hyphens:auto}
.b-t.vp-sp th, .b-t.vp-sp td {padding-left:7px;padding-right:7px}

/* ── Grosse Dialoge: Rumpf mit gestapelten Bloecken ──────────────────
   Personalentwicklung und Termintafel hatten ein eigenes Dialogmuster
   (dlg-h/dlg-b/dlg-f). Sie nutzen jetzt .dlg.plain wie alle anderen
   grossen Dialoge. Ihr Rumpf stapelte Meldungen, Felder und Hinweise mit
   gleichem Abstand — .kz-stapel behaelt das bei, ohne die uebrigen
   .dbody-Flaechen zu veraendern. */
.kz-stapel > * + * {margin-top:12px}

/* Felder als <label class="fld"><span>Name</span><input|select></label>.
   app.css gestaltet in .fld nur Eingaben in einer .inp-Huelle; ein
   direktes <select> blieb das native Bedienelement des Browsers — im
   Dunkelmodus ein weisser Kasten. Hier bekommt es das Kleid von .b-form. */
.fld > span:first-child {font-size:11.5px;font-weight:600;color:var(--c-ink-2)}
.fld > input:not([type="checkbox"]):not([type="radio"]), .fld > select, .fld > textarea,
.pe-eingabe > input, .pe-eingabe > select {
    font:inherit;font-size:13px;min-height:36px;padding:7px 10px;border:1px solid var(--c-line);border-radius:8px;
    background:var(--c-surface);color:var(--c-ink);width:100%;min-width:0;
    transition:border-color .18s,box-shadow .18s}
.fld > input:focus, .fld > select:focus, .fld > textarea:focus,
.pe-eingabe > input:focus, .pe-eingabe > select:focus {
    outline:none;border-color:var(--c-accent);box-shadow:0 0 0 3px var(--c-accent-soft)}
.fld > input[type="file"] {padding:6px 8px;font-size:12.5px}
.fld > input[type="date"], .pe-eingabe > input[type="date"] {color-scheme:inherit}

/* ── Personalentwicklung: Kennzahlen OWE ──────────────────────────────
   Verhaeltnisbalken statt Donut (Entwurf Modulsatz, Modul 3): ein Balken
   aus zwei Teilen, Legende mit Zahl und Anteil, Gesamtzahl darunter. */
.pe-owe-kacheln {display:grid;gap:12px;border-bottom:1px solid var(--c-line)}
.ratio {display:flex;flex-direction:column;gap:9px}
.ratio .bar {display:flex;height:13px;border-radius:99px;overflow:hidden;background:var(--c-tint);gap:2px}
.ratio .bar i {display:block}
.ratio .rlg {display:flex;gap:6px 14px;flex-wrap:wrap;font-size:11.5px;color:var(--c-ink-2)}
.ratio .rlg span {display:flex;align-items:center;gap:6px}
.ratio .rlg i {width:10px;height:10px;border-radius:3px;flex-shrink:0}
.ratio .rlg b {font-family:"IBM Plex Mono",monospace;font-weight:600;color:var(--c-ink)}
.ratio .tot {font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--c-ink-3)}
/* Summe unter dem Spaltennamen, wie im Bestand im Kopf der Spalte. */
.b-t th .pe-sum {display:block;margin-top:2px;color:var(--c-ink);font-weight:600;letter-spacing:0}
/* Der Knopf der Dateiauswahl ist ein eigenes Pseudoelement und blieb
   hell-grau, auch im Dunkelmodus. */
.fld > input[type="file"]::file-selector-button {font:inherit;font-size:12px;font-weight:600;margin-right:10px;
    padding:4px 10px;border:1px solid var(--c-line);border-radius:6px;background:var(--c-surface-2);color:var(--c-ink);cursor:pointer}

/* ══ Schale: Korrekturen aus der Gesamtpruefung (24.09.2026) ══════════
   Fuenf Fehler, die jedes Modul treffen. app.css bleibt eine Kopie des
   Frontends, darum stehen die Korrekturen hier. */

/* 1. Panelkoepfe am Tablet. app.css:832 setzt .b-ph auf nowrap mit
      nicht schrumpfender Knopfleiste; am Handy hebt app.css:888 das fuer
      Panels wieder auf, am Tablet nicht. Folge bei 916 px: Titel und
      Einheit brachen Wort fuer Wort um oder wurden auf 0 px gedrueckt. */
@media (max-width:1023px){
    .b-p .b-ph {flex-wrap:wrap;overflow:visible}
    .b-p .b-ph .r {flex-shrink:1;min-width:0;max-width:100%}
    .b-p .b-ph .r > .b-seg, .b-p .b-ph > .b-seg {max-width:100%;overflow-x:auto;scrollbar-width:none}
}

/* 2. Klebende erste Tabellenspalte am Handy. app.css:862 gibt ihr eine
      Mindest-, aber keine Hoechstbreite und laesst sie nicht umbrechen.
      War ihr Inhalt breiter als der Rahmen, rollten alle anderen Spalten
      unsichtbar darunter durch — gemessen bis 457 px bei 360 px Rahmen,
      Aktionsknoepfe unerreichbar. Ausserdem streckte die 600-px-Mindest-
      breite auch Tabellen mit zwei oder drei Spalten. */
@media (max-width:767px){
    .b-t th:first-child, .b-t td:first-child {max-width:46vw;white-space:normal;overflow-wrap:break-word}
    .b-t:not(:has(tr > :nth-child(4))) {min-width:0}
}

/* 3. Hauptknopf der Dialoge am Handy. app.css:960 dreht die Aktionszeile
      in eine Spalte; das flex:1 aus app.css:407 wirkt dann in der Hoehe,
      und der Knopf schrumpfte auf 21 px. Fuesse der anderen Dialogformen
      brechen am Handy ebenso untereinander um. */
@media (max-width:767px){
    .dlg .acts .sub, .dlg .acts .ghostbtn {flex:0 0 auto}
    .dlg.plain .dfoot, .dlg.plain .dfoot .r {flex-wrap:wrap}
    .dlg.plain .dfoot .r {width:100%}
    .dlg.plain .dfoot .r > * {flex:1 1 auto;justify-content:center}
    .b-form.c2 {grid-template-columns:minmax(0,1fr)}
}

/* 4. Dialoge ohne Hoehengrenze. „Alle Nachrichten" war 10.157 px hoch,
      Titel, X und Fuss rollten aus dem Bild. Jetzt hat der Dialog die
      Hoehe des Fensters, Kopf und Fuss bleiben stehen, der Rumpf rollt. */
.dlgwrap.fixed .dlg.plain {
    max-height:calc(100dvh - 48px);display:flex;flex-direction:column}
.dlgwrap.fixed .dlg.plain > form {
    display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
.dlgwrap.fixed .dlg.plain .dbody {overflow-y:auto;min-height:0;flex:1 1 auto}
@media (max-width:767px){
    .dlgwrap.fixed .dlg.plain {max-height:calc(100dvh - 28px)}
}

/* 5. Sortierbare Spaltenkoepfe. .b-t th button erbt mit font:inherit
      Schrift und Groesse, aber nicht Versalien und Laufweite — diese
      Koepfe standen in gemischter Schreibung neben den uebrigen. */
.b-t th button {text-transform:inherit;letter-spacing:inherit}

/* ══ Modulkorrekturen aus der Gesamtpruefung (24.09.2026) ═══════════ */

/* ── Anmeldung, Onboarding, Dashboard, Struktur-Atlas ── */
/* ==== Teil 1a: Anmeldung, Onboarding, Dashboard, Atlas ==== */

/* Anmeldung, Zustand "Angemeldet als": die Karte mit Kuerzel, Name und
   Position hatte keine Regel und zerfiel in einen losen Kreis ueber Text. */
.lg-known {display:flex;align-items:center;gap:12px;margin-top:17px;padding:12px 13px;border:1px solid var(--c-line);border-radius:10px;background:var(--c-surface-2)}
.lg-known .t {line-height:1.35;min-width:0}
.lg-known .t b {display:block;font-size:13.5px;font-weight:600}
.lg-known .t span {font-size:12px;color:var(--c-ink-3)}

/* Onboarding, Vertragsschritt: die Marke im Kopf war unsichtbar und
   "PraeLux DEV" stand als loser Text, weil .bt nur unter .lg-side
   gestaltet ist. Gleiche Form wie .err-top auf den Fehlerseiten. */
.ob-kopf .bt {display:flex;align-items:center;gap:10px;color:var(--c-ink)}
.ob-kopf .bt .plmark {width:26px;height:26px}
.ob-kopf .bt b {font-size:14.5px;font-weight:600}
.ob-kopf .bt .env {font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.08em;padding:2px 6px;border-radius:4px;background:var(--c-tint);color:var(--c-ink-3)}

/* Onboarding: nach der Unterschrift wird der Schrittanzeiger im Kopf
   getauscht; .ob-steps setzt display:flex und schluege sonst [hidden]. */
.ob-steps[hidden] {display:none}

/* Dashboard, Challenges: die eigene Zeile (vierte, vom Server angehaengt)
   war nicht hervorgehoben; app.js setzte nur bg-warning ohne Regel.
   Die klebende erste Zelle braucht dieselbe, deckende Farbe. */
.b-t tr.kz-ich > td, .b-t.stick tr.kz-ich > td {background:var(--c-accent-soft)}
.b-t tr.kz-luecke td {padding:3px 12px;color:var(--c-ink-3);text-align:left}

/* Dashboard, Challenges am Handy: Leer- und Ladezeile sind ein td mit
   colspan in der klebenden ersten Spalte und wurden abgeschnitten
   ("Für d..."). Diese Zeilen kleben nicht und stehen linksbuendig. */
.b-t.stick td[colspan] {position:static;box-shadow:none;text-align:left}

/* Onboarding (Fuehrungswerkzeug): Trennzeile vor den abgeschlossenen
   Vorgaengen, damit "Aktive Prozesse" nicht wie eine Liste aus lauter
   laufenden Vorgaengen aussieht. */
.b-t tr.kz-gruppe td {padding:7px 10px;background:var(--c-surface-2);font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--c-ink-3)}
.b-t tbody tr.kz-gruppe:hover {background:none}

/* Struktur-Atlas, Reiterzeile: am Handy war sie auf 133 px gedrueckt
   (aktiver Reiter unsichtbar), am Tablet fehlte "6 x 6". Die Zeile steht
   ausserhalb von .b-p, die zentrale Korrektur fuer .b-p .b-ph greift
   nicht. Reiter volle Breite und seitlich rollbar, Umschalter darunter. */
@media (max-width:1023px){
    .at-kopf {flex-wrap:wrap;row-gap:8px;overflow:visible}
    .at-kopf > .b-seg {flex:1 1 100%;max-width:100%;overflow-x:auto;scrollbar-width:none}
    .at-kopf > .b-seg::-webkit-scrollbar {display:none}
    .at-kopf > .b-seg > button {flex-shrink:0}
    .at-kopf > .r {flex:1 1 100%;min-width:0;flex-wrap:wrap;row-gap:6px}
}

/* Struktur-Atlas am Handy: Zoomregler, Minikarte und Hinweise (z-index 10)
   lagen ueber der klebenden unteren Navigation (.ph-tabs, z-index 6).
   isolation schliesst sie in die Leinwand ein. */
.at-canvas {isolation:isolate}

/* Struktur-Atlas am Handy: "Zur Wurzel" brach zweizeilig um, "Ebene
   tiefer/hoeher" liefen rechts aus dem Panel. Die Werkzeuge rutschen in
   eine eigene Zeile, die Ebenenknoepfe zeigen nur ihr Symbol (Name bleibt
   als title und zugaenglicher Text). */
@media (max-width:767px){
    #at-wurzel {white-space:nowrap}
    .at-werkzeuge {margin-left:0;flex:1 1 100%;flex-shrink:1;min-width:0}
    #at-tiefer, #at-hoeher {font-size:0;gap:0;padding:0 10px}
    #at-tiefer .ic, #at-hoeher .ic {width:16px;height:16px}
}
@media (max-width:767px){
    /* app.css:836 laesst .b-fils am Handy nicht umbrechen; im Atlas stehen
       dort Wurzel, Pfad und Werkzeuge, die zusammen nicht in eine Zeile passen. */
    .at-view .b-ph2 .b-fils {flex-wrap:wrap;overflow:visible}
    .at-werkzeuge .b-seg {flex:1 1 auto;min-width:0;overflow-x:auto;scrollbar-width:none}
}

/* ── Leistungsfaehigkeit, PraeLux in Zahlen ── */
/* ══ Teil 1b · Leistungsfähigkeit, PraeLux in Zahlen ═══════════════════
   Ergänzungen für kommandozentrale-blade.css. Jede Regel mit Warum. */

/* ── Leistungsfähigkeit ─────────────────────────────────────────────── */

/* Prozentzahl der Kopfzahlen (Bullets) in der Ampel des Bestands. Als
   Klasse statt Inline-Farbe, damit der dunkle Modus die Statusfarben
   seiner eigenen Palette nimmt. */
.fs-ton-ok {color:var(--st-ok)}
.fs-ton-warn {color:var(--st-warn)}
.fs-ton-bad {color:var(--st-bad)}

/* Hall of Fame und Nutzbares Volumen stehen nebeneinander; ohne diese
   Regel würde das kurze Dim-Panel auf die Höhe der langen Bestenliste
   gestreckt und bekäme unten eine leere Fläche. .g21/.g4 kennen ragged
   schon, .g11 noch nicht. */
.g11.ragged {align-items:start}

/* Zweite Kopfzeile mit Unterreitern (Hall of Fame, Sekundäranalyse) —
   im Entwurf enger als ein Panelkopf mit Titel. */
.b-ph.fs-unterreiter {padding-top:9px;padding-bottom:9px}

/* Hervorgehobene Zeilen der Challenges (Platz 1, „auf Kurs"). Früher ein
   Inline-Hellgrün #dcfce7, das im dunklen Modus weiß leuchtete. Als
   background-image über der Zellfarbe, damit auch die klebende erste
   Zelle (die eine eigene Hintergrundfarbe trägt) mitgefärbt wird und
   beim Scrollen deckend bleibt. */
.b-t tr.fs-hl > td {background-image:linear-gradient(var(--st-ok-bg),var(--st-ok-bg))}

/* Pfeil gegen den Vormonat in den Dimensions-Rankings; ersetzt drei
   Inline-Styles mit festen Hexfarben. */
.fs-rang {font-weight:700;font-size:11px;margin-left:6px;white-space:nowrap}
.fs-rang.auf {color:var(--st-ok)}
.fs-rang.ab {color:var(--st-bad)}
.fs-rang.gleich {color:var(--st-warn)}

/* Der Einleitungssatz der Planungsdialoge steht jetzt im Körper eines
   .dlg.plain; .dlg .lede bringt nur einen Abstand nach oben mit. */
.fs-plan .dbody .lede {margin:0 0 12px}

/* Die Medaille der Trainee-Stufe stand per float:right am Zellrand —
   in einer .b-t-Zelle ohne feste Breite rutscht sie so ans Ende der
   Spalte, weit weg vom Wort. Inline neben „Trainee Gold". */
.b-t td .medal {float:none;width:16px;vertical-align:-3px;margin-left:5px}

/* ── PraeLux in Zahlen ──────────────────────────────────────────────── */

/* Die Veränderung in der Kachel brach am Handy zwischen Zahl und
   Prozentzeichen („32,3 / %"). */
.zl-kacheln .delta {white-space:nowrap}

/* Kacheltitel am Handy: app.css erlaubt den Umbruch an jeder Stelle
   (overflow-wrap:anywhere) — „UNTERNEHMENSWACHST / UM". Silbentrennung
   nach deutschem Wörterbuch (die Seite trägt lang="de") trennt an
   einer Silbengrenze. */
@media (max-width:767px){
    .zl-kacheln .b-kpi .lab {overflow-wrap:normal;hyphens:auto;-webkit-hyphens:auto}
}

/* Tabelle „Alle Werte" am Handy: die klebende Kennzahlspalte nahm mit
   langen Namen ohne Umbruch rund 60 % der Breite ein, sichtbar blieben
   zwei Jahresspalten. Umbrechen lassen und begrenzen. */
@media (max-width:767px){
    .zl-tabelle td.nm {white-space:normal;max-width:150px;min-width:120px;hyphens:auto;-webkit-hyphens:auto}
}

/* ── Antragsstatus, Dokumenteportal ── */
/* ══ Teil 2a: Antragsstatus und Dokumenteportal ═════════════════════════
   Ergaenzungen fuer public/css/kommandozentrale-blade.css. */

/* Dokumenteportal: die Karten eines Schritts lagen ohne Abstand
   aufeinander (0 px). Das Raster der .b-body (gap 12px) greift nur fuer
   ihre direkten Kinder, die Karten stehen eine Ebene tiefer im Panel.
   minmax(0,1fr), damit eine breite Karte die Spalte nicht aufzieht. */
.do-schritt:not([hidden]) {display:grid; grid-template-columns:minmax(0,1fr); gap:12px}

/* Dokumenteportal: .haken war hier ungestaltet (es gab nur .ob-zust
   .haken) — die Kontrollkaestchen standen mit 19 px Zeilenabstand ohne
   Luecke, am Telefon zu kleine Trefferflaechen. */
.do-haken {display:grid; gap:6px}
.do-haken .cb {min-height:28px; align-items:center}

/* Kunde laden: die native Datalist zeigte ein ungestaltetes „▼" im
   Suchfeld; gesucht wird ohnehin durch Tippen. */
#do-kunde::-webkit-calendar-picker-indicator {display:none !important}

/* Dateiliste vor dem Erzeugen: etwas Abstand zum Hinweistext, lange
   Dateinamen duerfen umbrechen statt abgeschnitten zu werden. */
.do-dateien {margin-top:10px}
.do-dateien .t b {white-space:normal; overflow-wrap:anywhere; font-size:12px}

/* Antragsstatus, Filter: die Jahresauswahl bei „Bis" war am Telefon auf
   „202" abgeschnitten — flex:1 mit min-width:0 teilte die Breite halbe-
   halbe zwischen Monat (zweistellig) und Jahr (vierstellig). Das Jahr
   bekommt den groesseren Teil und eine Untergrenze fuer vier Ziffern
   samt Pfeil (bei 390 px gemessen: 80 px, vorher 62). */
.az-v-monat > select[name$="Year"] {flex:1.6 1 0; min-width:6.4em}

/* Antragsstatus, „Erweiterter Filter": die summary ist flex, dadurch
   fehlte das Aufklappzeichen — man sah nicht, dass sie aufgeht. Chevron
   wie .acc .head im Entwurf. */
.az-v-erweitert > summary {list-style:none}
.az-v-erweitert > summary::-webkit-details-marker {display:none}
.az-v-erweitert > summary::before {content:""; width:6px; height:6px; flex-shrink:0;
    border-right:1.5px solid currentColor; border-bottom:1.5px solid currentColor;
    transform:rotate(-45deg); transition:transform .15s}
.az-v-erweitert[open] > summary::before {transform:rotate(45deg)}

/* Dokumenteportal am Telefon: das Formular stand zweispaltig (164 + 156
   px), obwohl .b-form dort einspaltig ist. Grund: label.wide hat
   grid-column:span 2 und erzwingt damit eine zweite, implizite Spalte,
   in die dann auch die uebrigen Felder rutschen. 1/-1 spannt ueber die
   vorhandene eine Spalte. (Das Muster ist global in app.css:588 — hier
   nur fuer dieses Modul abgefangen.) */
@media (max-width:767px) {
    .do-schritt .b-form label.wide {grid-column:1/-1}
}

/* Neuer Empfehlungsgeber: das Feld „Salia-ID" traegt jetzt den Hinweis
   „auch FKS-Nummer genannt" und wird dadurch hoeher. Die Nachbarzeile
   „Führungskraft" ist ein Raster und verteilte die Mehrhoehe auf
   Beschriftung und Auswahl — die Auswahl stand 12 px tiefer als das
   Eingabefeld daneben. */
.az-eg .fld {align-content:start}

/* ── Termintafel, Wettkampf, Challengetool ── */
/* ═══ Teil 2b: Termintafel, Wettkampf, Challenge ═══════════════════════
   Ergaenzungen aus der UI-Pruefung (bericht-teil2b.md). Einzufuegen in
   public/css/kommandozentrale-blade.css. */

/* Telefon: der Kopf wandert in die seitlich laufende Chipleiste, die
   Hauptaktion („Neuer Termin", „Neuer Wettkampf") stand dort hinter Zeitraum
   und Ansichtswahl ausserhalb des Bildschirms. Mit kz-haupt markierte
   Knoepfe ruecken nach vorn (.kz-kopfteil ist display:contents, die Knoepfe
   sind also selbst Flex-Kinder der Leiste). Taugt auch fuer andere Module. */
.ph-chips .kz-haupt {order:-1}

/* Termintafel: bei 600 Zeilen sah man nach wenigen Zeilen nicht mehr,
   welche Spalte welcher Tag ist. Die Tafel bekommt eine eigene Hoehe und
   scrollt in sich, damit die Tageszeile oben kleben kann (.b-tw allein
   scrollt nur quer, dort greift sticky top nicht). Namens- und Klappkopf
   liegen ueber beiden Richtungen. */
.tt-tafel {max-height:calc(100dvh - 190px); overflow:auto}
.tt-tafel .b-tt thead th {position:sticky; top:0; z-index:2}
.tt-tafel .b-tt thead th.nm, .tt-tafel .b-tt thead th.cv {z-index:4}

/* Wochenansicht: die Tagesspalten waren ungleich breit (47 bis 101 px),
   je nachdem, wie viele Marken ein Tag hatte. Feste Tabellenaufteilung,
   die Tage teilen sich den Rest gleich. */
.b-tt.wide {table-layout:fixed}
.b-tt.wide th.nm {width:172px}
.b-tt.wide th.cv {width:26px}
@media (max-width:767px){
    .b-tt.wide th.nm {width:124px}
    .b-tt.wide td.d {min-width:0}
}

/* Bearbeiten-Dialog: die Felder stehen in einem <form>, der Abstand der
   Schale (.kz-stapel > * + *) erreicht nur direkte Kinder — sie klebten
   aneinander. */
.dbody form[data-tt-e-form] {display:grid; gap:12px}

/* Rueckfrage vor dem Loeschen im Dialog statt window.confirm. */
.tt-rueckfrage {flex-wrap:wrap; align-items:center; margin-top:10px}
.tt-rueckfrage > span:first-of-type {flex:1 1 200px}
.tt-rueckfrage-knoepfe {display:flex; gap:8px; margin-left:auto}

/* Auswertung: Zellen mit Balken hatten unten 9 px mehr Innenabstand als
   Zellen ohne (Wert 0) — die Ziffern einer Spalte standen verschieden
   hoch. Alle Zahlenzellen bekommen denselben Abstand. */
.ev-tab td.fig {position:relative; padding-bottom:9px}

/* Wettkampf-Uebersicht: bei 1440 px war die Tabelle 1804 px breit, Admin,
   Zustand und Aktionen lagen ausserhalb. Der Zeitraum steht zweizeilig
   (.u war nur in td.nm ein Block), die Teamkonstellation bricht um. */
.wk-liste td .u {display:block}
.wk-liste td.wk-teams {white-space:normal; min-width:200px; max-width:360px; line-height:1.5}
.wk-liste .b-ib {width:28px; height:28px}

/* Wettkampf-Live: die Panels liegen in #wk-live (das Nachladen tauscht
   genau diesen Knoten), nicht direkt in .b-body — die Luecke von .b-body
   erreichte sie nicht, Kopfreihe und „Teams & Teilnehmer" beruehrten sich. */
#wk-live {display:grid; gap:12px}

/* Reiter-Panels (data-kz-panel) sind klassenlose Wrapper in .b-body: die
   Luecke von .b-body erreichte die Panels darin nicht, sie lagen ohne
   Abstand aufeinander (Wettkampf-Editor, Schritte 1 bis 3). [hidden]
   gewinnt weiter ueber die !important-Regel der Schale. */
.b-body > [data-kz-panel] {display:grid; gap:12px; align-content:start; min-width:0}

/* Editor: Weiter/Zurueck rechts im Panelfuss, der Hinweis links daneben. */
.b-pf .wk-schritte {display:flex; gap:8px; margin-left:auto; flex-shrink:0}
.b-pf:has(.wk-schritte) {display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap}

/* Farbfeld: erbte padding 7px 9px der Formularfelder und schrumpfte zu
   einem schwarzen Strich, obwohl der Wert #0000dd war. */
.b-form input[type=color] {padding:2px; height:33px; width:56px; cursor:pointer}
.b-form input[type=color]::-webkit-color-swatch-wrapper {padding:0}
.b-form input[type=color]::-webkit-color-swatch {border:0; border-radius:5px}

/* Wertungskarten sind Knoepfe: der Browser zentriert deren Inhalt
   senkrecht, bei ungleich langem Text standen Symbol und Titel der drei
   Karten auf verschiedener Hoehe. */
button.b-oc {display:flex; flex-direction:column; justify-content:flex-start; align-items:stretch}

/* (.b-form label.wide am Telefon: siehe Abschnitt Einstellungen/Administration) */

/* Challenge-Ranking: Platz und Name teilen sich die erste, klebende
   Zelle. Rangzahl und Medaille gleich breit, damit die Namen buendig
   stehen. */
.ch-platz .b-med, .ch-platz .ch-rang {display:inline-flex; justify-content:center; width:20px; margin-right:8px; vertical-align:middle}
.ch-platz .ch-rang {color:var(--c-ink-3); font-weight:500}

/* Challenge-Formular: Grunddaten, Positionen, Ausgeschlossene, Bewertung
   und Preise lagen ohne Abstand aufeinander — das <form> ist das einzige
   Kind von .b-body. */
.ch-form {display:grid; gap:12px; min-width:0}

/* ── Meckerbox, Protokolle, Einstellungen, Administration, Benachrichtigungen ── */
/* ══ Teil 2c: Einstellungen, Administration, Meckerbox, Protokolle, News ══
   Ergaenzungen fuer public/css/kommandozentrale-blade.css. */

/* ── Einstellungen · Allgemein: „Zugaenge und Rechte" ────────────────
   Die nicht sichtbaren Reiter stehen je mit ihrer Bedingung in einer
   Liste. Ohne Zuruecksetzen erbte sie Einzug und Aufzaehlungspunkte des
   Browsers und sprang aus der Wertespalte der .b-kv heraus. */
.se-rechte {list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:4px}
.b-kv .v .chip + .chip {margin-left:4px}

/* ── Reiterleiste am Telefon ─────────────────────────────────────────
   Die Einstellungen haben bis zu zwoelf Reiter, 1.250 px breit. In der
   Chipleiste standen die Kopfknoepfe („Nutzer anlegen", „Event
   erstellen") dahinter, bei x = 1.273 px — praktisch unauffindbar. Jetzt
   umbricht die Chipleiste: die Knoepfe stehen oben, die Reiterleiste
   darunter in voller Breite und rollt in sich. */
@media (max-width:767px) {
    .ph-chips:has(> .kz-kopfteil > .se-reiter) {flex-wrap:wrap; overflow-x:visible}
    .ph-chips > .kz-kopfteil > .se-reiter {order:2; flex:1 0 100%; max-width:100%}
}

/* ── Administration: Reiter am Telefon ───────────────────────────────
   Acht Schalter in einer .b-seg von 200 px Breite; zu sehen waren
   „Aktive/Inaktive Nutzer", sechs weitere lagen ohne Hinweis dahinter;
   am Tablet (916 px) fehlten noch „Geburtstage" und „Gruppen". Bis
   1199 px bricht die Gruppe in Zeilen um, alle acht stehen im Bild. */
@media (max-width:1199px) {
    .b-seg.ad-reiter {flex-wrap:wrap; flex:1 0 100%; overflow:visible}
    .b-seg.ad-reiter button {flex:1 0 auto}
    /* .b-fils umbricht am Telefon nicht — die Suche stand dann rechts
       ausserhalb des Bildes (x = 396 px). Sie folgt in eigener Zeile. */
    .b-fils:has(> .ad-reiter) {flex-wrap:wrap}
    .b-fils:has(> .ad-reiter) > .b-fil {flex:1 0 100%}
}

/* ── Administration: Passwortfeld im Nutzerdialog ────────────────────
   .b-form input kleidet jedes Feld mit Rahmen und Polster ein — auch das
   in der .inp-Huelle, die selbst schon einen Rahmen hat. Ergebnis war
   ein doppelter Rahmen. Die Huelle bekommt die Masse der uebrigen
   Formularfelder, das Feld darin keinen eigenen Rahmen. */
.b-form .inp {height:auto; min-height:34px; padding:0 3px 0 9px; border-radius:7px; gap:6px}
.b-form .inp input {border:0; background:transparent; padding:7px 0; border-radius:0}
.b-form .inp button {width:28px; height:28px}

/* ── Administration: Learning Suite im Nutzerdialog ──────────────────
   Knopfzeile und Kursliste unter dem Bereich. Die Kurse sind Knoepfe,
   die Module und Lektionen aufklappen; der Fortschritt steht als Chip
   rechts daneben. */
.ad-ls-akt {display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-top:10px; font-size:12px}
.ad-ls-kurse {list-style:none; margin:10px 0 0; padding:0; border:1px solid var(--c-line); border-radius:7px}
.ad-ls-kurse > li {display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:7px 10px; border-bottom:1px solid var(--c-line); font-size:12.5px}
.ad-ls-kurse > li:last-child {border-bottom:0}
.ad-ls-kurs {flex:1 1 200px; text-align:left; font-weight:600; color:var(--c-ink)}
.ad-ls-kurs::before {content:"▸ "; color:var(--c-ink-3)}
.ad-ls-kurs[aria-expanded="true"]::before {content:"▾ "}
.ad-ls-baum {flex:1 0 100%; margin:4px 0 0; padding-left:16px; font-size:12px; color:var(--c-ink-2)}
.ad-ls-baum ul {margin:2px 0 6px; padding-left:16px; color:var(--c-ink-3)}

/* ── Meckerbox: Liste am Desktop ─────────────────────────────────────
   Bei 1440 px war die Tabelle 1.355 px breit, der Rahmen 1.141 px — die
   Aktionsspalte war abgeschnitten („Ans…"). Ursache waren die zwei
   Hinweis-Pills nebeneinander (nowrap) und lange Titel. Die Pills stehen
   jetzt untereinander, der Titel darf umbrechen. */
.b-t td.mb-hinweis {white-space:normal}
.b-t td.mb-hinweis .pill {display:table; margin:1px 0}
#mecker-liste td.nm {white-space:normal; min-width:180px}

/* ── Meckerbox: Abstand vor den Kommentaren ──────────────────────────
   Am Telefon stiessen die Flaechen „Zustand aendern" und „Kommentare"
   ohne Abstand aneinander; .g21 und die Flaeche darunter sind
   Geschwister ohne gemeinsames gap. */
.mb-kommentare {margin-top:var(--gap, 14px)}

/* ── .b-form am Telefon: breite Felder ───────────────────────────────
   app.css setzt .b-form unter 768 px auf eine Spalte, label.wide spannt
   aber weiter zwei (span 2). Das Raster legt dafuer eine zweite, implizite
   Spalte an — gemessen 134 px + 179 px im Nutzerdialog. Dann stehen die
   Abschnittskoepfe (.fs, 1/-1) nur in der ersten Spalte neben dem Feld,
   und alles ist zweispaltig gequetscht (Wartung, Event, Nutzer). Auf
   einer Spalte heisst „breit" schlicht: die ganze Zeile. */
@media (max-width:767px) {
    .b-form label.wide {grid-column:1/-1}
}

/* ── Meckerbox-Editor: Auswahlfelder von Quill ───────────────────────
   Groesse, Text- und Hintergrundfarbe sind nachgeruestet. quill.snow.css
   malt deren Beschriftung grau (#444) und die Klappliste weiss — im
   Dunkelmodus kaum lesbar bzw. ein heller Kasten. Hier die Farben der
   Schale. */
.kz-editor .ql-snow .ql-picker {color:var(--c-ink-2)}
.kz-editor .ql-snow .ql-picker-options {background:var(--c-surface); border-color:var(--c-line); box-shadow:var(--sh)}
.kz-editor .ql-snow .ql-picker.ql-expanded .ql-picker-label {border-color:var(--c-line)}
.kz-editor .ql-snow .ql-picker-item:hover, .kz-editor .ql-snow .ql-picker-item.ql-selected {color:var(--c-accent)}

/* ── Protokolle: Kopfleiste am Telefon ───────────────────────────────
   Reiter, Monatspfeile und Artauswahl stehen in der Chipleiste. Der
   Pfeil „naechster Monat" und die Auswahl lagen hinter dem rechten Rand
   des seitlich laufenden Streifens — bedienbar, aber nicht zu sehen.
   Die Leiste umbricht jetzt, alles steht im Bild. */
@media (max-width:767px) {
    .ph-chips:has(> .kz-kopfteil > .prot-reiter) {flex-wrap:wrap; overflow-x:visible}
}

/* ── Nachrichten: „Nachricht erstellen" am Telefon ───────────────────
   Der Knopf stand in der Chipleiste hinter Reitern und Zaehler, rechts
   ausserhalb des Bildes. Mit .kz-kopfaktion markiert, rueckt er nach
   vorn, und die Leiste umbricht statt seitlich zu laufen. */
@media (max-width:767px) {
    .ph-chips:has(.kz-kopfaktion) {flex-wrap:wrap; overflow-x:visible}
    .ph-chips > .kz-kopfteil > .kz-kopfaktion {order:-1}
}

/* ══ Restpunkte nach Entscheidung des Nutzers (24.09.2026) ═══════════ */

/* ── Schale: Meldung, Telefon-Dialog, Popup-Hinweis, Randschatten, Anmeldung, Dashboard, Onboarding, Revue ── */
/* ==== C1: Schale, Popups, Meldung, Onboarding ==== */

/* Zentrale Meldung (window.kzMeldung): schwebt oben rechts ueber allem,
   auch ueber offenen Dialogen (.dlgwrap.fixed hat z-index 80) — wer im
   Dialog speichert, soll die Rueckmeldung sehen. Der Stapel selbst nimmt
   keine Klicks an, nur die Meldungen darin. */
.kz-meldungen {position:fixed;top:calc(14px + env(safe-area-inset-top, 0px));right:16px;z-index:90;display:flex;flex-direction:column;gap:8px;width:min(380px, calc(100vw - 32px));pointer-events:none}
.kz-meldung {pointer-events:auto;align-items:flex-start;border:1px solid var(--c-line);box-shadow:var(--sh-dlg);background:var(--c-surface);color:var(--c-ink);animation:kz-meldung-ein .18s ease-out}
.kz-meldung .t {flex:1;min-width:0;overflow-wrap:anywhere;padding-top:1px}
/* .al.ok/.bad/.warn faerben Flaeche und Schrift in der Statusfarbe. Die
   Statusflaechen sind im Dunkelmodus teils durchscheinend; ueber einem
   Dialog schiene dann die Seite durch. Darum liegt die Statusflaeche auf
   --c-surface, dazu ein farbiger Rand links. */
.kz-meldung.ok {background:linear-gradient(var(--st-ok-bg), var(--st-ok-bg)), var(--c-surface)}
.kz-meldung.bad {background:linear-gradient(var(--st-bad-bg), var(--st-bad-bg)), var(--c-surface)}
.kz-meldung.warn {background:linear-gradient(var(--st-warn-bg), var(--st-warn-bg)), var(--c-surface)}
.kz-meldung.info {background:linear-gradient(var(--c-accent-soft), var(--c-accent-soft)), var(--c-surface)}
.kz-meldung.ok {border-left:3px solid var(--st-ok)}
.kz-meldung.ok > svg {color:var(--st-ok)}
.kz-meldung.bad {border-left:3px solid var(--st-bad)}
.kz-meldung.bad > svg {color:var(--st-bad)}
.kz-meldung.warn {border-left:3px solid var(--st-warn)}
.kz-meldung.warn > svg {color:var(--st-warn)}
.kz-meldung.info {border-left:3px solid var(--c-accent)}
.kz-meldung.info > svg {color:var(--c-accent)}
.kz-meldung .x {flex-shrink:0;width:24px;height:24px;margin:-2px -4px -2px 0;border-radius:6px;display:grid;place-items:center;color:var(--c-ink-3)}
.kz-meldung .x:hover {background:var(--c-tint);color:var(--c-ink)}
.kz-meldung .x svg {width:13px;height:13px}
@keyframes kz-meldung-ein {from {opacity:0;transform:translateY(-6px)}}
@media (prefers-reduced-motion: reduce) {.kz-meldung {animation:none}}
/* Am Handy oben ueber die volle Breite — rechts oben laege sie sonst
   halb hinter dem Daumen und verdeckte die Kopfknoepfe nur teilweise. */
@media (max-width:767px) {
    .kz-meldungen {left:12px;right:12px;top:calc(10px + env(safe-area-inset-top, 0px));width:auto}
}

/* Rollende Tabellen: kommandozentrale.js setzt kz-mehr-r/kz-mehr-l, wenn
   in die Richtung wirklich noch Spalten liegen. Rechts ein innerer
   Schatten an der Huelle; links traegt ihn die klebende erste Spalte
   (am Handy klebt sie immer), sonst die Huelle. Eigene Farbe statt
   --c-scrim: im Dunkelmodus war der Schatten mit der Abdunkelungsfarbe
   auf dunkler Flaeche praktisch unsichtbar. */
:root {--kz-rand:rgba(16, 24, 40, .22)}
@media (prefers-color-scheme: dark) {:root:not([data-theme="light"]) {--kz-rand:rgba(0, 0, 0, .85)}}
:root[data-theme="dark"] {--kz-rand:rgba(0, 0, 0, .85)}
.b-tw.kz-mehr-r {box-shadow:inset -22px 0 18px -14px var(--kz-rand)}
.b-tw.kz-mehr-l {box-shadow:inset 22px 0 18px -14px var(--kz-rand)}
.b-tw.kz-mehr-r.kz-mehr-l {box-shadow:inset -22px 0 18px -14px var(--kz-rand), inset 22px 0 18px -14px var(--kz-rand)}
.b-tw.kz-mehr-l .b-t.stick th:first-child, .b-tw.kz-mehr-l .b-t.stick td:first-child {box-shadow:1px 0 0 var(--c-line), 10px 0 12px -6px var(--kz-rand)}
@media (max-width:767px) {
    .b-tw.kz-mehr-l .b-t th:first-child, .b-tw.kz-mehr-l .b-t td:first-child {box-shadow:1px 0 0 var(--c-line), 10px 0 12px -6px var(--kz-rand)}
}

/* Dateiwaehler (Quartalsrevue, Dialog "Neue Quartalsrevue"): die
   Eingabe ist per .vh versteckt, ein label.ghostbtn oeffnet sie. Das
   Feld ist ein div statt label (label in label ist ungueltig), braucht
   darum die Form, die .b-form sonst nur label gibt. */
.b-form .kz-datei {grid-column:1/-1;display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--c-ink-2);min-width:0}
.kz-datei-zeile {display:flex;align-items:center;gap:10px;flex-wrap:wrap;min-width:0}
/* .b-form label macht jedes label zur Spalte — der Knopf bleibt eine Zeile. */
.b-form .kz-datei label.ghostbtn {flex-direction:row;gap:7px;cursor:pointer;color:var(--c-ink-2)}
/* Der Tastenfokus liegt auf der versteckten Eingabe; sichtbar wird er am Knopf. */
.kz-datei label.ghostbtn:has(input:focus-visible) {outline:2px solid var(--c-accent);outline-offset:2px}
.kz-datei-name {font-size:12px;color:var(--c-ink-3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.kz-datei-name.gewaehlt {color:var(--c-ink);font-weight:500}

/* Telefon-Dialog (kz/telefon) und Popup-Benachrichtigung (kz/hinweis):
   .dlg.plain laesst overflow sichtbar (Kopf und Fuss stehen, der Rumpf
   rollt). Die Fortschrittsleiste oben liegt absolut am Rand und stuende
   sonst ueber die runden Ecken hinaus. Der Beschnitt muss so hoch sein
   wie die Rundung: an einem 3px hohen Kasten schrumpft der Browser den
   Radius auf 3px, und die Leiste stand an beiden Ecken gerade ueber die
   Kante. Also 13px hoch (14px Radius minus 1px Rand, .dsteps liegt
   innerhalb des Rands), die Balken bleiben oben 3px. */
.dlg.plain > .dsteps {height:13px;align-items:flex-start;border-radius:13px 13px 0 0;overflow:hidden;z-index:1;pointer-events:none}
/* Breite wie im Entwurf: Telefon schmal, Benachrichtigung mit Bild breiter. */
.dlg.plain.kz-tel {max-width:440px}
.dlg.plain.kz-hin {max-width:560px}
.kz-tel .dbody, .kz-hin .dbody {display:grid;gap:14px}
.kz-tel .dbody > .lede {margin:0}
.kz-tel .lede b {color:var(--c-ink);font-weight:600}
/* Der Code ist ein Feld, nicht sechs Kaestchen: gesperrt und in fester
   Laufweite, damit er sich wie der Code in der SMS liest. */
.kz-tel-code {font-family:"IBM Plex Mono",ui-monospace,monospace !important;font-size:18px !important;letter-spacing:.35em}
/* Nebenwege im Code-Schritt als Textknoepfe, wie .authfoot a. */
.kz-tel-fuss {justify-content:space-between}
.kz-tel-link {font:inherit;font-size:12px;font-weight:600;color:var(--c-accent);padding:4px 0}
.kz-tel-link:hover:not([disabled]) {text-decoration:underline}
.kz-tel-link[disabled] {color:var(--c-ink-3);cursor:default}
.kz-tel .hint.kz-tel-ok {color:var(--st-ok);font-weight:600}
/* Die Stufenanzeige braucht im Kopf keinen Platz fuers Schliesskreuz
   extra — app.css:997 gibt .dhead .r schon 36px Abstand rechts. */
.kz-tel .dhead h3, .kz-hin .dhead h3 {min-width:0;overflow-wrap:anywhere}

/* Benachrichtigung: Bild oben, volle Breite, nie hoeher als ein Drittel
   des Fensters — sonst rollt der Text am Handy aus dem Bild. */
.kz-hin-bild {display:block;width:100%;max-height:33vh;object-fit:contain;border:1px solid var(--c-line);border-radius:9px;background:var(--c-surface-2)}
/* Der bereinigte Editortext: Absaetze und Listen mit ruhigen Abstaenden,
   Verweise in der Akzentfarbe. base.css setzt Listen und Absaetze auf 0. */
.kz-hin-text {font-size:13px;line-height:1.6;color:var(--c-ink-2);overflow-wrap:anywhere}
.kz-hin-text > * + * {margin-top:8px}
.kz-hin-text ul, .kz-hin-text ol {padding-left:20px}
.kz-hin-text ul {list-style:disc}
.kz-hin-text ol {list-style:decimal}
.kz-hin-text strong, .kz-hin-text b {color:var(--c-ink);font-weight:600}
.kz-hin-text a {color:var(--c-accent);text-decoration:underline}
.kz-hin-proto {background:var(--c-surface-2);color:var(--c-ink-2)}
.kz-hin-proto > svg {color:var(--c-ink-3)}
.kz-hin-proto b {color:var(--c-ink)}
/* Fehler beim Quittieren steht ausserhalb eines .fld, .fld .err greift nicht. */
.kz-hin-fehler {font-size:12.5px;font-weight:600;color:var(--st-bad)}
/* Benachrichtigung: Zaehler und „Bestaetigung erforderlich" unter dem
   Titel wie im Entwurf (dort in der Lede). Rechts neben einem langen
   Titel brachen sie sonst einzeln in eine rechtsbuendige zweite Zeile. */
.dlg.plain.kz-hin .dhead {flex-direction:column;align-items:flex-start;gap:7px;padding-right:52px}
.dlg.plain.kz-hin .dhead .r {margin:0}

/* Dashboard am Handy, Karrierefortschritt:
   - Die Kopfpille („100,0 %") brach in eine eigene Zeile, weil Titel und
     Einheit „Karrieresystem" die Breite fuellen. Die Einheit sagt am
     Handy nichts, was der Titel nicht sagt — sie weicht, die Pille bleibt
     neben dem Titel.
   - Der Pfeil zwischen aktueller und naechster Position stand neben der
     aktuellen, waehrend die naechste darunter umbrach; er zeigte ins
     Leere. Untereinander gestellt zeigt er nach unten. */
@media (max-width:767px) {
    .kz-karriere .b-ph {flex-wrap:nowrap}
    .kz-karriere .b-ph > .unit {display:none}
    .kz-karriere .b-ph h3 {flex:1 1 auto;min-width:0}
    .kz-karriere .b-ph .r {flex-shrink:0}
    .kz-weg {flex-direction:column;gap:4px}
    .kz-weg .pfeil {transform:rotate(90deg);margin:2px 0 0 2px}
}
/* Telefon-Dialog am Handy: „Schritt 1 von 2" brach neben dem Titel in
   eine eigene Zeile. Die Leiste oben zeigt den Fortschritt schon; die
   Pille bleibt nur fuer Vorleser (sichtbar versteckt wie .vh). */
@media (max-width:767px) {
    .kz-tel .dhead .r {position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;margin:0}
}

/* Oeffentliche Seiten am Handy (Anmeldung, Onboarding-Fehlerseiten):
   .lg steht dort mit min-height:100dvh untereinander. Die zwei Zeilen
   teilten sich die Resthoehe, die dunkle Markenflaeche wurde bei leeren
   Zeilen halb so hoch wie der Schirm, und .lg-form zentrierte ihren
   Inhalt senkrecht — daher der Leerraum ueber „Anmelden" bzw. der
   Inhalt der Fehlerseite erst in der Bildmitte. Jetzt: Marke so hoch wie
   ihr Inhalt, das Formular fuellt den Rest und beginnt oben. */
@media (max-width:767px) {
    .lg {grid-template-rows:auto 1fr;align-content:start}
    .lg-form {place-items:start center}
}

/* Onboarding, Fehlerseite „bereits unterschrieben": Abstand zwischen
   Hinweis und „Vertrag erneut senden". */
.ob-erneut {margin-top:14px}
.ob-erneut .ghostbtn[disabled] {opacity:.55;cursor:default}

/* ── Leistungsfaehigkeit, PraeLux in Zahlen, Monatsverdienst ── */
/* ==== C3: Leistungsfähigkeit, PraeLux in Zahlen, Monatsverdienst ==== */

/* Sortierbare Köpfe über rechtsbündigen Spalten. .b-t th button ist
   display:flex und damit ein Block — text-align:right am th schiebt ihn
   nicht. Ohne diese Regel stand „Teamvolumen" links über rechtsbündigen
   Beträgen, und das Pfeilsymbol sprang je nach Titellänge. */
.b-t th.r > button {margin-left:auto}

/* „Alle 100 zeigen" unter der Primäranalyse: eine Zeile zwischen Tabelle
   und Fuß, mittig, damit er als Fortsetzung der Liste gelesen wird und
   nicht als Aktion des Panels. */
.fs-mehr {display:flex;justify-content:center;padding:10px 14px;border-top:1px solid var(--c-line)}
.fs-mehr .ghostbtn.sm {width:auto;padding:0 14px}

/* Hall of Fame | Nutzbares Volumen erst ab 1024 px nebeneinander. .g11
   stapelt laut app.css erst unter 768 px; am Tablet (916 px) war die Hall
   of Fame dadurch ~430 px breit, und ihre vier Unterreiter liefen in der
   .b-seg unsichtbar seitlich hinaus — „Branchenmanager" war abgeschnitten,
   ohne dass etwas aufs Weiterwischen hinwies. */
@media (max-width:1023px) {
    .fs-hof-reihe {grid-template-columns:minmax(0,1fr)}
}

/* Suchfeld „Vertriebspartner" im Seitenkopf statt des <select> mit ~900
   Namen. Feste Breite bis an die Obergrenze aus .b-fil input (150 px):
   ohne Größe nimmt das Textfeld seine Standardbreite, und der Chip
   wechselt je nach Namenslänge die Breite. Der Rahmen zeigt den Fokus,
   weil .b-fil input outline:none setzt. */
.fs-vp-fil input {width:150px;min-width:0}
.fs-vp-fil input::placeholder {color:var(--c-ink-3)}
.fs-vp-fil:focus-within {border-color:var(--c-accent)}

/* Die Vorschlagsliste dieses Felds hängt mit position:fixed am Feld (die
   Lage setzt kommandozentrale-fortschritt.js). Am Telefon steht der
   Filter in der seitlich scrollenden Chipleiste (.ph-chips,
   overflow-x:auto) — eine absolut gesetzte Liste würde dort unten
   abgeschnitten. z-index unter den Dialogen (.dlgwrap.fixed: 80).
   display und Schrift zurücksetzen: die Liste ist ein <span> im Chip,
   und „.b-fil span" (app.css) macht jeden Span darin zu einer
   inline-flex-Zeile in Mono — die Namen standen sonst nebeneinander. */
.kz-vorschlag.fs-fest {position:fixed;right:auto;margin-top:0;z-index:60;display:block;
                       font-family:inherit;white-space:normal}

/* ── Antragsstatus: Umschalter Benoetigt ── */
/* ══ C4: Antragsstatus-Rest ═════════════════════════════════════════════
   Ergaenzungen fuer public/css/kommandozentrale-blade.css (nach den
   bestehenden .b-dc-Regeln um Z. 1651 einfuegen). */

/* Neuer Kundenprozess, Dokumentkarten: der Umschalter „Benötigt" /
   „Nicht benötigt" war ein kleiner grauer Monospace-Text ohne Rahmen und
   las sich wie eine Zustandsangabe, nicht wie ein Knopf. Jetzt ein
   umrandeter Knopf wie .b-tg mit Haken (benoetigt, aria-pressed=true)
   bzw. Plus (nicht benoetigt, zum Zurueckholen). Die Farbe nach
   Kartenzustand (.on gruen, .az-nicht gelb) bleibt, siehe unten. */
.b-dc .need {display:inline-flex; align-items:center; gap:4px; min-height:26px; padding:0 8px;
    border:1px solid var(--c-line); border-radius:6px; background:var(--c-surface); color:var(--c-ink-2);
    font-family:inherit; font-size:11px; font-weight:600; line-height:1; white-space:nowrap}
.b-dc .need svg {width:12px; height:12px; flex-shrink:0}
.b-dc .need[aria-pressed="true"] svg {color:var(--st-ok-fill)}
/* Nach Kartenzustand getoent statt gefuellt: Weiss auf der Fuellfarbe
   (app.css .b-dc.on .need, blade.css .b-dc.az-nicht .need) erreichte
   gemessen nur 1,8–2,8 : 1 (dunkel #E9B460 bzw. #4ED0A0, hell #D9860B).
   Die Tinte --st-ok/--st-warn auf der Karte liegt deutlich darueber. */
.b-dc.on .need {background:var(--c-surface); border-color:var(--st-ok-fill); color:var(--st-ok)}
.b-dc.az-nicht .need {background:var(--c-surface); border-color:var(--st-warn-fill); color:var(--st-warn)}
.b-dc.on .need svg, .b-dc.az-nicht .need svg {color:inherit}
.b-dc:not(.on) .need:hover {border-color:var(--c-accent); color:var(--c-accent)}
.b-dc .need:focus-visible {outline:2px solid var(--c-accent); outline-offset:2px}
/* Am Telefon eine Trefferflaeche, die man mit dem Daumen trifft. */
@media (pointer:coarse) {
    .b-dc .need {min-height:32px; padding:0 10px}
}

/* ── Termintafel T2+, Wettkampf-Uebersicht, Challenge-Ranking ── */
/* ══ C5: Termintafel, Wettkampf, Challenge — Feinschliff ════════════
   Ergaenzungen fuer public/css/kommandozentrale-blade.css. */

/* Termintafel: T2+ trug den Ton von T2 (blauer Rahmen) und war in
   Legende und Tafel nur am Kuerzel zu erkennen. Eigener Ton, gerahmt wie
   T2 (Folgetermin), aber in Rosa und leicht hinterlegt. Die Farbe ist ein
   Token, damit Hell- und Dunkelmodus je eine eigene Stufe bekommen:
   #B4235F auf Weiss 6,3:1 (auf der Hinterlegung 5,4:1), #F08DB8 auf
   --c-surface dunkel 7,5:1 (6,4:1). */
:root {--tt-t2p: #B4235F}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {--tt-t2p: #F08DB8}
}
:root[data-theme="dark"] {--tt-t2p: #F08DB8}
.tp.t2p {background:color-mix(in srgb, var(--tt-t2p) 10%, transparent);
    box-shadow:inset 0 0 0 1.5px var(--tt-t2p); color:var(--tt-t2p)}

/* Challenge-Ranking: die Rangzahl stand inline vor dem Namen, ein langer
   Name brach am Telefon unter die Zahl um. Als Flexreihe laeuft die
   zweite Zeile unter dem Namen weiter (haengender Einzug). */
.ch-platz .ch-pn {display:flex; align-items:flex-start; gap:0}
.ch-platz .ch-pn > span:last-child {min-width:0; white-space:normal; line-height:1.35; padding-top:1px}
.ch-platz .ch-pn .b-med, .ch-platz .ch-pn .ch-rang {flex-shrink:0}

/* Wettkampf-Uebersicht: Unterzeile und kompakte Aktionen in der ersten
   Zelle gibt es erst unter 1024 bzw. 768 px (siehe unten). */
.wk-liste .wk-kurz, .wk-liste .wk-kurz-akt {display:none}
.wk-liste .wk-akt {display:flex; gap:6px; align-items:center; justify-content:flex-end}
@media (min-width: 768px) {
    /* Die Liste scrollt ab hier nicht mehr seitlich; der Hinweis
       „Spalten seitlich scrollen" stimmte nicht. */
    .wk-hinweis {display:none}
}

/* Tablet (916 px): Die Tabelle war breiter als der Platz, Admin, Zustand
   und Aktionen lagen hinter dem Querscroll. Zustand und Admin stehen
   jetzt als Unterzeile unter dem Namen, ihre Spalten entfallen. */
@media (max-width: 1023px) {
    .wk-liste .wk-breit {display:none}
    .wk-liste td.nm {white-space:normal}
    .wk-liste .wk-kurz {display:flex; flex-wrap:wrap; align-items:center; gap:4px 8px; margin-top:5px;
        font-size:11.5px}
    .wk-liste td.wk-teams {min-width:160px}
}

/* Telefon: Die Liste scrollt weiter mit klebender Namensspalte (Zeitraum
   und Teams brauchen den Platz), die Aktionen stehen aber als Verweis und Symbole in
   der ersten Zelle statt ganz rechts ausserhalb des Bildschirms. Die
   Namensspalte war rund 260 px breit, jetzt hoechstens gut die Haelfte. */
@media (max-width: 767px) {
    .wk-liste .wk-sp-akt {display:none}
    .wk-liste td.nm {min-width:150px; max-width:52vw; overflow-wrap:anywhere}
    .wk-liste .wk-kurz-akt {display:block; margin-top:2px}
    .wk-liste .wk-kurz-akt .wk-akt {justify-content:flex-start; gap:2px}
    /* Trefferflaeche 32 px hoch wie die Symbolknoepfe daneben. */
    .wk-liste .wk-kurz-akt .b-lnk {min-height:32px; margin-right:8px}
    .wk-liste .wk-kurz-akt .b-ib {width:32px; height:32px}
}

/* ── Einstellungen: Suche Perso-Ausnahmen ── */
/* ── C6 · Einstellungen › Perso Ausnahmen: Suche über der Liste ──────────
   Warum: .b-pb traegt flex:1 und wuerde in einer hohen Flaeche wachsen;
   die Suchzeile soll nur so hoch sein wie ihr Feld. Unten kein Abstand,
   weil die Tabelle direkt anschliesst. Das Feld bleibt am Desktop auf
   Lesebreite begrenzt (sonst 1.200 px fuer eine Nummer), am Telefon
   nimmt es die volle Breite. 38 px statt 44 px: es steht in einem
   Flaechenkopf, nicht in einem Formular. */
.au-suche {flex:none;padding-bottom:10px}
.au-suche .inp {max-width:420px;height:38px}
@media (max-width:767px) {
    .au-suche .inp {max-width:none;height:44px}
}

/* ── Personalentwicklung: Teilnehmerfeld ABW, Praelux AGA, Zusammenfassung ── */
/* ── Personalentwicklung: Teilnehmerfeld ABW, Praelux AGA, Zusammenfassung ──
   Gehoert in kommandozentrale-blade.css (Abschnitt Personalentwicklung,
   nach .pe-abw-zahl). Die alten .pe-abw / .pe-abw-kopf / .pe-abw-zahl
   (Karten je Wochenende) nutzt nach dem Umbau nichts mehr und koennen weg. */

/* Die Wochenenden-Leiste besteht aus Verweisen, nicht aus Spans wie im
   Entwurf — ohne das hier waeren sie unterstrichen und blau. */
.pe-abw-leiste a.b-fil {text-decoration:none; cursor:pointer}
/* Die Kurznamen (OWE/MWE/SWE) stehen als .vh fuer Vorleser in den
   Chips. .vh ist position:absolute; ohne positionierten Vorfahren
   entkommen sie dem seitlich rollenden .b-fils, und am Telefon wurde die
   ganze Seite 4.393 px breit. */
.pe-abw-leiste {position:relative}
.pe-abw-leiste a.b-fil {position:relative}
.pe-abw-leiste a.b-fil:hover {border-color:var(--c-ink-3)}
.pe-abw-leiste a.b-fil.on:hover {border-color:var(--c-accent)}
.pe-abw-leiste a.b-fil:focus-visible {outline:2px solid var(--c-accent); outline-offset:2px}
/* Vergangene Wochenenden treten zurueck, bleiben aber waehlbar. */
.pe-abw-leiste a.b-fil.pe-vorbei:not(.on) {opacity:.72}

/* Ein Panel je Art innerhalb des Reiter-Panels: keine zweite Karte in der
   Karte, nur eine Trennlinie zwischen OWE, MWE und SWE. */
.pe-abw-panel + .pe-abw-panel {border-top:1px solid var(--c-line); margin-top:10px}
.pe-abw-panel > .b-ph {background:var(--c-surface-2)}

/* Aktionen und Bestaetigung einer Zeile bleiben auf einer Zeile. .b-ib
   ist in app.css display:grid, also ein Block — neben „Verschieben"
   rutschte der Abmelden-Knopf in eine zweite Zeile, jede Zeile wurde
   64 statt 31 px hoch. */
.pe-akt-zelle {white-space:nowrap}
.pe-akt-zelle .b-ib {display:inline-grid; vertical-align:middle; margin-left:6px; width:26px; height:26px}
.pe-swe, .pe-video {white-space:nowrap}
.pe-swe .ghostbtn, .pe-video .b-lnk {margin-left:6px}
.pe-mail {font-size:11.5px}

/* AGA: ein Kaestchen je Modul, gefuellt = Modultermin hinterlegt. */
.b-t th.c, .b-t td.c {text-align:center}
.pe-mod {display:inline-grid; place-items:center; width:17px; height:17px; border-radius:5px;
  border:1.5px solid var(--c-line); background:var(--c-surface); vertical-align:middle;
  /* haelt den .vh-Text („erledigt am …") im Kaestchen — sonst rollt er
     ausserhalb des Tabellen-Scrollers und macht die Seite am Telefon breit */
  position:relative}
.pe-mod.an {border-color:var(--c-accent); background:var(--c-accent); color:#fff}
.pe-mod .ic {width:11px; height:11px; stroke-width:2.6}
.pe-aga-kopf {border-top:1px solid var(--c-line)}
/* .b-sl .n ist fuer eine kurze Zahl gedacht (flex-shrink:0); hier steht
   ein Modulname, der am Telefon sonst ueber den Rand hinaus laeuft. */
.b-sl .n.pe-aga-alt {font-family:inherit; font-size:11.5px; font-weight:400; color:var(--c-ink-3);
  text-align:right; max-width:48%; flex-shrink:1; min-width:0; white-space:normal}

/* Zusammenfassung: immer genau drei Flaechen (OWE, MWE, SWE). app.css
   schaltet .b-sm am Tablet auf zwei Spalten — dann stand SWE allein in
   der zweiten Reihe neben einer leeren grauen Kachel. Am Telefon
   untereinander. */
.pe-sm.b-sm {grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:640px) {
  .pe-sm.b-sm {grid-template-columns:1fr}
}

/* Kennzahlen OWE: Vorschlag in der FKS-Spalte, bis er uebernommen ist. */
.pe-fks-vorschlag {font-style:italic; color:var(--c-ink-3); white-space:nowrap}

/* .pe-dateien (kommandozentrale-blade.css) macht die Zelle zur Flexbox;
   als Tabellenzelle faellt sie damit aus der Zeile (eigene Hoehe, eigener
   Hintergrund bei tr-warn). Im ABW-Panel bleibt sie eine Zelle. */
.pe-abw-panel td.pe-dateien {display:table-cell; white-space:nowrap}
.pe-abw-panel td.pe-dateien .b-lnk + .b-lnk {margin-left:9px}
