/* ============================================================
   Copilot – Styles
   Theme-Regel: ALLE Farben laufen über Custom Properties, die
   unter [data-theme="dark"] und [data-theme="light"] definiert
   sind. Niemals Farben hart in Komponenten codieren!
   ============================================================ */

/* Eine Schriftfamilie für die ganze App. Auch der QS-Bereich (#qs-app in
   qs.css) muss sie für gemeinsame Bausteine wie .btn benutzen – sonst sehen
   dieselben Knöpfe dort anders aus. */
:root {
    --font-app: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/* ---------- Themes ---------- */
[data-theme="dark"] {
    --bg: #0a0d12;
    --bg-gradient: radial-gradient(1200px 600px at 80% -10%, rgba(108, 140, 255, 0.10), transparent 60%),
                   radial-gradient(900px 500px at -10% 110%, rgba(165, 108, 255, 0.08), transparent 60%);
    --surface: #171d2a;
    --surface-2: #242e42;
    --surface-hover: #2c3752;
    --text: #e8ecf5;
    --text-muted: #a3aec3;
    --border: #3a4560;
    --accent: #6c8cff;
    --accent-rgb: 108, 140, 255;   /* --accent als RGB-Triple für rgba(var(--accent-rgb), X) */
    --accent-2: #a56cff;
    --accent-gradient: linear-gradient(135deg, #6c8cff, #a56cff);
    --accent-soft: rgba(108, 140, 255, 0.14);
    /* Gefüllte Flächen mit WEISSER Schrift (Knöpfe, aktive Umschalter).
       Bewusst dunkler als --accent: Weiß auf --accent schafft nur 3,07:1,
       auf --accent-btn 5,11:1 (WCAG AA). --accent selbst bleibt so hell wie
       bisher – für Texte, Icons und Chips auf dunklem Grund. */
    --accent-btn: #4665d8;
    --accent-btn-2: #8348d8;
    --accent-btn-gradient: linear-gradient(135deg, #4665d8, #8348d8);
    --positive: #4ade80;
    --positive-soft: rgba(74, 222, 128, 0.14);
    --negative: #f87171;
    --negative-soft: rgba(248, 113, 113, 0.14);
    --neutral: #93a3bd;
    --neutral-soft: rgba(147, 163, 189, 0.14);
    --gold: #e0aa3e;
    /* Orange für Warnpunkte (02.09.2026, Wunsch Sebastian im Teamplaner).
       Bewusst ein eigenes Token und kräftiger als --abs-schule (dem sandigen
       Orange der Schul-Balken): der Punkt sitzt in der Namensspalte und darf
       nicht wie eine Abwesenheitsart gelesen werden. */
    --warn-dot: #f97a26;
    /* Fläche einer bereits gelesenen Timeline-Zeile (03.09.2026). Bewusst ein
       eigenes Token je Theme statt eines Rechenwegs für beide: durchsichtig
       machen läuft in den Themes in ENTGEGENGESETZTE Richtungen (dunkel wird
       dunkler, hell wird heller) – gewollt ist beides Mal „etwas abgedunkelt".
       Hier Richtung Kartenfläche, damit die Zeile in den Hintergrund tritt. */
    --tl-gelesen: color-mix(in srgb, var(--surface-2) 60%, var(--surface));
    /* Arten der Abwesenheiten (18.08.2026, am 03.09.2026 umgestellt).
       **Jetzt: Urlaub BLAU, Krank ROT, Schule orange, Office die Akzentfarbe**
       (Vorgabe Sebastian). Vorher war Urlaub grün und Krank blau – grün las sich
       wie „alles gut" und Krank fiel gar nicht auf. **Nicht ohne Rücksprache
       zurücktauschen.**
       Bewusst eigene Tokens – NICHT --negative/--accent, damit „Status" und
       „Art einer Abwesenheit" nicht durcheinandergehen und die Farben je Theme
       nachgezogen werden können. Das Rot ist deshalb auch nicht --negative,
       sondern ein eigener, etwas wärmerer Ton. */
    --abs-urlaub: #4f8ff0;
    --abs-krank: #e2635f;
    --abs-schule: #e39a4e;
    /* Office (gebuchter Platz im Desksharing) – seit 04.09.2026 GRÜN statt in der
       Primärfarbe (Wunsch Sebastian). Eigenes Token wie bei den Abwesenheitsarten,
       damit es sich je Thema nachziehen lässt: ein sattes Grün, auf dem weiße
       Schrift lesbar bleibt – `--positive` ist im dunklen Thema zu hell dafür. */
    --abs-office: #2f9e63;
    /* Schrift auf gefüllten Statusflächen (Besetzungs-Kreis im Kalenderkopf).
       Im dunklen Thema sind --positive/--gold/--negative HELLE Töne, also
       gehört dunkle Schrift darauf. Im hellen Thema ist es umgekehrt. */
    --kreis-ink: #141a26;
    /* Ganz dezenter, breiter Schein oben rechts (body::before) */
    --glow-1: rgba(108, 140, 255, 0.13);
    --glow-2: rgba(165, 108, 255, 0.09);
    --shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 18px 45px -12px rgba(0, 0, 0, 0.60); /* schwebende Ebenen, z. B. Toast-Stapel */
    color-scheme: dark;
}

[data-theme="light"] {
    --bg: #e9edf5;
    --bg-gradient: radial-gradient(1200px 600px at 80% -10%, rgba(108, 140, 255, 0.10), transparent 60%),
                   radial-gradient(900px 500px at -10% 110%, rgba(165, 108, 255, 0.08), transparent 60%);
    --surface: #ffffff;
    --surface-2: #eaeff8;
    --surface-hover: #e2e8f3;
    --text: #1c2333;
    --text-muted: #5a6680;
    --border: #c4cee1;
    --accent: #4a68d8;
    --accent-rgb: 74, 104, 216;    /* --accent als RGB-Triple für rgba(var(--accent-rgb), X) */
    --accent-2: #8548dd;
    --accent-gradient: linear-gradient(135deg, #4a68d8, #8548dd);
    --accent-soft: rgba(74, 104, 216, 0.12);
    /* siehe Dark: gefüllte Flächen mit WEISSER Schrift */
    --accent-btn: #4a68d8;
    --accent-btn-2: #7f45d0;
    --accent-btn-gradient: linear-gradient(135deg, #4a68d8, #7f45d0);
    --positive: #15803d;
    --positive-soft: rgba(21, 128, 61, 0.12);
    --negative: #d33f3f;
    --negative-soft: rgba(211, 63, 63, 0.12);
    --neutral: #5a6680;
    --neutral-soft: rgba(90, 102, 128, 0.12);
    --gold: #9a6f08;
    /* siehe Dark: Orange für Warnpunkte, hier dunkler für den Kontrast auf Weiß */
    --warn-dot: #c1490b;
    /* siehe Dark: Fläche einer gelesenen Zeile. Im hellen Thema führt der Weg
       zur Kartenfläche (Weiß) nach OBEN – deshalb hier Richtung Rahmenfarbe,
       damit die Zeile auch hier etwas abgedunkelt ist und nicht aufhellt. */
    --tl-gelesen: color-mix(in srgb, var(--surface-2) 74%, var(--border));
    /* siehe Dark: eigene Tokens für die Arten, hier etwas dunkler für Kontrast.
       Umgestellt am 03.09.2026: Urlaub blau, Krank rot. */
    --abs-urlaub: #2f6ec9;
    --abs-krank: #c33e3a;
    --abs-schule: #b06a20;
    --abs-office: #1f8a55;
    /* siehe Dark: hier sind die Statusfarben dunkel, also weiße Schrift darauf */
    --kreis-ink: #ffffff;
    /* Ganz dezenter, breiter Schein oben rechts (body::before) */
    --glow-1: rgba(74, 104, 216, 0.10);
    --glow-2: rgba(133, 72, 221, 0.07);
    --shadow: 0 8px 24px rgba(28, 35, 51, 0.10);
    --shadow-sm: 0 2px 8px rgba(28, 35, 51, 0.08);
    --shadow-lg: 0 18px 45px -12px rgba(28, 35, 51, 0.22); /* schwebende Ebenen, z. B. Toast-Stapel */
    color-scheme: light;
}

/* ---------- Ebenen (z-index) ----------
   Verbindliche Reihenfolge für alle Overlays – neue Komponenten hier eintragen,
   damit die Werte nicht wieder auseinanderlaufen. Grundregel: Popups liegen
   IMMER über Inhalt, Navigation und Deko-Effekten.

     -1   Lichtschein im Hintergrund (body::before)
      0–3 Inhalt (Karten, Timeline-Punkte, Sparkline hinter den Zahlen …)
      5   Deko-Effekte: Partykanone, Mini-Partykanone, Zuspruch
          → bewusst unter Topbar, Navigation und allen Popups: Deko darf
            beim Hochschweben nichts Festes überlagern (10.08.2026)
     10   Topbar (sticky)
     20   Sidebar (Desktop)
     40   Sidebar (mobil, ausgeklappt)
     50   Anwesenheits-Karte
     60   Dropdowns in der Topbar (Benachrichtigungen, Notizbuch)
     70   Nach-oben-Knopf, Flyout-Untermenü der kompakten Sidebar
     80   QS-Popups (#qs-app .modal-overlay, in qs.css)
     90   Copilot-Popups (.modal-overlay)
    100   Schnellsuche
    120   Diagramm maximieren (#chartModal)
    200   QS-Chart-Tooltip (#charttip, in qs.css)
    300   Toast-Meldungen
   9000   Privatsphäre-Modus (.privacy-lock) – Sichtschutz über allem
   9999   Bild-Lightbox in QS (#imgPopup, in qs.css)                            */

/* ---------- Basis ---------- */
* { box-sizing: border-box; }

/* hidden-Attribut gewinnt immer (auch gegen display-Regeln von Komponenten) */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
    font-family: var(--font-app);
    background: var(--bg);
    background-image: var(--bg-gradient);
    background-attachment: fixed;
    color: var(--text);
    font-size: 15px;
    line-height: 1.55;
    transition: background-color 0.25s ease, color 0.25s ease;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 0.6em; }
h1 { font-size: 1.5rem; display: flex; align-items: center; gap: 0.5em; flex-wrap: wrap; }
h2 { font-size: 1.05rem; display: flex; align-items: center; gap: 0.4em; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

code {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.1em 0.4em;
    font-size: 0.85em;
}

.muted { color: var(--text-muted); font-size: 0.88em; }

.t-center { text-align: center; }

/* ---------- App-Grundgerüst ---------- */
.app { display: flex; min-height: 100vh; }

.sidebar {
    /* 200px seit 02.09.2026 (Variante D, Wunsch Sebastian). Vorher 264px – das
       stammte noch aus der Zeit der vollen Kachel mit Kontextzeile (20.08.2026),
       beides gibt es nicht mehr. Gemessen passt der Inhalt ab 191px ohne
       Abschneiden; 200 lässt Luft. Was dafür schmaler werden musste, steht im
       Block „D · Seitenleiste schmaler" am Ende der Datei. */
    width: 200px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 16px 12px;
    position: sticky;
    top: 0;
    height: 100vh;
    z-index: 20; /* damit die Anwesenheits-Karte über dem Inhalt liegt */
    transition: transform 0.25s ease;
}

.sidebar-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 10px 18px;
    font-weight: 700;
    font-size: 1.1rem;
}
/* Marken-Text gestapelt: "Copilot" + Team-Badge (Stil des früheren Dashboard-Kopfs) */
.sidebar-brand .brand-text { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.sidebar-brand .brand-name { font-size: 1.25rem; line-height: 1.05; }

/* Eingeklappter Zustand (nur Desktop – mobil übernimmt das Burger-Menü) */
@media (min-width: 901px) {
    html.sidebar-min .sidebar { width: 72px; padding: 16px 10px; }
    html.sidebar-min .sidebar .brand-text,
    html.sidebar-min .sidebar .nav-link span { display: none; }
    /* Bereichs-Label (z. B. "Verwaltung"): im Kompaktmodus nur eine feine Trennlinie */
    html.sidebar-min .sidebar .nav-section-label {
        height: 0;
        overflow: hidden;
        font-size: 0;
        padding: 0;
        margin: 10px 12px;
        border-top: 1px solid var(--border);
    }
    html.sidebar-min .sidebar-brand { justify-content: center; padding: 6px 0 14px; }
    html.sidebar-min .sidebar .nav-link { justify-content: center; padding-left: 0; padding-right: 0; }
    /* Profil + MA-Auge untereinander. Wichtig: der Profil-Link darf nicht in die
       Höhe wachsen (flex: 1 wirkt in der Spalte sonst vertikal) und soll die volle
       Breite bekommen – sonst sieht sein Aktiv-Zustand anders aus als bei den
       übrigen Punkten (z. B. Einstellungen). */
    html.sidebar-min .sidebar-foot-row { flex-direction: column; align-items: stretch; gap: 6px; }
    html.sidebar-min .sidebar-foot-row .nav-link { flex: none; }
    html.sidebar-min .sidebar-foot-row form { margin: 0; display: flex; justify-content: center; }
    /* Der Block um die Bereiche bleibt auch schmal erhalten, nur enger */
}

.logo-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: var(--accent-gradient);
    color: #fff;
    font-weight: 800;
    box-shadow: var(--shadow-sm);
}

/* Der Navi-Bereich scrollt, wenn das Fenster zu flach wird (18.08.2026) – Logo
   oben und der Fuß (Profil, Einstellungen, Abmelden) bleiben dabei stehen.
   `min-height: 0` ist der eigentliche Trick: ohne ihn wächst ein Flex-Kind über
   die Sidebar hinaus, statt zu scrollen, und der Fuß rutscht aus dem Bild.
   `overscroll-behavior` verhindert, dass am Listenende die Seite mitscrollt. */
.sidebar-nav {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}
/* Trennlinie + Beschriftung für den "Verwaltung"-Bereich in der Navigation.
   Die Abstände um die Linie sind am 20.08.2026 auf Wunsch gewachsen (vorher
   14px / 12px): sie trennt die Arbeitsbereiche von den Werkzeugen und darf
   das auch zeigen. `margin-top` = Luft über der Linie, `padding-top` = Luft
   zwischen Linie und Beschriftung. */
.nav-section-label {
    margin: 26px 12px 8px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* Punkte außerhalb der Blöcke (Sektion „Organisation") stehen auf EINER Stufe mit
   dem Sidebar-Fuß (Wunsch Sebastian 20.08.2026: „gleiche Größe wie unten"). Der
   gemeinsame Wert 0.84rem ist der Kompromiss zwischen den beiden alten Größen
   (0.86 oben / 0.82 unten) – beide Zonen sind damit erkennbar eine Stufe unter
   den Arbeitsbereichen im Block. Wer eine Größe ändert, ändert BEIDE.
   Die Werte für den Fuß stehen weiter oben bei `.sidebar-foot .nav-link`. */
.sidebar-nav > .nav-group .nav-link { font-size: 0.84rem; padding: 8px 12px; }
.sidebar-nav > .nav-group .nav-link > svg { width: 17px; height: 17px; opacity: 0.9; }

/* Sidebar-Fuß = Konfiguration, nicht Arbeitsbereich (12.08.2026): eigene Zone
   mit deutlicher Trennlinie, kleinerer und ruhigerer Schrift. So ist auf den
   ersten Blick klar, dass Profil und Einstellungen nicht zu den Bereichen
   darüber gehören. */
.sidebar-foot {
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 1px;
}
/* Größe und Icon-Maß identisch zur Sektion „Organisation" (Wunsch 20.08.2026) –
   Gegenstück steht bei `.sidebar-nav > .nav-group .nav-link`. */
.sidebar-foot .nav-link {
    padding: 7px 12px;
    font-size: 0.84rem;
    color: var(--text-muted);
    border-radius: 8px;
}
.sidebar-foot .nav-link svg { width: 17px; height: 17px; opacity: 0.85; }
.sidebar-foot .nav-link:hover { color: var(--text); }
.sidebar-foot .nav-link.active { background: transparent; color: var(--accent); font-weight: 600; }
.sidebar-foot .nav-link.active svg { opacity: 1; }

/* Weicher Verlauf an der Kante, sobald der Navi-Bereich scrollen kann (Klassen
   setzt app.js). Nötig, weil macOS keine dauerhafte Scrollleiste zeigt – ohne
   den Verlauf sieht ein abgeschnittener Punkt wie ein Darstellungsfehler aus.
   -webkit-mask für Safari. */
.sidebar-nav.is-scrollable {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent);
}
.sidebar-nav.is-scrolled {
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22px);
    mask-image: linear-gradient(to bottom, transparent, #000 22px);
}
.sidebar-nav.is-scrolled.is-scrollable {
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22px, #000 calc(100% - 26px), transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 22px, #000 calc(100% - 26px), transparent);
}

/* Flaches Fenster (18.08.2026, Variante „erst dichter, dann scrollen" – von
   Sebastian gewählt): Unter 760px Höhe entfallen die Kontextzeilen der Bereiche
   („Überblick & Ranking“) und die Abstände schrumpfen. Dadurch passt die
   Navigation deutlich länger ohne Scrollleiste; wird es noch flacher, scrollt
   .sidebar-nav. Hier stehen bewusst NUR Abstände und ein display:none – keine
   Farben, damit Dark und Light gleich bleiben. */
@media (max-height: 760px) {
    .sidebar { padding: 12px; }
    .sidebar-brand { padding: 4px 10px 12px; }
    .sidebar-brand .brand-name { font-size: 1.1rem; }
    .sidebar .nav-link { padding: 7px 12px; }
    .sidebar .nav-link.nav-main { padding: 6px 12px 6px 0; }
    /* Die Kontextzeile BLEIBT auch im flachen Fenster (Korrektur 20.08.2026):
       hier stand `display: none`, und weil Sebastians Fenster nur ~700px hoch
       ist, hat er den Beschreibungstext nie zu sehen bekommen. Nur die Abstände
       schrumpfen; wird es noch flacher, scrollt .sidebar-nav – das genügt.
       Seit dem 24.08.2026 zeigt ohnehin nur noch der AKTIVE Bereich seine
       Kontextzeile (Vorschlag „B", Block am Ende der Datei) – unabhängig von
       der Fensterhöhe. */
    .sidebar .nav-section-label { margin: 16px 12px 6px; padding-top: 13px; }
    .sidebar-nav > .nav-group .nav-link { padding: 6px 12px; }
    .sidebar-foot { margin-top: 6px; padding-top: 8px; }
    .sidebar-foot .nav-link { padding: 5px 12px; }
}

/* `.ma-toggle` (das Auge für den Mitarbeiter-Modus hinter dem Profilnamen) ist
   am 03.09.2026 ersatzlos entfallen – an seine Stelle tritt der Testblick im
   Profil. **Nicht ohne Rücksprache neu bauen.** Die Reihe bleibt: sie hält den
   Profil-Link auf voller Breite. */
.sidebar-foot-row { display: flex; align-items: center; gap: 4px; }
.sidebar-foot-row .nav-link { flex: 1; min-width: 0; }

.nav-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border-radius: 10px;
    color: var(--text-muted);
    font-weight: 500;
    transition: background 0.15s ease, color 0.15s ease;
}
.nav-link:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.nav-link.active { background: var(--accent-soft); color: var(--accent); }
.nav-link span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Hauptbereiche (Umbau 12.08.2026): keine Icon-Kacheln mehr – nur Titel und
   eine kurze, feste Kontextzeile. Der aktive Bereich bekommt eine schmale
   Akzentkante links und eine leise getönte Fläche; das ist ruhiger als die
   bunten Kacheln davor. Das Icon steckt weiter im HTML, ist aber nur im
   Kompaktmodus sichtbar – dort ist es der einzige Anker. */
.nav-link.nav-main {
    padding: 10px 12px 10px 0;
    position: relative;
    gap: 0;
    border-radius: 10px;
}
/* Icons auf einer festen Spalte (12.08.2026): dadurch beginnen ALLE Titel exakt
   untereinander, egal wie breit das Icon zeichnet. Gedämpft, damit sie den Titel
   nicht überstrahlen – der aktive Bereich bekommt das Icon in Akzentfarbe. */
.nav-link.nav-main > svg {
    width: 20px; height: 20px;
    /* links auf einer Linie mit dem C-Logo (.sidebar-brand hat 10px Innenabstand),
       rechts der schmale Abstand zum Titel */
    flex: 0 0 37px;
    box-sizing: content-box;
    padding: 0 7px 0 10px;
    opacity: 0.45;
    transition: opacity 0.15s ease, color 0.15s ease;
}
.nav-link.nav-main:hover > svg { opacity: 0.8; }
/* Die Akzentkante hat eine FESTE Höhe und wird nur ein-/ausgeblendet. Früher
   war ihre Höhe animiert – beim Verlassen fuhr sie sichtbar zur Mitte zusammen.
   Beim Hover gibt es bewusst keine Kante, nur die getönte Fläche: die Kante
   bleibt damit das Signal „hier stehst du". */
.nav-link.nav-main::before {
    content: "";
    position: absolute;
    left: 0; top: 50%;
    width: 3px; height: 62%;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
    transform: translateY(-50%);
    opacity: 0;
    transition: opacity 0.15s ease;
}
.nav-link.nav-main, .nav-link.nav-main:hover, .nav-link.nav-main.active { background: transparent; }
.nav-link.nav-main:hover { background: var(--surface-hover); }
.nav-link.nav-main .nav-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
/* Bewusst NICHT fett (Wunsch Sebastian 20.08.2026): 500 reicht, der aktive
   Bereich hebt sich über Farbe und Karte ab, nicht über die Strichstärke. */
.nav-link.nav-main .nav-label { font-weight: 500; font-size: 0.96rem; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Die Kontextzeile darf UMBRECHEN (max. zwei Zeilen, Wunsch 20.08.2026) – mit
   `nowrap` stand bei „Abwesenheiten & Office-Tage" nur „… Office-Ta…", der Text
   fehlte also genau dort, wo er etwas erklärt. */
.nav-link.nav-main .nav-desc {
    font-size: 0.72rem; font-weight: 400; color: var(--text-muted); line-height: 1.3;
    /* `white-space: normal` MUSS hier stehen: `.nav-link span` setzt weiter oben
       `nowrap`, und ohne das Zurücksetzen bricht nichts um, egal was hier folgt. */
    white-space: normal;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
/* Aktiver Bereich = VOLLE KACHEL (Variante „D", von Sebastian am 20.08.2026 aus
   fünf Vorschlägen in `_sidebar-vorschlaege.html` gewählt): gefüllt im
   Knopf-Verlauf, weiße Schrift.
   **Überholt am 24.08.2026** – der Block „Navigation ruhiger" ganz am Ende der
   Datei macht daraus wieder eine getönte Fläche mit Akzentkante (Vorschlag „A").
   Die Regeln hier bleiben als Grundlage stehen; wer die Kachel zurückwill,
   nimmt dort den A-Teil heraus. Der Standort ist damit auch aus dem Augenwinkel
   klar. `--accent-btn-gradient` ist Pflicht, nicht `--accent-gradient` – hier
   steht Text drauf (siehe Kontrast-Abschnitt in der Design-Regel).
   Die Akzentkante links entfällt auf der Kachel: auf gefüllter Fläche wäre sie
   unsichtbar, und die Kachel ist das Signal. */
.nav-link.nav-main.active {
    background: var(--accent-btn-gradient);
    box-shadow: var(--shadow-sm);
}
.nav-link.nav-main.active:hover { background: var(--accent-btn-gradient); filter: brightness(1.06); }
.nav-link.nav-main.active::before { display: none; }
.nav-link.nav-main.active > svg { opacity: 1; color: #fff; }
.nav-link.nav-main.active .nav-label { color: #fff; }
.nav-link.nav-main.active .nav-desc { color: #fff; opacity: 0.8; }
/* Kompaktmodus: Text weg (span-Regel oben), das Icon rückt in die Mitte */
html.sidebar-min .sidebar .nav-link.nav-main { padding: 9px 0; justify-content: center; }
html.sidebar-min .sidebar .nav-link.nav-main > svg { flex: none; padding: 0; opacity: 1; }
html.sidebar-min .sidebar .nav-link.nav-main .nav-body { display: none; }
html.sidebar-min .sidebar .nav-link.nav-main::before { display: none; }

/* Sub-Navigation (einzelne Gruppen unter "Gruppen"): eingerückt,
   mit Baum-Linie links und Pfeil vor jedem Eintrag */
.nav-sub-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin: 2px 0 6px 22px;
    padding-left: 8px;
    border-left: 1px solid var(--border);
}
.nav-link.nav-sub {
    padding: 4px 10px 4px 24px;
    font-size: 0.82rem;
    position: relative;
}
.nav-link.nav-sub::before {
    content: '›';
    position: absolute;
    left: 11px;
    top: 50%;
    transform: translateY(-52%);
    font-size: 0.85rem;
    line-height: 1;
    opacity: 0.6;
}
/* Eingeklappte Seitenleiste: Sub-Punkte ausblenden */
html.sidebar-min .nav-sub-list { display: none; }

/* Nur der Layout-Container (.app > .main) – ".main" allein würde auch
   fremde Elemente treffen (z. B. tr.main im QS-Dashboard) */
.app > .main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.topbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 24px;
    position: sticky;
    top: 0;
    z-index: 10;
    background: color-mix(in srgb, var(--bg) 85%, transparent);
    backdrop-filter: blur(8px);
}
.topbar-spacer { flex: 1; }
.topbar .nav-toggle { display: none; }

/* Icon-Gruppen in der Topbar (11.08.2026): Werkzeuge (Schnellnotiz, QS-Filter)
   und Globales (Suche, Glocke, Hilfe) je in einer eigenen Pille, der
   Theme-Umschalter steht frei daneben. Die Panels (Glocke/Notizbuch) ankern
   weiter an ihren .notif-wrap/.notebook-wrap – die Pille ändert daran nichts. */
.topbar-group {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
}
.topbar-group .btn-icon { border-radius: 999px; }
.topbar-group:empty { display: none; }

/* Etwas mehr Luft: begrenzte Breite, großzügigere Ränder (Dashboard & alle Seiten) */
.content { padding: 14px 32px 56px; max-width: 1280px; width: 100%; margin: 0 auto; }

.page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin: 14px 0 26px;
}
/* Gleicher Start unter der Topbar auf ALLEN Seiten (12.08.2026): die Überschrift
   bekommt eine feste Mindesthöhe in Knopfhöhe. Vorher richtete .page-head seinen
   Inhalt mittig aus – dadurch rutschte die Überschrift je nach Icon-Größe und
   Höhe der Knöpfe rechts um ein paar Pixel nach unten (/auszubildende und
   /qualitaetssicherung sahen deshalb anders aus als / und /zielerreichung). */
.page-head h1 { margin: 0; min-height: 40px; line-height: 1.3; }
.page-head h1 > svg { flex-shrink: 0; }
/* "Dein Tag": kompakte Übersichtszeile unter der Dashboard-Begrüßung */
.day-summary { margin: 7px 0 0; font-size: 0.92rem; color: var(--text-muted); }
.day-summary a { color: var(--accent); font-weight: 600; }
.day-summary .day-sep { opacity: 0.55; margin: 0 2px; }
/* Team-Kürzel (z. B. "B.AKTU" unter dem Copilot-Schriftzug): dezente Akzent-Pille */
.head-brand {
    display: inline-flex;
    align-items: center;
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.logo-badge-lg { width: 48px; height: 48px; border-radius: 14px; font-size: 1.35rem; }
/* Abschnitts-Überschrift innerhalb einer Seite (z. B. Azubi-Übersicht unter den Gruppen) */
.section-head { margin: 30px 0 14px; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 20px; align-items: center; }
.tab {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 10px 16px;
    font-weight: 600;
    font-size: 0.9rem;
    font-family: inherit;
    color: var(--text-muted);
    /* auch als <button> ohne Browser-Standardoptik (Rahmen/Hintergrund) */
    background: none;
    border: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    border-radius: 10px 10px 0 0;
    transition: color 0.15s ease, background 0.15s ease;
}
.tab:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
/* Zweite Ebene unter einer Tab-Leiste (Einstellungen → Allgemein →
   Qualitätssicherung: die Untertabs des QS-Panels). Bewusst kleiner und ohne
   eigene Trennlinie – zwei gleich starke Leisten übereinander liest niemand.
   Der aktive Reiter wird zur Pille, weil die Unterstreichung der Leiste
   darüber gehört. Farben aus den Tokens, gilt also in Dark und Light. */
.tabs.tabs-sub { border-bottom: 0; margin: -8px 0 18px; gap: 2px; flex-wrap: wrap; }
.tabs-sub .tab { padding: 6px 12px; font-size: 0.84rem; border-radius: 999px; margin-bottom: 0; }
.tabs-sub .tab.active { color: var(--accent); background: var(--accent-soft); border-bottom-color: transparent; }

/* Zahl an einem Tab (z. B. offenes Feedback in der Hilfe): dezente Pille, im
   aktiven Tab in der Akzentfarbe – sie zählt Arbeit, warnt aber nicht. */
.tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
}
.tab.active .tab-count { background: var(--accent-soft); border-color: transparent; color: var(--accent); }

/* ---------- Karten ---------- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 20px;
    box-shadow: var(--shadow-sm);
    transition: background-color 0.25s ease, border-color 0.25s ease;
}
/* HOVER-REGEL (12.08.2026): Flächen – Karten, Zeilen, Listeneinträge,
   Tabellenzellen – heben sich beim Überfahren NUR über den Hintergrund
   (--surface-hover) ab, nie über einen farbigen Rahmen. Einen Akzentrahmen
   bekommen ausschließlich Bedienelemente (Knöpfe, Chips, Eingabefelder,
   Farbfelder). Sonst wirkt die Oberfläche unruhig, weil jede Fläche beim
   Überfahren „aufblitzt". */
.card-narrow { max-width: 640px; }

/* Karten-Überschriften: heben sich als Sektions-Header vom Inhalt ab –
   Icon in Akzentfarbe, Trennlinie darunter (Dark & Light via Variablen) */
.card > h2 {
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text);
}
.card > h2 svg { color: var(--accent); }
.card > h2 .muted { text-transform: none; letter-spacing: normal; font-weight: 500; }

.grid { display: grid; gap: 20px; }
.grid-sidebar { grid-template-columns: 2fr 1fr; align-items: start; }
.grid-profile { grid-template-columns: 1fr 2fr; align-items: start; } /* Infos 4/12, Timeline 8/12 */
/* **Beide Spalten dürfen schrumpfen.** Raster-Felder haben von sich aus
   `min-width: auto` – ein einziger nicht umbrechender Inhalt (eine lange Zeile
   ohne Umbruch, eine breite Tabelle) macht die Spalte dann breiter als das
   Fenster, und die GANZE Seite bekommt einen waagerechten Rollbalken. Genau das
   ist am 04.09.2026 mit der Liste „Zuletzt passiert" passiert. */
.grid-profile > .stack { min-width: 0; }
/* Nur die LINKE Info-Spalte scrollt beim Lesen der Timeline oben mit (wie rechts
   auf dem Dashboard); wird sie – aufgeklappt – höher als der Bildschirm, scrollt
   sie intern. Wichtig: :first-child, sonst erwischt die Regel auch die rechte
   Spalte (das Logbuch-Panel ist ebenfalls ein .stack) und die wirkt wie ein iframe. */
.grid-profile > .stack:first-child {
    position: sticky;
    top: 76px;
    max-height: calc(100vh - 92px);
    overflow-y: auto;
    scrollbar-width: thin;
}
@media (max-width: 900px) {
    .grid-profile > .stack:first-child { position: static; max-height: none; overflow: visible; }
}

/* Einklappbare Info-Karten (Profil): Kopf = <summary> mit Kompakt-Info + Pfeil.
   Raster statt einer Zeile (14.08.2026): in der schmalen rechten Spalte (~300px)
   passten Titel + Kompakt-Info nicht nebeneinander. Die Überschrift schrumpfte,
   ihr Icon wurde auf 0 zusammengedrückt und der Text lief über die Info –
   Titel, Badge und Info lagen übereinander. Jetzt: Zeile 1 = Titel + Pfeil,
   Zeile 2 = Kompakt-Info. Kann nicht mehr überlappen, egal wie schmal. */
details.card-collapse > summary {
    list-style: none;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 10px;
    row-gap: 3px;
    cursor: pointer;
}
details.card-collapse > summary::-webkit-details-marker { display: none; }
details.card-collapse > summary h2 {
    margin: 0; padding: 0; border: 0;
    grid-column: 1; grid-row: 1;
    min-width: 0;
}
details.card-collapse > summary .collapse-caret { grid-column: 2; grid-row: 1; }
details.card-collapse > summary .collapse-info {
    grid-column: 1 / -1; grid-row: 2;
    max-width: 100%;
}
/* Ist die Karte offen, stehen die Werte ohnehin darunter – dann keine Kompakt-Info */
details.card-collapse[open] > summary .collapse-info { display: none; }
details.card-collapse[open] > summary { margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.collapse-info {
    font-size: 0.74rem; color: var(--text-muted); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; max-width: 55%;
    flex-shrink: 1;
}
.collapse-caret { display: inline-flex; color: var(--text-muted); flex-shrink: 0; transition: transform 0.2s ease; transform: rotate(-90deg); }
details.card-collapse[open] > summary .collapse-caret { transform: rotate(90deg); }
details.card-collapse > summary:hover .collapse-caret { color: var(--accent); }

/* Dashboard: Timeline links (8/12), Info-Karten rechts (4/12) */
/* Timeline 60 %, daneben 40 % für Ereignisse und Abwesenheiten (Wunsch 18.08.2026 –
   in 1/3 wurden die beiden Karten zu eng). */
.grid-dashboard { grid-template-columns: 3fr 2fr; align-items: start; gap: 26px; }
/* Rechte Spalte (Ereignisse & Abwesenheiten) bleibt beim Scrollen der Timeline
   oben angepinnt (76px = Höhe der Sticky-Topbar + etwas Luft) */
.grid-dashboard > .stack { position: sticky; top: 76px; }
.stack { display: flex; flex-direction: column; gap: 20px; }

/* Trend-Kachel: Mini-Verlauf rechts außen, Text behält den Vorrang */
/* (Kaputter Kommentar der früheren Trend-Kachel – 17.08.2026 entfernt.) */
#evCard { scroll-margin-top: 80px; } /* Anker landen unter der Sticky-Topbar */

/* Logbuch-Filter-Chips */
/* Zähler-Bubble in einem Filter-Chip (Gruppen-Reiter auf /auszubildende) */
.tl-chip-n {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 17px; padding: 0 5px; margin-left: 5px;
    border-radius: 999px; background: var(--surface-2); color: var(--text-muted);
    font-size: 0.68rem; font-weight: 700;
}
.tl-chip.active .tl-chip-n { background: rgba(255, 255, 255, 0.22); color: inherit; }

.tl-chips { display: flex; gap: 6px; margin: 2px 0 12px; flex-wrap: wrap; }
.tl-chip {
    font: inherit; font-size: 0.8rem; font-weight: 600;
    padding: 4px 12px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--border); background: var(--surface-2); color: var(--text-muted);
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
/* text-decoration: none gilt auch für Chips, die <a> sind (z. B. Monate/Quartale
   auf der Zielerreichung) – ein Chip ist ein Bedienelement, kein Textlink. */
.tl-chip, .tl-chip:hover { text-decoration: none; }
.tl-chip:hover { color: var(--text); border-color: var(--accent); }
.tl-chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }

/* 7-Tage-Streifen in der Ereignis-Karte */
/* minmax(0, …): die sieben Tage dürfen auf schmalen Bildschirmen schrumpfen */
.week-strip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin: 2px 0 14px; }
.ws-day {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    padding: 6px 2px 5px; border-radius: 10px; border: 1px solid transparent;
}
.ws-day.ws-today { background: var(--accent-soft); border-color: var(--accent); }
/* Sa/So sind keine Arbeitstage – sichtbar, aber zurückgenommen */
.ws-day.ws-weekend { opacity: 0.45; }
.ws-day.ws-weekend.ws-today { opacity: 1; }
.ws-wd { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); }
.ws-num { font-size: 0.82rem; font-weight: 600; line-height: 1.1; }
.ws-dot { width: 5px; height: 5px; border-radius: 50%; background: transparent; }
.ws-day.ws-has .ws-dot { background: var(--accent); }
/* Die eigene Geburtstagskarte in der Nebenspalte ist am 18.08.2026 entfallen –
   Geburtstage stehen jetzt hervorgehoben in der Ereignisliste (.deadline-list li.is-bday). */

/* ---------- Tabellen ---------- */
.table-wrap { overflow-x: auto; margin-top: 8px; }
.table { width: 100%; border-collapse: collapse; }
.table th {
    text-align: left;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
}
.table td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
.table tbody tr { transition: background 0.12s ease; }
.table tbody tr:hover { background: var(--surface-hover); }
.table-click tbody tr { cursor: pointer; }
.row-muted { opacity: 0.55; }

/* ---------- Benutzerliste ---------- */
.user-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.user-item {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 12px 14px;
}
.user-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.user-info { display: flex; flex-direction: column; min-width: 0; }
.user-info .muted { font-size: 0.8rem; }
.user-badges { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.user-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}
.user-actions form { margin: 0; }

/* Modul-Rechte pro Mitarbeiter (Einstellungen → Benutzer) */
.module-access {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
    font-size: 0.85rem;
}
.check-label.check-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    color: var(--text);
    cursor: pointer;
}

/* Modul Qs: Das Dashboard bringt eigene Styles mit (assets/css/qs.css,
   gescoped unter #qs-app) – hier bewusst nichts weiter. */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--accent-gradient);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    margin-right: 8px;
    vertical-align: middle;
    flex-shrink: 0;
}
.avatar-lg { width: 42px; height: 42px; font-size: 0.95rem; }

/* ---------- Ablegefläche für Dateien (Import) ----------
   Gemeinsamer Baustein: gestrichelter Rahmen, Hover und "over"-Zustand beim
   Ziehen. .slim zieht die Fläche zusammen, sobald Dateien geladen sind. */
.dropzone {
    border: 2px dashed var(--border);
    border-radius: 14px;
    padding: 34px 16px;
    text-align: center;
    cursor: pointer;
    background: var(--surface-2);
    transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone:hover { border-color: var(--accent); background: var(--surface-hover); }
.dropzone.over { border-color: var(--accent); background: var(--accent-soft); }
.dz-ico { font-size: 30px; line-height: 1; }
.dz-t { font-weight: 700; margin-top: 8px; }
.dz-s { font-size: 0.78rem; color: var(--text-muted); margin-top: 2px; }
.dropzone.slim { padding: 14px 16px; }
.dropzone.slim .dz-ico { font-size: 20px; }
.dropzone.slim .dz-t { font-size: 0.85rem; margin-top: 4px; }
.dropzone.slim .dz-s { display: none; }

/* ---------- Dezente Textaktion neben einer Überschrift ----------
   Kein Rahmen, kleine Schrift, Akzentfarbe beim Überfahren – dieselbe Idee wie
   „Alle ansehen“ in den Topbar-Panels. Benutzt u. a. im QS-Projekt-Popup
   (MEGA-Report, Vertrag). */

/* ---------- Badges ---------- */
.badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.76rem;
    font-weight: 600;
    white-space: nowrap;
}
.badge-positive, .badge-status-active { background: var(--positive-soft); color: var(--positive); }
.badge-negative, .badge-status-left { background: var(--negative-soft); color: var(--negative); }
.badge-neutral { background: var(--neutral-soft); color: var(--neutral); }
.badge-status-hired, .badge-role { background: var(--accent-soft); color: var(--accent); }
.badge-status-inactive { background: var(--neutral-soft); color: var(--neutral); }
/* Nur für Admins sichtbare Gruppe (is_hidden) – dezenter Hinweis in der Übersicht */
.badge-hidden { background: var(--neutral-soft); color: var(--text-muted); margin-left: 8px; }

/* ---------- Buttons ---------- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 9px 16px;
    border-radius: 10px;
    border: 1px solid transparent;
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    line-height: 1.5; /* <button> und <a> gleich hoch (Buttons haben sonst eine niedrigere UA-Zeilenhöhe) */
    cursor: pointer;
    background: none;
    color: var(--text);
    transition: transform 0.1s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(0.98); }

.btn-primary {
    background: var(--accent-btn-gradient);
    color: #fff;
    box-shadow: var(--shadow-sm);
}
.btn-primary:hover { box-shadow: var(--shadow); filter: brightness(1.06); }

.btn-ghost { border-color: var(--border); color: var(--text-muted); }
.btn-ghost:hover { background: var(--surface-hover); color: var(--text); }

/* Löschen-Knopf in Popups: rote Schrift auf ruhiger Fläche (Popup-Standard
   13.08.2026 – vorher hatte er nur einen Hover-Zustand und sah dadurch in
   Popups wie normaler Text aus). Zusammen mit .btn-ghost gewinnt weiter das
   Grau der Umrandung, das Rot kommt dort erst beim Überfahren. */
/* Löschen: als richtiger Knopf mit rotem Rahmen (Wunsch 19.08.2026 – vorher war
   nur roter Text da, das sah aus wie ein Link), beim Hovern voll rot mit weißer
   Schrift. Die kleinen Icon-Varianten in Listen (.btn-ghost.btn-danger-ghost)
   bleiben absichtlich rahmenlos und grau, sonst wären Listen voller roter Kästen. */
.btn-danger-ghost {
    color: var(--negative);
    border-color: color-mix(in srgb, var(--negative) 55%, transparent);
    background: color-mix(in srgb, var(--negative) 8%, transparent);
}
.btn-danger-ghost:hover {
    background: var(--negative);
    border-color: var(--negative);
    color: #fff;
}
.btn-ghost.btn-danger-ghost { color: var(--text-muted); border-color: transparent; background: none; }
.btn-ghost.btn-danger-ghost:hover { background: var(--negative-soft); color: var(--negative); border-color: transparent; }

/* Voll eingefärbter Gefahren-Button (z. B. "Alle Datensätze löschen") */
.btn-danger { background: var(--negative); color: #fff; box-shadow: var(--shadow-sm); }
.btn-danger:hover { box-shadow: var(--shadow); filter: brightness(1.08); }
.btn-danger:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }

/* Hervorgehobene "Alle Datensätze"-Karte (Einstellungen → Datensätze, rechte Spalte) */
.purge-all {
    border-color: color-mix(in srgb, var(--negative) 35%, transparent);
    background: var(--negative-soft);
}
/* Kein align-self: start hier! Die Karte sitzt in .stack (flex-direction: column),
   dort wirkt align-self auf die BREITE – die Karte schrumpfte dadurch auf ihren
   Inhalt statt die Spalte auszufüllen. Gegen vertikales Strecken genügt das
   align-items: start am .grid-sidebar. */
.purge-all-btn { width: 100%; justify-content: center; }

.btn-sm { padding: 5px 10px; font-size: 0.82rem; border-radius: 8px; }
.btn-block { width: 100%; justify-content: center; }
.btn-icon { padding: 8px; }
.btn-sm.btn-icon { padding: 5px 7px; }

.action-row { display: inline-flex; gap: 4px; align-items: center; }
/* Kopf-Aktionen (mehrere Buttons im Seitenkopf): mehr Abstand */
.action-row.head-actions { gap: 12px; }
.action-row form { display: inline-flex; margin: 0; }

/* ---------- Formulare ---------- */
.form { display: flex; flex-direction: column; gap: 14px; }
.form-tight { gap: 10px; margin-bottom: 18px; }
.form label { display: flex; flex-direction: column; gap: 5px; font-weight: 600; font-size: 0.86rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Checkbox-Zeile (z. B. Einstellungen → Gruppen → Dashboard-Anzeige)
   Farben über Custom Properties → funktioniert in Dark- und Lightmode */
.form label.check-label { flex-direction: row; align-items: center; gap: 10px; cursor: pointer; }
.check-label input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }

/* Datum-Schnellauswahl (Chips in Formularen) */
.quick-dates { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 4px 11px;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.chip:hover { border-color: var(--accent); color: var(--text); }
.chip.active {
    border-color: var(--accent);
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 12%, transparent);
}

input, select, textarea {
    font-family: inherit;
    font-size: 0.92rem;
    color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 12px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    width: 100%;
}
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { resize: vertical; }

input:disabled { opacity: 0.6; cursor: not-allowed; }

/* Segmented Control (Pflicht-Bewertung bei Anmerkungen) */

.seg { display: flex; gap: 8px; }
.seg input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.seg label {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--text-muted);
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.seg label:hover { background: var(--surface-hover); }
.seg input:focus-visible + label { box-shadow: 0 0 0 3px var(--accent-soft); }
.seg input:checked + label.seg-positive { background: var(--positive-soft); color: var(--positive); border-color: var(--positive); }

.seg input:checked + label.seg-negative { background: var(--negative-soft); color: var(--negative); border-color: var(--negative); }

.filter-bar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 6px; }
.filter-bar select { width: auto; }
.input-icon { position: relative; flex: 1; min-width: 200px; }
.input-icon svg {
    position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
    color: var(--text-muted); pointer-events: none;
}
.input-icon input { padding-left: 36px; }

/* ---------- Definition-Listen ---------- */
.def-list { display: grid; grid-template-columns: auto 1fr; gap: 6px 18px; margin: 0; }
.def-list dt { color: var(--text-muted); font-size: 0.86rem; }
.def-list dd { margin: 0; }

/* Gestapelte Variante: Begriff klein über dem Inhalt */
.def-stack { grid-template-columns: 1fr; gap: 0; }
.def-stack dt { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.04em; margin-top: 12px; }
.def-stack dt:first-child { margin-top: 0; }
.def-stack dd { margin-top: 2px; }

/* Arbeitsmodell-Box: bei einer Sonderregelung steht der Wert der Gruppe klein
   unter dem abweichenden Wert (14.08.2026) – so ist auf einen Blick klar, WAS
   abweicht, ohne in die Gruppe wechseln zu müssen. Kein Gold: der Stern daneben
   markiert die Abweichung, Gold bleibt den Fälligkeiten. */
.wt-orig {
    display: block;
    margin-top: 3px;
    font-size: 0.74rem;
    color: var(--text-muted);
    white-space: normal;
}
.wt-same { margin: 12px 0 0; font-size: 0.78rem; }

/* ---------- Timeline (Anmerkungen) ---------- */
.timeline { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.timeline-item {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--neutral);
    border-radius: 12px;
    padding: 12px 14px;
    /* Bewusst KEINE fadeIn-Animation: sie ließ Einträge bei jedem
       Seitenaufbau kurz "aufblitzen" (Systemmeldungen hatten sie nicht) */
}
.timeline-item p { margin: 6px 0 0; }
.timeline-item.note-positive { border-left-color: var(--positive); }
.timeline-item.note-negative { border-left-color: var(--negative); }
.timeline-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.timeline-head form { margin-left: auto; }
.timeline-trainee { font-weight: 600; color: var(--accent); }
.timeline-trainee:hover { text-decoration: none; }
/* Gruppen-Notizen: Name in Gold, passend zum Dot-Icon */
/* Gruppen-Notizen: Label in der Akzentfarbe (13.08.2026 von Gold umgestellt –
   Wunsch Sebastian: „schön in der gewählten primary-farbe") */
.timeline-group { color: var(--accent); }
.timeline-compact .timeline-item { padding: 10px 12px; }
.timeline-compact p { font-size: 0.88rem; }

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
}

/* ---------- Historie-Liste ---------- */
.history-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.history-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 12px;
}

.details summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--accent);
    margin: 12px 0;
    user-select: none;
}

/* Aufklappbare Formular-Bereiche (z. B. Gruppen-Einstellungen):
   trennen Themenblöcke sauber und skalieren für künftige Bereiche */

/* ---------- Eingebettete Meldungsboxen ----------
   Nur noch auf Login-Seite & Installer im Einsatz – in der App selbst
   erscheinen alle Meldungen als Toast unten am Browserrand. */
.flash {
    padding: 11px 16px;
    border-radius: 12px;
    margin-bottom: 14px;
    font-weight: 500;
    border: 1px solid transparent;
    animation: fadeIn 0.25s ease;
}
.flash-success { background: var(--positive-soft); color: var(--positive); border-color: color-mix(in srgb, var(--positive) 30%, transparent); }
.flash-error { background: var(--negative-soft); color: var(--negative); border-color: color-mix(in srgb, var(--negative) 30%, transparent); }

.empty-state { color: var(--text-muted); text-align: center; padding: 24px 12px; }

/* Dezenter Zusatz in Karten-Überschriften (z. B. "nächste 30 Tage") */
.h-hint { font-size: 0.72rem; font-weight: 400; color: var(--text-muted); margin-left: 2px; }

/* Aktions-Button im Toast (aktuell nur "Rückgängig" beim verzögerten Löschen) */
.toast .undo-btn {
    flex: none;
    align-self: center;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
    border-radius: 8px;
    color: var(--accent);
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    padding: 5px 10px;
    white-space: nowrap;
}
.toast .undo-btn:hover { background: var(--accent-soft); border-color: var(--accent); }

.error-code {
    font-size: 4rem;
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    justify-content: center;
}

/* ---------- Theme-Toggle ---------- */
/* Theme-Umschalter: zwei Icons in einer Pille, das aktive Theme ist
   mit einem Akzent-Kreis hinterlegt (kein wandernder Punkt mehr) */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface);
    cursor: pointer;
    color: var(--text-muted);
    transition: border-color 0.15s ease;
}
.theme-toggle:hover { border-color: var(--accent); }
.theme-toggle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    transition: background 0.2s ease, color 0.2s ease;
}
[data-theme="light"] .theme-toggle .icon-sun,
[data-theme="dark"] .theme-toggle .icon-moon {
    background: var(--accent-gradient, var(--accent));
    color: #fff;
}

/* ---------- Schnellsuche-Popup ---------- */
[data-theme="dark"] { --overlay: rgba(0, 0, 0, 0.55); }
[data-theme="light"] { --overlay: rgba(28, 35, 51, 0.35); }

.search-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: none;
    align-items: flex-start;
    justify-content: center;
    padding: 12vh 16px 0;
    background: var(--overlay);
    backdrop-filter: blur(3px);
}
.search-overlay.show { display: flex; }

.search-modal {
    width: 100%;
    max-width: 520px;
    padding: 14px;
    box-shadow: var(--shadow);
    animation: fadeIn 0.15s ease;
}

.search-results {
    list-style: none;
    margin: 10px 0 0;
    padding: 0;
    /* Seit dem Such-Ausbau kommen Treffer aus bis zu neun Bereichen – die Liste
       darf deshalb höher werden, bleibt aber im Bild (auch auf kleinen Fenstern). */
    max-height: min(56vh, 460px);
    overflow-y: auto;
}
.search-results li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 10px;
    cursor: pointer;
}
.search-results li strong { flex: 1; }
.search-results li.active { background: var(--accent-soft); }
.search-results .search-empty { cursor: default; color: var(--text-muted); justify-content: center; }
.search-results .search-empty:hover { background: none; }

.search-hint { margin-top: 10px; font-size: 0.76rem; text-align: center; }

kbd.kbd-hint {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 1px 6px;
    font-size: 0.72rem;
    font-family: inherit;
    color: var(--text-muted);
}
/* Kürzel-Badge in einem Knopf (z. B. „Zurücksetzen X“) – gilt seit 13.08.2026
   auch in der QS, damit die Filter-Knöpfe überall gleich aussehen. */
.btn .kbd-hint { margin-left: 6px; font-weight: 700; }
/* Auf dem Akzentverlauf (.btn-primary, z. B. „Eintrag erstellen N“) braucht das
   Kürzel eigene Farben – die Flächenfarben der Oberfläche würden dort als Fleck
   auffallen. Deshalb halbtransparentes Weiß, bewusst zurückgenommen (17.08.2026). */
.btn-primary .kbd-hint {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(255, 255, 255, 0.28);
    color: rgba(255, 255, 255, 0.72);
}
.btn-primary:hover .kbd-hint { color: rgba(255, 255, 255, 0.9); }
@media (max-width: 760px) { kbd.kbd-hint { display: none; } }

/* ---------- Detail-Popup (Einträge) ---------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: none;
    align-items: flex-start;
    justify-content: center;
    /* Gleicher Abstand nach oben wie das Such-Popup (12vh) */
    padding: 12vh 16px 6vh;
    background: var(--overlay);
    backdrop-filter: blur(3px);
    overflow-y: auto;
}
.modal-overlay.show { display: flex; }
/* Scrollen bleibt im Popup: am oberen/unteren Ende springt die Seite dahinter
   nicht weiter (Scroll-Chaining aus, zusätzlich sperrt app.js die Seite) */
.modal-overlay, .search-overlay { overscroll-behavior: contain; }
html.modal-open, html.modal-open body { overflow: hidden; }

.modal { position: relative; width: 100%; max-width: 560px; padding: 22px; animation: fadeIn 0.15s ease; }
/* Eintrag-Popup: mehr Platz als die schmalen Info-Popups */
.modal-entry { max-width: 720px; }
/* Schmales Popup für kurze Formulare und Info-Listen (Filter, Import, Ranglisten).
   Lag bis 13.08.2026 nur gescoped in qs.css – jetzt gilt es für alle Module,
   damit die Filter-Popups von QS und Zielerreichung gleich breit sind. */
.modal-narrow { max-width: 460px; }
/* Knopfzeile am Ende eines Filter-Popups: Anwenden + Zurücksetzen, gleich breit */
.filter-actions { display: flex; gap: 10px; margin-top: 18px; }
.filter-actions .btn { flex: 1; justify-content: center; }
/* Eintrag-Formular: die Felder liegen in abgesetzten Bereichen mit eigenem
   Hintergrund – gleiche Idee wie die Abschnitte im QS-Projekt-Popup */
.modal-entry .note-form { gap: 16px; margin-bottom: 4px; }
/* ---------- Popup-Standard (13.08.2026, „Variante A" – VERBINDLICH) ----------
   Alle Popups sind gleich aufgebaut, damit sie aus einem Guss wirken:
     1. Hauptüberschrift ganz oben in .modal-head – nur Text, KEIN Icon
     2. Inhalte kategorisiert in .modal-sec-Boxen (gefüllt + gerahmt)
     3. Jede Box hat eine .modal-sec-h: klein, Großbuchstaben, Akzentverlauf
     4. Keine Beschreibungstexte – stattdessen kurze Platzhalter im Feld
     5. Knöpfe nur mit Text (keine Icons): Hauptaktion .btn-primary,
        Nebenaktion .btn-accent, Löschen .btn-danger-ghost
   In der QS sind .psec / .psec-h (qs.css) genau diese Boxen.                */
.modal-sec {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface-2);
}
/* Überschrift einer Bereichs-Box (13.08.2026, VERBINDLICH für alle Popups):
   Inhalte werden kategorisiert, jede Kategorie bekommt eine Box mit Überschrift.
   Hervorgehoben im persönlichen Akzentverlauf – background-clip: text färbt die
   Schrift mit dem Gradienten, deshalb steht color: transparent dahinter. Der
   Fallback (color) greift, wenn ein Browser background-clip nicht kann. */
.modal-sec-h {
    margin: 0;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
@supports not (background-clip: text) {
    .modal-sec-h { -webkit-text-fill-color: currentColor; }
}
/* Überschrift zählt nicht als eigenes Feld: etwas engerer Abstand nach unten */
.modal-sec > .modal-sec-h { margin-bottom: -4px; }

/* Hier stand bis zum 13.08.2026 der Kommentar-Marker (.goal-cell-note) einer
   Matrix-Zelle. Die Kommentarfunktion der Zielwerte ist entfallen, der Marker
   damit auch. position: relative bleibt – Zellen setzen absolute Kinder. */
.goal-cell { position: relative; }

/* Die Bereichs-Boxen gibt es in allen Formular-Popups (Eintrag erstellen,
   Neue Notiz, Notiz bearbeiten, Feedback erstellen) – ein Abstand zwischen
   zwei Boxen, egal in welchem Popup sie stecken. */
.modal-sec + .modal-sec, .nb-edit .modal-sec + .modal-sec { margin-top: 14px; }
.modal-sec > .field, .modal-sec > label { margin-bottom: 0; }

.modal-form .modal-sec + .modal-actions-row, .nb-edit .modal-sec + .action-row { margin-top: 16px; }
.modal-entry .form-row { gap: 16px; }
.modal-entry .note-form > .note-submit-row { margin-top: 2px; }
/* Vergrößert: Popup nutzt fast den ganzen Bildschirm, alle Felder bleiben sichtbar */
.modal.is-big { max-width: min(1120px, 94vw); }
.modal-overlay:has(.modal.is-big) { padding-top: 2vh; padding-bottom: 2vh; }
/* Schreibfläche nimmt im großen Modus den Platz, der nach den übrigen Feldern
   übrig bleibt – so bleibt der Speichern-Knopf ohne Scrollen sichtbar */
.modal.is-big .rte-area,
.modal.is-big .editor-wrap textarea {
    min-height: clamp(180px, calc(94vh - 620px), 660px);
    max-height: calc(94vh - 600px);
}

/* Kopfbereich der Popups: hebt sich mit Hintergrund-Band und Trennlinie
   klar vom Inhalt ab (zieht sich bis an die Popup-Ränder) */
.modal .modal-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: -22px -22px 20px;
    padding: 18px 56px 16px 22px; /* rechts Platz für den Schließen-Button */
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    border-radius: 16px 16px 0 0;
    font-size: 1.02rem;
}

/* Überschrift im Popup-Kopf: überall gleich, egal ob als <strong> oder <h2>
   geschrieben (Popup-Standard, siehe oben bei .modal-sec) */
.modal .modal-head strong,
.modal .modal-head h2 {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 1.02rem;
    font-weight: 700;
    text-transform: none;
    letter-spacing: normal;
    color: var(--text);
}

/* Bearbeiten-Formular im Detail-Popup: luftigere Abstände */
.modal #noteEditForm { margin-top: 4px; gap: 16px; }
.modal-close {
    position: absolute;
    top: 10px;
    right: 12px;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    padding: 4px 10px;
    border-radius: 8px;
}
.modal-close:hover { background: var(--surface-hover); color: var(--text); }

.note-content {
    white-space: pre-line;
    margin: 14px 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 14px 16px;
}
/* ---------- Mini-Editor (optionale Formatierung im Eintrag-Formular) ---------- */
.editor-wrap { display: flex; flex-direction: column; gap: 7px; }
.editor-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.editor-label { font-weight: 600; font-size: 0.86rem; }
.editor-tools { display: inline-flex; align-items: center; gap: 4px; }
.editor-expand {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 26px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: pointer;
}
.editor-expand:hover { color: var(--accent); border-color: var(--accent); }
.editor-expand.active { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
/* Textfeld: von Haus aus deutlich mehr Schreibfläche */
.editor-wrap textarea { min-height: 150px; resize: vertical; }
.editor-toggle {
    background: none;
    border: none;
    padding: 2px 4px;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--accent);
    cursor: pointer;
}
.editor-toggle:hover { text-decoration: underline; }

.rte {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    overflow: hidden;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.rte:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.rte-toolbar {
    display: flex;
    align-items: center;
    gap: 2px;
    flex-wrap: wrap;
    padding: 7px 9px;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 1;
}
.rte-sep { width: 1px; align-self: stretch; margin: 2px 6px; background: var(--border); }
.rte-toolbar button {
    min-width: 30px;
    padding: 3px 8px;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 0.82rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.rte-toolbar button:hover { background: var(--surface-hover); color: var(--text); }
.rte-toolbar button.active { background: var(--accent-soft); color: var(--accent); }
.rte-toolbar button sub { font-size: 0.7em; }
.rte-area { padding: 12px 14px; min-height: 150px; overflow-y: auto; }
.rte-area:focus { outline: none; }
.rte-area ul, .rte-area ol { margin: 6px 0; padding-left: 22px; }

/* Formatierte Einträge im Detail-Popup (HTML mit Tag-Whitelist) */
.note-content-html { white-space: normal; }
.note-content-html p, .note-content-html div { margin: 0 0 8px; }
.note-content-html ul, .note-content-html ol { margin: 8px 0; padding-left: 22px; }
.note-content-html li { margin-bottom: 3px; }

/* Quelle/Link im Eintrag-Popup */
.note-link {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: -6px 0 14px;
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--accent);
    max-width: 100%;
}
.note-link span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.note-link svg { flex-shrink: 0; }

.note-meta-card {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.84rem;
    line-height: 1.4;
}
.note-meta-card .muted { font-size: 0.8rem; }

.edited-hint { font-size: 0.74rem; color: var(--text-muted); font-style: italic; }
.comment-count { display: inline-flex; align-items: center; gap: 3px; font-size: 0.78rem; }

/* Klickbare Einträge: nur ein dezenter Hintergrund-Hover (kein farbiger Rahmen) */
.timeline-click { cursor: pointer; transition: background 0.15s ease; }
.timeline-click:hover { background: var(--surface-hover); }

/* Dashboard-Timeline: durchgezogene Linie links, Dots an den Einträgen.
   Dot-Farbe = Bewertung, Icon im Dot = Typ (Anmerkung/Gesprächsprotokoll/System).
   Farben via Custom Properties → Dark- & Lightmode. */
.timeline-item { position: relative; }
.timeline-compact { position: relative; padding-left: 40px; }
.timeline-compact::before {
    content: '';
    position: absolute;
    left: 14px; /* Dot-Mitte (15px = 1px Item-Rand + halbe Dot-Breite) minus halbe Linienbreite */
    top: 8px;
    bottom: 8px;
    width: 2px;
    border-radius: 2px;
    background: var(--border);
}
/* Farbige linke Ränder braucht es hier nicht mehr – das übernimmt der Dot */
.timeline-compact .timeline-item,
.timeline-compact .timeline-item.note-positive,
.timeline-compact .timeline-item.note-negative { border-left: 1px solid var(--border); }
/* Wichtig: gleiche Randbreite (1px) wie normale Einträge, sonst sitzen die Dots
   der Systemmeldungen 2px weiter rechts (Dots sind relativ zum Innenrand positioniert) */
.timeline-compact .timeline-item.timeline-event { border-left: 1px solid transparent; }
/* Notizen an die Gruppe selbst sahen bis zum 03.09.2026 anders aus als alle
   anderen Karten: getönte Fläche und Rahmen in der Akzentfarbe (13.08.2026, in
   beiden Themes eigens gebaut). Das ist **ersatzlos entfallen** – Wunsch
   Sebastian: „die Box an sich bitte nicht farblich abändern gegenüber den
   anderen". Es genügt der größere Punkt links (`.tl-dot-team`), der die Zeile
   ohnehin heraushebt. Weniger Farbe im Verlauf heißt auch: die Bewertung
   (Positiv/Negativ) und der Akzent des Namens bleiben die einzigen Farbträger.
   **Nicht ohne Rücksprache neu bauen.** */
/* Dots: vollflächig gefüllt, Farbe = TYP des Eintrags (nicht mehr Bewertung).
   Anmerkung = Akzent, Gesprächsprotokoll = Violett, System = Grau, Gruppe = Gold. */
.tl-dot {
    position: absolute;
    left: -41px; /* 30px breit → Mitte bleibt auf der Linie */
    top: 7px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--neutral);
    border: none;
    color: #fff;
    z-index: 1;
}
.tl-dot-note { background: var(--accent); }
.tl-dot-protocol { background: var(--accent-2); }
/* Bewertung als dezentes Badge in der Kopfzeile (Neutral bleibt unbeschriftet) */
.tl-rating {
    font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
    padding: 1px 8px; border-radius: 999px; white-space: nowrap;
}
.tl-rating-positive { background: var(--positive-soft); color: var(--positive); }
.tl-rating-negative { background: var(--negative-soft); color: var(--negative); }
/* Leerer Zustand innerhalb einer Timeline (z. B. QS-Tab ohne Projekte) */
.timeline-empty { list-style: none; padding: 8px 0 4px; }

/* Obertabs innerhalb einer Karte (Logbuch | QS-Auswertung im Profil) */
.tabs-card { margin: -4px 0 16px; }

/* QS-Einträge im Profil: kleine, gefüllte Status-Punkte, mittig auf der Timeline-Linie
   (Linienmitte liegt bei -25px relativ zum Eintrag) */

/* Gefahrenzone (Bearbeiten-Modus im Profil): auffällig rot abgesetzt */
.danger-zone {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-top: 20px;
    border: 1px solid var(--negative);
    background: var(--negative-soft);
}
.danger-zone strong { color: var(--negative); }
.danger-zone-hint { color: var(--text-muted); font-size: 0.88rem; }
.danger-zone form { margin: 0; }

/* Bewertungs-Filter (Logbuch): Smiley-Icons rechts in der Filterzeile */
.tl-filter { align-items: center; }
.tl-rating { margin-left: auto; display: inline-flex; gap: 4px; }
/* Schalter „Systemmeldungen" (19.08.2026): eigene Ebene, deshalb abgesetzt hinter
   den Chips. Gilt nur noch fürs Logbuch (Profil/Gruppe) – dort schiebt ihn
   .tl-rating (margin-left:auto) nach rechts. Auf der Startseite steht seit dem
   31.08.2026 kein Schalter mehr in .tl-chips, sondern ein Icon-Knopf (.tl-ibtn). */
.tl-chips { align-items: center; }
.tl-filter .tl-sys { margin-left: 10px; padding-left: 12px; border-left: 1px solid var(--border); }
@media (max-width: 760px) {
    .tl-filter .tl-sys { margin-left: 0; padding-left: 0; border-left: 0; }
}
/* Umfang-Umschalter der Gruppen-Timeline: leicht abgesetzt von den Typ-Chips */
.tl-scope { display: inline-flex; gap: 6px; margin-left: 10px; padding-left: 12px; border-left: 1px solid var(--border); }
@media (max-width: 760px) { .tl-scope { margin-left: 0; padding-left: 0; border-left: 0; } }
.rate-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 5px 7px;
    border: 1px solid transparent;
    border-radius: 9px;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.rate-btn:hover { background: var(--surface-hover); }
.rate-btn.rate-positive:hover, .rate-btn.rate-positive.active { color: var(--positive); }
.rate-btn.rate-neutral:hover, .rate-btn.rate-neutral.active { color: var(--neutral); }
.rate-btn.rate-negative:hover, .rate-btn.rate-negative.active { color: var(--negative); }
.rate-btn.rate-positive.active { border-color: var(--positive); background: var(--positive-soft); }
.rate-btn.rate-neutral.active { border-color: var(--neutral); background: var(--neutral-soft); }
.rate-btn.rate-negative.active { border-color: var(--negative); background: var(--negative-soft); }

/* QS-Entwicklungs-Diagramm im Profil: Kopfzeile mit Trennlinie wie die Karten-Headlines */
.qs-chart-head {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}
.qs-chart-head h2 {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text);
}
.qs-chart-head h2 svg { color: var(--accent); }
/* Zwei Chip-Gruppen (Ansicht + Zeitraum) rechts im Diagramm-Kopf */
.qs-chart-switches { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* Kompakter Custom-Tooltip: ApexCharts-Hülle neutralisieren – gilt für ALLE
   Diagramme (Profil + QS-Auswertung), deren Inhalt copilotChartTip liefert */
.apexcharts-tooltip {
    background: var(--surface) !important;
    border: 1px solid var(--border) !important;
    box-shadow: var(--shadow) !important;
    border-radius: 10px !important;
}
.qs-chart-tip { padding: 8px 11px; font-size: 0.78rem; line-height: 1.5; color: var(--text); }
.qs-chart-tip .qct-head { font-weight: 700; margin-bottom: 4px; color: var(--text-muted); font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; }
.qs-chart-tip .qct-row { display: flex; align-items: center; gap: 7px; }
.qs-chart-tip .qct-row b { margin-left: auto; padding-left: 14px; font-variant-numeric: tabular-nums; }
.qs-chart-tip .qct-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
/* Detailzeile: gehört zur Zeile darüber (eingerückt, kleiner Punkt, gedämpft) */
.qs-chart-tip .qct-sub { padding-left: 15px; color: var(--text-muted); font-size: 0.94em; }
.qs-chart-tip .qct-sub .qct-dot { width: 6px; height: 6px; }
/* Legende: etwas Luft zwischen Farbpunkt und Text (ApexCharts-Standard sind 15px).
   Global, damit es auch im maximierten Diagramm-Popup und auf /qs greift. */
/* !important auch beim margin: ApexCharts setzt margin-left:-15px und injiziert
   sein Stylesheet erst beim Rendern – ohne !important gewinnt es. */
.apexcharts-legend-text { padding-left: 5px !important; margin-left: 0 !important; }

/* Beide Prüfseiten als Punktreihen im Profil (03.09.2026).
   Der Block stand vorher auf der QS-Seite (`.tov-*` in qs.css) und hat dort im
   Abnahmen-Modus die Tabelle verdrängt. Hier beantwortet er die Frage, die man
   im Profil stellt: „wie kam die Arbeit dieser Person zurück?"
   Punktreihe alt → neu, die letzten 20; bei wenig Platz brechen die Zeilen um
   (kein Kürzen per Skript wie früher – im Profil ist die Karte schmaler und ein
   Umbruch ist ehrlicher als heimlich weggelassene Punkte). */
.pqs {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.pqs-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pqs-tag { font-size: 0.72rem; color: var(--text-muted); flex: 0 0 78px; }
.pqs-pill {
    display: inline-block;
    min-width: 40px;
    text-align: center;
    font-size: 0.76rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 2px 8px;
}
.pqs-pill.g { background: var(--positive-soft); color: var(--positive); }
.pqs-pill.w { background: color-mix(in srgb, var(--gold) 15%, transparent); color: var(--gold); }
.pqs-pill.r { background: var(--negative-soft); color: var(--negative); }
.pqs-total { font-size: 0.76rem; color: var(--text-muted); margin-left: 2px; }
.pqs-dots { display: inline-flex; gap: 5px; align-items: center; flex-wrap: wrap; }
.pqs-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.pqs-dot.is-ok { background: var(--positive); }
.pqs-dot.is-warn { background: var(--gold); }
.pqs-dot.is-err { background: var(--negative); }
.pqs-keine { font-size: 0.7rem; color: var(--text-muted); }

/* Prominenter Weg in die QS-Auswertung (unter dem QS-Entwicklungs-Diagramm):
   Akzentverlauf wie die Hauptaktionen, Person/Gruppe ist dort schon gefiltert */
.qs-profile-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    margin-top: 16px;
    padding: 13px 20px;
    font-size: 0.95rem;
}
.qs-profile-btn-arrow { transition: transform 0.15s ease; }
.qs-profile-btn:hover .qs-profile-btn-arrow { transform: translateX(3px); }
.qs-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.78rem;
    white-space: nowrap;
}
.qs-pill-ok { background: var(--positive-soft); color: var(--positive); }
/* QS-Projektsuche im Such-Popup: Domain oben, darunter Datum/Status/Run/KdNr */
.search-item .search-qs { min-width: 0; }
.search-item .search-qs-domain { display: block; margin-bottom: 4px; word-break: break-all; }
.search-qs-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 3px 12px; font-size: 0.8rem; }
.search-qs-meta .qs-pill { font-size: 0.68rem; padding: 2px 8px; }
/* Fundstelle des Suchbegriffs: kleiner "Button-Look" mit dem Akzent-Verlauf */
.search-item mark.search-hl {
    background: var(--accent-btn-gradient);
    color: #fff;
    border-radius: 4px;
    padding: 0 3px;
    margin: 0 1px;
}
/* Bearbeiter-Name in QS-Einträgen auf der Gruppen-Seite */

/* Trefferzahl über den Ergebnis-Kategorien */
.search-count {
    font-size: 0.74rem;
    color: var(--text-muted);
    padding: 8px 10px 0;
}

/* ---------- Hilfe-Seite /help (Quick-Guide, Tastenkürzel, Feedback) ---------- */
.help-keys { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.help-keys td { padding: 9px 6px; border-bottom: 1px solid var(--border); vertical-align: top; }
.help-keys tr:last-child td { border-bottom: none; }
.help-keys td:first-child { white-space: nowrap; padding-right: 16px; }
kbd {
    display: inline-block;
    padding: 2px 7px;
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: 6px;
    background: var(--surface-2);
    font-family: inherit;
    font-size: 0.76rem;
}
/* Beschrifteter Notizbuch-Knopf in der Topbar: gleiche Höhe wie die Icon-Pillen.
   Ohne eigenen Rahmen – die Pille (.topbar-group) hat schon einen, zwei
   verschachtelte Rahmen sehen doppelt aus. */
.nb-open-btn { border-radius: 999px; gap: 6px; white-space: nowrap; font-size: 0.82rem; padding: 7px 13px; border-color: transparent; }
.nb-open-btn svg { flex-shrink: 0; }
/* Feedback-Tab auf /help: Tabelle mit Status, Text, Verfasser, Datum */
/* Ein Block je Status (Wird geprüft / Offen), Abstand zwischen den Blöcken */
.fb-sec { margin-bottom: 16px; }
.fb-sec .fb-table tbody tr:last-child td { border-bottom: none; }
.fb-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.fb-table th {
    text-align: left;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 700;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.fb-table td { padding: 12px 16px; border-bottom: 1px solid var(--border); vertical-align: top; }
.fb-table tr:last-child td { border-bottom: none; }
.fb-table tr:hover td { background: var(--surface-hover); }
/* Text nimmt den Platz, Verfasser und Datum bleiben schmal */
.fb-table th:nth-child(2), .fb-table td:nth-child(2) { width: 1%; white-space: nowrap; }
.fb-cell-text { line-height: 1.55; word-break: break-word; }
.fb-cell-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.fb-row-done .fb-cell-text { color: var(--text-muted); text-decoration: line-through; }

/* Vorschau + Detailzeile (19.08.2026): in der Übersicht steht eine Zeile,
   der ganze Text und der Verlauf kommen erst beim Aufklappen. Vorher füllte
   ein langes Feedback den halben Bildschirm. */
/* Damit die eine Zeile wirklich abschneidet und die Tabelle nicht breiter wird:
   die Textspalte bekommt max-width: 0 bei width: 100% (der Tabellen-Trick für
   text-overflow), die schmalen Spalten daneben behalten ihre Breite. */
.fb-table .fb-cell-text { width: 100%; max-width: 0; }
.fb-open {
    min-width: 0;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    padding: 0;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}
.fb-open:hover .fb-preview, .fb-open:focus-visible .fb-preview { color: var(--accent); }
.fb-chev { flex: none; display: inline-flex; color: var(--text-muted); transition: transform 0.16s ease; }
.fb-row.is-open .fb-chev { transform: rotate(90deg); color: var(--accent); }
/* Genau EINE Zeile (Wunsch Sebastian 19.08.2026): der Rest steht im Detail */
.fb-preview { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fb-detailrow td { background: var(--surface-2); }
.fb-detailrow[hidden] { display: none; }

/* Verlauf: wer hat wann erstellt, bearbeitet, geprüft, abgehakt */
.fb-log {
    margin: 12px 0 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 8px 18px;
    padding: 12px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
}
.fb-log-row { min-width: 0; }
.fb-log dt { font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 700; }
.fb-log dd { margin: 2px 0 0; display: flex; flex-wrap: wrap; gap: 4px 8px; font-size: 0.88rem; }
.fb-log dd .muted { font-variant-numeric: tabular-nums; }
.fb-log-row.is-empty dt { opacity: 0.65; }
/* Aktionen stehen als eine Reihe direkt unter dem Eintragstext */
.fb-table .fb-actions { margin-top: 10px; gap: 6px; flex-wrap: wrap; }
.fb-table .fb-actions form { margin: 0; display: inline-flex; }
.fb-table tr.is-editing td { background: var(--surface-hover); }
.fb-table tr.is-editing .fb-cell-txt { display: none; }
/* Bearbeiten direkt in der Zeile */
.fb-edit { display: flex; flex-direction: column; gap: 9px; }
.fb-edit[hidden] { display: none; }
.fb-edit textarea {
    width: 100%;
    resize: vertical;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 11px;
    color: var(--text);
    font: inherit;
    font-size: 0.9rem;
}
.fb-edit textarea:focus { outline: none; border-color: var(--accent); }
.fb-edit-btns { display: flex; align-items: center; gap: 8px; }
/* Erledigt-Box ganz unten: so zurückgenommen wie die Archiv-Zeile bei den
   Gruppen – ohne Kartenfläche, gestrichelt, leicht ausgegraut */
/* Blöcke im Feedback-Tab: Karte mit farbiger Kante, Punkt, Titel und Anzahl.
   (Hieß bis zum 02.09.2026 .fu-card* – der Name kam von den Wiedervorlagen,
   die Regeln gehören aber zum Feedback.) */
.fb-card { padding: 0; overflow: hidden; border-left: 3px solid var(--neutral); }

.fb-card > .fb-card-h {
    display: flex; align-items: center; gap: 9px;
    margin: 0; padding: 14px 18px;
    font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.fb-card-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--neutral); flex-shrink: 0; }

.fb-card-n {
    margin-left: auto;
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 22px; height: 20px; padding: 0 7px;
    border-radius: 999px; background: var(--surface); color: var(--text-muted);
    font-size: 0.72rem; letter-spacing: 0;
}
/* Erledigtes unten: zurückgenommen und eingeklappt (wie das Archiv bei den Gruppen) */
.fb-done-sep { border-top: 1px dashed var(--border); margin: 26px 4px 16px; }
.fb-done { padding: 0; border-style: dashed; }
.fb-done > summary {
    display: flex; align-items: center; gap: 11px;
    padding: 14px 18px; cursor: pointer; list-style: none;
    font-size: 0.9rem; color: var(--text-muted);
}
.fb-done > summary::-webkit-details-marker { display: none; }
.fb-done > summary:hover { color: var(--text); }
.fb-done[open] > summary { border-bottom: 1px solid var(--border); }
.fb-done > summary .fb-card-n { margin-left: auto; }
.fb-done-ico {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
    background: var(--positive-soft); color: var(--positive);
}
.fb-done-card { background: transparent; box-shadow: none; opacity: 0.75; }
.fb-done-card:hover, .fb-done-card[open] { opacity: 1; }
.fb-done-card > summary { cursor: pointer; }
.fb-done-card .fb-table { font-size: 0.85rem; }
.fb-done-card .fb-table th { background: transparent; }
/* Warum hier nichts zu bearbeiten ist (20.08.2026): „Wird geprüft" und
   „Erledigt" sperren Text und Löschen – das steht sichtbar am Eintrag, nicht
   in einem Tooltip. Nur für die, die ihn sonst ändern dürften. */
.fb-lock { display: flex; align-items: center; gap: 7px; margin: 10px 0 0;
    font-size: 0.82rem; color: var(--text-muted); }
.fb-lock svg { flex: none; opacity: 0.8; }
/* Hinweis im Popup „Feedback erstellen": bitte ein Thema je Eintrag */
.fb-new-hint { margin-top: -2px; }
/* Status-Badges entfallen – der Status steht in der Block-Überschrift */
/* Aktions-Badges unter dem Eintrag */
.fb-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.fb-badge {
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 600;
    border-radius: 999px;
    padding: 3px 10px;
    cursor: pointer;
    line-height: 1.4;
}
.fb-badge:hover { color: var(--text); background: var(--surface-hover); }
.fb-badge-danger:hover { color: var(--negative); border-color: var(--negative); background: var(--negative-soft); }
.fb-badge-check.active {
    color: var(--gold);
    background: color-mix(in srgb, var(--gold) 14%, transparent);
    border-color: color-mix(in srgb, var(--gold) 45%, transparent);
}
/* Erledigtes eingeklappt unten; Pfeil dreht sich beim Aufklappen */

/* Profil: Theme-Auswahl als Segmented Control (aktives Segment im Button-Verlauf),
   speichert sofort – daneben blendet kurz "Gespeichert" ein */
.theme-seg {
    display: inline-flex;
    gap: 4px;
    padding: 4px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    vertical-align: middle;
}
.theme-seg label { position: relative; cursor: pointer; }
.theme-seg input { position: absolute; opacity: 0; pointer-events: none; }
.theme-seg span {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 18px;
    border-radius: 999px;
    font-size: 0.88rem;
    color: var(--text-muted);
    transition: background 0.15s ease, color 0.15s ease;
}
.theme-seg span:hover { color: var(--text); }
.theme-seg input:checked + span {
    background: var(--accent-btn-gradient);
    color: #fff;
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}
.theme-save-hint {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 12px;
    font-size: 0.78rem;
    color: var(--positive);
    opacity: 0;
    transition: opacity 0.2s ease;
    vertical-align: middle;
}
.theme-save-hint.show { opacity: 1; }
/* Mehrere Regler in einer Karte (Profil → Kompakter Modus, 13.08.2026):
   je Zeile eine kleine Beschriftung links, der Umschalter rechts. */
.seg-rows { display: flex; flex-direction: column; gap: 14px; }
.seg-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 0; }
.seg-row-label { font-size: 0.86rem; font-weight: 600; color: var(--text-muted); min-width: 160px; }
.seg-row .theme-save-hint { margin-left: 0; }
@media (max-width: 560px) {
    .seg-row-label { min-width: 0; width: 100%; }
}
.qs-pill-warn { background: color-mix(in srgb, var(--gold) 16%, transparent); color: var(--gold); }
.qs-pill-err { background: var(--negative-soft); color: var(--negative); }
/* QS-Eintrag: Zeile 1 Domain + Status, Zeile 2 klein mit Datum/Run/KdNr inkl. Kopieren */

/* Typ-Filter rechts in der Chip-Zeile */

/* Interne Abnahmen: deutlich unpräsenter als finale QS */

/* Systemmeldungen: bewusst NICHT gefüllt – Umriss wie früher, damit sie
   sich von den vollflächigen Nutzer-Einträgen (Anmerkung/Protokoll) abheben */
.tl-dot-event { background: var(--surface-2); border: 2px solid var(--border); color: var(--text-muted); }
/* QS-Import: wie jede andere Systemmeldung grau im Umriss – erkennbar wird er
   am Import-Icon (siehe timeline_items.php) */
/* Gruppen-/Team-Notizen: Dot im Akzentverlauf und bewusst ETWAS GRÖSSER als die
   anderen (36 statt 30px, Icon 17 statt 14 – timeline_items.php), damit die Zeile
   auf einen Blick heraussticht (Wunsch Sebastian 13.08.2026). Der Verlauf
   unterscheidet ihn von der einfarbigen Anmerkung, die auch --accent benutzt.
   Seit 03.09.2026 ist er das EINZIGE Unterscheidungsmerkmal – die getönte Karte
   dazu ist entfallen (siehe `.tl-team-note` weiter oben).
   left = -(halbe Breite) - 26px, damit die Mitte weiter auf der Linie sitzt. */
.tl-dot-team {
    width: 36px;
    height: 36px;
    top: 4px;
    left: -44px;
    border-color: transparent;
    background: var(--accent-gradient);
    color: #fff;
}
.timeline-event .tl-dot { top: 0; }

/* Meilensteine (Azubi-Profil): goldener, etwas größerer Dot mit Party-Emoji */
.timeline-compact .timeline-item.timeline-milestone {
    background: transparent;
    border: 1px solid transparent;
    padding: 8px 12px;
    animation: none;
}
.tl-dot-milestone {
    width: 30px;
    height: 30px;
    left: -41px; /* 4px breiter als normale Dots → Mitte bleibt auf der Linie */
    top: 3px;
    font-size: 15px;
    border: 2px solid var(--gold);
    background: color-mix(in srgb, var(--gold) 14%, var(--surface));
}
.milestone-title { font-weight: 700; font-size: 0.98rem; color: var(--gold); }

/* Filter-Chips über der Profil-Timeline */
.tl-filter { margin: 10px 0 2px; }

/* ---------- Gruppen-Seiten ---------- */
/* Übersicht als Zeilen-Liste: Icon + Name links, Mitglieder-Avatare mittig, Statistik rechts */

/* Eine Karte pro Gruppe: Kopfzeile + Azubi-Tabelle in einem Block.
   Die Kopfzeile bekommt ein dezentes Farbband (wie Popup-Köpfe), damit sich
   die Gruppen klar voneinander abheben. */

/* Kopfzeile: dezenter Lila-Verlauf (Akzentfarbe der Buttons, stark abgemischt) –
   läuft nach rechts ins normale Band aus; funktioniert über Tokens in beiden Themes */

.group-trainees { border-top: 1px solid var(--border); padding: 4px 14px 6px; }
/* Feste Spaltenbreiten: jede Gruppe ist eine eigene Tabelle – ohne feste Breiten
   berechnet der Browser die Spalten pro Tabelle unterschiedlich (je nach Namenslängen)
   und die Gruppen-Tabellen wirken untereinander versetzt */
.group-trainees .table { table-layout: fixed; }
/* Spaltenbreiten der Übersicht (04.09.2026, „Variante B"): Klassen statt
   nth-child – die Spaltenzahl hat sich schon zweimal geändert. */
.group-trainees .table th:nth-child(1) { width: 30%; }  /* Person */
.group-trainees .table th.tl-c-aus   { width: 18%; }
.group-trainees .table th.tl-c-qs    { width: 19%; }
.group-trainees .table th.tl-c-log   { width: 14%; }
.group-trainees .table th.tl-c-heute { width: 13%; }
.group-trainees .table th.tl-c-warn  { width: 6%; text-align: center; }
.group-trainees .table td.tl-c-warn  { text-align: center; }
/* `.cell-flag` / `.cell-mood` gab es für die alten Haken- und Punkt-Spalten;
   sie sind mit dem Umbau entfallen (siehe _list.php). */
.group-trainees .table th { font-size: 0.72rem; padding: 10px 12px; }
.group-trainees .table td { padding: 10px 12px; }

/* ---------- Übersicht „Auszubildende": Hinweiszeile + Spalten (04.09.2026) ----------
   „Variante B" aus `_auszubildende-mockup.html`. Die Zeile über der Tabelle sagt,
   was in DIESER Gruppe gerade auffällt; jeder Knopf filtert die Liste darunter
   auf genau diese Personen. Ohne JavaScript bleiben es reine Zahlen – die Liste
   ist dann vollständig, es geht nichts verloren. */
.tl-hin { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 14px 4px; }
.tl-hin-b {
    display: inline-flex; align-items: center; gap: 8px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
    padding: 7px 12px; font: inherit; font-size: 0.82rem; color: var(--text); cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease;
}
.tl-hin-b:hover { background: var(--surface-hover); }
.tl-hin-b.active { border-color: var(--accent); background: var(--accent-soft); }
.tl-hin-b b { font-size: 1rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.tl-hin-b span { color: var(--text-muted); }

.tl-hin-b.t-warn b { color: var(--gold); }
.tl-hin-b.t-ok b { color: var(--positive); }

/* Person: Name oben, Gruppe/Sonderregelung klein darunter */
.tl-nm { min-width: 0; }
.tl-nm small { display: block; color: var(--text-muted); font-size: 0.74rem; margin-top: 1px; }
.tl-geb { cursor: help; }

/* Ausbildung: Balken + Lehrjahr */
.tl-aus { display: inline-flex; align-items: center; gap: 9px; white-space: nowrap;
    font-size: 0.82rem; color: var(--text-muted); }
.tl-bar { width: 64px; height: 6px; border-radius: 999px; background: var(--surface-2);
    overflow: hidden; flex: none; }
.tl-bar i { display: block; height: 100%; border-radius: 999px; background: var(--accent); }

/* Fehlerfrei: Zahl mit Ampel, dahinter die letzten fünf Prüfungen */
.tl-quote { font-weight: 700; font-variant-numeric: tabular-nums; }
.tl-quote.g { color: var(--positive); }
.tl-quote.w { color: var(--gold); }
.tl-quote.r { color: var(--negative); }
/* Die Punkt-Größe hing an `.mood .dot` – die Zelle heißt seit dem Umbau anders,
   die Farbklassen (`dot-positive/neutral/negative`) bleiben dieselben. */
.tl-dots { display: inline-flex; gap: 4px; margin-left: 8px; vertical-align: middle; }
.tl-dots .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }

/* Logbuch: ab 30 Tagen hervorgehoben – das ist die Zahl, wegen der man kommt */
.tl-log { font-size: 0.82rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.tl-log.old { color: var(--gold); font-weight: 600; }

/* Heute abwesend (aus dem absence.io-Zwischenspeicher, nie mit Abruf) */
.tl-weg { display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--text-muted); }
.tl-weg i { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); flex: none; }

@media (max-width: 900px) {
    /* Auf schmalen Karten fallen die beiden Zusatzspalten weg – Person, Quote
       und Logbuch tragen die Aussage. */
    .table-cards td.tl-c-aus, .table-cards td.tl-c-heute { display: none; }
}
/* Letzte Zeile ohne Trennlinie (Karte schließt die Liste optisch ab) */
.group-trainees .table tbody tr:last-child td { border-bottom: none; }
.group-row {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 14px 18px;
    color: inherit;
}
.group-row:hover { text-decoration: none; background: var(--surface-hover); }
/* In der Gruppen-Karte liegt ein Farbband – dort wird es beim Überfahren nur
   etwas kräftiger, statt gegen die einfarbige Hover-Fläche zu springen */

.group-row:hover .group-row-chevron { color: var(--accent); transform: translateX(2px); }
.group-row-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    flex-shrink: 0;
    background: var(--accent-soft);
    color: var(--accent);
}
.group-row-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.group-row-info strong { font-size: 1.02rem; }
.group-row-info .muted { font-size: 0.84rem; }
.group-row-stats {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-left: auto;
    text-align: right;
    font-size: 0.88rem;
    white-space: nowrap;
}
.group-row-stats .muted { font-size: 0.76rem; }
.group-row-chevron { color: var(--text-muted); flex-shrink: 0; transition: color 0.15s ease, transform 0.15s ease; }

/* Gestapelte Mitglieder-Avatare (überlappend, Tooltip = Name) */
/* ---------- Anwesenheit: Punkt im Marken-Kopf der Sidebar ----------
   Nur ein pulsierender Punkt; beim Überfahren (oder per Tastatur-Fokus) klappt
   eine kleine Karte mit den gerade aktiven Personen auf. */
/* Anker ist der Punkt selbst – die Karte klappt immer rechts daneben auf */
.presence { position: relative; margin-left: auto; display: flex; align-items: center; }
.presence[hidden] { display: none; }

@keyframes presence-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--positive) 60%, transparent); }
    70%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--positive) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--positive) 0%, transparent); }
}

/* Kompakter Modus: kein Platz neben dem Logo – der Punkt sitzt als Status-Marke
   mittig auf der unteren rechten Ecke des C-Logos (halb darüber, halb daneben).
   Das Logo ist 48 px groß und in der 72-px-Spalte zentriert. */
@media (min-width: 901px) {
    html.sidebar-min .presence {
        position: absolute;
        left: calc(50% + 24px);
        top: 54px;
        transform: translate(-50%, -50%);
        margin: 0;
    }
    
}

@media (max-width: 760px) {
    .group-row { flex-wrap: wrap; gap: 10px 14px; }
    .group-row-stats { text-align: left; margin-left: auto; }
    .group-row-chevron { display: none; }
}

/* Mitglieder-Liste auf der Gruppen-Seite */
.member-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.member-list li { display: flex; align-items: center; gap: 10px; }
.member-link { display: inline-flex; align-items: center; gap: 8px; color: var(--text); font-weight: 600; }
.member-link:hover { color: var(--accent); text-decoration: none; }
.member-list .badge { margin-left: auto; }

/* Monats-Trenner in der Timeline: dezente Zwischenüberschrift */
.timeline-day:first-child { margin-top: 0; }
.timeline-month {
    list-style: none;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin: 8px 0 -6px;
}

/* Vorschau in der Dashboard-Timeline: maximal 3 Zeilen */
.timeline-compact .timeline-item p {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Rechte Dashboard-Spalte (Termine): etwas kleinere Texte */
.grid-dashboard .stack .card { font-size: 0.86rem; }
.grid-dashboard .stack .deadline-when { font-size: 0.72rem; }

/* "Mehr laden" unter der Dashboard-Timeline */
/* "Mehr laden" (Dashboard-Logbuch): normaler Primär-Button, mittig unter der Timeline */
.timeline-more { display: flex; width: fit-content; margin: 16px auto 0; padding-left: 26px; padding-right: 26px; }

/* Automatische System-Events (blaues Info-Icon) */
/* Systemmeldungen: bewusst dezenter als Anmerkungs-Karten – schmale,
   gedämpfte Zeile statt Karte, fügt sich aber in die Timeline-Optik ein.
   (Farben über Custom Properties → Dark- & Lightmode) */
.timeline-item.timeline-event {
    background: transparent;
    border-color: transparent;
    border-left: 3px solid var(--border);
    padding: 4px 12px;
    animation: none;
}

.timeline-event .timeline-trainee { font-weight: 500; color: var(--text-muted); }
.timeline-event .timeline-head .muted { font-size: 0.78rem; }
.timeline-event p { margin: 2px 0 0; font-size: 0.82rem; color: var(--text-muted); }

/* Volle-Breite-Buttons in Modal-Formularen (Kommentieren) –
   gleiche Optik wie die 50/50-Aktionszeilen */
.modal-full-btn { width: 100%; justify-content: center; }

.modal-actions-row { display: flex; gap: 10px; margin-top: 18px; }
.modal-actions-row .btn { flex: 1; justify-content: center; }
.modal-actions-row form { flex: 1; display: flex; }

/* "Weitere Optionen" im Eintrag-Popup: eigener, abgesetzter Bereich
   mit neutralen Buttons – hebt sich klar von Bearbeiten/Löschen ab.
   (Farben via Custom Properties → Dark- & Lightmode) */
.modal-options {
    margin-top: 22px;
    padding: 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.modal-subhead {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}
.modal-options .modal-actions-row { margin-top: 10px; }
.modal-options .modal-actions-row .btn {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    box-shadow: none;
}
.modal-options .modal-actions-row .btn:hover {
    border-color: var(--accent);
    color: var(--accent);
    filter: none;
}
.modal-options .btn-count { background: var(--accent-soft); color: var(--accent); }

/* Name des Azubis (bzw. Team/Gruppe) im Popup-Kopf */
.modal-who { font-size: 1.02rem; margin-right: 2px; }
.btn-count {
    background: rgba(255, 255, 255, 0.25);
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 0.78rem;
}
.modal-section {
    border-top: 1px solid var(--border);
    margin-top: 14px;
    padding-top: 14px;
    animation: fadeIn 0.15s ease;
}
/* Kommentar schreiben: großzügiges Feld mit klarem Abstand zum Knopf darunter */
#commentForm { gap: 16px; }
#commentInput {
    min-height: 96px;
    padding: 12px 14px;
    border-radius: 12px;
    line-height: 1.5;
}
#commentInput::placeholder { color: var(--text-muted); }
.comment-list { list-style: none; margin: 8px 0 12px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.comment-list li { background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; }
.comment-list li p { margin: 4px 0 0; white-space: pre-line; }
.comment-list .comment-empty { background: none; border: none; text-align: center; }
.comment-head { display: flex; align-items: center; gap: 8px; font-size: 0.82rem; }
.comment-head form { margin-left: auto; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }

/* ---------- Termin-/Feedback-Listen ---------- */
.deadline-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.deadline-list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    flex-wrap: nowrap;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 12px;
}
/* Zweizeilig: Titel oben (wird ausgepunktet, voller Text per Hover-Tooltip
   bzw. Klick aufs Profil), Datum + Tage klein darunter */
.deadline-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.deadline-title {
    font-weight: 400; /* nur der Name (strong) ist fett */
    font-size: 0.8rem;
    color: var(--text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.deadline-icon { display: inline-flex; color: var(--accent); flex-shrink: 0; margin-top: 2px; }
.deadline-when { color: var(--text-muted); font-size: 0.78rem; white-space: nowrap; }
.deadline-when.deadline-soon { color: var(--accent); font-weight: 600; }
.deadline-list .badge { margin-left: auto; }

/* Dezenter "Alle anzeigen"-Schalter (z. B. unter den anstehenden Terminen) */
/* „Alle anzeigen (N weitere)": seit 13.08.2026 ein kleiner Knopf im Stil der
   echten Buttons (.btn.btn-primary.btn-sm) – hier bleibt nur der Abstand und
   dass er nicht auf die volle Breite gezogen wird. */
.show-all-btn { margin-top: 12px; align-self: flex-start; }

/* ---------- Benachrichtigungen (Glocke) ---------- */
.notif-wrap { position: relative; }
/* QS-Filter-Icon in der Topbar: Zähler-Badge wie bei der Glocke */
.topbar-filter { position: relative; }
/* Gesetzter Filter (04.09.2026, „Variante B"): der Icon-Knopf wächst zur Pille
   und trägt die ANZAHL neben dem Trichter, in der Warnfarbe getönt. Vorher hing
   dort nur ein `.notif-badge` in der Ecke – zu klein, um beim Arbeiten
   aufzufallen („nicht nur ne rote Eins dran").
   Rot ist hier bewusst nur GETÖNT, nicht gefüllt: ein gesetzter Filter ist kein
   Fehler, sondern ein Zustand, den man leicht vergisst.
   Gilt für beide Filter-Knöpfe – Qualitätssicherung (qs.js setzt die Klasse)
   und Zielerreichung (serverseitig im Layout). */
.topbar-filter.is-on {
    width: auto;
    gap: 7px;
    padding: 8px 12px 8px 10px;
    background: var(--negative-soft);
    border-color: color-mix(in srgb, var(--negative) 45%, transparent);
    color: var(--negative);
}
.topbar-filter.is-on:hover { background: color-mix(in srgb, var(--negative) 22%, transparent); }
.topbar-filter .flt-n { font-size: 0.82rem; font-weight: 700; font-variant-numeric: tabular-nums; }

.notif-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--negative);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.notif-wrap .btn { position: relative; }
.notif-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    width: 340px;
    max-width: 85vw;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow);
    z-index: 60;
    overflow: hidden;
}
.notif-head { padding: 10px 14px; font-weight: 700; font-size: 0.86rem; border-bottom: 1px solid var(--border); }
.notif-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.notif-list li { padding: 10px 14px; border-bottom: 1px solid var(--border); cursor: pointer; font-size: 0.86rem; }
.notif-list li:last-child { border-bottom: none; }
.notif-list li:hover { background: var(--surface-hover); }
.notif-list li.notif-unread { border-left: 3px solid var(--accent); background: var(--accent-soft); }
.notif-list li .muted { font-size: 0.76rem; }
.notif-list .notif-empty { cursor: default; text-align: center; padding: 18px; }
.notif-list .notif-empty:hover { background: none; }

/* Punkt ohne Zahl an den Topbar-Icons (12.08.2026): blau = etwas Neues bzw.
   Anstehendes, rot = dringend (überfällig / erledigtes Feedback). Der Ring in
   Hintergrundfarbe hebt ihn von der Icon-Pille ab. Zahlen stehen im Panel. */
.notif-dot {
    position: absolute;
    top: 1px;
    right: 1px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 2px var(--surface);
    pointer-events: none;
}
.notif-dot-bad { background: var(--negative); }
.notif-dot-ok { background: var(--positive); }
.notif-head-count-mute { color: var(--text-muted); background: var(--surface-2); }
/* ---------- Suche: Gruppen & Anmerkungs-Treffer ---------- */
.search-group {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    padding: 8px 10px 2px;
}
/* Knopf an einer Gruppen-Überschrift (25.08.2026): bisher nur „Leeren" an
   „Zuletzt geöffnet". Bewusst ein Textknopf ohne Fläche – er steht in einer
   Beschriftungszeile und darf die Trefferliste nicht überstimmen. Groß-
   schreibung und Laufweite erbt er von der Zeile, damit beide Enden gleich
   aussehen. Farbe erst beim Überfahren, damit ruhende Listen ruhig bleiben. */
.search-group-act {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: var(--text-muted);
    cursor: pointer;
    opacity: 0.85;
    transition: color 0.15s ease, opacity 0.15s ease;
}
.search-group-act:hover,
.search-group-act:focus-visible { color: var(--accent); opacity: 1; }
.search-note div { min-width: 0; }
.search-note .muted { font-size: 0.8rem; }

/* ---------- Toast-Meldungen ----------
   Meldungen unten rechts als Kartenstapel: mehrere Toasts liegen leicht
   versetzt übereinander statt untereinander. Mauszeiger oder Tastaturfokus
   fächert den Stapel auf (#toastStack.expanded) und hält die Timer an.
   Klick schließt sofort, "sticky" bleibt bis zum Klick stehen.
   Statusfarbe nur als Akzent auf Icon und Titel – der Meldungstext bleibt
   dadurch auch bei langen Fehlern lesbar statt komplett rot.
   (Farben ausschließlich über Custom Properties → Dark- & Lightmode) */
#toastStack {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 300;
    width: min(380px, calc(100vw - 32px));
    /* Platz für den zusammengeschobenen Stapel (Vorderkarte + Ränder dahinter) */
    min-height: 76px;
    pointer-events: none; /* leerer Bereich darf nichts abfangen */
}
#toastStack > .toast { pointer-events: auto; }

.toast {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 100%;
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 15px;
    border-radius: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    animation: toastIn 0.42s cubic-bezier(0.22, 1.1, 0.36, 1);
    transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1),
                opacity 0.32s ease, filter 0.32s ease;
}
.toast-click { cursor: pointer; }

/* Statusfarbe je Typ (Warnung nutzt --gold wie überall sonst in der App).
   „Erfolg" läuft seit 13.08.2026 in der persönlichen Akzentfarbe statt in Grün
   (Wunsch Sebastian) – Grün und Rot bleiben den echten Bewertungen vorbehalten. */
.toast-success { --toast-c: var(--accent); }
.toast-error   { --toast-c: var(--negative); }
.toast-warning { --toast-c: var(--gold); }
.toast-info    { --toast-c: var(--accent); }

.toast-ico {
    flex: none;
    width: 24px;
    height: 24px;
    margin-top: 1px;
    border-radius: 8px;
    display: grid;
    place-items: center;
    color: var(--toast-c, var(--accent));
    background: color-mix(in srgb, var(--toast-c, var(--accent)) 16%, transparent);
}
.toast-ico svg { display: block; width: 14px; height: 14px; }
.toast-body { flex: 1; min-width: 0; }
.toast-title { font-weight: 650; font-size: 0.92rem; color: var(--toast-c, var(--text)); }
.toast-msg { font-size: 0.87rem; color: var(--text-muted); overflow-wrap: anywhere; }
/* Toast ohne Titel (z. B. Info- und Rückgängig-Meldungen): Text ist die Hauptzeile */
.toast-plain .toast-msg { font-size: 0.92rem; font-weight: 500; color: var(--text); }

/* Zusammengeschoben: dahinterliegende Karten schrumpfen und rücken nach oben weg.
   Sie werden dabei auf die Höhe der Vorderkarte getrimmt (--toast-h wird in
   app.js gesetzt) und ihr Inhalt ausgeblendet – sonst ragt bei unterschiedlich
   langen Meldungen der Text der hinteren Karte oben heraus. */
#toastStack:not(.expanded) .toast:not([data-depth="0"]) {
    height: var(--toast-h, 62px);
    overflow: hidden;
}
#toastStack:not(.expanded) .toast:not([data-depth="0"]) > * {
    opacity: 0;
    transition: opacity 0.2s ease;
}
.toast[data-depth="1"] { transform: translateY(-11px) scale(0.955); filter: brightness(0.94); }
.toast[data-depth="2"] { transform: translateY(-20px) scale(0.915); filter: brightness(0.88); }
.toast[data-depth="3"] { transform: translateY(-27px) scale(0.88); opacity: 0.5; }
.toast[data-depth="4"] { transform: translateY(-32px) scale(0.85); opacity: 0; }

/* Aufgefächert: normaler Fluss, neueste Karte bleibt unten am Rand */
#toastStack.expanded { display: flex; flex-direction: column-reverse; gap: 9px; }
#toastStack.expanded .toast {
    position: relative;
    transform: none;
    filter: none;
    opacity: 1;
}
.toast.hide { opacity: 0 !important; transform: translateY(8px) scale(0.92) !important; }

@keyframes toastIn { from { opacity: 0; transform: translateY(26px) scale(0.94); } to { opacity: 1; } }

@media (max-width: 560px) {
    #toastStack { left: 12px; right: 12px; bottom: 12px; width: auto; }
}
html.no-anim .toast { animation: none; transition: opacity 0.15s linear; }

/* Kompakte Bewertungszeile neben dem Speichern-Button */
/* Speichern-Zeile in den Eintrag-Formularen: Button ~60 %, Bewertung ~40 % */
.note-submit-row { display: flex; gap: 10px; align-items: stretch; }
.note-submit-row .btn { flex: 3; justify-content: center; }
.note-submit-row .seg { flex: 2; min-width: 0; }
.seg-sm label { padding: 6px 8px; font-size: 0.78rem; border-radius: 8px; }

/* Bewertung als runde Gesichter (statt breiter Balken): kompakt, ausgewähltes
   Gesicht voll eingefärbt (grün/grau/rot) mit weichem Farbring */
.seg.seg-icons { display: flex; gap: 10px; flex: 0 0 auto; min-width: 0; }
.seg.seg-icons label {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    padding: 0;
    gap: 0;
    border-radius: 50%;
    justify-content: center;
    transition: transform 0.12s ease, background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.seg.seg-icons label:hover { transform: scale(1.06); }
.seg.seg-icons input:checked + label { transform: scale(1.06); color: #fff; }
.seg.seg-icons input:checked + label.seg-positive { background: var(--positive); border-color: var(--positive); box-shadow: 0 0 0 3px var(--positive-soft); }

.seg.seg-icons input:checked + label.seg-negative { background: var(--negative); border-color: var(--negative); box-shadow: 0 0 0 3px var(--negative-soft); }
/* In der Speichern-Zeile: Button nimmt die restliche Breite, Gesichter rechts daneben */
.note-submit-row .seg.seg-icons { flex: 0 0 auto; }

/* ---------- Mini-Zeitstrahl (Azubi-Liste): Position in der Ausbildung ----------
   Meilenstein-Ticks bei 1/3 (2. Lehrjahr), 2/3 (3. Lehrjahr) und am vsl. Ende.
   Farben ausschließlich über Custom Properties → Dark- & Lightmode. */
/* ---------- Mini-Zeitstrahl: Position in der Ausbildung ----------
   Meilenstein-Ticks bei 1/3 (2. Lehrjahr), 2/3 (3. Lehrjahr) und am vsl. Ende.
   Farben ausschließlich über Custom Properties → Dark- & Lightmode.
   Der Zeitstrahl steht nur noch im Profil (.profile-pt weiter unten) – die
   Azubi-Liste hat dafür keine Spalte mehr.
   17.08.2026: Hier standen zwei halb einkopierte Kommentarköpfe, der zweite ohne
   schließendes Zeichen. Er verschluckte eine Regel für die frühere Spalte
   td.pt-cell (die es nicht mehr gibt) und den Kommentar der Namens-Zelle. */
.name-cell { display: flex; align-items: center; gap: 10px; white-space: nowrap; }
.name-cell .avatar { margin-right: 0; }
.pt {
    position: relative;
    height: 6px;
    border-radius: 3px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    margin: 6px 2px 7px 0;
}
.pt-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    border-radius: 3px;
    background: var(--accent-gradient);
}
.pt-tick {
    position: absolute;
    top: -4px;
    width: 2px;
    height: 13px;
    border-radius: 1px;
    background: var(--border);
}
.pt-tick-end { right: 0; }
/* Dot am Anfang des Zeitstrahls: Ausbildungsbeginn (Datum per Tooltip) */
.pt-dot-start {
    position: absolute;
    left: 0;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--neutral);
}
.pt-marker {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--surface);
    box-shadow: var(--shadow-sm);
}

/* Ausbildungs-Zeitstrahl auf dem Profil: volle Breite über den beiden Spalten */
.profile-pt { padding: 16px 20px 12px; margin-bottom: 18px; }
/* Beim Seitenaufruf animiert "aufladen": Füllung + Marker wandern von 0 zur Position
   (Keyframes ohne "to" enden automatisch bei der Inline-Breite/-Position) */
.profile-pt .pt-fill { animation: pt-load 0.9s cubic-bezier(0.25, 0.7, 0.3, 1) 0.15s both; }
.profile-pt .pt-marker { animation: pt-load-marker 0.9s cubic-bezier(0.25, 0.7, 0.3, 1) 0.15s both; }
@keyframes pt-load { from { width: 0; } }
@keyframes pt-load-marker { from { left: 0; } }
.profile-pt-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 0.85rem; margin-bottom: 4px; }
.profile-pt .pt { height: 8px; border-radius: 4px; margin: 10px 0 8px; }
.profile-pt .pt-fill { border-radius: 4px; }
.profile-pt-legend { position: relative; height: 16px; font-size: 0.72rem; color: var(--text-muted); }
.profile-pt-legend span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.profile-pt-legend span:first-child { left: 0 !important; transform: none; }
.profile-pt-legend span:last-child { right: 0; left: auto !important; transform: none; }
/* Marker "Wechsel ins WEB" (1/3 des 2. Lehrjahrs): Akzentfarbe zur Unterscheidung */
.profile-pt .pt-tick-web { background: var(--accent); }
.profile-pt-legend .pt-legend-web { color: var(--accent); font-weight: 600; }

/* Archiv-Zeile in der Gruppen-Übersicht: abgesetzt von den aktiven Gruppen –
   gestrichelter Rahmen, kein Karten-Hintergrund. Die Trennlinie darüber
   (`.group-rows-sep`) ist am 02.09.2026 entfallen (Wunsch Sebastian): der
   gestrichelte Rahmen trennt schon, zwei Trenner übereinander sind einer zu viel.
   Der ABSTAND bleibt – er kommt jetzt als margin-top hierher. */
.group-row-archive {
    margin-top: 18px;
    opacity: 0.75;
    background: transparent;
    border-style: dashed;
}
.group-row-archive:hover { opacity: 1; background: var(--surface-hover); }
.group-row-archive .group-row-icon { background: var(--surface-2); color: var(--text-muted); }
.member-list li > .muted { font-size: 0.8rem; }

/* Haken/X-Spalten in der Azubi-Liste (Rufnummer, Geburtstag, Arbeitszeit) */

.flag-yes { color: var(--positive); display: inline-flex; vertical-align: middle; }
.flag-no { color: var(--negative); opacity: 0.75; display: inline-flex; vertical-align: middle; }
/* Auch im Tabellenkopf zentrieren (spezifischer als ".table th" mit text-align:left) */

/* Warnhinweis am Haken/X: Sonderregelung (weicht von der Gruppen-Regelung ab) */
/* Sonderregelungs-Stern (wie das Badge im Profil) hochgestellt neben dem Haken */
.flag-warn { display: inline-flex; color: var(--gold); vertical-align: super; margin-left: 2px; font-size: 0.68rem; line-height: 1; }

/* Badge "Sonderregelung" im Azubi-Profil (Arbeitszeit-Box) */
.badge-special {
    color: var(--gold);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
}

.mood { white-space: nowrap; }

/* ---------- Mobile Karten-Ansicht der Azubi-Liste (unter 760px) ----------
   Aus der breiten Tabelle werden Karten: Name oben, Zeitstrahl in voller Breite,
   Status/Haken/Stimmung als kompakte Zeile darunter. */
@media (max-width: 760px) {
    .table-cards thead { display: none; }
    .table-cards, .table-cards tbody, .table-cards tr, .table-cards td { display: block; width: 100%; }
    .table-cards tbody tr {
        background: var(--surface-2);
        border: 1px solid var(--border);
        border-radius: 12px;
        padding: 12px 14px;
        margin-bottom: 10px;
    }
    
    .table-cards td { padding: 3px 0; border: none; }
    /* Status, Haken/X und Stimmung in einer Zeile */
    .table-cards td.mood,
.table-cards td:has(.badge) { display: inline-block; width: auto; vertical-align: middle; margin-right: 12px; }
    .name-cell { white-space: normal; }
}
.mood .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 4px; }
.dot-positive { background: var(--positive); }
.dot-neutral { background: var(--neutral); }
.dot-negative { background: var(--negative); }

/* ---------- Login / Installation ---------- */
.auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 20px;
}
.auth-card { width: 100%; max-width: 400px; padding: 32px; }
.auth-logo { text-align: center; margin-bottom: 20px; }
.auth-logo .logo-badge { width: 52px; height: 52px; font-size: 1.5rem; border-radius: 14px; margin-bottom: 10px; }
.auth-logo h1 { justify-content: center; margin-bottom: 2px; }
.auth-logo h1 small { font-size: 0.6em; color: var(--text-muted); font-weight: 500; }
.auth-logo p { margin: 0; }
/* Team-Kürzel unter dem Schriftzug (statt der früheren Untertitel-Zeile) */
.auth-logo .head-brand { margin-top: 4px; }
/* Die `.auth-*`-Regeln darüber gehören jetzt NUR noch der Sperrmaske
   (Views/lock.php) und dem Install-Skript. Die Anmeldeseite selbst steht
   seit 20.08.2026 auf den `.lgn2-*`- und `.lgm-*`-Regeln direkt darunter. */

/* ---------- Anmeldeseite „Zwei Karten" (20.08.2026) ----------
   Variante 2 aus `_login-neu.html` mit dem Hintergrund „Atem-Glow" aus
   `_login-hintergrund.html`, von Sebastian gewählt: zwei Karten mittig auf dem
   gewohnten App-Hintergrund – links Marke, Begrüßung, Datum und die Tagesinfos,
   rechts die Anmeldung. Die frühere Farbfläche „Tageszeit" (`.lgn6-*`) ist damit
   entfallen; die Begrüßung folgt weiter der Uhrzeit, nur eben ohne Farbfläche.
   Alle Farben laufen über Tokens, die Kegel über --accent-rgb – die Seite folgt
   also der persönlichen Akzentfarbe. Schriftgrößen in rem, Abstände in px. */
.lgn-page { margin: 0; min-height: 100vh; display: flex; }
.lgn2 { position: relative; width: 100%; display: grid; place-items: center;
    padding: 40px 20px; overflow: hidden; background: var(--bg-gradient); }

/* --- Hintergrund: zwei große Lichtkegel, die sehr langsam wandern ---
   Reine Deko, deshalb ohne eigenes Markup-Gewicht (aria-hidden) und ohne
   jede Interaktion. Ohne Animationen stehen sie einfach still. */
.lgn2-bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.lgn2-bg::before, .lgn2-bg::after { content: ""; position: absolute; border-radius: 50%;
    filter: blur(90px); opacity: 0.75; }
.lgn2-bg::before { width: 780px; height: 780px; left: -160px; top: -220px;
    background: radial-gradient(circle, rgba(var(--accent-rgb), 0.55), transparent 68%);
    animation: lgn2Atem1 34s ease-in-out infinite alternate; }
.lgn2-bg::after { width: 700px; height: 700px; right: -180px; bottom: -260px;
    background: radial-gradient(circle, rgba(var(--accent-rgb), 0.40), transparent 68%);
    animation: lgn2Atem2 46s ease-in-out infinite alternate; }
[data-theme="light"] .lgn2-bg::before { opacity: 0.42; }
[data-theme="light"] .lgn2-bg::after { opacity: 0.34; }
@keyframes lgn2Atem1 { from { transform: none; } to { transform: translate(180px, 130px) scale(1.16); } }
@keyframes lgn2Atem2 { from { transform: none; } to { transform: translate(-160px, -110px) scale(1.12); } }
html.no-anim .lgn2-bg::before, html.no-anim .lgn2-bg::after { animation: none; }

/* --- die zwei Karten --- */
.lgn2-in { position: relative; z-index: 2; display: grid; grid-template-columns: 1fr 400px;
    gap: 22px; width: 100%; max-width: 960px; align-items: stretch; }
/* Leicht durchscheinend (Milchglas), damit man den Schein dahinter merkt –
   sonst wäre der Hintergrund unter den Karten einfach weg. */
.lgn2-karte { border: 1px solid var(--border); border-radius: 20px; padding: 30px 32px;
    display: flex; flex-direction: column; box-shadow: var(--shadow);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.lgn2-form { justify-content: center; }

/* Markenkopf wie in der Sidebar (`.sidebar-brand`): Logo-Plättchen, „Copilot"
   und das Team-Kürzel DARUNTER (Wunsch 20.08.2026 – vorher stand es hinter
   „Anmelden"). Wer sich anmeldet, sieht dieselbe Marke wie danach im Tool. */
.lgn2-brand { display: flex; align-items: center; gap: 12px; margin-bottom: auto; }
.lgn2-brand > i { width: 42px; height: 42px; border-radius: 13px; flex: none;
    background: var(--accent-gradient); display: inline-flex; align-items: center;
    justify-content: center; color: #fff; }
.lgn2-text { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; min-width: 0; }
.lgn2-name { font-size: 1.25rem; font-weight: 700; line-height: 1.05; }
.lgn2-badge { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em; padding: 4px 10px;
    border-radius: 999px; background: var(--accent-soft); color: var(--accent); }
/* Die eine große Zeile der Seite */
.lgn2-hi { display: block; margin-top: 30px; font-weight: 700; letter-spacing: -0.025em;
    line-height: 1.1; font-size: clamp(1.7rem, 3vw, 2.4rem); }
.lgn2-when { margin: 8px 0 0; color: var(--text-muted); font-size: 0.9rem; }
/* Zwei Pillen: heute abwesend, Geburtstage bis Sonntag. Sie stehen NUR da, wenn
   es welche gibt (login.php), und nennen nur Zahlen – die Seite ist ohne
   Anmeldung erreichbar, deshalb keine Namen und keine Abwesenheitsart. */
.lgn2-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.lgn2-pill { display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px;
    border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border);
    color: var(--text-muted); font-size: 0.78rem; font-weight: 600; }
.lgn2-pill svg { flex: none; opacity: 0.85; }

.lgn2-head { margin: 0 0 22px; font-size: 1.25rem; letter-spacing: -0.015em; }
.lgn2-flash { margin-bottom: 18px; }

/* ---------- Loginmaske (20.08.2026) ----------
   Feldstil C: BEIDE Felder in einem Block mit Trennlinie, Zeichen und
   Beschriftung liegen im Feld, die aktive Zeile wird akzentfarben hinterlegt
   (Fläche statt Rähmchen – dieselbe Regel wie „heute" im Teamplaner).
   Ohne JavaScript bleibt es ein normales POST-Formular mit zwei Feldern;
   Auge, Feststelltasten-Hinweis und Sende-Zustand sind Zugabe aus login.php. */
.lgm { display: grid; gap: 16px; width: 100%; max-width: 380px; }
.lgm-fields { display: grid; border: 1px solid var(--border); border-radius: 14px;
    background: var(--surface-2); overflow: hidden; }
.lgm-f { position: relative; padding: 4px 12px 4px 40px; }
.lgm-f + .lgm-f { border-top: 1px solid var(--border); }
.lgm-f input {
    width: 100%; padding: 26px 44px 10px 0; font-family: inherit; font-size: 1rem;
    color: var(--text); background: transparent; border: 0; outline: none; box-shadow: none;
}
/* Chrome legt sonst eine hellgelbe Fläche über das Feld */
.lgm-f input:-webkit-autofill,
.lgm-f input:-webkit-autofill:focus {
    -webkit-text-fill-color: var(--text); caret-color: var(--text);
    box-shadow: inset 0 0 0 100px var(--surface-2);
}
.lgm-f > label { position: absolute; left: 40px; top: 9px; pointer-events: none;
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--text-muted); }
.lgm-ic { position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
    display: inline-flex; color: var(--text-muted); transition: color 0.16s ease; }
/* aktive Zeile hinterlegen – liegt unter dem Text, deshalb ein eigenes ::before */
.lgm-f::before { content: ""; position: absolute; inset: 0; opacity: 0; pointer-events: none;
    background: color-mix(in srgb, var(--accent) 12%, transparent); transition: opacity 0.16s ease; }
.lgm-f:focus-within::before { opacity: 1; }
.lgm-f:focus-within .lgm-ic { color: var(--accent); }
.lgm-f.is-bad::before { opacity: 1; background: var(--negative-soft); }
/* Häkchen, sobald etwas drinsteht; beim Fehler ausgeblendet (sonst widersprüchlich) */
.lgm-ok { position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
    color: var(--positive); opacity: 0; transition: opacity 0.18s ease; pointer-events: none; }
.lgm-f.has-eye .lgm-ok { right: 40px; }
.lgm-f.is-filled .lgm-ok { opacity: 1; }
.lgm-f.is-bad .lgm-ok { opacity: 0; }
/* Passwort einblenden */
.lgm-eye { position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    display: inline-flex; padding: 6px; border: 0; border-radius: 8px; cursor: pointer;
    background: none; color: var(--text-muted); }
.lgm-eye:hover { color: var(--text); background: var(--surface-hover); }
/* Meldung und Hinweis stehen AM Feld, nicht als Band über dem Formular */
.lgm-msg, .lgm-hint { display: none; align-items: center; gap: 6px; margin: 0 0 10px;
    font-size: 0.78rem; }
.lgm-msg { color: var(--negative); }
.lgm-hint { color: var(--gold); }
.lgm-f.is-bad .lgm-msg { display: flex; }
.lgm-f.is-caps .lgm-hint { display: flex; }
.lgm-msg svg, .lgm-hint svg { flex: none; }
/* „Angemeldet bleiben" – eine Zeile zwischen Feldern und Knopf, bewusst leise */
.lgm-keep { display: flex; align-items: center; gap: 9px; font-size: 0.82rem;
    color: var(--text-muted); cursor: pointer; user-select: none; }
.lgm-keep input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.lgm-keep:hover { color: var(--text); }

/* Knopf: von Anfang an in voller Akzentfarbe (Wunsch 20.08.2026 – vorher war er
   entfärbt, solange ein Feld leer war, und wurde erst mit `is-ready` bunt).
   Beim Überfahren läuft EIN Glanzstreifen durch, der Pfeil rutscht ein Stück
   nach rechts und der Akzent-Ring geht auf – Bewegung nur hier, nicht als
   Dauerschleife. Alles hängt an `html.no-anim`, dann bleibt nur der Ring.
   **Auf der Anmeldeseite kommt die Klasse nur aus dem Betriebssystem** – die
   Profil-Einstellung „Animationen" kennt man erst nach der Anmeldung. */
.lgm-go { width: 100%; justify-content: center; position: relative; overflow: hidden;
    transition: box-shadow 0.22s ease, filter 0.22s ease; }
.lgm-go::before { content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
    transform: skewX(-18deg); pointer-events: none; opacity: 0;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.28), transparent); }
.lgm-go:hover { filter: brightness(1.06);
    box-shadow: var(--shadow), 0 0 0 3px var(--accent-soft); }
.lgm-go:hover::before { animation: lgmGlanz 0.75s ease; }
.lgm-go .lgm-arrow { display: inline-flex; transition: transform 0.25s ease; }
.lgm-go:hover .lgm-arrow { transform: translateX(3px); }
@keyframes lgmGlanz { from { left: -60%; opacity: 1; } to { left: 110%; opacity: 1; } }
html.no-anim .lgm-go::before { display: none; }
html.no-anim .lgm-go:hover .lgm-arrow { transform: none; }
.lgm-spin { display: none; width: 15px; height: 15px; border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.45); border-top-color: #fff;
    animation: lgmSpin 0.7s linear infinite; }
.lgm.is-sending .lgm-spin { display: inline-block; }
.lgm.is-sending .lgm-arrow, .lgm.is-sending .lgm-word { display: none; }
.lgm.is-sending .lgm-go::after { content: "Einen Moment …"; }
@keyframes lgmSpin { to { transform: rotate(360deg); } }
html.no-anim .lgm-spin { animation: none; border-top-color: rgba(255, 255, 255, 0.45); }
/* Ruckeln bei leerem Feld – ohne Animationen bleibt die rote Fläche als Signal */
@keyframes lgmShake { 10%, 90% { transform: translateX(-2px); } 30%, 70% { transform: translateX(3px); }
    50% { transform: translateX(-3px); } }
.lgm.is-shake { animation: lgmShake 0.4s ease; }
html.no-anim .lgm.is-shake { animation: none; }

@media (max-width: 900px) {
    /* Begrüßung oben, Maske darunter – die Felder bleiben am Daumen */
    .lgn-page { display: block; }
    .lgn2 { padding: 24px 16px 40px; min-height: 100vh; }
    .lgn2-in { grid-template-columns: 1fr; gap: 16px; }
    .lgn2-karte { padding: 24px 22px; }
    .lgn2-brand { margin-bottom: 22px; }
    .lgn2-hi { margin-top: 0; }
}

/* ---------- Bewegung zurücknehmen (12.08.2026, umgestellt 03.09.2026) ----------
   Alles bewegt sich sofort in den Endzustand: keine Übergänge, keine Aufbau-
   Animationen, keine Deko-Effekte. Diagramme regelt zusätzlich app.js
   (Apex: chart.animations.enabled), der QS-Ring seinen eigenen Zähler.

   **Eine Klasse, zwei Quellen (Stand 04.09.2026):** `html.no-anim` steht am
   `<html>`, wenn die Profil-Einstellung „Animationen" aus ist (Standard) ODER
   das Betriebssystem „Bewegung reduzieren" meldet – Letzteres trägt ein kurzes
   Skript im <head> nach. **CSS und JS fragen nur nach dieser Klasse**, nicht
   nach der Medienabfrage; die steht unten nur noch als Sicherheitsnetz für den
   Fall ohne JavaScript. (Zwischenstand 03.09.2026: die Profil-Einstellung war
   einmal entfallen und alles hing allein an der Medienabfrage.) */
html.no-anim *, html.no-anim *::before, html.no-anim *::after {
    animation-duration: 0.001s !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
    transition-delay: 0s !important;
}
/* Deko, die nur aus Bewegung besteht, entfällt ganz */
html.no-anim .mini-pop { display: none; }

/* Sicherheitsnetz ohne JavaScript: das Skript im <head> setzt `no-anim` bei
   „Bewegung reduzieren" nach – läuft kein JS, greift wenigstens diese Regel.
   **Wer oben etwas ändert, ändert es hier mit.** */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001s !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001s !important;
        transition-delay: 0s !important;
    }
    .mini-pop { display: none; }
}

/* ---------- Sichtschutz (echte Sperre, 12.08.2026) ----------
   Strg/⌘+Shift+L legt diesen Vorhang über die Seite (JS in app.js) und meldet
   die Sperre am Server – nach einem Neuladen kommt die Sperrmaske aus
   Views/lock.php. Wichtig: der Inhalt wird per filter: blur AM ELEMENT
   weichgezeichnet, nicht nur per backdrop-filter mit Transparenz – sonst bleibt
   er lesbar. Ebene 9000, siehe Ebenen-Skala oben. */
.privacy-lock {
    position: fixed;
    inset: 0;
    z-index: 9000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.privacy-lock[hidden] { display: none; }
.privacy-lock-veil {
    position: absolute;
    inset: 0;
    background: var(--bg);
    background-image: var(--bg-gradient);
}
.privacy-lock-card { position: relative; max-width: 400px; width: 100%; padding: 32px; }

/* Gesperrt: Seite dahinter unlesbar machen und nicht mitscrollen lassen */
html.is-locked, html.is-locked body { overflow: hidden; }
html.is-locked .app { filter: blur(18px) saturate(0.25) brightness(0.55); pointer-events: none; user-select: none; }
/* Der Vorhang selbst darf nicht mitgeblurrt werden */
html.is-locked .privacy-lock { filter: none; }

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
    /* minmax(0, 1fr): die Spalte darf schmaler werden als ihr breitester Inhalt –
       sonst zieht ein einzelnes breites Element (Diagramm, Tabelle) die ganze
       Seite auf und alles ragt rechts heraus. */
    .grid-sidebar,
.grid-profile,
.grid-dashboard,
.form-row { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
    .sidebar {
        position: fixed;
        z-index: 40;
        transform: translateX(-100%);
        box-shadow: var(--shadow);
    }
    .sidebar.open { transform: translateX(0); }
    .topbar .nav-toggle { display: inline-flex; }
    .content { padding: 8px 16px 32px; }
}

/* ---------- Nach-oben-Button (global, Optik wie .logo-badge) ---------- */
#toTop {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: 70;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: none;
    border-radius: 12px;
    background: var(--accent-btn-gradient);
    color: #fff;
    cursor: pointer;
    box-shadow: 0 8px 22px rgba(var(--accent-rgb), 0.4);
    /* Auspoppen: klein + durchsichtig nach unten weg */
    opacity: 0;
    transform: translateY(16px) scale(0.5);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;
}
#toTop.show {
    /* Aufpoppen mit leichtem Überschwingen (cubic-bezier oben) */
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}
#toTop:hover { transform: translateY(-3px) scale(1.05); box-shadow: 0 14px 30px rgba(var(--accent-rgb), 0.55); }
#toTop:active { transform: translateY(0) scale(0.94); }
#toTop:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.4); }
@media print { #toTop { display: none; } }

/* ---------- Diagramm maximieren ---------- */
/* Container mit Knopf oben rechts (sitzt über dem Diagramm, ohne Layout-Sprung) */
.chart-host { position: relative; }
.chart-max {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    opacity: 0.65;
    transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.chart-max:hover { opacity: 1; color: var(--accent); border-color: var(--accent); }
/* Popup: breit, Diagramm füllt die Fläche. Die QS-Variablen werden hier lokal
   aus den Copilot-Tokens gemappt – das Popup liegt außerhalb von #qs-app. */
#chartModal { z-index: 120; }   /* über den QS-Popups (z-index 80) und dem Layout (90) */
.modal-chart {
    max-width: 1180px;
    width: min(96vw, 1180px);
    --line: var(--border); --line-soft: var(--border);
    --card: var(--surface); --card2: var(--surface-2);
    --ink: var(--text); --muted: var(--text-muted);
}
.modal-chart #chartModalBody { margin-top: 6px; min-height: 320px; }

/* Hinweis unter dem Anmelde-Button (Login gilt 30 Tage) */
/* `.login-hint` (Hinweis „30 Tage angemeldet") ist am 19.08.2026 entfallen. */

/* --- Partykanone -----------------------------------------------------------
   Die große Kanone (.confetti-host/.confetti-bit samt @keyframes confetti-fly)
   ist am 13.08.2026 mit ihrem Auslöser entfallen: Konfetti nach einem QS-Import
   gibt es nicht mehr – **nicht ohne Rücksprache neu bauen.** Die kleine Kanone
   am QS-Verlauf des Dashboards (.mini-pop, Einstellungen → Dashboard →
   „Partykanone ab … %“) bleibt und bringt ihre Regeln selbst mit. */

/* ============================================================
   Einstellungen (Tabs) & Dashboard-Ergänzungen
   Alle Farben über die Theme-Variablen → Dark- und Lightmode.
   ============================================================ */

/* Karten-Kopf mit Zusatzinfo/Aktion rechts – gleiche Optik wie .card > h2 */
.card-title-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}
.card-title-row > h2 {
    margin: 0;
    padding: 0;
    border: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text);
}
.card-title-row > h2 svg { color: var(--accent); }
.card-title-row > .muted { margin-left: auto; font-size: 0.8rem; }

/* Kurzer Hinweistext in Karten (dezent, nie als Überschrift lesen) */
.card-hint {
    margin: 0 0 12px;
    font-size: 0.82rem;
    line-height: 1.5;
    color: var(--text-muted);
}
.card-hint:last-child { margin-bottom: 0; }

/* ---------- Gruppen-Blöcke (Einstellungen → Gruppen & Mitarbeiter) ---------- */
.set-groups { display: flex; flex-direction: column; gap: 10px; }
.set-group {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    transition: background-color 0.15s ease;
}
.set-group:hover { background: var(--surface-hover); }
.set-group > summary {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    cursor: pointer;
    user-select: none;
}
.set-group > summary::-webkit-details-marker { display: none; }
.set-group > summary:hover { background: var(--surface-hover); }
.sg-chev {
    display: inline-flex;
    color: var(--text-muted);
    flex-shrink: 0;
    transform: rotate(-90deg);
    transition: transform 0.2s ease, color 0.15s ease;
}
.set-group[open] > summary .sg-chev { transform: rotate(90deg); }
.set-group > summary:hover .sg-chev { color: var(--accent); }
.sg-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sg-main strong { font-size: 0.97rem; }
.sg-meta { font-size: 0.79rem; }
.sg-badges { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; flex-shrink: 0; }

.sg-body { padding: 0 14px 14px; }
.set-group[open] > .sg-body { border-top: 1px solid var(--border); padding-top: 12px; }
/* Aktionszeile der Gruppe: sitzt im aufgeklappten Bereich, damit die Kopfzeile ruhig bleibt */
.sg-tools { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.sg-tools form { display: inline-flex; }

/* Mitglieder einer Gruppe */
.member-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.member-list > li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.member-main {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    flex: 1;
    color: var(--text);
}
.member-main:hover { text-decoration: none; }
.member-main:hover .member-name strong { color: var(--accent); }
.member-name { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.member-name strong { font-size: 0.92rem; transition: color 0.15s ease; }
.member-name .muted { font-size: 0.76rem; }
.member-actions { display: inline-flex; gap: 4px; flex-shrink: 0; }
.member-actions form { display: inline-flex; }

/* Feld zum Kopieren (z. B. die Cron-Adresse der Backups): sieht wie Code aus,
   ein Klick markiert alles. Bewusst ein readonly-Feld statt <code>, damit man
   auch lange Adressen mit Strg+C mitnehmen kann. */
.input-copy {
    width: 100%;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.78rem;
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: text;
}

/* ---------- Kleine Kennzahl-Listen & Infoblöcke in den Info-Spalten ---------- */
.mini-stats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.mini-stats > li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 0.85rem;
    color: var(--text-muted);
}
.mini-stats > li strong { font-size: 1.05rem; color: var(--text); }

/* ---------- Anwesenheits-Punkt (Benutzerliste, Team-Karte) ---------- */

/* Modul-Rechte je Benutzer: eingeklappt, damit die Liste ruhig bleibt */
.module-access-box { margin-top: 10px; }
.module-access-box > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    cursor: pointer;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    transition: color 0.15s ease;
}
.module-access-box > summary::-webkit-details-marker { display: none; }
.module-access-box > summary:hover { color: var(--accent); }
.module-access-box > summary svg { color: var(--accent); }
.module-access-box > summary .muted { font-weight: 500; }

/* Karte "Dashboard anpassen": Felder kompakt untereinander */

/* ---------- Formular-Popups (neue Gruppe / Person / Benutzer) ---------- */
.modal-form { max-width: 640px; }
.modal-form .form { gap: 14px; }

.modal-form .modal-actions-row { margin-top: 6px; }

/* Gruppen-Zeile: Name und Badge in einer Zeile (Info-Spalte ist eine Spalte) */

@media (max-width: 900px) {
    .sg-badges { margin-left: 0; }
}

/* Zweite, ebenfalls hervorgehobene Aktion neben einem btn-primary
   (z. B. „Neue Gruppe“ neben „Neuer Mitarbeiter“) – beide Themes über Variablen */
.btn-accent {
    background: var(--accent-soft);
    border-color: rgba(var(--accent-rgb), 0.45);
    color: var(--accent);
    font-weight: 600;
}
.btn-accent:hover { background: rgba(var(--accent-rgb), 0.22); color: var(--accent); }
.btn-accent svg { color: var(--accent); }

/* Rechte Dashboard-Spalte: bleibt oben angepinnt, scrollt bei viel Inhalt
   (Ereignisse + Team + Anpassen) intern – sonst wäre der untere Teil nicht erreichbar */
.grid-dashboard > .stack {
    max-height: calc(100vh - 92px);
    overflow-y: auto;
    scrollbar-width: thin;
}
@media (max-width: 900px) {
    .grid-dashboard > .stack { position: static; max-height: none; overflow: visible; }
}

/* ---------- Lichtschein oben rechts ----------
   Eigene Ebene hinter dem Inhalt (z-index: -1), damit der Schein kräftiger
   sein und sich langsam bewegen kann. Farben kommen aus den Theme-Variablen,
   der Grundverlauf des Bodys (--bg-gradient) bleibt darunter erhalten. */
body::before {
    content: "";
    position: fixed;
    top: -35vh;
    right: -25vw;
    width: min(2000px, 132vw);
    height: min(1250px, 105vh);
    z-index: -1;
    pointer-events: none;
    /* Ein einziger, sehr breiter Schleier aus der rechten oberen Ecke –
       ruhig und ohne Bewegung; die Bewegung übernehmen die Partikel */
    background:
        radial-gradient(ellipse 58% 52% at 62% 45%, var(--glow-1), transparent 82%),
        radial-gradient(ellipse 52% 46% at 36% 62%, var(--glow-2), transparent 84%);
    filter: blur(30px);
}

/* Einstellungs-Karte „Dashboard anpassen“: Titel immer einzeilig,
   Inhalt nach Bereichen gruppiert (weitere Bereiche kommen später dazu) */
.set-block {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 13px 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.set-block .modal-subhead { display: flex; align-items: center; gap: 6px; }
.set-block .modal-subhead svg { color: var(--accent); }

/* Kopf aller Topbar-Panels: links Icon + Titel, rechts als Gruppe erst die
   Zahl, dann der Link („Alle ansehen“ bzw. „Alle schließen“). Einheitlich in
   Benachrichtigungen, Notizbuch und Feedback (12.08.2026). */
.notif-head { display: flex; align-items: center; gap: 8px; }
.notif-head svg { color: var(--accent); flex-shrink: 0; }
.notif-head-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 7px; }
.notif-head-count {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: 999px;
    padding: 2px 8px;
    white-space: nowrap;
}
.notif-head-count-bad { color: var(--negative); background: var(--negative-soft); }

/* ---------- Debug-Modus (Testdaten) ---------- */
/* Karte in den Einstellungen → Datensätze */
.debug-card.is-active { border-color: rgba(var(--accent-rgb), 0.55); background: var(--accent-soft); }
.debug-card .action-row { flex-wrap: wrap; gap: 8px; }
.debug-card form { display: inline-flex; }

/* Dauerhafter Hinweis in der Topbar */
.debug-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--gold);
    background: color-mix(in srgb, var(--gold) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
    white-space: nowrap;
}
.debug-pill:hover { background: color-mix(in srgb, var(--gold) 26%, transparent); text-decoration: none; }
.debug-pill svg { color: var(--gold); }

/* ---------- Kalender-Meldungen in der Seitenleiste (20.08.2026) ----------
   Bis dahin hing das als eigenes Icon in der Topbar (.cal-bar*, komplett
   entfallen). Jetzt sitzt alles am Kalender-Punkt der Navigation: rechts die
   Zahl der heute Abwesenden (normale .nav-count wie beim Notizbuch),
   DAVOR das goldene Warnzeichen, und beim Zeigen/Fokus geht
   der Aufklapper nach RECHTS auf – Variante 1 aus
   `_kalender-sidebar-vorschlaege.html`, von Sebastian gewählt.
   Warum `position: fixed` und ein paar Zeilen JavaScript statt reinem CSS:
   `.sidebar-nav` scrollt (overflow-y: auto) und schneidet alles ab, was aus ihr
   herausragt. app.js setzt deshalb top/left an der Zeile. Ohne JavaScript
   bleibt der Aufklapper weg – der Punkt führt aber weiterhin auf /kalender. */
.nav-cal { position: relative; }
/* Das Zeichen schiebt sich selbst nach rechts, die Zahl schließt dahinter an –
   sonst klebte es am Text und die Zahl säße nicht mehr am Rand. */
.nav-cal-flag { margin-left: auto; flex: none; color: var(--gold); font-size: 0.92rem; line-height: 1; }
.nav-cal-flag + .nav-count { margin-left: 6px; }
.nav-cal-panel {
    position: fixed; z-index: 80; display: none;
    width: 340px; max-width: calc(100vw - 40px); padding: 6px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 14px; box-shadow: var(--shadow);
}
.nav-cal-panel.is-open { display: block; }
/* Eine Zeile je Eintrag, notfalls abgeschnitten – umgebrochene Zeilen ließen die
   Liste zerfallen (Wunsch 18.08.2026). */
.nav-cal-panel a {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 9px; border-radius: 9px;
    font-size: 0.78rem; line-height: 1.4; color: var(--text);
}
.nav-cal-panel a > span:last-child {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nav-cal-panel a:hover { background: var(--surface-hover); text-decoration: none; }
.nav-cal-dot {
    flex: none; width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent);
}
.nav-cal-dot.is-warn { background: var(--gold); }
.nav-cal-dot.is-bad { background: var(--negative); }
.nav-cal-dot.k-urlaub { background: var(--abs-urlaub); }
.nav-cal-dot.k-krank  { background: var(--abs-krank); }
.nav-cal-dot.k-schule { background: var(--abs-schule); }
/* Der Aufklapper hat zwei Abschnitte: heute abwesend und Meldungen */
.nav-cal-sec {
    margin: 6px 9px 2px; font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--text-muted);
}
.nav-cal-sec:first-child { margin-top: 2px; }
/* Fehlende Vertretung an einer Abwesenheit (Wunsch 18.08.2026) */
.nav-cal-warn { color: var(--gold); margin-left: 4px; }
/* Kompaktmodus: der Text der Punkte ist weg, Zahl und Zeichen bleiben aber das
   Einzige, was den Kalender noch meldet – deshalb hier ausdrücklich sichtbar
   (die allgemeine Regel `html.sidebar-min .sidebar .nav-link span` blendet
   sonst jeden span im Punkt aus). Das Zeichen rutscht dabei an die linke obere
   Ecke, damit es sich nicht mit der Zahl überlagert. */
@media (min-width: 901px) {
    /* Gilt für ALLE Zähler: die Bubble am Icon war im Kompaktmodus bisher
       unsichtbar (auch beim Notizbuch) – die span-Regel oben
       ist spezifischer als der Positionsblock weiter unten, der sie eigentlich
       ans Icon setzt. Damit funktioniert der Kompaktmodus wieder wie gedacht. */
    html.sidebar-min .sidebar .nav-link .nav-count { display: block; }
    html.sidebar-min .sidebar .nav-cal .nav-cal-flag {
        display: block; position: absolute; top: 2px; left: 8px; margin: 0; font-size: 0.72rem;
    }
}
/* Mobil klappt nichts auf: dort gibt es kein Zeigen, und die Leiste liegt
   als Überlagerung über dem Inhalt. Der Punkt führt auf den Teamplaner. */
@media (max-width: 900px) {
    .nav-cal-panel { display: none !important; }
}

/* Kurzer Hinweis unter einer Seiten-Überschrift */
.page-head-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.page-head-main > h1 { margin: 0; min-height: 40px; line-height: 1.3; }
.head-hint {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-muted);
    transition: color 0.15s ease;
}
.head-hint svg { color: var(--accent); flex-shrink: 0; }
.head-hint:hover { color: var(--accent); text-decoration: none; }

/* Löschen-Box im Tab „QS-Auswertung“: sitzt abgesetzt unter dem Panel */
.qs-purge { margin-top: 24px; }

/* ---------- Einstellungen: Bereichs-Umschalter (Ebene 1) ----------
   Zwei große Bausteine (Copilot / QS-Auswertung) als segmentierter Schalter,
   die Unterpunkte darunter bleiben die gewohnten Tabs. */
.settings-switch {
    display: inline-flex;
    /* Seit 18.08.2026 sechs Bereiche: bei knapper Breite umbrechen statt überlaufen */
    flex-wrap: wrap;
    gap: 4px;
    padding: 4px;
    margin-bottom: 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.ss-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px;
    border-radius: 9px;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
    transition: background-color 0.15s ease, color 0.15s ease;
}
.ss-btn svg { color: var(--accent); }
.ss-btn:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.ss-btn.active { background: var(--accent-btn-gradient); color: #fff; box-shadow: var(--shadow-sm); }
.ss-btn.active svg { color: #fff; }
.ss-btn.active:hover { color: #fff; }

@media (max-width: 700px) {
    /* Vier Bereiche passen nicht mehr in eine Reihe – auf dem Telefon deshalb
       als 2x2-Raster, damit nichts abgeschnitten wird. */
    .settings-switch { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
    .ss-btn { justify-content: center; padding: 8px 10px; }
}

/* Karten-Kopf: Aktionen rechts (z. B. „Neue Gruppe“ an der Gruppenliste) */
.card-title-row .ct-actions { display: inline-flex; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.card-title-row > .muted + .ct-actions { margin-left: 12px; }

/* „Im QS-Modus öffnen“: Name der Person/Gruppe als dezenter Zusatz im Button */
.qs-profile-btn-scope {
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    font-size: 0.8rem;
    font-weight: 600;
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================
   Mobil (Telefon)
   Ziel: nichts läuft seitlich aus dem Bild, Aktionen liegen
   untereinander, Schriften und Abstände sind kompakter.
   Alle Farben weiterhin über die Theme-Variablen.
   ============================================================ */

/* Beschriftung des Vergrößern-Knopfes: am Desktop nur das Icon */
.chart-max-label { display: none; }

@media (max-width: 760px) {
    body { font-size: 14px; }
    h1 { font-size: 1.25rem; gap: 0.4em; }
    h2 { font-size: 0.98rem; }
    .content { padding: 8px 12px 40px; }

    /* Seitenkopf: Titel oben, Aktionen darunter über die ganze Breite */
    .page-head { flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
    .page-head .action-row,
    .page-head .head-actions { width: 100%; }
    .page-head .action-row .btn { flex: 1 1 auto; justify-content: center; }

    /* Karten & Raster kompakter */
    .card { padding: 14px; border-radius: 14px; }
    .card > h2, .card-title-row { margin-bottom: 12px; padding-bottom: 8px; }
    .grid { gap: 14px; }
    .stack { gap: 14px; }
    .grid-dashboard { gap: 16px; }

    /* Tab-Leisten: seitlich schiebbar statt umbrechend */
    .tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
    .tabs::-webkit-scrollbar { display: none; }
    .tab { padding: 9px 12px; font-size: 0.84rem; white-space: nowrap; }

    /* Karten-Kopf: Zusatzinfo und Aktionen unter die Überschrift */
    .card-title-row { flex-wrap: wrap; }
    .card-title-row > .muted,
    .card-title-row > .muted + .ct-actions,
    .card-title-row .ct-actions { margin-left: 0; width: 100%; }
    .card-title-row .ct-actions .btn { flex: 1 1 auto; justify-content: center; }

    /* Aktionsgruppen in Karten und Listen: volle Breite, untereinander */
    .sg-tools, .user-actions { width: 100%; }
    .sg-tools .btn, .sg-tools form, .user-actions .btn, .user-actions form { flex: 1 1 auto; justify-content: center; }
    .member-list > li { flex-wrap: wrap; }
    .member-actions { margin-left: auto; }

    /* Lange Wörter, Links und Namen brechen statt auszubrechen */
    .card, .modal, .timeline-item, .notif-panel { overflow-wrap: break-word; }

    /* Popups: schmalerer Rand, Knöpfe untereinander, Tabellen scrollbar */
    .modal-overlay { padding: 4vh 10px; align-items: flex-start; }
    .modal, .modal-entry, .modal-form, .modal.is-big { max-width: 100%; padding: 16px; }
    .modal .modal-head { margin: -16px -16px 14px; padding: 14px 46px 12px 16px; font-size: 0.95rem; }
    .modal-sec { padding: 12px 14px; gap: 12px; }
    .modal-actions-row { flex-direction: column; gap: 8px; }
    .modal-actions-row .btn, .modal-actions-row form { width: 100%; }
    .modal-full-btn { width: 100%; }
    .modal table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .modal .def-list { grid-template-columns: 1fr; }

    /* Diagramme: Vergrößern deutlich sichtbar und gut treffbar */
    .chart-max { width: auto; min-height: 34px; padding: 0 11px; gap: 7px; opacity: 1; font-size: 0.78rem; font-weight: 600; }
    .chart-max-label { display: inline; }
    .qs-chart-head { flex-wrap: wrap; gap: 8px; }

    /* Topbar: Debug-Hinweis kompakter, damit die Icons Platz behalten */
    .debug-pill { padding: 5px 9px; font-size: 0.7rem; }
    .topbar { gap: 8px; padding: 10px 14px; }
}

@media (max-width: 480px) {
    body { font-size: 13.5px; }
    h1 { font-size: 1.15rem; }
    .card { padding: 12px; }
    .tab { padding: 8px 10px; font-size: 0.8rem; }
    .btn { padding: 8px 13px; }
    .btn-sm { padding: 5px 9px; }
    .mini-stats > li { padding: 7px 10px; }
    /* „Im QS-Modus öffnen“: Name unter den Text statt daneben */
    .qs-profile-btn { flex-wrap: wrap; }
    .qs-profile-btn-scope { max-width: 100%; }
}

/* ============================================================
   Mobil, Teil 2: konkrete Stellen, die auf dem Telefon
   ausgebrochen sind (Gruppen-Seite, Benachrichtigungen, Topbar,
   Filter-Chips, Badges)
   ============================================================ */
@media (max-width: 760px) {
    /* --- Topbar: alles bleibt drin, notfalls in zwei Reihen --- */
    .topbar { flex-wrap: wrap; row-gap: 6px; padding: 8px 12px; }
    .topbar .btn-icon { padding: 8px; }
    .topbar .theme-toggle { flex-shrink: 0; }

    /* --- Benachrichtigungen: Panel am Bildschirm ausrichten, nicht am Glocken-Knopf --- */
    .notif-wrap { position: static; }
    .notif-panel {
        left: 10px;
        right: 10px;
        width: auto;
        max-width: none;
        top: calc(100% + 6px);
    }
    .notif-list { max-height: 60vh; }

    /* --- Gruppen-Zeile als kleines Raster: Icon + Name in einer Reihe,
       Avatare und Notiz-Info darunter (als Flexbox rutschte das Icon in eine
       eigene Zeile, sobald der Infotext lang wurde) --- */
    .group-row {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        align-items: center;
        gap: 8px 12px;
    }
    .group-row-icon { grid-row: 1; grid-column: 1; }
    .group-row-info { grid-row: 1; grid-column: 2; min-width: 0; }
    .group-row-info .muted { font-size: 0.78rem; }
    .group-row-stats {
        grid-row: 3;
        grid-column: 1 / -1;
        flex-direction: row;
        align-items: baseline;
        gap: 8px;
        margin-left: 0;
        text-align: left;
        font-size: 0.82rem;
    }
    .group-row-chevron { display: none; }
    

    /* --- Azubi-Liste als Karten: kompakt und ohne kryptische Häkchen ---
       Die drei Haken/X-Spalten (Rufnummer, Geburtstag, Arbeitsmodell) sind ohne
       Kopfzeile nicht lesbar – sie bleiben dem Desktop vorbehalten. */
    .table-cards tbody tr {
        display: grid;
        grid-template-columns: 1fr auto;
        align-items: center;
        gap: 6px 10px;
        padding: 10px 12px;
        margin-bottom: 8px;
    }
    
    .table-cards td:first-child { grid-column: 1; }
    .table-cards td:nth-child(2) { grid-column: 2; justify-self: end; }
    .table-cards td.mood { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; padding: 0; }
    .table-cards td.mood::before {
        content: attr(data-mlabel);
        min-width: 68px;
        font-size: 0.68rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--text-muted);
    }
    .table-cards .name-cell strong { font-size: 0.92rem; }

    /* --- Filter- und Chip-Reihen: seitlich schiebbar statt gequetscht --- */
    .tl-chips, .quick-dates {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 2px;
    }
    .tl-chips::-webkit-scrollbar, .quick-dates::-webkit-scrollbar { display: none; }
    .tl-chip, .chip { white-space: nowrap; flex: 0 0 auto; }

    /* --- Mehrere Badges: untereinander bzw. umbrechend, nie überlappend --- */
    .user-badges, .sg-badges, .timeline-head { flex-wrap: wrap; }
    .user-row { flex-wrap: wrap; }
    .user-badges { margin-left: 0; width: 100%; }
}

@media (max-width: 480px) {
    /* Debug-Hinweis nur als Symbol – sonst wird die Topbar zu voll */
    .debug-pill { padding: 6px; gap: 0; font-size: 0; }
    .debug-pill svg { width: 16px; height: 16px; }
    .table-cards td.mood::before { min-width: 60px; }
}

/* ============================================================
   Dashboard: Kopf mit Kontext, Abschnitte, Kennzahlen-Band,
   „Zu tun“, Team-Leiste, „Braucht Aufmerksamkeit“
   Alle Farben über die Theme-Variablen → Dark & Light.
   ============================================================ */

/* Die Kontextzeile unter der Begrüßung (`.dash-context` mit `.sep`, `.ctx-bad`,
   `.ctx-gold`) ist am 24.08.2026 den Chips gewichen – Regeln stehen weiter unten
   bei `.dash-chips`. **Nicht neu bauen.** */

/* Das Suchfeld auf der Startseite (`.dash-search`) ist am 24.08.2026 entfallen –
   die Schnellsuche steht jetzt als `.topbar-search` links in der Topbar und ist
   damit auf JEDER Seite erreichbar. **Nicht neu bauen.** */

/* Abschnitte: Überschrift, Linie, Hinweis rechts */
.dash-section { margin: 0 0 38px; }
.dash-section-head { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; }
.dash-section-head h2 {
    margin: 0; font-size: .76rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: .12em; color: var(--text-muted); white-space: nowrap;
}
.dash-section-head .rule { flex: 1; height: 1px; background: var(--border); }
.dash-section-head .hint { font-size: .76rem; color: var(--text-muted); white-space: nowrap; }

/* ---------- Kennzahlen-Band ----------
   Zwei Spalten, beide gleich hoch (align-items: stretch). Die Höhe gibt die
   Karte links vor, die Kachel rechts zieht sich darauf – deshalb hat rechts
   nichts eine feste Höhe. */
.kpi-band { display: grid; grid-template-columns: 2fr 1fr; gap: 18px; align-items: stretch; }
.kpi { display: flex; align-items: center; gap: 16px; color: var(--text); }
/* Kennzahlen-Kacheln: bewusst ohne Rahmenwechsel beim Überfahren */
a.kpi:hover { text-decoration: none; }
/* QS-Kachel: normaler Kartenrahmen, kein Hover-Effekt am Rahmen */

.kpi-title { font-size: .76rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); }

.kpi-trend { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; font-size: .84rem; font-weight: 700; }
.kpi-trend.is-ok { color: var(--positive); }
.kpi-trend.is-bad { color: var(--negative); }
.kpi-trend.is-neutral { color: var(--text-muted); font-weight: 500; }
.kpi-ico { width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center; flex-shrink: 0; }
.kpi-ico.ico-bad { background: var(--negative-soft); color: var(--negative); }
.kpi-ico.ico-accent { background: var(--accent-soft); color: var(--accent); }

@media (max-width: 900px) {
    .kpi-band { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
    .dash-section { margin-bottom: 26px; }
    .kpi { gap: 12px; }
    
    /* Auf dem Telefon zuerst die ruhigen Karten, dann die lange Timeline */
    .grid-dashboard { display: flex; flex-direction: column; }
    .grid-dashboard > .stack { order: -1; }
}

/* QS-Karte auf dem Dashboard: Kopf mit Zeitraum-Umschalter, zwei Ansichten */
.qs-kpi-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.qs-kpi-head .kpi-title { font-size: .82rem; }
.qs-kpi-head .quick-dates { margin-left: auto; }
/* Dezenter Hinweis rechts im Kopf: wann kamen zuletzt Prüfmails rein? */
.qs-kpi-import { margin-left: auto; font-size: 0.74rem; color: var(--text-muted); white-space: nowrap; }
/* Die ganze Karte ist der Link (12.08.2026) – der frühere Text
   „Zur Qualitätssicherung“ ist damit überflüssig. */
a.card.kpi-qs { display: flex; flex-direction: column; color: var(--text); }
/* Kein eigener Hover-Effekt: die Kachel daneben hat auch keinen */
a.card.kpi-qs:hover { text-decoration: none; }

/* Timeline-Kopfzeile: Datum, Bewertung und Zusatz-Icons stehen als Gruppe rechts.
   (Die Klasse .tl-rating wird auch vom Bewertungs-Filter benutzt – deren
   margin-left: auto darf hier nicht greifen, sonst rutscht das Badge allein.) */
.timeline-head .tl-meta {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.timeline-head .tl-rating { margin-left: 0; }

/* Verfasser der Zeile (12.08.2026): klein, grau, ganz rechts – gibt dem Eintrag
   einen Absender, ohne die Kopfzeile zu dominieren. */
.tl-author {
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
    opacity: 0.85;
}

/* Mehrere Hinweise unter einer Seiten-Überschrift (z. B. Sonderregelung) */
.head-hints { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.head-hint-gold { color: var(--gold); }
.head-hint-gold svg { color: var(--gold); }
.head-hint-gold:hover { color: var(--gold); }

/* Einklappbare Karten: Überschrift wie bei den übrigen Karten */
details.card-collapse > summary h2 {
    font-size: 0.88rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
    /* schmale Spalte: Badge darf umbrechen, das Icon nie schrumpfen */
    flex-wrap: wrap;
    row-gap: 5px;
}
details.card-collapse > summary h2 svg { color: var(--accent); flex: none; }

/* Profil- und Gruppen-Seite: Spalten getauscht – das Panel (QS-Diagramm,
   Logbuch/QS-Tabs) steht links und breit, die Info-Karten rechts und schmal.
   Umgesetzt über order, damit die Reihenfolge im HTML (und damit auf dem
   Telefon: erst Stammdaten, dann Timeline) unverändert bleibt. */
.grid-profile { grid-template-columns: 2fr 1fr; }
.grid-profile > .stack:first-child { order: 2; }
@media (max-width: 900px) {
    .grid-profile > .stack:first-child { order: 0; }
}

/* ---------- Datensätze bereinigen: Anzahl als Quadrat vor dem Titel ----------
   Zeigt auf einen Blick, wie viele Datensätze hinter der Kategorie stecken.
   Leere Kategorien werden gedimmt, damit die Zahl 0 nicht wie ein Alarm wirkt. */
/* Zeilen-Inhalt (Zahlenquadrat + Text) immer nebeneinander – gilt für alle
   Listen mit .history-list, nicht nur für die Datensätze-Liste. */
.history-list li > .purge-main,
.purge-list li > .purge-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.count-square {
    flex: 0 0 auto;
    min-width: 34px;
    height: 34px;
    padding: 0 7px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    background: color-mix(in srgb, var(--primary) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary) 34%, transparent);
    color: var(--primary);
    font-weight: 700;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.count-square.is-zero {
    background: var(--surface);
    border-color: var(--border);
    color: var(--text-muted);
}
@media (max-width: 480px) {
    .count-square { min-width: 30px; height: 30px; font-size: 13px; }
    .purge-list li > .purge-main { gap: 9px; }
}

/* Datensätze bereinigen (Stand 13.08.2026): Zeitraum-Leiste, Häkchen je
   Kategorie, Knopfzeile darunter. Die Liste selbst kommt aus der Purge-Registry
   der Module – hier steht nur die Optik. */
.purge-filter { margin-bottom: 10px; }
.purge-flabel { display: inline-flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: 0.86rem; }
.purge-flabel select, .purge-flabel input { width: auto; }
/* Die ganze Zeile ist das Label – klicken setzt das Häkchen */
.purge-list li > .purge-pick { cursor: pointer; flex: 1 1 auto; font-weight: 400; }
.purge-list li > .purge-pick.is-empty { cursor: default; opacity: 0.6; }
.purge-pick input[type="checkbox"] { flex: 0 0 auto; width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }
.purge-pick.is-empty input[type="checkbox"] { cursor: default; }
.purge-warn { font-size: 0.76rem; color: var(--gold); display: inline-flex; align-items: center; gap: 4px; }
.purge-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
/* Löschen sitzt rechts, deutlich abgesetzt von den Auswahl-Helfern */
.purge-actions .purge-go { margin-left: auto; }
@media (max-width: 560px) {
    .purge-actions .purge-go { margin-left: 0; width: 100%; justify-content: center; }
}

/* ============================================================
   Notizbuch (persönlich): Topbar-Panel, Zeilenliste, Profil-Box
   (Das Karten-Raster .nb-grid/.nb-card ist mit der Werkbank entfallen, die
   Regeln dafür sind am 17.08.2026 raus.)
   Farben ausschließlich über Custom Properties (Dark & Light).
   ============================================================ */

/* ---------- Farbmarkierungen einer Notiz ---------- */

/* ---------- Panel in der Topbar ---------- */
.notebook-wrap { position: relative; }
.notebook-panel {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    width: 330px;
    max-width: 85vw;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow);
    z-index: 60;
    overflow: hidden;
}
.nb-quick { padding: 12px 14px; display: flex; flex-direction: column; gap: 9px; }
.nb-quick textarea {
    width: 100%;
    resize: vertical;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 11px;
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
}
.nb-quick textarea:focus { outline: none; border-color: var(--accent); }
.nb-quick-foot { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
/* Geteilte Notizen (Migration 064): Badge in der Meta-Zeile und die
   Abschnitts-Überschrift „Von anderen geteilt" auf /notebook. */
.nb-shared {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 0.74rem; font-weight: 600;
    color: var(--accent); background: var(--accent-soft);
    border-radius: 999px; padding: 1px 8px; white-space: nowrap;
}
.nb-shared svg { vertical-align: -2px; }
.nb-public-field { align-items: flex-start; }
.nb-public-field > span { display: flex; flex-direction: column; gap: 2px; }
.nb-public-field .muted { font-weight: 400; font-size: 0.78rem; }
.nb-field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 12px; }

.nb-search {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 6px 12px;
    min-width: 240px;
}
.nb-search svg { color: var(--text-muted); flex-shrink: 0; }
.nb-search input {
    border: none;
    background: none;
    color: var(--text);
    font: inherit;
    font-size: 0.88rem;
    padding: 2px 0;
    min-width: 0;
    flex: 1 1 auto;
}
.nb-search input:focus { outline: none; }

.nb-pin {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-muted);
    padding: 2px;
    border-radius: 6px;
    display: inline-flex;
}
.nb-pin:hover { color: var(--gold); background: var(--surface-hover); }
.nb-pin.is-on { color: var(--gold); }
.nb-body {
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-muted);
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 8;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* Formatierte Notizen: gleiche Abstände wie im Eintrags-Popup (.note-content-html) */
.nb-body-rich p, .nb-body-rich div { margin: 0 0 6px; }
.nb-body-rich ul, .nb-body-rich ol { margin: 6px 0; padding-left: 20px; }
.nb-body-rich li { margin-bottom: 2px; }
.nb-body-rich > *:last-child { margin-bottom: 0; }
.nb-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.78rem; }
.nb-tag {
    background: var(--accent-soft);
    color: var(--accent);
    border-radius: 999px;
    padding: 2px 9px;
    font-weight: 600;
}
.nb-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--text-muted);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 2px 9px;
}
.nb-link:hover { color: var(--accent); border-color: var(--accent); }
.nb-edit {
    display: flex;
    flex-direction: column;
    gap: 12px;
    border-top: 1px solid var(--border);
    padding-top: 12px;
}
.nb-edit[hidden] { display: none; }

/* ---------- Leerer Zustand ---------- */
.nb-empty { display: flex; align-items: center; gap: 14px; }
.nb-empty-ico {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 12px;
    background: var(--accent-soft);
    color: var(--accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.nb-empty p { margin: 4px 0 0; font-size: 0.86rem; }

/* ---------- Box "Meine Notizen" in Profil & Gruppe ---------- */
.nb-box-hint { font-size: 0.8rem; margin: 0 0 10px; }
.nb-box-list { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.nb-box-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 8px 11px;
    font-size: 0.86rem;
}
.nb-box-list li a { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--text); }
.nb-box-list li a:hover { color: var(--accent); }
.nb-box-list li a span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nb-box-list li .muted { font-size: 0.76rem; white-space: nowrap; }
.nb-box-form { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.nb-box-form textarea {
    width: 100%;
    resize: vertical;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 9px 11px;
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
}
.nb-box-form textarea:focus { outline: none; border-color: var(--accent); }

/* ---------- Historie im Eintrag-Popup ---------- */
/* Knopf sieht aus wie der "Zuletzt bearbeitet"-Hinweis, ist aber klickbar */
.hist-toggle {
    display: block;
    background: none;
    border: none;
    padding: 0;
    margin-top: 2px;
    font-family: inherit;
    cursor: pointer;
    text-align: left;
    text-decoration: underline;
    text-decoration-style: dotted;
}
.hist-toggle:hover { color: var(--accent); }
.hist-list {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.hist-list > li {
    border-left: 2px solid var(--border);
    padding: 6px 0 6px 10px;
}
.hist-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 0.8rem; }
.hist-changes {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 6px;
}
.hist-changes li {
    font-size: 0.72rem;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
}
.hist-text {
    margin: 5px 0 0;
    font-size: 0.82rem;
    color: var(--text-muted);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
/* Trefferzahl im Filter-Chip (bisher nur im Notizbuch gestylt) */

/* ---------- Mobil ---------- */
@media (max-width: 760px) {
    .notebook-wrap { position: static; }
    .notebook-panel { left: 10px; right: 10px; width: auto; max-width: none; top: calc(100% + 6px); }
    .nb-search { width: 100%; min-width: 0; }
    
    .nb-field-row { grid-template-columns: minmax(0, 1fr); }
}

/* Feld-Zeile außerhalb von .form (Notizbuch-Formulare): gleiche Optik wie
   die Labels in .form – Beschriftung über dem Eingabefeld. */
.field { display: flex; flex-direction: column; gap: 5px; font-weight: 600; font-size: 0.86rem; }
.field .muted { font-weight: 400; }
.check { display: inline-flex; align-items: center; gap: 10px; font-size: 0.86rem; font-weight: 600; cursor: pointer; }
.check input[type="checkbox"] { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }

/* Schlagwort-Vorschläge im Notizbuch: vorhandene Wörter als kleine Chips
   unter dem Eingabefeld – ein Klick übernimmt sie (nochmal klicken leert). */
.nb-tagfield { gap: 7px; }
.nb-tagpicks { display: flex; flex-wrap: wrap; gap: 5px; }
.chip-sm { font-size: 0.72rem; padding: 2px 8px; }
.nb-tagfield label { display: flex; flex-direction: column; gap: 5px; }

/* Übernahme der Gruppen-Regelung: das zweite Häkchen samt Namensliste (17.08.2026).
   Gold, weil es um eine Warnung geht, nicht um einen Fehler – rot ist den
   Pflichtfeld-Meldungen vorbehalten. */
.wt-special-apply { color: var(--gold); }
.wt-special-hint {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    margin: -2px 0 0;
    font-size: 0.78rem;
    font-weight: 400;
    color: var(--text-muted);
}
.wt-special-hint svg { flex: none; margin-top: 2px; color: var(--gold); }

/* Pflichtfelder und Fehlermeldungen in Popups (17.08.2026).
   Das Sternchen sitzt an der Beschriftung, die Meldung unter dem Feld, die
   Sammelmeldung oben im Formular. Rot ist hier richtig: es IST der Fehler. */
/* Beschriftung samt Sternchen ist EIN Flex-Item – sonst rutscht der Stern in
   der Spalten-Ausrichtung von .form label in eine eigene Zeile. */
.form label > .lbl { display: block; }
.req { color: var(--negative); margin-left: 2px; font-weight: 700; }
.field-error {
    display: block;
    margin-top: 4px;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--negative);
}
/* Kein roter Rahmen am Feld (Wunsch Sebastian, 17.08.2026): das Sternchen an der
   Beschriftung und die Zeile „Bitte ausfüllen.“ darunter genügen. */
.form-errors {
    margin: 0 0 12px;
    padding: 9px 12px;
    border-radius: 10px;
    border: 1px solid color-mix(in srgb, var(--negative) 45%, var(--border));
    background: var(--negative-soft);
    color: var(--negative);
    font-size: 0.82rem;
    font-weight: 600;
}

/* Suche über dem Logbuch (17.08.2026). Seit dem 04.09.2026 steht sie allein in
   der Zeile und nimmt die volle Breite ein – die Zeitraum-Chips daneben
   (`.tl-find-range`, „3 Monate / 12 Monate / Alle") sind auf Wunsch entfallen,
   das Logbuch zeigt immer alles. **Nicht ohne Rücksprache neu bauen.** */
.tl-find { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.tl-find-input { flex: 1 1 auto; width: 100%; min-width: 0; }
.tl-find-input input { width: 100%; }

/* Ziel einer Sprungmarke kurz hervorheben (17.08.2026, siehe app.js) */
.jump-target { animation: jumpTarget 1.6s ease-out; }
@keyframes jumpTarget {
    0%   { background: var(--accent-soft); }
    100% { background: transparent; }
}
html.no-anim .jump-target { animation: none; }

/* ============================================================
   Sidebar-Navigation mit Unterpunkten
   Aufbau: .nav-group (Hauptpunkt + Unterliste) → .nav-row (Link + Pfeil)
   → .nav-sub-list (Unterpunkte). Im Kompaktmodus wird die Unterliste zum
   Flyout neben dem Icon; Zähler sitzen dann als Bubble am Icon.
   ============================================================ */
.nav-group { display: flex; flex-direction: column; }
.nav-row { display: flex; align-items: center; gap: 2px; }
.nav-row > .nav-link { flex: 1 1 auto; min-width: 0; }

/* Pfeil zum Auf-/Zuklappen – bewusst als eigener Knopf, damit der Klick auf
   den Namen weiterhin auf die Seite führt */
.nav-caret {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    color: var(--text-muted);
    border-radius: 8px;
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease, transform 0.2s ease;
    transform: rotate(0deg);
}
.nav-caret:hover { color: var(--accent); background: var(--surface-hover); }
.nav-caret[aria-expanded="true"] { transform: rotate(90deg); }

/* Zähler (offene Notizen; in Unterpunkten die Mitgliederzahl) */
.nav-count {
    flex: 0 0 auto;
    margin-left: auto;
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.7rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}
.nav-count.is-warn { background: var(--negative-soft); color: var(--negative); }
.nav-count.nav-count-soft { background: transparent; color: var(--text-muted); font-weight: 600; }

/* Titel der Unterliste: nur im Kompakt-Flyout sichtbar */
.nav-sub-title { display: none; }

/* Kompaktmodus (Desktop): Unterliste als Flyout neben dem Icon */
@media (min-width: 901px) {
    html.sidebar-min .nav-group { position: relative; }
    html.sidebar-min .nav-caret { display: none; }
    html.sidebar-min .nav-row { position: relative; }
    /* NUR in der Seitenleiste! `.nav-count` wird auch außerhalb benutzt – z. B.
       im Tab „Abwesenheiten" der Startseite (`.ag-tabs .nav-count`). Ohne das
       `.sidebar` davor sucht sich die Bubble dort den nächsten positionierten
       Vorfahren und klebt oben rechts in der Kartenecke; genau das war am
       04.09.2026 als einsame „1" über der Ereignis-Karte zu sehen.
       Der Kompaktmodus ist seit dem 03.09.2026 für alle an, also fiel es auf. */
    html.sidebar-min .sidebar .nav-count {
        position: absolute;
        top: 3px;
        right: 6px;
        margin: 0;
        min-width: 16px;
        padding: 0 4px;
        font-size: 0.62rem;
        line-height: 16px;
    }
    html.sidebar-min .nav-group:hover > .nav-sub-list,
    html.sidebar-min .nav-group:focus-within > .nav-sub-list {
        display: flex !important;      /* schlägt das hidden-Attribut */
        position: absolute;
        left: calc(100% + 8px);
        top: -6px;
        min-width: 200px;
        margin: 0;
        padding: 8px;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: 12px;
        box-shadow: var(--shadow);
        z-index: 70;
    }
    html.sidebar-min .nav-group > .nav-sub-list .nav-sub { padding-left: 24px; }
    html.sidebar-min .nav-group > .nav-sub-list .nav-sub span { display: inline; }
    html.sidebar-min .sidebar .nav-group > .nav-sub-list .nav-count {
        position: static;
        margin-left: auto;
        font-size: 0.68rem;
        line-height: normal;
    }
    html.sidebar-min .nav-group:hover > .nav-sub-list .nav-sub-title,
    html.sidebar-min .nav-group:focus-within > .nav-sub-list .nav-sub-title {
        display: block;
        padding: 2px 8px 6px;
        font-size: 0.7rem;
        font-weight: 700;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--text-muted);
    }
}

/* Mobil: etwas größere Tippflächen, Unterpunkte bleiben lesbar */
@media (max-width: 900px) {
    .nav-caret { width: 34px; height: 34px; }
    .nav-link.nav-sub { padding: 8px 10px 8px 24px; font-size: 0.86rem; }
    .nav-sub-list { margin-left: 18px; }
}

/* Ausgeblendete Gruppen in der Navigation (nur für Admins sichtbar):
   gleicher Punkt, nur dezent zurückgenommen und mit gestricheltem Rand. */
.nav-link.nav-sub-hidden { font-style: italic; opacity: 0.75; }
.nav-link.nav-sub-hidden::before { content: '⌀'; font-style: normal; font-size: 0.72rem; }

/* (sparkDraw/sparkDot gehörten zur Verlaufslinie der Kennzahlen und zur alten
   QS-Kachel – beide am 17.08.2026 entfallen, die Keyframes damit auch.) */

/* Kleine Partykanone am Ende der Linie (nur bei 100 %).
   Absolut statt fixed: die Koordinaten kommen als Seiten-Koordinaten aus
   app.js – so bleibt die Kanone beim Scrollen am Spark-Punkt kleben. */
.mini-pop { position: absolute; z-index: 5; pointer-events: none; } /* Deko-Ebene, siehe oben */
.mini-pop i {
    position: absolute;
    left: 0;
    top: 0;
    width: 6px;
    height: 6px;
    border-radius: 2px;
    animation: miniPop var(--dur, 0.9s) cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
@keyframes miniPop {
    0%   { transform: translate(0, 0) scale(0.6) rotate(0deg); opacity: 1; }
    70%  { opacity: 1; }
    100% { transform: translate(var(--tx), var(--ty)) scale(1) rotate(var(--rot, 180deg)); opacity: 0; }
}

/* Wer Animationen abbestellt hat, sieht die fertige Linie – ohne Bewegung */
html.no-anim .mini-pop { display: none; }

/* Der Zuspruch nach der Partykanone ("95 %, top!") ist am 19.08.2026 entfallen –
   das Konfetti reicht (Wunsch Sebastian). Mit ihm sind `.mini-cheer` und
   `@keyframes miniCheer` weg. Nicht ohne Rücksprache neu bauen. */

/* Erklärzeile unter einem Einstellungs-Feld (Dashboard anpassen) */
.set-hint { font-size: 0.78rem; margin: 2px 0 0; }

/* Knopfreihe über die ganze Breite (absence.io in den Einstellungen, 19.08.2026):
   vier gleich breite Knöpfe – je ein Viertel – mit Abstand nach oben und
   zueinander. Jeder Knopf steckt in einem eigenen <form> (eigene Route + CSRF),
   deshalb bekommen die Formulare die Rasterzelle und der Knopf die volle Breite. */
/* Zwei Knöpfe je Zeile (03.09.2026, Wunsch Sebastian – vorher vier): bei vier
   nebeneinander brachen die längeren Beschriftungen um und die Reihe wurde
   ungleich hoch. Der Abstand nach unten kam am selben Tag dazu, die Reihe klebte
   an der nächsten Box. **Nicht ohne Rücksprache zurück auf vier.** */
.set-btnrow {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    margin: 16px 0 22px;
}
.set-btnrow form { margin: 0; display: flex; }
.set-btnrow .btn { width: 100%; justify-content: center; }
@media (max-width: 560px) {
    .set-btnrow { grid-template-columns: 1fr; }
}

/* Zuordnungstabelle absence.io: Zeilen MIT hinterlegter Person grün markieren
   (Wunsch Sebastian 19.08.2026) – ein Häkchen im Auswahlfeld sah man beim
   Scrollen nicht. Farbband links + zarter Grünstich, damit es auch für
   Rot-Grün-Blinde eine Form und nicht nur eine Farbe ist. */
.abs-map-row.is-mapped > td:first-child { box-shadow: inset 3px 0 0 var(--positive); }
.abs-map-row.is-mapped > td { background: color-mix(in srgb, var(--positive) 9%, transparent); }
.abs-map-row.is-mapped select { border-color: color-mix(in srgb, var(--positive) 55%, var(--border)); }
.abs-map-legend { color: var(--positive); }

/* Backup-Karte (Einstellungen → Backups): Kopf mit Aktion, darunter die Liste */
.backup-card .count-square { color: var(--accent); }
.backup-card code { font-size: 0.86em; background: var(--surface-2); border-radius: 5px; padding: 1px 5px; }

/* Timeline: Name ohne Link (Azubi-Profil – immer dieselbe Person) und die
   Meldung einer Systemzeile, wenn sie im Kompaktmodus in die Kopfzeile rutscht */
.timeline-trainee.tl-name-self { pointer-events: none; }
.tl-event-title { color: var(--text-muted); font-size: 0.88rem; min-width: 0; overflow-wrap: anywhere; }

/* Benachrichtigungen schließen: X an der Zeile, "Alle schließen" im Kopf */
.notif-head { position: relative; }
.notif-clear {
    margin-left: auto;
    border: none;
    background: none;
    padding: 2px 4px;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    border-radius: 6px;
    white-space: nowrap;
}
.notif-clear, .notif-clear:hover { text-decoration: none; }
.notif-clear:hover { color: var(--accent); background: var(--surface-hover); }
.notif-list li { position: relative; padding-right: 34px; }
.notif-x {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--text-muted);
    border-radius: 6px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.notif-list li:hover .notif-x, .notif-x:focus-visible { opacity: 1; }
.notif-x:hover { color: var(--negative); background: var(--negative-soft); }
.notif-list .notif-empty { padding-right: 18px; }
/* Auf Touch-Geräten gibt es kein Hover – dort immer sichtbar */
@media (hover: none) {
    .notif-x { opacity: 1; }
}

/* ---------- Akzentfarbe im Profil ----------
   Farbfelder als Radiogroup: Verlaufs-Kachel plus Name, ausgewähltes Feld
   bekommt einen Ring in der Textfarbe (funktioniert bei jeder Farbe). */
.accent-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));   /* vier pro Zeile */
    gap: 10px;
    margin: 4px 0 10px;
}
.accent-opt {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: center;
    padding: 10px 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-2);
    cursor: pointer;
    transition: border-color 0.15s ease, transform 0.15s ease;
}
.accent-opt:hover { transform: translateY(-1px); border-color: var(--text-muted); }
.accent-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.accent-swatch {
    width: 100%;
    height: 34px;
    border-radius: 9px;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}
.accent-name { font-size: 0.76rem; font-weight: 600; color: var(--text-muted); text-align: center; }
.accent-opt:has(input:checked) {
    border-color: var(--text);
    box-shadow: 0 0 0 2px var(--text) inset;
}
.accent-opt:has(input:checked) .accent-name { color: var(--text); }
.accent-opt:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 620px) {
    .accent-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .accent-swatch { height: 28px; }
}

/* ---------- Profil: Gruppen und Dashboard-Bereiche ---------- */
.prof-group { display: flex; flex-direction: column; gap: 18px; }
.prof-group .dash-section-head { margin: 0; }
/* Der Knopf sitzt seit 03.09.2026 rechts in der Zeile mit der letzten Anmeldung
   (`.kt-fuss` schiebt ihn per `margin-left: auto` dorthin). Vorher war er über
   die ganze Breite und wirkte dadurch wie die Hauptsache der Karte – ist er
   nicht. **Nicht ohne Rücksprache wieder auf volle Breite.** */
.pw-toggle { flex: none; }

/* Bereiche des Dashboards: eine Zeile je Bereich, links Griff/Titel,
   rechts ein kleiner Aktiv/Aus-Regler (gleiche Optik wie .theme-seg). */
.dash-order { list-style: none; margin: 10px 0 12px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.dash-order-item {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 11px 13px;
    cursor: grab;
    transition: background-color 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
}
.dash-order-item:hover { background: var(--surface-hover); }
.dash-order-item.dragging { opacity: 0.4; box-shadow: var(--shadow); }
.dash-order-item.over { border-color: var(--accent); }
.dash-order-item.is-off { opacity: 0.6; }
.dash-order-item.is-off .dg-text strong { color: var(--text-muted); }
.dg-handle { display: inline-flex; color: var(--text-muted); flex-shrink: 0; cursor: grab; }
.dash-order-item:hover .dg-handle { color: var(--accent); }
.dg-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 9px;
    background: var(--accent-soft);
    color: var(--accent);
}
.dash-order-item.is-off .dg-ico { background: var(--surface); color: var(--text-muted); }
.dg-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: 0.88rem; }
.dg-text strong { line-height: 1.25; }
.dg-text .muted { font-size: 0.76rem; line-height: 1.35; }
.dg-seg { margin-left: auto; flex-shrink: 0; }

/* Kleine Variante des Segmented Controls – für Regler in Listenzeilen */
.theme-seg.seg-mini { gap: 2px; padding: 3px; }
.theme-seg.seg-mini .ms-btn {
    border: none;
    background: none;
    font: inherit;
    font-size: 0.76rem;
    padding: 5px 12px;
    border-radius: 999px;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.theme-seg.seg-mini .ms-btn:hover { color: var(--text); }
.theme-seg.seg-mini .ms-btn.is-on {
    background: var(--accent-btn-gradient);
    color: #fff;
    font-weight: 600;
    box-shadow: var(--shadow-sm);
}
@media (max-width: 760px) {
    .dash-order-item { flex-wrap: wrap; }
    .dg-text .muted { display: none; }
    .dg-seg { margin-left: auto; }
}
/* Zurücksetzen-Knopf unter der Bereichsliste */
.dash-order-reset { margin-top: 4px; }

/* Fragezeichen in der Topbar: Link auf /help. Der Punkt (Rückmeldung zu
   eigenem Feedback) sitzt absolut in der Ecke, deshalb position: relative. */
.topbar-help { position: relative; }
.topbar-help.is-active { color: var(--accent); }
/* Bausteine der Hilfe-Seite (früher Quick-Guide im Popup): Karten mit
   Abschnittstiteln und Kürzel-Tabellen. Die Karte bringt den Innenabstand mit. */
.help-cols {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 16px;
    align-items: start;
}
.help-card { padding: 18px 20px; }
.qg { padding: 0; }
.qg-sec {
    font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--text-muted); margin: 4px 0 8px;
}
.qg-sec + .qg-sec, .qg-keys + .qg-sec { margin-top: 16px; }
/* Die Listen-Bausteine des Quick-Guides (.qg-list/-ico/-txt/-dot) sind mit dem Tab
   am 19.08.2026 entfallen – geblieben sind Abschnittstitel, Kürzel-Tabelle und die
   Fußzeile darunter, die die Tastenkürzel-Seite weiter nutzt. */
.qg-keys { font-size: 0.82rem; }
.qg-keys td { padding: 6px 4px; }
.qg-foot { font-size: 0.74rem; margin: 12px 0 0; }

/* ---------- Suche: generische Treffer-Zeilen ----------
   Jeder Bereich (Personen, Anmerkungen, Notizbuch, QS …) benutzt dieselbe
   Zeile: optionaler Avatar, Titel + Zusatz, darunter ein Auszug. Farben
   ausschließlich über die Theme-Variablen. */
.search-item.has-body { align-items: flex-start; }
.search-item .search-body { flex: 1; min-width: 0; }
.search-item .search-body > strong { display: block; }
.search-meta { font-size: 0.8rem; font-weight: 400; }
.search-excerpt { font-size: 0.8rem; margin-top: 2px; overflow-wrap: anywhere; }
.search-item .badge { flex: none; align-self: center; }

/* ---------- Einstellungen → System → Prüfung (Smoke-Test) ----------
   Liste aller lesenden Seiten mit Statuspunkt. Läuft komplett im Browser
   (app.js), der Server liefert nur den Plan – siehe app/Core/Smoke.php. */
.smoke-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin: 14px 0 4px;
}
.smoke-progress { font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.smoke-summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    background: var(--neutral-soft);
    color: var(--neutral);
}
.smoke-summary.is-ok { background: var(--positive-soft); color: var(--positive); }
.smoke-summary.is-warn { background: var(--accent-soft); color: var(--accent); }
.smoke-summary.is-err { background: var(--negative-soft); color: var(--negative); }

.smoke-list { list-style: none; margin: 12px 0 0; padding: 0; }
.smoke-list li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    border-radius: 10px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    margin-bottom: 6px;
}
.smoke-list li.is-err { border-color: var(--negative); }
.smoke-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.smoke-main > strong { font-size: 0.9rem; }
.smoke-path { font-size: 0.78rem; overflow-wrap: anywhere; }
.smoke-state { font-size: 0.8rem; font-weight: 600; white-space: nowrap; }
.smoke-list li.is-ok .smoke-state { color: var(--positive); }
.smoke-list li.is-warn .smoke-state { color: var(--accent); }
.smoke-list li.is-err .smoke-state { color: var(--negative); }

/* Fehlermeldung als eigene Zeile unter dem Eintrag */
.smoke-list li.has-detail { flex-wrap: wrap; }
.smoke-detail {
    flex-basis: 100%;
    margin: 4px 0 0 26px;
    padding: 8px 10px;
    border-radius: 8px;
    background: var(--negative-soft);
    color: var(--text);
    font-size: 0.8rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow-wrap: anywhere;
}

/* Statuspunkt: grau (offen), pulsierend (läuft), grün/blau/rot (Ergebnis) */
.smoke-dot {
    flex: none;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--border);
    box-shadow: inset 0 0 0 1px var(--neutral-soft);
}
.smoke-dot-ok, .smoke-list li.is-ok .smoke-dot { background: var(--positive); box-shadow: none; }
.smoke-dot-warn, .smoke-list li.is-warn .smoke-dot { background: var(--accent); box-shadow: none; }
.smoke-dot-err, .smoke-list li.is-err .smoke-dot { background: var(--negative); box-shadow: none; }
.smoke-list li.is-running .smoke-dot {
    background: var(--accent);
    box-shadow: none;
    animation: smokePulse 0.9s ease-in-out infinite;
}
@keyframes smokePulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.35; transform: scale(0.7); }
}

/* Legende in der rechten Spalte */
.smoke-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.smoke-legend li { display: flex; align-items: flex-start; gap: 10px; font-size: 0.85rem; }
.smoke-legend .smoke-dot { margin-top: 5px; }

/* Die beiden Hinweislisten (übersprungen / ohne Beispieldaten) sind reine Info –
   bewusst leise und kompakt, damit sie neben den echten Ergebnissen zurücktreten */
.smoke-quiet { margin-top: 18px; padding-top: 12px; border-top: 1px dashed var(--border); }
.smoke-quiet-head {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    margin: 10px 0 4px; font-size: 0.8rem; font-weight: 600;
    letter-spacing: 0.02em; color: var(--text-muted);
}
.smoke-quiet-head:first-child { margin-top: 0; }
.smoke-quiet-head svg { opacity: 0.7; }
.smoke-quiet-head .muted { font-weight: 400; letter-spacing: 0; }
.smoke-quiet-list { list-style: none; margin: 0; padding: 0; }
.smoke-quiet-list li {
    display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
    padding: 4px 0 4px 19px; font-size: 0.85rem; color: var(--text-muted);
}
.smoke-quiet-list strong { color: var(--text); font-weight: 600; }
.smoke-quiet-list code { font-size: 0.78rem; }

html.no-anim .smoke-list li.is-running .smoke-dot { animation: none; opacity: 0.6; }

/* ============================= Zielerreichung (Modul Goals) =============================
   Alle Farben laufen über die Theme-Tokens bzw. color-mix mit transparent –
   Dark- und Lightmode brauchen deshalb keine eigenen Regeln. */

/* Diagramm-/Auswertungs-Karte in Profilen und Gruppen: die zwei Knöpfe im
   Kompaktmodus stehen nebeneinander und teilen sich die Breite (13.08.2026).
   auto-fit + minmax: bei nur einem Knopf füllt er die ganze Zeile, auf schmalen
   Bildschirmen rutschen sie untereinander – ohne eigene Media Query. */
.pnl-links { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; }
.pnl-links .btn { width: 100%; }
/* In der Kopfzeile stehen Zeitraum und (bei Gruppen) der Vergleichsmodus – die
   Grundregel steht oben bei .qs-chart-switches, hier nur die Abstände. */
.qs-chart-switches .tl-chips, .qs-chart-switches .quick-dates { margin: 0; }
/* Die Zeitraum-Leiste im Auswertungs-Panel füllt seit dem 04.09.2026 allein das
   Skript (nur Jahre mit Zahlen). Liegt für kein Jahr etwas vor, bleibt sie leer –
   dann soll sie auch keine Lücke in der Kopfzeile hinterlassen. */
#pnlRange:empty { display: none; }
/* Umschalter der Auswertung (QS ⇄ Zielerreichung): eigene Zeile links über dem
   Diagramm, damit die Kopfzeile nicht mit Chips zuläuft (13.08.2026). */
.pnl-metric-row { margin: 2px 0 14px; }
/* Die vier Kennzahlen der Zielerreichung stehen seit dem 04.09.2026 als eigene
   Chips in DERSELBEN Reihe (`.pnl-metric-row`) – die frühere zweite Zeile
   `.pnl-goal-row` ist entfallen. **Nicht wieder trennen.** Bei fünf Chips darf
   die Reihe umbrechen, das erledigt `.tl-chips` von sich aus. */

/* Überschrift mit Knöpfen/Pillen daneben. Beide Seiten, die das nutzen
   (Qualitätssicherung: .qs-headline, Zielerreichung: .head-line), sollen exakt
   gleich aussehen – deshalb liegen .icon-btn und .rail-lbl seit 13.08.2026 hier
   in app.css statt gescopet in qs.css. Unterschiedlich ist nur der Text.
   Die Mindesthöhe der h1 (40px, siehe .page-head h1) gilt weiter. */
.head-line { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-width: 0; }
.head-line h1 { margin-right: 4px; }
/* Knopf/Pille mit Icon + kleiner Beschriftung (z. B. „Letzter Import: …“) */
.icon-btn { display: inline-flex; align-items: center; gap: 6px; }
.rail-lbl { font-size: 10px; font-weight: 600; letter-spacing: 0; }
.head-line .btn svg, .qs-headline .btn svg { width: 17px; height: 17px; }

/* Kopfzeile rechts: Ansichts-Umschalter + "Werte eintragen" (wie in der QS).
   Die frühere Filterzeile .goal-filter ist am 13.08.2026 entfallen – Jahr und
   Person stehen jetzt im Popup hinter dem Filter-Icon in der Topbar. */
.goal-head-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.goal-head-actions .tl-chips { margin: 0; }

/* Abstand zwischen den Karten der Seite (Diagramm → Matrix).
   Die Kennzahlen-Kacheln (.goal-stats) sind am 12.08.2026 entfallen. */
.goal-chart-card { margin-bottom: 18px; }
.goal-matrix-card { margin-bottom: 18px; }

/* Bearbeiten-Seiten (Profil & Gruppe): volle Breite, Abschnitts-Layout –
   links deutliche Überschrift + Erklärzeile, rechts die Karte mit den Feldern */
.edit-grid { display: grid; gap: 22px; margin-bottom: 22px; }
.edit-section { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 22px; align-items: start; }
.edit-section-head { position: sticky; top: 76px; /* unter der Topbar stehen bleiben */ }
.edit-section-head h2 {
    display: flex; align-items: center; gap: 9px;
    margin: 0 0 6px; padding: 0; border: 0; font-size: 1.02rem;
}
.edit-section-head h2 svg { color: var(--accent); flex-shrink: 0; }
.edit-section-head .muted { margin: 0; font-size: 0.84rem; line-height: 1.5; }
.edit-section-body { min-width: 0; }
.edit-section-body .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.edit-section-body label { display: flex; flex-direction: column; gap: 5px; font-weight: 600; font-size: 0.86rem; margin-bottom: 14px; }
.edit-section-body label.check-label { flex-direction: row; align-items: center; gap: 10px; cursor: pointer; }
.edit-section-body .form-row label { margin-bottom: 14px; }
.edit-section-body > label:last-child, .edit-section-body .form-row:last-child label { margin-bottom: 0; }
.edit-actions .action-row { display: flex; gap: 10px; }
.edit-danger-title { color: var(--negative); }
.edit-danger-title svg { color: var(--negative) !important; }
@media (max-width: 900px) {
    .edit-section { grid-template-columns: 1fr; gap: 10px; }
    .edit-section-head { position: static; }
}

/* Gruppen-Übersicht: Profil-Lücken-Punkt */

@media (max-width: 900px) {
    .profile-pt-head { flex-wrap: wrap; }
}

/* Kopfzeile der Zielerreichungs-Karte: Knöpfe rechts neben dem Titel.
   Das Info-Popup „So entsteht die Punktzahl" und die Regeln dazu (.goal-info-*,
   .gi-*) sind am 02.09.2026 mit dem Prämien-Ranking entfallen. */
.goal-head-actions { display: flex; align-items: center; gap: 8px; }

/* Diagramm-Karte */
.goal-chart-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.goal-chart-head h2 { margin: 0; border: 0; padding: 0; }
.goal-metric-chips { margin: 0; }

/* Matrix Person × Monat/Quartal */
.goal-matrix-scroll { overflow-x: auto; }
.goal-matrix { border-collapse: collapse; width: 100%; min-width: 880px; }
.goal-matrix th, .goal-matrix td { padding: 6px 3px; text-align: center; border-bottom: 1px solid var(--border); }
.goal-matrix tbody tr:last-child th, .goal-matrix tbody tr:last-child td { border-bottom: 0; }
.goal-matrix thead th { color: var(--text-muted); font-size: 0.78rem; font-weight: 600; }
.goal-col-person { text-align: left !important; position: sticky; left: 0; z-index: 1;
    background: var(--surface); min-width: 172px; padding-right: 12px !important; }
.goal-col-avg { border-left: 1px solid var(--border); white-space: nowrap; }
.goal-col-avg small { color: var(--text-muted); }
.goal-person { display: inline-flex; align-items: center; gap: 9px; color: var(--text); min-width: 0; }
.goal-person:hover { text-decoration: none; color: var(--accent); }
.goal-person .avatar { flex-shrink: 0; }
.goal-person-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Zellen: IST groß, SOLL klein darunter; Ampel über die Tokens */
.goal-cell { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 100%;
    min-width: 54px; padding: 6px 3px; border-radius: 10px; border: 1px solid transparent;
    background: transparent; color: var(--text); font: inherit; }
button.goal-cell { cursor: pointer; transition: border-color 0.15s ease, background 0.15s ease; }
button.goal-cell:hover { background: var(--surface-hover); }
.goal-cell-main { font-weight: 700; font-size: 0.92rem; line-height: 1.15; }
.goal-cell-main small { font-weight: 500; color: var(--text-muted); font-size: 0.68rem; }
.goal-cell-sub { font-size: 0.67rem; color: var(--text-muted); white-space: nowrap; }
.goal-cell.g-ok   { background: color-mix(in srgb, var(--positive) 9%, transparent); }
.goal-cell.g-warn { background: color-mix(in srgb, var(--gold) 11%, transparent); }
.goal-cell.g-bad  { background: color-mix(in srgb, var(--negative) 10%, transparent); }
.goal-cell.g-ok .goal-cell-main   { color: var(--positive); }
.goal-cell.g-warn .goal-cell-main { color: var(--gold); }
.goal-cell.g-bad .goal-cell-main  { color: var(--negative); }

.goal-cell-add { color: var(--text-muted); opacity: 0.35; display: inline-flex; }
button.goal-cell:hover .goal-cell-add { opacity: 1; color: var(--accent); }
/* Personen ohne Werte in diesem Jahr (meist noch im Praktikum) stehen unten und
   sind abgedunkelt – beim Überfahren wieder voll da, damit sie bedienbar bleiben. */
.goal-row-empty { opacity: 0.55; transition: opacity 0.15s ease; }
.goal-row-empty:hover, .goal-row-empty:focus-within { opacity: 1; }

/* Zellen, in die nichts gehört: Zukunft (leer) und die Zeit vor dem
   Ausbildungsstart (Strich). Beide sind keine Knöpfe – hier gibt es nichts
   einzutragen, deshalb auch kein „+“ und kein Hover-Versprechen. */
.goal-cell-void { color: var(--text-muted); opacity: 0.3; font-weight: 400; }

/* Kennzahl-Varianten in den Zellen: die Chips über dem Diagramm setzen
   data-goal-metric an der Matrix-Karte, sichtbar ist nur die gewählte
   Variante (display: contents lässt die Kinder direkt im Zell-Flex sitzen). */
.goal-cm { display: contents; }
.goal-matrix-card .goal-cm-dlz,
.goal-matrix-card .goal-cm-projects,
.goal-matrix-card .goal-cm-sick { display: none; }
.goal-matrix-card[data-goal-metric="dlz"] .goal-cm-dlz,
.goal-matrix-card[data-goal-metric="projects"] .goal-cm-projects,
.goal-matrix-card[data-goal-metric="sick"] .goal-cm-sick { display: contents; }
.goal-matrix-card[data-goal-metric="dlz"] .goal-cm-ziel,
.goal-matrix-card[data-goal-metric="projects"] .goal-cm-ziel,
.goal-matrix-card[data-goal-metric="sick"] .goal-cm-ziel { display: none; }
/* Bei DLZ/Projekten/Krankheitstagen färbt der relative Farbverlauf (rot → gold → grün) die
   Zellen: --gc-dlz/--gc-proj setzt der Server je Zelle als style-Variable
   (Bestwert grün, schlechtester rot, Spanne = angezeigte Werte). Ohne Wert
   bleibt die Zelle neutral (Fallback transparent bzw. Textfarbe). */
.goal-matrix-card[data-goal-metric="dlz"] .goal-cell { background: color-mix(in srgb, var(--gc-dlz, transparent) 11%, transparent); }
.goal-matrix-card[data-goal-metric="projects"] .goal-cell { background: color-mix(in srgb, var(--gc-proj, transparent) 11%, transparent); }
.goal-matrix-card[data-goal-metric="dlz"] .goal-cell .goal-cell-main { color: var(--gc-dlz, var(--text)); }
.goal-matrix-card[data-goal-metric="projects"] .goal-cell .goal-cell-main { color: var(--gc-proj, var(--text)); }
/* Krankheitstage (25.08.2026): 0 Tage grün, wenige gold, viele rot – die Skala
   startet immer bei 0, nicht beim kleinsten angezeigten Wert (--gc-sick). */
.goal-matrix-card[data-goal-metric="sick"] .goal-cell { background: color-mix(in srgb, var(--gc-sick, transparent) 11%, transparent); }
.goal-matrix-card[data-goal-metric="sick"] .goal-cell .goal-cell-main { color: var(--gc-sick, var(--text)); }
.goal-metric-label { font-weight: 500; }

/* Bonus-Chip in der Quartalsansicht */
.goal-bonus { display: inline-flex; align-items: center; gap: 3px; font-size: 0.64rem; font-weight: 600;
    padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.goal-bonus-yes  { color: var(--positive); background: color-mix(in srgb, var(--positive) 14%, transparent); }
.goal-bonus-no   { color: var(--negative); background: color-mix(in srgb, var(--negative) 12%, transparent); }
.goal-bonus-open { color: var(--text-muted); background: color-mix(in srgb, var(--text-muted) 12%, transparent); }

/* Legende unter der Matrix */
.goal-legend { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.78rem; margin: 12px 0 0; }
.goal-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-left: 6px; }
.goal-dot:first-child { margin-left: 0; }
.goal-dot.g-ok   { background: var(--positive); }
.goal-dot.g-warn { background: var(--gold); }
.goal-dot.g-bad  { background: var(--negative); }

/* Löschen im Popup: klar vom Speichern-Formular abgesetzt */
.goal-delete-form { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);
    display: flex; justify-content: flex-end; }
/* .goal-form-hint ist am 13.08.2026 entfallen – der Hinweis im Zielwerte-Popup
   nutzt jetzt .modal-sec-hint wie in allen anderen Bereichs-Boxen. */

/* Schnell-Einfügen im Eintrags-Popup: eine Excel-Zeile, Felder füllen sich selbst */
.goal-paste-label textarea {
    resize: none; min-height: 38px; font-size: 0.82rem; white-space: pre; overflow-x: auto;
}
.goal-paste-hint { margin: -6px 0 0; font-size: 0.78rem; }

/* Einfüge-Feedback im Zielwerte-Popup: Haken am Label + grüne Umrandung der
   übernommenen Felder (gelbes "?" an der Person, wenn der Name nicht passt) */
#goalModal .form label { position: relative; }   /* Anker für den Haken */
.goal-check {
    position: absolute; top: 0; right: 0;
    display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px; border-radius: 50%;
    background: var(--positive-soft); color: var(--positive);
    font-size: 0.68rem; font-weight: 800; line-height: 1;
    animation: goalCheckIn 0.25s ease;
}
.goal-check.is-warn { background: color-mix(in srgb, var(--gold) 18%, transparent); color: var(--gold); }
@keyframes goalCheckIn { from { transform: scale(0.3); opacity: 0; } }
#goalModal input.goal-filled, #goalModal select.goal-filled {
    border-color: var(--positive);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--positive) 16%, transparent);
}
#goalModal select.goal-filled-warn {
    border-color: var(--gold);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 16%, transparent);
}
.goal-paste-hint.is-error { color: var(--negative); }

/* Mehrere Monate einfügen (Stand 13.08.2026): Vorschau im Popup, bevor
   gespeichert wird. Farbcode je Zeile – neu (grün), unverändert (grau),
   weicht ab (rot, wird überschrieben). Die einzelnen abweichenden Zellen sind
   zusätzlich markiert und tragen den alten Wert im Tooltip. */
.goal-bulk-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.goal-bulk-head strong { font-size: 1rem; }
.goal-bulk-person { margin-bottom: 12px; }
.goal-bulk-person select { width: 100%; }
.goal-bulk-scroll { max-height: 46vh; overflow: auto; border: 1px solid var(--border); border-radius: 12px; }
.goal-bulk-table { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
.goal-bulk-table th, .goal-bulk-table td { padding: 7px 10px; text-align: right; white-space: nowrap; }
.goal-bulk-table th:first-child, .goal-bulk-table td:first-child { text-align: left; }
.goal-bulk-table thead th {
    position: sticky;
    top: 0;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-muted);
}
.goal-bulk-table tbody tr + tr td { border-top: 1px solid var(--border); }
.goal-bulk-table tbody tr:hover td { background: var(--surface-hover); }
.goal-bulk-status { font-weight: 600; font-size: 0.76rem; }
/* Status sitzt hinter dem Monat (3. Spalte) und liest sich linksbündig besser */
.goal-bulk-table th:nth-child(3), .goal-bulk-table td.goal-bulk-status { text-align: left; }
.goal-bulk-table tr.is-new .goal-bulk-status { color: var(--positive); }
.goal-bulk-table tr.is-same .goal-bulk-status { color: var(--text-muted); }
.goal-bulk-table tr.is-diff .goal-bulk-status { color: var(--negative); }
/* Nur die Zelle, die sich unterscheidet – nicht die ganze Zeile einfärben */
.goal-bulk-changed { color: var(--negative); font-weight: 600; }
/* Aufklapp-Pfeil in einem Knopf (dreht sich, wenn der Bereich offen ist).
   Global, damit nicht jede Seite ihr eigenes Dreieck baut. */
.tg-ico { display: inline-block; transition: transform 0.15s ease; }
.is-open > .tg-ico { transform: rotate(90deg); }
/* „Werte von Hand eintragen“ im Zielerreichungs-Popup: der Knopf sitzt zwischen
   Person und den Feldern, deshalb etwas Luft nach oben */
.goal-manual-toggle { align-self: flex-start; margin-top: 2px; }

/* Merker über der Liste: laufenden Monat vorab abwählen */
.goal-bulk-opt {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 12px;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-2);
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
}
.goal-bulk-opt input[type="checkbox"] { flex: 0 0 auto; width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.goal-bulk-opt .muted { font-weight: 400; }

/* Häkchen-Spalte: abgewählte Monate werden nicht gespeichert (vor allem der
   laufende Monat – dessen IST-Wert ist ja noch unfertig) */
.goal-bulk-pick { width: 34px; text-align: center !important; }
.goal-bulk-pick input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; vertical-align: middle; }
.goal-bulk-table tr.is-skip td { opacity: 0.45; text-decoration: line-through; }
.goal-bulk-table tr.is-skip td.goal-bulk-pick { opacity: 1; text-decoration: none; }
/* Der laufende Monat: goldene Kante an der Monatsspalte plus Hinweis „läuft noch“ */
.goal-bulk-table tr.is-current td.goal-bulk-pick + td { box-shadow: inset 2px 0 0 var(--gold); }
.goal-bulk-current {
    display: inline-block;
    margin-left: 7px;
    padding: 1px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--gold) 18%, transparent);
    color: var(--gold);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.goal-bulk-note { margin: 10px 0 0; font-size: 0.8rem; }
.goal-bulk-note.is-error { color: var(--negative); }
.goal-bulk-actions { margin-top: 14px; gap: 8px; }

@media (max-width: 720px) {
    .goal-head-actions { width: 100%; }
    .goal-chart-head { flex-direction: column; align-items: flex-start; }
}

/* QS-Import-Punkt in der Timeline: gold statt grau (10.08.2026) */
.tl-dot-event.tl-dot-qs {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 45%, var(--border));
    background: color-mix(in srgb, var(--gold) 12%, var(--surface-2));
}

/* ============================================================
   Dashboard: mehr Luft (13.08.2026, Sebastians Wunsch „alles wirkt
   gequetscht"). BEWUSST nur auf der Startseite: alle Regeln hängen an
   .dash-section bzw. .grid-dashboard, damit Karten und Listen im Rest
   der App unverändert bleiben. Wer die Werte anfasst, prüft das
   Dashboard in Dark UND Light und auf einem schmalen Fenster.
   ============================================================ */
.dash-section { margin-bottom: 48px; }
.dash-section:last-child { margin-bottom: 8px; }
.dash-section-head { margin-bottom: 20px; }

/* Karten der Startseite: mehr Polsterung als die Standardkarte (20px) */
.dash-section .card { padding: 26px; }
.dash-section .card > h2 { margin-bottom: 18px; padding-bottom: 12px; }
.dash-section .card-title-row { margin-bottom: 18px; }

/* Abstände zwischen den Kacheln und Spalten */
.kpi-band { gap: 24px; }
.grid-dashboard { gap: 32px; }
.grid-dashboard > .stack { gap: 24px; }
/* Rechte Spalte bleibt bei 0.86rem und bei der normalen Polsterung: mit 26px
   und größerer Schrift wurden die Einträge in „Anstehend" abgeschnitten
   („wechselt in ‚2. Lehrja…"). Die Luft kommt dort über die Abstände. */
.grid-dashboard > .stack .card { padding: 20px; }

/* Anwesenheits-Karte im Profil (18.08.2026): EIN Monatsraster Mo–Fr in der
   schmalen rechten Spalte (~300px). Je Tag entweder eine Abwesenheit (Farbe der
   Art plus Buchstabe U/S/K, dieselben Tokens wie im Kalender) oder eine
   Office-Buchung in der Akzentfarbe mit „O". Die Wochengrafik darüber ist am
   18.08.2026 entfallen – der Monat zeigt beides. */
.ow-card { padding: 14px 16px; }
/* Titel und Office-Zähler müssen in ~270px nebeneinander passen – sonst rutscht
   der Zähler in eine zweite Zeile und die Karte wirkt zerfahren. */
.ow-card .card-title-row { flex-wrap: nowrap; gap: 8px; }
.ow-card .card-title-row h2 { font-size: 0.88rem; }
.ow-card .card-title-row .muted { font-size: 0.72rem; white-space: nowrap; }
/* Die Titelzeile der Karte bringt ihre eigene Trennlinie mit – eine zweite
   direkt darunter sah nach zwei Karten aus. */
.ow-month { margin-top: 10px; }
/* Drei Spalten: Pfeil · Mitte · Pfeil. So bleibt der Monatsname mittig, auch
   wenn „Heute" dazukommt. */
.ow-month-head {
    display: grid; grid-template-columns: 22px 1fr 22px; align-items: center; gap: 6px;
    font-size: 0.7rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 6px;
}
.ow-mcenter { display: flex; align-items: center; justify-content: center; gap: 6px; min-width: 0; }
.ow-mlabel { white-space: nowrap; }
.ow-mlabel.is-current { color: var(--text); }
/* Pfeile: dasselbe Chevron wie im Kalender (zeigt nach rechts, „zurück" wird
   gedreht). „Heute" erscheint nur, wenn wir woanders stehen. */
.ow-mnav, .ow-mtoday {
    display: inline-flex; align-items: center; justify-content: center;
    height: 22px; border-radius: 6px; color: var(--text-muted); flex: none;
}
.ow-mnav { width: 22px; }
/* „Heute" soll als Schaltfläche lesbar sein und nicht als Teil des Monatsnamens */
.ow-mtoday { padding: 0 7px; font-size: 0.62rem; letter-spacing: 0.06em;
    border: 1px solid var(--border); background: var(--surface-2); }
.ow-mnav:hover, .ow-mtoday:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.ow-month-head > .ow-mnav:first-child svg { transform: rotate(180deg); }
.ow-month-head > .ow-mnav:last-child svg { transform: none; }
/* Fünf Tage plus eine schmale Spalte für den Abgleich mit dem Arbeitszeitmodell */
.ow-mrow { list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)) 13px;
    gap: 4px; margin: 0 0 4px; padding: 0; align-items: center; }
.ow-mflag { display: flex; align-items: center; justify-content: center; font-size: 0.68rem; }
.ow-warnmark { color: var(--gold); }
.ow-okmark { color: var(--positive); }
.ow-sum { display: inline-flex; align-items: center; gap: 5px; }
.ow-mhead li { font-size: 0.6rem; font-weight: 700; letter-spacing: 0.04em;
    color: color-mix(in srgb, var(--text-muted) 75%, transparent); text-align: center; }
.ow-mday {
    display: flex; align-items: center; justify-content: center;
    height: 20px; border-radius: 5px;
    background: var(--surface-2); border: 1px solid var(--border);
    font-size: 0.64rem; font-weight: 600; color: var(--text-muted);
}
.ow-mday.is-abs, .ow-mday.is-office { color: var(--text); font-weight: 700; }
.ow-mday.is-abs.k-urlaub { background: color-mix(in srgb, var(--abs-urlaub) 55%, transparent); border-color: var(--abs-urlaub); }
.ow-mday.is-abs.k-krank  { background: color-mix(in srgb, var(--abs-krank) 55%, transparent);  border-color: var(--abs-krank); }
.ow-mday.is-abs.k-schule { background: color-mix(in srgb, var(--abs-schule) 55%, transparent); border-color: var(--abs-schule); }
/* Office = Platz im Desksharing gebucht, deshalb die Primärfarbe (Wunsch 18.08.2026) */
/* Monatsplan im Profil: dieselbe Sache wie im Kalender, also auch dieselbe Farbe
   – zwei Farben für einen Zustand wären schlicht verwirrend (04.09.2026). */
.ow-mday.is-office { background: var(--abs-office); border-color: transparent; color: #fff; }
/* Tage der Nachbarmonate treten zurück – aber nur, wenn dort nichts steht, das in
   diesen Monat hineinreicht: eine Schulwoche über den Monatswechsel behält ihre
   Farbe (Wunsch 18.08.2026). */
.ow-mday.is-other { opacity: 0.4; }
/* Heute muss auf JEDEM Untergrund auffallen (19.08.2026): der Akzentring ging auf
   einem Office-Tag unter, der selbst in der Akzentfarbe liegt. Deshalb ein Ring in
   der Textfarbe (hell im Dark-, dunkel im Lightmode) plus ein weicher Akzent-Hof.
   Ein Punkt unter der Zahl war zusätzlich drin – der Rahmen genügt (Wunsch 19.08.2026). */
.ow-mday.is-today {
    border-color: transparent;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--text) 85%, transparent),
                0 0 0 5px color-mix(in srgb, var(--accent) 30%, transparent);
    font-weight: 700;
}
.ow-mday.is-today:not(.is-abs):not(.is-office) { color: var(--text); }
/* Stand der absence.io-Daten unter dem Raster; Klick lädt neu (25.08.2026). */
.ow-stand {
    display: flex; align-items: center; justify-content: center; gap: 5px;
    margin-top: 8px; font-size: 0.68rem; color: var(--text-muted);
}
.ow-stand:hover { color: var(--text); text-decoration: none; }
.ow-stand svg { opacity: 0.7; flex: none; }
/* Blättern ohne Seitenwechsel: kurz gedimmt, solange nachgeladen wird. */
.ow-card.is-loading .ow-month { opacity: 0.5; }
.ow-card .ow-month { transition: opacity 0.15s ease; }

/* ---------- Kalender (Modul Calendar, 18.08.2026) ----------
   Monatsraster, serverseitig gerendert. Farben kommen aus den Tokens, damit Dark
   und Light stimmen; Wochenenden und der heutige Tag sind die einzigen
   Hervorhebungen – Gold bleibt den Fälligkeiten vorbehalten. */
/* Blättern (18.08.2026): eine Einheit aus Pfeil · Heute · Pfeil, Optik wie die
   Bereichsleiste der Einstellungen – auf einen Blick als Steuerung erkennbar. */
.cal-nav {
    display: inline-flex; align-items: center; gap: 2px; margin-left: auto;
    padding: 4px; border-radius: 12px;
    background: var(--surface-2); border: 1px solid var(--border);
}
.cal-nav-btn, .cal-nav-now {
    display: inline-flex; align-items: center; justify-content: center;
    height: 32px; border-radius: 9px; color: var(--text-muted);
    font-size: 0.84rem; font-weight: 600;
}
.cal-nav-btn { width: 34px; }
.cal-nav-now { padding: 0 14px; }
.cal-nav-btn:hover, .cal-nav-now:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
.cal-nav-now.is-current { color: var(--accent); background: var(--accent-soft); }
/* Das Chevron zeigt nach unten – hier einmal nach links, einmal nach rechts drehen */
.cal-prev svg { transform: rotate(180deg); }
.cal-next svg { transform: none; }
/* „Stand …“-Zeile ist gleichzeitig der Weg zum Neuladen */
a.cal-meta { display: inline-flex; align-items: center; gap: 6px; }
a.cal-meta:hover { color: var(--text); text-decoration: none; }
a.cal-meta svg { opacity: 0.7; }
.cal-card { padding: 20px; }
.cal-meta { font-size: 0.78rem; }
/* Am 03.09.2026 mit dem alten Kartenkopf entfallen – **nicht ohne Rücksprache
   neu bauen**: `.cal-head` (eine Reihe für Titel, Stand, Umschalter und
   Schalter), `.cal-sub` (Untertitel „31.08.–11.10.2026" der Wochen-Sicht),
   `.cal-sicht` (Umschalter Monat · 6 Wochen) und `.cal-chips` (Kennzahlen als
   eigenes Band). Der neue Kopf steht im Block „Kartenkopf Variante A" weiter
   unten in dieser Datei. */
.dash-chip.is-warn > i { background: var(--warn-dot); }
.dash-chip.is-warn.is-on { border-color: color-mix(in srgb, var(--warn-dot) 55%, var(--border));
    background: color-mix(in srgb, var(--warn-dot) 10%, var(--surface)); }
.cal-warn {
    display: flex; align-items: center; gap: 8px; margin: 0 0 12px;
    padding: 9px 12px; border-radius: 10px; font-size: 0.84rem;
    background: var(--err-bg); color: var(--err-ink);
}
/* Die Rasteransicht (Monatsgitter mit Tageskästchen) ist am 19.08.2026 entfallen –
   mit ihr die Regeln .cal-grid/.cal-wd/.cal-day/.cal-num/.cal-chip/.cal-tip und der
   Ansichts-Umschalter .cal-views. Der Kalender hat nur noch den Teamplaner.
   **Nicht ohne Rücksprache neu bauen.** */

/* Legende (Farbe je Art) – bleibt, sie erklärt auch die Balken im Planer */
.cal-legend {
    list-style: none; display: flex; flex-wrap: wrap; gap: 14px;
    margin: 0 0 12px; padding: 0; font-size: 0.76rem; color: var(--text-muted);
}
.cal-legend li { display: inline-flex; align-items: center; gap: 6px; }
.cal-legend-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--surface-2); }
.cal-legend .k-urlaub .cal-legend-dot { background: var(--abs-urlaub); }
.cal-legend .k-krank .cal-legend-dot  { background: var(--abs-krank); }
.cal-legend .k-schule .cal-legend-dot { background: var(--abs-schule); }
.cal-legend .k-office .cal-legend-dot { background: var(--abs-office); }
/* Feiertag steht nur in der Legende, wenn der Monat einen hat (View) */
.cal-legend .k-feiertag .cal-legend-dot { background: var(--accent-2); }

/* ---------- Teamplaner (Kalender, 2. Ansicht – 19.08.2026) ----------
   Zeile je Person, je Abwesenheit EIN Balken über die Tage. Das Monatsraster
   wiederholt bei zwei Wochen Urlaub zehnmal denselben Namen; hier steht er einmal.
   Spaltenzahl kommt als --tp-tage aus der View (28–31 Tage). */
/* Der Office-Schalter steht seit 03.09.2026 in der Werkzeugleiste (.ch-rechts),
   nicht mehr am rechten Rand der Kopfzeile – die Regel .cal-office { margin-left:
   auto } ist damit entfallen. */

/* ---------- Kippschalter (Wunsch 19.08.2026: „Toggler statt Knopf")
   Bewusst ein Baustein für die ganze App, damit der nächste Schalter gleich
   aussieht. Funktioniert an einem <a> (Zustand steht in der Adresse, siehe
   Office im Kalender) genauso wie an einem <button>; der Zustand hängt an
   `.is-on`, dazu role="switch" + aria-checked für Screenreader.
   Die Bewegung erledigen Transitions – der globale
   `prefers-reduced-motion`-Block schaltet sie ab. */
.switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-muted);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
}
.switch:hover, .switch:focus-visible { color: var(--text); text-decoration: none; }
.switch-track {
    position: relative;
    flex: none;
    width: 34px;
    height: 18px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    transition: background-color 0.18s ease, border-color 0.18s ease;
}
.switch-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--text-muted);
    transition: transform 0.18s ease, background-color 0.18s ease;
}
.switch:hover .switch-track { border-color: var(--accent); }
.switch.is-on { color: var(--text); }
.switch.is-on .switch-track { background: var(--accent-gradient); border-color: transparent; }
.switch.is-on .switch-knob { transform: translateX(16px); background: #fff; }
/* Der Rahmen um den Planer scrollt seit 03.09.2026 in BEIDE Richtungen und ist
   in der Höhe gedeckelt. Das ist der Trick, mit dem Kopfzeile UND Namensspalte
   gleichzeitig stehen bleiben: beide kleben an DIESEM Rahmen (sticky top bzw.
   sticky left), nicht am Fenster. Vorher klebte nur die Kopfzeile, und auch das
   nur, wenn der Planer gar nicht scrollen musste (Klasse `is-fit`, entfallen).
   Der Deckel lässt oben Platz für Topbar, Seitenkopf und Kartenkopf. */
.tp-wrap {
    overflow: auto;
    /* `max(...)` statt eines festen min-height: bei wenigen Personen schrumpft
       der Rahmen auf den Inhalt (kein leerer Kasten), auf einem flachen Fenster
       bleiben trotzdem 320px übrig. Die 300px sind Topbar + Seitenkopf +
       Kartenkopf. */
    max-height: max(320px, calc(100vh - 300px));
    padding-bottom: 4px;
    /* Ohne das rutscht die stehende Namensspalte beim schnellen Schieben kurz mit */
    overscroll-behavior-x: contain;
}
/* Die Namensspalte bleibt beim seitlichen Schieben stehen (Wunsch Sebastian
   20.08.2026) – sonst sieht man auf schmalen Fenstern Balken ohne zu wissen,
   zu wem sie gehören. Sticky wirkt hier gegen den scrollenden .tp-wrap.
   `margin-right: -10px` plus gleiches Padding deckt die Spaltenlücke mit ab,
   sonst blitzen die Zellen im 10px-Spalt durch. Der Hintergrund MUSS deckend
   sein (--surface = Farbe der Karte). */
.tp-corner, .tp-name, .tp-sec-t {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--surface);
}
/* Die beiden Eckfelder sind leer – ohne `stretch` wären sie 0 hoch und die
   Tageszahlen würden beim Schieben darunter durchscheinen. */
.tp-corner { align-self: stretch; }
.tp-sec-t { display: block; }
/* Mindestbreite aus der Zahl der Tage rechnen (20.08.2026): mit festen 620 px
   quetschte der Monat 31 Spalten auf 14 px – die Wochentagskürzel klebten
   aneinander („SASOMODI…"), statt dass der Rahmen scrollt. 26 px je Tag ist die
   Breite, ab der „MO 20" noch lesbar bleibt; darunter schiebt man .tp-wrap. */
/* Seit 02.09.2026 rechnet die View die Spalten selbst (--tp-cols: Arbeitstag 1fr,
   Wochenende 0.5fr – Punkt 1) und die Mindestbreite gleich mit (--tp-min: 26 px je
   Arbeitstag, 13 px je Wochenendtag). Die Namensspalte ist FEST (--tp-namew),
   damit die als Block gebaute Kopfzeile (.tp-hdr) dieselbe Breite trifft. */
.tp-grid { --tp-namew: 170px; --tp-gut: 10px; display: grid; grid-template-columns: var(--tp-namew) 1fr; align-items: center;
    column-gap: 14px; row-gap: 3px; min-width: var(--tp-min, calc(184px + var(--tp-tage, 31) * 26px)); }
.tp-row { display: grid; grid-template-columns: var(--tp-cols, repeat(var(--tp-tage, 31), minmax(0, 1fr))); gap: 2px; }
.tp-head { align-items: end; }
/* Kopfzeile als ein Block (Punkt 4): innen dieselben zwei Spalten wie das Raster.
   Sie klebt am oberen Rand von .tp-wrap (`top: 0`) – seit 03.09.2026 ohne
   Messerei, weil der Rahmen selbst scrollt. Deckender Hintergrund, sonst
   scheinen die Zeilen beim Scrollen durch.
   Die Ecke oben links muss über BEIDEM liegen (Kopf und Namensspalte) – sie
   steckt in diesem Block, dessen z-index über dem der Namen liegt. */
.tp-hdr {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: var(--tp-namew) 1fr; align-items: end;
    column-gap: 14px; row-gap: 3px;
    position: sticky; top: 0; z-index: 4;
    background: var(--surface); padding-bottom: 3px;
}
/* Kalenderwochen über dem Kopf (Wunsch 19.08.2026): je Woche ein hinterlegter
   Block über ihre Tage. Bewusst zurückgenommen – er ordnet die Tage, er soll sie
   nicht überstrahlen. Randwochen können ein Tag breit sein, deshalb `overflow`. */
.tp-weeks { margin-bottom: 3px; align-items: stretch; }
.tp-week {
    font-size: 0.62rem; font-weight: 700; letter-spacing: 0.04em;
    color: var(--text-muted); text-align: center; padding: 2px 0 3px;
    border-radius: 5px; background: color-mix(in srgb, var(--surface-2) 55%, transparent);
    overflow: hidden; white-space: nowrap; font-variant-numeric: tabular-nums;
}
/* Kopfzeile: Wochentag über der Zahl. Beide am 19.08.2026 vergrößert (Wunsch
   Sebastian) – vorher waren sie so klein, dass man den Tag suchen musste. Die
   Wochentags-Kürzel stehen jetzt in Textfarbe statt gedämpft. */
.tp-num {
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    font-size: 0.78rem; color: var(--text); text-align: center; padding-bottom: 5px;
    line-height: 1.1; font-weight: 600;
}
.tp-wd { font-size: 0.66rem; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--text-muted); font-weight: 700; }
/* ---------- „Ruhiger Planer" (08.09.2026, Variante A aus `_kalender-neu-mockup.html`,
   von Sebastian aus drei Denkrichtungen gewählt) ----------
   Grundsatz: Abwesenheit ist das Einzige, das laut ist. Deshalb
   · ist das WOCHENENDE keine Spalte mehr, sondern eine schmale Rille (`.tp-gut`,
     --tp-gut = 10px, hauchdünne Linie in der Mitte) – die Wochen lesen sich als Blöcke;
   · ist Office ein kleiner grüner PUNKT (`.tp-o`) statt einer gefüllten Pille;
   · ist eine Abwesenheit EIN Segment über ihre Arbeitstage (`.tp-seg`, `grid-column:
     span`) mit dem Wort mittig und Abstand zum Rand – ab drei Tagen das Wort, sonst
     der Buchstabe;
   · steht unter dem Kopf die Zeile BESETZUNG (`.tp-bes`): Füllbalken je Tag, Gold/Rot
     bei dünner Besetzung – sie ersetzt die eingefärbte Tageszahl vom 03.09.2026;
   · lassen sich Gruppen am Titel zuklappen; zugeklappt zeigt die Titelzeile eine
     Wärme-Spur (`.tp-heat`, Anteil der Abwesenden in der Gruppe).
   Die Wochenend-Regeln (`.tp-num.is-we`, `.tp-cell.is-we`, 0.5fr-Spalten) sind damit
   entfallen. Die Zellen tragen keine eigene Fläche mehr – nur „heute" und Feiertag
   tönen; das Raster gibt die Rille vor, nicht das Kästchen. */
.tp-gut {
    align-self: stretch; justify-self: center;
    width: 1px; min-height: 100%;
    background: color-mix(in srgb, var(--border) 80%, transparent);
}
.tp-head .tp-gut, .tp-weeks .tp-gut { background: transparent; }
.tp-week.is-leer { background: transparent; }
/* Die dritte Zeile im Tageskopf trägt seit dem 03.09.2026 (abends) nur noch den
   Feiertags-Punkt. Davor stand hier ein gefüllter Kreis mit den Anwesenden
   (`.tp-abs` → `.tp-da`, Farbe nach den Abwesenden) – siehe den Block ganz unten,
   warum er weg ist.

   `min-height` bleibt: die Zeile steht auch leer da. Ohne Mindesthöhe stünden
   Tage mit und ohne Punkt unterschiedlich hoch und die Kopfzeile wackelt. */
.tp-da { font-size: 0.6rem; line-height: 1; min-height: 0.6rem; color: var(--text-muted); font-weight: 600;
    font-variant-numeric: tabular-nums; margin-top: 1px; display: inline-flex; align-items: center; justify-content: center; }
.tp-num.is-today .tp-da { color: #fff; opacity: 0.85; }
/* Monatswechsel in der Wochen-Sicht: feine Linie links vom 1., in Kopf und
   Zeilen (nicht durch einen Balken hindurch – ein Urlaub über den Wechsel
   bleibt ein Balken); der Monatsname steht im KW-Block darüber („KW 40 · Okt"). */
.tp-num.is-m1, .tp-cell.is-m1 { position: relative; }
.tp-num.is-m1::before, .tp-cell.is-m1:not([class*=" k-"])::before {
    content: ""; position: absolute; left: -2px; top: -2px; bottom: -2px; width: 1px;
    background: color-mix(in srgb, var(--text-muted) 55%, transparent);
}
/* „heute" im Kopf (03.09.2026, Variante A aus `_heute-mockup.html`, von
   Sebastian aus drei Vorschlägen gewählt): die Tageszahl steht auf einer
   GEFÜLLTEN Akzentkachel mit weißer Schrift – dieselbe Sprache wie der aktive
   Bereich in der Navigation. Vorher waren nur Schrift und Größe anders, das ging
   in einer Kopfzeile mit 31 Spalten unter.
   **Pflicht ist `--accent-btn-gradient`, nicht `--accent`:** hier steht Text auf
   der Fläche, und weiß auf `--accent` schafft im Dark nur 3,07:1
   (Kontrast-Abschnitt, 20.08.2026).
   Das Polster macht die Kachel; `.tp-head` richtet die Köpfe unten aus
   (`align-items: end`), die Kachel wächst also nach oben und die Zeile bleibt
   ruhig. */
.tp-num.is-today {
    background: var(--accent-btn-gradient);
    border-radius: 9px;
    padding: 4px 2px 5px;
    color: #fff;
    font-weight: 700;
}
.tp-num.is-today .tp-day { font-size: 1.02rem; line-height: 1; color: #fff; }
.tp-num.is-today .tp-wd { font-size: 0.7rem; color: #fff; opacity: 0.85; }
.tp-name {
    display: flex; align-items: center; gap: 6px; min-width: 0;
    font-size: 0.8rem; color: var(--text); padding: 2px 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-name:hover { color: var(--accent); text-decoration: none; }
/* Deckung der stehenden Spalte: das Padding schafft den Abstand zwischen Zahl
   und Trennstrich (Wunsch 20.08.2026), das negative Margin zieht die Fläche über
   die 14px Spaltenlücke – sonst blitzen beim Schieben die Zellen im Spalt durch.
   Diese Regel MUSS nach `.tp-name` weiter oben stehen, sonst gewinnt deren
   Padding und der Abstand ist wieder weg. */
.tp-corner, .tp-name {
    padding-right: 14px;
    margin-right: -14px;
    border-right: 1px solid var(--border);
}
/* `.tp-tage` (Zahl der Abwesenheitstage hinter dem Namen) ist am 03.09.2026
   entfallen – Wunsch Sebastian, die Namensspalte soll nur noch EIN Zeichen
   tragen: den orangen Warnpunkt am Zeilenende. **Nicht ohne Rücksprache neu
   bauen.** */
/* Buchstabe im Balken (U/S/K/O, Wunsch 19.08.2026) – dieselbe Sprache wie der
   Monatsplan im Profil. Klein und mittig; im Wochenende bleibt er leer. */
.tp-cell {
    height: 20px; border-radius: 6px; background: transparent;
    display: flex; align-items: center; justify-content: center;
    line-height: 1; color: var(--text);
}
/* Office = Platz im Desksharing gebucht: ein leiser Punkt in `--abs-office` (grün,
   04.09.2026), seit 08.09.2026 keine Pille mehr. Nur im Planer, nur wenn eingeschaltet. */
.tp-o { width: 7px; height: 7px; border-radius: 50%; background: var(--abs-office); opacity: 0.9; display: block; }
/* Abwesenheits-Segment: EIN Element über alle Arbeitstage der Woche. Das Wort
   steht mittig mit 8px Luft zum Rand (Wunsch Sebastian 08.09.2026: „nicht direkt am
   Rand, paar Pixel Abstand und mittig"). Anfang/Ende der Abwesenheit sind stärker
   gerundet, ein Wochenbruch (Rille) nur leicht – so sieht man, dass es weitergeht. */
.tp-seg {
    height: 20px; margin: 0 1px; border-radius: 4px;
    display: flex; align-items: center; justify-content: center;
    padding: 0 8px; overflow: hidden; min-width: 0;
    color: #fff; font-size: 0.68rem; font-weight: 600; line-height: 1;
    letter-spacing: 0.01em; white-space: nowrap;
}
.tp-seg > span { overflow: hidden; text-overflow: ellipsis; }
.tp-seg.is-start { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.tp-seg.is-end { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
.tp-seg.k-urlaub { background: var(--abs-urlaub); }
.tp-seg.k-krank  { background: var(--abs-krank); }
.tp-seg.k-schule { background: var(--abs-schule); }
/* Besetzung: Füllstand = Anteil der Anwesenden (--tp-h). Neutral in der Akzentfarbe;
   Gold/Rot NUR an dünn besetzten Tagen (30 % / 50 % der Angezeigten, wie bisher) –
   ein Tag ohne Farbe ist der Normalfall. Feiertage bleiben leer. */
.tp-bes-l { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--text-muted); align-self: end; padding-bottom: 6px; }
.tp-bes-row { padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.tp-bes { height: 20px; display: flex; align-items: flex-end; justify-content: center; padding: 0 3px; }
.tp-bes > span {
    display: block; width: 100%; max-width: 28px; height: 16px; border-radius: 4px;
    background: color-mix(in srgb, var(--surface-2) 80%, transparent);
    position: relative; overflow: hidden;
}
.tp-bes > span::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--tp-h, 0%);
    background: var(--accent); opacity: 0.7;
}
.tp-bes.is-eng > span::after { background: var(--gold); opacity: 0.9; }
.tp-bes.is-knapp > span::after { background: var(--negative); opacity: 0.9; }
/* Wärme-Spur der zugeklappten Gruppe (Anteil Abwesender, --tp-p in %) */
.tp-sec-row.is-closed .tp-heat {
    height: 14px; border-radius: 4px; margin-bottom: 2px;
    background: color-mix(in srgb, var(--accent) calc(var(--tp-p, 0) * 1%), transparent);
}
/* Die Tönung `is-grp g-*` („Tag steckt im Gruppenbalken darüber") ist am
   03.09.2026 mit den Gruppenbalken entfallen. Sie war leise und ohne Buchstaben
   und las sich als „ausgegraut" statt als „steht oben". Jede Person zeigt ihren
   Balken wieder selbst. **Nicht ohne Rücksprache neu bauen.** */
/* Heute: die Spalte ist leicht in der Akzentfarbe hinterlegt statt jedes Kästchen
   einzeln umrandet (Wunsch 19.08.2026 – die Rähmchen wirkten wie leere Eingabefelder).
   Auf einem farbigen Balken bleibt die Farbe des Balkens; dort genügt der große,
   hervorgehobene Tag im Kopf. */
.tp-cell.is-today, .tp-bes.is-today {
    background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
}
.tp-bes.is-today { border-radius: 6px; }
/* Wochenende (Regel 03.09.2026: „nichts einfärben"): seit 08.09.2026 gibt es dort
   keine Zelle mehr, nur die Rille – ein Balken bricht davor ab und läuft in der
   nächsten Woche als eigenes Segment weiter. */
/* Gruppen-Titelzeile: links der Name in der stehenden Spalte, rechts eine LEERE
   Tageszeile. Die Trennlinie läuft unter beiden Feldern; das negative Margin
   zieht sie über die Spaltenlücke, wie bei .tp-name. (Bis 03.09.2026 standen
   rechts die Gruppenbalken – siehe oben.) */
.tp-sec-t, .tp-sec-row { margin-top: 12px; padding-bottom: 4px; border-bottom: 1px solid var(--border); }
.tp-sec-t { font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--text-muted); align-self: end; padding-right: 14px; margin-right: -14px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
.tp-sec-t:hover, .tp-sec-t:focus-visible { color: var(--text); outline: none; }
/* Pfeil: offen zeigt er nach unten (das Icon zeigt nach rechts, deshalb gedreht),
   zugeklappt nach rechts. */
.tp-sec-t > svg { flex: none; transform: rotate(90deg); transition: transform 0.18s ease; opacity: 0.8; }
.tp-sec-t.is-closed > svg { transform: none; }
.tp-sec-t > span { overflow: hidden; text-overflow: ellipsis; }
/* Die Felder der Titelzeile bleiben unsichtbar – die Zeile ist nur Trennlinie;
   erst zugeklappt tragen sie die Wärme-Spur (siehe .tp-heat). */
.tp-sec-row .tp-gcell { background: transparent; }
/* `.tp-soll` (Office-Pflicht hinter dem Gruppennamen) ist am 19.08.2026 entfallen –
   die Zahl steht nur noch im Tooltip des Warnpunkts. */
/* Person liegt in einer Woche unter der Office-Pflicht: oranger Punkt hinter dem
   Namen (02.09.2026, vorher ein Warndreieck ⚠). Der Ring in Hintergrundfarbe
   setzt ihn von der Zeile ab – gleiche Bauart wie der Punkt an der Glocke.
   Welche Wochen fehlen, sagt der Tooltip (`data-tip-rows`). */
.tp-warn {
    position: relative;
    /* Ans ENDE der Zeile (03.09.2026): vorher stand er direkt hinter dem Namen
       und die Zahl der Abwesenheitstage rechts. Die Zahl ist weg, der Punkt
       nimmt ihren Platz – dadurch stehen alle Punkte untereinander und eine
       Zeile ohne Punkt ist auf einen Blick eine Zeile ohne Befund. */
    margin-left: auto;
    flex: none;
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--warn-dot);
    box-shadow: 0 0 0 2px var(--surface);
    cursor: help;
}
/* Ein 8-px-Punkt ist als Ziel zu klein: die Fläche zum Zeigen wird unsichtbar
   auf 16 px vergrößert. Nicht mehr – sonst schluckt sie den Tooltip des Namens
   direkt daneben (Abstand in `.tp-name` sind 8 px). */
.tp-warn::after {
    content: ""; position: absolute; inset: -4px; border-radius: 50%;
}
/* Spalte beim Überfahren durchgehend hervorheben (Skript setzt is-hot) */
/* ---------- Feiertage (Berlin, 20.08.2026) ----------
   Nur Anzeige: die Spalte bekommt eine leichte Tönung, unter der Tageszahl sitzt
   ein kleiner Punkt, der Name steht im Tooltip. Farbe ist `--accent-2` (die
   zweite Farbe des persönlichen Verlaufs) – bewusst NICHT Gold (gehört den
   Fälligkeiten) und nicht die Arten-Farben von Urlaub/Krank/Schule. Liegt ein
   Balken auf dem Tag, gewinnt der Balken; „heute" bleibt ebenfalls stärker. */
.tp-cell.is-feiertag:not([class*=" k-"]):not(.is-today) {
    background: color-mix(in srgb, var(--accent-2) 20%, var(--surface-2));
}
.tp-num.is-feiertag .tp-day { color: var(--accent-2); }
.tp-feier {
    width: 4px; height: 4px; border-radius: 50%;
    background: var(--accent-2);
    display: inline-block;
}
/* Feiertags-Punkt auf der gefüllten Kachel: weiß statt Akzentfarbe */
.tp-num.is-today .tp-feier { background: #fff; }

.tp-cell.is-hot, .tp-bes.is-hot, .tp-heat.is-hot { background: var(--surface-hover); border-radius: 6px; }
/* Spaltenkopf beim Überfahren (03.09.2026, Variante 1 aus `_heute-mockup.html`):
   bisher färbte sich nur die Schrift – ohne Fläche sah man das kaum. Jetzt
   bekommt der Kopf dieselbe Art Fläche wie die Zellen darunter und wird
   sichtbar Teil der Spalte. */
.tp-num.is-hot {
    color: var(--accent); opacity: 1;
    background: var(--surface-hover);
    border-radius: 8px;
}
/* Die getönte FLÄCHE hinter den Tageszahlen (Auslastung des Tages) hat am
   03.09.2026 einen halben Tag gelebt: erst als Verlauf (Variante B5 aus
   `_kalenderkopf-auslastung-mockup.html` und `_kalenderkopf-b-farbe-mockup.html`),
   dann in Stufen über der Schwelle. Am selben Abend **ersatzlos entfallen** –
   Wunsch Sebastian: „es reicht die Zahl darunter". Mit ihr sind `.tp-num.is-last`
   und die Variable `--tp-ton` weg. Geblieben ist allein die eingefärbte Zahl
   (siehe Block weiter unten). **Nicht ohne Rücksprache neu bauen** – ebenso wenig
   die verworfenen Varianten A/C (feste Stufen als Fläche) und E (Balken unter der
   Zahl) oder die Farbtöne Grau, Akzent und Rot für die Fläche. */

/* „heute" behält seine gefüllte Kachel – nur einen Hauch heller. MUSS nach der
   Regel darüber stehen, sonst überschreibt die Hover-Fläche die Kachel. */
.tp-num.is-today.is-hot {
    background: var(--accent-btn-gradient);
    filter: brightness(1.08);
    color: #fff;
}
@media (max-width: 760px) {
    .tp-grid { --tp-namew: 110px; min-width: calc(var(--tp-min, 990px) * 0.85); }
    .tp-name { font-size: 0.74rem; }
}

/* Abwesenheiten-Abschnitt der Startseite (18.08.2026): kompakt, EINE Zeile je
   Eintrag – Punkt, Name/Gruppe, Art als Pille, Zeitraum rechts. Laufende
   Abwesenheiten bekommen den Punkt in der Akzentfarbe, anstehende in Textfarbe;
   Gold bleibt den Fälligkeiten vorbehalten. Hover hebt nur den Hintergrund. */
.abs-h {
    margin: 16px 0 6px; font-size: 0.72rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted);
}
.abs-h:first-child { margin-top: 2px; }
.abs-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.abs-list li {
    display: grid; grid-template-columns: 8px 1fr auto auto; align-items: center; gap: 10px;
    padding: 7px 8px; border-radius: 10px; font-size: 0.88rem;
}
.abs-list li:hover { background: var(--surface-hover); }
.abs-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-muted); flex: none; }
.abs-now .abs-dot { background: var(--accent); }
.abs-who { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.abs-art {
    padding: 2px 9px; border-radius: 999px; white-space: nowrap;
    background: var(--surface-2); border: 1px solid var(--border);
    font-size: 0.72rem; font-weight: 700; color: var(--text-muted);
}
/* Dieselben Art-Farben wie im Kalender, damit man sie nicht zweimal lernen muss */
.abs-art.k-urlaub { background: color-mix(in srgb, var(--abs-urlaub) 20%, transparent); border-color: color-mix(in srgb, var(--abs-urlaub) 45%, transparent); color: var(--text); }
.abs-art.k-krank  { background: color-mix(in srgb, var(--abs-krank) 20%, transparent);  border-color: color-mix(in srgb, var(--abs-krank) 45%, transparent);  color: var(--text); }
.abs-art.k-schule { background: color-mix(in srgb, var(--abs-schule) 20%, transparent); border-color: color-mix(in srgb, var(--abs-schule) 45%, transparent); color: var(--text); }
.abs-when { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Schmal: Zeitraum rutscht unter den Namen, damit nichts abgeschnitten wird */
@media (max-width: 700px) {
    .abs-list li { grid-template-columns: 8px 1fr auto; row-gap: 2px; }
    .abs-list .abs-when { grid-column: 2 / -1; }
}

/* Fußzeile in einer Startseiten-Karte („Stand 11:39 Uhr · aus absence.io“):
   klein und zurückgenommen, sie erklärt nur die Herkunft der Daten. */
.dash-foot { margin: 12px 0 0; font-size: 0.78rem; }

/* Timeline und Terminliste auf der Startseite */
.dash-section .timeline { gap: 14px; margin-top: 12px; }
.dash-section .timeline-item { padding: 14px 16px; }
/* Dots auf die Titelzeile ausrichten (19.08.2026): die Startseite polstert die
   Einträge stärker (14px statt 12px, Systemmeldungen sogar statt 4px), die
   top-Werte der Dots hängen aber an der normalen Polsterung. Dadurch saßen die
   Punkte über der Mitte des Titels – bei Systemmeldungen wie dem QS-Import mit
   rund 10px am deutlichsten, bei Anmerkungen und Gruppen-Notizen mit rund 4px.
   Die Mitte der Titelzeile liegt hier bei 25,6px: top = 25,6 - halbe Dot-Höhe. */
.dash-section .tl-dot { top: 10.5px; }                  /* 30px hoch */
.dash-section .timeline-event .tl-dot { top: 10.5px; }  /* hebt das top:0 der Systemmeldungen auf */
.dash-section .tl-dot-team { top: 7.5px; }              /* 36px hoch */
.dash-section .tl-dot-milestone { top: 6.5px; }         /* 30px + 2px Rahmen */
.dash-section .deadline-list { gap: 10px; margin-top: 12px; }
.dash-section .deadline-list li { padding: 10px 12px; }

/* Schmales Fenster: die Extra-Polsterung wieder zurücknehmen, sonst bleibt
   für den Inhalt zu wenig Breite übrig */
@media (max-width: 900px) {
    .dash-section .card { padding: 18px; }
    .dash-section { margin-bottom: 34px; }
    .kpi-band { gap: 16px; }
    .grid-dashboard { gap: 22px; }
}

/* Diagramm-Plätze freihalten (13.08.2026): ApexCharts baut das Diagramm erst
   per JS nach dem Seitenaufbau. Ohne reservierte Höhe ist die Karte für einen
   Moment leer, alles darunter (Matrix, Logbuch) rutscht nach oben und springt
   beim Rendern wieder zurück – besonders sichtbar beim Wechsel Monate/Quartale
   in der Zielerreichung, weil der ein echter Seitenaufbau ist.
   Werte = die Höhe, die ApexCharts danach selbst setzt (320 + 15 bzw. 260 + 15).
   Bewusst nur :empty – steht in der Karte die Meldung „Keine QS-Projekte im
   Zeitraum", ist der Platzhalter weg und es entsteht kein leeres Loch. */
#goalChart:empty { min-height: 335px; }
#qsMonthlyChart:empty { min-height: 275px; }

/* ============================================================
   Auszubildende (13.08.2026, „Variante A1"): Reiter je Gruppe oben,
   darunter EINE Box mit Kopfzeile, Info-Leiste und Mitglieder-Tabelle.
   Vorher stand jede Gruppe als eigene Karte untereinander – man musste
   scrollen und sah nie alle Gruppen gleichzeitig.
   ============================================================ */
.grp-tabs { margin: 0 0 18px; gap: 8px; }

/* Kopfzeile der Gruppen-Box: Icon, Name, Badge, Anzahl, rechts der Knopf */
.grp-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.grp-head-icon {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 12px;
    background: var(--accent-soft);
    color: var(--accent);
    flex: none;
}
/* Nicht .card > h2: die Überschrift steckt in .grp-head und soll deshalb weder
   Trennlinie noch Großbuchstaben bekommen */
.grp-head h2 { margin: 0; font-size: 1.06rem; font-weight: 700; }
.grp-head-n { font-size: 0.84rem; }
.grp-head .btn { margin-left: auto; }
.grp-head .badge { margin-left: 0; }

/* Info-Leiste: Arbeitszeitmodell · Gruppeneinträge.
   Gleich breite Zellen, getrennt durch Linien – immer an derselben Stelle,
   damit man die Werte beim Reiterwechsel vergleichen kann. */
.grp-bar {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: 18px;
    padding: 4px 0;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--surface-2);
}
.grp-bar-i {
    flex: 1;
    min-width: 200px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 18px;
    border-right: 1px solid var(--border);
}
.grp-bar-i:last-child { border-right: 0; }
/* Beschriftung im Akzentverlauf – gleiche Sprache wie die Bereichs-
   Überschriften in den Popups (.modal-sec-h) */
.grp-bar-k {
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
@supports not (background-clip: text) {
    .grp-bar-k { -webkit-text-fill-color: currentColor; }
}
.grp-bar-v { font-weight: 700; font-size: 0.94rem; }
.grp-bar-v a { color: var(--accent); text-decoration: none; }
.grp-bar-v a:hover { text-decoration: underline; }
.grp-bar-s { font-size: 0.76rem; color: var(--text-muted); }

/* Tabelle sitzt direkt in der Box – die Trennlinie von .group-trainees
   braucht sie hier nicht, die Info-Leiste trennt schon */
.grp-panel .group-trainees { border-top: 0; padding: 0; }
.grp-panel .empty-state { margin: 0; }

@media (max-width: 760px) {
    .grp-bar-i { border-right: 0; border-bottom: 1px solid var(--border); }
    .grp-bar-i:last-child { border-bottom: 0; }
    .grp-head .btn { margin-left: 0; width: 100%; justify-content: center; }
}

/* ============================================================
   Notizbuch – „Werkbank" (13.08.2026, Variante A von Sebastian gewählt)
   Drei Spalten: Schiene, Trefferliste, Notiz. Alle Farben über Tokens,
   damit Dark und Light automatisch stimmen; die drei Notiz-Typen (Idee,
   Workflow, Merker) färben sich über die Variable --nbt (siehe .nb-t-*). Hover-Regel: Flächen ändern nur den
   Hintergrund, Akzentrahmen gibt es an Bedienelementen und am ausgewählten
   Eintrag. Keine Bewegung – deshalb braucht hier nichts eine Sonderregel für
   `prefers-reduced-motion`.
   ============================================================ */
/* Variante „C" (Sebastian, 20.08.2026, aus `_notizbuch-vorschlaege.html`,
   danach nachgeschärft): nur noch ZWEI Spalten – Schiene und Liste. Jede Notiz
   steht über die volle Breite untereinander; angeklickt öffnet sie sich als
   POPUP (.nb-note-modal), dort wird sie auch bearbeitet. Vorher standen hier
   drei feste Spalten, die unterhalb von 1240 px auseinanderfielen. */
.nb-wb {
    display: grid;
    grid-template-columns: 208px minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}
.nb-wb-list { min-width: 0; }

/* ---------- Schiene links ---------- */
.nb-wb-rail { position: sticky; top: 74px; }
.nb-rail-group { margin-bottom: 18px; }
.nb-rail-group:last-child { margin-bottom: 0; }
.nb-rail-h {
    margin: 0 0 6px 10px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.nb-rail-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 10px 7px 13px;
    border-radius: 9px;
    color: var(--text);
    font-size: 0.87rem;
}
/* Akzentkante wie in der Hauptnavigation: feste Höhe, wird nur ein- und
   ausgeblendet. Beim Hover gibt es bewusst keine Kante, nur die getönte
   Fläche – die Kante bleibt das Signal „hier stehst du". */
.nb-rail-item::before {
    content: "";
    position: absolute;
    left: 0; top: 50%;
    width: 3px; height: 62%;
    border-radius: 0 3px 3px 0;
    background: var(--accent);
    transform: translateY(-50%);
    opacity: 0;
    transition: opacity 0.15s ease;
}
.nb-rail-item:hover { background: var(--surface-hover); text-decoration: none; }
.nb-rail-item.active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}
.nb-rail-item.active::before { opacity: 1; }
.nb-rail-item svg { color: var(--nbt, var(--text-muted)); flex-shrink: 0; }
.nb-rail-item.active svg { color: var(--accent); opacity: 1; }
.nb-rail-item > span:not(.n) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nb-rail-item .n { margin-left: auto; font-size: 0.74rem; color: var(--text-muted); }
.nb-rail-item.active .n {
    color: var(--accent);
    font-weight: 700;
}
.nb-rail-item.active .nb-rail-hash { color: var(--accent); }
.nb-rail-hash { color: var(--accent); font-weight: 700; }

/* ---------- Notiz-Typen und Status ---------- */
.nb-t-idea { --nbt: var(--accent); }
.nb-t-flow { --nbt: var(--positive); }
.nb-t-todo { --nbt: var(--gold); }

.nb-type {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
    color: var(--nbt, var(--text-muted));
    background: color-mix(in srgb, var(--nbt, var(--neutral)) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--nbt, var(--neutral)) 32%, transparent);
}

/* ---------- Trefferliste (Mitte) ---------- */
.nb-list-count { margin: 0 0 8px 2px; display: flex; align-items: center; gap: 10px; }
/* Eine Notiz je Zeile über die volle Breite (Wunsch Sebastian 20.08.2026 –
   das Raster mit zwei Karten nebeneinander ist wieder raus). `min-width: 0` an
   den Kindern bleibt: ohne das nimmt sich die Karte ihre min-content-Breite
   (Titel + Typ-Pille) und sprengt die Spalte. */
.nb-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.nb-list > li { min-width: 0; display: flex; }
.nb-list > li > .nb-row { flex: 1; min-width: 0; }
.nb-row-top, .nb-row-meta, .nb-row-prev { min-width: 0; }
.nb-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-left: 3px solid color-mix(in srgb, var(--nbt, var(--border)) 70%, transparent);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text);
}
.nb-row:hover { background: var(--surface-hover); text-decoration: none; }
.nb-row.is-active { border-color: var(--accent); background: var(--accent-soft); }
.nb-row.is-active .nb-row-title { color: var(--accent); }
.nb-c-blue   { --nbt: var(--accent); }
.nb-c-violet { --nbt: var(--accent-2); }
.nb-c-green  { --nbt: var(--positive); }
.nb-c-yellow { --nbt: var(--gold); }
.nb-c-red    { --nbt: var(--negative); }
.nb-row-top { display: flex; align-items: center; gap: 7px; }
.nb-row-title {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
    font-size: 0.92rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.nb-row-pin { color: var(--gold); display: inline-flex; flex: none; }
.nb-row-prev {
    font-size: 0.82rem;
    color: var(--text-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.nb-row-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 0.74rem; color: var(--text-muted); margin-top: 2px; }
.nb-row-links { display: inline-flex; align-items: center; gap: 3px; }
.nb-row-date { margin-left: auto; white-space: nowrap; }
.nb-row .nb-tag { font-size: 0.74rem; padding: 0; border: 0; background: none; }

/* ---------- Detailspalte (rechts) ---------- */
/* Die geöffnete Notiz steckt seit dem 20.08.2026 in einem POPUP (Wunsch
   Sebastian) – vorher Detailspalte, kurzzeitig Blende. Der Rahmen dafür ist das
   normale `.modal-overlay` der App, damit Schließen per X, Klick daneben und
   Escape ohne Sonderweg funktionieren. Die Notiz selbst bringt schon eine
   `.card` mit; im Popup wird die also flachgelegt, sonst Karte in Karte. */
.nb-note-modal { max-width: 860px; padding: 0; }
.nb-note-modal .nb-wb-detail { display: block; }
.nb-note-modal .nb-detail-card {
    border: 0;
    background: transparent;
    box-shadow: none;
    padding: 24px 26px 22px;
    max-height: min(76vh, 900px);
    overflow-y: auto;
}
/* Das X des Popups sitzt oben rechts – die Badge-Zeile darunter braucht deshalb
   rechts etwas Luft, sonst liegt ein Schlagwort unter dem Knopf. */
.nb-note-modal .nb-detail-badges { padding-right: 30px; }
.nb-detail-card { padding: 20px; }

.nb-detail-badges { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 8px; }
/* `.nb-detail-titlerow` ist am 03.09.2026 entfallen: darin stand rechts neben dem
   Titel der Anheft-Knopf – im Popup also direkt unter dem X. Der Titel steht jetzt
   allein, der Knopf unten bei den Aktionen. **Nicht ohne Rücksprache zurück.** */
.nb-detail-title { margin: 0; font-size: 1.15rem; line-height: 1.3; overflow-wrap: anywhere; }
/* Falls eine Notiz weder Typ noch Schlagwort hat, ist die Badge-Zeile leer und der
   Titel rückt nach oben – dann braucht er selbst Luft vor dem X. */
.nb-note-modal .nb-detail-title { padding-right: 30px; }
.nb-badge-pin { color: var(--gold); border-color: color-mix(in srgb, var(--gold) 45%, transparent); }
.nb-badge-pin svg { color: var(--gold); }
/* Erstellt / Geändert / Sichtbarkeit als Label-Wert-Paare untereinander (14.08.2026):
   in einer Zeile mit „·" getrennt war nicht auseinanderzuhalten. Labels etwas blasser
   als die Werte – wirkt in Dark und Light gleich, weil beides von `muted` erbt. */
.nb-detail-meta {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 3px 12px;
    margin: 7px 0 16px;
    font-size: 0.78rem;
    line-height: 1.35;
}
.nb-detail-meta .nb-meta-k { font-weight: 600; opacity: 0.72; }
/* Der Anheft-Knopf im Popup ist seit 03.09.2026 ein ganz normaler `.btn.btn-icon`
   wie das Archiv daneben – er braucht keine eigene Form mehr, nur die Farbe für
   „ist an“. (Die Fassung in der Liste, `.nb-pin` weiter oben, bleibt unberührt.) */
.nb-detail-acts .nb-pin.is-on {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 50%, transparent);
    background: color-mix(in srgb, var(--gold) 14%, transparent);
}
.nb-detail-acts .nb-pin:hover { color: var(--gold); }

/* Bereichs-Boxen wie im Popup-Standard („Variante A") */
.nb-sec {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 13px 15px;
    margin-bottom: 12px;
}
.nb-sec-h {
    margin: 0 0 9px;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}
@supports not (background-clip: text) {
    .nb-sec-h { -webkit-text-fill-color: currentColor; }
}
.nb-sec .nb-body { font-size: 0.92rem; color: var(--text); }

/* Links als Kette von Chips */
.nb-linklist { display: flex; flex-direction: column; gap: 7px; }
.nb-linkchip {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    padding: 6px 11px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--surface);
    color: var(--text);
    font-size: 0.84rem;
}
.nb-linkchip:hover { border-color: var(--accent); background: var(--surface-hover); text-decoration: none; }
.nb-linkchip svg { color: var(--accent); flex: none; }
.nb-linkchip > span:first-of-type { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nb-linkchip-host { margin-left: auto; font-size: 0.74rem; color: var(--text-muted); white-space: nowrap; flex: none; }

.nb-detail-acts {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    border-top: 1px solid var(--border);
    padding-top: 13px;
}
/* Löschen steht abgesetzt ganz rechts (03.09.2026): es ist das einzige in der
   Reihe, das sich nicht zurücknehmen lässt, und klebte vorher am Bearbeiten. */
.nb-detail-acts .nb-act-weg { margin-left: auto; }

/* Bearbeiten-Formular unter den Aktionen */
.nb-edit { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 14px; }
.nb-edit[hidden] { display: none; }

/* ---------- Formular-Bausteine (Popup und Bearbeiten) ---------- */
.nb-typepicks { display: flex; flex-wrap: wrap; gap: 6px; }
/* Die Chips sind <label> und stehen im Formular – ohne diese Regel gewinnt
   `.form label { flex-direction: column }` und das Icon säße ÜBER dem Wort.
   Gewollt: Icon vorne, kleiner Abstand, dann der Text. */
.form label.nb-typepick,
.nb-typepick { display: inline-flex; flex-direction: row; align-items: center; gap: 3px; cursor: pointer; user-select: none; }
.nb-typepick input { position: absolute; opacity: 0; width: 0; height: 0; }
.nb-typepick svg { color: var(--nbt, var(--text-muted)); }
.nb-typepick:has(input:checked) {
    color: var(--nbt, var(--accent));
    border-color: color-mix(in srgb, var(--nbt, var(--accent)) 55%, transparent);
    background: color-mix(in srgb, var(--nbt, var(--accent)) 14%, transparent);
    font-weight: 600;
}
.nb-typepick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }
.nb-linkrows { display: flex; flex-direction: column; gap: 8px; }
/* .modal-sec ist ein Flex-Container (Spalte) – ohne das zieht sich der Knopf
   über die ganze Breite wie die Hauptaktionen unten im Popup */
.modal-sec > [data-nb-linkadd] { align-self: flex-start; }
.nb-linkrow { display: grid; grid-template-columns: 1.4fr 1fr auto; gap: 8px; align-items: center; }
.nb-linkrow input {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 9px;
    padding: 8px 11px;
    color: var(--text);
    font: inherit;
    font-size: 0.86rem;
    min-width: 0;
}
.nb-linkrow input:focus { outline: none; border-color: var(--accent); }

/* ---------- Schnellnotiz-Panel ----------
   Typ-Chips, der Haken „Diese Seite verlinken" und die Liste der letzten
   Notizen sind am 13.08.2026 wieder entfallen (Wunsch Sebastian: nur Textfeld
   und Speichern) – ihre Regeln sind damit weg. */

/* ---------- Schmaler (20.08.2026 neu geordnet) ----------
   Vorher fiel die Werkbank unter 1240 px auseinander: die Schiene wurde zur
   vollen Zeile mit `flex: 1 1 200px`, drei Gruppen brauchten damit mehr Platz
   als da war – die Seite lief bis zu 180 px über. Jetzt gibt es drei klare
   Stufen. */
@media (max-width: 1180px) {
    .nb-wb { grid-template-columns: 190px minmax(0, 1fr); }
}
/* Ab hier wird aus der Schiene eine Zeile mit Pillen, die seitlich schiebbar
   ist – gestapelte Gruppen hätten die halbe Seite gefressen. */
@media (max-width: 1040px) {
    .nb-wb { grid-template-columns: minmax(0, 1fr); }
    .nb-wb-rail {
        position: static;
        display: flex; align-items: center; gap: 7px;
        flex-wrap: nowrap;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scrollbar-width: thin;
        padding-bottom: 6px;
        margin-bottom: 4px;
    }
    .nb-rail-group { display: flex; align-items: center; gap: 6px; margin: 0; flex: none; }
    .nb-rail-h { margin: 0 2px 0 6px; white-space: nowrap; }
    .nb-rail-item {
        padding: 6px 12px;
        border: 1px solid var(--border);
        border-radius: 999px;
        background: var(--surface);
        white-space: nowrap;
        font-size: 0.8rem;
    }
    .nb-rail-item::before { display: none; }
    .nb-rail-item.active { border-color: var(--accent); }
    .nb-rail-item .n { margin-left: 2px; }
}
@media (max-width: 900px) {
    .nb-note-modal .nb-detail-card { padding: 18px; max-height: none; }
    .nb-linkrow { grid-template-columns: 1fr auto; }
    .nb-linkrow input:first-child { grid-column: 1 / -1; }
}

/* ============================================================
   Startseite – Kennzahlen „Bühne" (13.08.2026, Variante A)
   Links die Quote als große Zahl mit Aufschlüsselung daneben, rechts die Kachel
   „Beanstandungen" (gleich hoch). Regeln, die hier gelten:
   – EINE große Zahl pro Seite (die Quote); alles andere ist kleiner.
   – Zahlen stehen in Textfarbe, die Farbe sitzt im Punkt davor. Farbig ist
     nur der Vergleich zum Vormonat – dort IST die Farbe die Richtung.
   – Keine aneinanderliegenden Statusflächen (kein gestapelter Balken):
     Grün und Rot liegen bei Rot-Grün-Blindheit ΔE 3,1 auseinander, sind also
     direkt nebeneinander nicht unterscheidbar. Jede Zeile trägt ihr Wort.
   ============================================================ */
/* Rechte Spalte: seit 17.08.2026 nur noch die Kachel „Beanstandungen" – sie
   füllt die Spalte und steht damit oben und unten bündig mit der Karte links
   (grid-auto-rows: 1fr teilt die Höhe gleichmäßig auf, bei einer Kachel also
   ganz). Kommen wieder mehrere dazu, teilen sie sich die Höhe automatisch. */
.kpi-side { display: grid; gap: 24px; grid-auto-rows: 1fr; align-content: stretch; }

.kpi-stage { display: flex; gap: 34px; align-items: flex-start; flex-wrap: wrap; }
.kpi-stage-num { min-width: 190px; flex: 0 1 auto; }

/* Die große Zahl: proportionale Ziffern (tabular-nums lässt 121 auseinanderfallen) */
.kpi-hero { display: block; font-size: 3.6rem; font-weight: 700; line-height: 1; letter-spacing: -0.02em; }
/* Die große Zahl steht in Textfarbe und wird erst unter 80 % orange (Wunsch
   13.08.2026). Ein Orange-Token gibt es in der App nicht – Gold gehört den
   Fälligkeiten, Rot den Fehlern –, deshalb wird es aus beiden gemischt: das
   ergibt in Dark UND Light ein sattes Orange, das den Themes folgt.
   Das Prozentzeichen bleibt zurückgenommen, damit die Zahl trägt. */
.kpi-hero { color: var(--text); }
.kpi-hero-alarm { color: color-mix(in srgb, var(--gold) 62%, var(--negative)); }
.kpi-hero small { font-size: 0.42em; font-weight: 600; color: var(--text-muted); margin-left: 0.16em; }
.kpi-hero-sub { display: block; color: var(--text-muted); font-size: 0.86rem; margin-top: 6px; }
.kpi-stage-num .kpi-trend { margin-top: 12px; }
.kpi-trend .muted { font-weight: 500; }

/* Aufschlüsselung als Zeilen */
.kpi-rows { flex: 1 1 260px; min-width: 240px; display: flex; flex-direction: column; gap: 10px; }
.kpi-row {
    display: grid;
    grid-template-columns: 10px 116px minmax(0, 1fr) 36px;
    align-items: center;
    gap: 10px;
    font-size: 0.86rem;
}
.kpi-row-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--kpi-tone, var(--neutral)); }
.kpi-row-name { color: var(--text-muted); }
.kpi-row-bar { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--kpi-tone, var(--neutral)) 22%, var(--surface-2)); }
.kpi-row-bar span { display: block; height: 100%; border-radius: 999px; background: var(--kpi-tone, var(--neutral)); }
.kpi-row-val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.kpi-row-acc  { --kpi-tone: var(--accent); }
.kpi-row-ok   { --kpi-tone: var(--positive); }
.kpi-row-warn { --kpi-tone: var(--gold); }
.kpi-row-bad  { --kpi-tone: var(--negative); }
/* „Projekte geprüft" ist die Summe, und bei 0 gibt es nichts zu zeigen –
   dort steht bewusst keine Leiste */
.kpi-row-acc .kpi-row-bar, .kpi-row-bar.is-empty { background: none; }

/* Die Verlaufslinie unter der Quote (.kpi-plot) ist am 17.08.2026 entfallen –
   Wunsch Sebastian, die Kennzahlen sollen nur den Monat zeigen. Nicht ohne
   Rücksprache zurückholen. */
.spark-goal { stroke: var(--text-muted); stroke-width: 1; opacity: 0.5; }
.spark-hit { cursor: help; }
/* ---------- Beanstandungs-Kachel (Variante C, 20.08.2026) ----------
   Von Sebastian aus fünf Vorschlägen gewählt (`_kennzahlen-kachel.html`):
   Kopfzeile, darunter Hinweise und Fehler als zwei eigene Kästen mit eigener
   Zahl, unten die häufigste Kategorie als Knopf (öffnet alle Kategorien).
   Die frühere Summenzeile („8 von 117 Projekten") ist auf seinen Wunsch
   entfallen – nicht ohne Rücksprache zurückholen. */
.kpi-findings { display: flex; flex-direction: column; }
.bn-head { display: flex; align-items: center; gap: 10px; }
.bn-head .kpi-ico { width: 34px; height: 34px; border-radius: 11px; }
.bn-none { display: flex; align-items: center; gap: 8px; margin: 18px 0 0;
    font-size: 0.88rem; color: var(--text-muted); }
.bn-none svg { flex: none; color: var(--positive); }
/* Die zwei Kästen: je ein Link, gefiltert auf seinen Status */
.bnC-split { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 20px; }
.bnC-box { border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px;
    background: var(--surface-2); color: var(--text); }
.bnC-box:hover { background: var(--surface-hover); text-decoration: none; }
/* Eine Null führt nirgendwohin (04.09.2026): der Kasten steht dann als <span>
   im Markup statt als Link – hier nur die Optik dazu, damit er nicht anklickbar
   AUSSIEHT. Die Zahl bleibt in ihrer Farbe, gedämpft wird die Fläche. */
.bnC-box.is-leer { opacity: 0.65; cursor: default; }
.bnC-box.is-leer:hover { background: var(--surface-2); }
.bnC-box b { display: block; font-size: 1.9rem; font-weight: 700; line-height: 1.05; }
.bnC-box > span { display: flex; align-items: center; gap: 7px; margin-top: 4px;
    font-size: 0.8rem; color: var(--text-muted); }
.bnC-box i { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--bn-tone); }
.bnC-box b { color: var(--bn-tone); }
.bnC-warn { --bn-tone: var(--gold); }
.bnC-bad { --bn-tone: var(--negative); }
/* Fußzeile: häufigste Kategorie als Knopf */
.bn-foot { margin-top: auto; padding-top: 18px; }
.bn-cat-lbl { display: block; margin-bottom: 7px; font-size: 0.72rem; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); }
.bn-cat { display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
    padding: 6px 12px; border-radius: 999px; border: 1px solid var(--border);
    background: var(--surface-2); color: var(--text-muted); font: inherit;
    font-size: 0.8rem; font-weight: 600; cursor: pointer; text-align: left; }
.bn-cat:hover { border-color: var(--accent); color: var(--text); }
.bn-cat svg { flex: none; opacity: 0.8; }
.bn-cat b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--text); font-weight: 700; }
.bn-cat-n { flex: none; font-variant-numeric: tabular-nums; color: var(--text); }
.bn-cat-more { flex: none; padding: 1px 7px; border-radius: 999px;
    background: var(--accent-soft); color: var(--accent); font-size: 0.72rem; font-weight: 700; }
/* Popup: alle Kategorien des Monats, häufigste zuerst */
.bn-catlist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.bn-catlist li { display: grid; grid-template-columns: minmax(0, 1fr) 28px; gap: 4px 10px;
    align-items: baseline; font-size: 0.86rem; }
.bn-catname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-muted); }
.bn-catlist li.is-top .bn-catname { color: var(--text); font-weight: 600; }
.bn-catlist b { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
/* Die Leisten laufen in der Akzentfarbe, die häufigste kräftiger: eine Kategorie
   ist kein Status – Gold und Rot würden hier „Hinweis/Fehler" behaupten. */
.bn-catbar { grid-column: 1 / -1; height: 5px; border-radius: 999px; background: var(--surface-2); }
.bn-catbar i { display: block; height: 100%; border-radius: 999px;
    background: rgba(var(--accent-rgb), 0.5); }
.bn-catlist li.is-top .bn-catbar i { background: var(--accent); }

.kpi-ico.ico-warn { background: var(--gold-soft, color-mix(in srgb, var(--gold) 14%, transparent)); color: var(--gold); }
.kpi-ico.ico-ok { background: var(--positive-soft); color: var(--positive); }

@media (max-width: 900px) {
    .kpi-stage { gap: 20px; }
    .kpi-hero { font-size: 3rem; }
    .kpi-row { grid-template-columns: 10px 104px minmax(0, 1fr) 32px; }
}

/* ---------- Ereignisse & Abwesenheiten (18.08.2026) ----------
   Eine Karte mit zwei Tabs in der Spalte neben der Timeline. (Das Prämien-Podium,
   das hier bis zum 02.09.2026 daneben stand, ist ersatzlos entfallen.) */
/* Geburtstage in der Ereignisliste: eigene Farbe, der heutige zusätzlich mit
   Rahmen – er hatte vorher eine eigene Karte und soll nicht untergehen. */
.deadline-list li.is-bday .deadline-icon { color: var(--accent); }
.deadline-list li.is-bday.is-now {
    border: 1px solid var(--accent);
    background: linear-gradient(135deg, var(--accent-soft), transparent 70%);
}
/* Karte „Ereignisse / Abwesenheiten" in der Verlaufs-Spalte: zwei Tabs statt zwei
   Karten (Wunsch 18.08.2026), Standard sind die Ereignisse. */
.ag-card .card-title-row { flex-wrap: nowrap; gap: 8px; }
.ag-tabs { margin: 0; flex-wrap: nowrap; }
.ag-tabs .tl-chip { padding: 3px 10px; font-size: 0.74rem; display: inline-flex; align-items: center; gap: 5px; }
.ag-tabs .nav-count { min-width: 0; padding: 0 5px; font-size: 0.66rem; }
.ag-card .ag-note { white-space: nowrap; font-size: 0.74rem; }
.ag-card .week-strip { margin-top: 12px; }

/* Der heutige Geburtstag darf umbrechen – der Satz („… und wird 21 – herzlichen
   Glückwunsch!") wurde in der 40-%-Spalte sonst abgeschnitten. */
.deadline-list li.is-bday.is-now .deadline-title {
    font-size: 0.9rem; white-space: normal; overflow: visible; text-overflow: clip;
}

/* ============================================================
   Große Monitore: Inhalt wächst mit (19.08.2026, Sebastians Wunsch
   „wenn genug Platz, Navigation breiter und Text größer")
   ------------------------------------------------------------
   Ein einziger Hebel steuert die Schrift: die WURZEL-Schriftgröße. Alle
   Schriftgrößen der App stehen in rem, Innenabstände und Rahmen dagegen in
   px – dadurch wächst auf einem großen Monitor der Text, das Layout bleibt
   aber ruhig (Knöpfe, Karten und Icons behalten ihre Proportionen).
   Alles über clamp(), also stufenlos: kein Sprung an einer Kante.

   Kurven (Breite → Wert):
     1440px → 16px Wurzel / 200px Navigation / 1280px Inhalt
     1920px → 17,3px      / 219px            / 1574px
     2560px → 18,9px      / 256px            / 1880px (Deckel)
   Die Navigation startet seit 02.09.2026 bei 200px (Variante D, siehe Block am
   Ende der Datei; vorher 264px). Der vw-Anteil ist mit 11,4vw so gewählt, dass
   sie – wie vorher mit 264px/15vw – ab etwa 1760px mitwächst: genau dort wird
   die Wurzelschrift sonst schneller groß als die Spalte breit.
   Unter 1200px greift die Regel nicht, damit die Handy- und Tablet-Regeln
   weiter oben (kleinere Polsterung, body 14px) unangetastet bleiben. */
@media (min-width: 1200px) {
    html { font-size: clamp(16px, 0.26vw + 12.26px, 19px); }
    /* stand bisher hart auf 15px – als rem-Wert (0,9375 × 16 = 15) wächst es mit */
    body { font-size: 0.9375rem; }
    .sidebar { width: clamp(200px, 11.4vw, 256px); }
    .content {
        max-width: clamp(1280px, 82vw, 1880px);
        padding-left: clamp(32px, 2.4vw, 56px);
        padding-right: clamp(32px, 2.4vw, 56px);
    }
}

/* ---------- Online Log (Einstellungen → System → Online Log, 19.08.2026) ----------
   Viele kurze Zeilen: kleinere Schrift, feste Spaltenbreiten für Zeit und Art,
   der Pfad darf bei Bedarf umbrechen. Die Art als kleine Pille – die Farbe sagt
   sofort, ob es eine Anmeldung, ein Seitenaufruf oder ein Rausflug war. */
.log-table-wrap { overflow-x: auto; margin-top: 10px; }
.log-table { font-size: 0.84rem; }
.log-table th, .log-table td { padding: 6px 10px; }
.log-table .log-when { white-space: nowrap; color: var(--text-muted); width: 1%; }
.log-table .log-path { overflow-wrap: anywhere; }
/* Zähler für wiederholte Aufrufe derselben Seite (19.08.2026) */
.log-hits {
    display: inline-block;
    margin-left: 4px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    font-size: 0.68rem;
    font-weight: 700;
    color: var(--text-muted);
}
.log-kind {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    white-space: nowrap;
    background: var(--surface-2);
    color: var(--text-muted);
    border: 1px solid var(--border);
}
.log-kind.is-login { background: var(--positive-soft); color: var(--positive); border-color: transparent; }
.log-kind.is-auto { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.log-kind.is-logout { background: var(--surface-2); color: var(--text-muted); }
.log-kind.is-lost { background: var(--negative-soft); color: var(--negative); border-color: transparent; }
.log-kind.is-view { background: transparent; color: var(--text-muted); border-color: var(--border); }
/* An-/Abmeldungen in der Seitenspalte: je Eintrag zwei Zeilen (Art + Name, Zeit) */
.log-events { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.log-events li {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 8px;
    align-items: center;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
    font-size: 0.84rem;
}
.log-events li:last-child { border-bottom: 0; padding-bottom: 0; }
.log-ev-name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.log-ev-time, .log-ev-note { grid-column: 1 / -1; font-size: 0.76rem; }

/* ---------- Tooltip – STILLGELEGT am 20.08.2026 ----------
   Tooltips sind auf Sebastians Wunsch abgeschaltet („kein Mehrwert, stören
   eher"); app.js baut diese Hülle deshalb nicht mehr. Die Regeln bleiben
   stehen, damit der Schalter `TIPS_AN` in app.js allein genügt, um alles
   zurückzuholen. **Diagramm-Tooltips sind davon nicht betroffen** – die
   laufen über `.qs-chart-tip`/`#charttip` und ApexCharts.

   Der Baustein (falls er zurückkommt):
   EIN Baustein für die ganze App: `data-tip="…"` am Element, optional
   `data-tip-sub` (zweite Zeile, gedämpft), `data-tip-val` (Wert rechts) und
   `data-tip-tone="ok|warn|bad"` (färbt nur die Werte-/Sub-Zeile ein) und
   `data-tip-rows="A=1|B=2"` (kleine Liste zwischen Titel und zweiter Zeile).
   Das Markup baut app.js einmal am Body, deshalb steht hier nur die Hülle.
   Der native `title`-Tooltip wird NICHT mehr benutzt (er ließ sich nicht
   gestalten und erschien im Kalender doppelt neben dem eigenen Popup).
   Ebene 9500: über Popups (80) und Sichtschutz (9000), damit ein Tooltip
   auch in einem Modal sichtbar ist. */
.tip {
    position: fixed; z-index: 9500; top: 0; left: 0; pointer-events: none;
    max-width: 300px; opacity: 0; transform: translateY(3px);
    transition: opacity 0.12s ease, transform 0.12s ease;
    font-size: 0.78rem; line-height: 1.45; color: var(--text);
}
.tip.is-on { opacity: 1; transform: none; }
html.no-anim .tip { transition: none; transform: none; }
.tip-in {
    position: relative; background: var(--surface); border: 1px solid var(--border);
    border-radius: 12px; padding: 9px 12px; box-shadow: var(--shadow-lg);
}
/* Pfeil: gedrehtes Quadrat mit zwei Kanten – sitzt über der Mitte des
   Elements, auch wenn der Tooltip am Fensterrand verschoben wurde
   (app.js setzt dafür --tip-arrow). */
.tip-in::after {
    content: ""; position: absolute; left: var(--tip-arrow, 50%); width: 9px; height: 9px;
    margin-left: -5px; background: var(--surface); border: 1px solid var(--border);
    border-top: 0; border-left: 0; transform: rotate(45deg);
}
.tip[data-pos="top"] .tip-in::after { bottom: -5px; }
.tip[data-pos="bottom"] .tip-in::after { top: -5px; transform: rotate(225deg); }
.tip-main { display: block; }
/* Zeilenliste (data-tip-rows, 02.09.2026): Beschriftung links, Wert rechts.
   Kompakt gehalten – der Tooltip soll eine Übersicht sein, keine Tabelle.
   Ab der zweiten Zeile eine feine Trennlinie, damit die Werte zu lesen sind,
   ohne dass jede Zeile eingerahmt wirkt. */
.tip-rows {
    display: grid; grid-template-columns: 1fr auto; gap: 0 14px;
    margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--border);
}
.tip-row { display: contents; }
.tip-row-k { color: var(--text-muted); white-space: nowrap; }
.tip-row-v { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tip-row:only-child .tip-row-k:last-child { grid-column: 1 / -1; }
.tip-sub { display: block; color: var(--text-muted); margin-top: 3px; }
.tip-val { float: right; margin-left: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.tip[data-tone="ok"] .tip-val { color: var(--positive); }
.tip[data-tone="warn"] .tip-val { color: var(--gold); }
.tip[data-tone="bad"] .tip-val { color: var(--negative); }

/* ============================================================
   Startseite – Auffrischung vom 24.08.2026 (aus `_startseite-mockup.html`,
   von Sebastian in einem Durchgang bestätigt: „gerne alles umsetzen").
   Neun Punkte, unten in derselben Reihenfolge kommentiert. ALLES hängt an
   `.dash-*` bzw. `.topbar-search` – der Rest der App bleibt unberührt.
   Wer hier etwas anfasst: Dark UND Light prüfen, dazu ein schmales Fenster
   (unter 900px) und ein breites (ab 1850px, dort greift Punkt 7).
   ============================================================ */

/* ---------- (1) Schnellsuche in der Topbar ----------
   Ersetzt zwei Einstiege in dasselbe Popup: das Lupen-Icon rechts und den
   breiten Knopf `.dash-search` auf der Startseite. Bewusst ein Knopf und kein
   Eingabefeld – getippt wird im Popup, so gibt es nur EIN Suchfeld.
   Die Taste steht sichtbar als `<kbd>` daneben (Tooltips sind abgeschaltet). */
.topbar-search {
    display: flex;
    align-items: center;
    gap: 9px;
    width: clamp(200px, 26vw, 420px);
    padding: 7px 12px;
    border-radius: 999px;
    cursor: pointer;
    text-align: left;
    font: inherit;
    font-size: 0.86rem;
    color: var(--text-muted);
    background: var(--surface);
    border: 1px solid var(--border);
    transition: background-color 0.15s ease, border-color 0.15s ease;
}
.topbar-search:hover { background: var(--surface-hover); border-color: var(--accent); }
/* Icons in Flex-Zeilen nie schrumpfen lassen (Regel aus der Profil-Sidebar) */
.topbar-search svg { flex: none; color: var(--accent); }
.topbar-search span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-search .kbd-hint { flex: none; }

/* ---------- (2) Kontextzeile als Chips ----------
   Klickbare Pillen statt eines Satzes mit Mittelpunkten: größere Klickfläche
   und auf einen Blick zählbar. Farbe sitzt im Punkt, die Zahl bleibt in
   Textfarbe (Design-Regel). */
.dash-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 0; }
.dash-chips .dash-day { font-size: 0.86rem; color: var(--text-muted); margin-right: 2px; }
.dash-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 11px 4px 9px;
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    transition: background-color 0.15s ease, border-color 0.15s ease;
}
a.dash-chip:hover { background: var(--surface-hover); text-decoration: none; }
.dash-chip > i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--text-muted); }
.dash-chip > b { font-weight: 700; }
.dash-chip.is-bad > i { background: var(--negative); }
.dash-chip.is-bad { border-color: color-mix(in srgb, var(--negative) 34%, var(--border)); }
.dash-chip.is-acc > i { background: var(--accent); }
.dash-chip.is-ok { color: var(--text-muted); }
.dash-chip.is-ok > i { background: var(--positive); }
/* „N online" (03.09.2026, Variante C): grüner Punkt wie bei is-ok, aber normale
   Textfarbe – die Zahl soll lesbar sein, nicht zurückgenommen. Bewusst KEINE
   getönte Fläche: die Kontextzeile bleibt ruhig, der Punkt genügt. */
.dash-chip.is-online > i { background: var(--positive); }
.dash-chip.is-online { border-color: color-mix(in srgb, var(--positive) 34%, var(--border)); }

/* ---------- (3) Karten-Hierarchie auf der Startseite ----------
   Alle Karten der Seite verlieren den Schatten und bekommen 18px Radius; NUR
   die Bühne (QS-Quote) trägt eine ganz leichte Akzentfläche. So entsteht eine
   Blickachse, ohne eine zweite große Zahl einzuführen. Popups sind ausgenommen
   (`:not(.modal)`) – sie stehen über der Seite und brauchen ihren Schatten.

   Die 2px-Kante im Akzentverlauf über der Bühne ist am 24.08.2026 wieder
   entfallen („was soll der Strich über der Box?"): sie saß eine Haarlinie
   innerhalb des Kartenrahmens und sah dadurch aus wie ein zweites, lose
   darüberliegendes Element. **Nicht ohne Rücksprache neu bauen** – die
   Akzentfläche allein trägt die Hierarchie. */
.dash-section .card:not(.modal) { box-shadow: none; border-radius: 18px; }
.dash-section a.card.kpi-qs {
    background: color-mix(in srgb, var(--accent) 7%, var(--surface));
    border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}
.dash-section a.card.kpi-qs:hover { background: color-mix(in srgb, var(--accent) 11%, var(--surface)); }

/* ---------- (4) Die große Zahl und ihr Trend ----------
   Tabellarische Ziffern: beim Hochzählen wechselt die Breite sonst mit jeder
   Ziffer und die Zahl zappelt. Der Trend sitzt in einer Pille statt frei in
   der Zeile – er ist eine Angabe, kein Fließtext. */
.dash-section .kpi-hero b { font-variant-numeric: tabular-nums; }
.dash-section .kpi-stage-num .kpi-trend {
    padding: 3px 10px 3px 8px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    font-size: 0.78rem;
}
.dash-section .kpi-stage-num .kpi-trend .muted { font-weight: 500; }

/* ---------- (5) Abschnitte laufen gestaffelt an ----------
   10px hoch, 0,5s, je Block 60ms später (`--rise-delay` setzt die View).
   Abschaltbar wie jede Animation: `prefers-reduced-motion` stellt alles sofort
   fertig hin. (Die zusätzliche Profil-Einstellung „Animationen" ist am
   03.09.2026 entfallen.) */
@keyframes dashRise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
/* WICHTIG: `backwards`, NICHT `both` (25.08.2026). Mit `both` behält der Block nach
   der Animation einen Transform (Identitätsmatrix, nicht `none`) – und ein Vorfahre
   mit Transform wird zum Bezugsrahmen für `position: fixed`. Das Popup
   „Beanstandungen nach Kategorie" öffnete deshalb nur innerhalb des
   Kennzahlen-Blocks und war auch nur darin scrollbar. `backwards` hält den
   Anfangszustand vor dem Start (das braucht die Verzögerung) und lässt danach den
   normalen Wert gelten – also kein Transform mehr. */
.dash-rise { animation: dashRise 0.5s cubic-bezier(0.22, 0.7, 0.25, 1) var(--rise-delay, 0ms) backwards; }
html.no-anim .dash-rise { animation: none; }

/* ---------- (6) Leerzustände ----------
   Icon, ein Satz, wo es passt eine Aktion – statt einer grauen Textzeile.
   Ersetzt `.empty-state` auf der Startseite; die Klasse bleibt für den Rest
   der App unverändert. */
.empty-box { text-align: center; padding: 26px 14px 20px; }
.empty-box-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    margin-bottom: 10px;
    border-radius: 14px;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.empty-box-ico svg { flex: none; }
.empty-box p { margin: 0; font-size: 0.88rem; color: var(--text-muted); }
.empty-box .btn { margin-top: 12px; }
/* In der schmalen rechten Spalte etwas kompakter */
.grid-dashboard > .stack .empty-box { padding: 18px 8px 14px; }

/* ---------- (7) Kennzahlen und Ranking in einer Reihe – ENTFALLEN 31.08.2026 ----
   Ab 1850px Fensterbreite standen Bühne · Beanstandungen · Podium nebeneinander.
   Auf Sebastians Monitor wirkte das Ranking dadurch wie eine dritte Box neben den
   beiden Kennzahlen-Karten und sein Text brach stark um. Regel und Wrapper
   (.dash-top / .dash-top-flip, dazu die Paar-Logik in der Dashboard-View) sind
   komplett raus – jede Kachel steht wieder allein über die volle Breite.
   Nicht ohne Rücksprache neu bauen. (Das Ranking selbst gibt es seit dem
   02.09.2026 gar nicht mehr.) */

/* ---------- (8) Tagestrenner der Timeline bleiben stehen ----------
   Beim Scrollen durch die Startseiten-Timeline klebt „Heute"/„Gestern" unter
   der Topbar (die ist sticky mit ~64px Höhe und z-index 10 – der Trenner
   bleibt darunter). */
#dashTimeline .timeline-day {
    position: sticky;
    /* Die Topbar ist 70px hoch (gemessen, ab 820px Breite) – 4px Luft darunter,
       sonst schiebt sich der Trenner unter die durchscheinende Leiste. */
    top: 74px;
    z-index: 2;
    margin: 8px 0 -2px;
    padding: 5px 8px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: blur(6px);
}

/* ---------- (9) Sichtbarer Fokus ----------
   Die Startseite ist voller Karten-Links; mit der Tastatur war nicht zu sehen,
   wo man steht. Kein border-radius hier – der Ring folgt dem Radius des
   Elements. */
.dash-section a.card:focus-visible,
.dash-section .card a:focus-visible,
.dash-section .card button:focus-visible,
.dash-chip:focus-visible,
.topbar-search:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

@media (max-width: 1100px) {
    /* Weniger Platz in der Topbar: das Feld wird schmaler, bleibt aber lesbar */
    .topbar-search { width: clamp(150px, 20vw, 240px); }
    .topbar-search .kbd-hint { display: none; }
}
@media (max-width: 760px) {
    /* Ab hier steht links der Menü-Knopf und rechts die Icon-Gruppen – dann
       bleibt von der Suche nur die Lupe, im runden Maß der anderen Icon-Knöpfe. */
    .topbar-search { width: 38px; height: 38px; padding: 0; justify-content: center; }
    .topbar-search span { display: none; }
    .dash-chips { gap: 6px; }
    .dash-chips .dash-day { font-size: 0.8rem; }
    .dash-chip { font-size: 0.78rem; padding: 3px 9px 3px 8px; }
    /* Auf dem Handy ist die Topbar 62px hoch */
    #dashTimeline .timeline-day { top: 66px; }
}

/* ============================================================
   Navigation ruhiger (24.08.2026) – Vorschläge A, B und C aus
   `_sidebar-ruhiger.html`, von Sebastian zusammen gewählt („A, B und C bitte").
   Reihenfolge im Block ist Absicht: erst die Geometrie (C), dann die Texte (B),
   zuletzt der Standort (A) – A muss die Icon-Regeln aus C überstimmen können.
   Alles hier ist reines CSS, im Markup hat sich nichts geändert.
   ============================================================ */

/* ---------- C · Alles auf einer Kante ----------
   Vorher standen drei Zonen auf drei Linien: die Arbeitsbereiche mit einer
   37px-Icon-Spalte (Titel ab 78px), „Organisation" und der Fuß mit 17px-Icons
   und 10px Abstand (Titel ab 51px). Das Auge las drei Listen statt einer
   Navigation. Jetzt gilt die Spalte der Arbeitsbereiche für ALLE Punkte der
   Seitenleiste – die Schriftgrößen bleiben gestuft, die Stufen sind gewollt
   (siehe `.sidebar-nav > .nav-group .nav-link` weiter oben). */
.sidebar-nav > .nav-group .nav-link,
.sidebar-foot .nav-link {
    padding-left: 0;
    gap: 0;
}
.sidebar-nav > .nav-group .nav-link > svg,
.sidebar-foot .nav-link > svg {
    width: 20px;
    height: 20px;
    flex: 0 0 37px;
    box-sizing: content-box;
    padding: 0 7px 0 10px;
    opacity: 0.45;
}
.sidebar-nav > .nav-group .nav-link:hover > svg,
.sidebar-foot .nav-link:hover > svg { opacity: 0.8; }
.sidebar-foot .nav-link.active > svg { opacity: 1; }
/* Der Titel nimmt den Rest der Zeile, der Zähler bleibt rechts stehen */
.sidebar-nav > .nav-group .nav-link > span:not(.nav-count),
.sidebar-foot .nav-link > span:not(.nav-count) { flex: 1; min-width: 0; }
/* Markenkopf einzeilig: Logo, Name und Team-Badge in einer Reihe. Beide
   Regeln sind auf `.sidebar-brand` beschränkt – `.logo-badge-lg` und
   `.head-brand` stehen auch auf der Anmeldeseite und in der Sperrmaske. */
.sidebar-brand { gap: 10px; }
.sidebar-brand .brand-text { flex-direction: row; align-items: center; gap: 8px; }
.sidebar-brand .logo-badge-lg { width: 38px; height: 38px; border-radius: 11px; font-size: 1.15rem; }
.sidebar-brand .head-brand { font-size: 0.62rem; padding: 1px 8px; }
/* Kompaktmodus (72px breite Leiste) braucht seine eigenen Icon-Maße zurück –
   die Regeln oben sind gleich spezifisch und stehen weiter unten in der Datei. */
@media (min-width: 901px) {
    html.sidebar-min .sidebar .nav-link > svg {
        flex: none;
        padding: 0;
        opacity: 1;
    }
}

/* ---------- B · Keine Kontextzeile, dafür Luft (25.08.2026) ----------
   Erst zeigte nur der aktive Bereich seine Beschreibung (24.08.2026), jetzt
   zeigt sie KEINER mehr (Wunsch Sebastian 25.08.2026: „beim Aktivzustand
   braucht es darunter keinen Sub-Text"). Alle fünf Arbeitsbereiche sind damit
   einzeilig und gleich hoch – der Standort wird allein über Fläche, Kante und
   Farbe gelesen (Teil A). Die gewonnene Höhe geht als Abstand zwischen die
   Hauptpunkte zurück: `margin-block` statt größerem Innenabstand, damit die
   getönte Fläche des aktiven Bereichs nicht aufquillt.
   Die `.nav-desc`-Regeln weiter oben bleiben stehen – wer die Zeile zurückwill,
   nimmt hier das `display: none` heraus. Das Markup liefert sie weiter. */
.nav-link.nav-main .nav-desc { display: none; }
.nav-link.nav-main { padding-block: 8px; margin-block: 3px; }
/* Flaches Fenster (~700px, Sebastians Standard): etwas enger, aber der Abstand
   bleibt sichtbar. Höhere Spezifität als der `.sidebar …`-Block weiter oben,
   sonst gewinnt dort das padding-Shorthand. */
@media (max-height: 760px) {
    .sidebar .nav-link.nav-main { padding-block: 7px; margin-block: 2px; }
}

/* ---------- A · Ruhiger Standort ----------
   Die volle Kachel im Knopf-Verlauf war der größte Farbblock der Oberfläche und
   wanderte beim Navigieren mit. Jetzt: getönte Fläche plus die schmale
   Akzentkante links (`.nav-link.nav-main::before`, die dafür wieder eingeblendet
   wird), Titel und Icon in der Akzentfarbe. Gleiche Sprache wie „heute" im
   Teamplaner: Hervorhebung als Fläche, nicht als Rähmchen. */
.nav-link.nav-main.active {
    background: var(--accent-soft);
    box-shadow: none;
}
.nav-link.nav-main.active:hover {
    background: color-mix(in srgb, var(--accent) 20%, var(--surface));
    filter: none;
}
.nav-link.nav-main.active::before { display: block; opacity: 1; }
/* Muss die Icon-Deckkraft aus C überstimmen, deshalb der lange Selektor */
.sidebar-nav > .nav-group .nav-link.nav-main.active > svg { opacity: 1; color: var(--accent); }
.nav-link.nav-main.active .nav-label { color: var(--accent); font-weight: 600; }
/* wirkungslos seit 25.08.2026 (Kontextzeile ist ausgeblendet, siehe B) */
.nav-link.nav-main.active .nav-desc { color: var(--text-muted); opacity: 1; }

/* ============================================================
   Timeline – gelesen/ungelesen (31.08.2026, zweimal überarbeitet 03.09.2026)
   ------------------------------------------------------------
   Immer privat: keine Zählung, keine Namen, keine Anzeige beim
   Verfasser. Hieß bis zum 03.09.2026 „für mich erledigt".

   Drei Dinge sind am 03.09.2026 gekippt – **nichts davon ohne
   Rücksprache wieder einführen:**
   1. `.timeline-item.tl-done` (halbe Deckkraft für Gelesenes). Nach ein
      paar Wochen stand damit die halbe Timeline blass da und sah kaputt
      aus. Gedämpft wird nichts mehr – die Abschnitte trennen.
   2. Der dauerhaft sichtbare `.tl-check` in der Zeile und der Knopf
      `#noteMarkBtn` im Popup. **Öffnen IST Lesen**, und zurück auf
      ungelesen geht bewusst gar nicht.
      **ABER:** ein Haken BEIM ÜBERFAHREN ist am Abend des 03.09.2026 auf
      ausdrücklichen Wunsch zurückgekommen – siehe eigener Block weiter
      unten. Er steht nur an ungelesenen Zeilen und ist eine Abkürzung,
      nicht der einzige Weg.
   3. Die Sonderregel für Geräte ohne Mauszeiger (`@media (hover: none)`)
      – mit dem Haken vom Abend ist sie ebenfalls wieder da.

   ============================================================
   Abschnitte „Neu" und „Bereits gelesen" (03.09.2026)
   ------------------------------------------------------------
   Variante A aus `_gelesen-mockup.html`, von Sebastian aus vier
   Vorschlägen gewählt. Die Startseiten-Timeline steht in zwei Listen
   statt in einer; jede bekommt eine Überschriftenzeile mit Zahl und
   einer Handlung rechts („Alle als gelesen markieren" bzw. auf-/
   zuklappen). Tages-Trenner gibt es dort nicht mehr – zwei
   Gliederungen übereinander lesen sich nicht.
   ============================================================ */
.tl-sec {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 10px; padding: 8px 12px;
    background: var(--surface-2); border-radius: 10px;
}
.tl-sec-t {
    font-size: 0.72rem; font-weight: 700; letter-spacing: 0.07em;
    text-transform: uppercase; color: var(--text);
}
/* Die Zahl meint ALLE sichtbaren Anmerkungen, nicht die geladene Seite –
   sie kommt vom Server (NoteModel::countUnmarked). */
.tl-sec-n {
    font-size: 0.72rem; font-weight: 700; line-height: 1;
    padding: 3px 8px; border-radius: 999px;
    background: var(--accent-soft); color: var(--accent);
    font-variant-numeric: tabular-nums;
}
/* „Bereits gelesen" ist die ruhigere der beiden Zeilen */
.tl-sec-alt .tl-sec-t { color: var(--text-muted); }
.tl-sec-alt .tl-sec-n { background: var(--surface-hover); color: var(--text-muted); }
.tl-sec-btn {
    font: inherit; font-size: 0.76rem; font-weight: 600; cursor: pointer;
    margin-left: auto; padding: 4px 10px; border-radius: 999px;
    border: 1px solid var(--border); background: transparent; color: var(--text-muted);
    display: inline-flex; align-items: center; gap: 6px;
}
.tl-sec-btn:hover { color: var(--text); border-color: var(--accent); }
.tl-sec-btn:disabled { opacity: 0.5; cursor: default; }
/* Der Pfeil zeigt zu, wenn eingeklappt, und nach unten, wenn offen */
.tl-sec-btn svg { transition: transform 0.15s ease; }
.tl-sec-btn[aria-expanded="true"] svg { transform: rotate(90deg); }
.tl-sec-abstand { margin-top: 26px; }
/* „Neu" leer: nicht einfach nichts, sondern die Antwort auf die Frage */
.tl-leer { margin: 0 0 4px; font-size: 0.86rem; color: var(--text-muted); }
/* ============================================================
   Filterzeile der Startseiten-Timeline (31.08.2026)
   Variante C aus `_timeline-filter-mockup.html`.

   Vorher: vier Chips + zwei beschriftete Kippschalter. Zusammen breiter als die
   Spalte – auf breiten Monitoren wächst die Wurzelschrift mit (clamp ab 1200px),
   die Spalte aber langsamer –, also brachen die Schalter in eine zweite Zeile um
   und standen dort rechts allein.

   Jetzt: links EIN Umschalter für die Bewertung (man wählt einen von vieren, das
   ist eine Entscheidung), rechts zwei Icon-Knöpfe für die Ebenen. Zusammen rund
   die halbe Breite. Beide Bauteile sind bewusst NEU und hängen nicht an `.tl-chip`
   – die Chip-Klasse trägt in der ganzen App Reiter und Filter und darf sich nicht
   ändern.
   ============================================================ */
.tl-seg {
    display: inline-flex;
    padding: 2px;
    gap: 2px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
}
.tl-seg-b {
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-muted);
    padding: 4px 13px;
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
}
.tl-seg-b:hover { color: var(--text); }
.tl-seg-b.active { background: var(--accent-soft); color: var(--accent); }

/* Die zwei Ebenen: Haken = nur Offene, Blitz = Systemmeldungen. Beschriftung
   steckt im Tooltip und im aria-label (siehe Dashboard-View). */
/* `.tl-ibtns`/`.tl-ibtn` sind seit 03.09.2026 ohne Inhalt: der einzige Knopf
   darin war der Blitz für die Systemmeldungen, und die stehen nicht mehr auf der
   Startseite (nur noch im Profil der Person). Die Regeln bleiben als Bauteil
   stehen – **einen neuen Knopf dort aber nicht ohne Rücksprache einhängen.** */

/* Der Systemmeldungs-Schalter ist seit dem 02.09.2026 ein <a> (Zustand in der
   Adresse) – ein Bedienelement, kein Textlink, also ohne Unterstreichung. */

/* Auf schmalen Fenstern darf die Zeile umbrechen – dann stehen die Icon-Knöpfe
   links unter dem Umschalter statt rechts allein in der Luft. */

/* ============================================================
   D · Seitenleiste schmaler (02.09.2026, Variante D – Wunsch Sebastian)
   ============================================================
   Gemessen, nicht geschätzt: die Leiste stand auf 264px, obwohl 242px
   gereicht hätten. Der Engpass war NICHT der Markenkopf (201px), sondern
   eine einzige Zeile – „Kalender ⚠ 7" mit 242px, 21px mehr als das viel
   längere „Qualitätssicherung" (221px). Vier Eingriffe bringen sie auf
   191px; eingestellt sind 200px.

   Reihenfolge nach Wirkung:
     Warnzeichen → oranger Punkt   −21px
     Icon-Spalte 26px + 16px-Icons −16px
     Schrift eine Stufe kleiner     −8px
     Markenkopf gestapelt            0px (aber: Kopf 201 → 115px)

   Der Markenkopf bringt an der Breite nichts, weil er nie gebremst hat.
   Er ist trotzdem dabei: gestapelt ist er für künftige Schritte aus dem
   Rennen und ruhiger. Damit dreht die Runde „C · Alles auf einer Kante"
   (24.08.2026) genau diesen einen Punkt wieder zurück – der Rest von C
   (gemeinsame Icon-Spalte für alle Punkte) bleibt.
   ============================================================ */

/* ---------- Der eigentliche Engpass: das Warnzeichen am Kalender ----------
   Zwei Dinge stimmten hier nicht. Erstens die Breite: der Glyph braucht rund
   20px, die Kalenderseite meldet dasselbe seit ihrem Umbau mit einem orangen
   Punkt – derselbe Punkt hier spart die Breite UND macht beide Stellen
   gleich. Zweitens ein Fehler: die Regel
   `.sidebar-nav > .nav-group .nav-link > span:not(.nav-count)` im Block C gibt
   JEDEM Span `flex: 1` – auch diesem. Das zog ihn auf 73px auf und ließ ihn
   beim Verschmälern an das Wort „Kalender" rutschen. */
.sidebar-nav > .nav-group .nav-link > span.nav-cal-flag { flex: 0 0 auto; }  /* `span` MUSS mit: die Regel im Block C endet auf `span:not(.nav-count)`
     und ist damit eine Stufe spezifischer als eine reine Klassenkette. */
.nav-cal-flag {
    font-size: 0; line-height: 0; color: transparent;
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--warn-dot);
    margin-left: 7px;
}
/* Im Kompaktmodus sitzt der Punkt oben links am Icon (Position kommt aus dem
   Block bei `.nav-cal-panel`), nur die Schriftgröße muss hier auf 0 bleiben –
   die dortige Regel ist spezifischer und setzt sie sonst wieder auf 0.72rem. */
@media (min-width: 901px) {
    html.sidebar-min .sidebar .nav-cal .nav-cal-flag { font-size: 0; top: 4px; left: 9px; }
}

/* ---------- Icon-Spalte schmaler ----------
   Icons von 20 auf 16px, Polster von 7/10 auf 5/5. 16px ist die Grenze:
   darunter werden Zielscheibe und Zahnrad zu Matsch. Der Markenkopf zieht
   mit (Innenabstand 5px statt 10px), damit das C-Logo weiter senkrecht mit
   den Icons fluchtet – die Sidebar-Polsterung geht dafür von 12 auf 10px. */
.sidebar { padding-left: 10px; padding-right: 10px; }
.sidebar-nav > .nav-group .nav-link > svg,
.sidebar-foot .nav-link > svg,
.nav-link.nav-main > svg {
    width: 16px; height: 16px;
    flex: 0 0 26px;
    padding: 0 5px;
}
.sidebar-brand { padding-left: 5px; }
/* Der Kompaktmodus lebt allein von den Icons – dort bleiben sie bei 20px.
   Die Regeln oben sind gleich spezifisch und stehen weiter unten in der Datei,
   deshalb muss das Maß hier ausdrücklich zurück. */
@media (min-width: 901px) {
    html.sidebar-min .sidebar .nav-link > svg { width: 20px; height: 20px; }
}

/* ---------- Markenkopf gestapelt ----------
   Logo links, „Copilot" und das Team-Badge rechts untereinander – so war es
   bis zum 24.08.2026 schon einmal. Beide Regeln bleiben auf `.sidebar-brand`
   beschränkt: `.logo-badge-lg` und `.head-brand` stehen auch auf der
   Anmeldeseite und in der Sperrmaske. */
.sidebar-brand .brand-text { flex-direction: column; align-items: flex-start; gap: 3px; }
.sidebar-brand .brand-name { font-size: 1.12rem; }
.sidebar-brand .head-brand { font-size: 0.58rem; padding: 1px 7px; letter-spacing: 0.06em; }
.sidebar-brand .logo-badge-lg { width: 32px; height: 32px; border-radius: 9px; }

/* ---------- Schrift eine Stufe kleiner ----------
   Arbeitsbereiche 0,96 → 0,90rem, „Organisation" und Fuß 0,84 → 0,80rem.
   Unter 0,88rem wird es auf einem großen Monitor unruhig – dort zieht die
   Regel „Platz auf großen Monitoren nutzen" (19.08.2026) die Wurzelschrift
   ohnehin wieder hoch. Wer eine der beiden Größen ändert, ändert BEIDE
   (Sektion und Fuß stehen seit 20.08.2026 auf einer Stufe). */
.nav-link.nav-main .nav-label { font-size: 0.9rem; }
.sidebar-nav > .nav-group .nav-link,
.sidebar-foot .nav-link { font-size: 0.8rem; }
.nav-section-label { font-size: 0.62rem; }

/* ============================================================
   Kartenkopf Variante A (03.09.2026, von Sebastian aus vier Vorschlägen in
   `_kalenderkopf-mockup.html` gewählt)
   ============================================================
   Der Kopf der Kalenderkarte stand auf VIER Bändern übereinander – Titelzeile,
   Kennzahlen, Legende, Gruppen-Reiter. Alle vier mit ähnlich kleinen, ähnlich
   grauen Elementen; das Auge fand keine Rangfolge und es wirkte gequetscht.
   Jetzt zwei Zonen mit klarer Aufgabe:

     Zone 1 (.ch-top)     wo bin ich und was ist los
     Zone 2 (.ch-leiste)  was zeige ich

   Mit derselben Runde ist die Sechs-Wochen-Sicht entfallen (siehe oben) – der
   Umschalter, der bisher in der Kopfzeile stand, fällt damit von selbst weg.
   ============================================================ */

/* ---------- Zone 1: Titel und Lage ----------
   Monat groß, der Stand klein DARUNTER statt daneben: so ist er erkennbar eine
   Fußnote zum Monat und nicht der zweite von vier gleichrangigen Punkten auf
   einer Linie. Er bleibt der Weg zum Neuladen (a.cal-meta weiter oben). */
.ch-top {
    display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
    margin-bottom: 12px;
}
.ch-titel { min-width: 0; }
.ch-titel h2 { margin: 0 0 2px; }
.ch-titel .cal-meta { font-size: 0.76rem; }
/* Kennzahlen rechts auf Titelhöhe. `margin-left: auto` schiebt sie an den
   rechten Rand; bricht die Zeile im schmalen Fenster um, stehen sie links
   unter dem Titel – dort, wo sie vor dem 03.09.2026 immer standen. */
.ch-kennz { margin: 4px 0 0 auto; }

/* ---------- Zone 2: Werkzeugleiste ----------
   Eine abgesetzte Fläche fasst zusammen, was zusammengehört: Gruppe wählen
   (links), Farben nachschlagen und Office ein-/ausschalten (rechts). Die
   Fläche ist das eigentliche Mittel gegen „gequetscht" – sie macht aus drei
   losen Bändern EIN Bedienfeld. */
.ch-leiste {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 8px 12px; margin: 0 0 14px;
    background: var(--surface-2); border-radius: 12px;
}
.ch-leiste .cal-tabs { margin: 0; }
/* Legende und Schalter als EIN Block rechts – damit sie beisammen bleiben, wenn
   die Leiste umbricht, und damit die Leiste ohne Reiter (nur eine Gruppe)
   genauso aussieht. */
.ch-rechts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-left: auto; }
/* Gibt es nur eine Gruppe, fallen die Reiter weg (View) – dann steht der Block
   links statt allein am rechten Rand mit einem Loch davor. */
.ch-leiste > .ch-rechts:only-child { margin-left: 0; }
.ch-rechts .cal-legend { margin: 0; }
/* Trennstrich zwischen Legende und Schalter: beide heißen „Office" – der Punkt
   erklärt die Farbe, der Schalter blendet die Ebene ein. Ohne den Strich liest
   man es als ein Element. */
.ch-trenn { width: 1px; height: 20px; background: var(--border); flex: none; }

/* Flaches oder schmales Fenster: die Leiste darf enger werden, aber die Fläche
   bleibt – sie ist die eigentliche Aussage. */
@media (max-width: 900px) {
    .ch-leiste { padding: 8px 10px; gap: 10px; }
    .ch-rechts { gap: 10px; }
    .ch-kennz { margin-left: 0; }
}

/* ============================================================
   Konto-Karte im Profil (03.09.2026, Variante A aus
   `_konto-und-gelesen-mockup.html`, aus drei Vorschlägen gewählt)
   ------------------------------------------------------------
   Vorher: vier Zeilen einer Definitionsliste, der eigene Name genauso groß
   wie „Letzter Login", darunter ein Knopf über die volle Breite. Jetzt zwei
   Zonen – oben WER (Kürzel, Name, Benutzername, Rolle als Chip), unten
   abgesetzt die Nebensache und der Weg zum Passwort. Kürzel statt Bild: die
   App kennt keine Profilbilder, zwei Buchstaben genügen als Anker.
   ============================================================ */
.kt-kopf { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* Deko ohne Schrift darauf – deshalb `--accent-gradient` und NICHT der
   Knopf-Verlauf (die Buchstaben sind weiß, aber groß und fett: der Kontrast
   reicht hier, siehe Kontrast-Abschnitt). */
.kt-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 14px; flex: none;
    background: var(--accent-gradient); color: #fff;
    font-weight: 700; font-size: 0.98rem; letter-spacing: 0.02em;
}
.kt-wer { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kt-wer strong { font-size: 1.12rem; line-height: 1.2; }
.kt-user { font-size: 0.8rem; color: var(--text-muted); }
.kt-rolle {
    display: inline-flex; align-items: center; gap: 5px; margin-left: auto; flex: none;
    font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 999px;
    background: var(--accent-soft); color: var(--accent);
}
/* Untere Zone: durch eine Linie abgesetzt, der Knopf rechts */
.kt-fuss {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
}
.kt-zuletzt { display: inline-flex; align-items: center; gap: 7px;
    font-size: 0.8rem; color: var(--text-muted); }
.kt-fuss .btn { margin-left: auto; }

/* ============================================================
   Testblick als andere Person (03.09.2026)
   ------------------------------------------------------------
   Ersetzt den Mitarbeiter-Modus (das Auge im Sidebar-Fuß), der als kleines
   eingefärbtes Icon regelmäßig übersehen wurde. Das Band steht deshalb ganz
   oben über allem und in Gold – der Farbe für „hier stimmt etwas nicht ganz",
   aber ohne Alarm. Es ist KEIN Fehler, nur ein Zustand, den man sehen muss.
   ============================================================ */
.tv-band {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    padding: 8px 18px;
    background: color-mix(in srgb, var(--gold) 16%, var(--surface));
    border-bottom: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
    font-size: 0.86rem; color: var(--text);
    position: relative; z-index: 45;   /* über der Sidebar (20), unter Popups */
}
.tv-band-t { display: inline-flex; align-items: center; gap: 9px; }
.tv-band-t svg { color: var(--gold); flex: none; }
.tv-band form { margin-left: auto; }
/* Die Auswahl (seit 03.09.2026 in Einstellungen → System → Debug-Modus, vorher im
   Admin-Profil): Feld und Knopf in einer Zeile, sonst nichts – kein Erklärtext,
   keine Beschriftung über dem Feld. **Nicht ohne Rücksprache wieder aufblasen.** */
.tv-form { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tv-wahl { flex: 1; min-width: 180px; }

/* ============================================================
   Wiedervorlage (03.09.2026, Migration 082)
   ------------------------------------------------------------
   Ein Notizbuch-Typ mit Datum – KEIN neues Modul (das alte „Tasks" bleibt
   entfernt, siehe CLAUDE.md). Drei Stellen tragen dieselbe Farbe: die
   Erinnerung oben auf der Startseite, die Zeile im Notizbuch und das Abzeichen
   im Popup.

   Farbwahl: `--gold` heißt in dieser App „schau mal her", ohne Alarm zu
   schlagen (wie das Testblick-Band). Überfälliges wird NICHT rot – eine
   vergessene Notiz ist kein Fehler. Der Typ-Chip selbst läuft über `--nbt`
   wie die anderen drei Typen.
   ============================================================ */
.nb-t-due { --nbt: var(--gold); }

/* Datumsfeld im Formular – steht direkt unter den Typ-Chips */
.nb-duefield { margin: 10px 0 2px; max-width: 240px; }
.nb-duefield[hidden] { display: none; }

/* Abzeichen im Popup und Datum in der Listenzeile */
.nb-badge-due {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 45%, transparent);
}
.nb-badge-due svg { color: var(--gold); }
.nb-badge-due.is-faellig {
    background: color-mix(in srgb, var(--gold) 16%, transparent);
    font-weight: 600;
}
.nb-due { display: inline-flex; align-items: center; gap: 4px; color: var(--text-muted); }
.nb-due svg { flex: none; }
.nb-due.is-faellig { color: var(--gold); font-weight: 600; }
.nb-due-done { color: var(--gold); border-color: color-mix(in srgb, var(--gold) 40%, transparent); }

/* Die Zeile in der Trefferliste: erst ab dem Fälligkeitstag auffällig. Vorher
   trägt sie nur das Datum in der Meta-Zeile – sonst stünde die halbe Liste
   dauerhaft in Gold, und die Hervorhebung wäre nichts mehr wert. */
.nb-row.is-faellig {
    border-left-color: var(--gold);
    background: color-mix(in srgb, var(--gold) 7%, transparent);
}
.nb-row.is-faellig .nb-row-title { font-weight: 700; }
/* Die gerade geöffnete Zeile behält ihre Markierung – sonst überschriebe das Gold
   hier den Akzent, weil dieser Block weiter unten in der Datei steht. */
.nb-row.is-faellig.is-active { border-color: var(--accent); background: var(--accent-soft); }
.nb-row.is-faellig.is-active .nb-row-title { color: var(--accent); }
.nb-row.is-faellig:hover { background: var(--surface-hover); }

/* ---------- Erinnerung ganz oben auf der Startseite ----------
   Steht über allen Abschnitten und ist bewusst KEIN sortierbarer Abschnitt
   (DashSections) – eine Erinnerung, die man sich wegsortieren kann, ist keine.
   **Nicht ohne Rücksprache in die Abschnitte einreihen.** */
.dash-wv {
    margin: 0 0 20px;
    padding: 14px 18px;
    border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
    border-radius: 14px;
    background: color-mix(in srgb, var(--gold) 10%, var(--surface));
}
.dash-wv-h {
    display: flex; align-items: center; gap: 8px;
    margin: 0 0 10px; font-size: 0.92rem; font-weight: 700; color: var(--text);
}
.dash-wv-h svg { color: var(--gold); flex: none; }
.dash-wv-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.dash-wv-item {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
}
.dash-wv-titel { font-weight: 600; color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.dash-wv-titel:hover { color: var(--accent); }
.dash-wv-wann { font-size: 0.78rem; color: var(--text-muted); white-space: nowrap; }
.dash-wv-item.is-spaet .dash-wv-wann { color: var(--gold); font-weight: 600; }
.dash-wv-item form { margin-left: auto; }
@media (max-width: 560px) {
    .dash-wv-item form { margin-left: 0; width: 100%; }
    .dash-wv-item form .btn { width: 100%; justify-content: center; }
}

/* Der Balken „Bereits gelesen" ist seit 03.09.2026 als GANZES der Umschalter
   (Wunsch Sebastian) – der Knopf rechts ist nur noch Beschriftung (ein <span>,
   kein <button>). Deshalb hier der Zeiger und die Hover-Fläche am Balken. */
.tl-sec-alt[role="button"] { cursor: pointer; }
.tl-sec-alt[role="button"]:hover { background: var(--surface-hover); }
.tl-sec-alt[role="button"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tl-sec-alt[role="button"]:hover .tl-sec-btn { color: var(--accent); border-color: var(--accent); }
/* Der Pfeil zeigt, wohin es geht: zugeklappt nach unten, offen nach oben. */
.tl-sec-alt .tl-sec-btn svg { transition: transform 0.15s ease; }
.tl-sec-alt[aria-expanded="true"] .tl-sec-btn svg { transform: rotate(180deg); }

/* ============================================================
   Neu vs. bereits gelesen – Variante C (03.09.2026 abends)
   ------------------------------------------------------------
   Aus `_gelesen2-mockup.html`, von Sebastian aus fünf Vorschlägen gewählt
   (A „Akzentkante", B „Gelesene ohne Karte", D „Kopf einfärben" und A+C sind
   verworfen – **nicht ohne Rücksprache bauen**).

   Zwei Dinge, mehr nicht:
   1. Der Punkt auf der Linie trägt an ungelesenen Zeilen einen Ring in der
      Akzentfarbe – wie ein ungelesener Chat. Bewusst IMMER Akzent, auch am
      violetten Gesprächsprotokoll-Punkt: der Ring sagt „neu", nicht „welche Art".
   2. Gelesene Karten nehmen ihre Fläche zurück.

   Warum ein eigenes Token (`--tl-gelesen`) und nicht `opacity` am ganzen
   Element: Deckkraft macht auch den TEXT blass – genau daran ist die frühere
   Klasse `.tl-done` gescheitert (die halbe Timeline sah kaputt aus). Und warum
   nicht einfach `color-mix(…, transparent)`: durchsichtig läuft in den Themes
   in ENTGEGENGESETZTE Richtungen – dunkel wird dunkler, hell wird heller.
   Gewollt ist beides Mal „etwas abgedunkelt" (Wunsch Sebastian), deshalb je
   Thema ein eigener Mischweg (siehe Theme-Block oben). Beide rechnen nur mit
   Flächen- und Rahmenfarben, nie mit dem Akzent – die Akzentfarbe ist
   einstellbar und darf hier nichts verschieben.
   ============================================================ */
.timeline-item[data-tl="note"]:not([data-tl-done]) > .tl-dot {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 32%, transparent);
}
.timeline-item[data-tl-done] > .tl-dot {
    background: var(--surface-hover);
    color: var(--text-muted);
    box-shadow: none;
}
/* Nur die Fläche, NICHT die Ränder: die linke Kante trägt in der langen
   Timeline noch die Bewertung (grün/rot) und darf nicht mit verblassen. */
.timeline-item[data-tl-done] { background: var(--tl-gelesen); }
.timeline-item[data-tl-done]:hover { background: var(--surface-hover); }

/* ---------- Haken „gelesen" beim Überfahren ----------
   Wieder da seit 03.09.2026 abends, nach ausdrücklicher Rücksprache – die
   Fassung von morgens desselben Tages war entfallen. Unterschiede: er steht
   NUR an ungelesenen Zeilen (zurück auf ungelesen gibt es nicht), er ist eine
   Abkürzung neben dem Öffnen, und sein Platz ist immer reserviert, damit die
   Kopfzeile beim Überfahren nicht springt. */
.tl-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    flex: none;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.14s ease, color 0.14s ease, border-color 0.14s ease, background 0.14s ease;
}
.timeline-item:hover .tl-check,
.tl-check:focus-visible { opacity: 1; }
.tl-check:hover {
    color: var(--accent);
    border-color: var(--accent);
    background: var(--accent-soft);
}
/* Gelesene Zeilen tragen keinen Schalter – auch dann nicht, wenn das Markup
   noch von vorher stammt (nachgeladene Seite, gerade abgehakte Zeile). */
.timeline-item[data-tl-done] .tl-check { display: none; }
/* Ohne Mauszeiger gibt es kein Überfahren – dort steht er gedämpft dauerhaft da. */
@media (hover: none) {
    .tl-check { opacity: 0.5; }
}
html.no-anim .tl-check { transition: none; }

/* Die eingefärbte Tageszahl im Kalenderkopf („dünn besetzt", 03.09.2026 abends,
   `.tp-num.is-eng` / `.is-knapp`) ist am 08.09.2026 in die Zeile BESETZUNG gewandert
   (`.tp-bes`, gleiche Schwellen). Die davor verworfenen Kopf-Varianten (Kreis mit
   Anwesenden/Abwesenden, getönte Fläche, Balken unter der Zahl) bleiben verworfen –
   **nicht ohne Rücksprache neu bauen.** */

/* ============================================================
   Halbrund-Bogen um eine Kennzahl (03.09.2026, Variante C)
   ------------------------------------------------------------
   Aus `_kennzahlen-ring-mockup.html`, von Sebastian aus vier Vorschlägen
   gewählt – zusammen mit der Entscheidung, auch den Hero-Bogen in der
   Qualitätssicherung auf Halbrund umzustellen: **beide Seiten sollen dieselbe
   Form zeigen.** Verworfen und **nicht ohne Rücksprache zu bauen:** der volle
   Ring (A), der kleine Ring mit Text daneben (B) und die nackte Zahl von vorher.

   Hier reines CSS. Die QS zeichnet ihren Bogen mit ApexCharts – das liegt dort
   ohnehin für die Diagramme –, die Startseite lädt die Bibliothek NICHT, und
   für einen Bogen lohnt sie sich nicht. Zwei Techniken, eine Form; wer das
   angleichen will, holt sich eine 600-KB-Bibliothek auf die Startseite.

   Aufbau: ein Kreis als `conic-gradient`, dessen untere Hälfte transparent ist
   (`from -90deg`, Farbe bis `q/2` Prozent, Spur bis 50 %, dann nichts). Ein
   `mask` schneidet die Mitte heraus – **bewusst kein zweiter Kreis in der
   Kartenfarbe**, sonst müsste jede Stelle, die den Bogen benutzt, ihren
   Hintergrund kennen.

   `--bogen-q` (0…100) setzt die View inline. Die Farbe kommt aus `--bogen-farbe`
   und folgt der Zahl daneben: normal Akzent, unter 80 % dasselbe Orange wie die
   Zahl (`is-alarm`).
   ============================================================ */
/* Der Bogen lädt sich beim Erscheinen auf (03.09.2026, Wunsch Sebastian):
   aus der leeren Spur heraus wächst die Fläche auf ihren Wert und nimmt dabei
   ihre Farbe an – nicht fertig eingefärbt dastehen.

   **Warum `@property`:** eine gewöhnliche Custom Property ist für den Browser
   ein Text und lässt sich nicht animieren – der Wert würde am Ende der
   Animation springen. Erst die Registrierung mit `syntax` macht `--bogen-fill`
   zu einer Zahl und `--bogen-ton` zu einer Farbe, die interpoliert werden
   können. Browser ohne `@property` zeigen den Bogen einfach ohne Aufladen.

   **Die statischen Werte auf `.bogen` sind Pflicht, nicht Deko:** sie sind der
   Zustand ohne Animation (reduzierte Bewegung, fehlendes `@property`). Fehlen
   sie, bleibt `--bogen-ton` auf seinem Initialwert `transparent` – der Bogen
   wäre unsichtbar. */
/* `inherits: true` ist Pflicht: gezeichnet wird der Bogen in `::before`, und ein
   Pseudo-Element erbt vom Element. Mit `inherits: false` sähe `::before` nur den
   Initialwert und stünde für immer auf demselben Stand – der erste Anlauf blieb
   genau daran hängen. */
@property --bogen-anim { syntax: "<number>"; inherits: true; initial-value: 1; }
/* **Kein `var()` in den Keyframes.** Der erste Versuch animierte direkt auf
   `var(--bogen-q)` – das schlug fehl, die Substitution greift dort nicht und der
   Bogen blieb leer. Deshalb läuft hier nur ein Faktor 0 → 1, und Füllstand wie
   Farbmischung rechnen ihn im Verlauf ein. */
@keyframes bogen-laden { from { --bogen-anim: 0; } to { --bogen-anim: 1; } }
.bogen {
    --bogen-q: 0;
    --bogen-w: 196px;
    --bogen-dicke: 17px;
    /* Grün, solange die Quote stimmt; unter der Schwelle setzt `is-alarm` das
       Orange der Zahl daneben. Bis 03.09.2026 war der gute Fall die
       Akzentfarbe – „grün bzw. orange" ist die Sprache, die alle anderen
       Qualitätszahlen sprechen. */
    --bogen-farbe: var(--positive);
    --bogen-anim: 1;   /* Zustand ohne Animation: voll und farbig */
    animation: bogen-laden 1.1s cubic-bezier(.22,.75,.3,1) both;
    position: relative;
    width: var(--bogen-w);
    /* Bogen + Platz für die Zahl darin. 0.62 statt 0.5: der offene Bauch trägt
       die Zahl, sonst stünde sie auf dem Rand. */
    height: calc(var(--bogen-w) * 0.62);
    display: flex;
    align-items: flex-end;
    justify-content: center;
}
.bogen.is-alarm { --bogen-farbe: color-mix(in srgb, var(--gold) 62%, var(--negative)); }
.bogen::before {
    content: "";
    position: absolute;
    left: 0; top: 0;
    width: var(--bogen-w);
    height: var(--bogen-w);
    border-radius: 50%;
    background: conic-gradient(from -90deg,
        color-mix(in srgb, var(--bogen-farbe) calc(var(--bogen-anim) * 100%), var(--surface-hover))
            calc(var(--bogen-q) * var(--bogen-anim) * 0.5%),
        var(--surface-hover) 0 50%,
        transparent 0);
    -webkit-mask: radial-gradient(circle closest-side,
        transparent calc(100% - var(--bogen-dicke) * 2), #000 calc(100% - var(--bogen-dicke) * 2 + 1px));
    mask: radial-gradient(circle closest-side,
        transparent calc(100% - var(--bogen-dicke) * 2), #000 calc(100% - var(--bogen-dicke) * 2 + 1px));
}
html.no-anim .bogen { animation: none; }
/* Die Zahl sitzt im offenen Bauch, leicht über der Grundlinie des Bogens. */
.bogen .kpi-hero { position: relative; font-size: 2.9rem; padding-bottom: 2px; }
@media (max-width: 700px) {
    .bogen { --bogen-w: 168px; --bogen-dicke: 15px; }
    .bogen .kpi-hero { font-size: 2.4rem; }
}

/* ---------- Azubi-Profil: Kennzahlen-Streifen + Reiter (04.09.2026) ----------
   Die Seite hatte acht Blöcke untereinander („wirkt sehr überladen"). Seitdem
   liegt der Inhalt in vier Reitern – Überblick · Logbuch · Leistung · Person
   (Variante A aus `_profil-tabs-mockup.html`, von Sebastian aus drei Vorschlägen
   gewählt; B „fünf Reiter" und C „zwei Reiter mit fester Spalte" sind verworfen,
   **nicht ohne Rücksprache bauen**).

   Der Kennzahlen-Streifen steht ÜBER den Reitern und bleibt deshalb immer
   sichtbar – das ist die Gegenleistung dafür, dass der Rest hinter Reitern
   verschwindet. Vier Kacheln, keine Diagramme: die Zahl und eine Einordnung. */
.pk-stats { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 18px; }
.pk-stat {
    flex: 1 1 170px;
    display: flex;
    flex-direction: column;
    gap: 1px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 12px 14px;
}
.pk-stat .pk-l { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: var(--text-muted); }
.pk-stat .pk-v { font-size: 1.5rem; font-weight: 700; line-height: 1.15;
    font-variant-numeric: tabular-nums; }
/* „vor 2 Tagen" ist Text, keine Zahl – sonst sprengt es die Kachel */
.pk-stat .pk-v-text { font-size: 1.05rem; padding-top: 5px; }
.pk-stat .pk-v.is-ok { color: var(--positive); }
.pk-stat .pk-v.is-warn { color: var(--warn-ink, var(--gold, #eda11f)); }
.pk-stat .pk-v.is-bad { color: var(--negative); }
.pk-stat .pk-s { font-size: 0.78rem; color: var(--text-muted); }

/* Reiter: der gemeinsame Baustein `.tabs`, nur mit etwas mehr Luft darunter */
.profile-tabs { margin-bottom: 18px; }
/* Ohne JavaScript stehen alle Reiter offen – `hidden` wirkt nur mit dem Skript.
   Die Seite bleibt dadurch vollständig lesbar. */
.profile-panel[hidden] { display: none; }

/* Die Kurzliste „Zuletzt passiert" (.pk-last*) ist mit dem Reiter „Überblick"
   am 04.09.2026 wieder entfallen – sie hat die Spalte gesprengt und damit die
   ganze Seite seitlich scrollen lassen (siehe die Regel unten). Das Logbuch
   zeigt dieselben Einträge vollständig. **Nicht ohne Rücksprache neu bauen.** */
