/* ===========================================================================
   UNTERBAU — uebernommen aus der frueheren assets/css/style.css.
   ---------------------------------------------------------------------------
   Diese Datei wurde zuvor VOR style-kollin.css geladen und war zu zwei Dritteln
   wirkungslos: die meisten Deklarationen ueberschrieb Kollin sofort wieder.
   Uebrig ist genau das hier — die Regeln, die WIRKLICH gewirkt haben. Sie stehen
   ganz oben, also an derselben Stelle der Kaskade wie vorher die eigene Datei.
   Alles danach in dieser Datei gewinnt gegen sie, so wie es immer war.
   =========================================================================== */
:root {
    --primary: #2563eb;

    /* === Abstände ===========================================================
       Ein 2px-Raster. Vorher standen hier 28 verschiedene Werte auf 461
       Stellen — dieselbe Rolle mal mit 9px, mal mit 10px, mal mit 11px.
       Neue Regeln nehmen eine STUFE, sie erfinden keinen Wert. Was daneben
       liegt, bleibt bewusst als nackter px-Wert stehen und faellt dadurch auf.
       ---------------------------------------------------------------------- */
    --s-2: 2px;
    --s-4: 4px;
    --s-6: 6px;
    --s-8: 8px;
    --s-10: 10px;
    --s-12: 12px;
    --s-14: 14px;
    --s-16: 16px;
    --s-18: 18px;
    --s-24: 24px;
    --s-32: 32px;

}
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
html {
    scroll-behavior: smooth;
}
/* Knöpfe und Felder erben die Schrift NICHT von selbst — der Browser gibt ihnen seine
   eigene, und dann steht Arial neben der Hausschrift. Nur die Familie: Größen bleiben,
   wo sie gesetzt sind. Als nackte Elementregel verliert das gegen jede Klasse, die
   bewusst eine andere Schrift wählt (Zeitfelder in der Festbreite). */
button, input, select, textarea, optgroup {
    font-family: inherit;
}
body {
    min-height: 100vh;
}
.container {
    margin: 0 auto;
}
.container-narrow {
    margin: 0 auto;
}
.app-header-inner {
    flex-wrap: wrap;
}
.app-logo {
    text-decoration: none;
}
.form-section {
    border-bottom: 1px solid var(--gray-200);
}
.form-section h2 {
    text-transform: uppercase;
}
.form-grid .full {
    grid-column: 1 / -1;
}
.field label {
    margin-bottom: var(--s-6);
}
.field label .req {
    color: var(--danger);
    margin-left: var(--s-2);
}
.field input,
.field select,
.field textarea {
    width: 100%;
    padding: var(--s-10) var(--s-12);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-sm);
    font-size: 14px;
    font-family: inherit;
    background: white;
    color: var(--gray-900);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}
.field .hint {
    margin-top: var(--s-4);
}
.radio-group {
    margin-top: var(--s-4);
}
.radio-group input {
    margin: 0;
    cursor: pointer;
}
.check-cards input:checked + span {
    font-weight: 500;
}
.btn-secondary {
    border: 1px solid var(--gray-300);
}
.form-footer {
    border-top: 1px solid var(--gray-200);
}
.form-footer .hint {
    font-size: 13px;
    color: var(--gray-500);
}
.alert-danger {
    border: 1px solid #fecaca;
}
.login-card h1 {
    text-align: center;
}
.login-card p {
    color: var(--gray-500);
    font-size: 14px;
    text-align: center;
    margin-bottom: var(--s-24);
}
.login-card .field {
    margin-bottom: var(--s-14);
}
.login-card .btn {
    width: 100%;
    justify-content: center;
}
.admin-toolbar {
    margin-bottom: var(--s-18);
}

.data-table tr:last-child td {
    border-bottom: none;
}
.data-table tr:hover {
    background: var(--gray-50);
}
.data-table .actions {
    display: flex;
    gap: var(--s-6);
    flex-wrap: wrap;
}
.status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.empty-state .icon {
    opacity: 0.3;
}
.empty-state h3 {
    margin-bottom: var(--s-6);
}
.empty-state p {
    color: var(--gray-500);
    font-size: 14px;
}
.app-footer {
    text-align: center;
}
@media print {
    body {
        background: white;
    }
}

/* =============================================================================
   Personal-Portal — "Kollin" Edition (Overlay)
   Lädt NACH style.css und überschreibt visuelle Tokens.
   Inspiriert von kollin.de: warmes Papier, CMYK-Akzente, handgeschriebene
   Akzente in Caveat, freundliche Du-Tonalität.
   ============================================================================= */

:root {
    /* === Typografie === */
    --font-display: "Plus Jakarta Sans", "Inter Tight", -apple-system, sans-serif;
    --font-sans:    "Plus Jakarta Sans", "Inter Tight", -apple-system, sans-serif;
    --font-hand:    "Caveat", cursive;
    --font-mono:    "JetBrains Mono", "SF Mono", ui-monospace, monospace;

    /* === Papier === */
    --paper:   #fbf8f1;
    --paper-2: #f5efe2;
    --surface: #ffffff;

    /* === Ink === */
    --ink:   #14110c;
    --ink-2: #3a352b;
    --ink-3: #6e6757;
    /* --ink-4 ist LEISE SCHRIFT, keine Linie (dafür gibt es --line-2). Auf --paper
       hatte das alte #aea689 nur 2,3:1 — auf dem Handy bei 9-10px unlesbar.
       Jetzt 4,3:1 und damit auch bei Sonne draußen noch zu lesen. */
    --ink-4: #7d755f;
    --line:   #e9e2d0;
    --line-2: #d6cdb4;

    /* === CMYK === */
    --c: #00a4d6;
    --m: #e6357a;
    --y: #f5c413;
    --k: #14110c;

    /* === Accent (Magenta-Default) === */
    --accent:        var(--m);
    --accent-2:      #b81e57;
    --accent-soft:   rgba(230, 53, 122, 0.12);
    --accent-paper:  #fde7ef;

    /* Bestehende CSS-Variablen aus style.css überschreiben,
       damit Komponenten ohne Klassen-Änderung in Kollin-Look erscheinen. */
    --primary:        var(--accent);
    --primary-hover:  var(--accent-2);
    --primary-light:  var(--accent-paper);
    --success:        #1f8a4c;
    /* Dunkle Tinte derselben Farbe — für Text AUF --success-light.
       #1f8a4c steht dort mit 3,8:1 und ist auf einem Handy draußen nicht
       zu lesen. --success bleibt die Signalfarbe für Flächen und Punkte. */
    --success-2:      #16703c;
    --success-light:  #def5e6;
    --warning:        #b8651a;
    --warning-light:  rgba(184, 101, 26, 0.12);
    --danger:         #b81e57;
    --gray-50:  var(--paper);
    --gray-100: var(--paper-2);
    --gray-200: var(--line);
    --gray-300: var(--line-2);
    --gray-400: var(--ink-4);
    --gray-500: var(--ink-3);
    --gray-600: var(--ink-3);
    --gray-700: var(--ink-2);
    --gray-800: var(--ink);
    --gray-900: var(--ink);

    --radius:    16px;
    --radius-sm: 10px;
    --radius-lg: 26px;

    --shadow:
        0 1px 0 rgba(20, 17, 12, 0.04),
        0 2px 6px rgba(20, 17, 12, 0.05);
    --shadow-md:
        0 1px 0 rgba(20, 17, 12, 0.04),
        0 2px 6px rgba(20, 17, 12, 0.05),
        0 12px 32px -10px rgba(20, 17, 12, 0.10);
    --shadow-lg:
        0 1px 0 rgba(20, 17, 12, 0.04),
        0 4px 12px rgba(20, 17, 12, 0.08),
        0 24px 48px -14px rgba(20, 17, 12, 0.16);

    --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

    /* Seitenrand. Kopfzeile UND Seiteninhalt speisen sich hieraus, sonst fluchten
       Logo und Überschrift nicht — das war unterhalb 1081px auf keiner Seite der Fall. */
    --gutter: 32px;
}
@media (max-width: 1080px) { :root { --gutter: 16px; } }
@media (max-width: 480px)  { :root { --gutter: 12px; } }

/* Akzent-Themes (kannst du im body über data-theme schalten).
   ACHTUNG: --accent trägt an fünfzehn Stellen WEISSE Schrift (Abzeichen,
   Punkte, Bänder). Kontrast ist symmetrisch — eine Farbe, die als Text auf
   Weiß zu hell ist, ist auch als Grund unter weißer Schrift zu hell. Die
   Marken-Reinformen --c (#00a4d6) und #b8901c standen dort bei 2,9:1; hier
   die abgedunkelten Varianten, die 4,5:1 erreichen. Wer sie aufhellt, macht
   jedes Abzeichen dieses Themes unlesbar, ohne dass irgendwo ein Fehler
   auftaucht — pruefe.py --nur kontrast meldet es. */
[data-theme="cyan"]   { --accent: #0b7fa6; --accent-2: #006c91; --accent-soft: rgba(0,164,214,0.12);  --accent-paper: #d9f1fb; }
[data-theme="yellow"] { --accent: #917010; --accent-2: #7d6010; --accent-soft: rgba(245,196,19,0.18); --accent-paper: #fff3c4; }
[data-theme="black"]  { --accent: var(--k); --accent-2: #000;   --accent-soft: rgba(20,17,12,0.08);    --accent-paper: var(--paper-2); }

/* ============================================================================
   BODY — warmes Papier statt grauer Gradient
   ============================================================================ */
body {
    font-family: var(--font-sans) !important;
    font-size: 14px;
    line-height: 1.5;
    color: var(--ink);
    background: var(--paper) !important;
    position: relative;
    -webkit-font-smoothing: antialiased;
}

/* Papierkorn als feines Overlay */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 0;
    opacity: 0.40;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence baseFrequency='0.85' numOctaves='2' seed='3'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.35'/></svg>");
    mix-blend-mode: multiply;
}

/* ============================================================================
   GLOBAL-POLISH — dezente, einheitliche Feinheiten (Scrollbars, Auswahl, Fokus)
   ============================================================================ */
/* Schlanke, zur warmen Palette passende Scrollbars (Firefox + WebKit) */
* { scrollbar-width: thin; scrollbar-color: var(--line-2) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--line-2); border-radius: 999px;
    border: 2px solid transparent; background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--ink-4); background-clip: padding-box; }

/* Textauswahl im Akzent-Ton */
::selection { background: var(--accent-soft); color: var(--ink); }

/* Einheitlicher, dezenter Tastatur-Fokus (nur bei Tastatur, nicht bei Maus-Klick) */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
:focus:not(:focus-visible) { outline: none; }

/* ============================================================================
   Projektleiter-Filter + "Am frühesten raus"-Hervorhebung (Projekte + Übersicht)
   ============================================================================ */
.leader-filter { margin-top: var(--s-16); display: flex; align-items: center; gap: var(--s-10); flex-wrap: wrap; }
.leader-filter label {
    display: inline-flex; align-items: center; gap: var(--s-6);
    font-family: var(--font-mono); font-size: 10px; color: var(--ink-3);
    text-transform: uppercase; letter-spacing: 0.12em; font-weight: 700;
}
.leader-filter label::before {
    content: ""; width: 14px; height: 14px; flex-shrink: 0; opacity: 0.75;
    background: no-repeat center / contain;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236e6757' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='12' cy='7' r='4'/%3E%3C/svg%3E");
}
.leader-filter select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    font-family: inherit; font-size: 13px; font-weight: 600; color: var(--ink);
    background-color: var(--surface);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%236e6757' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 13px center; background-size: 11px 8px;
    border: 1px solid var(--line); border-radius: 12px;
    padding: var(--s-10) 36px var(--s-10) var(--s-14); cursor: pointer; max-width: 260px;
    box-shadow: var(--shadow); transition: border-color .15s, box-shadow .15s;
}
.leader-filter select:hover { border-color: var(--ink-4); }
.leader-filter select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-paper); }
.leader-filter-reset {
    display: inline-flex; align-items: center; gap: var(--s-4);
    font-family: var(--font-mono); font-size: 11px; color: var(--ink-3);
    text-decoration: none; padding: var(--s-8) var(--s-14); border-radius: 999px;
    border: 1px solid var(--line); background: var(--surface);
    transition: border-color .15s, color .15s, background .15s;
}
.leader-filter-reset:hover { border-color: var(--accent-2); color: var(--accent-2); background: var(--accent-paper); text-decoration: none; }
@media (max-width: 480px) {
    .leader-filter { width: 100%; }
    .leader-filter select { flex: 1; max-width: none; }
}

@keyframes urgent-glow {
    0%, 100% { box-shadow: 0 0 0 1px var(--accent), 0 8px 22px -14px rgba(230, 53, 122, 0.30); }
    50%      { box-shadow: 0 0 0 1px var(--accent), 0 12px 30px -10px rgba(230, 53, 122, 0.55); }
}

@media (prefers-reduced-motion: reduce) {  .next-due-banner { animation: none; } }

/* "Als Nächstes raus"-Banner (Übersicht) — leuchtet dezent */
.next-due-banner {
    margin-top: var(--s-14);
    display: flex; align-items: center; gap: var(--s-10); flex-wrap: wrap;
    padding: var(--s-12) var(--s-16); border-radius: 14px;
    background: var(--accent-paper); border: 1px solid var(--accent);
    color: var(--ink); text-decoration: none;
    box-shadow: 0 0 0 1px var(--accent);
    animation: urgent-glow 2.6s ease-in-out infinite;
}
.next-due-banner:hover { background: #fde0ea; }
.next-due-ic  { font-size: 18px; line-height: 1; }
.next-due-txt { font-size: 13px; }
.next-due-txt strong { color: var(--accent-2); }
.next-due-go  { margin-left: auto; font-family: var(--font-mono); font-size: 11px; color: var(--accent-2); font-weight: 700; }
@media (max-width: 480px) { .next-due-go { margin-left: 0; } }

/* Übersicht: "Projekte im Zeitraum"-Panel mit Legende (Farbe + Name + Leiter) */
.ov-projects {
    margin-top: var(--s-24); padding: var(--s-16) var(--s-18);
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow);
}
.ov-projects-head {
    display: flex; align-items: center; gap: var(--s-10); margin-bottom: var(--s-14);
    font-family: var(--font-mono); font-size: 10px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
}
.ov-projects-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 20px; height: 20px; padding: 0 var(--s-6);
    background: var(--accent-paper); color: var(--accent-2);
    border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: 0;
}
.ov-legend { display: flex; flex-wrap: wrap; gap: var(--s-8); }
.ov-legend-item {
    display: inline-flex; align-items: center; gap: var(--s-8);
    padding: var(--s-8) var(--s-12) var(--s-8) var(--s-12); border-radius: 10px;
    background: var(--paper-2); border: 1px solid var(--line);
    text-decoration: none !important; color: var(--ink); font-size: 13px;
    transition: border-color 0.15s, transform 0.1s, box-shadow 0.15s;
}
.ov-legend-item:hover { border-color: var(--ink-4); transform: translateY(-1px); box-shadow: var(--shadow); }
.ov-legend-item.urgent { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ov-legend-dot { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; }
.ov-legend-name { font-weight: 700; color: var(--ink); }
.ov-legend-leader {
    font-family: var(--font-mono); font-size: 10px; color: var(--ink-3);
    background: var(--surface); border: 1px solid var(--line);
    padding: var(--s-2) var(--s-8); border-radius: 999px;
}

/* Container ein bisschen breiter */
.container       { max-width: 1280px; padding: 0 var(--gutter); position: relative; z-index: 1; }
.container-narrow{ max-width: 880px;  padding: 0 var(--gutter); position: relative; z-index: 1; }

/* ============================================================================
   APP-HEADER (Topbar) mit Kollin-Logo
   ============================================================================ */
.app-header {
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    padding: var(--s-18) 0;
    box-shadow: none;
    position: sticky;
    top: 0;
    z-index: 30;
    animation: kollin-drop 0.55s var(--ease-out) both;
}
@keyframes kollin-drop {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* Die Menüs der Kopfzeile (Glocke, Konto) liegen im Stapel des Kopfes — der Kopf muss
   deshalb in JEDEM Design eine Position tragen, sonst gilt sein z-index nicht (siehe
   glas/00-grund.css). Mit 30 liegt er über dem Seitenrahmen (.container, z-index 1) und
   allem darin. Ist ein Menü OFFEN, steigt er über alles, was zur Seite gehört und am
   Fenster klebt: Leiste unten (40), Rückmelde-Knopf (40), Assistent (41). Darüber liegen
   nur Fenster und Blätter (ab 49) — die schließen das Menü ohnehin. */
.app-header:has(.notif-menu.open, .lang-menu.open) { z-index: 45; }

.app-header-inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 var(--gutter);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-24);
}

.app-logo {
    display: flex;
    align-items: center;
    gap: var(--s-14);
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
    line-height: 1.15;
}

.app-logo .app-logo-mark { display: none; } /* alte Initiale ausblenden */

.app-logo img.kollin-logo {
    height: 44px;
    width: auto;
    display: block;
    transition: transform 0.4s var(--ease-spring);
}
.app-logo:hover img.kollin-logo { transform: rotate(-2deg) scale(1.04); }

.app-logo .brand-text {
    display: flex;
    flex-direction: column;
    padding-left: var(--s-14);
    border-left: 1px solid var(--line-2);
    line-height: 1.2;
}
.app-logo .brand-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
}
.app-logo .brand-sub {
    font-size: 11px;
    color: var(--ink-3);
    font-family: var(--font-mono);
    letter-spacing: 0.04em;
}

.app-nav { display: flex; gap: var(--s-4); align-items: center; }
/* Die waagerechte Linkleiste im Kopf gibt es nicht mehr — die Navigation liegt
   in der Funktions-Leiste. Ihre Regeln (.app-nav a) standen aber weiter hier und
   trafen mit Spezifität (0,1,1) alles, was HEUTE in <nav class="app-nav"> steht:
   die Zeilen des Glocken-Menüs und den Fußlink. Die Zeilen wurden dadurch 31px
   hoch statt 40 (Tippziel verfehlt), bekamen Pillenform und die falsche Farbe —
   ohne dass irgendwo etwas falsch aussah, denn die Regeln sahen ja gewollt aus.
   Gelöscht statt eingeschränkt: <nav class="app-nav"> hat keine direkten
   <a>-Kinder mehr, ein `.app-nav > a` wäre totes CSS. */

/* CMYK-Streifen unter Topbar */
.cmyk-strip {
    height: 3px;
    background: linear-gradient(
        to right,
        var(--c) 0% 25%,
        var(--m) 25% 50%,
        var(--y) 50% 75%,
        var(--k) 75% 100%
    );
}

/* ============================================================================
   EYEBROW — kleine Monospace-Überschrift mit pulsing Dot
   ============================================================================ */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--s-10);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    font-weight: 500;
    margin-bottom: var(--s-24);
}
.eyebrow .dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--accent);
    animation: kollin-pulse 2.2s ease-in-out infinite;
    box-shadow: 0 0 0 0 var(--accent-soft);
}
@keyframes kollin-pulse {
    0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); }
    50%      { box-shadow: 0 0 0 6px transparent; }
}

/* ============================================================================
   HAND — Caveat-Akzente in Headlines
   ============================================================================ */
.hand {
    /* Steht ausschließlich in Überschriften („Hallo <em class=hand>Anna</em>")
       und erbt deren Größe — also Großschrift, für die 3:1 genügt. Die Regel
       selbst setzt keine Größe, deshalb hier belegt statt stillschweigend. */
    --kontrast-ok: "Zierschrift, erbt immer eine Überschriftgröße";
    font-family: var(--font-hand);
    font-style: normal;
    font-weight: 600;
    color: var(--accent);
    display: inline-block;
    transform: rotate(-2deg) translateY(4px);
    margin: 0 var(--s-4);
    letter-spacing: 0;
}

/* ============================================================================
   HEADLINES — editorial Display
   ============================================================================ */
h1, h2, h3 { font-family: var(--font-display); letter-spacing: -0.018em; }

/* ============================================================================
   BUTTONS
   ============================================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--s-10);
    padding: var(--s-12) var(--s-24);
    background: var(--ink);
    color: var(--paper);
    border: 1px solid var(--ink);
    border-radius: 999px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.3s var(--ease-spring), background 0.3s, color 0.3s;
    text-decoration: none;
    position: relative;
    overflow: hidden;
}
.btn::before {
    content: "";
    position: absolute;
    top: 0; left: -100%;
    width: 100%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
    transition: left 0.6s var(--ease-out);
}
.btn:hover         { transform: translateY(-2px); background: var(--accent); border-color: var(--accent); color: white; }
.btn:hover::before { left: 100%; }
.btn:active        { transform: translateY(0) scale(0.98); }

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: white;
    box-shadow: 0 8px 20px -8px var(--accent-soft);
}
.btn-primary:hover { background: var(--accent-2); border-color: var(--accent-2); }

.btn-secondary {
    background: var(--surface);
    color: var(--ink);
    border-color: var(--line-2);
    box-shadow: var(--shadow);
}
.btn-secondary:hover {
    background: var(--paper-2);
    border-color: var(--ink-3);
    color: var(--ink);
}

.btn-sm { padding: var(--s-8) var(--s-14); font-size: 12px; }
.btn svg { width: 14px; height: 14px; }

.form-section {
    padding: var(--s-24);
    margin-bottom: var(--s-18);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    transition: transform 0.35s var(--ease-out), box-shadow 0.35s, border-color 0.3s;
}
.form-section:focus-within {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
    border-color: var(--accent);
}
.form-section h2 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    letter-spacing: -0.012em;
    color: var(--ink);
    margin-bottom: var(--s-18);
    padding-bottom: 0;
    border: 0;
}

.form-grid {
    display: grid;
    /* minmax(0, 1fr) statt 1fr: `1fr` bedeutet `minmax(auto, 1fr)`, und dieses
       `auto` verbietet der Spur, unter die Eigenbreite ihres Inhalts zu gehen.
       Bei einem Feld mit nativem Bedienelement wächst die Spur dadurch über den
       Behälter hinaus. Beide Seiten müssen nachgeben — die Spur hier, das Feld
       über sein min-width. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-16) var(--s-18);
}
.form-grid > .field { min-width: 0; }

/* Am Handy einspaltig. MUSS hier stehen, NACH der Grundregel:
   Beide Selektoren sind `.form-grid` (0,1,0), und bei gleicher Spezifität
   gewinnt die spätere Regel. Diese hier stand über 600 Zeilen WEITER OBEN und
   wurde deshalb nie wirksam — jedes Formular blieb auf dem Handy zweispaltig,
   mit rund 155px schmalen Spalten. Für ein Datumsfeld ist das zu wenig; es
   stand dann über den Rand. Ein @media-Block schützt NICHT vor der Kaskade. */
@media (max-width: 640px) {
    .form-grid { grid-template-columns: minmax(0, 1fr); }
}
.form-grid .field.full,
.form-grid .field-full { grid-column: 1 / -1; }

.field { display: flex; flex-direction: column; gap: var(--s-6); }
.field label {
    font-size: 12px;
    color: var(--ink-2);
    font-weight: 600;
}
.field .req { color: var(--accent-2); font-family: var(--font-mono); font-size: 11px; }

/* style.css nimmt der LETZTEN .form-section die Unterkante (Rest aus dem alten
   Trennlinien-Layout, Spezifität 0,2,0). Hier sind es Karten mit Rahmen — die
   unterste stand deshalb unten offen. Gleiche Spezifität, spätere Datei gewinnt. */
.form-section:last-of-type { border-bottom: 1px solid var(--line); }
/* Die Liste muss JEDEN Texttyp nennen, den ein Formular benutzt. Fehlt einer,
   greift für ihn die unspezifische Regel aus style.css (.field input = 0,1,1)
   und das Feld steht weiß mit anderem Polster NEBEN seinen Nachbarn — genau so
   sahen time und datetime-local aus, direkt neben dem Datumsfeld derselben Zeile. */
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="date"],
.field input[type="time"],
.field input[type="datetime-local"],
.field input[type="number"],
.field input[type="password"],
.field input[type="search"],
.field input[type="url"],
.field textarea,
.field select {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: var(--s-12) var(--s-14);
    font-size: 14px;
    color: var(--ink);
    font-family: inherit;
    transition: border-color 0.25s, background 0.25s, box-shadow 0.25s, transform 0.25s;
    width: 100%;
    /* min-width: 0 ist hier kein Zierrat, sondern die Bedingung dafür, dass
       `width: 100%` überhaupt greifen kann. WebKit auf dem iPhone gibt
       date-/time-Feldern aus ihrem nativen Bedienelement eine Mindestbreite —
       die schlägt die 100 %, und das Feld steht dann über den Kartenrand
       hinaus. Auf dem Gerät gemessen: die Datums- und Zeitfelder endeten rund
       26px weiter rechts als das Textfeld und der Knopf darunter.
       In Chrome passiert das NICHT — deshalb fällt es beim Entwickeln nie auf. */
    min-width: 0;
}

/* iOS-Safari: date-, time- und datetime-Felder tragen ein NATIVES Bedienelement.
   Dessen Breite lässt sich weder mit `width: 100%` noch mit `min-width: 0`
   unterbieten — beides haben wir zuerst versucht, beides half nicht. Erst
   `appearance: none` nimmt dem Feld diese Eigenbreite und macht daraus eine
   ganz normale Box.
   Auf dem Gerät gemessen: die drei Felder standen rund 26px weiter rechts als
   das Textfeld und der Knopf im selben Formular. In Chrome tritt das NICHT auf,
   dort schrumpfen dieselben Felder anstandslos — deshalb ist es am Schreibtisch
   unsichtbar.
   `max-width: 100%` ist der Riegel dahinter: was auch immer eine Fassung sich
   als Eigenbreite ausdenkt, über den Behälter kommt sie nicht hinaus.
   `min-height` gibt die Höhe zurück, die `appearance: none` dem Feld nimmt —
   und trifft dabei gleich die Tippziel-Grenze dieser Datei. */
.field input[type="date"],
.field input[type="time"],
.field input[type="datetime-local"],
input[type="date"],
input[type="time"],
input[type="datetime-local"] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    max-width: 100%;
    min-width: 0;
    min-height: 40px;
}
.field input:focus,
.field textarea:focus,
.field select:focus {
    outline: none;
    border-color: var(--accent);
    background: white;
    box-shadow: 0 0 0 4px var(--accent-soft);
    transform: translateY(-1px);
}
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-4); }
.field .hint { font-size: 11px; color: var(--ink-3); }

/* Monospace-Look für IBAN, Steuer-ID, RV-Nummer, SV-Nummer */
input[name="iban"],
input[name="bic"],
input[name="steuer_id"],
input[name="rv_nummer"],
input[name="sv_nummer"] {
    font-family: var(--font-mono);
    letter-spacing: 0.02em;
}

/* Radio-Pills statt Browser-Radios */
.radio-group {
    display: flex;
    gap: var(--s-8);
    flex-wrap: wrap;
}
.radio-group label {
    display: inline-flex;
    align-items: center;
    gap: var(--s-8);
    padding: var(--s-10) var(--s-16);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 13px;
    color: var(--ink-2);
    cursor: pointer;
    transition: all 0.25s var(--ease-out);
    user-select: none;
    font-weight: 500;
}
.radio-group label:hover {
    background: white;
    border-color: var(--ink-4);
    color: var(--ink);
    transform: translateY(-1px);
}
.radio-group label:has(input:checked) {
    color: white;
    border-color: var(--accent);
    background: var(--accent);
    box-shadow: 0 4px 12px -4px var(--accent-soft);
    font-weight: 600;
}
.radio-group input[type="radio"] { display: none; }

/* check-cards: Status, Schulabschluss, Berufsausbildung */
.check-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
    gap: var(--s-8);
}
.check-cards label {
    display: flex;
    align-items: center;
    gap: var(--s-10);
    padding: var(--s-14) var(--s-16);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 12px;
    font-size: 13px;
    color: var(--ink-2);
    cursor: pointer;
    transition: all 0.25s var(--ease-out);
}
.check-cards label:hover {
    background: white;
    border-color: var(--ink-4);
    color: var(--ink);
}
.check-cards label:has(input:checked) {
    color: white;
    border-color: var(--accent);
    background: var(--accent);
    font-weight: 600;
}
.check-cards input[type="radio"] { accent-color: white; }

/* Die Fußzeile eines Formulars trägt nur die Knöpfe — sie ist keine Karte. */
.form-footer {
    margin-top: var(--s-18);
    border: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-12);
    flex-wrap: wrap;
}
@media (max-width: 560px) {
    .form-footer .btn { flex: 1 1 auto; justify-content: center; }
}

/* ============================================================================
   ADMIN — Tabs, Toolbar, Tabelle
   ============================================================================ */
.admin-toolbar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin: var(--s-32) 0 var(--s-16);
    gap: var(--s-24);
    flex-wrap: wrap;
}
.admin-toolbar h1 {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 38px;
    letter-spacing: -0.022em;
    line-height: 1.05;
    color: var(--ink);
}

.data-table {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-md);
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
}
.data-table th {
    text-align: left;
    font-size: 10px;
    font-weight: 700;
    color: var(--ink-3);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    padding: var(--s-14) var(--s-18);
    border-bottom: 1px solid var(--line);
    background: var(--paper-2);
}
.data-table td {
    padding: var(--s-16) var(--s-18);
    border-bottom: 1px solid var(--line);
    font-size: 13px;
    vertical-align: middle;
    color: var(--ink);
}
.data-table tbody tr {
    transition: background 0.25s;
}
.data-table tbody tr:hover { background: var(--paper-2); }
.data-table tbody tr:last-child td { border-bottom: 0; }

/* Status-Pills neu */
.status            { display: inline-flex; align-items: center; gap: var(--s-8); font-size: 12px; padding: var(--s-4) var(--s-12) var(--s-4) var(--s-10); border-radius: 999px; font-weight: 600; }
.status-open       { background: var(--warning-light); color: var(--warning); }
.status-done       { background: var(--accent-paper);  color: var(--accent-2); }
.status .status-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* Alerts (Erfolg/Warnung/Fehler) */
.alert {
    background: var(--accent-paper);
    color: var(--accent-2);
    border: 1px solid var(--accent);
    border-radius: 14px;
    padding: var(--s-16) var(--s-18);
    font-size: 13px;
    line-height: 1.55;
    margin-bottom: var(--s-16);
}
.alert-danger {
    background: rgba(184, 30, 87, 0.08);
    color: #6f1235;
    border-color: rgba(184, 30, 87, 0.35);
}

/* Empty-State */
.empty-state {
    padding: 80px var(--s-24);
    text-align: center;
    color: var(--ink-3);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-top: var(--s-16);
    box-shadow: var(--shadow-md);
}
/* Leer-Zustand-Symbol. Hängt am .icon selbst und nicht an .empty-state: Chat
   und Aushilfen-Übersicht bauen ihren eigenen Leer-Zustand, bekommen aber
   dasselbe Zeichen. Ohne feste Box fiele das SVG auf 300x150 zurück.
   Die Zurückhaltung kommt über die Farbe, nicht über opacity — 0.3 aus dem
   Unterbau löst ein 1,6px-Strichbild fast auf. */
.icon {
    opacity: 1;
    display: flex; justify-content: center;
    color: var(--ink-4);
    margin-bottom: var(--s-12);
}
.icon svg { width: 40px; height: 40px; display: block; }
.empty-state h3 {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 24px;
    color: var(--ink);
    margin: var(--s-8) 0;
}


/* ============================================================================
   LOGIN- / Setup-Karte
   ============================================================================ */
.login-card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 22px;
    padding: 44px 40px;
    box-shadow: var(--shadow-lg);
    margin: 40px auto;
    position: relative;
    animation: kollin-drop 0.6s var(--ease-out);
}
.login-card::before {
    /* Ohne Emoji: der Rest der Oberfläche zeichnet mit Strichsymbolen. */
    content: "Hi";
    position: absolute;
    top: -20px;
    right: 18px;
    font-family: var(--font-hand);
    font-size: 28px;
    color: var(--accent);
    transform: rotate(6deg);
    font-weight: 600;
    background: var(--paper);
    padding: 0 var(--s-8);
}
.login-card h1 {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 32px;
    margin-bottom: var(--s-8);
    letter-spacing: -0.02em;
    color: var(--ink);
}
@media (max-width: 480px) {
    .login-card { padding: var(--s-32) var(--s-24); border-radius: 18px; margin: var(--s-24) auto; }
    .login-card h1 { font-size: 27px; }
}

/* ============================================================================
   FOOTER — Kollin
   ============================================================================ */
/* Der Fuß steht IMMER ganz unten. Die Seite ist eine Spalte von Fensterhöhe; der Rahmen
   mit dem Inhalt (.app-shell) nimmt, was übrig bleibt, und schiebt den Fuß damit an den
   unteren Fensterrand. Ist der Inhalt länger als das Fenster, ändert sich nichts — der
   Fuß folgt wie bisher auf ihn. Vorher endete eine kurze Seite („Meine Einsätze" ohne
   Einsätze) mitten im Bild, und darunter blieb die halbe Fensterhöhe leer.
   Die Seiten ohne Anmeldung sind für genau diese Spalte gebaut (ihr <main> trägt
   `flex: 1`): Karte mittig, Fuß unten.
   dvh: Am iPhone ist 100vh höher als das sichtbare Fenster, der Fuß läge unter dem Rand.
   Nur am Bildschirm — gedruckt wird wie bisher im Block. */
@media screen {
    body { display: flex; flex-direction: column; min-height: 100dvh; }
    .app-shell { flex: 1 0 auto; }
}
.app-footer {
    margin-top: 60px;
    padding: var(--s-32);
    color: var(--ink-3);
    font-size: 11px;
    border-top: 1px solid var(--line);
    background: var(--paper);
    font-family: var(--font-mono);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    position: relative;
    z-index: 1;
}
.app-footer-inner {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    /* Mittig: Die Verweise sind 40 px hoch (Tippziel), die Zeilen daneben nicht — ohne das
       stand „© …" oben an der Kante und die Verweise eine halbe Zeile tiefer. */
    align-items: center;
    gap: var(--s-16);
    flex-wrap: wrap;
}
/* Impressum und Datenschutz: Die Schrift bleibt klein, das Tippziel nicht (war 17 px hoch). */
.app-footer-inner a { display: inline-flex; align-items: center; min-height: 40px; }
.app-footer .signature {
    font-family: var(--font-hand);
    font-size: 18px;
    color: var(--ink-2);
    text-transform: none;
    letter-spacing: 0;
}

/* ============================================================================
   REVEAL / STAGGER — IntersectionObserver-getrieben via kollin.js
   ============================================================================ */
[data-reveal] {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}
[data-reveal].in { opacity: 1; transform: translateY(0); }

[data-reveal-stagger] > * {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
[data-reveal-stagger].in > * { opacity: 1; transform: translateY(0); }
[data-reveal-stagger].in > *:nth-child(1) { transition-delay: 0.06s; }
[data-reveal-stagger].in > *:nth-child(2) { transition-delay: 0.14s; }
[data-reveal-stagger].in > *:nth-child(3) { transition-delay: 0.22s; }
[data-reveal-stagger].in > *:nth-child(4) { transition-delay: 0.30s; }
[data-reveal-stagger].in > *:nth-child(5) { transition-delay: 0.38s; }
[data-reveal-stagger].in > *:nth-child(6) { transition-delay: 0.46s; }

/* Section-Head mit Nummerierung 01 / 12 — automatisch via CSS-Counter,
   damit das Markup nicht 12× von Hand erweitert werden muss. */
.form-section > h2 {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    letter-spacing: -0.012em;
    color: var(--ink);
    margin: 0 0 var(--s-18);
    border: 0;
    padding: 0;
}

/* Stat-Row mit Karten + CMYK-Punkten — adaptiv: passt sich der Breite an (Handy → 1-2 Spalten). */
.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
    gap: var(--s-14);
    margin-bottom: var(--s-24);
}
@media (max-width: 760px) {
    .stat-row { grid-template-columns: repeat(2, 1fr); gap: var(--s-10); }
}
.stat-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: var(--s-18);
    box-shadow: var(--shadow);
    transition: all 0.4s var(--ease-out);
    position: relative;
    overflow: hidden;
}
.stat-card:nth-child(1)::before { background: var(--c); }
.stat-card:nth-child(2)::before { background: var(--m); }
.stat-card:nth-child(3)::before { background: var(--y); }
.stat-card:nth-child(4)::before { background: var(--k); }
.stat-card::before {
    content: "";
    position: absolute;
    top: 14px;
    right: 14px;
    width: 8px; height: 8px;
    border-radius: 50%;
    opacity: 0.85;
}
.stat-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}
.stat-card .stat-lbl {
    font-size: 10px;
    color: var(--ink-3);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    font-weight: 700;
    margin-bottom: var(--s-8);
}
.stat-card .stat-val {
    font-family: var(--font-display);
    font-size: 34px;
    font-weight: 800;
    color: var(--ink);
    line-height: 1;
    letter-spacing: -0.025em;
}
.stat-card .stat-trend {
    margin-top: var(--s-8);
    font-size: 12px;
    color: var(--accent);
    font-family: var(--font-mono);
}

/* Auf dem Handy nahmen vier Kacheln mit 34px-Zahlen den ganzen ersten Bildschirm.
   Ab hier stehen dieselben Zahlen als schmale Zeilen: Wert links, Bezeichnung
   daneben. Gleiche Information, ein Drittel der Höhe. */
@media (max-width: 560px) {
    .stat-row { grid-template-columns: 1fr; gap: 0; margin-bottom: var(--s-18);
                border: 1px solid var(--line); border-radius: var(--radius);
                background: var(--surface); overflow: hidden; box-shadow: var(--shadow); }
    .stat-card { padding: var(--s-10) var(--s-14); border: 0; border-radius: 0; box-shadow: none;
                 display: flex; align-items: baseline; gap: var(--s-10);
                 border-top: 1px solid var(--line); background: transparent; }
    .stat-card:first-child { border-top: 0; }
    .stat-card:hover { transform: none; box-shadow: none; }
    .stat-card::before { display: none; }
    .stat-card .stat-lbl { margin-bottom: 0; order: 2; }
    .stat-card .stat-val { font-size: 20px; order: 1; min-width: 3ch; }
    .stat-card .stat-trend { margin-top: 0; order: 3; margin-left: auto; }
}

/* ============================================================================
   Login: SSL/CSRF Footer-Zeile
   ============================================================================ */
.login-card .lead {
    font-size: 13px;
    color: var(--ink-3);
    margin-bottom: var(--s-24);
}
.login-card .security-tags {
    font-size: 10px;
    color: var(--ink-3);
    margin-top: var(--s-24);
    font-family: var(--font-mono);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: center;
}

/* ============================================================================
   Responsive Anpassungen
   ============================================================================ */
@media (max-width: 960px) {
    .brand-text { display: none; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============ MONATSKALENDER (Übersicht + Aushilfen) ============ */
.mcal {
    margin-top: var(--s-14);
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: var(--shadow-md);
}
.mcal-wd {
    background: var(--paper-2);
    padding: var(--s-8) var(--s-10);
    font-family: var(--font-mono);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--ink-3);
    text-align: center;
}
.mcal-cell {
    background: var(--surface);
    min-height: 110px;
    padding: var(--s-6);
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
    position: relative;
}
.mcal-cell.out { background: var(--paper); }
.mcal-cell.out .mcal-day { color: var(--ink-4); }
.mcal-cell.today { background: var(--accent-paper); }
.mcal-cell-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.mcal-day { font-weight: 700; font-size: 14px; color: var(--ink); line-height: 1; }
.mcal-cell.today .mcal-day { color: var(--accent-2); }
.mcal-delivery { font-size: 14px; }
.mcal-projects { display: flex; flex-direction: column; gap: var(--s-2); min-height: 0; flex: 1; }
.mcal-pill {
    padding: var(--s-2) var(--s-6);
    font-size: 11px;
    font-weight: 600;
    border-radius: 4px;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
    transition: transform 0.1s, opacity 0.1s;
}
.mcal-pill:hover { transform: translateX(2px); opacity: 0.85; }
/* Mehrfarbige Pille: Farb-Streifen links statt einfachem border-left */
.mcal-pill.multi {
    display: flex;
    align-items: center;
    gap: var(--s-6);
    padding-left: var(--s-4);
}
.mmc-pill.multi {
    display: flex;
    align-items: center;
    gap: var(--s-4);
    padding-left: var(--s-2);
}
.pill-strip {
    flex-shrink: 0;
    display: inline-flex;
    flex-direction: column;
    align-self: stretch;
    width: 3px;
    border-radius: 2px;
    overflow: hidden;
    min-height: 12px;
}
.pill-strip > span { flex: 1 1 0; display: block; min-height: 3px; }
/* „+2" in der Aushilfen-Monatsansicht (dort werden nur 4 Schichten je Tag gezeigt). */
.mcal-more { font-family: var(--font-mono); font-size: 10px; color: var(--ink-3); padding: 1px var(--s-6); }
@media (max-width: 768px) {
    .mcal-cell { min-height: 70px; padding: var(--s-4); }
    .mcal-pill { font-size: 10px; padding: 1px var(--s-4); }
    .mcal-day { font-size: 12px; }
}
/* Zwischenstufe: ab 1200px wird es eng — Nav-Links dichter setzen, statt sie
   in eine zweite Zeile umbrechen zu lassen (das schob vorher den Seiteninhalt
   sichtbar nach unten und ließ die Kopfzeile doppelt so hoch wirken). */
@media (max-width: 1200px) {
    .app-logo img.kollin-logo { height: 38px; }
}

/* Unter 1080px rückt die Kopfzeile zusammen. Die frühere Burger-Klapp-Navigation
   ist entfallen — die Ziele stehen vollständig im Funktions-Hub. */
@media (max-width: 1080px) {
    .app-header-inner { gap: var(--s-12); }
    .app-nav { gap: var(--s-8); justify-content: flex-end; }
    .notif-bell, .lang-switcher { flex-shrink: 0; }
}
@media (max-width: 480px) {
    .app-header-inner { gap: var(--s-8); }
    .brand-sub { display: none; }
}

/* ====== Schönere Dropdowns (native select aufgehübscht) ====== */
.field select,
select.kollin-select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-color: var(--surface);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236e6757' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 14px center;
    padding-right: 40px !important;
    border: 1px solid var(--line);
    border-radius: 10px;
    color: var(--ink);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    transition: border-color 0.15s, box-shadow 0.15s, background-color 0.15s;
}
.field select:hover,
select.kollin-select:hover { border-color: var(--line-2); }
.field select:focus,
select.kollin-select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
    background-color: #fff;
}
.field select:disabled { opacity: 0.55; cursor: not-allowed; background-color: var(--paper-2); }

/* ====== Benachrichtigungs-Glocke ====== */
.notif-bell { position: relative; }
.notif-trigger {
    position: relative; display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 999px;
    background: var(--paper-2); border: 1px solid var(--line);
    cursor: pointer; font-size: 17px; line-height: 1; padding: 0;
}
.notif-trigger:hover { background: var(--surface); border-color: var(--ink-4); }
.notif-badge {
    position: absolute; top: -3px; right: -3px;
    min-width: 17px; height: 17px; padding: 0 var(--s-4);
    background: var(--accent); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 17px; text-align: center;
    border-radius: 999px; font-family: var(--font-mono);
    border: 2px solid var(--paper);
}
/* Das Menü der Glocke: Kopfzeile, Liste, Fuß — untereinander in einer Spalte. Nur die
   Liste rollt; Kopf und Fuß bleiben stehen. Höher als der Platz unter dem Kopf wird das
   Menü nie (am Handy: bis zur Leiste unten). --notif-oben ist die Oberkante des Menüs im
   Fenster — das Skript in _footer.php misst sie beim Öffnen; ohne Skript gilt der Wert
   der üblichen Kopfhöhe. */
.notif-menu {
    display: none; position: absolute; top: calc(100% + 8px); right: 0;
    flex-direction: column;
    width: 380px; max-width: calc(100vw - 32px);
    max-height: calc(100vh - var(--notif-oben, 76px) - var(--leiste-unten) - var(--s-12));
    max-height: calc(100dvh - var(--notif-oben, 76px) - var(--leiste-unten) - var(--s-12));
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 14px; box-shadow: var(--shadow-lg);
    z-index: 60; overflow: hidden;
}
.notif-menu.open { display: flex; }
.notif-head {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between; gap: var(--s-8);
    padding: var(--s-4) var(--s-4) var(--s-4) var(--s-16); border-bottom: 1px solid var(--line);
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em;
    color: var(--ink-3); font-weight: 700;
}
/* Beide Hälften auf Tippziel-Höhe: So bleibt die Kopfzeile gleich hoch, ob der
   Knopf nun steht oder nicht — sonst springt das Menü, sobald alles gelesen ist. */
.notif-head > * { display: flex; align-items: center; min-height: 40px; }
/* MUSS hier stehen: die Zeile darüber setzt `display` auf JEDES Kind und schlägt
   damit die Browser-Regel für [hidden] — ohne diese Ausnahme bliebe der Knopf
   auch dann stehen, wenn es nichts abzuräumen gibt. */
.notif-head > [hidden] { display: none; }
.notif-head-act {
    flex: 0 0 auto; padding: 0 var(--s-12);
    background: none; border: 0; border-radius: 999px; cursor: pointer;
    font-family: inherit; font-size: 12px; font-weight: 600;
    letter-spacing: 0; text-transform: none; color: var(--accent-2);
}
.notif-head-act:hover { background: var(--paper-2); }
.notif-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }

/* Ein Eintrag: Zeichen links, daneben der Text, darunter klein die Zeit. Eine Zeile je
   Meldung, durch eine Linie getrennt — keine Kästen im Kasten. */
.notif-item {
    display: flex; align-items: flex-start; gap: var(--s-12);
    padding: var(--s-12) var(--s-16); text-decoration: none; color: var(--ink);
    border-bottom: 1px solid var(--line); transition: background 0.1s;
}
.notif-item:last-child { border-bottom: 0; }
a.notif-item:hover { background: var(--paper-2); }
/* Zeichen der Meldung (notif_icon) bzw. des Kanals: derselbe ruhige Kreis wie bei den
   Personen daneben (.pkreis, 36 px) — die linke Kante steht in einer Flucht. */
.notif-sym {
    flex: 0 0 36px; width: 36px; height: 36px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--paper-2); color: var(--ink-2);
}
.notif-sym svg { width: 18px; height: 18px; display: block; }
.notif-sym-warn { background: var(--warning-light); color: var(--warning); }
/* min-height = Höhe des Zeichens: Eine einzeilige Meldung steht mittig neben ihm, eine
   mehrzeilige beginnt auf seiner Höhe und wächst nach unten. */
.notif-item-main { flex: 1 1 auto; min-width: 0; min-height: 36px; display: flex; flex-direction: column; justify-content: center; gap: var(--s-2); }
/* Text der Meldung: bricht um, höchstens drei Zeilen — der Rest steht auf der Seite
   „Alle Benachrichtigungen". Lange Wörter (Projektnamen) sprengen die Spalte nicht. */
.notif-item-text {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
    font-size: 13px; line-height: 1.4; color: var(--ink-2); overflow-wrap: anywhere;
}
/* Beide als Block: Als inline-Spans standen Name und Vorschau in einer Zeile
   ohne Trennung, und die Kürzung mit … griff nicht (text-overflow wirkt nur auf
   Blockelementen) — eine lange Vorschau lief 290 px über die Spalte hinaus. */
.notif-item-name { display: block; font-weight: 700; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-item-prev {
    display: block;
    font-size: 12px; color: var(--ink-3); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
}
/* Zeit: klein unter dem Text (Meldung) bzw. rechts neben dem Namen (Gespräch). */
.notif-item-when { flex: 0 0 auto; font-family: var(--font-mono); font-size: 10px; color: var(--ink-3); white-space: nowrap; }
.notif-item-kopf { display: flex; align-items: baseline; gap: var(--s-8); min-width: 0; }
.notif-item-kopf .notif-item-name { flex: 1 1 auto; min-width: 0; }
/* Ungelesen: der Text wird kräftig, rechts steht ein Punkt. Keine gefärbte Fläche — sie
   machte aus drei neuen Meldungen eine rosa Wand, in der nichts mehr hervorstach. */
.notif-item.unread .notif-item-text { color: var(--ink); font-weight: 600; }
/* position: Im Punkt steht für Vorlese-Programme „Ungelesen" (.sr-only, absolut) — es braucht hier seinen Anker. */
.notif-neu { position: relative; flex: 0 0 8px; align-self: center; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
/* Angetippt oder mit „Alle gelesen" abgeräumt: Die Zeile verliert .unread, der Punkt geht mit. */
.notif-item:not(.unread) > .notif-neu { display: none; }
.notif-chat.unread .notif-item-prev { color: var(--ink-2); font-weight: 600; }
.notif-item-badge {
    flex-shrink: 0; align-self: center; min-width: 18px; height: 18px; padding: 0 var(--s-6);
    background: var(--accent); color: #fff; font-size: 10px; font-weight: 700;
    border-radius: 999px; display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-mono);
}
/* Abschnitt („Planung", „Nachrichten"): eigene Zeile auf getöntem Grund — so ist auf
   einen Blick klar, wo die Meldungen enden und die Gespräche anfangen. */
.notif-section {
    display: flex; align-items: center; gap: var(--s-6);
    padding: var(--s-8) var(--s-16); background: var(--paper);
    border-bottom: 1px solid var(--line);
    font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--ink-3); font-family: var(--font-mono);
}
.notif-empty {
    display: flex; flex-direction: column; align-items: center; gap: var(--s-8);
    padding: var(--s-32) var(--s-16); text-align: center; color: var(--ink-3); font-size: 13px;
}
.notif-empty .notif-sym { color: var(--ink-4); }
.notif-all {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center; min-height: 44px;
    padding: 0 var(--s-16);
    font-size: 13px; font-weight: 600; color: var(--accent-2); text-decoration: none;
    border-top: 1px solid var(--line);
}
.notif-all:hover { background: var(--paper-2); }
@media (max-width: 600px) {
    /* Am Handy fast fensterbreit. Das Menü hängt dort am KOPF (er klebt oben und ist so
       breit wie das Fenster), nicht mehr an der Glocke: `top: 100%` ist dann seine
       Unterkante — gleich, wie hoch der Kopf im jeweiligen Design ist. Vorher stand es
       `fixed` bei 64 px und verließ sich darauf, dass der Kopf zufällig sein Bezugsrahmen
       ist (ein stehengebliebenes transform bzw. der Weichzeichner). */
    .notif-bell { position: static; }
    .notif-menu { top: calc(100% + var(--s-6)); right: var(--s-8); left: var(--s-8); width: auto; max-width: none; }
}

/* ====== Sub-Tabs (Unter-Navigation in einem Bereich) ====== */
.subtabs {
    display: inline-flex; gap: var(--s-2); padding: var(--s-4); margin: var(--s-4) 0 var(--s-24);
    background: var(--paper-2); border: 1px solid var(--line); border-radius: 999px;
    flex-wrap: wrap;
}
.subtabs a {
    padding: var(--s-8) var(--s-16); border-radius: 999px; font-size: 13px; font-weight: 600;
    color: var(--ink-3); text-decoration: none; transition: all 0.12s;
    display: inline-flex; align-items: center; gap: var(--s-6);
}
.subtabs a:hover { color: var(--ink); background: var(--surface); }
.subtabs a.active { background: var(--ink); color: var(--paper); }
.subtab-badge {
    min-width: 16px; height: 16px; padding: 0 var(--s-4); border-radius: 999px;
    background: var(--accent); color: #fff; font-size: 10px; font-weight: 700;
    font-family: var(--font-mono); display: inline-flex; align-items: center; justify-content: center;
}
@media (max-width: 600px) {
    .subtabs { display: flex; width: 100%; }
    .subtabs a { flex: 1; justify-content: center; padding: var(--s-10) var(--s-8); }
}

/* ============================================================================
   BENACHRICHTIGUNGS-KANÄLE — Auswahl-Karten, Switch, Mini-Chips
   Geteilt von Profil, Einladung (Onboarding) und Versand-Übersicht.
   ============================================================================ */

/* --- Kanal-Auswahlkarten (Profil + Einladung) --- */
.chan-list { display: flex; flex-direction: column; gap: var(--s-12); }

.chan-card {
    display: flex; align-items: center; gap: var(--s-16);
    padding: var(--s-16) var(--s-18);
    background: var(--paper);
    border: 1.5px solid var(--line);
    border-radius: var(--radius-sm);
    transition: border-color 0.25s var(--ease-out), background 0.25s, box-shadow 0.25s, transform 0.25s var(--ease-out);
}
.chan-card:hover { transform: translateY(-1px); box-shadow: var(--shadow); }
/* Aktiver Zustand wird per :has(checkbox:checked) gesetzt — moderne Browser. */
.chan-card.is-on,
.chan-card:has(input[type="checkbox"]:checked) {
    border-color: var(--accent);
    background: var(--accent-paper);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
.chan-card.is-locked { background: linear-gradient(180deg, var(--surface), var(--paper)); border-color: var(--line-2); }
/* Deaktiviert: Kanal technisch (noch) nicht verfügbar — sichtbar, aber nicht wählbar. */
.chan-card.is-disabled { background: var(--paper-2); border-color: var(--line); opacity: 0.7; }
.chan-card.is-disabled:hover { transform: none; box-shadow: none; }
.chan-card.is-disabled .chan-ico { background: var(--paper-2); color: var(--ink-4); }
.chan-card.is-disabled .chan-title { color: var(--ink-2); }
.chan-card .chan-pill.is-soon { background: var(--paper-2); color: var(--ink-3); border: 1px dashed var(--line-2); }

.chan-card .chan-ico {
    flex: 0 0 auto;
    width: 44px; height: 44px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    font-size: 22px; line-height: 1;
    background: var(--surface); border: 1px solid var(--line);
}
.chan-card.is-on .chan-ico,
.chan-card:has(input[type="checkbox"]:checked) .chan-ico { background: #fff; border-color: var(--accent); }

.chan-card .chan-body { flex: 1 1 auto; min-width: 0; }
.chan-card .chan-title {
    /* flex-wrap: Auf schmalen Handys passt „Auf dem Handy" + Fähnchen nicht in
       eine Zeile. Ohne Umbruch quetscht der Flexbox-Algorithmus stattdessen den
       Titel zusammen („In der / App"). Mit Umbruch rutscht das Fähnchen sauber
       in die nächste Zeile und der Titel bleibt lesbar. */
    display: flex; align-items: center; gap: var(--s-8); flex-wrap: wrap;
    font-weight: 700; font-size: 15px; color: var(--ink); letter-spacing: -0.01em;
}
.chan-card .chan-desc { font-size: 12.5px; color: var(--ink-3); margin-top: var(--s-2); line-height: 1.45; }
.chan-card .chan-pill {
    font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em;
    padding: var(--s-2) var(--s-8); border-radius: 999px; background: var(--accent-soft); color: var(--accent-2); font-weight: 700;
}
.chan-card.is-locked .chan-pill { background: var(--paper-2); color: var(--ink-3); }
.chan-card .chan-warn { font-size: 11.5px; color: var(--warning); margin-top: var(--s-6); display: flex; align-items: center; gap: var(--s-6); }

/* --- iOS-Style Switch --- */
.switch { position: relative; flex: 0 0 auto; display: inline-block; width: 48px; height: 28px; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .slider {
    position: absolute; inset: 0; cursor: pointer;
    background: var(--line-2); border-radius: 999px;
    transition: background 0.25s var(--ease-out);
}
.switch .slider::before {
    content: ""; position: absolute; height: 22px; width: 22px; left: 3px; top: 3px;
    background: #fff; border-radius: 50%;
    box-shadow: 0 1px 3px rgba(20,17,12,0.25);
    transition: transform 0.28s var(--ease-spring);
}
.switch input:checked + .slider { background: var(--accent); }
.switch input:checked + .slider::before { transform: translateX(20px); }
.switch input:focus-visible + .slider { box-shadow: 0 0 0 4px var(--accent-soft); }
.switch input:disabled + .slider { opacity: 0.5; cursor: not-allowed; }
.switch.is-locked .slider { background: var(--accent); opacity: 0.65; cursor: default; }
.switch.is-locked .slider::before { transform: translateX(20px); }

/* --- Nummerierter Schritt-Punkt (Onboarding) --- */
.step-dot {
    flex: 0 0 auto;
    width: 26px; height: 26px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--accent); color: #fff;
    font-family: var(--font-mono); font-size: 13px; font-weight: 700;
    box-shadow: 0 2px 6px var(--accent-soft);
}

/* --- Mini-Kanal-Chips (Versand-Tabelle) --- */
.chan-chips { display: inline-flex; gap: var(--s-6); flex-wrap: wrap; align-items: center; }
.chan-chip {
    font-family: var(--font-mono); font-size: 10px; font-weight: 700;
    letter-spacing: 0.04em; padding: var(--s-4) var(--s-8); border-radius: 999px;
    border: 1px solid transparent; white-space: nowrap;
}
.chan-chip.chan-on    { background: #e3f5ea; color: var(--success-2); border-color: #bfe6cd; }
.chan-chip.chan-muted { background: var(--paper-2); color: var(--ink-4); }

@media (max-width: 560px) {
    .chan-card { padding: var(--s-14); gap: var(--s-12); }
    .chan-card .chan-ico { width: 38px; height: 38px; font-size: 19px; }
}

/* ============================================================================
   PLANUNGS-STATUS-CHIPS — einheitliche Statusfarben (Wochenübersicht + Planung)
   Ein Chip pro Status; Farbe = Bedeutung. Punkt links = Statusfarbe.
   ============================================================================ */
.pchip {
    display: inline-flex; align-items: center; gap: var(--s-6);
    padding: var(--s-4) var(--s-10); border-radius: 999px;
    font-size: 11px; font-weight: 700; line-height: 1.3;
    white-space: nowrap; border: 1px solid transparent;
    /* Anker für ein .sr-only darin: ohne positionierten Vorfahren richtet sich
       das absolut positionierte Span am Dokument aus und entkommt dem
       waagerechten Scroll-Rahmen der Wochentabelle — die Seite wurde dadurch
       930px statt 371px breit. */
    position: relative;
}
.pchip::before {
    content: ""; width: 6px; height: 6px; border-radius: 50%;
    background: currentColor; flex: 0 0 auto;
}
/* „Offen" ist der Ausgangszustand — also KEIN Signal. Als vollwertiger Chip war es
   in der Wochenübersicht die häufigste Kachel und übertönte die echten Zustände.
   Jetzt bleibt in der Zelle nur der blasse Punkt; benannt wird er in der Legende
   unter der Tabelle (dort steht der Chip MIT Text — der gap greift nur, wenn
   wirklich Text daneben steht). */
.pchip-open {
    background: transparent; color: var(--ink-4); padding: var(--s-4) 0; font-weight: 500;
}
.pchip-open::before { background: var(--line-2); }
.pchip-available  { background: #d9f1fb;              color: #0b6c8c; }
.pchip-accepted   { background: #def5e6;              color: var(--success-2); }
.pchip-auto       { background: #ece9fb;              color: #5b46c9; }
.pchip-planned    { background: var(--accent-paper);  color: var(--accent-2); }
.pchip-partial    { background: var(--warning-light); color: var(--warning); }
.pchip-conflict   { background: #fdecec;              color: #b91c1c; border-color: #f2b8b8; }
.pchip-rejected   { background: #f1efe8;              color: var(--ink-3); }
.pchip-rejected::before,
.pchip-cancelled::before { opacity: 0.6; }
.pchip-cancelled  { background: #f1efe8;              color: var(--ink-3); text-decoration: line-through; }

/* ============================================================================
   ============================================================================
   PLANUNGS-OBERFLÄCHEN — geteilte Bausteine
   ----------------------------------------------------------------------------
   Alles hier ist EINMAL definiert und wird von planung.php,
   board.php, wochenuebersicht.php und annahmeprojekt.php benutzt. Vorher hatte
   jede Seite ihre eigene Kopie derselben Karten/Chips/Wochen-Navigation — mit
   leicht anderen Abständen, Farben und Bedeutungen. Eine Quelle = eine Optik.
   ============================================================================
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. BREITER CONTAINER
   Das Wochen-Raster ist das breiteste Element der App. Bei 1280px Deckel scrollte
   es auf großen Bildschirmen INNERHALB der Karte, obwohl rechts 200px leer waren.
   .container-wide gibt den Planungs-Seiten die volle Breite (mit Sicherheitsrand).
   --------------------------------------------------------------------------- */
.container-wide { max-width: min(1760px, 100%); }
/* Auf breiten Seiten soll die Kopfzeile genauso breit laufen wie der Inhalt —
   sonst steht die Navigation sichtbar schmaler als das Raster darunter. */
body[data-wide="1"] .app-header-inner { max-width: min(1760px, 100%); }

/* ---------------------------------------------------------------------------
   2. SEITENKOPF — Eyebrow + Titel + Zeitraum/Aktionen
   Ersetzt die per-Seite zusammengebauten Inline-Styles.
   --------------------------------------------------------------------------- */
/* .admin-toolbar ist der ältere Name desselben Bausteins. Beide teilen sich hier
   die Regeln, damit Seiten mit altem Markup automatisch gleich aussehen — statt
   den Seitenkopf an neun Stellen einzeln nachzupflegen. */
.page-head,
.admin-toolbar {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--s-24); flex-wrap: wrap; margin: var(--s-24) 0 var(--s-4);
}
.page-head .ph-main { min-width: 0; }
.page-head h1,
.admin-toolbar h1 { margin: 0; font-size: clamp(26px, 3vw, 38px); line-height: 1.08; letter-spacing: -0.02em; }
.page-head .ph-sub,
.admin-toolbar > div > p { color: var(--ink-3); margin: var(--s-8) 0 0; max-width: 62ch; font-size: 13px; line-height: 1.55; }
.page-head .ph-side { text-align: right; flex-shrink: 0; }
/* Arbeitsansichten (Planung, Kalender, Versand …): Der Seitenkopf ist dort kein
   Aushängeschild, sondern nur noch Orientierung — kleiner Titel, wenig Luft, damit
   das Raster sofort sichtbar ist. Der Zeitraum steht in der Wochen-Navigation. */
.page-head.compact { margin: var(--s-18) 0 0; align-items: center; }
.page-head.compact h1 { font-size: clamp(21px, 2.2vw, 28px); }
.page-head.compact .eyebrow { margin-bottom: var(--s-6); }
/* Der Eyebrow steht direkt über der Überschrift — der globale 24px-Abstand
   riss den Kopf sonst auseinander. */
.page-head .eyebrow,
.admin-toolbar .eyebrow { margin-bottom: var(--s-10); }

/* Zurück-Link über dem Kopf */
.backlink {
    display: inline-flex; align-items: center; gap: var(--s-6);
    font-size: 12px; color: var(--ink-3); text-decoration: none;
    margin-top: var(--s-24); padding: var(--s-4) var(--s-8) var(--s-4) var(--s-4); border-radius: 8px;
}
.backlink:hover { color: var(--accent-2); background: var(--accent-paper); }

/* ---------------------------------------------------------------------------
   3. PROJEKT-UNTERNAVIGATION
   Vorher gab es je Seite nur einen „← Zurück zu …"-Link; wo man im Projekt ist,
   war nicht sichtbar. Jetzt: eine Reiter-Leiste mit dem aktiven Schritt.
   --------------------------------------------------------------------------- */
.subnav {
    display: flex; gap: var(--s-4); flex-wrap: wrap; align-items: center;
    margin: var(--s-14) 0 0; padding: var(--s-4);
    background: var(--paper-2); border: 1px solid var(--line); border-radius: 999px;
    width: fit-content; max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.subnav::-webkit-scrollbar { display: none; }
.subnav a {
    display: inline-flex; align-items: center; gap: var(--s-6);
    padding: var(--s-8) var(--s-14); border-radius: 999px; white-space: nowrap;
    font-size: 12.5px; font-weight: 600; color: var(--ink-3); text-decoration: none;
    transition: background 0.15s, color 0.15s;
}
.subnav a:hover { background: var(--surface); color: var(--ink); }
.subnav a.active { background: var(--ink); color: #fff; }
/* Bewusst ohne Icons: fünf Emoji neben fünf Wörtern sind doppelte Information
   und machen die Leiste unruhig. */

/* ---------------------------------------------------------------------------
   4. WOCHEN-/ZEITRAUM-NAVIGATION
   --------------------------------------------------------------------------- */
.weeknav { display: flex; gap: var(--s-8); align-items: center; flex-wrap: wrap; margin-top: var(--s-14); }
.weeknav .wn-spacer { flex: 1 1 40px; }
.weeknav .wn-group {
    display: inline-flex; align-items: stretch;
    border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
    overflow: hidden;
}
.weeknav .wn-group a, .weeknav .wn-group button {
    padding: var(--s-8) var(--s-14); font-size: 12px; font-weight: 600; color: var(--ink-2);
    text-decoration: none; background: transparent; border: 0; cursor: pointer;
    display: inline-flex; align-items: center;
}
.weeknav .wn-group a + a, .weeknav .wn-group a + button { border-left: 1px solid var(--line); }
.weeknav .wn-group a:hover, .weeknav .wn-group button:hover { background: var(--accent-paper); color: var(--accent-2); }
.weeknav .wn-group a.active { background: var(--ink); color: #fff; }
/* Der angezeigte Zeitraum gehört neben die Blättern-Knöpfe — nicht als eigener
   Block an den rechten Seitenrand. */
.weeknav .wn-label {
    font-family: var(--font-mono); font-size: 12px; color: var(--ink-3);
    white-space: nowrap; letter-spacing: 0.02em;
}
.weeknav .wn-label strong { color: var(--ink); font-weight: 700; }

/* Auswahl „zweites Projekt / Annahme-Pool" */
.second-view-picker { display: inline-flex; align-items: center; gap: var(--s-6); font-size: 12px; color: var(--ink-3); }
.second-view-picker select {
    font-size: 12px; padding: var(--s-6) var(--s-10); border-radius: 999px;
    border: 1px solid var(--line); background: var(--surface); color: var(--ink); max-width: 230px;
}

/* ============================================================================
   5. AUSHILFEN-POOL  —  „wer ist frei, wer ist schon vergeben?"
   ----------------------------------------------------------------------------
   Kernidee: Die 7 Tages-Kästchen einer Karte sind die Hauptinformation. Ihre
   Farbe beantwortet auf einen Blick die Frage, die man beim Verteilen stellt:
       grau   = hat für den Tag gar keine Zeit gemeldet
       grün   = verfügbar UND noch frei
       pink   = in DIESEM Projekt schon eingeplant
       dunkel = in einem ANDEREN Projekt vergeben  (Streifenmuster + 🔒)
   Das Streifenmuster ist bewusst zusätzlich zur Farbe da — Farbe allein reicht
   bei Rot-Grün-Schwäche nicht.
   ============================================================================ */
.pool-panel {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 16px; padding: var(--s-18); box-shadow: var(--shadow-md);
}
.pool-panel > .pool-bar { margin-bottom: var(--s-12); }

.pool-bar { display: flex; align-items: center; gap: var(--s-10) var(--s-14); flex-wrap: wrap; }
.pool-bar h2, .pool-bar h3 {
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em;
    color: var(--ink-3); font-weight: 700; margin: 0;
}
.pool-bar .count { font-family: var(--font-mono); color: var(--ink-4); font-weight: 400; }
.pool-bar .pool-spacer { flex: 1 1 20px; }
.pool-search {
    padding: var(--s-8) var(--s-12); border: 1px solid var(--line); border-radius: 999px;
    background: var(--paper); font-size: 12px; min-width: 190px; color: var(--ink);
}
.pool-search:focus { outline: none; border-color: var(--accent); background: var(--surface); }

/* Segment-Filter: Alle / Nur freie / Nur vergebene */
.pool-filter {
    display: inline-flex; padding: var(--s-4); gap: var(--s-2);
    background: var(--paper-2); border: 1px solid var(--line); border-radius: 999px;
}
.pool-filter button {
    border: 0; background: transparent; cursor: pointer;
    padding: var(--s-6) var(--s-12); border-radius: 999px;
    font-size: 11.5px; font-weight: 700; color: var(--ink-3);
    font-family: inherit; white-space: nowrap;
}
.pool-filter button:hover { color: var(--ink); }
.pool-filter button.active { background: var(--surface); color: var(--ink); box-shadow: var(--shadow); }
.pool-filter button .n { font-family: var(--font-mono); font-weight: 500; opacity: 0.7; margin-left: var(--s-4); }

/* Legende — bewusst klein und blass: sie erklärt einmal und soll danach verschwinden,
   nicht mit den Filtern um Aufmerksamkeit konkurrieren. */
.pool-legend {
    display: flex; align-items: center; gap: var(--s-10); flex-wrap: wrap;
    font-size: 10px; color: var(--ink-4); letter-spacing: 0.01em;
}
.pool-legend i { display: inline-flex; align-items: center; gap: var(--s-4); font-style: normal; }
.pool-legend .sw {
    width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto;
}

/* Karten-Raster */
.pool-grid {
    list-style: none; padding: 0; margin: var(--s-12) 0 0;
    display: grid; grid-template-columns: repeat(auto-fill, minmax(min(232px, 100%), 1fr));
    gap: var(--s-10); align-items: start;
}

/* ---- Personen-Karte ---- */
.pcard {
    position: relative;
    background: var(--paper); border: 1px solid var(--line); border-left: 3px solid var(--line-2);
    border-radius: 12px; padding: var(--s-10) var(--s-12); margin: 0; cursor: grab;
    transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s, opacity 0.18s;
}
.pcard:hover { border-color: var(--accent); border-left-color: var(--accent); transform: translateY(-1px); box-shadow: 0 6px 16px -6px var(--accent-soft); }
.pcard:active { cursor: grabbing; }
.pcard.is-hidden, .pcard.hidden { display: none; }

.pcard-head { display: flex; justify-content: space-between; gap: var(--s-8); align-items: baseline; }
.pcard-name { flex: 1 1 auto; font-weight: 600; font-size: 13px; color: var(--ink); min-width: 0; overflow-wrap: anywhere; }
/* Gesicht vor dem Namen: klein, damit die Karte so dicht bleibt wie vorher. */
.pcard-head .pcard-kreis { width: 24px; height: 24px; font-size: 10px; align-self: center; }
.pcard-hours { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); white-space: nowrap; flex-shrink: 0; }
.pcard-hours.over { color: #b91c1c; font-weight: 700; }

/* Eine ruhige Textzeile statt eines Feldes aus umrandeten Chips: Zeitfenster links,
   Qualifikationen rechts. Rahmen suggerierten vorher Klickbarkeit, die es nie gab. */
.pcard-meta {
    margin-top: var(--s-8); display: flex; align-items: baseline; gap: var(--s-4) var(--s-10); flex-wrap: wrap;
    font-size: 11px; line-height: 1.45; min-width: 0;
}
.pcard-meta .pm-time { font-family: var(--font-mono); color: var(--ink-2); white-space: nowrap; }
.pcard-meta .pm-skills {
    color: var(--ink-4); min-width: 0; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto;
}
.pcard-meta .muted { color: var(--ink-4); font-style: italic; }

/* ---- Die 7 Tages-Kästchen ---- */
.pcard-days { display: flex; gap: var(--s-4); margin-top: var(--s-10); }
.pday {
    flex: 1; min-width: 0; text-align: center; padding: var(--s-6) 0;
    font-family: var(--font-mono); font-size: 10px; font-weight: 700;
    letter-spacing: 0.04em; border-radius: 6px;
    color: var(--ink-4); background: var(--paper-2);
    border: 1px solid transparent;
    position: relative; cursor: default;
}
.pday.is-free  { background: #1f8a4c; color: #fff; }
.pday.is-own   { background: var(--accent); color: #fff; }
.pday.is-other,
.pday.is-mixed {
    color: #fff; background-color: #3a352b;
    background-image: repeating-linear-gradient(
        -45deg,
        rgba(255,255,255,0.20) 0 3px,
        rgba(255,255,255,0)    3px 7px
    );
}
/* „mixed" = hier UND woanders: dunkel mit Akzent-Rand, damit beides ablesbar bleibt */
.pday.is-mixed { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* Vergangene Tage treten zurück — sie sind nicht mehr planbar */
.pday.is-past { opacity: 0.5; }

/* ---- „Schon vergeben"-Zeile: EINE Zeile, kein Kasten ---- */
.pcard-flag {
    margin-top: var(--s-8); display: flex; align-items: baseline; gap: var(--s-6);
    font-size: 10.5px; line-height: 1.4; color: var(--ink-2); min-width: 0;
}
.pcard-flag .fl-projects {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--ink-3);
}

/* Karte einer bereits woanders vergebenen Person: sichtbar zurückgenommen,
   aber NICHT gesperrt — der Planer darf bewusst umverteilen. */
.pcard.is-taken { border-left-color: #3a352b; background: var(--surface); }
.pcard.is-taken .pcard-name { color: var(--ink-2); }
.pcard.is-own   { border-left-color: var(--accent); }
.pcard.is-free  { border-left-color: #1f8a4c; }

/* Auswahl per Tippen (Touch-Modus) */
.pcard.tap-selected {
    background: var(--accent); border-color: var(--accent); border-left-color: var(--accent);
    box-shadow: 0 8px 20px -8px var(--accent-soft);
}
.pcard.tap-selected .pcard-name,
.pcard.tap-selected .pcard-hours { color: #fff; }
.pcard.tap-selected .pcard-meta,
.pcard.tap-selected .pcard-meta .pm-time { color: #fff; }
.pcard.tap-selected .pcard-meta .pm-skills,
.pcard.tap-selected .pcard-meta .muted { color: rgba(255,255,255,0.82); }
.pcard.tap-selected .pcard-flag,
.pcard.tap-selected .pcard-flag .fl-projects { color: #fff; }
/* Das Kürzel im Kreis: getönt auf Akzent war es nicht zu lesen (2,4:1) — weißer Kreis. */
.pcard.tap-selected .pcard-kreis { background: #fff; color: var(--accent-2); }
.pcard.tap-selected .pday { background: rgba(255,255,255,0.20); color: #fff; }
.pcard.tap-selected .pday.is-free { background: #fff; color: #1f8a4c; }
.pcard.tap-selected .pday.is-own  { background: #fff; color: var(--accent); }
.pcard.tap-selected .pday.is-other,
.pcard.tap-selected .pday.is-mixed { background-color: rgba(20,17,12,0.55); }

.pool-empty {
    display: none; text-align: center; color: var(--ink-4);
    font-size: 12px; padding: var(--s-18) var(--s-8);
}
.pool-empty.show { display: block; }

/* Handy: Karten dürfen mehr Platz brauchen, Tages-Kästchen werden Tap-Ziele */
@media (max-width: 768px) {
    .pool-grid { grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); }
    .pcard-meta { font-size: 12px; }
    .pcard-days { gap: var(--s-6); margin-top: var(--s-12); }
    .pday { padding: var(--s-8) 0; font-size: 11px; }
}

/* ---------------------------------------------------------------------------
   6. WERKZEUGLEISTE — Filter, Suche und Sortierung in EINER Zeile
   Vorher standen Reiter, Suchfeld, Leiter-Filter und Aktionsknöpfe als vier
   eigene Blöcke untereinander; die eigentliche Liste rutschte damit unter die
   Bildschirmkante. Alles gehört in eine umbruchfähige Leiste.
   --------------------------------------------------------------------------- */
.toolbar-row {
    display: flex; align-items: center; gap: var(--s-10) var(--s-16); flex-wrap: wrap;
    margin: var(--s-16) 0 var(--s-4);
}
.toolbar-row > form { margin: 0; }
.toolbar-row .leader-filter { margin: 0; }

/* Beim Ziehen schrumpft die Karte auf Name + Tage: eine volle Karte am Cursor
   verdeckt sonst genau die Schicht, auf die man zielt. */
.pcard.sortable-drag .pcard-meta,
.pcard.sortable-drag .pcard-flag,
.pcard.sortable-fallback .pcard-meta,
.pcard.sortable-fallback .pcard-flag { display: none; }
.pcard.sortable-drag,
.pcard.sortable-fallback {
    box-shadow: var(--shadow-lg);
    border-color: var(--accent);
    max-width: 220px;
}

/* ---------------------------------------------------------------------------
   7. EINGEKLAPPTE „HINZUFÜGEN"-BLÖCKE
   Anlege-Formulare standen dauerhaft offen auf Seiten, deren Aufgabe das Anzeigen
   ist. Als aufklappbarer Block belegen sie eine Zeile statt eines halben Bildschirms.
   --------------------------------------------------------------------------- */
.add-block { margin-top: var(--s-16); }
.add-block > summary {
    cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: var(--s-8);
    padding: var(--s-10) var(--s-16); border-radius: 999px;
    border: 1px dashed var(--line-2); background: transparent;
    font-size: 13px; font-weight: 600; color: var(--ink-3);
    transition: border-color .15s, color .15s, background .15s;
}
.add-block > summary::-webkit-details-marker { display: none; }
.add-block > summary:hover { border-color: var(--accent-2); color: var(--accent-2); background: var(--accent-paper); }
.add-block[open] > summary {
    border-style: solid; border-color: var(--line); background: var(--surface); color: var(--ink);
}

/* (Zweitrangige Zeilen-Aktionen erschienen hier beim Überfahren — .row-2nd. Seit der
   Neuordnung trägt jede Zeile EINEN Knopf, der ihre Aktionen im Blatt öffnet: siehe
   ZEILEN-MENÜ am Ende dieser Datei.) */

/* ---------------------------------------------------------------------------
   9. ARCHIV-TABELLE + SEITEN-NAVIGATION
   Erledigte Projekte und Papierkorb sind Nachschlage-Listen. Als Karten mit
   Kennzahl-Kacheln brauchten 25 Einträge ein Dutzend Bildschirme; als Zeilen
   passen sie auf zwei.
   --------------------------------------------------------------------------- */
.archive-table td { padding: var(--s-12) var(--s-16); vertical-align: middle; }
.archive-table th { padding: var(--s-10) var(--s-16); }
.archive-name { color: var(--ink); font-weight: 600; text-decoration: none; }
.archive-name:hover { color: var(--accent-2); text-decoration: underline; }
.archive-sub { font-family: var(--font-mono); font-size: 10px; color: var(--ink-4); margin-top: var(--s-2); }
.archive-mono { font-family: var(--font-mono); font-size: 12px; color: var(--ink-2); white-space: nowrap; }

/* Endgültiges Löschen sieht anders aus als alles andere — es ist die einzige
   Aktion auf dieser Seite, die sich nicht rückgängig machen lässt. */
.btn-destroy { color: #b91c1c; border-color: #f2b8b8; }
.btn-destroy:hover { background: #b91c1c; border-color: #b91c1c; color: #fff; }

/* Auf schmalen Bildschirmen fallen Zeitraum und Umfang weg — Name, Datum und
   Aktionen tragen die Liste. */
@media (max-width: 680px) {
    .col-hide-sm { display: none; }
    .archive-table td, .archive-table th { padding: var(--s-10) var(--s-12); }
}

.year-filter { display: inline-flex; align-items: center; gap: var(--s-6); margin: 0; }
.year-filter label {
    font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.12em; color: var(--ink-3); font-weight: 700;
}
.year-filter select {
    padding: var(--s-8) var(--s-10); border: 1px solid var(--line); border-radius: 999px;
    background: var(--surface); font-size: 12px; color: var(--ink);
}

.pager {
    margin-top: var(--s-24); display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap;
}
.pager a {
    min-width: 34px; height: 34px; padding: 0 var(--s-10);
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--line); border-radius: 10px; background: var(--surface);
    font-family: var(--font-mono); font-size: 12.5px; color: var(--ink-2);
    text-decoration: none; transition: border-color .12s, background .12s, color .12s;
}
.pager a:hover { border-color: var(--accent-2); color: var(--accent-2); background: var(--accent-paper); }
.pager a.active {
    background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 700;
}
.pager a.active:hover { background: var(--ink); color: #fff; }
.pager .pg-step.is-off { opacity: 0.35; pointer-events: none; }
.pager .pg-gap { color: var(--ink-4); padding: 0 var(--s-2); font-family: var(--font-mono); }
.pg-info {
    margin-left: var(--s-10); font-family: var(--font-mono); font-size: 11px; color: var(--ink-4);
    white-space: nowrap;
}

/* ============================================================================
   ============================================================================
   AUSHILFEN-BEREICH + HANDY
   ----------------------------------------------------------------------------
   Die Aushilfen öffnen die App fast ausschließlich auf dem Handy (als PWA).
   Deshalb gilt hier dieselbe Regel wie in der Produktion — nur strenger:
   der Kopf ist Orientierung, nicht Aushängeschild, und jede Wiederholung
   kostet auf 375 px Breite eine halbe Bildschirmhöhe.
   ============================================================================
   ============================================================================ */

/* ============================================================================
   HANDY-DURCHGANG — gilt für BEIDE Bereiche
   ============================================================================ */
@media (max-width: 640px) {
    /* Seitenkopf: Titel kleiner, die Aktionen darunter über die volle Breite
       nebeneinander. Ein rechtsbündiger Knopf neben einer umbrechenden
       Überschrift ergibt auf 375 px eine zerrissene Zeile. */
    .page-head { gap: var(--s-12); margin-top: var(--s-18); }
    .page-head h1, .admin-toolbar h1 { font-size: clamp(23px, 7vw, 30px); }
    .page-head.compact h1 { font-size: clamp(20px, 6vw, 25px); }
    .page-head .ph-side { display: flex; gap: var(--s-8); width: 100%; }
    .page-head .ph-side .btn { flex: 1 1 0; min-width: 0; justify-content: center; }
    .page-head .ph-sub { font-size: 13px; }

    /* Die Reiter scrollen seitlich (gleichartige Elemente, klare Leserichtung).
       Die Zeitraum-Leiste darf dagegen NICHT scrollen: sonst rutscht der
       „Nächste Woche"-Knopf unsichtbar aus dem Bild. Sie bricht um, und der
       Zeitraum bekommt eine eigene Zeile. */
    .subnav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
    .subnav::-webkit-scrollbar { display: none; }
    .weeknav { flex-wrap: wrap; gap: var(--s-8); }
    .weeknav .wn-group { flex-wrap: nowrap; }
    .weeknav .wn-spacer { display: none; }
    .weeknav .wn-label { flex: 1 0 100%; order: 9; font-size: 11px; }
    .weeknav .wn-group a, .weeknav .wn-group button { padding: var(--s-10) var(--s-12); }

    /* Werkzeugleisten brechen um, statt den Inhalt seitlich rauszuschieben. */
    .toolbar-row { gap: var(--s-8) var(--s-10); }
    /* min-height: die Suchleiste ist am Handy ein Tippziel wie jedes andere.
       Ohne sie misst sie 36,5px — unter der 40px-Regel dieser Datei. */
    .toolbar-row .pool-search, .toolbar-row input[type="search"] {
        width: 100%; min-width: 0; min-height: 40px;
    }
    /* Die Filter-Reiter (Aktiv/Erledigt/Alle/Papierkorb) sind zusammen breiter als
       ein Handybildschirm. Ohne eigenen Scroll-Bereich schob die Leiste die GANZE
       Seite seitlich weg — auf jeder Ansicht der Projektliste. */

    /* Alles, was tippbar ist, bekommt eine echte Trefferfläche (44 px Empfehlung). */
    .btn, .pager a, .subnav a, .weeknav .wn-group a { min-height: 40px; }
    /* Die kleinen Symbol-Knöpfe im Planungsraster und in Listen: mit dem Daumen
       liegen 25–30 px zu dicht an den Nachbar-Elementen. */
    .station-del, .shift-del, .assignment-pill .remove-x, .slot-del {
        min-width: 36px; min-height: 36px; font-size: 19px;
    }
    .add-shift-cell { min-height: 36px; }
    /* Das Schicht-Menü und seine Schnellwahl waren die einzigen tippbaren Dinge
       unterhalb dieser Grenze: gemessen 33,5px und 25px. Polsterung ist dafür
       das falsche Werkzeug — eine Stufe mehr ergäbe 35,5 bzw. 27px und verfehlt
       die Regel weiter. Die Höhe gehört hierher, zu den anderen Trefferflächen. */
    .shiftctx-menu button { min-height: 40px; }
    #shiftctx-editor .sc-quick button { min-height: 36px; }
    .btn { padding: var(--s-12) var(--s-16); }
    .btn-sm { padding: var(--s-10) var(--s-14); }

    /* Pool: eine Karte pro Zeile liest sich auf dem Handy besser als zwei halbe. */
    .pool-grid { grid-template-columns: 1fr; }
    .pool-bar { gap: var(--s-8) var(--s-10); }
    .pool-filter { width: 100%; justify-content: space-between; }
    .pool-filter button { flex: 1 1 0; padding: var(--s-12) var(--s-6); min-height: 38px; }
    .pool-legend { font-size: 10px; gap: var(--s-8); }

    /* Seiten-Navigation zentriert und mit größeren Zielen. */
    .pager { justify-content: center; }
    .pager a { min-width: 40px; height: 40px; }
    .pg-info { width: 100%; text-align: center; margin: var(--s-6) 0 0; }

}

/* iOS zoomt beim Fokus in ein Eingabefeld hinein, wenn die Schrift < 16px ist.
   Das reißt das Layout auseinander und lässt sich nur über die Schriftgröße lösen. */
/* Die .field-Varianten MÜSSEN hier mitstehen: `.field input[type="text"]` (0,2,1,
   weiter oben, 14px) schlug die nackte Typ-Regel (0,1,1) — und damit galt die
   16px-Regel ausgerechnet in keinem Formular, auch nicht beim Anmelden. Gleiche
   Spezifität, spätere Stelle gewinnt. */
@media (max-width: 820px) {
    input[type="text"], input[type="search"], input[type="password"], input[type="email"],
    input[type="number"], input[type="tel"], input[type="date"], input[type="time"],
    input[type="datetime-local"], input[type="url"], select, textarea,
    .field input[type="text"], .field input[type="search"], .field input[type="password"],
    .field input[type="email"], .field input[type="number"], .field input[type="tel"],
    .field input[type="date"], .field input[type="time"], .field input[type="datetime-local"],
    .field input[type="url"], .field select, .field textarea { font-size: 16px; }
}

/* Die schwebenden Knöpfe (KI-Assistent rechts, Feedback links) liegen fest über der
   Seite. Auf dem Handy verdecken sie sonst genau die letzte Zeile der Liste —
   und damit oft eine Schaltfläche. Deshalb unten Platz freihalten. */
@media (max-width: 640px) {
    main { padding-bottom: 92px; }
}

/* --- Planungs-Raster auf dem Handy ------------------------------------------
   Das Wochenraster bleibt breit und scrollt seitlich — das ist bei sieben Tagen
   unvermeidlich. Was sich beheben lässt: die Stationsspalte fraß die halbe
   Bildschirmbreite, und die Auswahl „Zweites Projekt" brach in drei Zeilen um. */
@media (max-width: 640px) {
    /* Die Beschriftung bleibt — ein Feld, in dem nur „keins" steht, sagt nicht, wovon. */
    .second-view-picker { flex-wrap: wrap; }
    .second-view-picker select { max-width: 170px; }

    /* Das Raster selbst: Abschnitt PLANUNGSRASTER am Ende der Datei. */
}

/* Tabellen mit vielen Spalten brauchen einen eigenen Scroll-Rahmen: .data-table
   selbst hat overflow:hidden (runde Ecken), würde also auf schmalen Bildschirmen
   einfach abschneiden — inklusive der Aktions-Schaltflächen ganz rechts. */
.table-scroll {
    margin-top: var(--s-18); overflow-x: auto; -webkit-overflow-scrolling: touch;
    border-radius: var(--radius);
}
.table-scroll > .data-table { margin-top: 0; min-width: 100%; }
@media (max-width: 640px) {
    .table-scroll > .data-table { min-width: 520px; }
}

/* --- Verfügbarkeit: Trefferflächen ------------------------------------------
   Die Aushilfen bedienen diese Seite fast nur mit dem Daumen. */
.slot-del {
    background: none; border: 0; cursor: pointer; color: var(--ink-3);
    font-size: 20px; line-height: 1; border-radius: 8px;
    min-width: 40px; min-height: 40px;
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 auto;
}
.slot-del:hover, .slot-del:focus-visible { color: var(--accent-2); background: var(--accent-paper); }

.avail-mode-btn {
    border: 0; cursor: pointer; border-radius: 999px;
    font-family: var(--font-mono); font-size: 11px;
    text-transform: uppercase; letter-spacing: 0.08em;
    padding: var(--s-12) var(--s-18); min-height: 40px;
}

/* ============================================================================
   DAS MENÜ — die Orte der App
   ----------------------------------------------------------------------------
   Vier Orte (Übersicht, Woche, Projekte, Aushilfen), dazu Einstellungen für den
   Admin. Breite Fenster: Leiste links. Schmale Fenster: Leiste unten, mit dem
   Daumen erreichbar. Nachrichten, Glocke und Konto sitzen in der Kopfzeile.
   Quelle der Einträge: includes/_hub.php.
   ============================================================================ */

/* Höhe der Leiste unten. Alles, was am unteren Rand klebt (Meldungen, schwebende
   Knöpfe), rechnet sie mit ein — sonst läge es auf dem Menü. Breite Fenster: 0. */
:root { --leiste-unten: 0px; }

.app-shell {
    display: flex; align-items: flex-start; gap: 0;
    max-width: 100%;
}
.app-content { flex: 1 1 auto; min-width: 0; }

/* --- Leiste links ---------------------------------------------------------- */
.sidenav {
    flex: 0 0 208px; width: 208px; align-self: stretch;
    border-right: 1px solid var(--line); background: var(--paper);
    /* Spalte, damit die Leiste darin die Höhe des Rahmens ausfüllen kann (siehe unten). */
    display: flex; flex-direction: column;
}
/* Höchstens fensterhoch (dann rollt sie in sich und bleibt stehen), auf kurzen Seiten so
   hoch wie der Rahmen. Mit fester Höhe (100vh − 110px) war JEDE Seite 140 px höher als
   das Fenster — der Fuß lag auch auf einer leeren Seite unter dem Rand. */
.sidenav-inner {
    position: sticky; top: 96px;
    flex: 1 1 auto; max-height: calc(100vh - 110px); overflow-y: auto;
    padding: var(--s-18) var(--s-14) var(--s-18) var(--s-18);
    display: flex; flex-direction: column; gap: var(--s-4);
}

.hub-tile {
    display: flex; align-items: center; gap: var(--s-12); min-width: 0;
    text-decoration: none; color: var(--ink-2);
    transition: border-color .14s, background .14s, color .14s;
}
/* Strichsymbole: feste Größe, Farbe kommt vom Text. */
.hub-ico { flex: 0 0 auto; width: 20px; height: 20px; display: inline-flex;
           align-items: center; justify-content: center; color: inherit; }
.hub-ico svg { width: 20px; height: 20px; display: block; }
.hub-label { display: block; font-size: 14px; font-weight: 600; color: inherit; line-height: 1.25; }

.hub-list { display: flex; flex-direction: column; gap: var(--s-2); }
.hub-list .hub-tile {
    min-height: 44px; padding: var(--s-10) var(--s-12);
    border: 1px solid transparent; border-radius: 12px; background: transparent;
}
.hub-list .hub-tile:hover { background: var(--surface); border-color: var(--line); color: var(--ink); }
.hub-list .hub-tile.active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
/* Einstellungen: abgesetzt am Fuß — kein Ort des Alltags. */
.hub-fuss { margin-top: auto; padding-top: var(--s-10); border-top: 1px solid var(--line); }

/* --- Leiste unten (schmale Fenster) ---------------------------------------- */
.unten-leiste { display: none; }

@media (max-width: 1080px) {
    /* 50 Tippfläche + 2 x 6 Polster + 1 Linie */
    :root { --leiste-unten: calc(63px + env(safe-area-inset-bottom, 0px)); }
    .sidenav { display: none; }
    .unten-leiste {
        display: flex; gap: var(--s-2);
        /* z-index unter allen Dialogen und Blättern der App (ab 49): Ein geöffnetes
           Fenster liegt über dem Menü, nicht darunter. Über Kopfzeile (30) und Pool (6). */
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
        padding: var(--s-6) var(--s-6) calc(var(--s-6) + env(safe-area-inset-bottom, 0px));
        background: var(--surface); border-top: 1px solid var(--line);
    }
    .unten-leiste .hub-tile {
        flex: 1 1 0; flex-direction: column; justify-content: center; gap: var(--s-2);
        min-height: 50px; padding: var(--s-4) var(--s-2); border-radius: 12px;
        color: var(--ink-3);
    }
    .unten-leiste .hub-label {
        font-size: 11px; max-width: 100%;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .unten-leiste .hub-tile.active { background: var(--paper-2); color: var(--ink); }
    /* Platz für die Leiste: Das Letzte auf der Seite ist der Fuß (er steht NACH .app-content).
       Der Platz gehört deshalb an ihn — am Inhalt ließ er nur eine Lücke davor, und
       Impressum/Datenschutz lagen unter der Leiste. */
    .app-footer { padding-bottom: calc(var(--s-32) + var(--leiste-unten)); }
}
/* Das Konto-Menü endet ÜBER der Leiste unten und rollt in sich: Am kleinen Handy
   (375 x 667) lag „Abmelden" sonst hinter ihr. 76px = Kopfzeile samt Abstand.
   Gilt in jeder Breite (--leiste-unten ist am Schreibtisch 0): In einem niedrigen
   Fenster (Laptop, geteilter Bildschirm) reichte das Menü sonst unter den Fensterrand,
   und „Abmelden" war nicht zu erreichen. */
.lang-menu.konto-menu {
    max-height: calc(100vh - 76px - var(--leiste-unten) - var(--s-12));
    max-height: calc(100dvh - 76px - var(--leiste-unten) - var(--s-12));
    overflow-y: auto; overscroll-behavior: contain;
}
/* Eingebettet im Backoffice-Fenster und beim Drucken gibt es kein Menü. */
@media print { .unten-leiste, .sidenav { display: none !important; } }

/* --- Kopfzeile: Einstellungen, Nachrichten, Konto --------------------------- */
.kopf-rund {
    position: relative; flex: 0 0 40px; width: 40px; height: 40px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--line); background: var(--paper-2); color: var(--ink-2);
    text-decoration: none; transition: background .14s, border-color .14s, color .14s;
}
.kopf-rund:hover { background: var(--surface); border-color: var(--ink-4); color: var(--ink); }
.kopf-rund.is-aktiv { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.kopf-ico { display: inline-flex; width: 18px; height: 18px; }
.kopf-ico svg { width: 18px; height: 18px; display: block; }
/* In breiten Fenstern stehen die Einstellungen in der Leiste links. */
.kopf-einst { display: none; }
@media (max-width: 1080px) { .kopf-einst { display: inline-flex; } }
/* Am Handy trägt die Kopfzeile nur Logo und Symbole — in EINER Zeile. Weiter oben
   steht dafür schon „.brand-text { display: none }", die Regel verliert aber gegen
   „.app-logo .brand-text { display: flex }" (zwei Klassen, später im Stylesheet):
   Der Schriftzug blieb stehen und schob die Symbole in eine zweite Zeile. */
@media (max-width: 640px) {
    .app-logo .brand-text { display: none; }
    .app-header-inner { flex-wrap: nowrap; }
}

.hub-badge {
    display: inline-block; margin-left: var(--s-8); min-width: 18px; padding: 1px var(--s-6);
    border-radius: 999px; background: var(--accent-2); color: #fff; text-align: center;
    font-family: var(--font-mono); font-size: 10px; font-weight: 700; line-height: 1.5;
    vertical-align: 1px;
}
.kopf-rund .kopf-zaehler { position: absolute; top: -4px; right: -6px; margin-left: 0; }

/* Der Konto-Knopf erbt die Maße des früheren Sprach-Umschalters (.lang-trigger,
   in _header.php) — deshalb zwei Klassen im Selektor: Er muss dessen Regeln schlagen. */
.lang-trigger.konto-trigger {
    width: 40px; padding: 0; justify-content: center;
    background: var(--ink); border-color: var(--ink); color: var(--paper);
    font-family: var(--font-sans); font-size: 12px; font-weight: 700; letter-spacing: 0.02em;
}
.lang-trigger.konto-trigger:hover { background: var(--ink-2); border-color: var(--ink-2); }
.lang-menu.konto-menu { min-width: 224px; }
.konto-menu a { min-height: 40px; }
.konto-name {
    font-family: var(--font-mono); font-size: 11px; color: var(--ink-3);
    padding: var(--s-8) var(--s-12) var(--s-6);
}
.konto-titel {
    font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--ink-3); padding: var(--s-10) var(--s-12) var(--s-4);
    border-top: 1px solid var(--line); margin-top: var(--s-6);
}
.konto-trenner { border-top: 1px solid var(--line); margin: var(--s-6) 0; }
.konto-ico { display: inline-flex; width: 18px; height: 18px; color: var(--ink-3); }
.konto-ico svg { width: 18px; height: 18px; display: block; }
/* Zwei Klassen: schlägt .hub-feedback aus dem Rückmelde-Fenster (padding: 0; display: inline). */
.konto-menu .konto-knopf {
    display: flex; align-items: center; width: 100%; min-height: 40px;
    padding: var(--s-8) var(--s-12); border-radius: 8px;
    font-size: 13px; font-weight: 500; color: var(--ink);
}
.konto-menu .konto-knopf:hover { background: var(--paper-2); }

/* ============================================================================
   PERSONENSEITE EINER AUSHILFE
   Kopfzeile mit den harten Fakten, danach Kennzahlen und zwei Spalten:
   was ansteht und was gemeldet wurde.
   ============================================================================ */
.person-meta {
    display: flex; align-items: center; gap: var(--s-6) var(--s-14); flex-wrap: wrap;
    margin-top: var(--s-14); font-size: 12px; color: var(--ink-3);
}
.person-meta .pm-item { font-family: var(--font-mono); }
.person-meta .pm-skill {
    font-size: 10.5px; padding: var(--s-2) var(--s-10); border-radius: 999px;
    background: var(--paper-2); border: 1px solid var(--line); color: var(--ink-2);
}
.person-meta .pm-spacer { flex: 1 1 10px; }
/* Überall, nicht nur in .person-meta: Der Verweis „Können bewerten" steht daneben
   und kam sonst im Blau des Browsers. */
.pm-link { color: var(--accent-2); font-weight: 600; text-decoration: none; }
.pm-link:hover { text-decoration: underline; }

.person-note {
    margin: var(--s-12) 0 0; padding: var(--s-10) var(--s-14); border-radius: 10px;
    background: rgba(37,99,235,0.06); border: 1px solid rgba(37,99,235,0.18);
    font-size: 13px; color: var(--ink-2); max-width: 70ch;
}

.person-cols {
    margin-top: var(--s-24); display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--s-24) var(--s-32);
}
.person-h2, .pu-h2 {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-12);
    margin: 0 0 var(--s-10); font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em;
    color: var(--ink-3); font-weight: 700;
}
.person-h2-link { font-size: 11px; letter-spacing: 0; text-transform: none; color: var(--accent-2); text-decoration: none; font-weight: 600; }
.person-h2-link:hover { text-decoration: underline; }
.person-empty { font-size: 13px; color: var(--ink-4); margin: 0; }

.person-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.person-list li {
    display: flex; align-items: baseline; gap: var(--s-10); flex-wrap: wrap;
    padding: var(--s-10) var(--s-12); border-radius: 10px; background: var(--surface);
    border: 1px solid var(--line); font-size: 13px;
}
.person-list .pl-date { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); flex: 0 0 auto; min-width: 62px; }
.person-list .pl-time { font-family: var(--font-mono); font-size: 12px; color: var(--ink); font-weight: 600; flex: 0 0 auto; }
.person-list .pl-main { color: var(--ink-2); text-decoration: none; min-width: 0; flex: 1 1 auto; }
.person-list .pl-main:hover { color: var(--accent-2); }
.person-list .pl-station { color: var(--ink-4); }
.person-list .pl-note { font-size: 11px; color: #2563eb; }

@media (max-width: 640px) {
    .person-cols { margin-top: var(--s-18); gap: var(--s-18); }
    .person-meta { font-size: 11.5px; gap: var(--s-6) var(--s-10); }
}

/* ---------------------------------------------------------------------------
   AUSHILFEN-AUSWAHL MIT SUCHE
   Ersetzt ein Auswahlfeld mit 50 Einträgen. Tippen filtert, Enter springt zum
   ersten Treffer.
   --------------------------------------------------------------------------- */
.ppicker { margin-top: var(--s-14); max-width: 560px; }
.ppicker-label {
    display: block; font-family: var(--font-mono); font-size: 10px;
    text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-3);
    font-weight: 700; margin-bottom: var(--s-6);
}
.ppicker-search {
    width: 100%; box-sizing: border-box; padding: var(--s-10) var(--s-14);
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--surface); font: inherit; font-size: 14px; color: var(--ink);
}
.ppicker-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ppicker-list {
    list-style: none; margin: var(--s-8) 0 0; padding: var(--s-4);
    display: flex; flex-wrap: wrap; gap: var(--s-4);
    max-height: 168px; overflow-y: auto;
    border: 1px solid var(--line); border-radius: 14px; background: var(--paper);
}
.ppicker-item {
    display: inline-block; padding: var(--s-8) var(--s-14); border-radius: 999px;
    background: var(--surface); border: 1px solid var(--line);
    font-size: 13px; color: var(--ink-2); text-decoration: none; white-space: nowrap;
}
.ppicker-item:hover { border-color: var(--accent); color: var(--accent-2); background: var(--accent-paper); }
.ppicker-item.active { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }
.ppicker-empty { display: none; margin: var(--s-8) var(--s-2) 0; font-size: 12px; color: var(--ink-4); }
@media (max-width: 640px) {
    .ppicker-list { max-height: 200px; }
    .ppicker-item { padding: var(--s-10) var(--s-14); }
}

.filter-chip {
    display: inline-flex; align-items: center; gap: var(--s-8); min-height: 40px;
    padding: var(--s-8) var(--s-12) var(--s-8) var(--s-14); border-radius: 999px;
    border: 1px solid var(--ink); background: var(--ink); color: #fff;
    font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.filter-chip span { opacity: 0.6; font-size: 16px; line-height: 1; }
.filter-chip:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.filter-chip:hover span { opacity: 1; }

/* Zwei Wege, eine Aushilfe anzulegen — beide von Anfang an sichtbar. */
.newway { margin-top: var(--s-16); display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: var(--s-10); max-width: 720px; }
.newway-item {
    display: block; padding: var(--s-14) var(--s-16); border-radius: 14px; text-decoration: none;
    border: 1px solid var(--line); background: var(--paper); color: var(--ink-2);
}
.newway-item strong { display: block; font-size: 13.5px; color: var(--ink); }
.newway-item span { display: block; font-size: 12px; color: var(--ink-3); margin-top: var(--s-4); line-height: 1.45; }
.newway-item.active { border-color: var(--ink); background: var(--surface); }
a.newway-item:hover { border-color: var(--accent); background: var(--accent-paper); }

/* ============================================================================
   KORREKTUR: Ankreuzfelder in Formularfeldern
   ----------------------------------------------------------------------------
   Größe und Farbe der Ankreuzfelder — und die Rücknahme der Breiten-Falle.
   style.css setzt `.field input { width: 100% }` OHNE Typ-Einschränkung (das muss
   dort so bleiben, sonst überholt es die Kollin-Feldoptik, siehe Kommentar dort).
   Hier steht die typgenaue Gegenregel: `.field input[type="checkbox"]` hat mit
   (0,2,1) die höhere Spezifität und gewinnt. Ohne sie wären Checkboxen 98px breit
   und schöben die Beschriftung aus ihrer Karte.
   ============================================================================ */
/* Alle Ankreuzfelder in der Hausfarbe — sonst standen die Systemblauen z.B. in
   der Versand-Tabelle mitten im warmen Papier. */
input[type="checkbox"], input[type="radio"] { accent-color: var(--accent); }

.field input[type="checkbox"],
.field input[type="radio"],
.check-cards input[type="checkbox"],
.check-cards input[type="radio"],
.radio-group input[type="checkbox"],
.radio-group input[type="radio"] {
    width: 17px; height: 17px; min-width: 17px; flex: 0 0 auto;
    padding: 0; margin: 0;
    border: 0; border-radius: 0; background: none; box-shadow: none;
    accent-color: var(--accent);
    cursor: pointer;
}
/* Auf der angekreuzten (magentafarbenen) Karte braucht das Häkchen einen hellen
   Kontrast — sonst steht Akzentfarbe auf Akzentfarbe. */
.check-cards label:has(input:checked) input[type="checkbox"],
.check-cards label:has(input:checked) input[type="radio"],
.radio-group label:has(input:checked) input[type="checkbox"],
.radio-group label:has(input:checked) input[type="radio"] { accent-color: #fff; }

/* Beschriftung darf umbrechen, ohne die Karte zu sprengen. */
.check-cards label { align-items: flex-start; }
.check-cards label > span { min-width: 0; overflow-wrap: anywhere; line-height: 1.35; }
.radio-group label > span { white-space: nowrap; }
/* Schmal: Ein langer Text („Einladungs-Mail mit Setup-Link (7 Tage gültig)") ragte aus
   der Karte. Die Pille darf nicht breiter werden als ihr Behälter, ihr Text bricht um. */
@media (max-width: 640px) {
    .radio-group label { max-width: 100%; border-radius: 20px; }
    .radio-group label > span { white-space: normal; min-width: 0; }
}

/* ============================================================================
   TAGES-BLOCK (Annahmeprojekt)
   Vorher: graue Kästen mit Inline-Styles, ein wuchtiges Auswahlfeld je Zeile.
   Jetzt: ruhige Zeilen, Name und Zeit links, Zuordnung rechts.
   ============================================================================ */
.day-block {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 16px; padding: var(--s-16) var(--s-18); box-shadow: var(--shadow);
}
.day-block.is-today { border-color: var(--accent); }
.day-block-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s-12); margin-bottom: var(--s-12);
}
.day-block-head h3 {
    margin: 0; font-size: 15px; font-weight: 700; color: var(--ink);
    text-transform: none; letter-spacing: -0.01em;
}
.day-block-count {
    font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
    letter-spacing: 0.1em; color: var(--ink-4);
}

.annahme-list { display: flex; flex-direction: column; gap: 1px; }
.annahme-row {
    display: flex; align-items: center; gap: var(--s-12); flex-wrap: wrap;
    padding: var(--s-10); border-radius: 10px;
    transition: background 0.14s;
}
.annahme-row:hover { background: var(--paper); }
.annahme-row + .annahme-row { border-top: 1px solid var(--line); }
.ar-who { flex: 1 1 190px; min-width: 0; display: flex; align-items: baseline; gap: var(--s-10); flex-wrap: wrap; }
.ar-name { font-weight: 600; font-size: 14px; color: var(--ink); text-decoration: none; }
.ar-name:hover { color: var(--accent-2); text-decoration: underline; }
.ar-time { font-family: var(--font-mono); font-size: 11.5px; color: var(--ink-3); }
.ar-notime { color: var(--ink-4); font-style: italic; }
.ar-empty { font-size: 12px; color: var(--ink-4); }
.annahme-row .annahme-shift {
    flex: 1 1 230px; min-width: 0; padding: var(--s-10) var(--s-12);
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--paper); font-size: 12.5px; color: var(--ink);
}
.annahme-row .annahme-shift:focus { outline: none; border-color: var(--accent); background: var(--surface); }
/* Der „Einplanen"-Knopf tritt zurück, bis eine Schicht gewählt ist — sonst
   dominieren bei 20 Zeilen 20 pinke Knöpfe den Bildschirm. */
.annahme-row .annahme-assign { opacity: 0.45; transition: opacity 0.15s; }
.annahme-row:hover .annahme-assign,
.annahme-row:focus-within .annahme-assign { opacity: 1; }

@media (max-width: 640px) {
    .day-block { padding: var(--s-14); }
    .annahme-row { gap: var(--s-8); }
    /* Gemessen 38px: das Menue war das einzige Bedienelement der Zeile unter der
       40px-Grenze — der „Einplanen"-Knopf daneben misst 40px. */
    .annahme-row .annahme-shift { flex-basis: 100%; min-height: 40px; }
    .annahme-row .annahme-assign { opacity: 1; }
}
/* Schmales Handy: Name, Auswahl und Knopf untereinander. Die Breiten-Vorgabe von .ar-who
   (flex-basis 190px) würde in der Spalte zur HÖHE — in jeder Karte klaffte ein 190 px
   hohes Loch zwischen Name und Auswahl. */
@media (max-width: 560px) {
    .annahme-row { flex-direction: column; align-items: stretch; }
    .annahme-row .ar-who, .annahme-row .annahme-shift { flex: 0 0 auto; }
    .annahme-row .annahme-shift { min-width: 0; width: 100%; }
    .annahme-row .annahme-assign { width: 100%; }
}

/* ============================================================================
   ============================================================================
   BEWEGUNG
   ----------------------------------------------------------------------------
   Regel für dieses Projekt: Animation zeigt, WAS PASSIERT IST — sie schmückt nicht.
   Jede Bewegung ist kurz (<= 380 ms) und läuft genau einmal. Der globale
   prefers-reduced-motion-Block weiter oben schaltet alles hier ab.
   ============================================================================
   ============================================================================ */

/* --- 1. Gestaffeltes Erscheinen --------------------------------------------
   Karten in einem Raster erscheinen nacheinander statt alle auf einmal. Das
   führt das Auge von links oben nach rechts unten. Der Index kommt aus dem JS
   (--i), gedeckelt, damit späte Karten nicht spürbar warten. */
/* Nur der ANFANG steht im Keyframe („backwards" hält ihn während der Wartezeit).
   Früher war die Karte von Haus aus unsichtbar und wurde erst durch die Animation
   sichtbar — lief die nicht (Tab im Hintergrund, Druck), blieb der Pool leer. */
.stagger > * {
    animation: stagger-in .34s var(--ease-out) backwards;
    animation-delay: calc(var(--i, 0) * 28ms);
}
@keyframes stagger-in { from { opacity: 0; transform: translateY(8px); } }

/* --- 2. Neu eingetragene Person in einer Schicht ---------------------------
   Die Pille springt kurz auf und blitzt im Akzent — man sieht, WO die Person
   gelandet ist, ohne suchen zu müssen. */
.assignment-pill.just-added,
.pill.just-added {
    animation: pill-in .42s var(--ease-spring) both;
}
@keyframes pill-in {
    0%   { opacity: 0; transform: scale(.7); box-shadow: 0 0 0 0 var(--accent-soft); }
    55%  { opacity: 1; transform: scale(1.06); box-shadow: 0 0 0 7px var(--accent-soft); }
    100% { opacity: 1; transform: scale(1);   box-shadow: 0 0 0 0 rgba(0,0,0,0); }
}

/* Entfernen: kurz zusammenfallen statt hart verschwinden. */
.assignment-pill.just-removed,
.pill.just-removed {
    animation: pill-out .2s var(--ease-out) forwards;
    pointer-events: none;
}
@keyframes pill-out { to { opacity: 0; transform: scale(.8); } }

/* --- 3. Zeile hebt sich beim Überfahren ------------------------------------ */
.data-table tbody tr { transition: background .14s, box-shadow .14s; }
.data-table tbody tr:hover { background: var(--paper); }

/* --- 4. Aktiver Punkt in der Seitenleiste ----------------------------------
   Ein schmaler Balken wächst am linken Rand — zeigt beim Seitenwechsel, wohin
   man gesprungen ist. */
.hub-list .hub-tile { position: relative; }
.hub-list .hub-tile.active::before {
    content: ""; position: absolute; left: -6px; top: 8px; bottom: 8px; width: 3px;
    border-radius: 3px; background: var(--accent);
    animation: rail-grow .3s var(--ease-out) both;
}
@keyframes rail-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* --- 5. Zahlen zählen hoch -------------------------------------------------
   Nur eine Übergangs-Kaschierung; die Zählung selbst macht kollin.js. */
.stat-val.counting { font-variant-numeric: tabular-nums; }

/* --- 6. Aufklappen (details) ----------------------------------------------- */
.add-block[open] > *:not(summary){
    animation: fold-down .24s var(--ease-out) both;
}
@keyframes fold-down { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* --- 7. Tages-Kästchen im Pool: sanfter Farbwechsel beim Überfahren -------- */
.pday { transition: transform .12s var(--ease-out); }
.pcard:hover .pday { transform: translateY(-1px); }

/* --- 8. Seitenwechsel: Inhalt fährt einmal kurz ein ------------------------ */
/* „backwards", nicht „both": Mit „both" bleibt nach der Animation transform:
   matrix(1,0,0,1,0,0) stehen — unsichtbar, aber jedes position:fixed-Element in
   <main> (Schicht-Kontextmenü, Einsatz-Menü, Toasts, Sammelleiste) rechnet dann
   ab <main> statt ab dem Fenster und landet um Seitenleiste + Kopf versetzt. */
.app-content > main { animation: page-in .26s var(--ease-out) backwards; }
@keyframes page-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* --- 9. Von Seite zu Seite: überblenden statt umschalten --------------------
   Der Browser blendet beim Wechsel der Seite die alte in die neue über (View
   Transitions). Kopfzeile, Menü und die Leiste unten tragen einen Namen — sie
   bleiben dabei stehen, nur der Inhalt wechselt. Wer das nicht kann, schaltet um
   wie bisher. Nur ohne „Bewegung reduzieren". */
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
}
::view-transition-old(root), ::view-transition-new(root) { animation-duration: 0.18s; }
.app-header   { view-transition-name: kopf; }
.sidenav      { view-transition-name: menue; }
.unten-leiste { view-transition-name: leiste; }

/* --- 10. Blatt und Meldung erscheinen ---------------------------------------
   Das Blatt kommt von dort, wo es hingehört: am Schreibtisch von rechts, am Handy
   von unten. Nur „from": Nach dem Einfahren bleibt kein transform stehen (siehe
   Punkt 8 — ein stehengebliebenes transform verschiebt alles, was fest sitzt). */
.blatt:not([hidden])        { animation: blatt-rein .22s var(--ease-out); }
.blatt-hinter:not([hidden]) { animation: hinter-rein .18s ease-out; }
.kmeldung:not([hidden])     { animation: meldung-rein .24s var(--ease-out); }
@keyframes blatt-rein   { from { opacity: 0; transform: translateX(32px); } }
@keyframes blatt-hoch   { from { opacity: 0; transform: translateY(48px); } }
@keyframes hinter-rein  { from { opacity: 0; } }
@keyframes meldung-rein { from { opacity: 0; transform: translateX(-50%) translateY(14px); } }
@media (max-width: 640px) { .blatt:not([hidden]) { animation-name: blatt-hoch; } }

/* --- 11. Druckgefühl ---------------------------------------------------------
   Was man antippt, gibt kurz nach. Kein Hüpfen, kein Nachschwingen — nur die
   Rückmeldung „getroffen". */
.btn:active, .pk-neu:active, .blatt-rund:active, .hub-schalter button:active,
a.hubk-zeile:active, .ziel:active:not(:disabled), .unten-leiste a:active { transform: scale(0.97); }

/* --- 12. Start: Kacheln erscheinen, Säulen wachsen, Balken ziehen auf -------
   Die Startseite ist der Einstieg — hier darf sich etwas bewegen. Reihenfolge über
   --i (im Markup gesetzt). „backwards" statt „both": Danach gilt wieder der eigene
   Stil der Kachel, sonst höbe sie sich beim Überfahren nicht mehr. */
.hub[data-ansicht="kacheln"] .hubk { animation: hub-auf .34s var(--ease-out) backwards; animation-delay: calc(var(--i, 0) * 45ms); }
.hubw-saeule i   { transform-origin: bottom; animation: hub-wachsen .5s var(--ease-out) backwards; animation-delay: calc(160ms + var(--i, 0) * 40ms); }
.hubkal-balken   { transform-origin: left;   animation: hub-ziehen .45s var(--ease-out) backwards;  animation-delay: calc(220ms + var(--i, 0) * 50ms); }
@keyframes hub-auf     { from { opacity: 0; transform: translateY(10px); } }
@keyframes hub-wachsen { from { transform: scaleY(0); } }
@keyframes hub-ziehen  { from { transform: scaleX(0); } }
/* Was brennt, pulst — und nur das. */
.hubk .ist-rot > .hubk-punkt { animation: kollin-pulse 2.2s ease-in-out infinite; }

/* --- 13. Listen, die nachgeladen werden --------------------------------------
   Solange die Ziele kommen, stehen Platzhalter in ihrer Form da; die Zeilen
   erscheinen dann, statt aufzuspringen. */
.ziel-skelett {
    height: 64px; border-radius: 14px;
    background: linear-gradient(90deg, var(--paper-2) 25%, var(--paper) 50%, var(--paper-2) 75%);
    background-size: 200% 100%; animation: skelett 1.1s linear infinite;
}
@keyframes skelett { to { background-position: -200% 0; } }
.ziele > .ziel { animation: hub-auf .2s var(--ease-out) backwards; }

/* --- 14. Die Woche der Aushilfe: der nächste Einsatz zuerst, dann die Tage --- */
.mw-naechster { animation: hub-auf .34s var(--ease-out) backwards; }
.mw-tag       { animation: hub-auf .3s var(--ease-out) backwards; animation-delay: 90ms; }

/* ==========================================================================
   Handy-Mitteilungen — Karte im Profil (ergänzt .chan-card)
   ========================================================================== */

/* Bestätigung statt Warnung: gleiche Position, andere Farbe. */
.chan-warn.is-ok { color: #15803d; }

/* Kleines „aktiv"-Fähnchen neben dem Titel. */
.chan-pill.is-on {
    background: #dcfce7;
    color: #15803d;
    border-color: #86efac;
}

/* Gerät kann kein Push (z.B. iPhone im Safari-Tab): Karte bleibt sichtbar,
   erklärt aber warum, statt einen toten Schalter anzubieten. */
.chan-card.is-disabled { opacity: 0.62; }
.chan-card.is-disabled .switch { pointer-events: none; }

/* „Testmitteilung senden" — bewusst als Textlink, nicht als weiterer Button:
   die Karte soll nicht nach zwei gleichwertigen Aktionen aussehen. */
.push-test {
    margin-top: var(--s-8);
    padding: 0;
    text-align: left;   /* Buttons zentrieren ihren Text von Haus aus */
    background: none;
    border: 0;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--accent);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.push-test:hover:not(:disabled) { color: var(--accent-2); }
.push-test:disabled { opacity: 0.5; cursor: default; }

/* Auf dem Handy hat der Hinweistext oft mehrere Zeilen — Karte darf mitwachsen. */
@media (max-width: 600px) {
    #card-push .chan-warn { line-height: 1.45; }
}

/* Einmaliger Hinweis auf der Aushilfen-Startseite. Bewusst zurückhaltend:
   eine Zeile, ein Knopf, ein Kreuz — kein zweites Banner-Ungetüm. */
.push-prompt {
    display: flex;
    align-items: center;
    gap: var(--s-12);
    margin: 0 0 var(--s-16);
    padding: var(--s-12) var(--s-14);
    background: var(--accent-paper);
    border: 1px solid var(--accent-soft);
    border-radius: 14px;
    animation: fold-down 0.35s ease both;   /* vorhandene Keyframes wiederverwenden */
}
.push-prompt[hidden] { display: none; }
.push-prompt-ico { font-size: 20px; line-height: 1; flex: 0 0 auto; }
.push-prompt-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.push-prompt-body strong { font-size: 14px; color: var(--ink); }
.push-prompt-body span   { font-size: 12.5px; color: var(--ink-3); line-height: 1.4; }
.push-prompt .btn { flex: 0 0 auto; }
.push-prompt-x {
    flex: 0 0 auto;
    width: 28px; height: 28px;
    display: flex; align-items: center; justify-content: center;
    background: none; border: 0; border-radius: 8px;
    font-size: 20px; line-height: 1; color: var(--ink-3); cursor: pointer;
}
.push-prompt-x:hover { background: rgba(0,0,0,0.05); color: var(--ink); }

@media (max-width: 560px) {
    /* Auf dem Handy in zwei Zeilen umbrechen, statt den Text zu quetschen. */
    .push-prompt { flex-wrap: wrap; row-gap: var(--s-10); }
    .push-prompt-body { flex: 1 1 100%; order: 1; }
    .push-prompt-ico  { order: 0; }
    .push-prompt-x    { order: 0; margin-left: auto; }
    .push-prompt .btn { order: 2; flex: 1 1 100%; justify-content: center; }
}

/* Person-Chip „Handy aus": sichtbar, aber zurückhaltend — es ist eine
   Feststellung, keine Warnung. Der Planer soll es finden, wenn er es sucht. */
.person-meta .pm-item.is-muted { color: var(--ink-4); opacity: 0.75; }

/* ==========================================================================
   BENACHRICHTIGUNGEN — die Seite selbst trägt ihre Stile (notifications/index.php,
   Richtung D). Das Glocken-Menü steht oben im Abschnitt „Benachrichtigungs-Glocke".
   ========================================================================== */

/* Nur für Vorlese-Programme: sichtbar für sie, unsichtbar auf dem Bildschirm. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Knöpfe im Seitenkopf, die in einem <form> stecken (weil sie eine Aktion
   auslösen), sollen sich trotzdem wie direkte Kinder verhalten — sonst greifen
   die Handy-Regeln für .ph-side .btn nicht und die Knöpfe brechen aus dem
   Raster. */
.page-head .ph-side form { display: contents; }

/* ==========================================================================
   HANDY-MITTEILUNGEN — Anleitung und Selbstauskunft
   Geht etwas nicht, soll die Karte den GRUND nennen und den Weg zeigen,
   statt nur einen toten Schalter anzubieten.
   ========================================================================== */

.push-steps {
    margin: var(--s-10) 0 0;
    padding-left: var(--s-18);
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--ink-2);
}
.push-steps li { margin-bottom: var(--s-6); }
.push-steps li::marker { color: var(--accent-2); font-weight: 700; }

.push-install { margin-top: var(--s-10); }

/* Selbstauskunft: zugeklappt unauffällig, aufgeklappt eine nüchterne Liste.
   Am Handy gibt es keine Entwickler-Werkzeuge — das hier ist der Ersatz. */
.push-why {
    margin-top: var(--s-10);
    font-family: var(--font-mono);
    font-size: 11px;
}
.push-why > summary {
    cursor: pointer;
    color: var(--ink-3);
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: var(--s-6);
}
.push-why > summary::-webkit-details-marker { display: none; }
.push-why > summary::before { content: '›'; transition: transform 0.15s ease; }
.push-why[open] > summary::before { transform: rotate(90deg); }
.push-why > summary:hover { color: var(--ink); }

.push-why ul {
    margin: var(--s-8) 0 0;
    padding: var(--s-8) var(--s-10);
    list-style: none;
    background: var(--paper-2);
    border-radius: 8px;
}
.push-why li {
    /* Zeichen links, Text direkt daneben. KEIN space-between — das schöbe den
       Text ans rechte Ende und die Liste liefe ausgefranst auseinander. */
    display: flex;
    align-items: baseline;
    gap: var(--s-8);
    padding: var(--s-2) 0;
    color: var(--ink-3);
    line-height: 1.5;
}
.push-why li::before { content: '•'; flex: 0 0 auto; }
.push-why li.is-ok::before  { content: '✓'; color: #15803d; }
.push-why li.is-bad::before { content: '✕'; color: #b91c1c; }
.push-why li.is-bad { color: var(--ink-2); font-weight: 600; }

/* Gesperrter Zustand auf dem Handy: Anleitung und Selbstauskunft brauchen die
   volle Breite. Symbol und Schalter rücken in eine eigene Zeile darüber — der
   Schalter ist hier ohnehin gesperrt, und zwei Wörter pro Zeile liest niemand.
   Bewusst NUR für den gesperrten Zustand: Im Normalfall bleibt die Karte
   einzeilig wie die anderen Kanäle. */
@media (max-width: 560px) {
    #card-push.is-disabled { flex-wrap: wrap; row-gap: var(--s-6); }
    #card-push.is-disabled .chan-ico  { order: 0; }
    #card-push.is-disabled .switch    { order: 1; margin-left: auto; }
    #card-push.is-disabled .chan-body { order: 2; flex: 1 1 100%; }
    #card-push.is-disabled .push-steps { padding-left: var(--s-18); }
}

/* Der Schalter der Handy-Karte ist ein <label> und damit das EINZIGE Tippziel
   dieser Karte (die Nachbarkarten sind komplett Labels). Auf dem Handy braucht
   er deshalb eine großzügige Trefferfläche — 48x28 sind zu wenig zum Treffen. */
#push-switch { cursor: pointer; }
@media (max-width: 820px) {
    #push-switch::after {
        content: '';
        position: absolute;
        top: -10px; right: -8px; bottom: -10px; left: -8px;
    }
}

/* Fehlertext im Startseiten-Hinweis kann eine technische Meldung enthalten —
   er muss umbrechen dürfen und darf die Karte nicht sprengen. */
.push-prompt-body span { overflow-wrap: anywhere; }

/* ===========================================================================
   AUSWAHL MIT SUCHE
   Ersetzt ein Raster aus Ankreuz-Karten durch: gewählte Einträge als Chips,
   darunter ein Suchfeld. Vier Skills sind als Raster in Ordnung, dreißig
   Stationen nicht mehr — und die Liste wächst immer nur in eine Richtung.
   Die Checkboxen bleiben im Formular (.chipwahl-quelle) und tragen die Werte;
   ohne JavaScript sieht man das gewohnte Raster.
   =========================================================================== */
.chipwahl-quelle { display: none; }
.chipwahl { margin-top: var(--s-6); }

.chipwahl-gewaehlt {
    display: flex; flex-wrap: wrap; gap: var(--s-6);
    min-height: 32px; align-items: center; margin-bottom: var(--s-8);
}
.chipwahl-leer { font-size: 12px; color: var(--ink-4); font-style: italic; }

.chipwahl-chip {
    display: inline-flex; align-items: center; gap: var(--s-6);
    padding: var(--s-6) var(--s-10); border-radius: 999px;
    background: var(--accent-paper); border: 1px solid transparent;
    color: var(--accent-2); font-size: 13px; font-weight: 600;
    cursor: pointer; font-family: inherit;
}
.chipwahl-chip i { font-style: normal; font-size: 15px; line-height: 1; opacity: .55; }
.chipwahl-chip:hover { border-color: var(--accent); }
.chipwahl-chip:hover i { opacity: 1; }

.chipwahl-suche { position: relative; max-width: 320px; }
.chipwahl-feld {
    width: 100%; padding: var(--s-10) var(--s-14);
    background: var(--paper); border: 1px solid var(--line);
    border-radius: var(--radius-sm); font-family: inherit; font-size: 14px;
    color: var(--ink);
}
.chipwahl-feld:focus {
    outline: none; border-color: var(--accent); background: var(--surface);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

.chipwahl-liste {
    position: absolute; top: calc(100% + var(--s-4)); left: 0; right: 0; z-index: 20;
    max-height: 240px; overflow-y: auto;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius-sm); box-shadow: var(--shadow-md);
    padding: var(--s-4);
}
.chipwahl-option {
    display: block; width: 100%; text-align: left;
    padding: var(--s-8) var(--s-10); border: 0; border-radius: var(--s-8);
    background: transparent; font-family: inherit; font-size: 13.5px;
    color: var(--ink); cursor: pointer;
}
.chipwahl-option:hover, .chipwahl-option:focus-visible {
    background: var(--accent-paper); color: var(--accent-2);
}
.chipwahl-nix { padding: var(--s-8) var(--s-10); font-size: 13px; color: var(--ink-4); }

/* Auf dem Handy die volle Breite — 320px sind dort fast der ganze Bildschirm. */
@media (max-width: 560px) { .chipwahl-suche { max-width: 100%; } }

/* ===========================================================================
   STRICHSYMBOLE AUSSERHALB DER FUNKTIONS-LEISTE
   Glocke, Pfeilspitze, Kanal-Kacheln und Statuszeichen waren Emoji. Emoji
   tragen eine Farbe, die nichts bedeutet, und werden auf jedem Gerät anders
   gezeichnet — neben den einfarbigen Symbolen der Leiste sah das aus wie zwei
   verschiedene Programme. Die Behälter waren auf Schriftgröße ausgelegt; ein
   SVG braucht eine Box, sonst fällt es auf die Standardgröße 300x150 zurück.
   =========================================================================== */
.notif-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; color: var(--ink-2);
}
.notif-icon svg { width: 20px; height: 20px; display: block; }
.notif-trigger:hover .notif-icon { color: var(--ink); }

.chev {
    display: inline-flex; align-items: center; justify-content: center;
    width: 12px; height: 12px; color: var(--ink-3);
}
.chev svg { width: 12px; height: 12px; display: block; }

.chan-card .chan-ico svg { width: 22px; height: 22px; display: block; color: var(--ink-2); }
.chan-card.is-on .chan-ico svg,
.chan-card:has(input[type="checkbox"]:checked) .chan-ico svg { color: var(--accent); }
.chan-card.is-disabled .chan-ico svg { color: var(--ink-4); }

.notif-section svg { flex: 0 0 auto; width: 12px; height: 12px; display: block; }

/* Zeichen im Knopf: .btn ist inline-flex mit gap, der Abstand kommt von dort. */
.btn-ico { display: inline-flex; flex: 0 0 auto; width: 14px; height: 14px; }
.btn-ico svg { width: 14px; height: 14px; display: block; }

.wmeta-late svg { width: 13px; height: 13px; display: block; }

@media (max-width: 640px) {
    .chan-card .chan-ico svg { width: 19px; height: 19px; }
}

/* Zeichen VOR einer Beschriftung — in Knöpfen, Menüpunkten und Merkzeilen.
   EINE Klasse für alle, sonst erfindet jede Stelle ihre eigene Größe. */
.label-ico { display: inline-flex; flex: 0 0 auto; width: 15px; height: 15px; vertical-align: -2px; }
.label-ico svg { width: 15px; height: 15px; display: block; }

/* Das Schichtmenü bekommt dadurch eine Symbolspalte: die Beschriftungen
   fluchten, statt je nach Zeichenbreite zu springen. */
.shiftctx-menu button { display: flex; align-items: center; gap: var(--s-8); text-align: left; }
.shiftctx-menu button .label-ico { color: var(--ink-3); }
.shiftctx-menu button.danger .label-ico { color: inherit; }

/* Belegt-Zeichen der Pool-Karte steht bei 10,5px Text — kleiner als sonst. */
.pcard-flag .label-ico { width: 12px; height: 12px; align-self: center; }
.pcard-flag .label-ico svg { width: 12px; height: 12px; }

.push-prompt-ico { display: inline-flex; }
.push-prompt-ico svg { width: 20px; height: 20px; display: block; }
.ai-note-emoji { display: flex; justify-content: center; color: var(--ink-4); }
.ai-note-emoji svg { width: 26px; height: 26px; display: block; }

/* Grundgröße jedes Strichsymbols aus hub_symbol(). In em, damit es mit der
   Schrift wächst, in der es steht — ein Symbol in einem 11px-Hinweis soll
   kleiner sein als eines in einem 15px-Knopf. Feste Größen (.hub-ico svg,
   .icon svg, .label-ico svg …) schlagen diese Regel über die Spezifität. */
.ksym {
    width: 1.15em; height: 1.15em;
    display: inline-block; vertical-align: -0.18em;
    flex: 0 0 auto;
}


/* ===========================================================================
   KÖNNEN-GRADE
   Dreißig Regler untereinander sind auf einem Handy unbedienbar. Deshalb liegen
   die Skills in Gruppen, zugeklappt: man sieht fünf Kopfzeilen und entscheidet,
   wo man arbeitet. <details> kann das ohne JavaScript.
   =========================================================================== */
.gradgruppe {
    border: 1px solid var(--line); border-radius: 12px;
    background: var(--paper); margin-top: var(--s-8);
}
.gradgruppe > summary {
    cursor: pointer; list-style: none;
    display: flex; align-items: center; gap: var(--s-10);
    min-height: 44px; padding: var(--s-8) var(--s-14);
    font-size: 14px; font-weight: 600; color: var(--ink);
}
.gradgruppe > summary::-webkit-details-marker { display: none; }
.gradgruppe > summary::after {
    content: "▾"; margin-left: auto; color: var(--ink-4); font-size: 11px; transition: transform .15s;
}
.gradgruppe[open] > summary::after { transform: rotate(180deg); }
.gradgruppe .gg-zahl {
    font-family: var(--font-mono); font-size: 11px; font-weight: 400;
    color: var(--ink-3); letter-spacing: 0.04em;
}
.gradliste { padding: 0 var(--s-14) var(--s-8); }

/* Weiche Untergrenze: eine feste schiebt schmale Fenster seitlich weg. */
.gradzeile {
    display: grid;
    grid-template-columns: minmax(min(180px, 40%), 1fr) minmax(0, 1.4fr);
    align-items: center; gap: var(--s-6) var(--s-14);
    padding: var(--s-6) 0; border-top: 1px solid var(--line);
}
.gradzeile .gradname { font-size: 14px; font-weight: 600; color: var(--ink); margin: 0; }

.gradwahl { display: flex; align-items: center; gap: var(--s-12); min-width: 0; }
.gradwahl-quelle { display: none; }

/* Die 40px sind das Tippziel, nicht die Strichstärke — die Spur ist 6px hoch
   und sitzt mittig darin. Ein 6px hoher Regler ist mit dem Daumen nicht zu
   treffen. */
.gradwahl-regler {
    -webkit-appearance: none; appearance: none;
    flex: 1 1 auto; width: 100%; min-width: 0;
    height: 40px; margin: 0; padding: 0;
    background: transparent; border: 0; box-shadow: none;
    cursor: pointer;
}
.gradwahl-regler::-webkit-slider-runnable-track {
    height: 6px; border-radius: 999px; background: var(--line-2);
}
.gradwahl-regler::-moz-range-track {
    height: 6px; border-radius: 999px; background: var(--line-2);
}
.gradwahl-regler::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 26px; height: 26px; margin-top: -10px;
    border-radius: 999px; background: var(--accent);
    border: 3px solid var(--surface); box-shadow: var(--shadow);
}
.gradwahl-regler::-moz-range-thumb {
    width: 26px; height: 26px;
    border-radius: 999px; background: var(--accent);
    border: 3px solid var(--surface); box-shadow: var(--shadow);
}
.gradwahl-regler:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--accent-soft); }
.gradwahl-regler:focus-visible::-moz-range-thumb     { box-shadow: 0 0 0 4px var(--accent-soft); }

/* "nicht bewertet" und "kann es nicht" sind keine Stufe der Skala: das eine ist
   eine Lücke, das andere eine Aussage. Beides darf nicht wie ein Grad aussehen. */
.gradwahl[data-stufe=""]  .gradwahl-regler::-webkit-slider-thumb { background: var(--ink-4); }
.gradwahl[data-stufe=""]  .gradwahl-regler::-moz-range-thumb     { background: var(--ink-4); }
.gradwahl[data-stufe="0"] .gradwahl-regler::-webkit-slider-thumb { background: var(--danger); }
.gradwahl[data-stufe="0"] .gradwahl-regler::-moz-range-thumb     { background: var(--danger); }

.gradwahl-wert { flex: 0 0 auto; min-width: 104px; font-size: 12px; color: var(--ink-3); }

/* ---- Grad-Zeichen auf der Personenseite ---- */
.koennen {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--s-6) var(--s-8); margin-top: var(--s-12);
}
.koennen-leer { font-size: 12px; color: var(--ink-4); font-style: italic; }
.kgrad {
    display: inline-flex; align-items: center; gap: var(--s-8);
    padding: var(--s-4) var(--s-10); border-radius: 999px;
    background: var(--paper-2); border: 1px solid var(--line);
    font-size: 12px; color: var(--ink-2);
}
.kgrad .kg-name { font-weight: 600; color: var(--ink); }
.kgrad .kg-bar {
    width: 44px; height: 4px; border-radius: 999px;
    background: var(--line-2); overflow: hidden;
}
.kgrad .kg-bar > span { display: block; height: 100%; background: var(--accent); }
.kgrad .kg-zahl { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
.kgrad.is-nicht .kg-name { color: var(--ink-4); text-decoration: line-through; }
.kgrad.is-ohne  .kg-zahl { color: var(--warning); }

@media (max-width: 640px) {
    /* Name oben, Regler darunter über die volle Breite. Nebeneinander bliebe für
       den Regler bei 375px zu wenig, um zehn Stufen zu treffen. */
    .gradzeile { grid-template-columns: minmax(0, 1fr); gap: var(--s-2); }
    .gradwahl-wert { min-width: 0; }
    .gradliste { padding: 0 var(--s-12) var(--s-8); }
}

/* ==========================================================================
   Face ID / Fingerabdruck (Passkeys) — Profil, Anmeldeseite, Hinweis
   includes/_passkey-card.php, login.php
   ========================================================================== */
/* .btn setzt display — das hidden-Attribut allein bliebe wirkungslos. */
.passkey-actions [hidden], .push-prompt [hidden], .login-passkey [hidden], .login-passkey[hidden] { display: none !important; }
.passkey-intro { color: var(--ink-3); font-size: 13px; margin: calc(-1 * var(--s-12)) 0 var(--s-16); }
.passkey-actions { display: flex; align-items: center; gap: var(--s-12); flex-wrap: wrap; margin-top: var(--s-14); }
.passkey-status { margin: 0; font-size: 13px; color: var(--ink-3); }
.passkey-status:empty { display: none; }
.passkey-row .btn { flex: 0 0 auto; }

.login-passkey { margin-top: var(--s-14); }
.login-passkey .btn { width: 100%; justify-content: center; }
.login-passkey .alert { margin: var(--s-12) 0 0; }
.login-passkey-note { margin: var(--s-10) 0 0; font-size: 13px; color: var(--ink-3); text-align: center; line-height: 1.45; }
.login-or {
    display: flex; align-items: center; gap: var(--s-10); margin-bottom: var(--s-14);
    font-family: var(--font-mono); font-size: 11px; color: var(--ink-4);
    text-transform: uppercase; letter-spacing: 0.08em;
}
.login-or::before, .login-or::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }

/* Kleine Auswahlfelder in Werkzeugleisten: auf dem Handy 16px, sonst zoomt iOS beim
   Antippen hinein (Projektleiter-Filter, „Zweites Projekt", Annahmeprojekt, Projektsuche). */
@media (max-width: 820px) {
    .leader-filter select, .second-view-picker select, .annahme-row .annahme-shift{ font-size: 16px; }
}

/* ===========================================================================
   RICHTUNG D — große Bedienflächen (Wochenübersicht, Planung, Projekte,
   Aushilfen-Seiten). Gemeinsame Bausteine:
   - große Knöpfe (.btn-lg, .btn-block, .btn-ok, .btn-danger, .btn-danger-quiet)
   - „Zu klären"-Linsen (.linsen > .linse)
   - EIN Blatt: am Schreibtisch Seitenleiste rechts, am Handy Blatt von unten
     (.blatt-hinter + .blatt). Hängt per assets/js/blatt.js an document.body —
     sonst bezieht sich position: fixed auf main (Einblend-Transform) und der
     Kopf mit z-index 30 liegt darüber.
   - Meldung mit „Rückgängig" (.kmeldung). Erscheint nur nach einer Handlung
     und geht von selbst wieder: nichts schwebt DAUERHAFT über dem Text.
   - Passungsfarben fürs Einteilen (.shift-box.fit-*) und das Aushilfen-Dock.
   =========================================================================== */
.btn-lg { min-height: 52px; padding: 0 var(--s-24); font-size: 15px; font-weight: 800; justify-content: center; }
.btn-block { width: 100%; justify-content: center; }
.btn-ok { background: var(--success-2); border-color: var(--success-2); color: #fff; }
.btn-ok:hover { background: #125c31; border-color: #125c31; color: #fff; }
.btn-danger { background: #b91c1c; border-color: #b91c1c; color: #fff; }
.btn-danger:hover { background: #991b1b; border-color: #991b1b; color: #fff; }
.btn-danger-quiet { background: var(--surface); color: #b91c1c; border: 2px solid #f2b8b8; }
.btn-danger-quiet:hover { background: #fdecec; border-color: #b91c1c; color: #b91c1c; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; transform: none; }

/* --- Linsen: ein Druck blendet alles andere blass --- */
.linsen { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-8); }
.linsen-titel { font-size: 14px; font-weight: 800; color: var(--ink); margin-right: var(--s-4); }
.linse {
    min-height: 44px; display: inline-flex; align-items: center; gap: var(--s-8);
    padding: 0 var(--s-16); border: 2px solid transparent; border-radius: 999px;
    font: inherit; font-size: 14px; font-weight: 800; cursor: pointer; line-height: 1.2;
}
.linse b { font-family: var(--font-mono); font-size: 15px; font-weight: 700; }
.linse[aria-pressed="true"] { border-color: currentColor; }
.linse:disabled { opacity: 0.5; cursor: default; }
.linse[hidden] { display: none; }
/* Am Handy eine wischbare Zeile statt vier umbrochener — die Woche rückt nach oben. */
@media (max-width: 640px) {
    .linsen { flex-wrap: nowrap; overflow-x: auto; margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter) var(--s-4); scrollbar-width: none; }
    .linsen::-webkit-scrollbar { display: none; }
    .linse, .linsen-titel { flex: 0 0 auto; white-space: nowrap; }
    .linse { min-height: 40px; padding: 0 var(--s-14); font-size: 13px; }
}
.linse-konflikt { background: #fdecec; color: #b91c1c; }
.linse-gemeldet { background: #d9f1fb; color: #0b6c8c; }
.linse-anfrage  { background: var(--accent-paper); color: var(--accent-2); }
.linse-leer     { background: #f1efe8; color: var(--ink-2); }
.linse-weg      { background: transparent; color: var(--accent-2); border-color: transparent; }

/* --- Blatt: Seitenleiste (Schreibtisch) / Blatt von unten (Handy) --- */
.blatt-hinter { position: fixed; inset: 0; z-index: 1200; background: rgba(20, 17, 12, 0.32); }
.blatt {
    position: fixed; z-index: 1201; top: 0; right: 0; bottom: 0;
    width: 470px; max-width: 100vw; box-sizing: border-box; overflow-y: auto; overscroll-behavior: contain;
    display: flex; flex-direction: column; gap: var(--s-16);
    padding: var(--s-24); background: var(--surface); color: var(--ink);
    box-shadow: -24px 0 60px rgba(20, 17, 12, 0.2);
}
.blatt[hidden], .blatt-hinter[hidden], .kmeldung[hidden] { display: none; }
/* Das Blatt selbst nimmt den Fokus nur als Rückhalt an (tabindex="-1", blatt.js: ein Klick
   auf Text darin) — es ist kein Bedienelement und bekommt keinen Fokusrahmen. */
.blatt:focus, .blatt:focus-visible { outline: none; }
/* Bausteine im Blatt setzen display selbst (.blatt-rund: inline-flex) — das hidden-
   Attribut allein bliebe dann wirkungslos (wie bei .btn, siehe Passkey-Abschnitt). */
.blatt [hidden] { display: none !important; }
.blatt-griff { display: none; }
.blatt-kopf { display: flex; align-items: flex-start; gap: var(--s-12); }
.blatt-kopf-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.blatt-titel { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; }
.blatt-unter { font-size: 14px; color: var(--ink-2); }
.blatt-rund {
    flex: 0 0 auto; width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%; background: var(--paper-2); color: var(--ink); cursor: pointer;
    font: inherit; font-size: 20px; line-height: 1;
}
.blatt-rund:hover { background: var(--line); }
.blatt-rund .ksym { width: 20px; height: 20px; }
.blatt-warnung {
    margin: 0; display: flex; align-items: center; gap: var(--s-8);
    padding: var(--s-10) var(--s-14); border-radius: 14px; background: #fdecec; color: #b91c1c;
    font-size: 14px; font-weight: 800;
}
.blatt-block {
    display: flex; flex-direction: column; gap: var(--s-12);
    padding: var(--s-14) var(--s-14) var(--s-14) var(--s-18); border-radius: 18px;
    background: var(--paper); box-shadow: inset 5px 0 0 var(--farbe, var(--line-2));
}
.blatt-block-kopf { display: flex; flex-direction: column; gap: var(--s-2); }
.blatt-block-kopf b { font-size: 16px; font-weight: 800; }
.blatt-block-kopf span { font-size: 14px; color: var(--ink-2); }
.blatt-block-kopf .mono { font-family: var(--font-mono); }
.blatt-block-hinweis { font-size: 13px; font-weight: 700; color: var(--accent-2); }
.blatt-knoepfe { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); }
.blatt-knoepfe-1 { grid-template-columns: minmax(0, 1fr); }
.blatt-inhalt { display: flex; flex-direction: column; gap: var(--s-14); }
/* Der Hauptweg über die ganze Breite, die Nebenwege darunter zu zweit. */
.blatt-knopf-breit { grid-column: 1 / -1; }
.blatt-text { margin: 0; font-size: 14px; color: var(--ink-2); line-height: 1.45; }
.blatt-leise { margin: 0; font-size: 13px; color: var(--ink-3); line-height: 1.45; }
.blatt-link { align-self: flex-start; min-height: 44px; display: inline-flex; align-items: center; font-size: 15px; font-weight: 800; color: var(--accent-2); text-decoration: none; }
.blatt-link:hover { text-decoration: underline; }
.blatt-fehler { margin: 0; padding: var(--s-10) var(--s-14); border-radius: 12px; background: #fdecec; color: #b91c1c; font-size: 14px; font-weight: 700; }
.blatt-fehler:empty { display: none; }
.blatt-ok {
    display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-10);
    padding: var(--s-18); border-radius: 18px; background: #eef8f1;
}
.blatt-ok-zeichen {
    width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; background: var(--success-2); color: #fff;
}
.blatt-ok-zeichen .ksym { width: 24px; height: 24px; }
.blatt-ok b { font-size: 18px; font-weight: 800; }
.blatt-zitat { margin: 0; padding: var(--s-10) var(--s-14); border-left: 3px solid var(--accent); background: var(--surface); border-radius: 0 12px 12px 0; font-size: 14px; color: var(--ink-2); }

/* Woche einer Person: sieben Kästchen, das gewählte mit Ring */
.miniwoche { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--s-6); }
.miniwoche > button, .miniwoche > span {
    min-height: 54px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2);
    padding: 0; border: 2px solid transparent; border-radius: 12px; background: var(--paper-2); color: var(--ink-3);
    font: inherit; cursor: pointer;
}
.miniwoche b { font-size: 12.5px; font-weight: 800; }
.miniwoche small { font-family: var(--font-mono); font-size: 10.5px; font-weight: 700; }
.miniwoche .mw-einsatz { background: var(--farbe, var(--ink-2)); color: #fff; }
.miniwoche .mw-doppelt { background: #fdecec; color: #b91c1c; }
.miniwoche .mw-frei    { background: #d9f1fb; color: #0b6c8c; }
.miniwoche .mw-ok      { background: #def5e6; color: var(--success-2); }
.miniwoche .mw-frage   { background: var(--surface); color: var(--accent-2); border: 2px dashed var(--accent); }
.miniwoche .is-aktiv   { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); }

/* Tagwahl im Blatt: große Kacheln mit dem, was die Person gemeldet hat */
.tagwahl { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-8); }
.tagwahl > button {
    min-height: 66px; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: var(--s-2);
    padding: var(--s-8) var(--s-12); border: 2px solid var(--line); border-radius: 16px; background: var(--surface);
    color: var(--ink-2); font: inherit; text-align: left; cursor: pointer; box-sizing: border-box;
}
.tagwahl > button b { font-size: 15px; font-weight: 800; color: var(--ink); }
.tagwahl > button small { font-size: 12px; font-weight: 700; color: var(--ink-3); }
.tagwahl > button.is-frei { border-color: #9fd3e6; background: #eef8fc; }
.tagwahl > button.is-frei small { color: #0b6c8c; }
.tagwahl > button[aria-pressed="true"] { border-color: var(--ink); background: var(--ink); }
.tagwahl > button[aria-pressed="true"] b, .tagwahl > button[aria-pressed="true"] small { color: #fff; }
.tagwahl > button:disabled { opacity: 0.5; cursor: not-allowed; }
.zeitfelder { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); }
.zeitfelder label { display: flex; flex-direction: column; gap: var(--s-4); font-size: 13px; font-weight: 700; color: var(--ink-2); min-width: 0; }
.zeitfelder input {
    min-width: 0; min-height: 52px; padding: 0 var(--s-14); border: 2px solid var(--line); border-radius: 14px;
    background: var(--surface); font-family: var(--font-mono); font-size: 18px; color: var(--ink);
}
.zeitfelder input:focus { outline: none; border-color: var(--ink); }
/* Ein Textfeld im Blatt (Notiz am Einsatz). 16px: darunter zoomt iOS beim Antippen hinein. */
.blatt-feld { display: flex; flex-direction: column; gap: var(--s-4); font-size: 13px; font-weight: 700; color: var(--ink-2); min-width: 0; }
.blatt-feld input {
    min-width: 0; min-height: 52px; padding: 0 var(--s-14); border: 2px solid var(--line); border-radius: 14px;
    background: var(--surface); font: inherit; font-size: 16px; font-weight: 400; color: var(--ink);
}
.blatt-feld input:focus { outline: none; border-color: var(--ink); }
/* Notiz am Einsatz: Symbol, daneben der Text — er bricht um. */
.blatt-notiz { display: flex; align-items: flex-start; gap: var(--s-6); font-size: 13px; line-height: 1.4; color: var(--ink-2); overflow-wrap: anywhere; }
.blatt-notiz .ksym { flex: 0 0 auto; width: 14px; height: 14px; margin-top: var(--s-2); }
/* Was die Aushilfe zu dem Einsatz gemeldet hat („komme später", „krank"): Zeichen und Satz. */
.blatt-meldung { display: flex; align-items: flex-start; gap: var(--s-6); font-size: 13px; font-weight: 700; line-height: 1.4; overflow-wrap: anywhere; }
.blatt-meldung .ksym { flex: 0 0 auto; width: 15px; height: 15px; margin-top: var(--s-2); }
.blatt-block-kopf .blatt-meldung-late { color: #9a4a0f; }
.blatt-block-kopf .blatt-meldung-sick { color: #b91c1c; }

/* Schalter als Knopf (role="switch") — kein verstecktes Eingabefeld, das ohne
   umschließendes <label> nichts täte (siehe .switch-Falle in der Gestaltungsregel). */
.kschalter {
    display: flex; align-items: center; gap: var(--s-12); min-height: 56px; width: 100%;
    padding: 0 var(--s-14); border: 0; border-radius: 16px; background: var(--paper-2);
    font: inherit; font-size: 15px; font-weight: 700; color: var(--ink); text-align: left; cursor: pointer;
}
.kschalter-spur { flex: 0 0 auto; position: relative; width: 50px; height: 30px; border-radius: 999px; background: #cfc6b1; transition: background 0.15s; }
.kschalter-spur::after {
    content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%;
    background: #fff; box-shadow: 0 1px 2px rgba(20, 17, 12, 0.25); transition: left 0.15s;
}
.kschalter[aria-checked="true"] .kschalter-spur { background: var(--success-2); }
.kschalter[aria-checked="true"] .kschalter-spur::after { left: 23px; }

@media (max-width: 640px) {
    /* dvh: Mit eingeblendeter Adressleiste (und quer) ist das Fenster niedriger als 100vh —
       der Kopf des Blatts mit „Schließen" läge sonst über dem oberen Rand. */
    .blatt {
        top: auto; left: 0; width: auto; max-height: 88vh; max-height: 88dvh;
        border-radius: 24px 24px 0 0; padding: var(--s-10) var(--s-16) var(--s-24);
        box-shadow: 0 -16px 48px rgba(20, 17, 12, 0.24);
    }
    .blatt-griff { display: block; align-self: center; width: 44px; height: 5px; border-radius: 3px; background: var(--line-2); flex: 0 0 auto; }
    .blatt-titel { font-size: 21px; }
    .blatt-rund { width: 44px; height: 44px; }
    .zeitfelder input { font-size: 18px; }
    .blatt .btn-lg { padding: 0 var(--s-12); font-size: 14px; }
}

/* --- Meldung mit Rückgängig --- */
.kmeldung {
    position: fixed; z-index: 1300; left: 50%; bottom: calc(var(--s-24) + var(--leiste-unten)); transform: translateX(-50%);
    width: max-content; max-width: calc(100vw - 2 * var(--gutter)); box-sizing: border-box;
    display: flex; align-items: center; gap: var(--s-12); min-height: 52px;
    padding: var(--s-6) var(--s-6) var(--s-6) var(--s-18); border-radius: 18px;
    background: var(--ink); color: #fff; box-shadow: var(--shadow-lg);
    font-size: 14px; font-weight: 700; line-height: 1.35;
}
.kmeldung-text { flex: 1 1 auto; min-width: 0; }
.kmeldung-ok    { background: var(--success-2); }
.kmeldung-frage { background: #0b6c8c; }
.kmeldung-fehler { background: #fdecec; color: #b91c1c; box-shadow: inset 0 0 0 1px #f2b8b8, var(--shadow-lg); }
.kmeldung button {
    flex: 0 0 auto; min-height: 40px; padding: 0 var(--s-14); border: 0; border-radius: 12px;
    background: rgba(255, 255, 255, 0.9); color: var(--ink); font: inherit; font-size: 13px; font-weight: 800; cursor: pointer;
}
.kmeldung-fehler button { background: #fff; }
.kmeldung button + button { margin-left: calc(-1 * var(--s-6)); }
@media (max-width: 640px) { .kmeldung { bottom: calc(var(--s-16) + var(--leiste-unten)); width: calc(100vw - 2 * var(--gutter)); } }

/* --- Passung beim Einteilen: grün ganz, orange teilweise, blau wird Anfrage, grau geht nicht --- */
.fit-badge {
    align-self: flex-start; display: inline-flex; align-items: center; min-height: 24px;
    padding: 0 var(--s-10); border-radius: 999px; font-size: 12px; font-weight: 800; line-height: 1.2;
    background: #f1efe8; color: var(--ink-2); white-space: nowrap;
}
.fit-badge-ganz  { background: #def5e6; color: var(--success-2); }
.fit-badge-teil  { background: #fcebd9; color: #9a4a0f; }
.fit-badge-keine { background: #d9f1fb; color: #0b6c8c; }
/* Über .planung-grid eine Stufe spezifischer als .shift-box.full aus dem Abschnitt
   PLANUNGSRASTER — so gewinnt die Passungsfarbe ohne !important. Dieselben Farben
   zeigen beim Verschieben, was der Server zu einem Ziel sagt (move-targets.php). */
.planung-grid .shift-box.fit-ganz  { border-color: var(--success); background: #f1faf4; box-shadow: 0 0 0 1px var(--success); }
.planung-grid .shift-box.fit-teil  { border-color: #d97706; background: #fdf6ec; box-shadow: 0 0 0 1px #d97706; }
.planung-grid .shift-box.fit-keine { border-color: #0b6c8c; border-style: dashed; background: #f2fafd; }
.shift-box.fit-aus   { opacity: 0.5; }
.planung-grid .shift-box.fit-ziel { transform: scale(1.03); box-shadow: 0 0 0 3px var(--ink), 0 18px 40px rgba(20, 17, 12, 0.18); position: relative; z-index: 2; }
.shift-box .fit-badge { margin-top: var(--s-4); }
@media (prefers-reduced-motion: reduce) { .planung-grid .shift-box.fit-ziel { transform: none; } }
.blatt-abschnitt { font-size: 15px; font-weight: 800; color: var(--ink); }

/* Ziele beim Verschieben (und die übrigen Einsätze der Woche): eine Zeile je Schicht.
   Der Stand steht als Text in der Zeile — keine Farbe ohne Wort. Gesperrte Zeilen
   bleiben lesbar, damit der Grund ankommt. */
.ziele { position: relative; display: flex; flex-direction: column; gap: var(--s-6); }
.ziel {
    display: grid; grid-template-columns: 6px minmax(0, 1fr) auto; column-gap: var(--s-10); align-items: center;
    width: 100%; min-height: 56px; padding: var(--s-8) var(--s-12) var(--s-8) var(--s-8); text-align: left;
    border: 1px solid var(--line); border-radius: 14px; background: var(--surface); color: var(--ink);
    font: inherit; cursor: pointer;
}
.ziel:hover:not(:disabled) { border-color: var(--line-2); background: var(--paper); }
.ziel-farbe { align-self: stretch; border-radius: 3px; background: var(--farbe, var(--line-2)); }
.ziel-text { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.ziel-text b { font-size: 15px; font-weight: 800; overflow-wrap: anywhere; }
.ziel-text span { font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.ziel-text .mono { font-family: var(--font-mono); }
.ziel-text .ziel-grund { color: #9a4a0f; font-weight: 600; }
.ziel-text .ziel-neben { color: var(--ink-3); }
.ziel-besetzt { font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.ziel:disabled { cursor: default; background: var(--paper); }
.ziel.ist-gesperrt .ziel-text b { color: var(--ink-3); }
.ziel.ist-hier { border-style: dashed; }
.ziel.ist-frage, .ziel.ist-teil { border-color: #e6c9a8; }
.ziel-gruende { display: flex; flex-direction: column; gap: var(--s-6); }
.ziel-gruende:empty { display: none; }
/* 16px: darunter zoomt iOS beim Antippen in das Feld hinein. */
.ziel-suche {
    min-height: 44px; padding: 0 var(--s-14); border: 1px solid var(--line-2); border-radius: 12px;
    background: var(--surface); color: var(--ink); font: inherit; font-size: 16px;
}
.ziel-suche[hidden] { display: none; }
.blatt-gut { color: #0b6c8c; font-weight: 800; }
.blatt-achtung { color: #9a4a0f; font-weight: 800; }
.blatt-wege { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s-16); }
/* min-width: Ein kurzes Wort („Notiz") bleibt als Tippziel so breit wie hoch. */
button.blatt-link { min-width: 44px; padding: 0; border: 0; background: transparent; font: inherit; font-size: 15px; font-weight: 800; cursor: pointer; }
.blatt-link.blatt-link-leise { color: var(--ink-3); font-size: 14px; font-weight: 700; }
.blatt-warnung .ksym { width: 18px; height: 18px; flex: 0 0 auto; }

/* --- Anfrage-Karten der Aushilfe (Banner, Mitteilungen) — Richtung D --- */
.d-anfragen { display: flex; flex-direction: column; gap: var(--s-12); margin-top: var(--s-16); max-width: 760px; }
.d-anfrage {
    display: flex; flex-direction: column; gap: var(--s-12); padding: var(--s-16);
    border: 1.5px solid rgba(230, 53, 122, 0.35); border-radius: 22px; background: #fdf1f5;
}
.d-anfrage.is-proposal { border-color: rgba(3, 105, 161, 0.3); background: #eef6fb; }
.d-anfrage-kopf { display: flex; align-items: center; gap: var(--s-8); font-size: 15px; font-weight: 800; color: var(--ink); }
.d-anfrage-kopf .label-ico { color: var(--accent-2); display: inline-flex; }
.d-anfrage.is-proposal .d-anfrage-kopf .label-ico { color: #0369a1; }
.d-anfrage-karte { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-14); border-radius: 16px; background: var(--surface); }
.d-anfrage-zeile { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-4) var(--s-12); }
.d-anfrage-zeile b { font-size: 20px; font-weight: 800; letter-spacing: -0.01em; }
.d-anfrage-zeile .d-anfrage-zeit { font-family: var(--font-mono); font-weight: 600; }
.d-anfrage-statt { font-size: 14px; color: var(--ink-3); }
.d-anfrage-hinweis { font-size: 13px; color: var(--ink-2); }
.d-anfrage-knoepfe { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-8); }
.d-anfrage-knoepfe .btn { width: 100%; }
.d-anfrage-fertig { display: flex; align-items: center; gap: var(--s-10); font-size: 15px; font-weight: 800; color: var(--success-2); }
.d-anfrage-fertig.ist-nein { color: var(--ink-2); }
.d-anfrage-fertig svg { width: 22px; height: 22px; flex: none; }

/* ===========================================================================

   RICHTUNG C — die Sprache der Projektübersicht, für alle Seiten

   Großer Name, Reiter als Pillen daneben, runde Knöpfe in Daumengröße, das
   Dringende als farbige Kachel obenauf, Listen als ruhige Zeilen. Entstanden
   für produktion/projekte.php; seit 04.10.2026 gilt sie überall.

   Teil 1 sind die Bausteine selbst (pk-…). Teil 2 stellt die älteren geteilten
   Bausteine (Seitenkopf, Reiter, Knöpfe, Tabellen, Karten) auf dieselbe Sprache
   — so sehen Seiten mit bestehendem Markup gleich aus, ohne dass jede einzeln
   umgeschrieben werden muss.

   =========================================================================== */

/* ---------------------------------------------------------------------------
   Teil 1 · Bausteine
   --------------------------------------------------------------------------- */
.pk-kopf { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-16) var(--s-24); margin-bottom: var(--s-24); }
.pk-kopf h1 { margin: 0; font-size: 44px; font-weight: 800; letter-spacing: -0.035em; line-height: 1; }
.pk-luft { flex: 1 1 0; }
.pk-reiter { display: inline-flex; gap: var(--s-6); padding: var(--s-6); border-radius: 999px; background: var(--paper-2); max-width: 100%; overflow-x: auto; }
.pk-reiter a {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--s-18);
    border-radius: 999px; color: var(--ink-2); font-weight: 700; font-size: 15px; text-decoration: none; white-space: nowrap;
}
.pk-reiter a:hover { color: var(--ink); text-decoration: none; }
.pk-reiter a[aria-current="page"] { background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(20, 17, 12, 0.14); }
.pk-neu {
    min-height: 52px; display: inline-flex; align-items: center; gap: var(--s-8); padding: 0 var(--s-24);
    border-radius: 999px; background: var(--accent-2); color: #fff; font-weight: 800; font-size: 16px; text-decoration: none;
}
.pk-neu:hover { color: #fff; background: #9c1849; text-decoration: none; }
.pk-neu svg, .pk-neu-rund svg { width: 20px; height: 20px; }

.pk-leiste { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-10) var(--s-16); margin-bottom: var(--s-24); }
.pk-leiste .leader-filter, .pk-leiste .year-filter { margin: 0; }
.pk-wochen-nav { display: inline-flex; gap: var(--s-6); }
.pk-wochen-nav a {
    min-width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--s-14);
    border-radius: 999px; border: 1px solid var(--line-2); background: var(--surface); color: var(--ink); font-weight: 700; text-decoration: none;
}
.pk-wochen-nav a:hover { border-color: var(--ink-4); text-decoration: none; }
.pk-kw { font-family: var(--font-mono); font-size: 13px; color: var(--ink-3); }
.pk-kw b { color: var(--ink); font-weight: 600; }
.pk-suche { display: flex; align-items: center; gap: var(--s-8); flex: 1 1 320px; min-width: 0; margin: 0; }
.pk-suche input[type="search"] {
    flex: 1 1 auto; min-width: 0; height: 52px; padding: 0 var(--s-18); border: 1px solid transparent; border-radius: 999px;
    background: var(--paper-2); font-size: 16px; color: var(--ink);
}
.pk-suche input[type="search"]:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-paper); }
.pk-papierkorb { display: inline-flex; align-items: center; gap: var(--s-6); color: #9a4a0f; font-weight: 700; font-size: 14px; text-decoration: none; min-height: 44px; }

/* Zuerst erledigen */
.pk-zuerst { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: var(--s-16); margin-bottom: var(--s-24); }
.pk-kachel { display: flex; align-items: center; gap: var(--s-18); min-height: 96px; padding: var(--s-18) var(--s-24); border-radius: 24px; color: var(--ink); text-decoration: none; }
.pk-kachel:hover { text-decoration: none; color: var(--ink); filter: brightness(0.98); }
.pk-kachel-zahl { font-family: var(--font-mono); font-size: 44px; font-weight: 500; line-height: 1; }
.pk-kachel-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.pk-kachel-text b { font-size: 17px; font-weight: 800; }
.pk-kachel-text span { font-size: 14px; color: var(--ink-2); overflow-wrap: anywhere; }
.pk-kachel-pfeil { width: 44px; height: 44px; flex: none; display: flex; align-items: center; justify-content: center; border-radius: 50%; color: #fff; font-size: 18px; }
.pk-kachel-luecke   { background: var(--accent-paper); }
.pk-kachel-luecke .pk-kachel-zahl { color: var(--accent-2); }
.pk-kachel-luecke .pk-kachel-pfeil { background: var(--accent-2); }
.pk-kachel-konflikt { background: #fdecec; }
.pk-kachel-konflikt .pk-kachel-zahl { color: #b91c1c; }
.pk-kachel-konflikt .pk-kachel-pfeil { background: #b91c1c; }
.pk-kachel-versand  { background: #fdf3c4; }
.pk-kachel-versand .pk-kachel-zahl { color: #6b4e00; }
.pk-kachel-versand .pk-kachel-pfeil { background: var(--ink); }

/* Karten */
.pk-karten { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: var(--s-18); }
.pk-karte { position: relative; display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 24px; background: var(--surface); }
.pk-karte-kopf {
    position: relative; min-height: 104px; display: flex; flex-direction: column; justify-content: space-between; gap: var(--s-10);
    padding: var(--s-18) 64px var(--s-18) var(--s-24); border-radius: 23px 23px 0 0; background: var(--pk-farbe, #5b5550); color: #fff;
}
.pk-meta { display: flex; align-items: center; gap: var(--s-6); font-size: 13px; font-weight: 600; opacity: 0.92; }
.pk-pin svg { width: 14px; height: 14px; display: block; }
.pk-name { color: #fff; font-size: 24px; font-weight: 800; letter-spacing: -0.025em; line-height: 1.1; text-decoration: none; overflow-wrap: anywhere; }
.pk-name:hover { color: #fff; text-decoration: underline; }
.pk-mehr { position: absolute; top: var(--s-12); right: var(--s-12); }
.pk-mehr > summary {
    list-style: none; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
    border-radius: 50%; background: rgba(255, 255, 255, 0.16); color: #fff; cursor: pointer;
}
.pk-mehr > summary::-webkit-details-marker { display: none; }
.pk-mehr > summary:hover, .pk-mehr[open] > summary { background: rgba(255, 255, 255, 0.32); }
.pk-mehr > summary:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.pk-punkte { display: inline-flex; gap: var(--s-4); }
.pk-punkte i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; }
.pk-menue {
    position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 230px; padding: var(--s-6);
    display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 16px; background: var(--surface);
    box-shadow: 0 18px 40px rgba(20, 17, 12, 0.16);
}
.pk-menue form { margin: 0; }
.pk-menue a, .pk-menue button {
    white-space: nowrap; width: 100%; min-height: 44px; display: flex; align-items: center; padding: 0 var(--s-12); border: 0; border-radius: 10px;
    background: none; color: var(--ink); font: inherit; font-size: 15px; font-weight: 600; text-align: left; text-decoration: none; cursor: pointer;
}
.pk-menue a:hover, .pk-menue button:hover { background: var(--paper-2); text-decoration: none; color: var(--ink); }
.pk-menue .ist-gefahr { color: #b91c1c; }
.pk-menue .ist-gefahr:hover { color: #b91c1c; background: #fdecec; }

.pk-rumpf { flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--s-16); padding: var(--s-18) var(--s-24) var(--s-24); }
.pk-stand { display: flex; flex-direction: column; gap: var(--s-8); }
.pk-stand-zeile { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--s-4) var(--s-8); }
.pk-zahl { font-family: var(--font-mono); font-size: 24px; font-weight: 500; letter-spacing: -0.02em; }
.pk-stand-wort { font-size: 15px; color: var(--ink-2); }
.pk-hinweis { margin-left: auto; font-size: 13px; font-weight: 700; color: #6b4e00; }
.pk-text { font-size: 14px; color: var(--ink-2); }
.pk-balken { display: block; height: 12px; border-radius: 6px; background: var(--paper-2); overflow: hidden; }
.pk-balken > span { display: block; height: 100%; border-radius: 6px; background: var(--pk-farbe, var(--ink)); }
.pk-tage { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--s-6); }
.pk-tag {
    height: 54px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2);
    border-radius: 14px; font-size: 12px; font-weight: 700; box-sizing: border-box;
}
.pk-tag-wert { font-family: var(--font-mono); font-size: 16px; font-weight: 500; line-height: 1; }
.pk-tag-ausruf { font-family: var(--font-sans); font-weight: 800; font-size: 17px; }
.pk-tag-haken svg { width: 18px; height: 18px; display: block; }
.pk-tag-leer     { border: 1.5px dashed var(--line-2); color: var(--ink-4); }
.pk-tag-fehlt    { background: var(--accent-paper); color: var(--accent-2); }
.pk-tag-ohne     { background: var(--paper-2); color: var(--ink-3); }
.pk-tag-konflikt { background: #fdecec; color: #b91c1c; }
.pk-tag-voll     { background: #e6f4ea; color: var(--success-2); }
.pk-tag.ist-vorbei { opacity: 0.45; }
.pk-cta {
    margin-top: auto; min-height: 52px; display: flex; align-items: center; justify-content: center; gap: var(--s-10);
    border-radius: 999px; font-size: 16px; font-weight: 800; text-decoration: none; text-align: center; padding: 0 var(--s-16);
}
.pk-cta:hover { text-decoration: none; }
.pk-cta-pink    { background: var(--accent-2); color: #fff; }
.pk-cta-pink:hover { background: #9c1849; color: #fff; }
.pk-cta-schwarz { background: var(--ink); color: #fff; }
.pk-cta-schwarz:hover { background: #2e2920; color: #fff; }
.pk-cta-grau    { background: var(--paper-2); color: var(--ink); }
.pk-cta-grau:hover { background: var(--line); color: var(--ink); }
.pk-neu-kachel {
    min-height: 300px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-12);
    border: 2px dashed var(--line-2); border-radius: 24px; color: var(--ink-2); font-size: 17px; font-weight: 800; text-decoration: none;
}
.pk-neu-kachel:hover { border-color: var(--ink-4); color: var(--ink); text-decoration: none; }
.pk-neu-rund { width: 60px; height: 60px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--paper-2); }
.pk-leer { margin: var(--s-8) 0 var(--s-24); }

.pk-legende { margin: var(--s-24) 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-8) var(--s-18); font-size: 13px; color: var(--ink-2); }
.pk-legende > span { display: inline-flex; align-items: center; gap: var(--s-8); }
.pk-legende i {
    width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px;
    font-style: normal; font-family: var(--font-mono); font-weight: 600; font-size: 12px;
}
.pk-legende i svg { width: 14px; height: 14px; }

/* Zeilen: Archiv, Papierkorb, vorbei-aber-offen */
.pk-abschnitt { margin-top: var(--s-32); }
.pk-abschnitt h2 {
    margin: 0 0 var(--s-12); font-family: var(--font-mono); font-size: 11px; font-weight: 500; text-transform: uppercase;
    letter-spacing: 0.12em; color: var(--ink-3);
}
.pk-zeilen { display: flex; flex-direction: column; gap: var(--s-10); }
.pk-zeile {
    min-height: 68px; display: grid; grid-template-columns: 14px minmax(0, 1fr) auto auto auto 44px; align-items: center;
    gap: var(--s-16); padding: var(--s-10) var(--s-14) var(--s-10) var(--s-24); border-radius: 20px; background: var(--paper-2);
}
.pk-zeile-kurz { grid-template-columns: 14px minmax(0, 1fr) auto; }
.pk-punkt { width: 14px; height: 14px; border-radius: 4px; }
.pk-zeile-name { display: flex; flex-direction: column; min-width: 0; }
.pk-zeile-name > a { font-size: 17px; font-weight: 800; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.pk-zeile-name > a:hover { color: var(--accent-2); text-decoration: underline; }
.pk-zeile-unter { font-size: 13px; color: var(--ink-2); }
.pk-nur-handy { display: none; }
.pk-zeile-zeit, .pk-zeile-std { font-family: var(--font-mono); font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.pk-zeile-std { min-width: 56px; text-align: right; }
.pk-zeile-aktionen { display: flex; gap: var(--s-6); }
.pk-zeile-aktionen form, .pk-zeile-aktion { margin: 0; }
.pk-rund {
    width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; padding: 0;
    border: 1px solid var(--line-2); border-radius: 50%; background: var(--surface); color: var(--ink); cursor: pointer;
}
.pk-rund svg { width: 18px; height: 18px; }
.pk-rund:hover { border-color: var(--ink-4); }
.pk-rund.ist-gefahr { color: #b91c1c; border-color: #f2b8b8; }
.pk-rund.ist-gefahr:hover { background: #b91c1c; border-color: #b91c1c; color: #fff; }
.pk-zeile-pfeil {
    width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; flex: none;
    border-radius: 50%; background: var(--surface); color: var(--ink); font-size: 18px; text-decoration: none;
}
.pk-zeile-pfeil:hover { text-decoration: none; color: var(--ink); }
@media (hover: hover) {
    .pk-zeile .pk-zeile-aktionen { opacity: 0; transition: opacity 0.12s; }
    .pk-zeile:hover .pk-zeile-aktionen, .pk-zeile:focus-within .pk-zeile-aktionen { opacity: 1; }
}

.pk-system {
    display: flex; align-items: center; gap: var(--s-14); padding: var(--s-16) var(--s-18); border: 1px dashed var(--line-2);
    border-radius: 20px; background: var(--surface); color: var(--ink); text-decoration: none;
}
.pk-system:hover { text-decoration: none; border-color: var(--ink-4); color: var(--ink); }
.pk-system .icon { flex: 0 0 auto; margin: 0; }
.pk-system-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.pk-system-text b { font-size: 16px; font-weight: 800; }
.pk-system-text span { font-size: 13px; color: var(--ink-3); }

@media (max-width: 640px) {
    .pk-kopf { gap: var(--s-12); margin-bottom: var(--s-18); }
    .pk-kopf h1 { font-size: 34px; }
    .pk-reiter { order: 9; flex: 1 1 100%; }
    .pk-reiter a { flex: 1 0 auto; padding: 0 var(--s-12); font-size: 14px; }
    .pk-neu { min-height: 48px; padding: 0 var(--s-18); font-size: 15px; }
    .pk-leiste { gap: var(--s-8) var(--s-12); margin-bottom: var(--s-18); }
    .pk-leiste .leader-filter { width: 100%; }
    .pk-zuerst { gap: var(--s-10); margin-bottom: var(--s-18); }
    .pk-kachel { min-height: 80px; gap: var(--s-14); padding: var(--s-14) var(--s-16); border-radius: 20px; }
    .pk-kachel-zahl { font-size: 34px; }
    .pk-kachel-text b { font-size: 16px; }
    .pk-kachel-text span { font-size: 13px; }
    .pk-kachel-pfeil { width: 40px; height: 40px; }
    .pk-karten { gap: var(--s-14); }
    .pk-karte-kopf { min-height: 92px; padding: var(--s-16) 64px var(--s-16) var(--s-18); }
    .pk-name { font-size: 21px; }
    .pk-rumpf { padding: var(--s-16) var(--s-18) var(--s-18); gap: var(--s-14); }
    .pk-tage { gap: var(--s-4); }
    .pk-tag { height: 50px; border-radius: 12px; font-size: 11px; }
    .pk-neu-kachel { min-height: 120px; }
    .pk-zeile { grid-template-columns: 12px minmax(0, 1fr) auto; gap: var(--s-8) var(--s-12); padding: var(--s-12) var(--s-12) var(--s-12) var(--s-16); }
    .pk-zeile-zeit, .pk-zeile-std, .pk-zeile .pk-zeile-pfeil { display: none; }
    .pk-nur-handy { display: inline; }
    .pk-zeile-name > a { font-size: 16px; }
}

/* ---------------------------------------------------------------------------
   Teil 2 · Die geteilten Bausteine in derselben Sprache
   --------------------------------------------------------------------------- */

/* Seitenkopf: der Name groß, alles Weitere in derselben Zeile. */
.page-head,
.admin-toolbar { align-items: center; gap: var(--s-16) var(--s-24); margin: var(--s-24) 0 var(--s-18); }
.page-head h1,
.admin-toolbar h1 { font-size: 44px; font-weight: 800; letter-spacing: -0.035em; line-height: 1; overflow-wrap: anywhere; }
/* Arbeitsansichten mit Raster: Der Name bleibt kräftig, lässt dem Raster aber Platz. */
.page-head.compact { margin: var(--s-18) 0 var(--s-4); }
.page-head.compact h1 { font-size: 30px; }
.page-head .ph-side { display: flex; align-items: center; gap: var(--s-10); flex-wrap: wrap; text-align: left; }
/* Der Eyebrow wiederholt, was Titel und Leiste schon sagen. */
.page-head .eyebrow,
.admin-toolbar .eyebrow { display: none; }
.page-head .subtabs, .admin-toolbar .subtabs, .page-head .view-switcher { margin: 0; }

/* Reiter: eine Pillen-Gruppe, der aktive Reiter liegt hell obenauf. */
.subnav,
.subtabs,
.view-switcher {
    display: inline-flex; flex-wrap: nowrap; align-items: center; gap: var(--s-6); padding: var(--s-6);
    border: 0; border-radius: 999px; background: var(--paper-2);
    width: fit-content; max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
.subnav::-webkit-scrollbar, .subtabs::-webkit-scrollbar, .view-switcher::-webkit-scrollbar { display: none; }
.subnav a,
.subtabs a,
.view-switcher a {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center; gap: var(--s-6);
    padding: 0 var(--s-18); border-radius: 999px; white-space: nowrap;
    color: var(--ink-2); font-size: 15px; font-weight: 700; text-decoration: none; background: none;
}
.subnav a:hover, .subtabs a:hover, .view-switcher a:hover { color: var(--ink); background: none; text-decoration: none; }
.subnav a.active, .subtabs a.active, .view-switcher a.active,
.subnav a[aria-current="page"], .subtabs a[aria-current="page"] {
    background: var(--surface); color: var(--ink); box-shadow: 0 1px 3px rgba(20, 17, 12, 0.14);
}
.subtabs { margin: 0 0 var(--s-24); }

/* Blättern: runde Knöpfe in Daumengröße, der Zeitraum daneben. */
.weeknav { gap: var(--s-10) var(--s-16); margin: var(--s-4) 0 var(--s-18); }
.weeknav .wn-group { gap: var(--s-6); border: 0; border-radius: 0; background: none; overflow: visible; }
.weeknav .wn-group a, .weeknav .wn-group button {
    min-width: 44px; height: 44px; justify-content: center; padding: 0 var(--s-14);
    border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
    color: var(--ink); font-size: 14px; font-weight: 700;
}
.weeknav .wn-group a + a, .weeknav .wn-group a + button { border-left: 1px solid var(--line-2); }
.weeknav .wn-group a:hover, .weeknav .wn-group button:hover { background: var(--surface); border-color: var(--ink-4); color: var(--ink); }
.weeknav .wn-group a.active { background: var(--ink); border-color: var(--ink); color: #fff; }
.weeknav .wn-label { font-size: 13px; }
.weeknav .wn-label strong { font-weight: 600; }

/* Knöpfe: ruhig, rund, groß genug für den Daumen. Kein Glanz, kein Hüpfen. */
.btn {
    min-height: 44px; justify-content: center; gap: var(--s-8); padding: 0 var(--s-18);
    font-size: 15px; font-weight: 700; transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.btn::before { content: none; }
.btn:hover, .btn:active { transform: none; }
.btn:hover { background: #2e2920; border-color: #2e2920; color: #fff; }
.btn-primary { min-height: 48px; padding: 0 var(--s-24); background: var(--accent-2); border-color: var(--accent-2); font-weight: 800; box-shadow: none; }
.btn-primary:hover { background: #9c1849; border-color: #9c1849; }
.btn-secondary { background: var(--surface); border-color: var(--line-2); color: var(--ink); box-shadow: none; }
.btn-secondary:hover { background: var(--surface); border-color: var(--ink-4); color: var(--ink); }
.btn-sm { min-height: 40px; padding: 0 var(--s-16); font-size: 14px; }
.btn-primary.btn-sm { min-height: 44px; padding: 0 var(--s-18); font-size: 15px; }
.btn svg { width: 18px; height: 18px; }

/* Suche und Filter: ein rundes Feld auf Papier. */
.pool-search,
.toolbar-row input[type="search"],
.toolbar-row input[type="text"] {
    height: 48px; padding: 0 var(--s-18); border: 1px solid var(--line-2); border-radius: 999px;
    background: var(--surface); font-size: 16px; color: var(--ink);
}
.pool-search:focus,
.toolbar-row input[type="search"]:focus,
.toolbar-row input[type="text"]:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-paper); }
.leader-filter select { min-height: 44px; border-radius: 999px; font-size: 15px; font-weight: 600; }

/* Tabellen: jede Zeile eine helle Karte mit feiner Linie — dieselbe Fläche wie die
   Kacheln der Startseite und die Projektkarten. Die erste Spalte trägt den Namen.
   Kein Kasten um das Ganze — die Zeilen sind die Liste. */
.data-table {
    border: 0; border-radius: 0; background: none; box-shadow: none; overflow: visible;
    border-collapse: separate; border-spacing: 0 var(--s-10);
}
.data-table th {
    padding: 0 var(--s-16) 0; border: 0; background: none;
    font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: 0.12em; color: var(--ink-3);
}
.data-table td {
    padding: var(--s-14) var(--s-16); font-size: 15px; background: var(--surface);
    border: 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.data-table td:first-child { padding-left: var(--s-18); border-left: 1px solid var(--line); border-radius: 18px 0 0 18px; }
.data-table td:last-child  { padding-right: var(--s-18); border-right: 1px solid var(--line); border-radius: 0 18px 18px 0; }
.data-table td:only-child  { border-radius: 18px; }
.data-table tbody tr:hover { background: none; }
.data-table tbody tr:hover td { background: var(--paper); border-color: var(--line-2); }
.data-table tbody tr:last-child td { border-bottom: 1px solid var(--line); }
.data-table td strong, .data-table td > a:first-child { font-size: 16px; font-weight: 800; color: var(--ink); }

/* Kürzel einer Person: ein Kreis mit den Anfangsbuchstaben, in einer von sechs
   ruhigen Tönungen (aus dem Namen gerechnet — dieselbe Person hat überall dieselbe).
   Baustein: person_kreis() in includes/helpers.php. */
.pkreis {
    flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: 50%; overflow: hidden;
    background: var(--paper-2); color: var(--ink-2);
    font-size: 13px; font-weight: 800; letter-spacing: 0.02em; line-height: 1; text-transform: uppercase;
}
/* Konto-Knopf in der Kopfzeile: Profilbild über dem Kürzel, wenn es eines gibt. */
.konto-trigger { position: relative; overflow: hidden; }
.konto-bild { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
/* Das Profilbild liegt ÜBER dem Kürzel: Fällt es aus, bleibt das Kürzel stehen. */
.pkreis { position: relative; }
.pkreis img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.pkreis-1 { background: var(--accent-soft); }
.pkreis-2 { background: rgba(0, 164, 214, 0.15); }
.pkreis-3 { background: rgba(245, 196, 19, 0.24); }
.pkreis-4 { background: rgba(31, 138, 76, 0.15); }
.pkreis-5 { background: rgba(91, 70, 201, 0.13); }
.pkreis-gross { width: 56px; height: 56px; font-size: 19px; }
/* Name mit Kürzel davor — in Listen und im Seitenkopf der Person. */
.mit-kreis { display: inline-flex; align-items: center; gap: var(--s-12); min-width: 0; }
.page-head h1.mit-kreis { display: flex; flex-wrap: wrap; }

/* Karten und Abschnitte: dieselbe Rundung wie die Projektkarte, flach statt schwebend. */
.form-section,
.empty-state,
.stat-card { border-radius: 24px; box-shadow: none; }
.form-section:focus-within { transform: none; box-shadow: none; border-color: var(--line-2); }
.form-section h2 { font-size: 20px; font-weight: 800; letter-spacing: -0.02em; }
.stat-card:hover { transform: none; box-shadow: none; }

/* Der Name in einer Listen-Zeile: kräftig, führt zur Sache selbst. */
.zeile-name { font-size: 17px; font-weight: 800; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.zeile-name:hover { color: var(--accent-2); text-decoration: underline; }

/* Kennzahlen: dieselbe Ruhe wie die Kacheln der Projektübersicht — Zahl groß,
   Bezeichnung daneben, kein Farbpunkt, kein Schweben. */
.stat-card { background: var(--surface); border: 1px solid var(--line); }
.stat-card::before { content: none; }
.stat-card .stat-val { font-family: var(--font-mono); font-weight: 500; letter-spacing: -0.02em; color: var(--ink); }
.stat-card .stat-lbl { color: var(--ink-2); }
/* Am Handy sind die Kennzahlen Zeilen in EINER Karte (Regel weiter oben). Die Ausnahme
   steht hier noch einmal, HINTER der Regel für die Kachel — bei gleicher Spezifität
   gewinnt die spätere, und sonst wird jede Zeile wieder eine eigene runde Fläche. */
@media (max-width: 560px) {
    .stat-card { background: transparent; border: 0; border-top: 1px solid var(--line); border-radius: 0; }
    .stat-card:first-child { border-top: 0; }
}

@media (max-width: 640px) {
    /* Am Handy trägt die Zeile nur, was man zum Wiederfinden braucht. Kontakt,
       Skills und Stundenlimit stehen auf der Personenseite. */
    .data-table .col-2nd { display: none; }
    .table-scroll > .data-table-kurz { min-width: 0; }
    /* Am Handy gehört die Breite dem Namen: Die übrigen Spalten nehmen nur, was sie
       brauchen, und das Kürzel entfällt — sonst bricht ein Name mitten im Wort. */
    .data-table-kurz td:not(:first-child), .data-table-kurz th:not(:first-child) { width: 1%; white-space: nowrap; }
    .data-table-kurz .pkreis { display: none; }
    /* Aushilfen: Der eine Knopf der Seite geht über die ganze Breite. */
    body[data-role="aushilfe"] .page-head .pk-neu { flex: 1 1 100%; justify-content: center; }
    body[data-role="aushilfe"] .page-head .pk-luft { display: none; }
    .page-head, .admin-toolbar { gap: var(--s-12); margin: var(--s-16) 0 var(--s-14); }
    .page-head h1, .admin-toolbar h1 { font-size: 34px; }
    .page-head.compact h1 { font-size: 24px; }
    .subnav a, .subtabs a, .view-switcher a { padding: 0 var(--s-12); font-size: 14px; }
    .subtabs { display: inline-flex; width: fit-content; max-width: 100%; margin-bottom: var(--s-18); }
    .subtabs a { flex: 0 0 auto; }
    .btn-primary { min-height: 48px; }
    .data-table td { padding: var(--s-12); font-size: 14px; }
    .data-table td:first-child { padding-left: var(--s-16); }
}

/* ============================================================================
   ZEILEN-MENÜ — ein Knopf je Zeile statt einer Knopfreihe
   ----------------------------------------------------------------------------
   Markup: includes/_zeilen-menue.php. Der Knopf öffnet die Aktionen der Zeile im
   Blatt (.blatt, weiter oben). Die Zeile sagt, WER — was man mit ihr tun kann,
   muss nicht in jeder Zeile stehen.
   ============================================================================ */
/* position: relative — die versteckte Spaltenüberschrift (.sr-hint) ist absolut
   gesetzt und entkäme sonst dem Rahmen der Tabelle. */
.zm-zelle { width: 1%; text-align: right; white-space: nowrap; position: relative; }
.zm-knopf {
    width: 40px; height: 40px; padding: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-2); background: var(--surface); color: var(--ink-2);
    cursor: pointer; transition: border-color .14s, color .14s, background .14s;
}
.zm-knopf:hover { border-color: var(--ink-4); color: var(--ink); background: var(--paper); }
.zm-knopf .ksym { width: 20px; height: 20px; fill: currentColor; }
.zm-liste { display: flex; flex-direction: column; gap: var(--s-6); }
.zm-liste form { margin: 0; display: flex; flex-direction: column; }
.zm-akt {
    display: flex; align-items: center; gap: var(--s-10); width: 100%; min-height: 48px;
    padding: var(--s-10) var(--s-14); border: 1px solid var(--line); border-radius: 12px;
    background: var(--paper); color: var(--ink); font: inherit; font-size: 15px; font-weight: 600;
    text-align: left; text-decoration: none; cursor: pointer;
}
.zm-akt:hover { background: var(--paper-2); border-color: var(--line-2); }
.zm-akt.zm-heikel { color: var(--accent-2); }
.zm-neben { margin-left: auto; font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: var(--ink-3); }

/* ============================================================================
   OFFENE PUNKTE — was die Planung zu tun hat (produktion/offene-punkte.php)
   ----------------------------------------------------------------------------
   Je Zeile ein Knopf. Rechnung: includes/heute.php. Rot = brennt (heute/morgen,
   falsch geplant), Gelb = steht an, ohne Farbe = Hinweis. Die Startseite zeigt
   davon die ersten vier in einer Kachel (Abschnitt START).
   ============================================================================ */
.ht-datum { font-family: var(--font-mono); font-size: 13px; color: var(--ink-3); }
.ht-block { margin-top: var(--s-24); max-width: 880px; }
.ht-zahl {
    letter-spacing: 0; padding: 1px var(--s-8); border-radius: 999px;
    background: var(--ink); color: var(--paper); font-weight: 500;
}
.ht-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-6); }
.ht-zeile {
    display: flex; align-items: center; gap: var(--s-12); min-height: 64px;
    padding: var(--s-10) var(--s-12) var(--s-10) var(--s-16);
    background: var(--surface); border: 1px solid var(--line); border-radius: 16px;
}
.ht-punkt { flex: 0 0 10px; width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }
.ht-rot .ht-punkt  { background: var(--accent); }
.ht-gelb .ht-punkt { background: var(--y); }
.ht-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.ht-text b { font-size: 15px; font-weight: 700; line-height: 1.3; }
.ht-text span { font-size: 13px; color: var(--ink-3); }
.ht-knopf { flex: 0 0 auto; }
.ht-neben {
    flex: 0 0 auto; min-height: 40px; display: inline-flex; align-items: center;
    padding: 0 var(--s-4); font-size: 13px; font-weight: 600; color: var(--accent-2); text-decoration: none;
}
.ht-neben:hover { text-decoration: underline; }
.ht-frei { margin: 0; font-size: 14px; color: var(--ink-3); }

@media (max-width: 640px) {
    /* Text über die volle Breite, der Knopf rutscht darunter — sonst bleibt dem Text
       neben einem breiten Knopf keine lesbare Zeile. */
    .ht-zeile { flex-wrap: wrap; }
    .ht-text { flex-basis: calc(100% - var(--s-24)); }
    .ht-punkt + .ht-text { flex-basis: calc(100% - var(--s-32)); }
    /* bündig mit dem Text: Punkt (10px) + Abstand */
    .ht-knopf, .ht-neben { margin-left: calc(10px + var(--s-12)); }
}

/* Stand des Plan-Versands im Kopf der Planung: ein ruhiger Verweis; Farbe nur, wenn
   die Aushilfen etwas noch nicht wissen. */
.plan-stand {
    display: inline-flex; align-items: center; min-height: 32px; padding: 0 var(--s-12); border-radius: 999px;
    border: 1px solid var(--line); background: var(--surface); color: var(--ink-3);
    font-size: 12px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.plan-stand:hover { border-color: var(--line-2); color: var(--ink); text-decoration: none; }
.plan-stand.ist-offen { border-color: var(--accent-2); color: var(--accent-2); }

/* ============================================================================
   START — die Kacheln der Planung (produktion/index.php)
   ----------------------------------------------------------------------------
   Jede Kachel ist eine Vorschau auf einen Ort: Kopf (Symbol, Name, eine Zeile
   Stand, Zahl) und darunter ein Ausschnitt mit echten Daten. Die ganze Kachel
   ist das Ziel (.hubk-link::after liegt über ihr); Zeilen darin sind eigene
   Ziele und liegen darüber. „Kompakt" zeigt nur die Köpfe als Liste.
   Rechnung: includes/hub-kacheln.php, Umschalter: assets/js/hub.js.

   Drei, zwei oder eine Spalte — nach der Breite des Rasters, nicht des Fensters
   (links steht je nach Gerät das Menü). Der Normalfall bleibt ohne Farbe; Farbe
   bekommt nur, was fehlt oder brennt.
   ============================================================================ */
.hub-schalter {
    display: inline-flex; gap: var(--s-2); padding: var(--s-2);
    border: 1px solid var(--line); border-radius: 999px; background: var(--paper-2);
}
.hub-schalter button {
    min-height: 40px; padding: 0 var(--s-14); border: 0; border-radius: 999px; background: transparent;
    font: inherit; font-size: 13px; font-weight: 600; color: var(--ink-3); cursor: pointer;
}
.hub-schalter button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(20, 17, 12, 0.1); }

/* Gruß über dem Seitennamen — der Markenton gehört auf die Einstiegsseite. Der Name
   in der Handschrift ist groß genug, dass die Akzentfarbe als Großschrift zählt. */
.hub-kopf { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.hub-gruss { font-size: 15px; color: var(--ink-3); }
.hub-gruss .hand { font-size: 26px; line-height: 1; transform: rotate(-2deg) translateY(2px); }
.hub { container-type: inline-size; max-width: 1180px; margin-top: var(--s-18); }
/* align-items: start — jede Kachel ist so hoch wie ihr Inhalt, keine wird auf die
   Höhe der Nachbarin gestreckt. */
.hub-raster { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: var(--s-16); align-items: start; }

.hubk {
    position: relative; display: flex; flex-direction: column; gap: var(--s-12); min-width: 0;
    padding: var(--s-16); border: 1px solid var(--line); border-radius: 20px; background: var(--surface);
    transition: transform 0.16s var(--ease-out), box-shadow 0.16s var(--ease-out), border-color 0.16s;
}
/* Zwei Spalten breit — erst, wenn es zwei Spalten gibt. Sonst entstünde am Handy
   eine zweite Spalte neben der Seite. */
@container (min-width: 680px) { .hubk-breit { grid-column: span 2; } }
@media (hover: hover) {
    .hubk:hover { transform: translateY(-2px); border-color: var(--line-2); box-shadow: 0 10px 24px rgba(20, 17, 12, 0.07); }
}
@media (prefers-reduced-motion: reduce) {
    .hubk { transition: none; }
    .hubk:hover { transform: none; }
}

.hubk-kopf {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; column-gap: var(--s-12); align-items: center;
    grid-template-areas: "ico titel zahl pfeil" "ico kurz zahl pfeil";
}
.hubk-ico {
    grid-area: ico; width: 40px; height: 40px; display: grid; place-items: center;
    border-radius: 12px; background: var(--paper-2); color: var(--ink-2);
}
.hubk-ico svg { width: 20px; height: 20px; }
/* Je Kachel ein Hauch der Farbfamilie — nur das Symbolfeld, nicht die Kachel. */
.hubk-ico.ist-m { background: var(--accent-soft); }
.hubk-ico.ist-c { background: rgba(0, 164, 214, 0.13); }
.hubk-ico.ist-y { background: rgba(245, 196, 19, 0.2); }
.hubk-ico.ist-g { background: rgba(31, 138, 76, 0.13); }
.hubk-titel { grid-area: titel; margin: 0; font-size: 16px; font-weight: 800; line-height: 1.25; letter-spacing: -0.01em; }
.hubk-link { color: inherit; text-decoration: none; }
.hubk-link:hover { color: inherit; text-decoration: none; }
.hubk-link::after { content: ""; position: absolute; inset: 0; border-radius: 20px; }
.hubk-link:focus-visible { outline: none; }
.hubk-link:focus-visible::after { outline: 2px solid var(--ink); outline-offset: 2px; }
.hubk-kurz { grid-area: kurz; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--ink-3); }
.hubk-zahl {
    grid-area: zahl; min-width: 28px; padding: var(--s-2) var(--s-8); border-radius: 999px; text-align: center;
    background: var(--ink); color: var(--paper); font-family: var(--font-mono); font-size: 12px; font-weight: 500;
}
.hubk-zahl.ist-warn, .hat-dringend .hubk-zahl { background: var(--accent-2); color: #fff; }
.hubk-pfeil { grid-area: pfeil; display: inline-flex; color: var(--ink-4); }
.hubk-pfeil svg { width: 18px; height: 18px; transform: rotate(-90deg); }

.hubk-inhalt { display: flex; flex-direction: column; gap: var(--s-8); min-width: 0; }
/* Ziele in der Vorschau liegen über dem Ziel der Kachel. */
.hubk-inhalt a { position: relative; z-index: 1; }
.hubk-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.hubk-liste li + li { border-top: 1px solid var(--line); }
.hubk-zeile {
    display: flex; align-items: center; gap: var(--s-10); min-height: 48px; padding: var(--s-6) var(--s-4);
    border-radius: 10px; color: var(--ink); text-decoration: none;
}
a.hubk-zeile:hover { background: var(--paper-2); color: var(--ink); text-decoration: none; }
.hubk-punkt { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--line-2); }
.ist-rot > .hubk-punkt  { background: var(--accent); }
.ist-gelb > .hubk-punkt { background: var(--y); }
.hubk-farbe { flex: 0 0 6px; width: 6px; height: 28px; border-radius: 3px; }
.hubk-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.hubk-text b { font-size: 14px; font-weight: 700; line-height: 1.3; overflow-wrap: anywhere; }
.hubk-text b.hubk-normal { font-weight: 500; }
.hubk-text span { font-size: 12px; color: var(--ink-3); }
.hubk-text .hubk-mono { font-family: var(--font-mono); }
.hubk-text .hubk-hinweis { color: var(--accent-2); font-weight: 600; }
.hubk-pin { display: inline-flex; vertical-align: -2px; color: var(--ink-4); }
.hubk-pin svg { width: 13px; height: 13px; }
.hubk-tun { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--accent-2); white-space: nowrap; }
.hubk-wert { flex: 0 0 auto; font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; color: var(--ink-3); white-space: nowrap; }
.hubk-wert.fehlt { color: var(--accent-2); font-weight: 700; }
.hubk-leer { margin: 0; font-size: 13px; color: var(--ink-3); }
.hubk-fuss { margin: 0; font-size: 12px; color: var(--ink-4); }
.hubk-mehr {
    align-self: flex-start; min-height: 40px; display: inline-flex; align-items: center;
    font-size: 13px; font-weight: 600; color: var(--accent-2); text-decoration: none;
}
.hubk-mehr:hover { text-decoration: underline; }

/* Woche: eine Säule je Tag, gefüllt bis zum Anteil der besetzten Plätze. */
.hubw { position: relative; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--s-6); align-items: end; }
.hubw-tag { display: flex; flex-direction: column; align-items: center; gap: var(--s-4); min-width: 0; }
.hubw-fehlt { min-height: 16px; font-family: var(--font-mono); font-size: 11px; font-weight: 700; color: var(--accent-2); }
.hubw-saeule { position: relative; width: 100%; max-width: 30px; height: 56px; border-radius: 8px; background: var(--paper-2); overflow: hidden; }
.hubw-saeule i { position: absolute; left: 0; right: 0; bottom: 0; background: var(--success); }
.hubw-tag.hat-luecke .hubw-saeule i { background: var(--accent); }
.hubw-tag.ist-leer .hubw-saeule { background: transparent; border: 1px dashed var(--line-2); box-sizing: border-box; }
.hubw-tag.ist-vorbei { opacity: 0.5; }
.hubw-name { font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
.hubw-tag.ist-heute .hubw-name { padding: 0 var(--s-6); border-radius: 999px; background: var(--ink); color: var(--paper); }

/* Aushilfen: drei Zahlen, keine Namen. */
.hubk-werte { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-8); margin: 0; }
.hubk-werte div { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; padding: var(--s-10); border-radius: 12px; background: var(--paper); }
.hubk-werte dt { font-size: 12px; line-height: 1.3; color: var(--ink-3); overflow-wrap: anywhere; }
/* Die Zahl steht oben (order), im Markup aber nach ihrer Bezeichnung — so liest sie
   ein Vorleseprogramm richtig herum, und die Zahlen stehen auf einer Linie. */
.hubk-werte dd { order: -1; margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.hubk-werte .ist-offen dd { color: var(--accent-2); }

/* Kalender: die nächsten Tage als Balken je Projekt, Liefertage als Raute. */
.hubkal { display: flex; flex-direction: column; gap: var(--s-8); min-width: 0; }
.hubkal-achse, .hubkal-spur { display: grid; grid-template-columns: repeat(var(--hubkal-tage, 14), minmax(0, 1fr)); }
.hubkal-tag {
    display: flex; flex-direction: column; align-items: center; padding: var(--s-2) 0; border-radius: 8px;
    font-family: var(--font-mono); font-size: 11px; line-height: 1.3; color: var(--ink-2);
}
.hubkal-tag i { font-style: normal; color: var(--ink-3); }
.hubkal-tag.ist-we { color: var(--ink-4); }
.hubkal-tag.ist-we i { color: var(--ink-4); }
.hubkal-tag.ist-heute, .hubkal-tag.ist-heute i { background: var(--ink); color: var(--paper); }
.hubkal-zeile { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.hubkal-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; color: var(--ink-2); }
.hubkal-spur { position: relative; align-items: center; height: 14px; border-radius: 7px; background: var(--paper-2); }
.hubkal-balken { grid-row: 1; height: 14px; border-radius: 7px; }
.hubkal-balken.offen-l { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.hubkal-balken.offen-r { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.hubkal-lieferung {
    position: relative; z-index: 1; grid-row: 1; justify-self: center; box-sizing: border-box; width: 10px; height: 10px;
    border: 2px solid var(--ink); background: var(--surface); transform: rotate(45deg);
}
.hubkal-legende { display: inline-flex; align-items: center; gap: var(--s-6); margin-right: var(--s-10); }

/* Kompakt: nur die Köpfe, als eine Liste. */
.hub[data-ansicht="kompakt"] { max-width: 760px; }
.hub[data-ansicht="kompakt"] .hub-raster {
    grid-template-columns: minmax(0, 1fr); gap: 0; overflow: hidden;
    border: 1px solid var(--line); border-radius: 20px; background: var(--surface);
}
.hub[data-ansicht="kompakt"] .hubk {
    justify-content: center; min-height: 64px; padding: var(--s-12) var(--s-16);
    border: 0; border-radius: 0; box-shadow: none; transform: none;
}
.hub[data-ansicht="kompakt"] .hubk + .hubk { border-top: 1px solid var(--line); }
.hub[data-ansicht="kompakt"] .hubk:hover { background: var(--paper); }
.hub[data-ansicht="kompakt"] .hubk-breit { grid-column: auto; }
.hub[data-ansicht="kompakt"] .hubk-link::after { border-radius: 0; }
.hub[data-ansicht="kompakt"] .hubk-inhalt { display: none; }

/* ============================================================================
   VERLAUF — wer hat was wann geändert (produktion/verlauf.php)
   ----------------------------------------------------------------------------
   Nach Tagen gebündelt, je Eintrag Uhrzeit, Symbol der Art, der Satz und darunter
   Projekt und wer. Ein verschickter Plan ist eine Linie: Was darüber steht, kam
   danach. Rechnung: includes/verlauf.php.
   ============================================================================ */
.vl-filter { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-8); margin-top: var(--s-18); max-width: 880px; }
/* 16px: darunter zoomt iOS beim Antippen in das Feld hinein. */
.vl-suche {
    flex: 1 1 220px; min-width: 0; min-height: 44px; padding: 0 var(--s-14);
    border: 1px solid var(--line-2); border-radius: 12px; background: var(--surface); color: var(--ink); font: inherit; font-size: 16px;
}
.vl-arten { display: inline-flex; gap: var(--s-2); padding: var(--s-2); border: 1px solid var(--line); border-radius: 999px; background: var(--paper-2); }
.vl-arten a {
    min-height: 40px; display: inline-flex; align-items: center; padding: 0 var(--s-14); border-radius: 999px;
    font-size: 13px; font-weight: 600; color: var(--ink-3); text-decoration: none;
}
.vl-arten a.active { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(20, 17, 12, 0.1); }
.vl-stand { margin: var(--s-12) 0 0; font-size: 13px; color: var(--ink-3); }
.vl-stand a { margin-left: var(--s-8); color: var(--accent-2); font-weight: 600; }
.vl { max-width: 880px; margin-top: var(--s-18); display: flex; flex-direction: column; gap: var(--s-24); }
.vl-tag-name {
    margin: 0 0 var(--s-8); font-family: var(--font-mono); font-size: 11px; font-weight: 700;
    letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3);
}
.vl-liste { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: 16px; background: var(--surface); overflow: hidden; }
.vl-zeile { display: grid; grid-template-columns: 44px 24px minmax(0, 1fr); column-gap: var(--s-10); align-items: start; padding: var(--s-10) var(--s-14); }
.vl-zeile + .vl-zeile { border-top: 1px solid var(--line); }
.vl-zeit { padding-top: var(--s-2); font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.vl-ico { display: inline-flex; padding-top: var(--s-2); color: var(--ink-4); }
.vl-ico svg { width: 18px; height: 18px; }
.vl-text { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.vl-text b { font-size: 14px; font-weight: 500; line-height: 1.4; overflow-wrap: anywhere; }
.vl-text span { font-size: 12px; color: var(--ink-3); }
.vl-text a { color: var(--ink-2); font-weight: 600; text-decoration: none; }
.vl-text a:hover { color: var(--accent-2); text-decoration: underline; }
.vl-versand { background: var(--paper-2); }
.vl-versand .vl-text b { font-weight: 700; }
.vl-versand .vl-ico { color: var(--ink); }
/* Vorschau in der Übersicht eines Projekts: dieselbe Liste, darunter der Weg zum Ganzen. */
.vl-vorschau { max-width: 760px; display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-14); }
.vl-vorschau > .vl { align-self: stretch; margin-top: var(--s-14); }
.vl-leer { max-width: 880px; margin-top: var(--s-24); display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-12); color: var(--ink-3); font-size: 14px; }
.vl-leer p { margin: 0; }
.vl-seiten { max-width: 880px; margin-top: var(--s-18); display: flex; justify-content: space-between; gap: var(--s-8); }

/* ============================================================================
   SUCHE — Aushilfen, Projekte, Funktionen
   ----------------------------------------------------------------------------
   Fenster oben in der Mitte (nicht unten: dort läge am Handy die Tastatur).
   Markup: includes/_suche.php, Skript: assets/js/suche.js. Die Treffer benutzen
   die Zeilen des Zeilen-Menüs (.zm-akt).
   ============================================================================ */
.suche {
    position: fixed; z-index: 1201; top: var(--s-32); left: 50%; transform: translateX(-50%);
    width: 560px; max-width: calc(100vw - 2 * var(--s-16)); max-height: calc(100vh - 2 * var(--s-32));
    box-sizing: border-box; display: flex; flex-direction: column; gap: var(--s-12);
    padding: var(--s-14); border-radius: 20px;
    background: var(--surface); color: var(--ink); box-shadow: 0 24px 60px rgba(20, 17, 12, 0.28);
}
.suche[hidden] { display: none; }
.suche-kopf { display: flex; align-items: center; gap: var(--s-10); }
.suche-ico { flex: 0 0 auto; display: inline-flex; color: var(--ink-3); }
.suche-ico svg { width: 20px; height: 20px; }
/* 16px: darunter zoomt iOS beim Antippen in das Feld hinein. */
.suche-feld {
    flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 var(--s-4);
    border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 16px;
}
.suche-feld:focus { outline: none; }
.suche-liste { display: flex; flex-direction: column; gap: var(--s-4); overflow-y: auto; min-height: 0; }
.suche-treffer { flex-wrap: wrap; gap: var(--s-2) var(--s-10); }
.suche-treffer.ist-gewaehlt { background: var(--paper-2); border-color: var(--ink); }
.suche-titel { min-width: 0; overflow-wrap: anywhere; }
.suche-unter { font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: var(--ink-3); }
.suche-leer { margin: 0; padding: var(--s-10) var(--s-4); font-size: 14px; color: var(--ink-3); }
@media (max-width: 640px) {
    .suche { top: var(--s-8); max-height: calc(100vh - 2 * var(--s-8)); border-radius: 16px; }
}

/* ============================================================================
   EINSTELLUNGEN — Liste der Abschnitte, daneben der Abschnitt
   ----------------------------------------------------------------------------
   Markup: render_einstellungen_nav() / einstellungen_ende() in includes/helpers.php.
   Am Schreibtisch steht die Liste links. Am Handy steht sie allein; data-offen am
   Rahmen sagt, welcher Abschnitt offen ist (leer = Liste zeigen).
   ============================================================================ */
.einst {
    display: grid; grid-template-columns: 216px minmax(0, 1fr); gap: var(--s-24);
    align-items: start; margin-top: var(--s-16);
}
.einst-nav { display: flex; flex-direction: column; gap: var(--s-2); position: sticky; top: 104px; }
.einst-nav a {
    display: flex; align-items: center; justify-content: space-between; gap: var(--s-8);
    min-height: 42px; padding: var(--s-6) var(--s-12); border-radius: 10px;
    font-size: 14px; font-weight: 600; color: var(--ink-2); text-decoration: none;
}
.einst-nav a:hover { background: var(--surface); color: var(--ink); }
.einst-nav a.active { background: var(--paper-2); color: var(--ink); }
.einst-pfeil { display: none; font-size: 20px; line-height: 1; color: var(--ink-3); }
/* Gruppen in der Liste: Team, Planung, Benachrichtigungen, Verbindungen, Daten, System. */
.einst-gruppe {
    margin: var(--s-14) 0 var(--s-2); padding: 0 var(--s-12); font-family: var(--font-mono); font-size: 11px; font-weight: 700;
    letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-4);
}
.einst-gruppe:first-child { margin-top: 0; }
.einst-inhalt { min-width: 0; }
.einst-zurueck, .einst-titel { display: none; }

@media (max-width: 760px) {
    .einst { display: block; }
    .einst-nav { position: static; gap: var(--s-6); }
    .einst-nav a {
        min-height: 52px; padding: var(--s-6) var(--s-16);
        background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
        font-size: 16px; color: var(--ink);
    }
    /* In der Liste ist nichts „aktiv" — man wählt erst. */
    .einst-nav a.active { background: var(--surface); }
    .einst-pfeil { display: inline; }
    /* Entweder die Liste oder der Abschnitt. */
    .einst[data-offen=""] .einst-inhalt { display: none; }
    .einst:not([data-offen=""]) .einst-nav { display: none; }
    .einst-zurueck {
        display: inline-flex; align-items: center; min-height: 44px; margin-bottom: var(--s-8);
        font-size: 15px; font-weight: 700; color: var(--accent-2); text-decoration: none;
    }
    /* Am Handy sagt diese Zeile, in welchem Abschnitt man ist — die Liste ist dann weg.
       Die kleinen Abschnitts-Überschriften einzelner Abschnitte wären doppelt. */
    .einst-titel { display: block; margin: 0 0 var(--s-14); font-size: 22px; font-weight: 800; letter-spacing: -0.015em; }
    .einst-inhalt .team-panel > h2:first-child { display: none; }
}

/* ============================================================================
   ÜBERSICHT EINES PROJEKTS (produktion/projekt.php)
   ----------------------------------------------------------------------------
   Oben der Stand der Woche — derselbe Baustein wie die Karte in der Projektliste
   (.pk-stand, .pk-tage; includes/_projekt-stand.php). Darunter, was zum Projekt
   gehört: Stationen (ein Knopf je Station, Zeilen-Menü), Lieferdaten, die letzten
   Änderungen und zuletzt die Stammdaten.
   ============================================================================ */
.pu-titel { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s-8) var(--s-12); }
.pu-farbe { flex: 0 0 auto; width: 16px; height: 16px; border-radius: 5px; }
.pu-titel .status { font-size: 13px; }
.pu-meta { margin: var(--s-6) 0 0; font-size: 14px; color: var(--ink-3); }
.pu-meta a { margin-left: var(--s-8); color: var(--accent-2); font-weight: 600; text-decoration: none; white-space: nowrap; }
.pu-meta a:hover { text-decoration: underline; }

.pu-woche {
    max-width: 760px; margin-top: var(--s-24); padding: var(--s-18) var(--s-24) var(--s-24);
    display: flex; flex-direction: column; gap: var(--s-16);
    border: 1px solid var(--line); border-radius: 24px; background: var(--surface);
}
.pu-woche-kopf { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-8) var(--s-12); }
.pu-woche-titel { margin: 0; font-size: 18px; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); }
.pu-woche-leer { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; padding: var(--s-16) var(--s-24); font-size: 14px; color: var(--ink-3); }
.pu-woche-leer p { margin: 0; }

.pu-h2 { margin-top: var(--s-32); }
.pu-h2-zahl { font-family: var(--font-mono); font-weight: 400; letter-spacing: 0; color: var(--ink-4); }
.pu-leer-text { max-width: 380px; margin: var(--s-8) auto 0; }

.pu-stationen { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: var(--s-12); align-items: start; }
.pu-station { min-width: 0; padding: var(--s-14) var(--s-14) var(--s-16) var(--s-18); border: 1px solid var(--line); border-radius: 20px; background: var(--surface); }
.pu-station-kopf { display: flex; align-items: center; gap: var(--s-10); }
.pu-punkt { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background: var(--st-farbe, var(--ink-3)); }
.pu-station-name { flex: 1 1 auto; min-width: 0; margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; text-transform: none; color: var(--ink); overflow-wrap: anywhere; }
.pu-station-text { margin: var(--s-6) 0 0; font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.pu-station-wort { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-3); }
.pu-station-fuss { margin: var(--s-4) 0 0; font-size: 13px; color: var(--ink-3); }
.pu-station-form { margin-top: var(--s-14); padding-top: var(--s-14); border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: var(--s-10); }
.pu-station-form[hidden] { display: none; }
.pu-knoepfe { display: flex; flex-wrap: wrap; gap: var(--s-8); margin-top: var(--s-4); }

.pu-lieferungen { display: flex; flex-wrap: wrap; gap: var(--s-8); }
.pu-lieferung {
    display: inline-flex; align-items: center; gap: var(--s-8); padding: var(--s-4) var(--s-4) var(--s-4) var(--s-12);
    border: 1px solid var(--accent); border-radius: 999px; background: var(--accent-paper); font-size: 13px;
}
.pu-lieferung b { font-family: var(--font-mono); font-weight: 600; color: var(--accent-2); }
.pu-lieferung-text { font-size: 12px; color: var(--ink-2); }
.pu-lieferung.ist-vorbei { border-color: var(--line); background: var(--paper-2); }
.pu-lieferung.ist-vorbei b { color: var(--ink-3); }
.pu-lieferung form { display: inline-flex; margin: 0; }
.pu-lieferung button {
    width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%; background: transparent;
    color: var(--ink-3); font-size: 16px; line-height: 1; cursor: pointer;
}
.pu-lieferung button:hover { background: var(--surface); color: var(--accent-2); }

.pu-stamm-zeile { margin: 0; font-size: 13px; color: var(--ink-3); }
.pu-stamm { max-width: 720px; margin-top: var(--s-10); }
.pu-stamm > form { margin-top: var(--s-14); }

@media (max-width: 640px) {
    .pu-woche { padding: var(--s-16) var(--s-16) var(--s-18); }
    /* Titel und Knopf in einer Zeile, die Woche darunter. */
    .pu-woche-kopf .pk-luft { display: none; }
    .pu-woche-titel { flex: 1 1 auto; }
    .pu-woche-kopf .pk-kw { order: 3; flex: 1 0 100%; }
    .pu-woche-leer { padding: var(--s-14) var(--s-16); }
    .pu-lieferung button { width: 36px; height: 36px; }
}

/* ============================================================================
   PLANUNGSRASTER — Stationen × Tage (produktion/planung.php)
   ----------------------------------------------------------------------------
   Die ganze Woche auf einen Blick: feste Spaltenbreiten, Tage ohne Schicht
   schmal (die Seite zählt sie und gibt --pg-voll / --pg-leer mit). Früher bestimmte
   der längste Name die Spaltenbreite — bei 1280 px lag der Sonntag außerhalb.

   Farbe trägt nur, was noch fehlt oder klemmt. Eine besetzte Schicht ist der
   Normalfall und bleibt still:
     (nichts)    Sollzahl nicht erreicht — helle Karte, Belegung als Abzeichen im Akzent
     .full       besetzt — Papierton, Belegung leise
     .ohne-soll  keine Sollzahl (∞) — wie besetzt, ihr fehlt nie jemand
   Ist ein Teil der Schichtzeit von niemandem abgedeckt, steht das leise an der Belegung
   (.shift-coverage.hat-luecke: ein kleiner Punkt; WANN niemand da ist, steht in der
   Hinweiszeile des Docks, sobald die Schicht angetippt ist, und im Vorschlags-Blatt).
   Bis 05.10.2026 war das ein roter Rand und eine rote Zeile im Kasten.
   Die Passungsfarben beim Einteilen (.fit-*, Abschnitt RICHTUNG D) gewinnen über
   ihre höhere Spezifität.

   Dieser Abschnitt steht am ENDE der Datei: Er löst die Regeln ab, die bis
   04.10.2026 im <style> der Seite standen und damit jede gleich starke Regel
   von hier oben überstimmten.
   ============================================================================ */
.planung-grid-wrap {
    background: var(--surface); border: 1px solid var(--line); border-radius: 24px;
    overflow-x: auto;
}
.planung-grid {
    /* 122 px: darunter passen Zeit und Belegung nicht mehr in eine Zeile. Sieben volle
       Tage ergeben 990 px — das passt in ein 1280er-Fenster auch dann, wenn die
       Bildlaufleiste Platz nimmt (dem Raster bleiben dann 995 px; mit 124 px lief es
       dort 9 px in sich). */
    --pg-station: 136px; --pg-tag: 122px; --pg-schmal: 78px;
    width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 0;
    min-width: calc(var(--pg-station) + var(--pg-voll, 7) * var(--pg-tag) + var(--pg-leer, 0) * var(--pg-schmal));
}
.pg-col-station { width: var(--pg-station); }
.pg-col-leer { width: var(--pg-schmal); }
/* Breites Fenster: Die Tage OHNE Schicht wachsen mit (ihren Anteil rechnet die Seite,
   raster_leer_breite()). Sonst teilten sich nur die Tage MIT Schicht den Platz — bei
   zwei von sieben wurde ein Schichtkasten 580 px breit, daneben standen fünf Streifen.
   Darunter bleiben sie schmal, damit die Woche in ein 1280er-Fenster passt. */
@media (min-width: 1440px) {
    .pg-col-leer { width: var(--pg-leer-breit, var(--pg-schmal)); }
}

.planung-grid th, .planung-grid td { border-bottom: 1px solid var(--line); vertical-align: top; }
.planung-grid th, .planung-grid .day-cell { border-right: 1px solid var(--line); }
.planung-grid th:last-child, .planung-grid .day-cell:last-child { border-right: 0; }
.planung-grid td { padding: var(--s-4); }
.planung-grid td.day-cell { position: relative; }

/* --- Kopfzeile: Wochentag kräftig, Datum und Stunden leise --- */
.planung-grid th {
    padding: var(--s-12) var(--s-10) var(--s-10);
    background: var(--surface); text-align: left;
    font-size: 11px; font-weight: 600; color: var(--ink-3); white-space: nowrap; overflow: hidden;
}
/* Die feste Spalte liegt ÜBER allem, was im Raster angehoben wird (gewählte Schicht,
   Ziel beim Ziehen, das × einer Schicht) — sonst schimmert es beim Seitwärts-Scrollen durch. */
.planung-grid .pg-ecke {
    position: sticky; left: 0; z-index: 5;
    padding-left: var(--s-14);
    font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
}
.pg-wtag { font-size: 13px; font-weight: 800; color: var(--ink); }
.planung-grid th .day-date { margin-left: var(--s-4); font-family: var(--font-mono); font-size: 11px; font-weight: 400; color: var(--ink-3); }
.planung-grid th.is-leer .day-date { display: block; margin-left: 0; }
@media (min-width: 1440px) {
    .planung-grid th.is-leer .day-date { display: inline; margin-left: var(--s-4); }
}
/* Heute: Strich unter dem Kopf und zwei feine Linien die Spalte hinunter. */
.planung-grid th.today { box-shadow: inset 0 -3px 0 var(--accent); }
.planung-grid th.today .pg-wtag { color: var(--accent-2); }
.planung-grid .day-cell.is-today { box-shadow: inset 1px 0 0 var(--accent-soft), inset -1px 0 0 var(--accent-soft); }
/* Liefertag: der Kopf ist getönt, das Abzeichen sagt, warum. */
.planung-grid th.delivery { background: var(--accent-paper); }
.planung-grid .delivery-badge { margin-top: var(--s-4); font-size: 10px; font-weight: 700; color: var(--accent-2); }
/* Vergangene Tage und Wochenende treten zurück — ohne dass ihr Inhalt verblasst. */
.planung-grid .is-we, .planung-grid .day-cell.past { background: var(--paper); }

/* Stunden je Tag, je Station und für die Woche. Eine Null ist keine Auskunft:
   Sie bleibt unsichtbar, hält aber ihre Zeile, damit nichts springt. */
.col-hours, .row-hours {
    font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: 0;
    color: var(--ink-3); white-space: nowrap; text-transform: none;
}
.col-hours { margin-top: var(--s-4); }
.row-hours { margin-top: var(--s-6); }
.pg-tag .col-hours[data-mins="0"], .row-hours[data-mins="0"] { visibility: hidden; }
.pg-ecke .col-hours { color: var(--ink); font-weight: 700; }

/* --- Stationsspalte: bleibt beim Seitwärts-Scrollen stehen --- */
.planung-grid .station-cell {
    position: sticky; left: 0; z-index: 4;
    padding: var(--s-12) var(--s-10) var(--s-12) var(--s-14);
    background: var(--surface); border-right: 1px solid var(--line);
}
.station-inner .station-name { display: block; font-size: 14px; font-weight: 700; line-height: 1.25; color: var(--ink); overflow-wrap: break-word; }
/* Löschen liegt als kleines Abzeichen an der Ecke und nimmt keinen Platz weg.
   Unsichtbar MUSS auch unklickbar heißen — sonst liegt ein blindes Lösch-Ziel
   mitten im Raster (der Tipp-Weg tippt genau dorthin, um einzuteilen). */
.planung-grid .station-del, .planung-grid .shift-del {
    position: absolute; z-index: 1; width: 22px; height: 22px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-2); border-radius: 50%; background: var(--surface); color: var(--ink-3);
    font-size: 15px; line-height: 1; cursor: pointer;
    opacity: 0; pointer-events: none; transition: opacity 0.12s, background 0.12s, color 0.12s, border-color 0.12s;
}
/* Unten rechts: dort steht nie der Name, auch wenn er zwei Zeilen braucht. */
.planung-grid .station-del { right: var(--s-6); bottom: var(--s-8); }
.planung-grid .shift-del { top: -9px; right: -7px; }
/* In der letzten Spalte ragte es 2 px aus dem Rahmen. */
.planung-grid .day-cell:last-child .shift-del { right: -2px; }
.station-cell:hover .station-del, .shift-box:hover .shift-del,
.planung-grid .station-del:focus-visible, .planung-grid .shift-del:focus-visible { opacity: 1; pointer-events: auto; }
.planung-grid .station-del:hover, .planung-grid .shift-del:hover { background: #fdecec; border-color: #f2b8b8; color: #b91c1c; }

/* --- Schicht hinzufügen: nur in der Zelle, über der man steht --- */
.add-shift-cell {
    width: 100%; min-height: 28px; padding: var(--s-4);
    border: 1px dashed var(--line-2); border-radius: 10px; background: transparent;
    color: var(--ink-4); font-size: 11px; font-weight: 600; cursor: pointer;
    opacity: 0; transition: opacity 0.12s, border-color 0.12s, color 0.12s, background 0.12s;
}
.day-cell:hover .add-shift-cell, .add-shift-cell:focus-visible { opacity: 1; }
.add-shift-cell:hover { border-color: var(--accent); color: var(--accent-2); background: var(--accent-paper); }
.day-cell.is-leer .asc-wort { display: none; }
@media (min-width: 1440px) and (hover: hover) {
    .day-cell.is-leer .asc-wort { display: inline; }
}
.add-station-btn {
    width: 100%; padding: var(--s-10); border: 1px dashed var(--line-2); border-radius: 12px;
    background: transparent; color: var(--ink-3); font-size: 12px; font-weight: 600; cursor: pointer;
}
.add-station-btn:hover { border-color: var(--accent); color: var(--accent-2); background: var(--accent-paper); }
.planung-grid .add-station-row .station-cell { padding: var(--s-8); }
.planung-grid .add-station-row td { border-bottom: 0; }

/* --- Schichtkasten --- */
.shift-box {
    position: relative; margin-bottom: var(--s-4); padding: var(--s-6);
    background: var(--surface); border: 1px solid var(--line-2); border-radius: 12px;
    transition: border-color 0.15s, box-shadow 0.15s;
}
.shift-box.full, .shift-box.ohne-soll { background: var(--paper); border-color: var(--line); }
.shift-box.sortable-drag-over {
    border-color: var(--accent) !important; background: var(--accent-paper);
    box-shadow: 0 0 0 3px var(--accent-soft);
}
/* Das Abzeichen der Passung darf im schmalen Kasten umbrechen statt hinauszuragen. */
.shift-box > .fit-badge { max-width: 100%; padding: var(--s-2) var(--s-8); font-size: 11px; white-space: normal; }
/* Person gewählt: Jede Schicht ist jetzt ein Ziel. Schicht gewählt: Sie hebt sich ab. */
.planung-grid.has-selection .shift-box { cursor: pointer; }
.planung-grid.has-selection .shift-box:hover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.planung-grid.has-selection .shift-box.fit-aus { cursor: not-allowed; }
.shift-box.is-gewaehlt { z-index: 2; box-shadow: 0 0 0 3px var(--ink), 0 10px 24px rgba(20, 17, 12, 0.12); }
.shift-box .shift-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4); margin-bottom: var(--s-4); }
.shift-box .shift-time { font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.shift-coverage {
    margin-left: auto; padding: 1px var(--s-2); border-radius: 6px;
    background: var(--accent-paper); color: var(--accent-2);
    font-family: var(--font-mono); font-size: 10px; font-weight: 700; white-space: nowrap;
}
.shift-box.full .shift-coverage, .shift-box.ohne-soll .shift-coverage { padding: 1px 0; background: transparent; color: var(--ink-3); font-weight: 600; }
/* Zeitlich offen: In einem Teil der Schichtzeit ist niemand da (das Skript setzt
   .hat-luecke). Zu sehen ist ein kleiner Punkt an der Belegung — an der besetzten
   Schicht wie an der, der noch Personen fehlen. Was er heißt, steht in der Legende des
   Docks (.sw-luecke); WANN niemand da ist, steht in der Hinweiszeile, sobald die Schicht
   angetippt ist — ein Hinweis nur beim Überfahren wäre am Handy unsichtbar.
   Vergangene Tage bleiben ohne Punkt: Daran ist nichts mehr zu planen. */
.shift-coverage.hat-luecke { position: relative; }
/* Der Punkt sitzt an der Ecke der Belegung und nimmt keine Breite weg — sonst bräche
   in einer schmalen Spalte die Belegung unter die Zeit. */
.shift-coverage.hat-luecke::after {
    content: ""; position: absolute; top: -2px; right: -5px; width: 6px; height: 6px;
    border-radius: 50%; background: var(--warning);
}
.day-cell.past .shift-coverage.hat-luecke::after { display: none; }
.pool-legend .sw-luecke { width: 6px; height: 6px; border-radius: 50%; background: var(--warning); }

/* --- Eine Person in der Schicht ---
   Eine Zeile je Person. Name und vereinbarte Zeit sind EINE ruhige Einheit
   (.pill-text): nebeneinander, wenn die Spalte es hergibt, sonst die Zeit unter dem
   Namen. Der Name darf umbrechen statt abgeschnitten zu werden — „Monique G…" hilft
   niemandem. Nur der Kommentar der Aushilfe steht in einer eigenen Zeile darunter. */
.shift-assignments { list-style: none; margin: 0; padding: 0; min-height: 8px; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
.assignment-pill {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-4);
    margin: 0; padding: var(--s-2) var(--s-2) var(--s-2) var(--s-8); min-height: 28px; min-width: 0;
    background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
    font-size: 12px; font-weight: 600; line-height: 1.25; color: var(--ink);
    cursor: pointer; transition: background 0.15s, border-color 0.15s, color 0.15s;
}
/* Zeilenwechsel vor dem Kommentar — nur, wenn es einen gibt (sonst hinge an jeder
   Pille eine leere Zeile). */
.assignment-pill:has(.ap-note)::after { content: ""; order: 3; flex: 0 0 100%; height: 0; }
/* Zum Verschieben gewählt (Tipp-Weg): Diese Person sucht gerade ihr Ziel. */
.assignment-pill.tap-selected { background: var(--accent-paper); border-color: var(--accent); color: var(--accent-2); box-shadow: 0 0 0 2px var(--accent-soft); }
.assignment-pill:hover { background: var(--accent-paper); border-color: var(--accent); color: var(--accent-2); }
.assignment-pill .ac-mark, .assignment-pill .ns-mark, .assignment-pill .rq-mark { order: 0; flex: 0 0 auto; font-weight: 700; }
/* Offene Anfrage: das Fragezeichen als Strichsymbol (hub_symbol), in der Farbe der Pille. */
.assignment-pill .rq-mark { display: inline-flex; width: 15px; height: 15px; color: var(--accent-2); }
.assignment-pill .rq-mark svg { width: 15px; height: 15px; display: block; }
/* Meldung der Aushilfe zum heutigen Einsatz (einsatz_meldung()): „komme später" als Uhr mit
   der Ankunftszeit, „bin krank" als Warnzeichen. Gehört zur Einheit aus Name und Zeit; der
   ganze Satz steht im Fenster der Person. */
.assignment-pill .pill-meldung { flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--s-2); align-self: center; color: #8a4a10; }
.assignment-pill .pill-meldung svg { width: 14px; height: 14px; display: block; }
.assignment-pill .pill-meldung.ist-krank { color: #b91c1c; }
.assignment-pill .pm-zeit { font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; white-space: nowrap; }
/* … und derselbe Satz im Fenster der Person. */
.am-meldung { margin: calc(-1 * var(--s-10)) 0 var(--s-14); padding: var(--s-8) var(--s-12); border-radius: 10px; background: var(--warning-light); color: var(--ink); font-size: 13px; line-height: 1.4; }
.am-meldung[hidden] { display: none; }
/* Profilbild in der Pille: klein vor dem Namen. Die Pille rückt dafür links etwas ein. */
.assignment-pill .pill-kreis { order: 0; width: 18px; height: 18px; margin-left: calc(-1 * var(--s-4)); font-size: 10px; letter-spacing: 0; }
.assignment-pill .pill-text { order: 1; flex: 1 1 0; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 var(--s-6); }
/* Silbentrennung für lange Nachnamen („Herrmanns-dörfer"); „anywhere" nur als Notnagel. */
.assignment-pill .pill-name { flex: 0 1 auto; min-width: 0; hyphens: auto; -webkit-hyphens: auto; overflow-wrap: anywhere; }
.assignment-pill .remove-x {
    order: 2; flex: 0 0 auto; width: 22px; height: 22px; padding: 0;
    border: 0; border-radius: 50%; background: transparent; color: var(--ink-4);
    font-size: 16px; line-height: 1; cursor: pointer; touch-action: manipulation;
}
.assignment-pill .remove-x:hover, .assignment-pill .remove-x:focus-visible, .assignment-pill .remove-x:active {
    background: var(--accent-paper); color: var(--accent-2); outline: none;
}
/* Offene Anfrage: noch nicht zugesagt — gestrichelt. */
.assignment-pill.is-request { border-style: dashed; border-color: var(--accent); background: var(--accent-paper); }
.assignment-pill.has-actual { background: var(--success-light); border-color: rgba(31, 138, 76, 0.35); color: var(--success-2); }
.assignment-pill.has-actual:hover { border-color: var(--success); }
.assignment-pill.no-show { background: var(--warning-light); border-color: rgba(184, 101, 26, 0.4); color: #8a4a10; text-decoration: line-through; }
/* Vereinbarte Zeit bzw. gemeldetes Fenster („09:00–12:00"), wenn die Person die Schicht
   nicht ganz abdeckt: leise hinter dem Namen, ohne eigene Fläche. */
.assignment-pill .ap-time {
    flex: 0 0 auto; font-family: var(--font-mono); font-size: 10.5px; font-weight: 500; color: var(--ink-3); white-space: nowrap;
}
/* Kommentar der Aushilfe zu ihrer Verfügbarkeit — gekürzt, ganz im Tooltip. */
.assignment-pill .ap-note {
    order: 5; flex: 0 1 auto; min-width: 0; margin: 0 var(--s-6) var(--s-2) 0; padding: 1px var(--s-6); border-radius: 6px;
    background: #e8effd; color: #1d4fc4;
    font-size: 10px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* --- Dicht am Schreibtisch ---
   Mit der Maus braucht eine Namenszeile keine 28 px: 22 px je Person und 2 px
   dazwischen — vier Namen stehen auf 94 statt 124 px (Luca, 05.10.2026: „unnötig viel
   Platz zwischen den Namen"). Das × hielt die Zeile sonst auf 28 px, auch solange es
   unsichtbar ist. Touch und schmale Fenster behalten ihre großen Tippziele (Block
   darunter) — die beiden Medienabfragen schließen einander aus. */
@media (hover: hover) and (min-width: 769px) {
    .shift-box .shift-head { margin-bottom: var(--s-2); }
    .shift-assignments { gap: var(--s-2); }
    .assignment-pill { min-height: 22px; padding-top: 0; padding-bottom: 0; }
    .assignment-pill .remove-x { width: 18px; height: 18px; font-size: 14px; }
    .add-shift-cell { min-height: 20px; padding: var(--s-2) var(--s-4); }
}

/* --- Touch und schmale Fenster ---
   Ohne Hover gäbe es weder „Schicht hinzufügen" noch „Löschen". Beides bleibt
   sichtbar, aber leise; die Spalten werden etwas breiter, damit das × der Schicht
   neben Zeit und Belegung Platz hat. */
@media (hover: none), (max-width: 768px) {
    .planung-grid { --pg-tag: 156px; }
    .add-shift-cell { opacity: 1; min-height: 36px; border-color: transparent; font-size: 15px; }
    .add-shift-cell .asc-wort { display: none; }
    .planung-grid .shift-del {
        /* 36 px Trefferfläche, aber nur 28 px im Satz: der Rest ragt in den Rand. */
        position: static; flex: 0 0 auto; width: 36px; height: 36px; margin: calc(-1 * var(--s-8)) calc(-1 * var(--s-8)) calc(-1 * var(--s-8)) 0;
        border-color: transparent; background: transparent; font-size: 18px;
        opacity: 0.55; pointer-events: auto;
    }
    .planung-grid .station-del {
        right: var(--s-4); bottom: var(--s-4); width: 30px; height: 30px;
        border-color: transparent; background: transparent; font-size: 18px;
        opacity: 0.55; pointer-events: auto;
    }
    .assignment-pill { padding-right: var(--s-2); }
    .assignment-pill .remove-x { width: 34px; height: 34px; font-size: 20px; background: var(--paper-2); }
}
@media (max-width: 640px) {
    .planung-grid { --pg-station: 108px; --pg-schmal: 60px; }
    .planung-grid .station-cell { padding: var(--s-10) var(--s-8) var(--s-10) var(--s-12); }
    .station-inner .station-name { font-size: 13px; }
    .planung-grid th { padding: var(--s-10) var(--s-8) var(--s-8); }
    .planung-grid .pg-ecke { padding-left: var(--s-12); }
}

/* ============================================================================
   WOCHE ANLEGEN — Schichten aus einer Vorlage für mehrere Stationen und Tage
   ----------------------------------------------------------------------------
   Eingeklappter Block unter dem Planungsraster (produktion/planung.php). Bis
   04.10.2026 stand das Formular im Reiter „Schichten"; der ist entfallen, geplant
   wird an einer Stelle. Bei einem Eingabefehler rendert der Block offen, mit den
   abgeschickten Eingaben; die Meldung steht im Formular.
   ============================================================================ */
/* Den Abstand zu Raster und Dock trägt das Layout der Planung. Nach einem Fehler
   springt die Seite an den Block — der Kopf steht fest darüber, deshalb die Luft. */
.woche-anlegen { margin-top: 0; scroll-margin-top: calc(3 * var(--s-32)); }
.wa-form { max-width: 800px; margin-top: var(--s-16); display: flex; flex-direction: column; gap: var(--s-16); }
.wa-form .alert { margin: 0; }
/* Name einer GRUPPE (Stationen, Wochentage): sieht aus wie ein Feldname, ist aber
   keiner — ein <label> ohne Feld beschriftet nichts. */
.wa-name { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.wa-form .check-cards { grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr)); }
/* Das Datum hinter dem Wochentag: leise, aber in der Farbe der Pille. Eine feste
   Tintenfarbe wäre auf der angekreuzten (Akzent) nicht zu lesen. */
.wa-datum { font-family: var(--font-mono); font-size: 10px; opacity: 0.75; }
.wa-personen { max-width: 180px; }
.wa-ohne, .wa-ohne a { color: var(--accent-2); }

/* ============================================================================
   PLANUNG — ZWEI PROJEKTE NEBENEINANDER (produktion/planung.php, 05.10.2026)
   ----------------------------------------------------------------------------
   Über „Zweites Projekt" steht ein zweites Raster neben dem ersten: dieselbe Woche,
   jedes in seinem Rahmen mit eigenem Seitwärts-Lauf. Personen wandern durch Ziehen
   oder per Tipp von einem ins andere (Skript der Seite; geprüft wird am Server).

     .planung-paar            Behälter für ein oder zwei Raster
     .planung-paar.ist-zwei   zwei Raster: ab 1280 px nebeneinander, darunter untereinander
     .planung-teil            ein Projekt: Kopf (.pt-kopf, nur zu zweit) und .planung-grid-wrap

   Zu zweit hat jedes Raster nur die halbe Breite. Damit Namen lesbar bleiben (rund
   80 px je Name), rücken Stationsspalte und Tage OHNE Schicht zusammen, und das × einer
   Person erscheint erst beim Überfahren (Entfernen geht weiter über Klick → Fenster und
   über Rechtsklick). Zwei Wochen mit fünf Schicht-Tagen passen ab etwa 1700 px ganz ins
   Bild, zwei mit sieben ab 1920 px; darunter läuft jedes Raster in seinem Rahmen.
   ============================================================================ */
.planung-paar { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-18); align-items: start; }
.planung-teil { min-width: 0; }
.pt-kopf { display: flex; align-items: center; gap: var(--s-8); min-height: 36px; margin-bottom: var(--s-8); padding: 0 var(--s-6); }
.pt-punkt { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; background: var(--pk-farbe, var(--accent)); }
.pt-name {
    flex: 1 1 auto; min-width: 0; margin: 0; font-family: inherit; font-size: 15px; font-weight: 700; line-height: 1.25;
    letter-spacing: 0; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pt-zu {
    flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 36px; padding: 0 var(--s-12);
    border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
    font-size: 12px; font-weight: 600; color: var(--ink-2); text-decoration: none; white-space: nowrap;
}
.pt-zu:hover, .pt-zu:focus-visible { border-color: var(--accent); background: var(--accent-paper); color: var(--accent-2); }

@media (min-width: 1280px) {
    .planung-paar.ist-zwei { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-16); }
    /* 108 px je Tag: Zeit und Belegung bleiben in einer Zeile, ein Name hat rund 80 px. */
    .planung-paar.ist-zwei .planung-grid { --pg-station: 96px; --pg-tag: 108px; --pg-schmal: 44px; }
    /* Die halbe Breite reicht nicht für mitwachsende leere Tage. */
    .planung-paar.ist-zwei .pg-col-leer { width: var(--pg-schmal); }
    .planung-paar.ist-zwei .planung-grid th { padding: var(--s-10) var(--s-6) var(--s-8); }
    .planung-paar.ist-zwei .planung-grid .pg-ecke { padding-left: var(--s-10); }
    .planung-paar.ist-zwei .planung-grid th.is-leer { padding-left: var(--s-4); padding-right: var(--s-2); }
    /* Das Datum steht in JEDEM Tageskopf unter dem Wochentag — so sind die Köpfe beider
       Raster gleich hoch, egal welches gerade leere Tage hat. Dazu hält jeder Tageskopf die
       Zeile für den Liefertag frei, sobald eines der beiden einen hat (.pg-platzhalter). */
    .planung-paar.ist-zwei .planung-grid th .day-date { display: block; margin-left: 0; }
    .planung-paar.ist-zwei .planung-grid th.is-leer .day-date { font-size: 10px; }
    .planung-paar.ist-zwei .day-cell.is-leer .asc-wort { display: none; }
    .planung-paar.ist-zwei .planung-grid .day-cell { padding: var(--s-2); }
    .planung-paar.ist-zwei .planung-grid .station-cell { padding: var(--s-10) var(--s-6) var(--s-10) var(--s-10); }
    .planung-paar.ist-zwei .station-inner .station-name { font-size: 13px; hyphens: auto; -webkit-hyphens: auto; }
    .planung-paar.ist-zwei .shift-box { padding: var(--s-4); }
    .planung-paar.ist-zwei .shift-box .shift-time { font-size: 10px; }
    .planung-paar.ist-zwei .assignment-pill { padding-left: var(--s-6); }
}
/* Mit Maus: Das × einer Person liegt über dem Rand der Pille und erscheint beim
   Überfahren oder mit der Tastatur. Unsichtbar heißt unklickbar. */
@media (min-width: 1280px) and (hover: hover) {
    .planung-paar.ist-zwei .assignment-pill { position: relative; }
    .planung-paar.ist-zwei .assignment-pill .remove-x {
        position: absolute; top: 50%; right: var(--s-2); margin-top: -9px;   /* halbe Höhe des × (18 px) */
        background: var(--surface); box-shadow: 0 0 0 1px var(--line-2);
        opacity: 0; pointer-events: none;
    }
    .planung-paar.ist-zwei .assignment-pill:hover .remove-x,
    .planung-paar.ist-zwei .assignment-pill .remove-x:focus-visible { opacity: 1; pointer-events: auto; }
    .planung-paar.ist-zwei .assignment-pill .remove-x:hover { background: var(--accent-paper); color: var(--accent-2); }
}
/* Ohne Maus bleibt das × sichtbar (34 px) — die Spalten brauchen dafür mehr Breite. */
@media (min-width: 1280px) and (hover: none) {
    .planung-paar.ist-zwei .planung-grid { --pg-tag: 148px; }
}
/* Sehr breite Bildschirme: Zu zweit darf die Seite breiter werden als die üblichen
   1760 px — zwei volle Wochen brauchen den Platz. Ab dort wachsen auch zu zweit die
   leeren Tage mit. */
@media (min-width: 1900px) {
    .container-wide:has(.planung-paar.ist-zwei) { max-width: min(2400px, 100%); }
    body[data-wide="1"]:has(.planung-paar.ist-zwei) .app-header-inner { max-width: min(2400px, 100%); }
}
@media (min-width: 2300px) {
    .planung-paar.ist-zwei .pg-col-leer { width: var(--pg-leer-breit, var(--pg-schmal)); }
}
/* Platzhalter für den Liefertag im Kopf: unsichtbar, aber so hoch wie das Abzeichen. */
.planung-grid .pg-platzhalter { visibility: hidden; }

/* ============================================================================
   PLANUNG — VERSCHIEBEN: Ziele, Hinweise, ein Zug zur Zeit (produktion/planung.php)
   ----------------------------------------------------------------------------
   Wird eine Person verschoben (Ziehen oder Tippen), färbt die Antwort des Servers die
   Schichten (.fit-*, Abschnitt RICHTUNG D) und schreibt in das Abzeichen jedes Ziels,
   was er dazu sagt: den Grund in der ersten Zeile, darunter JEDEN Hinweis
   (.fit-hinweis) — ein Hinweis nur beim Überfahren wäre am Handy unsichtbar.
   ============================================================================ */
.shift-box > .fit-badge.hat-hinweise { display: block; border-radius: 10px; padding: var(--s-4) var(--s-8); }
.fit-hinweis { display: block; margin-top: var(--s-2); font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
/* Mehrere Hinweise: Dann wird vor dem Verschieben ohnehin gefragt (das Blatt zeigt sie
   ganz) — hier je Hinweis höchstens zwei Zeilen. */
.fit-hinweis.ist-kurz { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }

/* Ein Zug zur Zeit: Solange ein Verschieben unterwegs ist, nimmt die Planung nichts an
   (das Skript sperrt Ziehen und Tippen). Zu sehen ist das erst, wenn es länger dauert —
   sonst flackerte die Seite bei jedem Zug kurz. Die Hinweiszeile des Docks sagt, was läuft. */
.planung-layout.ist-gesperrt { cursor: progress; }
.planung-layout.ist-gesperrt .planung-paar,
.planung-layout.ist-gesperrt .second-view,
.planung-layout.ist-gesperrt .pool-grid { opacity: 0.55; transition: opacity 0.2s 0.3s; }
@media (prefers-reduced-motion: reduce) {
    .planung-layout.ist-gesperrt .planung-paar,
    .planung-layout.ist-gesperrt .second-view,
    .planung-layout.ist-gesperrt .pool-grid { transition: none; }
}
/* Solange gesperrt ist, bleibt eine Meldung von vorhin zu lesen — ihr „Rückgängig" aber ist
   taub (das Skript setzt disabled). Das soll man ihm ansehen. Ebenso die Auswahl „Zweites Projekt". */
.kmeldung button:disabled { opacity: 0.45; cursor: default; }
.js-zweites-projekt:disabled { opacity: 0.55; cursor: default; }

/* =============================================================================
   WAS IST NEU (neuigkeiten.php) — ruhige Liste, eine Karte je Auslieferung
   ============================================================================= */
.neu-liste { display: grid; gap: var(--s-16); max-width: 680px; }
.neu-eintrag { min-width: 0; }
.neu-eintrag .neu-datum { margin: 0 0 var(--s-4); font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.neu-eintrag h2 { margin: 0 0 var(--s-12); }
.neu-eintrag ul { margin: 0; padding-left: var(--s-18); display: grid; gap: var(--s-8); }
.neu-eintrag li { line-height: 1.5; overflow-wrap: anywhere; }


/* =============================================================================
   APP INSTALLIEREN (installieren.php) — geführt, ruhig, für jedes Alter lesbar
   -----------------------------------------------------------------------------
   Grundabschnitt für beide Designs (das Glas-Design legt in glas/15-installieren.css
   nur Haut darüber). Eine Spalte, ein Satz und ein Bild je Ansicht, große Knöpfe:
   Schrift der Schritte mindestens 20 px, Knöpfe mindestens 56 px, Bilder breit.
   Nur der eine leise Satz zu „Nur im Browser öffnen" ist klein (15 px).
   ============================================================================= */
.inst { flex: 1 0 auto; width: 100%; max-width: 480px; margin: 0 auto; padding: var(--s-12) var(--s-16) var(--s-32); display: flex; flex-direction: column; gap: var(--s-12); }
.inst [hidden] { display: none; }
.inst-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.inst-oben { display: flex; justify-content: flex-end; }
.inst-sprache { position: relative; }
.inst-sprache > summary {
    list-style: none; display: inline-flex; align-items: center; gap: var(--s-6);
    min-height: 44px; padding: 0 var(--s-14); border: 1px solid var(--line-2); border-radius: 999px;
    background: var(--surface); color: var(--ink); font-size: 16px; font-weight: 700; cursor: pointer;
}
.inst-sprache > summary::-webkit-details-marker { display: none; }
.inst-chev, .inst-chev svg { display: inline-flex; width: 18px; height: 18px; }
.inst-sprache-menue {
    position: absolute; right: 0; top: calc(100% + var(--s-6)); z-index: 5; min-width: 180px;
    padding: var(--s-6); border: 1px solid var(--line); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow-md);
}
.inst-sprache-menue a { display: flex; align-items: center; min-height: 48px; padding: 0 var(--s-12); border-radius: 10px; color: var(--ink); font-size: 16px; text-decoration: none; }
.inst-sprache-menue a.aktiv { background: var(--accent-paper); color: var(--accent-2); font-weight: 700; }

.inst-karte {
    min-width: 0; display: grid; gap: var(--s-24); padding: var(--s-24) var(--s-18); text-align: center;
    background: var(--surface); border: 1px solid var(--line); border-radius: 22px; box-shadow: var(--shadow-lg);
}
.inst-kopf { display: grid; justify-items: center; gap: var(--s-10); }
.inst-kopf img { width: 64px; height: 64px; border-radius: 16px; }
.inst-kopf h1 { margin: 0; font-size: 26px; line-height: 1.15; color: var(--ink); overflow-wrap: anywhere; }

.inst-zustand { min-width: 0; display: grid; gap: var(--s-18); justify-items: stretch; }
.inst-text { margin: 0; font-size: 20px; font-weight: 700; line-height: 1.35; color: var(--ink); overflow-wrap: anywhere; }
.inst-hinweis { margin: var(--s-12) 0 0; font-size: 18px; font-weight: 600; line-height: 1.35; color: var(--ink-2); overflow-wrap: anywhere; }
.inst-zaehler { margin: 0; font-size: 18px; font-weight: 700; color: var(--ink-2); }
.inst-haken, .inst-haken svg { display: block; width: 96px; height: 96px; margin: 0 auto; }
.inst-haken { color: var(--success-2); }
.inst-haken svg { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }

.inst-bild { display: block; width: 100%; max-width: 260px; height: auto; margin: 0 auto var(--s-12); color: var(--ink); }
.inst-bild .b-karte { fill: var(--paper); stroke: var(--line-2); stroke-width: 2; }
.inst-bild .b-leise { fill: var(--line-2); }
.inst-bild .b-trenn { fill: none; stroke: var(--line-2); stroke-width: 2; }
.inst-bild .b-ico { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.inst-bild .b-ico circle { fill: currentColor; stroke: none; }
.inst-bild .b-ak { color: var(--accent-2); }
.inst-bild .b-ring { fill: none; stroke: var(--accent-2); stroke-width: 3; }
.inst-bild .b-ring-d { fill: none; stroke: var(--accent-2); stroke-width: 3; }
.inst-bild .b-akf { fill: var(--accent-soft); }
.inst-bild .b-ak-fl { fill: var(--accent-2); }
.inst-bild .b-pille { fill: var(--verlauf-a, var(--accent-2)); }
.inst-bild .b-weiss { fill: #fff; }

.inst-liste { list-style: none; display: grid; gap: var(--s-24); }
.inst-nr {
    display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; margin-right: var(--s-10);
    border-radius: 50%; background: var(--accent-2); color: #fff; font-size: 18px; font-weight: 800; vertical-align: middle;
}
.inst-liste .inst-nr { display: flex; margin: 0 auto var(--s-8); }
.inst-schritte { list-style: none; }
/* Im Ablauf am iPhone zählt jede Zeile: Das Symbol oben entfällt, und unten bleibt Platz, damit der
   Pfeil am Fensterrand nichts verdeckt. */
.inst[data-aktiv="ios"] { padding-bottom: 88px; }
.inst[data-aktiv="ios"] .inst-kopf img { display: none; }

.inst-punkte { display: flex; justify-content: center; gap: var(--s-8); }
.inst-punkte i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }
.inst-punkte i.ist-aktiv { background: var(--accent-2); }
.inst-nav { display: grid; gap: var(--s-6); justify-items: center; }
.inst-nav .btn { justify-self: stretch; }
.inst-text-knopf {
    min-height: 48px; padding: 0 var(--s-18); border: 0; background: none; color: var(--ink-2);
    font-size: 17px; font-weight: 700; text-decoration: underline; cursor: pointer;
}

/* Niedrige Fenster (kleines iPhone, Leiste unten): das Bild gibt Höhe ab, der Knopf bleibt im Blick. */
@media (max-height: 700px) { .inst-bild { max-width: 190px; margin-bottom: var(--s-8); } .inst-karte { gap: var(--s-18); } }

.inst .btn { width: 100%; min-height: 56px; padding: 0 var(--s-18); font-size: 18px; font-weight: 800; }
.inst .btn .btn-ico, .inst .btn .btn-ico svg { width: 22px; height: 22px; }
.inst-zweite { display: grid; gap: var(--s-12); }
.inst-note { margin: 0; font-size: 15px; line-height: 1.45; color: var(--ink-2); overflow-wrap: anywhere; }

/* Der Pfeil zeigt auf das echte Teilen-Symbol des Geräts und sitzt deshalb am Rand des
   Fensters. Er hüpft ein paar Mal und bleibt dann stehen. Nur transform; die Keyframes nennen
   nur den Anfang (das Ende ist die Lage des Pfeils selbst). */
@keyframes inst-huepfen { from { transform: translateY(-8px); } }
@keyframes inst-huepfen-hoch { from { transform: translateY(8px); } }
.inst-pfeil { animation: inst-huepfen 0.7s ease-in-out 11 alternate; }
.inst-pfeil-fest {
    position: fixed; width: 56px; height: 56px; display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--accent-2); border-radius: 50%; background: var(--surface); color: var(--accent-2);
    box-shadow: var(--shadow-md); pointer-events: none;
}
.inst-pfeil-fest svg { width: 30px; height: 30px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* Safari am iPhone: Teilen-Symbol unten Mitte, knapp über der Leiste (und über der Home-Anzeige). */
.inst-pfeil-fest[data-lage="unten"] { left: 50%; margin-left: -28px; bottom: calc(var(--s-6) + env(safe-area-inset-bottom, 0px)); }
/* Chrome/Firefox am iPhone: oben rechts. Safari am iPad: oben rechts, etwas weiter innen. */
.inst-pfeil-fest[data-lage^="oben"] { top: calc(var(--s-6) + env(safe-area-inset-top, 0px)); animation-name: inst-huepfen-hoch; }
.inst-pfeil-fest[data-lage^="oben"] svg { transform: rotate(180deg); }
.inst-pfeil-fest[data-lage="oben-iphone"] { right: var(--s-12); }
.inst-pfeil-fest[data-lage="oben-ipad"] { right: 96px; }
@media (prefers-reduced-motion: reduce) {
    .inst-pfeil { animation: none; }
}

/* Konto-Menü: „App installieren" gibt es nicht in der installierten App
   (Android/Desktop: display-mode; iPhone: Klasse .ist-app, gesetzt in _footer.php). */
@media (display-mode: standalone) { .lang-menu a.konto-installieren { display: none; } }
html.ist-app .lang-menu a.konto-installieren { display: none; }
