/* Wyld Management — design system */

/* ====================== Inter (self-hosted) ======================
   Inter Variable Font (OFL-Lizenz, https://rsms.me/inter/) — eine
   einzige Datei deckt alle Gewichte 100-900 + Italic ab. Lokal aus
   public/fonts/inter/ ausgeliefert, kein externer CDN, kein Tracking.
   `font-display: swap` zeigt sofort den System-Fallback und tauscht
   nahtlos sobald die woff2-Datei geladen ist (~340 KB cached forever).
================================================================== */
@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter/InterVariable.woff2') format('woff2-variations'),
         url('/fonts/inter/InterVariable.woff2') format('woff2');
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Inter';
    src: url('/fonts/inter/InterVariable-Italic.woff2') format('woff2-variations'),
         url('/fonts/inter/InterVariable-Italic.woff2') format('woff2');
    font-weight: 100 900;
    font-style: italic;
    font-display: swap;
}

/* ====================== Icons ======================
   SVG-Sprite-Pattern: <x-icon name="..."/> rendert ein <svg class="icon">
   mit <use href="/img/icons.svg#icon-NAME">. Stroke nutzt currentColor,
   Größe folgt der Schriftgröße — daher passt jedes Icon automatisch in
   Buttons, Headlines, Nav-Links ohne separate Größenklassen.

   Größen-Varianten für Stellen, wo das 1em-Defauft zu klein/groß ist:
     .icon-sm — 14px (Listentabellen, Mini-Buttons)
     .icon-md — 18px (Page-Titles, Card-Headers)
     .icon-lg — 22px (Hero-Bereiche)
*/
.icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    flex-shrink: 0;
    vertical-align: -0.15em;
    fill: none;
    stroke: currentColor;
    /* Sicherheits-Defaults falls ein Symbol mal ohne eigene Stroke-Attribute
       liegt — der Sprite setzt sie eigentlich pro <symbol>. */
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.icon-sm { width: 14px; height: 14px; vertical-align: -2px; }

/* In Buttons soll das Icon konsistent neben Text sitzen ohne extra margin */
.btn .icon { vertical-align: -0.2em; margin-right: 6px; }
.btn .icon:last-child:not(:first-child) { margin-right: 0; margin-left: 6px; }
.btn-icon .icon { margin: 0; vertical-align: -0.2em; }

:root {
    /* Primary brand palette */
    --primary-orange: #fe5900;
    --primary-anthracite: #223439;

    --accent: var(--primary-orange);
    --accent-soft: #fff1e6;
    --accent-strong: #cc4700;

    /* Sidebar palette (derived from anthracite) */
    --sidebar-bg: var(--primary-anthracite);
    --sidebar-border: #2f4449;
    --sidebar-border-strong: #486068;
    --sidebar-hover: #2c4147;
    --sidebar-text: #c8d3d6;
    --sidebar-text-subtle: #7d9097;

    --bg: #f5f5f3;
    --surface: #ffffff;
    --surface-2: #fafaf8;
    --border: #e5e4e0;
    --text: #1b1b18;
    --text-muted: #706f6c;
    --text-subtle: #a1a09a;
    --red: #d94343;
    --yellow: #d4a206;
    --green: #2f9e44;
    --blue: #2563eb;
    --gray: #8a8a86;
    --radius: 8px;
    --radius-lg: 12px;
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
    --shadow: 0 4px 12px rgba(0,0,0,0.06);

    /* === z-index Hierarchie (klein → groß) ===
       Content  · Banner  · FABs  · Toasts  · Modals  · Phase  · Party
       Werte sind absichtlich Lücken-frei dokumentiert, damit man immer
       weiß wo etwas hingehört. Magische 9999 sind hier verboten. */
    --z-content:        1;
    --z-banner:        60;   /* sticky-Banner (broadcast, admin-toolbar) */
    --z-banner-party:  70;   /* Party-Banner über andere Banner */
    --z-fab:         9990;   /* notification, clock, audit-tail */
    --z-toolbar:     9998;   /* admin-toolbar, nahe an FABs aber über content */
    --z-toast:      10000;   /* Flash-Toasts immer obenauf */
    --z-modal:      10500;   /* admin-modal-backdrop */
    --z-quickjump:  10600;   /* ⌘K Command-Palette über regulären Modals */
    --z-dialog:     10700;   /* app-dialog (Confirm-Ersatz) über regulären Modals */
    --z-broadcast-confirm: 10800; /* zweistufiger Broadcast-Confirm-Dialog */
    --z-tooltip:    10900;  /* Info-Tip-Popover — über Modals/Dialogen */
    --z-overlay-party:    99999;  /* Konfetti-Wolke deckt fast alles */
    --z-overlay-phase:   100000;  /* Mode-Übergang über allem für 1.4s */
}

/* Dark theme: applied when [data-theme="dark"] OR [data-theme="system"]
   AND the OS prefers dark. Sidebar palette stays anthracite either way. */
:root[data-theme="dark"],
:root[data-theme="system"] {
    color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
    :root[data-theme="system"] {
        --bg: #14171a;
        --surface: #1d2125;
        --surface-2: #181c20;
        --border: #2a2f34;
        --text: #e8e8e6;
        --text-muted: #a8a8a4;
        --text-subtle: #6a6e72;
        --accent-soft: #3a2a1c;
        --shadow-sm: 0 1px 2px rgba(0,0,0,0.35);
        --shadow: 0 4px 14px rgba(0,0,0,0.45);
    }
}
:root[data-theme="dark"] {
    --bg: #14171a;
    --surface: #1d2125;
    --surface-2: #181c20;
    --border: #2a2f34;
    --text: #e8e8e6;
    --text-muted: #a8a8a4;
    --text-subtle: #6a6e72;
    --accent-soft: #3a2a1c;
    --shadow-sm: 0 1px 2px rgba(0,0,0,0.35);
    --shadow: 0 4px 14px rgba(0,0,0,0.45);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
    font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    /* Kleine Inter-Optimierungen: aktiviert Ligaturen und alternative
       Ziffern-Glyphen (z.B. "case-aligned" Großbuchstaben-Ziffern). */
    font-feature-settings: 'cv11', 'ss01', 'ss03';
    font-optical-sizing: auto;
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
    line-height: 1.5;
    /* Body selbst nicht scrollen — die Sidebar bleibt damit garantiert
       still, und nur der Inhaltsbereich (.main) scrollt intern. Sorgt
       außerdem dafür, dass FABs / Popovers ein stabiles Viewport haben. */
    overflow: hidden;
}
a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

/* Layout shell — feste Viewport-Höhe; nur .main scrollt intern,
   die Sidebar steht völlig still (siehe body { overflow: hidden }). */
/* Layout-Shell: schwebende Sidebar in einem 12px-Padding-Rahmen, dazwischen
   ein Gap. Sidebar wirkt damit als „Karte" abgesetzt vom Hintergrund, analog
   zu den Content-Cards (gleicher radius, gleiche shadow-Familie). */
.layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    height: 100vh;   /* Fallback für sehr alte Browser */
    /* iOS: sowohl 100vh als auch 100dvh laufen hinter die Browser-UI — dvh
       „springt" zudem nach dem Laden auf den großen Wert, wodurch die
       height:100%-Sidebar unten über den sichtbaren Bereich hinausragt.
       100svh = kleinste sichtbare Höhe: stabil, springt nicht, läuft nie über. */
    height: 100svh;
    padding: 12px;
    /* Home-Indikator (iPad/iPhone) unten freihalten — auf Desktop 0. */
    padding-bottom: calc(12px + env(safe-area-inset-bottom));
    gap: 12px;
    box-sizing: border-box;
    transition: grid-template-columns 0.18s ease;
}
body.sidebar-collapsed .layout { grid-template-columns: 64px 1fr; }

/* Responsive: bei schmalen Viewports wird body.sidebar-collapsed via JS
   gesetzt (siehe layouts/app.blade.php — Inline-Script direkt nach <body>
   + Resize-Listener). Die Media Queries hier kümmern sich nur noch um die
   reduzierten Layout-Paddings und die schmalere Grid-Column für die
   Sidebar — die Sichtbarkeits-Regeln der Sidebar-Innenelemente kommen
   alle aus body.sidebar-collapsed-Selektoren weiter unten. */
@media (max-width: 980px) {
    .layout,
    body.sidebar-collapsed .layout { grid-template-columns: 56px 1fr; padding: 8px; gap: 8px; }
    /* Negative Margin gleich Layout-Padding, damit main weiter die volle
       Viewport-Höhe nutzt — sonst entstünde eine 4px-Diskrepanz. */
    .main { margin: -8px -8px -8px 0; padding: 0; }
    .main-fixed  { padding: 8px 14px 0; }
    .main-scroll { padding: 0 14px 96px; scroll-padding-bottom: 96px; }
}
@media (max-width: 560px) {
    /* Sehr schmal — Layout-Padding weiter reduziert, Sidebar bleibt schmal
       (Icon-only). Topbar wird flexibel umbrechend, Page-Actions wandern
       unter den Titel. */
    .layout,
    body.sidebar-collapsed .layout { padding: 6px; gap: 6px; grid-template-columns: 52px 1fr; }
    .main { margin: -6px -6px -6px 0; padding: 0; }
    .main-fixed  { padding: 6px 10px 0; }
    .main-scroll { padding: 0 10px 96px; scroll-padding-bottom: 96px; }
    .topbar {
        flex-wrap: wrap; gap: 8px;
        padding: 12px 14px;
    }
    .topbar-titles { flex: 1 1 100%; min-width: 0; }
    .topbar-actions { flex: 1 1 100%; flex-wrap: wrap; }
    .page-title { font-size: 17px; }
    .page-subtitle { font-size: 12px; }
}

/* iPad/Touch-Tablet: nutzt jetzt die native iOS-Shell (Bottom-Tabs + Sidebar
   als Off-Canvas-Drawer), NICHT mehr die Desktop-Sidebar-Spalte. Definiert im
   iPad-Block weiter unten (Suche: "GLEICHE iOS-Shell wie das iPhone"). Siehe
   docs/UI-CONVENTIONS.md §19.1. */
.sidebar {
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    display: flex; flex-direction: column;
    padding: 16px 0;
    /* Sidebar selbst NICHT scrollen — Brand/Search bleiben oben,
       .sidebar-foot bleibt unten dauerhaft sichtbar. Nur .sidebar-nav
       darf intern scrollen (min-height: 0 + overflow-y: auto). */
    height: 100%;
    overflow: hidden;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    border: 1px solid var(--sidebar-border);
}
/* Im eingeklappten Zustand wird das Logo selbst zum Toggle (siehe JS).
   Cursor wechselt entsprechend, dezenter Hover. */
body.sidebar-collapsed .brand-link {
    cursor: e-resize;
}
body.sidebar-collapsed .brand-link:hover .brand-logo-mark {
    transform: scale(1.04);
    transition: transform 0.18s ease;
}
.sidebar-brand {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 20px 18px;
    margin-bottom: 0;
    position: relative;
    flex-shrink: 0;
}
.sidebar-toggle {
    margin-left: auto;
    background: transparent;
    border: 1px solid var(--sidebar-border);
    color: var(--sidebar-text);
    width: 24px; height: 24px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; line-height: 1;
    padding: 0;
    transition: transform 0.18s ease, color 0.12s, border-color 0.12s;
}
.sidebar-toggle:hover { color: white; border-color: var(--sidebar-border-strong); }
body.sidebar-collapsed .sidebar-brand { padding: 8px 12px 18px; justify-content: center; }
/* Chevron-Button im eingeklappten Zustand ausblenden — das Logo selbst
   übernimmt die Toggle-Rolle. */
body.sidebar-collapsed .sidebar-toggle { display: none; }
.brand-link {
    display: inline-flex; align-items: center;
    line-height: 0;
    flex: 1;
    min-width: 0;
}
.brand-logo { display: block; height: 28px; width: auto; max-width: 100%; }
.brand-logo-mark { display: none; height: 32px; }
body.sidebar-collapsed .brand-logo-full { display: none; }
body.sidebar-collapsed .brand-logo-mark { display: block; }
/* Toast Notifications — Stack oben rechts */
.toast-container {
    position: fixed;
    top: 16px; right: 16px;
    display: flex; flex-direction: column;
    gap: 8px;
    z-index: 9999;
    pointer-events: none;
    max-width: 380px;
    width: calc(100vw - 32px);
}
.toast {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--text-muted);
    border-radius: var(--radius-lg);
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.15);
    padding: 12px 14px 12px 14px;
    display: flex; align-items: flex-start; gap: 10px;
    pointer-events: auto;
    transform: translateY(-120%);
    opacity: 0;
    transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.18s;
    position: relative;
    overflow: hidden;
}
.toast.toast-visible { transform: translateY(0); opacity: 1; }
.toast.toast-leaving { transform: translateY(-8px); opacity: 0; }
/* "merging" = sanftes Wegfliegen Richtung Drawer wenn das Notification-Center geöffnet wird */
.toast.toast-merging {
    transform: translateX(110%) scale(0.96);
    opacity: 0;
    transition: transform 0.32s cubic-bezier(0.4, 0, 1, 1), opacity 0.28s;
}
.toast-success { border-left-color: var(--green); }
.toast-info    { border-left-color: var(--blue); }
.toast-warning { border-left-color: var(--yellow); }
.toast-error   { border-left-color: var(--red); }
.toast-icon { font-size: 18px; line-height: 1.2; flex-shrink: 0; }
.toast-text { flex: 1; min-width: 0; }
.toast-title { font-weight: 600; color: var(--text); font-size: 14px; line-height: 1.3; }
.toast-message { color: var(--text-muted); font-size: 12px; margin-top: 2px; line-height: 1.4; }
.toast-close {
    background: none; border: none; cursor: pointer;
    color: var(--text-muted); font-size: 18px; line-height: 1;
    padding: 0; width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.toast-close:hover { color: var(--text); }
.toast-progress {
    position: absolute; bottom: 0; left: 0;
    height: 2px; background: var(--accent);
    width: 100%;
    transform-origin: left;
    animation: toast-progress 10s linear forwards;
}
@keyframes toast-progress {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}

/* Floating Notification Bell (FAB unten rechts) */
.notification-fab {
    position: fixed;
    bottom: 24px; right: 24px;
    width: 56px; height: 56px;
    border-radius: 50%;
    background: var(--accent);
    color: white;
    border: none;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 16px rgba(254, 89, 0, 0.35);
    z-index: 9998;
    transition: transform 0.15s, box-shadow 0.15s;
}
.notification-fab:hover { transform: scale(1.08); box-shadow: 0 8px 22px rgba(254, 89, 0, 0.45); }
/* Icon-Wrapper als eigener Flex-Centerer + SVG-Größe explizit + vertical-align
   zurücksetzen, damit der Lucide-Stroke perfekt im Kreis sitzt. */
.notification-fab-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; line-height: 1;
}
.notification-fab-icon svg.icon,
.notification-fab .icon { width: 24px; height: 24px; vertical-align: 0; }

/* Stempeluhr-FAB — links neben dem Notification-Bell */
.clock-fab {
    position: fixed;
    bottom: 24px; right: 88px;  /* 24 + 56 + 8 = links vom Bell */
    width: 56px; height: 56px;
    border-radius: 50%;
    background: #6b7280;  /* default: clocked_out */
    color: white;
    border: none;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
    z-index: 9998;
    transition: transform 0.15s, box-shadow 0.15s, background 0.25s;
    position: fixed;
}
.clock-fab:hover { transform: scale(1.08); box-shadow: 0 8px 22px rgba(0, 0, 0, 0.25); }
.clock-fab-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; line-height: 1;
}
.clock-fab-icon svg.icon,
.clock-fab .icon { width: 24px; height: 24px; vertical-align: 0; }
.clock-fab[data-status="clocked_in"] {
    background: #16a34a;  /* grün — Arbeit läuft */
    box-shadow: 0 6px 16px rgba(22, 163, 74, 0.4);
}
.clock-fab[data-status="on_break"] {
    background: #f59e0b;  /* gelb — Pause */
    box-shadow: 0 6px 16px rgba(245, 158, 11, 0.4);
}

.clock-popover {
    position: fixed;
    bottom: 90px; right: 88px;
    width: 320px;
    max-height: calc(100vh - 120px);
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
    padding: 14px;
    z-index: 9999;
}
.clock-popover-head {
    display: flex; align-items: baseline; gap: 8px;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border);
}
.clock-popover-head strong { font-size: 14px; color: var(--text); }
.clock-popover-time { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.clock-popover-day { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; font-size: 12px; }
.clock-pop-stat { display: flex; justify-content: space-between; }
.clock-pop-stat span { color: var(--text-muted); }
.clock-pop-stat strong { font-variant-numeric: tabular-nums; }
.clock-pop-empty { color: var(--text-muted); font-size: 12px; font-style: italic; }
.clock-popover-warning {
    background: #fef3c7;
    border-left: 3px solid #f59e0b;
    color: #7a5615;
    padding: 6px 8px;
    font-size: 11px;
    border-radius: 4px;
    margin-bottom: 10px;
}
.clock-popover-actions { display: flex; flex-direction: column; gap: 6px; }
.clock-popover-actions .btn { justify-content: center; width: 100%; }
.clock-popover-footer {
    display: flex;
    gap: 6px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}
/* Footer-Buttons gleichmäßig auf die Breite verteilen — wirken so wie ein
   Pair, statt zwei lose Text-Links. */
.clock-popover-footer .btn { flex: 1; justify-content: center; }

/* ---------- Ticket-Stoppuhr im Stempeluhr-Popover ---------- */
/* Eigene Optik: kein Card-im-Card, sondern flach ins Popover integriert.
   Eine schmale Trennlinie + zarte Section-Überschrift grenzen sie von
   den Arbeitszeit-Aktionen ab. */
.sw-section {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}
.sw-section[hidden] { display: none; }
.sw-section-head {
    display: flex; align-items: baseline; gap: 6px;
    margin-bottom: 8px;
}
.sw-section-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text);
}
/* Popover-Variante überschreibt das alte Sidebar-Styling vollständig.
   Keine eigene Box, kein eigener Hintergrund — fließt direkt im Popover. */
.stopwatch-popover {
    background: transparent;
    border: none;
    padding: 0;
    margin: 0;
    display: flex; flex-direction: column; gap: 8px;
}

/* Time-Display + Start/Pause-Buttons in einer Zeile */
.stopwatch-popover .sw-top {
    display: flex; gap: 6px; align-items: stretch;
}
.stopwatch-popover .stopwatch-display {
    flex: 1;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 8px 10px;
    border-radius: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 18px;
    font-weight: 600;
    letter-spacing: 0.5px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 8px;
    transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.stopwatch-popover .stopwatch-display:hover {
    border-color: var(--accent);
    background: var(--surface);
}
.stopwatch-popover.is-running .stopwatch-display {
    color: var(--accent);
    border-color: var(--accent);
    background: rgba(254, 89, 0, 0.06);
}
.stopwatch-popover .stopwatch-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--text-muted);
    flex-shrink: 0;
}
.stopwatch-popover.is-running .stopwatch-dot {
    background: var(--accent);
    box-shadow: 0 0 0 0 rgba(254, 89, 0, 0.5);
    animation: sw-pulse 1.4s ease-in-out infinite;
}
.stopwatch-popover .stopwatch-controls { display: flex; gap: 4px; }
.stopwatch-popover .sw-btn {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 0 10px;
    min-width: 36px;
    height: auto;
    border-radius: 8px;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    display: inline-flex; align-items: center; justify-content: center;
}
.stopwatch-popover .sw-btn:hover:not(:disabled) {
    background: var(--surface);
    color: var(--text);
    border-color: var(--accent);
}
.stopwatch-popover .sw-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}
.stopwatch-popover .sw-btn-start { color: var(--green, #2f9e44); }
.stopwatch-popover .sw-btn-start:hover:not(:disabled) {
    border-color: var(--green, #2f9e44);
    background: rgba(47, 158, 68, 0.08);
}
.stopwatch-popover .sw-btn-pause { color: var(--yellow, #d4a206); }
.stopwatch-popover .sw-btn-pause:hover:not(:disabled) {
    border-color: var(--yellow, #d4a206);
    background: rgba(212, 162, 6, 0.08);
}

/* Inputs: kompakt, neutral, gleicher Look wie .list-filter-row Inputs */
.stopwatch-popover .stopwatch-fields { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.stopwatch-popover .sw-input {
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 6px 9px;
    border-radius: 6px;
    font: inherit;
    font-size: 12.5px;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.stopwatch-popover .sw-input::placeholder { color: var(--text-muted); }
.stopwatch-popover .sw-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(254, 89, 0, 0.12);
}
.stopwatch-popover .sw-textarea { resize: vertical; min-height: 44px; font-family: inherit; line-height: 1.35; }
.stopwatch-popover .sw-ticket-row { display: flex; gap: 4px; align-items: stretch; }
.stopwatch-popover .sw-ticket-row .sw-input { flex: 1; min-width: 0; }
.stopwatch-popover .sw-ticket-open {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: 6px;
    text-decoration: none;
    font-size: 13px;
    flex-shrink: 0;
    transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.stopwatch-popover .sw-ticket-open:hover {
    color: var(--accent); border-color: var(--accent); background: var(--surface-2);
}
.stopwatch-popover .sw-ticket-open[hidden] { display: none; }

/* Save-Button: primäre Aktion, volle Breite, akzentuiert */
.stopwatch-popover .sw-btn-save {
    width: 100%;
    background: var(--accent);
    border: 1px solid var(--accent);
    color: white;
    padding: 7px 10px;
    border-radius: 8px;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    min-width: 0;
    transition: background 0.12s, border-color 0.12s;
}
.stopwatch-popover .sw-btn-save:hover:not(:disabled) {
    background: var(--accent-strong, var(--accent));
    border-color: var(--accent-strong, var(--accent));
}

.stopwatch-popover .sw-status {
    min-height: 14px;
    font-size: 11px;
    color: var(--text-muted);
    text-align: center;
}
.stopwatch-popover .sw-status[data-kind="ok"] { color: var(--green, #2f9e44); }
.stopwatch-popover .sw-status[data-kind="warn"] { color: var(--yellow, #d4a206); }
.stopwatch-popover .sw-status[data-kind="err"] { color: var(--red, #e03131); }
/* Reiner Indikator-Punkt — keine Zahl mehr. Erscheint nur, wenn
   ungelesene Notifications da sind (JS togglet [hidden]). Die genaue
   Anzahl steht im geöffneten Drawer, im FAB nur „da ist was". */
.notification-fab-badge {
    position: absolute;
    top: 4px; right: 4px;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--red);
    border: 2px solid var(--surface);
    pointer-events: none;
}

/* Wenn ungelesene da sind: pulsierender Ring (bewusst KEIN Hüpfen mehr). */
.notification-fab.has-unread::before {
    content: '';
    position: absolute; inset: -4px;
    border-radius: 50%;
    border: 2px solid var(--accent);
    animation: fab-pulse 2s ease-out infinite;
    pointer-events: none;
}
@keyframes fab-pulse {
    0%   { transform: scale(1);   opacity: 0.7; }
    100% { transform: scale(1.5); opacity: 0; }
}
.notification-fab.has-unread:hover { transform: scale(1.08); }

/* Slide-over Drawer */
.notification-drawer-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 9990;
    opacity: 0;
    transition: opacity 0.25s;
}
.notification-drawer-backdrop.is-open { opacity: 1; }

/* Floating-Card-Variante: 12px-Frame zu allen Seiten (passend zum
   Layout-Padding), Border + Radius + Shadow rundherum. Slide-In bleibt
   horizontal, aber mit etwas Offset damit die Karte „reinschwebt"
   statt aus dem Bildschirm zu kleben. */
.notification-drawer {
    position: fixed;
    top: 12px; right: 12px; bottom: 12px;
    width: 400px; max-width: calc(100vw - 24px);
    background: var(--surface); color: var(--text);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.22);
    z-index: 9999;
    display: flex; flex-direction: column;
    overflow: hidden;
    transform: translateX(calc(100% + 24px));
    transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
.notification-drawer.is-open { transform: translateX(0); }
.notification-drawer-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.notification-drawer-title {
    margin: 0;
    font-size: 15px;
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.notification-drawer-actions {
    display: flex;
    gap: 4px;
    flex: none;
}
.notification-perm-banner {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 18px;
    background: rgba(254, 89, 0, 0.08);
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    color: var(--text);
    line-height: 1.4;
}
.notification-perm-banner[hidden] { display: none; }
.notification-perm-banner > span { flex: 1; min-width: 0; }
.notification-perm-banner > button { flex-shrink: 0; }
.notification-drawer-body {
    flex: 1; overflow-y: auto;
}
.notification-empty { padding: 36px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* Notification-Center-Items teilen das Design der Toasts (gleiche Karten-Optik
   mit linksseitiger Level-Border und Icon-Layout). */
.notification-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--text-muted);
    border-radius: var(--radius-lg);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
    padding: 12px 14px;
    margin: 10px 14px;
    display: flex; align-items: flex-start; gap: 10px;
    text-decoration: none; color: inherit;
    transition: background 0.12s, box-shadow 0.12s;
    position: relative;
}
.notification-item:hover {
    background: var(--surface-2);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.notification-item.level-success { border-left-color: var(--green); }
.notification-item.level-info    { border-left-color: var(--blue); }
.notification-item.level-warning { border-left-color: var(--yellow); }
.notification-item.level-error   { border-left-color: var(--red); }
.notification-item.is-unread { background: var(--accent-soft); }
.notification-item.is-unread .notification-item-title { font-weight: 600; }
.notification-item.is-unread::after {
    content: '';
    position: absolute; top: 14px; right: 36px;
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent);
}
.notification-item-icon { font-size: 18px; flex-shrink: 0; line-height: 1.2; }
.notification-item-body { flex: 1; min-width: 0; }
.notification-item-title { font-size: 14px; font-weight: 500; line-height: 1.3; color: var(--text); }
.notification-item-msg { font-size: 12px; color: var(--text-muted); margin-top: 2px; line-height: 1.4; }
.notification-item-ago { font-size: 11px; color: var(--text-muted); margin-top: 4px; opacity: 0.7; }
.notification-item-dismiss {
    background: none; border: none; cursor: pointer;
    color: var(--text-muted); font-size: 18px; line-height: 1;
    padding: 0; width: 22px; height: 22px;
    align-self: flex-start; flex-shrink: 0;
}
.notification-item-dismiss:hover { color: var(--red); }

/* Globale Sidebar-Suche */
.sidebar-search {
    position: relative;
    padding: 8px 14px 8px;
    flex-shrink: 0;
}
.sidebar-search input[type="search"] {
    width: 100%;
    background: rgba(255, 255, 255, 0.06);
    color: var(--sidebar-text);
    border: 1px solid var(--sidebar-border);
    border-radius: 6px;
    padding: 7px 36px 7px 28px;
    font-size: 13px;
    font-family: inherit;
    outline: none;
    transition: background 0.15s, border-color 0.15s;
}
.sidebar-search input[type="search"]::placeholder { color: var(--sidebar-text-subtle); }
.sidebar-search input[type="search"]:focus {
    background: rgba(255, 255, 255, 0.1);
    border-color: var(--sidebar-border-strong);
}
.sidebar-search-icon {
    position: absolute;
    left: 22px; top: 50%; transform: translateY(-50%);
    color: var(--sidebar-text-subtle);
    font-size: 13px;
    pointer-events: none;
}
/* Eingeklappte Sidebar: Suchleiste wird zum reinen Icon-Button. Eingabe-
   feld, Kbd-Hint und Resultate werden komplett ausgeblendet — Klick aufs
   Lupen-Icon klappt die Sidebar wieder auf (siehe JS in app.blade.php). */
body.sidebar-collapsed .sidebar-search {
    padding: 4px 12px 12px;
    margin-bottom: 8px;
}
body.sidebar-collapsed .sidebar-search input[type="search"],
body.sidebar-collapsed .sidebar-search .sidebar-search-kbd,
body.sidebar-collapsed .sidebar-search .sidebar-search-results,
body.sidebar-collapsed .sidebar-search .sidebar-search-icon {
    display: none;
}
body.sidebar-collapsed .sidebar-search-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 32px;
    background: transparent;
    border: 1px solid var(--sidebar-border);
    color: var(--sidebar-text);
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
body.sidebar-collapsed .sidebar-search-btn:hover {
    background: var(--sidebar-hover);
    color: white;
    border-color: var(--sidebar-border-strong);
}
body.sidebar-collapsed .sidebar-search-btn .icon { width: 16px; height: 16px; }
/* Im aufgeklappten Zustand bleibt der Button-Trigger unsichtbar */
.sidebar-search-btn { display: none; }

/* Sidebar Quick-Actions — Capture-Pattern direkt unter der Suche */
.sidebar-quick {
    display: flex; flex-direction: column; gap: 6px;
    padding: 8px 14px 12px;
    border-bottom: 1px solid var(--sidebar-border);
    margin-bottom: 0;
}
/* Zeile aus gleich breiten Schnellaktions-Buttons (Notiz/Ticket/Zeit bzw.
   Portale/Tools). Eingeklappt stapeln sie vertikal (nur Icons). */
.sidebar-quick-row { display: flex; gap: 6px; }
body.sidebar-collapsed .sidebar-quick-row { flex-direction: column; gap: 4px; }
/* Vollbreite-Variante (z.B. Wissensdatenbank, allein in der Reihe): Icon +
   Label nebeneinander statt gestapelt. */
.sidebar-quick-wide { flex-direction: row; justify-content: center; gap: 6px; }
.sidebar-quick-btn {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 8px 4px;
    background: transparent;
    border: 1px solid var(--sidebar-border);
    border-radius: 6px;
    color: var(--sidebar-text);
    font: inherit;
    font-size: 11px;
    cursor: pointer;
    text-decoration: none;
    position: relative;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.sidebar-quick-btn:hover {
    background: var(--sidebar-hover);
    border-color: var(--sidebar-border-strong);
    color: #fff;
}
.sidebar-quick-icon { font-size: 18px; line-height: 1; }
svg.sidebar-quick-icon { width: 18px; height: 18px; stroke-width: 1.8; }
.sidebar-quick-label { font-size: 10px; letter-spacing: 0.02em; }
.sidebar-quick-badge {
    position: absolute;
    top: 2px; right: 2px;
    min-width: 16px; height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: #ef4444;
    color: white;
    font-size: 9px;
    font-weight: 700;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

/* Collapsed: nur Icon, kein Label */
body.sidebar-collapsed .sidebar-quick {
    padding: 8px 6px;
    flex-direction: column;
    gap: 4px;
}
body.sidebar-collapsed .sidebar-quick-btn {
    padding: 8px 0;
}
body.sidebar-collapsed .sidebar-quick-label { display: none; }

.sidebar-search-results {
    position: absolute;
    top: 100%; left: 8px; right: 8px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    max-height: 70vh;
    overflow-y: auto;
    z-index: 100;
    margin-top: 4px;
}
.sidebar-search-empty { padding: 14px; color: var(--text-muted); font-size: 13px; text-align: center; }
.sidebar-search-group {
    padding: 8px 12px 4px;
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
}
.sidebar-search-group:first-child { border-top: none; }
.sidebar-search-item {
    display: block;
    padding: 8px 12px;
    color: var(--text);
    text-decoration: none;
    border-top: 1px solid var(--border);
}
.sidebar-search-item:first-of-type { border-top: none; }
.sidebar-search-item:hover,
.sidebar-search-item.is-active { background: var(--accent-soft); }
.sidebar-search-item-title { font-size: 13px; font-weight: 500; }
.sidebar-search-item-sub { font-size: 11px; color: var(--text-muted); margin-top: 1px; }

.sidebar-nav {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
    /* Vertikales Padding = Ruhe-Abstand zu den Trennlinien. Beim Scrollen
       clippt overflow trotzdem exakt an der Kante (= an der Linie), die
       Module verschwinden also „hinter" der Linie statt schon davor. */
    padding: 8px; gap: 2px;
    overflow-y: auto; overflow-x: hidden;
    /* Schmaler Scrollbar passend zum dunklen Sidebar-Look */
    scrollbar-width: thin;
    scrollbar-color: var(--sidebar-border-strong) transparent;
    /* Anti-Sprung beim Page-Load:
       1) overflow-anchor: none — Browser soll nicht selbst Scroll-Position
          adjustieren, wenn Inhalt darüber wächst/schrumpft (kann z.B. durch
          Badge-Animationen passieren).
       2) scroll-behavior: auto — selbst wenn global smooth-scroll aktiv
          ist, soll der scrollTop-Restore nach Page-Load NICHT animiert
          werden (sonst sieht der User die Animation als „Sprung"). */
    overflow-anchor: none;
    scroll-behavior: auto;
}
/* Sidebar-Nav bleibt invisible, bis das Inline-Restore-Skript am Ende
   des <nav>-Tags die gespeicherte Scroll-Position gesetzt hat. Verhindert
   sicher den FOUC selbst dann, wenn der Browser zwischen DOM-Parse und
   Skript-Lauf bereits einen Frame painted hat. Das Attribut wird vom
   Skript per removeAttribute weggenommen — bei JS-Error bleibt die nav
   hidden, aber das ist im Sidebar-Kontext akzeptabel (alle Quick-Buttons
   + Brand + Profil bleiben weiterhin sichtbar). */
.sidebar-nav[data-restore-pending] { visibility: hidden; }
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb {
    background: var(--sidebar-border);
    border-radius: 3px;
}
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: var(--sidebar-border-strong); }
.nav-section {
    color: var(--sidebar-text-subtle);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    padding: 14px 12px 6px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    cursor: pointer;
    user-select: none;
    transition: color 0.12s;
}
.nav-section:hover { color: var(--sidebar-text); }
.nav-section > span:first-child {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 1;
}
.nav-section-chevron {
    display: inline-block;
    transition: transform 0.15s, opacity 0.15s;
    font-size: 13px;
    opacity: 0.85;
    margin-left: auto;
    padding: 0 4px;
    line-height: 1;
}
.nav-section:hover .nav-section-chevron { opacity: 1; }
.nav-section.is-collapsed .nav-section-chevron { transform: rotate(-90deg); }
.nav-section-cog {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 4px;
    color: var(--sidebar-text-subtle);
    text-decoration: none;
    font-size: 13px;
    line-height: 1;
    transition: background 0.12s, color 0.12s;
}
.nav-section-cog:hover { background: var(--sidebar-hover); color: white; }
.nav-section-cog.is-active { background: var(--accent); color: white; }
.nav-link {
    display: flex; align-items: center; gap: 10px;
    color: var(--sidebar-text);
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 13px;
    transition: background 0.12s, color 0.12s;
    white-space: nowrap;
}
.nav-link:hover { background: var(--sidebar-hover); color: white; }
.nav-link.is-active { background: var(--accent); color: white; }
.nav-icon { width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
/* Wenn nav-icon ein SVG (Lucide) ist statt Emoji, soll es Stroke-Currentcolor nutzen
   und exakt die definierte Größe haben (überschreibt das 1em-Default von .icon). */
svg.nav-icon { width: 18px; height: 18px; vertical-align: middle; }
.nav-label { overflow: hidden; }
body.sidebar-collapsed .nav-link { justify-content: center; padding: 8px; }
body.sidebar-collapsed .nav-label { display: none; }
body.sidebar-collapsed .nav-section { display: none; }
body.sidebar-collapsed .badge { display: none; }
body.sidebar-collapsed .sidebar-nav { padding: 8px 6px; }
.badge {
    margin-left: auto;
    background: rgba(255,255,255,0.18);
    color: white;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
}
.nav-link.is-active .badge { background: rgba(0,0,0,0.18); }
.sidebar-foot {
    border-top: 1px solid var(--sidebar-border);
    padding: 12px;
    margin-top: 0;
    flex-shrink: 0;
    background: var(--sidebar-bg);
}
.user-chip {
    display: flex; align-items: center; gap: 10px; min-width: 0;
    color: inherit; text-decoration: none;
    padding: 6px 8px;
    margin: 0 -8px;
    border-radius: 6px;
    transition: background 0.12s;
}
.user-chip:hover { background: var(--sidebar-hover); color: inherit; }
.avatar {
    width: 32px; height: 32px; border-radius: 50%;
    color: white; font-weight: 600; font-size: 12px;
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-lg { width: 72px; height: 72px; font-size: 22px; }
.avatar-edit {
    display: flex; gap: 16px; align-items: center;
    padding: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 14px;
}
.avatar-edit-fields { flex: 1; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.avatar-edit-fields .form-row { margin: 0; }
.avatar-edit-fields .form-row > span {
    display: block;
    font-size: 11px; color: var(--text-muted);
    text-transform: uppercase; letter-spacing: 0.04em;
    margin-bottom: 4px;
}
/* line-height 1.4 statt 1.2 — sonst beißt overflow:hidden Descender
   wie g / p / y in der unteren Linie ab. */
.user-meta { line-height: 1.4; min-width: 0; overflow: hidden; }
.user-name { font-size: 13px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role { font-size: 11px; color: var(--sidebar-text-subtle); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-actions {
    display: flex; gap: 6px;
    /* Trennlinie zwischen User-Chip und Logout/Design — full-width wie die
       übrigen Sidebar-Linien (negativer Rand hebt das Foot-Padding auf,
       Padding rückt die Buttons wieder ein). */
    margin: 12px -12px 0;
    padding: 12px 12px 0;
    border-top: 1px solid var(--sidebar-border);
}
.sidebar-action-form { flex: 1; display: flex; margin: 0; padding: 0; }
.sidebar-action {
    flex: 1;
    display: inline-flex; align-items: center; justify-content: center;
    gap: 6px;
    background: transparent;
    border: 1px solid var(--sidebar-border);
    color: var(--sidebar-text);
    padding: 6px 10px;
    border-radius: 6px;
    font: inherit;
    font-size: 12px;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    white-space: nowrap;
}
.sidebar-action:hover { background: var(--sidebar-hover); color: white; border-color: var(--sidebar-border-strong); }
.sidebar-action .nav-icon { width: 14px; font-size: 13px; }


body.sidebar-collapsed .sidebar-foot { padding: 12px 8px; }
body.sidebar-collapsed .user-chip { justify-content: center; }
body.sidebar-collapsed .user-meta { display: none; }
body.sidebar-collapsed .sidebar-actions { flex-direction: column; gap: 4px; }
body.sidebar-collapsed .sidebar-action { padding: 6px; }
body.sidebar-collapsed .sidebar-action .nav-label { display: none; }

/* Main area — bricht VERTIKAL aus dem 12px-Layout-Padding aus, damit
   die scrollbare Fläche die volle Viewport-Höhe nutzt. Die Sidebar
   floatet weiter mit ihrem Rahmen, weil sie das Padding-Frame der
   Layout-Shell mitmacht. Negative Margins extendieren main über die
   Grid-Cell-Grenzen hinaus; inner padding (12px oben/unten) gibt dem
   Content trotzdem Atemraum, damit Topbar nicht direkt am Edge klebt. */
.main {
    margin: -12px -12px -12px 0;
    height: 100vh;
    box-sizing: border-box;
    /* .main selbst scrollt NICHT mehr. Es ist nur noch der Flex-Container
       für die zwei Zonen .main-fixed (oben, fix) und .main-scroll (unten,
       scrollbar). So bleiben Banner + Topbar dauerhaft im Viewport. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
}
/* Obere Zone: Banner-Stack + Topbar. Scrollt nicht mit, bleibt fix
   oben. Horizontales + oberes Padding kommt hier rein, damit die
   Karten-Optik der Topbar sauber im Layout-Rahmen sitzt. */
.main-fixed {
    flex: 0 0 auto;
    padding: 12px 28px 0;
    box-sizing: border-box;
    /* Damit die Sticky-Stat-Kacheln darunter beim Scrollen sauber UNTER
       diese Zone gleiten und nicht hindurchscheinen — sie haben eigenen
       Background, .main-fixed liegt davor in z-Reihenfolge. */
    position: relative;
    z-index: 10;
}
/* Untere Zone: einziger Scroll-Container. Bottom-Padding ist groß (96px)
   damit FABs (notification-fab + clock-fab, je 56×56 mit bottom: 24px)
   am unteren Viewport-Rand keinen Content verdecken. */
.main-scroll {
    flex: 1 1 auto;
    min-height: 0;        /* sonst kollabiert flex-Kind nicht und scrollt nicht */
    padding: 0 28px 96px;
    box-sizing: border-box;
    overflow-y: auto;
    overflow-x: hidden;
    /* Scrollbar-Platz dauerhaft reservieren — sonst springt die Content-
       Breite, sobald sich die Seitenhöhe ändert (z.B. wenn in der
       Abrechnung Zeiten bestätigt/zurückgenommen werden und die Scrollbar
       erscheint/verschwindet). */
    scrollbar-gutter: stable;
    /* Anker-Sprünge sollen nicht hinter Sticky-Stat-Kacheln landen — die
       paar Pixel reichen, weil die fixe Topbar schon außerhalb des Scroll-
       Bereichs liegt. */
    scroll-padding-top: 8px;
    scroll-padding-bottom: 96px;
}
/* Stat-Card-Kacheln am Anfang der Content-Spalte werden an die Oberkante
   geheftet. :has(.stat-card) sorgt dafür, dass „normale" Card-Grids
   (z.B. auf Show-Seiten) NICHT ungewollt sticky werden.
   Kein extra Padding/Margin: damit JS exakt offsetHeight + flex-gap + 1px
   border = thead.natural-Y rechnen kann und der Thead ohne Jitter
   einrastet. */
.content > .cards-grid:first-child:has(.stat-card) {
    position: sticky;
    top: 0;
    z-index: 8;  /* ÜBER dem Sticky-Thead (z=7): wenn der Thead nach dem
                    Tabellen-Ende „entrastet" und nach oben scrollt, soll
                    er hinter den Stat-Kacheln verschwinden, nicht über
                    sie hinweg bis zur Topbar gleiten. */
    background: var(--bg);
}
/* Topbar als schwebende Karte — Optik passt zur Sidebar und zu den Cards.
   Vorher hatte sie nur eine Bottom-Border, was bei schwebender Sidebar
   visuell unstimmig wirkte. */
.topbar {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    margin-bottom: 14px;
}
.topbar-titles-wrap { display: flex; align-items: center; gap: 14px; min-width: 0; flex: 1 1 auto; }
.topbar-titles { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/* Zurück-Button links neben Page-Title. Wird automatisch vom Layout
   eingeblendet wenn die aktuelle Route nach Resource-Konvention einen
   logischen Parent hat (*.show → *.index, *.edit → *.show / *.index,
   *.create → *.index). Override per @section('back_url'/'back_hide'). */
.page-title-back {
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 36px; height: 36px;
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--text-muted);
    background: var(--bg);
    text-decoration: none;
    flex: none;
    transition: background 0.12s, color 0.12s, border-color 0.12s, transform 0.12s;
}
.page-title-back:hover {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: var(--accent);
    transform: translateX(-2px);
}
.page-title-back .icon { width: 18px; height: 18px; }

.page-title { font-size: 20px; font-weight: 600; margin: 0; }
.page-title .icon, .page-title svg.icon, svg.page-title-icon {
    width: 22px; height: 22px;
    vertical-align: -4px;
    stroke-width: 1.8;
    color: var(--accent);
    margin-right: 8px;
}
.page-subtitle { font-size: 14px; color: var(--text-muted); }
.page-subtitle a { color: var(--accent); font-weight: 600; }
.page-subtitle a:hover { color: var(--accent-strong); text-decoration: underline; }
.topbar-actions { display: flex; gap: 8px; align-items: flex-start; }
.content { display: flex; flex-direction: column; gap: 18px; }

/* Admin-Bereich (Routes admin.*, roles.*, users.*, audit.*): Content-
   Spalte wird auf 900 px begrenzt + zentriert. Konsistent mit der
   .form-narrow-Konvention für Einzelspalten-Formulare. Geltungsbereich
   wird über die `is-admin-area`-Body-Class aus layouts/app.blade.php
   gesteuert; siehe Kommentar dort. */
body.is-admin-area .content {
    max-width: 900px;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

/* Buttons */
.btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 14px;
    border-radius: 6px;
    font-family: inherit;
    font-size: 13px; font-weight: 500;
    /* box-sizing explizit: <button>-Elemente erben UA-Default border-box,
       <a> nutzt content-box vom globalen Default. Bei expliziter width/
       height (z.B. Topbar-Icon-Only-Buttons) ergibt das sonst je 1px
       Differenz pro Border → Button rendert sichtbar tiefer als der
       Link daneben. Border-box vereinheitlicht beides. */
    box-sizing: border-box;
    /* line-height explizit setzen — sonst rendern <button>-Elemente
       browserseitig mit line-height:normal (= ~15px bei 13px Schrift),
       während <a class="btn"> die 1.5 vom Body erbt → sichtbarer
       Höhen-Unterschied. */
    line-height: 1.5;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    transition: all 0.1s;
}
.btn:hover { border-color: var(--text); color: var(--text); }
.btn-primary { background: var(--accent); border-color: var(--accent); color: white; }
.btn-primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: white; }
.btn-danger { background: var(--red); border-color: var(--red); color: white; }
.btn-danger:hover { background: #b13333; color: white; }
.btn-success { background: var(--green); border-color: var(--green); color: white; }
.btn-success:hover { background: #268a3a; border-color: #268a3a; color: white; }
/* Aktiver Zustand für Toggle-Buttons (z.B. View-Switcher in der Topbar):
   gleiche Größe wie ein normaler .btn, aber per Akzent abgesetzt — bewusst
   NICHT voll gefüllt wie der Primary-CTA. */
.btn.is-active { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.btn.is-active:hover { border-color: var(--accent-strong); color: var(--accent-strong); }
.btn-sm { padding: 4px 10px; font-size: 12px; }

/* Segmented Toggle — zusammenhängende Button-Gruppe, optisch ein langer
   Button mit Trennlinien (z.B. Rollen-Filter Lieferant/Partner/Beide in der
   Topbar). Generisch gehalten, funktioniert mit <a> wie mit <button>. Das
   aktive Segment ist akzentuiert. */
.seg-toggle {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
}
.seg-btn {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--surface);
    border: none;
    /* Maße bewusst identisch zu .btn (padding/font/line-height), damit der
       Toggle exakt so hoch ist wie die Buttons daneben. Der 1px-Rahmen sitzt
       am Container .seg-toggle, deshalb hier randlos. */
    padding: 7px 14px;
    font: inherit; font-size: 13px; font-weight: 500; line-height: 1.5;
    color: var(--text-muted);
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.12s, color 0.12s;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--border); }
.seg-btn:hover { background: var(--surface-2); color: var(--text); }
.seg-btn.is-active,
.seg-btn.is-active:hover { background: var(--accent); color: #fff; }
/* Deaktivierte Buttons: ausgegraut, kein Hover-Effekt, nicht klickbar. */
.btn:disabled,
.btn[disabled] { opacity: 0.45; cursor: not-allowed; pointer-events: none; }
.btn-primary:disabled,
.btn-primary[disabled] { background: var(--accent); border-color: var(--accent); }

/* Topbar-Primary-Buttons systemweit als Icon-Only. Text bleibt im DOM
   (für Screen-Reader + title-Tooltip), wird aber visuell auf 0 gesetzt;
   <svg.icon> behält seine Größe über width/height.
   Selector [title]: nur Buttons mit Hover-Tooltip — das markiert die
   echten Action-Buttons. Tab-/Toggle-Buttons (clock-Index: Heute/Woche/
   Monat) und Filter-Panel-Buttons („Anwenden") haben kein title und
   bleiben mit Label sichtbar. */
/* Topbar-Actions: feste min-height + Kinder vertikal zentrieren statt
   flex-start. Damit hat der Container immer die gleiche Cross-Size,
   egal ob ein einzelner Icon-Only-Button drin sitzt (34px) oder ein
   Filter+Primary-Kombo (~35-36px). Sub-Pixel-Rundung beim Top-Level-
   Centering der Topbar führte sonst zu 0.5-1px Versatz wenn der
   Primary-Button alleine in den Actions stand (z.B. Telefonnotizen). */
.topbar-actions { min-height: 36px; align-items: center; }

/* Alle direkten Topbar-Aktions-Controls exakt gleich hoch (36px). Die
   Icon-Only-Primary-Quadrate sind bereits 36px; labeled .btn (~35.5px),
   Dropdown-/Filter-Summaries und Segment-Toggles wurden vorher sub-pixel
   niedriger gerendert → sichtbar „zu niedrig". min-height vereinheitlicht.
   Nur direkte Kinder — Buttons innerhalb von Dropdown-/Filter-Popovers
   (z.B. „Anwenden", „PDF erzeugen") behalten ihre Größe. */
.topbar-actions > .btn,
.topbar-actions > .dropdown-menu > summary.btn,
.topbar-actions > .list-filter > summary.btn,
.topbar-actions > .seg-toggle,
.topbar-actions > form > .btn { min-height: 36px; }

/* Quadratischer Icon-Only-Button. 34×34px, Text bleibt im DOM auf
   font-size:0; gap:0 + justify-content:center sorgen dafür dass das
   Icon trotz unsichtbarem Text-Knoten exakt mittig sitzt. */
.topbar-actions .btn-primary[title] {
    font-size: 0;
    line-height: 1;
    gap: 0;
    margin: 0;
    /* 36px = gerundete Hoehe der weissen .btn-Controls daneben (border 2 +
       padding 14 + line-height 19.5 = 35.5). Vorher 34px -> der orange
       Primary wirkte minimal „zu niedrig". Mobil ist via .btn:has(.icon)
       ohnehin schon 36px. */
    width: 36px;
    height: 36px;
    padding: 0;
    justify-content: center;
}
/* .icon ist normalerweise 1em groß — mit font-size:0 würde es auf 0×0
   schrumpfen und unsichtbar werden. Explizite Pixel-Größe macht
   das Icon wieder sichtbar. */
.topbar-actions .btn-primary[title] .icon {
    width: 16px;
    height: 16px;
    margin: 0;
}
/* Icon-only Dropdown-Summary (z.B. ⋯-Overflow) in der Topbar: quadratisch
   36×36 wie die Icon-Buttons daneben (Stift/Primary), statt breiter .btn-Pille. */
.topbar-actions > .dropdown-menu > summary.btn-icon {
    width: 36px; height: 36px; min-height: 36px; padding: 0;
    gap: 0; justify-content: center;
}
.topbar-actions > .dropdown-menu > summary.btn-icon .icon {
    width: 16px; height: 16px; margin: 0;
}

/* Dropdown-Menü (HTML <details>) */
.dropdown-menu { position: relative; display: inline-block; }
.dropdown-menu > summary {
    list-style: none;
    user-select: none;
}
.dropdown-menu > summary::-webkit-details-marker { display: none; }
.dropdown-menu > summary::marker { content: ''; }
.dropdown-menu[open] > summary { border-color: var(--accent); color: var(--accent); }
.dropdown-menu-list {
    position: absolute;
    top: calc(100% + 4px); right: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    min-width: 320px;
    list-style: none;
    margin: 0; padding: 4px;
    z-index: 100;
}
.dropdown-menu-list li { margin: 0; }
.dropdown-menu-list a,
.dropdown-menu-list button {
    display: block;
    width: 100%;
    padding: 8px 12px;
    color: var(--text);
    text-decoration: none;
    background: none; border: none;
    border-radius: 6px;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: 13px;
    transition: background 0.1s;
}
.dropdown-menu-list a:hover,
.dropdown-menu-list button:hover { background: var(--surface-2); }
.dropdown-menu-list strong { display: block; font-weight: 600; color: var(--text); }
.dropdown-menu-list span { display: block; font-size: 11px; color: var(--text-muted); margin-top: 2px; }

/* Cards */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 18px;
    box-shadow: var(--shadow-sm);
}
.card h2, .card h3 { margin: 0 0 12px; font-size: 15px; }

/* Icon vor einer Card-Headline — dezent, in Akzentfarbe. Gilt sowohl wenn
   das Icon als <x-icon class="card-h-icon"/> in einem <h3> sitzt als auch
   wenn ein bloßes <svg> direkt im h3 platziert ist (Skript-Migration). */
.card h2 svg.card-h-icon, .card h3 svg.card-h-icon,
.card h2 > svg.icon:first-child, .card h3 > svg.icon:first-child {
    width: 16px; height: 16px;
    color: var(--accent);
    vertical-align: -3px;
    margin-right: 6px;
    flex-shrink: 0;
}

.cards-grid {
    display: grid;
    /* Default-Min: 240px — bei <980px greift max 2 Kacheln, <600px nur 1.
       Vorher waren 180px → drei Kacheln passten auch noch bei sehr engen
       Viewports und sahen gequetscht aus. */
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 14px;
}
@media (max-width: 980px) {
    .cards-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .cards-grid { grid-template-columns: 1fr; }
    .stat-card { height: auto; min-height: 100px; }
}
.stat-card {
    display: flex;
    flex-direction: column;
    min-height: 120px;     /* statt fixe height — Karten mit stat-sub
                              (z.B. Arbeitszeiten „Arbeit heute") brauchen
                              etwas mehr Platz und sollen nicht clippen */
    overflow: hidden;
    position: relative;    /* Anker für stat-card-icon oben rechts */
}
.stat-card .stat-value { font-size: 26px; font-weight: 700; margin-top: 4px; }
.stat-card .stat-label { color: var(--text-muted); font-size: 12px; padding-right: 32px; }

/* Dezenter Kontext-Hinweis oben rechts in der Kachel.
   Folgt currentColor; pro Kachel wird die Farbe ggf. inline gesetzt. */
.stat-card-icon {
    position: absolute;
    top: 14px;
    right: 16px;
    width: 22px;
    height: 22px;
    color: var(--accent);
    opacity: 0.5;
    pointer-events: none;
    transition: opacity 0.12s, transform 0.12s;
}
.stat-card-link:hover .stat-card-icon { opacity: 0.9; transform: scale(1.05); }

/* Tables */
/* `overflow: clip` statt `hidden` — clip schneidet weiterhin sauber an den
   abgerundeten Ecken, erzeugt aber KEINEN Scroll-Container. Damit kann der
   sticky <th> seinen Scroll-Anker bis zu .main-scroll durchreichen und
   beim Scrollen am oberen Rand kleben bleiben.

   KEINE 1px-border am Wrapper: die liefe sonst vertikal an der Seite
   neben dem Sticky-Thead und wäre auf jeder Index-Seite mit Tabelle
   sichtbar (das war das „schmale Striche links/rechts"-Problem). Die
   Tabelle hebt sich auch ohne Border klar vom Body-Background ab —
   Surface (#fff bzw. #1d2125) vs Body (#f5f5f3 bzw. #14171a). */
.table-wrap { background: var(--surface); border-radius: var(--radius-lg); overflow: clip; }
/* border-collapse: separate (statt collapse) — sonst rendert
   border-radius an einzelnen Zellen nicht. Wird gebraucht, damit der
   Sticky-Thead seine Eck-Rundungen behält, wenn der Wrapper darüber
   rausscrollt. border-spacing: 0 hält das Bild visuell identisch zu
   collapse. */
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.table th, .table td { padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--border); }
.table th {
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    height: 38px;
    line-height: 1;
    vertical-align: middle;
}
/* Sticky Thead NUR für Tabellen in .table-wrap. Rohe <table class="table">
   in .card oder anderen Containern (z.B. clock/index, customers/show)
   scrollen normal mit ihrem Container — sonst entstünden Notch- und
   Hintergrund-Artefakte, weil das ::before-Eckmasking var(--bg) annimmt
   und die Karten-Hintergründe var(--surface) sind.

   Wenn die Seite oben Stat-Kacheln hat, stapelt sich der Thead darunter
   — die Variable wird per JS aus der Höhe des Sticky-Stat-Blocks + Flex-
   Gap gesetzt (siehe layouts/app.blade.php). Default 1px kompensiert
   sub-pixel-Rendering. z-index 7 sitzt ÜBER dem Sticky-Stats-Block
   (z=6), damit der Thead trotz dessen Padding-Overlay sichtbar bleibt. */
.table-wrap .table thead th {
    position: sticky;
    top: var(--sticky-stack-top, 1px);
    z-index: 7;
}
/* Sticky-Thead mit Eck-Rundungen.
   Für Index-Seiten, wo cards-grid direkt vor der Tabelle steht
   (z.B. Tickets), deckt das Stats-Overlay die komplette Thead-Höhe
   ab und kümmert sich um den Notch außerhalb der Rundung.
   Für Index-Seiten mit Zwischensektionen (z.B. Abrechnung: h2's
   zwischen Stat-Kacheln und mehreren Tabellen) gibt es kein
   Stats-Overlay über dem Thead — der Eck-Notch würde sonst Tbody-
   Zeilen durchscheinen lassen. Lösung: ::before am Eck-th mit
   radialem Gradient maskiert das Eck-Dreieck selber mit var(--bg).
   Bei Tickets ist das harmlos redundant (Stats deckt ohnehin ab),
   bei Abrechnung übernimmt das Pseudo die Maskierung. */
.table-wrap .table thead tr:first-child th:first-child {
    border-top-left-radius: var(--radius-lg);
}
.table-wrap .table thead tr:first-child th:last-child {
    border-top-right-radius: var(--radius-lg);
}
.table-wrap .table thead tr:first-child th:first-child::before,
.table-wrap .table thead tr:first-child th:last-child::before {
    content: '';
    position: absolute;
    top: 0;
    width: var(--radius-lg);
    height: var(--radius-lg);
    pointer-events: none;
}
.table-wrap .table thead tr:first-child th:first-child::before {
    left: 0;
    background: radial-gradient(circle at bottom right,
                                transparent var(--radius-lg),
                                var(--bg) var(--radius-lg));
}
.table-wrap .table thead tr:first-child th:last-child::before {
    right: 0;
    background: radial-gradient(circle at bottom left,
                                transparent var(--radius-lg),
                                var(--bg) var(--radius-lg));
}
.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-2); }
.table tbody tr[data-row-href], .table tbody tr[data-row-modal] { cursor: pointer; }
.table tbody tr[data-row-href]:hover, .table tbody tr[data-row-modal]:hover { background: var(--accent-soft); }

/* Toggle Switch (Checkbox als Slider) */
.toggle-switch {
    position: relative;
    display: inline-block;
    width: 42px; height: 22px;
    flex-shrink: 0;
}
.toggle-switch input { opacity: 0; width: 0; height: 0; position: absolute; }
.toggle-switch .slider {
    position: absolute; cursor: pointer; inset: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 22px;
    transition: background 0.15s, border-color 0.15s;
}
.toggle-switch .slider::before {
    position: absolute; content: "";
    height: 16px; width: 16px;
    left: 2px; bottom: 2px;
    background: white;
    border-radius: 50%;
    transition: transform 0.15s;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.toggle-switch input:checked + .slider {
    background: var(--accent);
    border-color: var(--accent);
}
.toggle-switch input:checked + .slider::before {
    transform: translateX(20px);
}
.toggle-switch input:focus-visible + .slider {
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Arbeitszeit-Plan (Mitarbeiter-Formular) — Wochentage als Tabelle mit
   Toggle-Switch pro Tag. Inaktive Tage werden dezent abgeblendet. */
.schedule-table td { vertical-align: middle; }
.schedule-table .schedule-toggle-cell { text-align: center; }
.schedule-table .schedule-day { font-weight: 500; }
.schedule-table input[type="number"],
.schedule-table input[type="time"] { width: 100%; }
.schedule-table tr.is-inactive td:not(.schedule-toggle-cell) { opacity: 0.45; }

/* Permission list — gruppierte Schalter mit Beschreibung */
.permission-group { margin-bottom: 18px; }
.permission-group-title {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    margin: 0 0 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border);
}
.permission-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px dashed var(--border);
}
.permission-row:last-child { border-bottom: none; }
.permission-row-text { flex: 1; min-width: 0; }
.permission-row-label { font-weight: 500; color: var(--text); }
.permission-row-desc { color: var(--text-muted); font-size: 12px; margin-top: 2px; }
.permission-row-code {
    font-family: ui-monospace, monospace;
    font-size: 10px;
    color: var(--text-muted);
    opacity: 0.6;
    margin-left: 6px;
}

/* Pills / status */
.pill {
    display: inline-block; padding: 2px 10px;
    border-radius: 10px;
    font-size: 11px; font-weight: 600;
    background: #eee; color: #555;
}
.pill-red { background: #fde7e7; color: #b13333; }
.pill-yellow { background: #fef3c7; color: #92651b; }
.pill-green { background: #d4f4dd; color: #226e3a; }
.pill-blue { background: #dbe9ff; color: #1e3a8a; }
.pill-gray { background: #ececec; color: #555; }

/* Pagination-Footer mit Per-Page-Selector ----------------------------------- */
.pager-bar {
    display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
    margin: 14px 0 4px; padding: 8px 0;
    border-top: 1px solid var(--border);
    font-size: 13px;
}
.pager-meta { color: var(--text-muted); }
.pager-meta strong { color: var(--text); }
.pager-perpage { display: inline-flex; align-items: center; gap: 4px; }
.pager-perpage-link {
    display: inline-block; padding: 3px 9px; border-radius: 4px;
    font-size: 12px; font-weight: 600; text-decoration: none;
    color: var(--text-muted); background: transparent;
    border: 1px solid var(--border);
}
.pager-perpage-link:hover { background: var(--surface-2); color: var(--text); }
.pager-perpage-link.is-active {
    background: var(--accent); border-color: var(--accent); color: white; cursor: default;
}
.pager-links { margin-left: auto; }

/* Support-ID puzzle pieces ----------------------------------------------------
   Kunden-ID + Geräte-ID = Support-ID. Die zwei Bestandteile werden farblich
   und durch eine Chevron-/V-Form so dargestellt, dass sie ineinandergreifen,
   wenn sie zur Support-ID kombiniert werden. Standalone (z.B. Kunden-ID auf
   der Kunden-Show) signalisieren die Formen, dass es ein Bestandteil einer
   längeren Kette ist.
*/
.support-id-pair { display: inline-flex; align-items: stretch; line-height: 1; }
.support-id-piece {
    display: inline-block; padding: 5px 11px;
    font: 600 13px/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: 0.06em; color: white; white-space: nowrap;
}
.support-id-piece.kunde {
    background: var(--blue); padding-right: 17px;
    clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 0 100%);
}
.support-id-piece.geraet {
    background: var(--accent); padding-left: 17px;
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 8px 50%);
}
.support-id-pair .support-id-piece.geraet { margin-left: -8px; }

/* Forms */
.form-row { display: grid; gap: 6px; margin-bottom: 14px; }
.form-row label { font-size: 12px; font-weight: 500; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.form-row input[type=text],
.form-row input[type=email],
.form-row input[type=password],
.form-row input[type=number],
.form-row input[type=date],
.form-row input[type=datetime-local],
.form-row input[type=time],
.form-row input[type=file],
.form-row select,
.form-row textarea {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    min-height: 36px;
    box-sizing: border-box;
    /* width:100% zwingt das Feld auf die Container-/Grid-Spalten-Breite.
       Ohne das nimmt z.B. ein <select> seine intrinsische Breite (=
       längste Option, etwa ein langer Ticket-Titel) an und überläuft im
       2-spaltigen form-grid die Spalte → Überlappung mit dem Nachbarfeld,
       besonders im schmalen Modal-Kontext. */
    width: 100%;
}
/* form-grid-Zellen dürfen unter ihre intrinsische Content-Breite
   schrumpfen — sonst hilft width:100% am Feld nichts, weil die Zelle
   selbst von einem langen Select aufgebläht würde. */
.form-grid > .form-row { min-width: 0; margin-bottom: 0; }
/* Info-Hinweis hinter Feld-Labels (x-info-tip) — kompaktes „i", Beschreibung
   als nativer Tooltip beim Hovern. Ersetzt lange <small>-Hilfetexte unter
   den Feldern, die sonst die Formularhöhe aufblähen. */
.info-tip {
    display: inline-flex; align-items: center; vertical-align: middle;
    margin-left: 5px; color: var(--text-muted); cursor: help;
}
.info-tip > .icon { width: 14px; height: 14px; }
.info-tip:hover, .info-tip:focus-visible { color: var(--accent); outline: none; }
/* In Labels (uppercase) den Tooltip-Text nicht großschreiben/spacen erben. */
label .info-tip { text-transform: none; letter-spacing: 0; }
/* Popover-Bubble — hängt am <body> (per JS positioniert), damit sie in
   scrollenden Overlays nicht abgeschnitten wird. Erscheint bei Hover,
   Klick (Toggle) und Tastatur-Fokus. */
.info-tip-pop {
    position: fixed; z-index: var(--z-tooltip); max-width: 260px;
    background: var(--text); color: var(--bg);
    padding: 8px 11px; border-radius: 7px;
    font-size: 12px; line-height: 1.45; font-weight: 400;
    text-transform: none; letter-spacing: 0; text-align: left;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
    opacity: 0; transform: translateY(4px);
    transition: opacity 0.12s ease, transform 0.12s ease;
    pointer-events: none;
}
.info-tip-pop.is-visible { opacity: 1; transform: translateY(0); }
.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus {
    outline: 2px solid var(--accent-soft);
    border-color: var(--accent);
}
.form-row textarea { min-height: 64px; resize: vertical; }
.form-row small { font-size: 11px; }
/* Standalone-Eingabefeld außerhalb einer .form-row (z.B. Inline-Felder in
   Modals): derselbe abgerundete Look wie Formularfelder, aber OHNE erzwungene
   100%-Breite — die Breite bestimmt der Kontext (Flex/inline max-width).
   Vermeidet, dass blanke <input> auf den eckigen Browser-Default zurückfallen. */
.input-text {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    min-height: 36px;
    box-sizing: border-box;
}
.input-text:focus {
    outline: 2px solid var(--accent-soft);
    border-color: var(--accent);
}
/* minmax(0, 1fr) statt 1fr — lange Select-Optionen (z.B. „WYLD-Ticket-
   2026-09-15 · Sehr langer Titel des Tickets") können sonst die intrinsische
   Grid-Spalten-Breite über 1fr hinaus pushen und das ganze Layout breiter
   machen als der Container — speziell in Modals führt das zu seitlichem
   Scroll. */
/* align-items: start — sonst strecken sich Felder auf die Höhe der
   höchsten Zelle einer Reihe (z.B. wenn das Nachbarfeld einen Hilfetext
   <small> hat). Das machte u.a. das Kundennummer-Feld unnötig hoch. */
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px 18px; align-items: start; }
/* Standard content/form layout when there's no right-anchored sidebar.
   900 px ist die kanonische Hauptspalten-Breite — gleichzeitig die
   Breite der linken Spalte auf zweispaltigen Detail-Seiten (siehe
   `.ticket-detail`). Auf der Detail-Seite kommt rechts noch eine
   ~466 px Sidebar dazu (Gesamt-Container max-width: 1380 px); auf
   Einspalten-Seiten zentriert sich `.form-narrow` mittig in der
   verfügbaren Content-Area. Pages mit eigener Sidebar nutzen ihren
   eigenen Grid (siehe `.ticket-detail`). */
.form-narrow {
    width: 100%;
    max-width: 900px;
    margin: 0 auto;
    align-self: center;
}
@media (max-width: 720px) {
    .form-grid, .form-grid-3 { grid-template-columns: 1fr; }
}

/* Tighter inputs inside data tables (master/edit rows) */
.table input[type=text],
.table input[type=email],
.table input[type=number],
.table input[type=date],
.table input[type=datetime-local],
.table input[type=color],
.table select,
.table textarea {
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: 5px;
    font-size: 12px;
    font-family: inherit;
    background: var(--surface);
    color: var(--text);
    width: 100%;
    box-sizing: border-box;
    min-height: 32px;
}
.table input:focus, .table select:focus, .table textarea:focus {
    outline: 2px solid var(--accent-soft);
    border-color: var(--accent);
}

/* Hidden helper */
.hidden { display: none !important; }

/* Stat-card link variant */
.stat-card-link { text-decoration: none; color: inherit; transition: transform 0.12s, box-shadow 0.12s; display: block; }
.stat-card-link:hover { transform: translateY(-2px); box-shadow: var(--shadow); color: inherit; }
.stat-card .stat-sub { color: var(--text-muted); font-size: 12px; margin-top: 4px; }

/* ===================== Dashboard ===================== */

/* Begrüßung oben — tageszeit-abhängiger Gradient als Card-Hintergrund.
   Keine Szene, keine Animation: nur Farbe, die zur Tageszeit passt. */
.dashboard-greeting {
    display: flex; align-items: center; justify-content: space-between; gap: 18px;
    margin-bottom: 14px;
    padding: 18px 22px;
}
.dashboard-greeting .greeting-hi {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    color: var(--text);
}
.dashboard-greeting .greeting-name {
    color: var(--accent);
    font-weight: 700;
}
.dashboard-greeting .greeting-sub {
    margin: 4px 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

/* Dynamisches Briefing — Fließtext-Absatz mit hervorgehobenen Zahlen
   und Namen. Ersetzt den vorherigen einzeiligen greeting-sub-Text und
   das frühere Stichpunkt-Format. */
.greeting-briefing {
    margin: 8px 0 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--text);
    max-width: 70ch;
}
.greeting-briefing strong { font-weight: 600; }
.dashboard-greeting--night .greeting-briefing { color: rgba(243, 245, 255, 0.92); }
.dashboard-greeting .greeting-meta {
    text-align: right;
    flex-shrink: 0;
}
.dashboard-greeting .greeting-date {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: capitalize;
}
.dashboard-greeting .greeting-time {
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 24px;
    color: var(--text);
    line-height: 1.1;
}

/* Phasen-Gradienten — Stimmung kommt aus dem Farbverlauf, Text bleibt lesbar.
   Die hellen Varianten haben fixe Pastell-Hintergründe (theme-unabhängig)
   → Text-Variablen werden lokal auf dunkle Töne gepinnt, sonst würde im
   Dark-Mode ein helles var(--text) auf hellem Pastell-Gradient enden. */
.dashboard-greeting--dawn    { background: linear-gradient(110deg, #ffd9b3 0%, #ffe9d1 45%, #fff5e6 100%); }
.dashboard-greeting--morning { background: linear-gradient(110deg, #fff4cc 0%, #e7f3ff 50%, #cfe6ff 100%); }
.dashboard-greeting--day     { background: linear-gradient(110deg, #d6ecff 0%, #b9dcff 60%, #9ccaff 100%); }
.dashboard-greeting--evening { background: linear-gradient(110deg, #ffc99a 0%, #f3a5b8 55%, #c994d4 100%); }
.dashboard-greeting--night   { background: linear-gradient(110deg, #2c3458 0%, #404a78 55%, #5762a3 100%); }

.dashboard-greeting--dawn,
.dashboard-greeting--morning,
.dashboard-greeting--day,
.dashboard-greeting--evening {
    --text: #1a1d22;
    --text-muted: #4a5260;
}

/* Nacht-Variante ist dunkel — Text und Akzentfarbe invertieren. */
.dashboard-greeting--night .greeting-hi,
.dashboard-greeting--night .greeting-time { color: #f3f5ff; }
.dashboard-greeting--night .greeting-sub,
.dashboard-greeting--night .greeting-date { color: rgba(243, 245, 255, 0.72); }
.dashboard-greeting--night .greeting-name { color: #ffb98a; }

/* Etwas kleinere KPI-Tiles auf dem Dashboard */
/* .cards-grid-compact wurde entfernt — Dashboard nutzt jetzt das
   Standard-Cards-Grid für konsistente Höhe + Abstände im ganzen System. */

/* Zweispaltige Panel-Reihe */
.dashboard-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    margin-bottom: 14px;
}
@media (max-width: 980px) {
    .dashboard-row { grid-template-columns: 1fr; }
}
.dashboard-stack { display: flex; flex-direction: column; gap: 14px; }

.dashboard-panel { padding: 16px 18px; }
.dashboard-panel .panel-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}
.dashboard-panel .panel-head h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}
.dashboard-panel .panel-link {
    font-size: 12px;
    color: var(--text-muted);
    text-decoration: none;
}
.dashboard-panel .panel-link:hover { color: var(--accent); }

/* „Mein Tag" — 3-spaltiges Mini-Grid */
.my-day-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
}
@media (max-width: 540px) {
    .my-day-grid { grid-template-columns: 1fr; }
}
.my-day-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    margin-bottom: 6px;
}
.my-day-value {
    font-size: 20px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}
.my-day-sub {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 4px;
}

/* Anwesenheit */
.presence-stats {
    display: flex; gap: 22px;
    margin-bottom: 12px;
}
.presence-stats > div {
    display: flex; align-items: baseline; gap: 6px;
}
.presence-count {
    font-size: 22px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--green);
}
.presence-label {
    font-size: 12px;
    color: var(--text-muted);
}
.presence-empty {
    color: var(--text-muted);
    font-size: 13px;
    font-style: italic;
}
.presence-list {
    display: flex; flex-wrap: wrap; gap: 6px;
}
.presence-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 10px 3px 3px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 20px;
    font-size: 12px;
    position: relative;
}
.presence-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px;
    border-radius: 50%;
    color: white;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    flex-shrink: 0;
}
.presence-name { color: var(--text); }
.presence-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* Mini-Listen (Tickets, Geburtstage, Notifications — kompakt statt Tabelle) */
.mini-list { list-style: none; margin: 0; padding: 0; }
.mini-list-item {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}
.mini-list-item:last-child { border-bottom: none; }
.mini-list-no {
    flex-shrink: 0;
    min-width: 64px;
    font-weight: 600;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}
.mini-list-no:hover { text-decoration: underline; }
.mini-list-title {
    flex: 1;
    min-width: 0;
    color: var(--text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
a.mini-list-title:hover { color: var(--accent); }
.mini-list-meta {
    flex-shrink: 0;
    color: var(--text-muted);
    font-size: 12px;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pill-sm {
    padding: 1px 7px;
    font-size: 10px;
}

/* Geburtstag-heute besonders hervorheben */
.birthday-today {
    background: linear-gradient(135deg, rgba(254,89,0,0.07), var(--surface));
    border-left: 3px solid var(--accent);
}
.birthday-line {
    padding: 6px 0;
    font-size: 13px;
    color: var(--text);
}

/* Meta-list (definition list for ticket overview etc.) */
.meta-list { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0; }
.meta-list dt { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; align-self: start; }
.meta-list dd { margin: 0; font-size: 13px; }
.meta-label { font-size: 11px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }
.pill-row { display: flex; flex-wrap: wrap; gap: 4px; }

/* Timeline (ticket detail view) */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }

/* Ticket detail layout:
   - Linke Hauptspalte (Beschreibung, Verlauf, Projektordner) auf
     900 px gedeckelt — selbe Standardbreite wie `.form-narrow` und der
     Admin-Bereich. So bleibt der Lesefluss in Kommentaren und
     Beschreibung konsistent.
   - Rechte Sidebar (Übersicht + Zeit erfassen) hält ihre ~1/3-Quote
     der Gesamtbreite — sichergestellt durch `max-width: 1380px` auf
     dem Container und `1fr` für die Sidebar:
       900 (main) + 14 (gap) + ~466 (sidebar) ≈ 1380
       → 466 / 1380 ≈ 33,8 %
   Auf engen Viewports schrumpft die Sidebar bis 280 px, darunter
   greift der Mobile-Breakpoint und stapelt einspaltig. */
.ticket-detail {
    /* Flexible fr-Tracks statt content-basiertem minmax(0, 900px): so hängt
       die Spaltenbreite NICHT vom Inhalt ab. Sonst schrumpfte die linke
       Spalte (z.B. in der Abrechnung, wenn nach dem Bestätigen Buttons
       wegfallen) und die rechte Spalte sprang entsprechend breiter.
       Bei max-width 1380px ergibt 2fr ≈ 900px — also optisch identisch. */
    grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    max-width: 1380px;
    /* width:100% ist nötig, weil .content ein Flex-Column ist: ein Flex-
       Item mit auto-Rändern auf der Querachse ignoriert align-items:stretch
       und schrumpft sonst auf seine Inhaltsbreite. Ohne das rendern Detail-
       seiten je nach Tabellenbreite unterschiedlich breit (Abrechnung vs.
       Bestellung). Mit width:100% füllt das Grid immer bis max-width. */
    width: 100%;
    margin-left: auto;
    margin-right: auto;
}
.ticket-main {
    display: flex; flex-direction: column; gap: 14px;
    width: 100%;
    min-width: 0;
}
/* Rechte Spalte der Detailseiten: sticky Meta-/Summen-/Aktions-Sidebar.
   Standard-Layout, siehe docs/UI-CONVENTIONS.md §13 + <x-detail-layout>. */
.detail-sidebar {
    display: flex; flex-direction: column; gap: 14px;
    position: sticky; top: 0; align-self: start;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    scrollbar-gutter: stable;
}
@media (max-width: 1024px) {
    .ticket-detail { grid-template-columns: 1fr; max-width: 900px; }
}
.ticket-description {
    margin: 0;
    padding: 4px 0 4px 16px;
    border-left: 3px solid var(--accent);
    font-size: 16px;
    line-height: 1.6;
    white-space: pre-wrap;
}
.ticket-description.is-collapsible {
    overflow: hidden;
    transition: max-height 0.25s ease;
}
.ticket-description.is-collapsible.is-collapsed {
    max-height: 6.4em;  /* ~ 4 Zeilen bei line-height 1.6 */
    position: relative;
    mask-image: linear-gradient(to bottom, black 70%, transparent);
    -webkit-mask-image: linear-gradient(to bottom, black 70%, transparent);
}
.ticket-description.is-collapsible:not(.is-collapsed) {
    max-height: none;
    mask-image: none;
    -webkit-mask-image: none;
}
.ticket-desc-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px; height: 22px;
    margin-left: 4px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 50%;
    cursor: pointer;
    color: var(--text-muted);
    transition: transform 0.2s, background 0.15s, color 0.15s;
}
.ticket-desc-toggle:hover { background: var(--surface-2); color: var(--accent); }
.ticket-desc-toggle[aria-expanded="true"] { transform: rotate(180deg); }
.ticket-desc-toggle .ticket-desc-chevron { font-size: 11px; line-height: 1; }
.ticket-desc-more {
    display: block;
    margin: 6px 0 0 16px;
    background: transparent;
    border: none;
    color: var(--accent);
    font-size: 12px;
    cursor: pointer;
    padding: 0;
}
.ticket-desc-more:hover { text-decoration: underline; }
.ticket-description.is-collapsible:not(.is-collapsed) ~ .ticket-desc-more { display: none; }
.subtitle-sep { margin: 0 6px; color: var(--text-subtle); }
.subtitle-meta { color: var(--text-muted); font-weight: 500; }
.timeline::before {
    content: '';
    position: absolute;
    left: 13px; top: 8px; bottom: 8px;
    width: 2px;
    background: var(--border);
}
.tl-item { position: relative; padding: 0 0 12px 40px; --tl-color: var(--gray); }
.tl-item:last-child { padding-bottom: 0; }

.tl-icon {
    position: absolute;
    left: 0; top: 0;
    width: 28px; height: 28px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--tl-color);
    color: var(--text);
    font-size: 14px;
    line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
    z-index: 1;
}
.tl-card {
    border: 1px solid var(--border);
    border-left: 3px solid var(--tl-color);
    border-radius: 6px;
    padding: 10px 12px;
    background: var(--surface);
}
.tl-meta {
    font-size: 12px;
    color: var(--text-muted);
    display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
}
.tl-content { margin-top: 6px; white-space: pre-wrap; font-size: 13px; line-height: 1.5; }
.tl-time .tl-content { color: var(--text-muted); }

/* per-kind colors */
.tl-comment { --tl-color: var(--accent); }
.tl-comment.is-internal { --tl-color: var(--yellow); }
.tl-comment.is-internal .tl-card { background: #fef9e7; }
/* Live-Update-Toasts (Bottom-Right, fadeout nach ~8 Sek). Werden von
   resources/js/live.js dynamisch erzeugt — keine Templates dafür im
   Blade. Stacken übereinander wenn mehrere gleichzeitig kommen. */
.live-toast {
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 9999;
    display: flex;
    align-items: center;
    gap: 10px;
    background: #ffffff;
    color: var(--text);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: 6px;
    padding: 12px 16px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    font-size: 13px;
    line-height: 1.4;
    max-width: 360px;
    animation: live-toast-in 0.25s ease-out;
}
.live-toast-info    { border-left-color: var(--blue, #2563eb); }
.live-toast-warning { border-left-color: #fe5900; }
.live-toast-icon { font-size: 18px; flex-shrink: 0; }
.live-toast-body  { word-break: break-word; }
@keyframes live-toast-in {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Flash-Effekt für gerade aktualisierte Elemente (Timeline-Comment,
   Status-Pille). Subtil, nicht aufdringlich. */
.tl-flash {
    animation: tl-flash-anim 1.5s ease-out;
}
@keyframes tl-flash-anim {
    0%   { box-shadow: 0 0 0 4px rgba(254, 89, 0, 0.4); background: rgba(254, 89, 0, 0.08); }
    100% { box-shadow: 0 0 0 0   rgba(254, 89, 0, 0);   background: transparent; }
}

/* Frisch eingefügte Tabellen-/Timeline-Zeile pulsiert 5 Sek lang orange. */
.tl-row-fresh {
    animation: tl-row-fresh-anim 5s ease-out;
}
@keyframes tl-row-fresh-anim {
    0%, 30%  { background: rgba(254, 89, 0, 0.12); }
    100%     { background: transparent; }
}

/* Customer-Email-Kommentar: blauer Akzent, leicht gefärbter Hintergrund —
   klar als externer Beleg erkennbar, gleichzeitig im Stil der Timeline. */
.tl-comment-email { --tl-color: var(--blue, #2563eb); }
.tl-comment-email .tl-card {
    background: #eff6ff;
    border-left: 3px solid var(--blue, #2563eb);
}
.tl-comment-email .tl-content { white-space: pre-wrap; }
.tl-time { --tl-color: #2563eb; }
.tl-attachment { --tl-color: #6f8389; }
.tl-milestone { --tl-color: var(--gray); }
.tl-milestone.tl-blue { --tl-color: var(--blue); }
.tl-milestone.tl-green { --tl-color: var(--green); }
.tl-milestone.tl-gray { --tl-color: var(--gray); }
.tl-milestone .tl-meta { font-weight: 600; color: var(--text); }

/* Card header row (h3 + edit toggle button on the right) */
.card-header-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.card-header-row > *:first-child { flex: 1; }

/* Geräte-Belegung (Faceplate): Ports als Kacheln je Seite (Front/Rück). */
.port-face-wrap { margin: 4px 0 14px; }
.port-face-side { font-size: 12px; color: var(--text-muted); margin: 10px 0 4px; }
.port-face { display: flex; flex-wrap: wrap; gap: 6px; }
.port-box {
    flex: 0 0 auto; width: 74px; min-height: 46px;
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px;
    padding: 5px 7px; border-radius: 5px;
    border: 1px solid var(--border); background: var(--surface);
    color: var(--text); font: inherit; text-align: left;
    position: relative; overflow: hidden;
}
button.port-box[data-open-modal] { cursor: pointer; }
button.port-box[data-open-modal]:hover { border-color: var(--text-muted); }
.port-box.is-connected { border-color: #fe5900; background: color-mix(in srgb, #fe5900 12%, var(--surface)); }
.port-box.is-free { border-style: dashed; color: var(--text-muted); }
.port-box.is-off { opacity: 0.5; }
.port-box-label { font-size: 11px; font-weight: 600; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.port-box-link { font-size: 10px; color: #fe5900; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.port-box-vlan { font-size: 10px; color: var(--text-muted); white-space: nowrap; }
.port-box-poe { position: absolute; top: 1px; right: 3px; font-size: 9px; line-height: 1; }
.port-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; font-size: 11px; color: var(--text-muted); }
.port-legend .port-dot { display: inline-block; width: 11px; height: 11px; border-radius: 2px; border: 1px solid var(--border); vertical-align: -1px; margin-right: 4px; }
.port-legend .port-dot.is-connected { border-color: #fe5900; background: color-mix(in srgb, #fe5900 25%, var(--surface)); }
.port-legend .port-dot.is-free { border-style: dashed; }
.port-legend .port-dot.is-off { opacity: 0.5; background: var(--text-subtle); }

/* Time capture (ticket: log time) */
.tc-date-line {
    display: flex; align-items: center; gap: 6px;
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 10px;
    justify-content: center;
}
.tc-date-edit {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-muted);
    padding: 2px 6px;
    cursor: pointer;
    font-size: 11px;
    line-height: 1;
}
.tc-date-edit:hover { background: var(--surface-2); color: var(--text); }

.tc-spinners {
    display: flex; align-items: stretch; justify-content: center;
    gap: 6px;
    margin-bottom: 10px;
}
.tc-spinner { flex: 1; min-width: 0; }
.tc-label {
    text-align: center;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 4px;
}
.tc-clock {
    display: flex; align-items: stretch; justify-content: center;
    gap: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 4px 6px;
}
.tc-seg {
    display: flex; flex-direction: column; align-items: stretch;
    justify-content: center;
    cursor: ns-resize;
    user-select: none;
    padding: 0;
    border-radius: 7px;
    transition: background 0.12s, box-shadow 0.12s;
    outline: none;
    width: 56px;
    position: relative;
}
.tc-seg::before, .tc-seg::after {
    content: '';
    position: absolute;
    left: 8px; right: 8px;
    height: 1px;
    background: var(--accent);
    opacity: 0;
    transition: opacity 0.16s;
    pointer-events: none;
}
.tc-seg::before { top: calc(50% - 14px); }
.tc-seg::after  { top: calc(50% + 14px); }
.tc-seg:hover, .tc-seg:focus { background: var(--accent-soft); }
.tc-seg:hover::before, .tc-seg:hover::after,
.tc-seg:focus::before, .tc-seg:focus::after { opacity: 0.45; }
.tc-seg:focus-visible { box-shadow: 0 0 0 2px var(--accent); }
.tc-arrow {
    background: transparent; border: none;
    color: var(--text-muted);
    font-size: 9px; line-height: 1;
    cursor: pointer;
    height: 12px;
    padding: 0;
    opacity: 0.35;
    transition: opacity 0.12s, color 0.12s;
}
.tc-seg:hover .tc-arrow,
.tc-seg:focus .tc-arrow { opacity: 1; }
.tc-arrow:hover { color: var(--accent); }
.tc-wheel {
    position: relative;
    height: 64px;
    width: 100%;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 28%, black 72%, transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0%, black 28%, black 72%, transparent 100%);
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.tc-row {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    text-align: center;
    line-height: 1.2;
    transition: transform 0.18s ease, opacity 0.18s ease;
}
.tc-row.prev, .tc-row.next {
    font-size: 13px;
    color: var(--text-muted);
    opacity: 0.55;
    height: 16px;
}
.tc-row.current {
    font-size: 24px;
    font-weight: 700;
    color: var(--text);
    height: 28px;
    line-height: 28px;
    text-shadow: 0 0 6px var(--surface), 0 0 6px var(--surface);
}
.tc-colon {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 24px;
    font-weight: 700;
    color: var(--text-muted);
    padding: 0 2px;
    align-self: center;
    line-height: 1;
}
.tc-arrow-between {
    color: var(--text-muted);
    font-size: 18px;
    align-self: center;
    padding: 0 2px;
}
.tc-quick-row {
    display: flex;
    gap: 6px;
    justify-content: center;
    margin-bottom: 8px;
}
.tc-quick-row .tc-quick {
    flex: 1;
    justify-content: center;
    padding: 9px 12px;
    font-size: 13px;
}
.tc-duration {
    text-align: center;
    font-size: 13px;
    color: var(--accent);
    font-weight: 600;
    background: var(--accent-soft);
    border: 1px solid #f5d3b5;
    border-radius: 6px;
    padding: 6px 8px;
    margin-bottom: 12px;
}
.tc-duration.is-zero { color: var(--text-muted); background: var(--surface-2); border-color: var(--border); }
.tl-att-thumb { display: inline-block; width: 56px; height: 56px; border-radius: 6px; overflow: hidden; border: 1px solid var(--border); flex-shrink: 0; background: var(--surface-2); }
.tl-att-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Inline-Anhänge an einem Kommentar (im Timeline-Eintrag) */
.tl-comment-files {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.tl-comment-file {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    text-decoration: none;
    font-size: 12px;
    transition: background 0.15s, border-color 0.15s;
}
.tl-comment-file:hover { background: var(--surface); border-color: var(--accent); color: var(--accent); }
.tl-comment-file-image {
    width: 80px; height: 80px;
    padding: 0;
    overflow: hidden;
}
.tl-comment-file-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tl-comment-file-icon { font-size: 18px; flex-shrink: 0; }
.tl-comment-file-name { font-weight: 500; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-comment-file-size { color: var(--text-muted); font-size: 10px; }
.tl-att-icon { font-size: 28px; line-height: 1; flex-shrink: 0; width: 56px; height: 56px; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 6px; background: var(--surface-2); }

/* Project folder — list / tile view */
.folder-view-toggle { display: inline-flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.fv-btn {
    background: transparent;
    border: none;
    padding: 5px 10px;
    font: inherit;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.fv-btn + .fv-btn { border-left: 1px solid var(--border); }
.fv-btn:hover { background: var(--surface-2); color: var(--text); }
.fv-btn.is-active { background: var(--accent); color: white; }

#project-folder[data-view="tiles"] .folder-list { display: none; }
#project-folder[data-view="list"] .folder-tiles { display: none; }

.folder-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 12px;
}
.folder-tile {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    overflow: hidden;
    display: flex; flex-direction: column;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.folder-tile:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.folder-tile-thumb {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 4 / 3;
    background: var(--surface-2);
    overflow: hidden;
    text-decoration: none;
    flex-direction: column;
}
.folder-tile-thumb img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.folder-tile-icon { color: var(--text-muted); }
.folder-tile-meta {
    padding: 8px 10px;
    border-top: 1px solid var(--border);
    min-width: 0;
}
.folder-tile-name {
    font-size: 12px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.folder-tile-sub {
    font-size: 11px;
    color: var(--text-muted);
    margin-top: 2px;
}
.folder-tile-actions {
    display: flex;
    gap: 4px;
    padding: 6px 10px 8px;
    justify-content: flex-end;
    align-items: center;
}

/* Attachment viewer modal */
.att-modal {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.86);
    z-index: var(--z-modal);
    display: flex;
    flex-direction: column;
    padding: 24px;
}
.att-modal-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 0 12px;
    color: white;
    font-size: 13px;
}
.att-modal-bar #att-name { font-weight: 500; word-break: break-all; }
.att-modal-bar .btn {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.18);
    color: white;
}
.att-modal-bar .btn:hover { background: rgba(255, 255, 255, 0.2); }
.att-modal-close {
    position: absolute;
    top: 12px; right: 16px;
    background: transparent;
    border: none;
    color: white;
    font-size: 32px;
    cursor: pointer;
    line-height: 1;
    padding: 4px 10px;
    border-radius: 6px;
    transition: background 0.12s;
}
.att-modal-close:hover { background: rgba(255, 255, 255, 0.12); }
.att-modal-body {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: auto;
    background: white;
    border-radius: var(--radius);
    min-height: 0;
}
.att-modal-body img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}
.att-modal-body iframe {
    width: 100%;
    height: 100%;
    border: none;
    background: white;
}
.checkbox-row {
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 14px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text);
    text-transform: none;
    letter-spacing: 0;
    font-weight: normal;
}
.checkbox-row input[type=checkbox] {
    width: 16px; height: 16px;
    margin: 0;
    accent-color: var(--accent);
    cursor: pointer;
    flex-shrink: 0;
}
.form-actions { display: flex; gap: 8px; margin-top: 12px; padding-top: 14px; border-top: 1px solid var(--border); }

/* List toolbar pattern: sortable headers + filter popover.
   Apply this convention to all list views (Tickets, Zeiten, Kunden, …). */
.table th.sortable { padding: 0; }
.table th.sortable a {
    display: flex; align-items: center; justify-content: space-between;
    gap: 6px;
    padding: 10px 14px;
    color: inherit; text-decoration: none;
    user-select: none;
}
.table th.sortable a:hover { background: var(--bg); color: var(--accent); }
.table th.sortable .sort-arrow { font-size: 10px; opacity: 0.4; line-height: 1; }
.table th.sortable.is-sorted a { color: var(--accent); }
.table th.sortable.is-sorted .sort-arrow { opacity: 1; }
.table td.cell-title { font-weight: 600; }
.table td.cell-title a { color: inherit; }
.table td.cell-title a:hover { color: var(--accent); }

.list-filter { position: relative; display: inline-block; }
.list-filter > summary {
    list-style: none;
    cursor: pointer;
    display: inline-flex; align-items: center; gap: 6px;
}
.list-filter > summary::-webkit-details-marker { display: none; }
.list-filter > summary::marker { content: ''; }
.list-filter[open] > summary { background: var(--surface-2); border-color: var(--accent); color: var(--accent); }
.list-filter > summary.is-active { border-color: var(--accent); color: var(--accent); }
.list-filter-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px;
    padding: 0 5px;
    background: var(--accent); color: white;
    border-radius: 10px;
    font-size: 11px; font-weight: 600;
}
.list-filter-popover {
    position: absolute; top: calc(100% + 6px); right: 0;
    min-width: 300px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 12px;
    z-index: 30;
}
/* Modal-Kopf des Filters — nur auf Mobil sichtbar (dort ist das Popover ein
   zentriertes Modal, s. §19); auf Desktop ausgeblendet (Popover hat keinen
   Kopf). Mobile-Override setzt display:flex. */
.list-filter-modal-head {
    display: none;
    align-items: center; justify-content: space-between;
    padding: 13px 16px; border-bottom: 1px solid var(--border);
    font-weight: 600; font-size: 15px;
}
.list-filter-modal-close {
    background: none; border: 0; font-size: 22px; line-height: 1;
    color: var(--text-muted); cursor: pointer; padding: 0 4px;
}
.list-filter-modal-close:hover { color: var(--text); }
.list-filter-form { display: flex; flex-direction: column; gap: 8px; }
.list-filter-row { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-muted); font-weight: 500; }
.list-filter-row > input,
.list-filter-row > select {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    background: var(--surface);
    color: var(--text);
}
.list-filter-row > input:focus,
.list-filter-row > select:focus { outline: 2px solid rgba(254,89,0,0.25); border-color: var(--accent); }
.list-filter-actions {
    display: flex; gap: 8px;
    margin-top: 6px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

/* Alerts */
.alert {
    /* Horizontal-Padding 18px ist die SYSTEMWEIT kanonische Banner-/Card-
       Padding-Breite (siehe docs/UI-CONVENTIONS.md §12). Cards (.card)
       nutzen die gleichen 18px → der rechte Rand von Action-Buttons in
       Bannern fluchtet mit Action-Buttons in Cards. */
    padding: 10px 18px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    font-size: 13px;
}
.alert-info { background: #eef4ff; border-color: #cfd9f7; color: #1e3a8a; }
.alert-success { background: #e8f7ed; border-color: #c4e8d3; color: #226e3a; }
.alert-error { background: #fdecec; border-color: #f4c4c4; color: #b13333; }

/* Empty state */
.empty {
    padding: 40px 20px;
    text-align: center;
    color: var(--text-muted);
    background: var(--surface-2);
    border-radius: var(--radius);
}

/* =====================================================================
   Super-Admin-Toolbar + Banner (Zeitreise / Doppelgänger)
===================================================================== */
.admin-banner {
    display: flex; align-items: center; gap: 12px;
    /* Schwebend wie die Sidebar / Topbar. Padding 10px/18px = kanonische
       Banner-Padding-Breite, identisch zu `.alert`, `.broadcast-banner`,
       `.card` → siehe docs/UI-CONVENTIONS.md §12. */
    margin: 0 0 10px 0;
    padding: 10px 18px;
    min-height: 48px;
    font-size: 13px;
    line-height: 1.4;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    /* Beim Scrollen am oberen Rand kleben bleiben — Scroll-Container
       ist .main (overflow-y: auto). */
    position: sticky;
    top: 0;
    z-index: var(--z-banner);
}
/* Slide-Animation nur beim ERSTEN Erscheinen im aktuellen Tab —
   die is-fresh-Klasse setzt unten ein kleines JS via sessionStorage,
   damit Modulwechsel kein erneutes Einblenden auslösen. */
.admin-banner.is-fresh { animation: admin-banner-slide-down 0.4s ease-out; }
/* Hinweis: gestackte Banner (admin + broadcast + party) bekommen ihren
   sticky-top dynamisch via JS — siehe updateBannerStacks() in app.blade.php.
   Statische CSS-Werte wären falsch, sobald Mini- und Volle Banner gemischt
   sind (32px vs 52px vs 48px). */

/* Farb-Paletten — gleiche Hex-Werte wie die <x-banner>-Component, damit
   System-Banner (Admin-Modi, Broadcasts) und Page-Banner zur selben
   visuellen Familie gehören. Vorher waren das gradientige Knaller in
   weißer Schrift; jetzt flache Pastelle mit dunkler Schrift + Border. */
.admin-banner-time   { background: #e0e7ff; border: 1px solid #a5b4fc; color: #3730a3; }  /* info */
.admin-banner-doppel { background: #fef3c7; border: 1px solid #f3d97a; color: #7a5615; }  /* warning */
.admin-banner-maint  { background: #fef3c7; border: 1px solid #f3d97a; color: #7a5615; }  /* warning */
.admin-banner-xray   { background: #e0e7ff; border: 1px solid #a5b4fc; color: #3730a3; }  /* info */
.admin-banner-actions-group { display: flex; gap: 6px; flex-shrink: 0; }

/* =====================================================================
   X-Ray-Modus — Visualisiert Permission-Gates und ungesicherte
   Aktionen für den Super-Admin.
   Wenn gleichzeitig Party-Mode läuft, würden die Buttons hüpfen UND
   ihren X-Ray-Outline+Label haben → unlesbar. In dem Fall friert der
   Party-Bounce ein, damit man die Permission-Labels in Ruhe lesen kann.
===================================================================== */
body.party-mode.xray-mode .btn,
body.party-mode.xray-mode .card,
body.party-mode.xray-mode .nav-link,
body.party-mode.xray-mode tbody tr,
body.party-mode.xray-mode .pill,
body.party-mode.xray-mode .admin-toolbar-handle {
    animation: none !important;
    transform: none !important;
}
body.xray-mode [data-xray-perm] {
    outline: 2px dashed #fe5900;
    outline-offset: 3px;
    position: relative;
}
body.xray-mode [data-xray-perm]::before {
    content: '🔒 ' attr(data-xray-perm);
    position: absolute;
    top: -18px; left: -2px;
    background: #fe5900;
    color: #fff;
    padding: 1px 8px;
    border-radius: 3px;
    font-size: 10px;
    font-weight: 600;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: 0.02em;
    white-space: nowrap;
    z-index: 5;
    pointer-events: none;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
body.xray-mode [data-xray-type="canany"]::before {
    content: '🔓 ANY: ' attr(data-xray-perm);
    background: #f59e0b;
}

/* Ungesicherte interaktive Aktionen — kandidatenmäßig markiert */
body.xray-mode [data-xray-ungated] {
    outline: 2px dotted #ef4444;
    outline-offset: 3px;
    position: relative;
}
body.xray-mode [data-xray-ungated]::before {
    content: '⚠ ungesichert ' attr(data-xray-ungated);
    position: absolute;
    top: -18px; right: -2px;
    background: #ef4444;
    color: #fff;
    padding: 1px 8px;
    border-radius: 3px;
    font-size: 10px;
    font-weight: 600;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    white-space: nowrap;
    z-index: 5;
    pointer-events: none;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
/* Wenn beides zutrifft, zeigt nur das positive Label (data-xray-perm) */
body.xray-mode [data-xray-perm][data-xray-ungated]::before {
    content: '🔒 ' attr(data-xray-perm);
    background: #fe5900;
}

/* Aktiv-Style für den Toolbar-Button */
.admin-toolbar-btn.is-active {
    background: rgba(254, 89, 0, 0.25);
}

/* =====================================================================
   Element-Inspector — schwebender Tooltip am Cursor, Crosshair-Mode
===================================================================== */
.eli-tooltip {
    position: fixed;
    pointer-events: none;
    z-index: 999999; /* über allem, auch Phase-Overlay */
    background: rgba(20, 23, 26, 0.94);
    color: #fff1e6;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    line-height: 1.3;
    padding: 4px 8px;
    border-radius: 4px;
    border: 1px solid rgba(254, 89, 0, 0.6);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    white-space: nowrap;
    max-width: 480px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.eli-tooltip[hidden] { display: none; }
.eli-tooltip.is-copied {
    background: rgba(34, 197, 94, 0.96);
    border-color: rgba(134, 239, 172, 0.7);
    color: #fff;
}

/* Aktiver Inspector-Modus: nur ein dezenter Dashed-Outline am gehoverten
   Element. Cursor bleibt normal, weil Klicks weiter normal navigieren —
   Kopieren läuft über die Tastatur (Taste C).
   `:not(:has(*:hover))` greift exakt am deepest-hovered Element, sonst
   stapeln sich Outlines von Ancestor-Elementen. */
body.is-eli-active *:hover:not(:has(*:hover)) {
    outline: 1px dashed rgba(254, 89, 0, 0.7);
    outline-offset: -1px;
}
/* Toolbar bleibt von Inspector-Effekten ausgenommen */
body.is-eli-active #admin-toolbar *:hover { outline: none; }

/* =====================================================================
   Live-Audit-Tail — floating Panel bottom-left, Terminal-Look
===================================================================== */
.audit-tail {
    position: fixed;
    bottom: 24px; left: 24px;
    width: 420px;
    max-width: calc(100vw - 48px);
    max-height: 380px;
    background: #1a1d28;
    color: #e6e9ef;
    border: 1px solid #2c3142;
    border-radius: 10px;
    box-shadow: 0 12px 28px rgba(0,0,0,0.35);
    z-index: 9997;
    display: flex; flex-direction: column;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    overflow: hidden;
}
.audit-tail[hidden] { display: none; }
.audit-tail-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 8px 12px;
    background: rgba(255,255,255,0.04);
    border-bottom: 1px solid #2c3142;
    cursor: grab;
    user-select: none;
}
.audit-tail.is-dragging { opacity: 0.92; box-shadow: 0 20px 40px rgba(0,0,0,0.45); }
.audit-tail.is-dragging .audit-tail-head { cursor: grabbing; }
.audit-tail-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: #e6e9ef;
}
.audit-tail-pulse {
    color: #4ad994;
    margin-left: 4px;
    animation: at-pulse 1.6s ease-in-out infinite;
}
.audit-tail.is-paused .audit-tail-pulse { color: #f59e0b; animation: none; }
@keyframes at-pulse {
    0%, 100% { opacity: 0.4; }
    50%      { opacity: 1; }
}
.audit-tail-actions { display: flex; gap: 4px; }
.audit-tail-btn {
    background: transparent;
    border: 1px solid #2c3142;
    color: #cdd3e1;
    width: 24px; height: 24px;
    border-radius: 4px;
    font-size: 12px; line-height: 1;
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    text-decoration: none;
    font-family: inherit;
}
.audit-tail-btn:hover { background: #2c3142; color: #fff; }

.audit-tail-list {
    list-style: none; margin: 0; padding: 6px 10px;
    overflow-y: auto;
    flex: 1;
    font-size: 11.5px;
    line-height: 1.5;
}
.audit-tail-empty {
    color: #6e7587;
    font-style: italic;
    text-align: center;
    padding: 12px 0;
}
.audit-tail-row {
    display: flex; flex-wrap: wrap; gap: 6px;
    padding: 4px 0;
    border-bottom: 1px dashed rgba(255,255,255,0.04);
}
.audit-tail-row:last-child { border-bottom: none; }
.audit-tail-row.is-new {
    background: linear-gradient(90deg, rgba(74,217,148,0.18), transparent);
    animation: at-flash 1.5s ease-out;
}
@keyframes at-flash {
    0%   { background: rgba(74,217,148,0.32); }
    100% { background: transparent; }
}
.at-time   { color: #6e7587; flex-shrink: 0; }
.at-tt     { color: #f0c36d; flex-shrink: 0; }
.at-who    { color: #82d49a; min-width: 0; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.at-imp    { color: #d49af0; }
.at-entity { color: #9ec1ff; }
.at-id     { color: #6e7587; }
.at-action { color: #ffce4a; }
.at-field  { color: #ff8a40; font-weight: 600; }
.at-change { color: #cdd3e1; flex-basis: 100%; padding-left: 0; font-size: 10.5px; opacity: 0.85; }

/* Cleanup-Wizard-Cards — verschiedene Zustände visuell trennen */
.cleanup-check { border-left: 4px solid var(--border); }
.cleanup-check.cleanup-ok     { border-left-color: #22c55e; }
.cleanup-check.cleanup-action { border-left-color: var(--accent); }
.cleanup-check.cleanup-warn   { border-left-color: #f59e0b; }
.cleanup-details summary {
    cursor: pointer;
    font-size: 12px;
    color: var(--text-muted);
    user-select: none;
    padding: 4px 0;
}
.cleanup-details[open] summary { margin-bottom: 4px; color: var(--text); font-weight: 500; }
.cleanup-details .table th { background: var(--surface-2); font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; }
.cleanup-details .table td { padding: 6px 12px; }
/* 22px-Slot wie .broadcast-icon / <x-banner>-Icon — Icon-Mitte fluchtet
   systemweit, egal wie groß das einzelne Icon ist. */
.admin-banner-icon {
    font-size: 18px; flex-shrink: 0;
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
}
.admin-banner-text { flex: 1; }
.admin-banner-action { margin: 0; }
.admin-banner-btn {
    /* Erbt die Banner-Text-Farbe — funktioniert daher auf jedem der vier
       Pastell-Töne ohne explizite Per-Ton-Variante. */
    background: rgba(0,0,0,0.06);
    color: inherit;
    border: 1px solid currentColor;
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 12px;
    cursor: pointer;
    font: inherit;
    font-weight: 500;
    transition: background 0.12s;
}
.admin-banner-btn:hover { background: rgba(0,0,0,0.12); }
@keyframes admin-banner-slide-down {
    from { transform: translateY(-100%); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}

/* Toolbar bottom-center: kollabiert ist sie ein runder Button, beim
   Hover/Focus klappt sie zu einer schmalen Leiste auf. Im kollabierten
   Zustand ist die äußere Hülle transparent, damit kein dunkler Ring
   um den orange-Button sichtbar wird — Hintergrund + Shadow blendet
   erst beim Aufklappen ein. */
.admin-toolbar {
    position: fixed;
    bottom: 22px;
    left: 50%;
    transform: translateX(-50%);
    display: flex; align-items: center;
    background: transparent;
    color: #fff;
    /* Stadium / Pill — bleibt egal wie hoch die Toolbar wird perfekt
       halbkreisförmig an den Enden. */
    border-radius: 9999px;
    padding: 0;
    z-index: 9998;
    box-shadow: none;
    overflow: hidden;
    transition: background 0.22s ease, box-shadow 0.22s ease, padding 0.22s ease;
}
.admin-toolbar:hover,
.admin-toolbar:focus-within {
    background: #1a1d28;
    padding: 6px;
    box-shadow: 0 8px 22px rgba(0,0,0,0.28);
}
.admin-toolbar-handle {
    /* Gleiche Maße wie clock-fab / notification-fab (56×56 + 24px Icon). */
    width: 56px; height: 56px;
    border: none;
    background: linear-gradient(135deg, #fe5900 0%, #ff8a40 100%);
    color: #fff;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    font-size: 24px;
    line-height: 1;
    flex-shrink: 0;
    /* Eigenen Schatten — damit der Button auch kollabiert (transparente
       Hülle) leicht „schwebt". Im aufgeklappten Zustand übernimmt der
       Hüllen-Shadow den größeren Lift. */
    box-shadow: 0 6px 16px rgba(254, 89, 0, 0.4);
    transition: transform 0.2s, box-shadow 0.2s;
}
.admin-toolbar:hover .admin-toolbar-handle,
.admin-toolbar:focus-within .admin-toolbar-handle { box-shadow: none; }
.admin-toolbar-handle:hover { transform: scale(1.04); }
.admin-toolbar-handle-icon { display: block; }

.admin-toolbar-tray {
    display: flex; gap: 4px; align-items: center;
    /* Auf mehrere Zeilen umbrechen wenn nötig — wir lassen ~4 Buttons
       pro Reihe und brechen den Rest in die nächste Zeile um. */
    flex-wrap: wrap;
    max-width: 0;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    margin-left: 0;
    transition: max-width 0.28s cubic-bezier(0.16, 1, 0.3, 1),
                max-height 0.28s cubic-bezier(0.16, 1, 0.3, 1),
                opacity 0.2s ease,
                margin-left 0.28s ease;
}
.admin-toolbar:hover .admin-toolbar-tray,
.admin-toolbar:focus-within .admin-toolbar-tray {
    /* Breite-Anker: ca. 4 Buttons pro Reihe (118 min-width × 4 + Gaps).
       Höhe: passt 3 Reihen Buttons (34px × 3 + 4px-Gap × 2 = 110px) plus
       Innenpadding-Reserve. Mehr als 12 Buttons schicken wir nicht in
       die Toolbar — wenn doch nötig, separates Drawer-Konzept bauen. */
    max-width: 540px;
    max-height: 150px;
    opacity: 1;
    margin-left: 6px;
}
.admin-toolbar-btn {
    display: inline-flex; align-items: center; gap: 6px;
    min-width: 118px; /* gleichmäßige Reihen-Optik trotz unterschiedlicher Labels */
    background: transparent;
    color: #fff;
    border: none;
    padding: 8px 14px 8px 10px;
    border-radius: 22px;
    font-size: 13px;
    font: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.12s;
    text-decoration: none; /* auch für <a>-Variante (z.B. Aufräum-Wizard) */
}
.admin-toolbar-btn:hover { color: #fff; background: rgba(255,255,255,0.12); }
.admin-toolbar-btn-icon { font-size: 16px; }
.admin-toolbar-btn-label { font-weight: 500; }

/* Confirmation-Modal — schlicht, zentriert. */
.admin-modal-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.5);
    display: flex; align-items: center; justify-content: center;
    z-index: var(--z-modal);
    opacity: 0;
    transition: opacity 0.2s ease;
}
.admin-modal-backdrop[hidden] { display: none; }
.admin-modal-backdrop.is-open { opacity: 1; }
.admin-modal {
    background: var(--surface);
    color: var(--text);
    border-radius: 12px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.35);
    width: 100%;
    /* Zwei systemweite Modal-Breiten (siehe docs/UI-CONVENTIONS.md §17):
       Standard 600px, breit via .admin-modal-wide. KEINE Inline-max-width
       je Modal mehr — sorgt sonst für uneinheitliche Breiten im System. */
    max-width: 600px;
    max-height: calc(100vh - 40px);
    overflow-y: auto;
    /* Horizontal NICHT scrollen — Inhalt umbrechen lassen statt einer
       Scrollbar nach rechts. Browser schaltet bei overflow-y:auto sonst
       implizit overflow-x:auto an, was bei langem Picker-Display-Text
       („Mi, 12. November 2026") oder breiten Form-Grids zu seitlichem
       Scroll führt. */
    overflow-x: hidden;
    transform: translateY(20px);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Ruhezustand bewusst transform:none (nicht translateY(0)) — JEDER
   Transform-Wert ≠ none macht das Modal zum „containing block" für
   position:fixed-Kinder, wodurch die Custom-Picker-Popovers wieder im
   overflow-y:auto des Modals gefangen wären. Die Einblende-Animation
   läuft trotzdem (von translateY(20px) auf none interpoliert). */
.admin-modal-backdrop.is-open .admin-modal { transform: none; }
/* Breite Variante — für Modals mit Tabellen/Positionen oder breiten
   Mehrspalten-Zeilen (z.B. Bestell-Positionen, Ticket-Bearbeiten). */
.admin-modal-wide { max-width: 820px; }
.admin-modal-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
}
.admin-modal-head h3 { margin: 0; font-size: 16px; font-weight: 600; }
.admin-modal-close {
    background: none; border: none;
    font-size: 22px; line-height: 1;
    color: var(--text-muted); cursor: pointer;
    padding: 0 4px;
}
.admin-modal-close:hover { color: var(--text); }
.admin-modal-body { padding: 16px 18px; }
.admin-modal-hint {
    margin: 0 0 14px;
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.5;
    padding: 10px 12px;
    background: var(--surface-2);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
}
.admin-modal-row { display: flex; gap: 10px; margin-bottom: 12px; }
.admin-modal-row label {
    display: flex; flex-direction: column; gap: 5px;
    font-size: 11.5px; color: var(--text-muted);
    font-weight: 500;
    flex: 1;
    /* min-width: 0 erlaubt dem Flex-Item, unter die intrinsische
       Mindestbreite seines date/number-Inputs zu schrumpfen — sonst
       sprengt z.B. ein type=date-Feld das Label und überlappt das
       Nachbarfeld in einer 3-spaltigen admin-modal-row. */
    min-width: 0;
}
/* Form-Elemente in Admin-Modals — einheitlicher Look (gepolsterte Inputs,
   sanfter Accent-Glow on focus, runde Ecken 8 px). Wirkt systemweit auf
   admin-modal-Instanzen — Phone-Note, Quick-Ticket, Quick-Time, Toolbar-
   Modals etc. — damit Eingabe-Erfahrung überall konsistent ist. */
.admin-modal-row input[type="date"],
.admin-modal-row input[type="time"],
.admin-modal-row input[type="text"],
.admin-modal-row input[type="email"],
.admin-modal-row input[type="number"],
.admin-modal-row input[type="password"],
.admin-modal-row input[type="url"],
.admin-modal-row input[type="search"],
.admin-modal-row input[type="tel"],
.admin-modal-row input:not([type]),
.admin-modal-row select,
.admin-modal-row textarea {
    padding: 9px 11px;
    font-size: 13.5px;
    font-family: inherit;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    transition: border-color 0.12s, box-shadow 0.12s;
}
.admin-modal-row textarea { resize: vertical; min-height: 64px; }
/* Volle Label-Breite + border-box, damit Felder mit dem flex-geschrumpften
   Label mitskalieren und nicht über den Nachbarn in mehrspaltigen
   admin-modal-rows ragen (Überlappung beim Zeiteintrag-Bearbeiten). */
.admin-modal-row input,
.admin-modal-row select,
.admin-modal-row textarea {
    width: 100%;
    box-sizing: border-box;
}
.admin-modal-row input:focus,
.admin-modal-row select:focus,
.admin-modal-row textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(254, 89, 0, 0.15);
    outline: none;
}
.admin-modal-row input:disabled,
.admin-modal-row select:disabled,
.admin-modal-row textarea:disabled {
    background: var(--surface-2);
    color: var(--text-muted);
    cursor: not-allowed;
}
.admin-modal-fieldset {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 10px 14px;
    margin: 6px 0 0;
}
.admin-modal-fieldset legend { padding: 0 6px; font-size: 12px; color: var(--text-muted); }
.admin-modal-radio {
    display: flex; align-items: flex-start; gap: 8px;
    padding: 6px 0;
    font-size: 13px;
    cursor: pointer;
}
.admin-modal-radio input { margin-top: 3px; }
.admin-modal-foot {
    display: flex; justify-content: flex-end; gap: 10px;
    padding: 12px 18px;
    border-top: 1px solid var(--border);
}
.admin-modal-results { display: flex; flex-direction: column; gap: 2px; max-height: 200px; overflow-y: auto; margin-top: 4px; }
.admin-modal-result {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    text-align: left;
    padding: 7px 10px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
    font: inherit;
}
.admin-modal-result:hover { background: var(--surface-2); border-color: var(--accent); }
/* Optionale zweite Zeile in einem Such-Treffer (z.B. Firmen-Zugehörigkeiten
   einer Person beim „bestehende Person verknüpfen"-Picker). */
.admin-modal-result small { display: block; margin-top: 2px; font-size: 12px; color: var(--text-muted); }
/* <fieldset>-Reset für umschaltbare Modal-Modi (z.B. „neu anlegen" vs.
   „bestehende verknüpfen"). BEWUSST kein display: damit das [hidden]-Attribut
   den inaktiven Modus weiter ausblenden kann (sonst überschreibt eine
   display-Regel die UA-[hidden]-Regel). */
.contact-pane { border: 0; margin: 0; padding: 0; min-inline-size: auto; }
/* Wiederholbare Kontaktkanäle (mehrere E-Mail/Telefon/Mobil): Eingabe + ±-Button
   pro Zeile, gestapelt unter dem Feld-Label (siehe <x-contact-channels>). */
.channel-row { display: flex; gap: 6px; align-items: center; }
.channel-row + .channel-row { margin-top: 6px; }
.channel-row > input { flex: 1; min-width: 0; }
.channel-row > .btn-icon { flex: none; }
.admin-modal-selected {
    margin-top: 10px;
    padding: 8px 10px;
    background: rgba(254,89,0,0.08);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    font-size: 13px;
    color: var(--accent);
    font-weight: 500;
}

/* =====================================================================
   TERMIN-MODAL — wiederverwendbar, mit Custom Date- und Time-Pickern.
   Sitzt auf dem admin-modal-Pattern auf, fügt nur die spezifischen
   Layout-Elemente dazu.
===================================================================== */
.event-modal-field {
    display: flex; flex-direction: column; gap: 5px;
    margin-bottom: 12px;
    position: relative;  /* Anker für Picker-Popovers */
    /* min-width: 0 erlaubt flex-children, unter ihre intrinsische
       Content-Breite zu schrumpfen — sonst quetscht ein langer
       Pickbtn-Text die ganze Row breiter als das Modal. */
    min-width: 0;
}
.event-modal-field > label {
    font-size: 11.5px; color: var(--text-muted);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.event-modal-field > input,
.event-modal-field > textarea,
.event-modal-select {
    padding: 9px 11px;
    font-size: 13.5px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.event-modal-field > input:focus,
.event-modal-field > textarea:focus,
.event-modal-select:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(254, 89, 0, 0.15);
    outline: none;
}
.event-modal-row {
    display: flex; gap: 10px; margin-bottom: 10px;
    align-items: flex-end;
    /* In sehr schmalen Modals umbrechen statt seitlich scrollen. */
    flex-wrap: wrap;
}
.event-modal-row .event-modal-field { margin-bottom: 0; }

/* -------- Picker-Display-Buttons (Datum, Uhrzeit) -------- */
.event-modal-pickbtn {
    display: flex; align-items: center; gap: 8px;
    padding: 9px 11px;
    font: inherit; font-size: 13.5px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text);
    cursor: pointer;
    text-align: left;
    transition: border-color 0.12s, box-shadow 0.12s;
    width: 100%;
}
.event-modal-pickbtn .icon {
    color: var(--accent);
    flex-shrink: 0;
}
.event-modal-pickbtn > span {
    flex: 1;
    min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.event-modal-pickchev {
    width: 14px; height: 14px;
    color: var(--text-muted);
    transition: transform 0.18s;
}
.event-modal-pickbtn:hover {
    border-color: var(--accent);
}
.event-modal-pickbtn.is-open {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(254, 89, 0, 0.15);
}
.event-modal-pickbtn.is-open .event-modal-pickchev {
    transform: rotate(180deg);
    color: var(--accent);
}
.event-modal-pickbtn:disabled {
    opacity: 0.55; cursor: not-allowed;
    background: var(--surface-2);
}
/* Einzel-Uhrzeit-Picker (<x-time-picker>) — Button füllt die (Tabellen-)Zelle. */
.time-picker { position: relative; }
.time-picker > .event-modal-pickbtn { width: 100%; }

.event-modal-pickpop {
    /* position:fixed + JS-Positionierung (positionPop): das Popover ragt
       über den Modal-Rand hinaus, statt das Modal scrollen zu lassen.
       top/left werden per JS aus dem Button-Rect gesetzt. */
    position: fixed;
    top: 0;
    left: 0;
    z-index: var(--z-tooltip);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 14px 36px rgba(0,0,0,0.18);
    padding: 12px;
    animation: eventPopIn 0.16s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Explicit display:none neben dem [hidden]-HTML-Attribut — meine
   spezifischere .event-modal-pickpop-Regel oben überschreibt sonst nicht
   display, aber lass uns auf Nummer sicher gehen. Ohne das schwebt der
   Picker in manchen Browsern als unsichtbarer Block im Modal-Body. */
.event-modal-pickpop[hidden] { display: none; }
@keyframes eventPopIn {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Pop für die Uhrzeit / Dauer rechts ausrichten, damit es nicht
   außerhalb des Modal-Rands liegt — Datum bleibt links-ausgerichtet,
   weil das Datum-Feld am linken Rand sitzt. */
.event-modal-field:has([data-role="time-pop"]) .event-modal-pickpop,
.event-modal-field:has([data-role="duration-pop"]) .event-modal-pickpop {
    left: auto;
    right: 0;
}

/* -------- Mini-Kalender im Date-Popover -------- */
.event-modal-cal {
    width: 280px;
}
.event-modal-cal-head {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: 6px;
    margin-bottom: 10px;
}
.event-modal-cal-title {
    font-weight: 600;
    font-size: 14px;
    text-align: center;
    color: var(--text);
}
.event-modal-cal-nav,
.event-modal-cal-today {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 6px;
    padding: 4px 8px;
    font: inherit;
    font-size: 12px;
    line-height: 1;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.event-modal-cal-nav {
    width: 28px; height: 28px;
    display: flex; align-items: center; justify-content: center;
}
.event-modal-cal-nav svg {
    width: 14px; height: 14px;
}
.event-modal-cal-nav:hover,
.event-modal-cal-today:hover {
    background: var(--surface-2);
    color: var(--accent);
}
.event-modal-cal-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    margin-bottom: 4px;
}
.event-modal-cal-weekdays span {
    font-size: 10.5px;
    color: var(--text-muted);
    text-align: center;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 4px 0;
}
.event-modal-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.event-modal-cal-day {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text);
    font: inherit;
    font-size: 12.5px;
    line-height: 1;
    height: 32px;
    border-radius: 6px;
    cursor: pointer;
    transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.event-modal-cal-day:hover {
    background: var(--surface-2);
    border-color: var(--border);
}
.event-modal-cal-day.is-outside {
    color: var(--text-subtle);
    opacity: 0.55;
}
.event-modal-cal-day.is-today {
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
}
.event-modal-cal-day.is-selected {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    font-weight: 600;
}
.event-modal-cal-day.is-selected:hover {
    background: var(--accent);
    color: #fff;
}
.event-modal-cal-day.is-weekend:not(.is-selected):not(.is-today) {
    color: var(--text-muted);
}

/* -------- Time-Picker im Time-Popover -------- */
.event-modal-time {
    display: flex;
    gap: 4px;
    padding: 8px;
}
.event-modal-time-col {
    display: flex; flex-direction: column;
    gap: 2px;
    max-height: 240px;
    overflow-y: auto;
    padding: 2px;
    /* Schmale Scrollbar im Wyld-Stil */
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.event-modal-time-col::-webkit-scrollbar { width: 6px; }
.event-modal-time-col::-webkit-scrollbar-thumb {
    background: var(--border); border-radius: 3px;
}
.event-modal-time-cell {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    line-height: 1;
    padding: 7px 16px;
    border-radius: 6px;
    cursor: pointer;
    text-align: center;
    transition: background 0.1s, color 0.1s;
    min-width: 52px;
    font-variant-numeric: tabular-nums;
}
.event-modal-time-cell:hover {
    background: var(--surface-2);
}
.event-modal-time-cell.is-selected {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}

/* -------- Duration-Picker im Duration-Popover -------- */
.event-modal-duration {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 200px;
    padding: 8px;
}
.event-modal-duration-opt {
    background: transparent;
    border: 1px solid transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    line-height: 1;
    padding: 8px 12px;
    border-radius: 6px;
    cursor: pointer;
    text-align: left;
    transition: background 0.1s, color 0.1s;
}
.event-modal-duration-opt:hover {
    background: var(--surface-2);
}
.event-modal-duration-opt.is-selected {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}
.event-modal-duration-custom {
    margin-top: 6px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}
.event-modal-duration-custom label {
    display: flex; align-items: center; gap: 8px;
    font-size: 12px;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
    margin: 0;
}
.event-modal-duration-custom input {
    flex: 1;
    padding: 6px 8px;
    font-size: 13px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-variant-numeric: tabular-nums;
}
.event-modal-duration-custom input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(254, 89, 0, 0.15);
    outline: none;
}

/* -------- Quick-Chips: Datum-Shortcuts -------- */
.event-modal-quickrow {
    display: flex; align-items: center; gap: 6px;
    flex-wrap: wrap;
    margin: 0 0 14px;
}
.event-modal-chip {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text);
    font: inherit;
    font-size: 12px;
    padding: 5px 11px;
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s, transform 0.06s;
}
.event-modal-chip:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.event-modal-chip:active { transform: scale(0.96); }
.event-modal-chip:disabled {
    opacity: 0.5; cursor: not-allowed; pointer-events: none;
}

/* -------- Ganztägig-Toggle -------- */
.event-modal-allday {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    margin: 0;
    text-transform: none;
    letter-spacing: 0;
}
.event-modal-allday input[type="checkbox"] { margin: 0; }

/* -------- Live-Preview „Endet um …" -------- */
.event-modal-preview {
    display: flex; align-items: center; gap: 8px;
    margin: 6px 0 0;
    padding: 10px 12px;
    background: rgba(254, 89, 0, 0.07);
    border: 1px solid rgba(254, 89, 0, 0.18);
    border-radius: 8px;
    font-size: 12.5px;
    color: var(--text);
    font-weight: 500;
}
.event-modal-preview .icon { color: var(--accent); }

/* =====================================================================
   PARTY-MODUS — Banner, Effekte, Chaos
===================================================================== */
.party-banner {
    display: flex; align-items: center; gap: 12px;
    /* Padding 10px/18px = kanonische Banner-Padding-Breite, identisch zu
       `.alert`, `.broadcast-banner`, `.admin-banner`, `.card`. Siehe
       docs/UI-CONVENTIONS.md §12. */
    margin: 0 0 10px 0;
    padding: 10px 18px;
    min-height: 48px;
    color: #fff;
    font-size: 13px;
    line-height: 1.45;
    border-radius: var(--radius-lg);
    position: sticky;
    top: 0;
    z-index: var(--z-banner-party);
    box-shadow: var(--shadow);
    background: linear-gradient(90deg, #ff3d8b 0%, #ff8a40 25%, #ffd23a 50%, #4ad994 75%, #5cb6ff 100%);
    background-size: 300% 100%;
    animation: party-rainbow 6s linear infinite;
}
@keyframes party-rainbow {
    from { background-position: 0% 50%; }
    to   { background-position: 300% 50%; }
}
.party-banner-icon {
    font-size: 22px; animation: party-spin 2s linear infinite;
    /* 22px-Slot wie alle anderen Banner-Icons. */
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
/* Quiet-Variante für Super-Admin-Spielverderber: gedämpft, keine
   Rainbow-Animation, kein Spin — nur ein Hinweis dass die Party noch
   läuft + Notbremse erreichbar. Verwendet die <x-banner>-Info-Palette,
   damit's sich im sonstigen Banner-System einreiht. */
.party-banner-quiet {
    background: #e0e7ff;
    border: 1px solid #a5b4fc;
    color: #3730a3;
    animation: none;
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.party-banner-quiet .party-banner-icon { animation: none; opacity: 0.85; }
.party-banner-quiet .party-banner-btn {
    background: rgba(0,0,0,0.06);
    color: inherit;
    border: 1px solid currentColor;
}
.party-banner-quiet .party-banner-btn:hover { background: rgba(0,0,0,0.12); }
.party-banner-quiet.is-dismissed { opacity: 0; transform: translateY(-100%); }
.party-banner-text { flex: 1; }
.party-banner-actions { display: flex; gap: 6px; flex-shrink: 0; }
.party-banner-action { margin: 0; }
.party-banner-btn {
    background: rgba(0,0,0,0.35);
    color: #fff;
    border: 1px solid rgba(255,255,255,0.55);
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 12px;
    cursor: pointer;
    font: inherit;
    font-weight: 600;
    white-space: nowrap;
}
.party-banner-btn:hover { background: rgba(0,0,0,0.55); }
.party-banner-btn-strong {
    background: rgba(0,0,0,0.55);
    border-color: rgba(255,255,255,0.8);
}
.party-banner-btn-strong:hover { background: rgba(0,0,0,0.75); }
.party-music-btn.party-music-muted {
    /* Visualisierung: leiser Puls solange Sound aus ist — fällt auf */
    animation: party-music-pulse 1.4s ease-in-out infinite;
}
@keyframes party-music-pulse {
    0%, 100% { background: rgba(0,0,0,0.35); box-shadow: 0 0 0 0 rgba(255,255,255,0.5); }
    50%      { background: rgba(255,255,255,0.25); box-shadow: 0 0 0 6px rgba(255,255,255,0); }
}

/* Hinweis: Stack-Offset wird dynamisch per JS gesetzt — siehe
   updateBannerStacks() in app.blade.php. Statisch wäre's bei gemischten
   Banner-Größen (mini 32 / normal 52 / admin 48) immer falsch. */

/* Effekt-Container ist viewport-weit + ignoriert Clicks. */
.party-effects {
    position: fixed; inset: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: var(--z-overlay-party);
}
.party-confetti {
    position: absolute;
    top: -40px;
    line-height: 1;
    animation: party-fall linear forwards;
    user-select: none;
}
@keyframes party-fall {
    0%   { transform: translateY(0) rotate(0deg); opacity: 1; }
    90%  { opacity: 1; }
    100% { transform: translateY(110vh) rotate(var(--party-rot-end, 360deg)); opacity: 0; }
}
.party-float {
    position: absolute;
    bottom: -40px;
    line-height: 1;
    animation: party-rise ease-out forwards;
    user-select: none;
}
@keyframes party-rise {
    0%   { transform: translateY(0) scale(1); opacity: 0; }
    15%  { opacity: 1; }
    100% { transform: translateY(-110vh) scale(1.4); opacity: 0; }
}
.party-burst {
    position: fixed;
    line-height: 1;
    animation: party-burst-anim 1.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    user-select: none;
    will-change: transform, opacity;
}
@keyframes party-burst-anim {
    0%   { transform: translate(-50%, -50%) scale(0.3) rotate(0); opacity: 1; }
    100% { transform: translate(calc(-50% + var(--party-burst-x)), calc(-50% + var(--party-burst-y))) scale(1) rotate(var(--party-burst-rot)); opacity: 0; }
}

/* === DAS EIGENTLICHE CHAOS === Body-weite Effekte bei party-mode === */

/* Hue-rotate über die ganze App — Farbpalette dreht sich periodisch */
body.party-mode {
    animation: party-hue 8s linear infinite;
}
@keyframes party-hue {
    0%   { filter: hue-rotate(0deg); }
    100% { filter: hue-rotate(360deg); }
}

/* Cards wackeln stärker */
body.party-mode .card {
    animation: party-wobble 2.6s ease-in-out infinite;
    transform-origin: center;
}
body.party-mode .card:nth-of-type(2n)   { animation-delay: -0.5s; animation-duration: 2.2s; }
body.party-mode .card:nth-of-type(3n)   { animation-delay: -1.1s; animation-duration: 3.1s; }
body.party-mode .card:nth-of-type(5n)   { animation-delay: -1.7s; animation-duration: 3.5s; }
@keyframes party-wobble {
    0%, 100% { transform: rotate(-2deg) scale(1); }
    50%      { transform: rotate(2deg) scale(1.02); }
}

/* Screen-Shake — Body wird ab und zu durchgerüttelt (JS triggert klasse) */
body.party-shake { animation: party-shake 0.8s ease-out, party-hue 8s linear infinite; }
@keyframes party-shake {
    0%, 100%       { transform: translate(0, 0) rotate(0); }
    10%            { transform: translate(-6px, 3px) rotate(-0.8deg); }
    20%            { transform: translate(7px, -2px) rotate(0.9deg); }
    30%            { transform: translate(-5px, 4px) rotate(-1deg); }
    40%            { transform: translate(8px, 2px) rotate(0.7deg); }
    55%            { transform: translate(-4px, -3px) rotate(-0.5deg); }
    70%            { transform: translate(5px, 2px) rotate(0.5deg); }
    85%            { transform: translate(-2px, 1px) rotate(-0.2deg); }
}

/* Quersliding "WUHU"-Worte */
.party-wuhu {
    position: fixed;
    z-index: var(--z-overlay-party);
    font-weight: 900;
    color: var(--wuhu-color, #ff3d8b);
    text-shadow: 2px 2px 0 #000, -2px -2px 0 #fff, 0 6px 16px rgba(0,0,0,0.3);
    letter-spacing: 0.02em;
    user-select: none;
    pointer-events: none;
    white-space: nowrap;
    animation: party-wuhu-l2r linear forwards;
}
.party-wuhu-l2r { left: -200px; animation-name: party-wuhu-l2r; }
.party-wuhu-r2l { right: -200px; animation-name: party-wuhu-r2l; }
@keyframes party-wuhu-l2r {
    0%   { transform: translateX(0) rotate(-6deg) scale(0.8); opacity: 0; }
    15%  { opacity: 1; }
    50%  { transform: translateX(50vw) rotate(2deg) scale(1.1); }
    85%  { opacity: 1; }
    100% { transform: translateX(110vw) rotate(8deg) scale(0.9); opacity: 0; }
}
@keyframes party-wuhu-r2l {
    0%   { transform: translateX(0) rotate(6deg) scale(0.8); opacity: 0; }
    15%  { opacity: 1; }
    50%  { transform: translateX(-50vw) rotate(-2deg) scale(1.1); }
    85%  { opacity: 1; }
    100% { transform: translateX(-110vw) rotate(-8deg) scale(0.9); opacity: 0; }
}

/* Mid-Session-Onset: kurzer "BAM" wenn die Party plötzlich startet */
body.party-onset .main {
    animation: party-onset-flash 1.4s ease-out;
}
@keyframes party-onset-flash {
    0%   { box-shadow: inset 0 0 0 9999px rgba(255, 61, 139, 0.4); }
    30%  { box-shadow: inset 0 0 0 9999px rgba(255, 210, 58, 0.25); }
    60%  { box-shadow: inset 0 0 0 9999px rgba(74, 217, 148, 0.15); }
    100% { box-shadow: inset 0 0 0 9999px rgba(0,0,0,0); }
}

/* Buttons hüpfen */
body.party-mode .btn {
    animation: party-bounce 0.55s ease-in-out infinite alternate;
}
@keyframes party-bounce {
    from { transform: translateY(0); }
    to   { transform: translateY(-3px); }
}

/* Sidebar-Links zittern leicht — wie bei zu viel Kaffee */
body.party-mode .nav-link {
    animation: party-jitter 0.5s linear infinite;
}
body.party-mode .nav-link:nth-of-type(2n) { animation-delay: -0.1s; }
body.party-mode .nav-link:nth-of-type(3n) { animation-delay: -0.2s; }
body.party-mode .nav-link:nth-of-type(5n) { animation-delay: -0.3s; }
@keyframes party-jitter {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-1.5px) rotate(-0.8deg); }
    75%      { transform: translateX(1.5px) rotate(0.8deg); }
}

/* Sidebar-Brand spinnt */
body.party-mode .brand-logo,
body.party-mode .sidebar-brand .brand-link {
    animation: party-spin 4s linear infinite;
}
@keyframes party-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* Topbar-Title pulsiert wie ein Discoknopf */
body.party-mode .page-title {
    animation: party-disco 1.2s ease-in-out infinite;
    background: linear-gradient(90deg, #ff3d8b, #ff8a40, #ffd23a, #4ad994, #5cb6ff, #ff3d8b);
    background-size: 200% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
@keyframes party-disco {
    0%, 100% { background-position: 0% 50%; transform: scale(1); }
    50%      { background-position: 100% 50%; transform: scale(1.04); }
}

/* Tabellen-Zeilen schubsen sich gegenseitig */
body.party-mode tbody tr {
    animation: party-shimmy 4s ease-in-out infinite;
}
body.party-mode tbody tr:nth-of-type(2n) { animation-delay: -1s; animation-direction: reverse; }
body.party-mode tbody tr:nth-of-type(3n) { animation-delay: -2s; animation-duration: 3.2s; }
@keyframes party-shimmy {
    0%, 100% { transform: translateX(0); }
    50%      { transform: translateX(6px); }
}

/* Pills rotieren langsam */
body.party-mode .pill {
    animation: party-pill 5s linear infinite;
    display: inline-block;
}
@keyframes party-pill {
    0%   { transform: rotate(-3deg); }
    50%  { transform: rotate(3deg); }
    100% { transform: rotate(-3deg); }
}

/* FAB-Buttons hüpfen-rotieren */
body.party-mode .clock-fab,
body.party-mode .notification-fab,
body.party-mode .admin-toolbar-handle {
    animation: party-fab 1s ease-in-out infinite;
}
@keyframes party-fab {
    0%, 100% { transform: translateY(0) rotate(-8deg); }
    50%      { transform: translateY(-6px) rotate(8deg); }
}

/* Eingabefelder zittern bei Focus etwas extra */
body.party-mode input:focus,
body.party-mode textarea:focus,
body.party-mode select:focus {
    animation: party-jitter 0.3s linear infinite;
}

/* =====================================================================
   Quick Jump — Command Palette (⌘K / Strg+K). Modal mit Prefix-Suche
   ("t 12345" → Ticket, "c Acme" → Kunde, "> aktion" → Aktion).
===================================================================== */
.qj-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: var(--z-quickjump);
    opacity: 0;
    transition: opacity 0.15s ease;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
.qj-backdrop[hidden] { display: none; }
.qj-backdrop.is-open { opacity: 1; }

.qj-modal {
    position: fixed;
    top: 12vh;
    left: 50%;
    transform: translateX(-50%) translateY(-8px);
    width: min(640px, calc(100vw - 32px));
    max-height: 70vh;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
    z-index: calc(var(--z-quickjump) + 1);
    display: flex;
    flex-direction: column;
    opacity: 0;
    transition: opacity 0.15s ease, transform 0.15s ease;
    overflow: hidden;
}
.qj-modal[hidden] { display: none; }
.qj-modal.is-open { opacity: 1; transform: translateX(-50%) translateY(0); }

.qj-search {
    display: flex; align-items: center; gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}
.qj-search-icon { color: var(--text-muted); display: inline-flex; }
.qj-search-icon svg.icon { width: 18px; height: 18px; }
.qj-search input[type="search"] {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 15px;
    padding: 0;
    /* WebKit search-clear button ausblenden – wir haben Esc + Hint */
    appearance: none; -webkit-appearance: none;
}
.qj-search input[type="search"]::-webkit-search-decoration,
.qj-search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.qj-search input::placeholder { color: var(--text-muted); }
.qj-kbd {
    padding: 2px 6px;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 11px;
    color: var(--text-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    background: var(--bg);
    line-height: 1;
}

.qj-hints {
    display: flex; flex-wrap: wrap; gap: 4px 10px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 11px;
}
.qj-hints.is-hidden { display: none; }
.qj-hint {
    display: inline-flex; align-items: center; gap: 5px;
    color: var(--text-muted);
}
.qj-hint kbd {
    padding: 1px 5px;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--bg);
    color: var(--text);
    font-size: 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    line-height: 1;
    min-width: 14px;
    text-align: center;
}

.qj-results {
    flex: 1;
    overflow-y: auto;
    padding: 6px 0 10px;
}
.qj-results-empty {
    padding: 28px 16px;
    text-align: center;
    color: var(--text-muted);
    font-size: 13px;
}
.qj-group {
    padding: 10px 16px 4px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    font-weight: 600;
}
.qj-item {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 16px;
    text-decoration: none;
    color: var(--text);
    font-size: 13px;
    border-left: 3px solid transparent;
    cursor: pointer;
}
.qj-item:hover { background: var(--bg); }
.qj-item.is-active {
    background: var(--accent-soft);
    border-left-color: var(--accent);
}
.qj-item-icon {
    color: var(--text-muted);
    flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px;
}
.qj-item-icon svg.icon { width: 16px; height: 16px; }
.qj-item.is-active .qj-item-icon { color: var(--accent); }
.qj-item-body { flex: 1; min-width: 0; }
.qj-item-title {
    font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.qj-item-sub {
    font-size: 11px;
    color: var(--text-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Treffer-Highlight im Titel: orange + bold, kein Background damit es
   sich nicht mit der is-active-Hervorhebung beißt. */
.qj-mark {
    background: transparent;
    color: var(--accent);
    font-weight: 700;
    padding: 0;
}
.qj-item.is-active .qj-mark { color: var(--accent); }

/* Mini-Toast für Math-Copy-Feedback. Schwebt im Modal mittig unten. */
.qj-toast {
    position: absolute;
    left: 50%; bottom: 56px;
    transform: translateX(-50%) translateY(8px);
    background: var(--text);
    color: var(--surface);
    padding: 6px 12px;
    border-radius: 6px;
    font-size: 12px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.25);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    white-space: nowrap;
}
.qj-toast.is-show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.qj-footer {
    display: flex; gap: 18px; flex-wrap: wrap;
    padding: 8px 16px;
    border-top: 1px solid var(--border);
    background: var(--bg);
    font-size: 11px;
    color: var(--text-muted);
}
.qj-footer kbd {
    padding: 1px 5px;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    line-height: 1;
    margin-right: 3px;
    min-width: 14px;
    text-align: center;
    display: inline-block;
}

/* =====================================================================
   AppDialog — globaler Confirm/Alert-Ersatz für native Browser-Dialoge
===================================================================== */
.app-dialog-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.55);
    display: flex; align-items: center; justify-content: center;
    z-index: var(--z-dialog);
    opacity: 0;
    transition: opacity 0.2s ease;
    padding: 20px;
}
.app-dialog-backdrop[hidden] { display: none; }
.app-dialog-backdrop.is-open { opacity: 1; }
.app-dialog {
    background: var(--surface);
    color: var(--text);
    border-radius: 14px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.4);
    max-width: 440px;
    width: 100%;
    padding: 24px 24px 18px;
    text-align: center;
    transform: scale(0.92);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
.app-dialog-backdrop.is-open .app-dialog { transform: scale(1); }
.app-dialog-icon { font-size: 44px; line-height: 1; margin-bottom: 6px; }
.app-dialog-icon svg.icon { width: 44px; height: 44px; vertical-align: middle; }
.app-dialog-title { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
.app-dialog-message {
    margin: 0 0 18px;
    color: var(--text-muted);
    font-size: 13.5px;
    line-height: 1.55;
}
.app-dialog-actions {
    display: flex; gap: 10px; justify-content: center;
}

/* =====================================================================
   System-Broadcast-Banner + Acknowledge-Dialog
===================================================================== */
.broadcast-banner {
    display: flex; align-items: center; gap: 12px;
    /* Schwebend wie admin-banner / topbar — eigene Karten-Optik in der
       .main-Spalte. Padding 10px/18px ist die kanonische Banner-Padding-
       Breite und identisch zu `.alert` und `.card` (horizontal 18px) —
       Icon-Position links und Action-Button-Position rechts fluchten
       systemweit (siehe docs/UI-CONVENTIONS.md §12). */
    margin: 0 0 10px 0;
    padding: 10px 18px;
    min-height: 48px;
    font-size: 13px;
    line-height: 1.45;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    position: sticky;
    top: 0;
    z-index: calc(var(--z-banner) + 5); /* Broadcast minimal über admin-banner */
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.broadcast-banner.is-dismissed { opacity: 0; transform: translateY(-100%); }
.broadcast-banner.is-fresh { animation: admin-banner-slide-down 0.4s ease-out; }
/* Flache Pastell-Töne + dunkle Schrift + 1px Border — gleiche Palette wie
   die <x-banner>-Component, damit System-Broadcasts und Seiten-Banner
   zur selben visuellen Familie gehören (siehe UI-CONVENTIONS Sektion 7). */
.broadcast-info     { background: #e0e7ff; border: 1px solid #a5b4fc; color: #3730a3; }
.broadcast-warning  { background: #fef3c7; border: 1px solid #f3d97a; color: #7a5615; }
.broadcast-critical {
    background: #fee2e2; border: 1px solid #fca5a5; color: #991b1b;
    animation: broadcast-pulse-crit 2s ease-in-out infinite;
}
@keyframes broadcast-pulse-crit {
    0%, 100% { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
    50%      { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.28), 0 2px 8px rgba(0,0,0,0.1); }
}
/* Fixe 22px-Slot-Breite — egal ob das Icon selbst 22px (Voll-Banner) oder
   16px (Mini-Banner nach Bestätigung) groß ist, das Icon zentriert in
   einem 22px breiten Slot → optisch fluchtet die Icon-Mitte zwischen
   Mini-Banner und Voll-Banner darunter. */
.broadcast-icon {
    font-size: 22px; flex-shrink: 0;
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
}
.broadcast-body { flex: 1; min-width: 0; }
.broadcast-message { font-weight: 500; }
.broadcast-meta {
    margin-top: 2px;
    font-size: 11px;
    opacity: 0.72;
}
/* Bestätigen-Button im Banner — verwendet das System-`.btn .btn-sm`-
   Styling (siehe oben). `.broadcast-dismiss` ist nur noch ein JS-Hook,
   keine eigene Optik mehr. So fühlt sich der Button identisch zu allen
   anderen Buttons im System an. */
.broadcast-dismiss { flex-shrink: 0; }

/* Mini-Variante nach Bestätigung — schmaler, eine Zeile, deaktiviert
   das Animation-Pulsieren bei critical. Klickbar ist NUR der Toggle-
   Button (siehe unten), nicht der ganze Banner — sonst fühlte sich der
   ganze Banner wie ein dead-link an. */
.broadcast-banner-mini {
    min-height: 32px;
    padding: 6px 18px;
    font-size: 12.5px;
    opacity: 0.92;
    animation: none !important;
}
.broadcast-banner-mini .broadcast-icon { font-size: 16px; }
.broadcast-banner-mini .broadcast-body {
    display: flex; align-items: center;
    overflow: hidden;
    min-width: 0;
}
.broadcast-mini-text {
    display: flex; align-items: baseline; gap: 4px;
    min-width: 0; flex: 1;
    line-height: 1.3;
}
.broadcast-mini-preview {
    color: inherit; opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1;
}

/* Inline-Toggle „mehr/weniger" — erscheint nur wenn Text > 90 Zeichen
   ist (Server entscheidet beim Render). Klick toggelt is-expanded. */
.broadcast-mini-toggle {
    flex-shrink: 0;
    background: rgba(0,0,0,0.06);
    border: 1px solid currentColor;
    color: inherit;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    white-space: nowrap;
    transition: background 0.12s, transform 0.12s;
}
.broadcast-mini-toggle:hover { background: rgba(0,0,0,0.12); }
.broadcast-mini-toggle:active { transform: scale(0.95); }

/* Expanded-State: Vorschau-Span darf umbrechen und in die Höhe gehen */
.broadcast-banner-mini.is-expanded {
    align-items: flex-start;
}
.broadcast-banner-mini.is-expanded .broadcast-mini-text {
    align-items: flex-start;
    flex-wrap: wrap;
}
.broadcast-banner-mini.is-expanded .broadcast-mini-preview {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.5;
}

/* Stack-Offset wird dynamisch per JS gesetzt — siehe updateBannerStacks()
   in app.blade.php. Mini-Banner sind 32px, volle 52px → statisch wäre's
   immer falsch. */

/* Ack-Confirm-Dialog */
.broadcast-confirm-backdrop {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.55);
    display: flex; align-items: center; justify-content: center;
    z-index: var(--z-broadcast-confirm);
    opacity: 0;
    transition: opacity 0.2s ease;
}
.broadcast-confirm-backdrop[hidden] { display: none; }
.broadcast-confirm-backdrop.is-open { opacity: 1; }
.broadcast-confirm {
    background: var(--surface);
    color: var(--text);
    border-radius: 14px;
    box-shadow: 0 24px 64px rgba(0,0,0,0.4);
    max-width: 440px;
    width: calc(100% - 32px);
    padding: 24px 24px 18px;
    text-align: center;
    transform: scale(0.92);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}
.broadcast-confirm-backdrop.is-open .broadcast-confirm { transform: scale(1); }
/* WICHTIG: die nachfolgenden Dialog-Innen-Selektoren auf den Backdrop scopen,
   sonst kollidieren sie mit gleichnamigen Klassen im Banner-Button (z.B.
   .broadcast-confirm-icon, .broadcast-confirm-text) und blasen den
   „Kenntnis genommen"-Button auf. */
.broadcast-confirm-backdrop .broadcast-confirm-icon { font-size: 48px; line-height: 1; margin-bottom: 8px; width: auto; height: auto; background: transparent; border-radius: 0; }
.broadcast-confirm-backdrop .broadcast-confirm-icon svg.icon { width: 48px; height: 48px; }
.broadcast-confirm-backdrop .broadcast-confirm-title { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
.broadcast-confirm-backdrop .broadcast-confirm-text { margin: 0 0 18px; color: var(--text-muted); font-size: 13px; line-height: 1.55; }
.broadcast-confirm-actions {
    display: flex; gap: 10px; justify-content: center;
    margin-bottom: 12px;
}
.broadcast-confirm-stage {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* =====================================================================
   Modus-Übergangs-Overlay (Zeitreise / Doppelgänger rein und raus)
===================================================================== */
.phase-overlay {
    position: fixed; inset: 0;
    z-index: var(--z-overlay-phase);
    display: flex; align-items: center; justify-content: center; flex-direction: column;
    pointer-events: auto;
    overflow: hidden;
}
.phase-overlay[hidden] { display: none; }
.phase-overlay-bg {
    position: absolute; inset: 0;
    z-index: 0;
    opacity: 0;
}
.phase-overlay-rings {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    z-index: 1;
    pointer-events: none;
}
.phase-ring {
    position: absolute;
    width: 160px; height: 160px;
    border-radius: 50%;
    border: 2px solid transparent;
    opacity: 0;
    transform: scale(0);
}
.phase-overlay-center {
    position: relative;
    z-index: 2;
    font-size: 96px;
    line-height: 1;
    opacity: 0;
    transform: scale(0.5);
    filter: drop-shadow(0 8px 24px rgba(0,0,0,0.5));
}
.phase-overlay-caption {
    position: relative;
    z-index: 2;
    margin-top: 22px;
    color: #fff;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.02em;
    opacity: 0;
    text-shadow: 0 2px 8px rgba(0,0,0,0.4);
}

/* ---------- Time Travel ENTER (Wormhole) ---------- */
.is-tt-enter .phase-overlay-bg {
    background: radial-gradient(circle at center, #3b3a82 0%, #14154a 55%, #060924 100%);
    animation: phase-fade-in 0.32s ease-out forwards;
}
.is-tt-enter .phase-overlay-center {
    animation: phase-clock-warp 1.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.is-tt-enter .phase-overlay-caption {
    animation: phase-caption-pulse 1.3s ease-out 0.3s forwards;
}
.is-tt-enter .phase-ring {
    border-color: #9b9fff;
    animation: phase-ring-expand 1.1s ease-out forwards;
}
.is-tt-enter .phase-ring:nth-child(1) { animation-delay: 0.05s; }
.is-tt-enter .phase-ring:nth-child(2) { animation-delay: 0.25s; }
.is-tt-enter .phase-ring:nth-child(3) { animation-delay: 0.45s; }

/* ---------- Time Travel EXIT (Heim) ---------- */
.is-tt-exit .phase-overlay-bg {
    background: radial-gradient(circle at center, #ffe9b8 0%, #b8d8ff 50%, #ffffff 100%);
    animation: phase-fade-in 0.28s ease-out forwards;
}
.is-tt-exit .phase-overlay-center {
    color: #2a3a78;
    animation: phase-earth-home 1.05s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.is-tt-exit .phase-overlay-caption {
    color: #2a3a78;
    text-shadow: none;
    animation: phase-caption-pulse 1.05s ease-out 0.2s forwards;
}
.is-tt-exit .phase-ring {
    border-color: rgba(255,255,255,0.75);
    animation: phase-ring-collapse 0.85s ease-out forwards;
}
.is-tt-exit .phase-ring:nth-child(1) { animation-delay: 0.00s; }
.is-tt-exit .phase-ring:nth-child(2) { animation-delay: 0.10s; }
.is-tt-exit .phase-ring:nth-child(3) { animation-delay: 0.20s; }

/* ---------- Doppelgänger ENTER (Mask Shift) ---------- */
.is-doppel-enter .phase-overlay-bg {
    background: linear-gradient(135deg, #5b1f6e 0%, #b04ab5 50%, #e0639a 100%);
    animation: phase-fade-in 0.28s ease-out forwards;
}
.is-doppel-enter .phase-overlay-center {
    animation: phase-mask-arrive 1.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.is-doppel-enter .phase-overlay-caption {
    animation: phase-caption-pulse 1.3s ease-out 0.3s forwards;
}
.is-doppel-enter .phase-ring {
    border-style: dashed;
    border-color: rgba(255,255,255,0.6);
    animation: phase-ring-expand 1.0s ease-out forwards;
}
.is-doppel-enter .phase-ring:nth-child(1) { animation-delay: 0.10s; width: 220px; height: 220px; }
.is-doppel-enter .phase-ring:nth-child(2) { animation-delay: 0.30s; width: 220px; height: 220px; }
.is-doppel-enter .phase-ring:nth-child(3) { animation-delay: 0.50s; width: 220px; height: 220px; }

/* ---------- Doppelgänger EXIT (Maske fällt / Poof) ---------- */
.is-doppel-exit .phase-overlay-bg {
    background: radial-gradient(circle at center, #f5e1f1 0%, #ffffff 100%);
    animation: phase-fade-in 0.25s ease-out forwards;
}
.is-doppel-exit .phase-overlay-center {
    color: #5b1f6e;
    animation: phase-wand-poof 0.95s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.is-doppel-exit .phase-overlay-caption {
    color: #5b1f6e;
    text-shadow: none;
    animation: phase-caption-pulse 0.95s ease-out 0.15s forwards;
}
.is-doppel-exit .phase-ring {
    border-color: rgba(176, 74, 181, 0.5);
    animation: phase-ring-puff 0.8s ease-out forwards;
}
.is-doppel-exit .phase-ring:nth-child(1) { animation-delay: 0.05s; }
.is-doppel-exit .phase-ring:nth-child(2) { animation-delay: 0.20s; }
.is-doppel-exit .phase-ring:nth-child(3) { animation-delay: 0.35s; }

/* ---------- Keyframes ---------- */
@keyframes phase-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes phase-caption-pulse {
    0%   { opacity: 0; transform: translateY(8px); }
    35%  { opacity: 1; transform: translateY(0); }
    80%  { opacity: 1; }
    100% { opacity: 0; transform: translateY(-4px); }
}
@keyframes phase-clock-warp {
    0%   { opacity: 0; transform: scale(0.2) rotate(0deg); }
    25%  { opacity: 1; transform: scale(1) rotate(180deg); }
    65%  { opacity: 1; transform: scale(1.15) rotate(720deg); }
    100% { opacity: 0; transform: scale(2.2) rotate(1080deg); }
}
@keyframes phase-ring-expand {
    0%   { opacity: 0.9; transform: scale(0.1); }
    100% { opacity: 0;   transform: scale(4.5); }
}
@keyframes phase-earth-home {
    0%   { opacity: 0; transform: scale(2.4) rotate(-180deg); }
    50%  { opacity: 1; transform: scale(1) rotate(0); }
    85%  { opacity: 1; transform: scale(1) rotate(0); }
    100% { opacity: 0; transform: scale(1.05) rotate(0); }
}
@keyframes phase-ring-collapse {
    0%   { opacity: 0;   transform: scale(4.5); }
    50%  { opacity: 0.9; transform: scale(1.5); }
    100% { opacity: 0;   transform: scale(0); }
}
@keyframes phase-mask-arrive {
    0%   { opacity: 0; transform: scale(0.6) rotateY(-180deg); filter: blur(6px); }
    25%  { opacity: 1; filter: blur(0); }
    55%  { transform: scale(1.1) rotateY(0deg); }
    75%  { transform: scale(1.1) rotateY(0deg); }
    100% { opacity: 0; transform: scale(1.3) rotateY(0deg); }
}
@keyframes phase-wand-poof {
    0%   { opacity: 0; transform: scale(0.3) rotate(-30deg); }
    35%  { opacity: 1; transform: scale(1.15) rotate(15deg); }
    70%  { opacity: 1; transform: scale(1.15) rotate(15deg); }
    100% { opacity: 0; transform: scale(1.9) rotate(30deg); filter: blur(4px); }
}
@keyframes phase-ring-puff {
    0%   { opacity: 0;   transform: scale(0.4); }
    40%  { opacity: 0.7; transform: scale(1.2); }
    100% { opacity: 0;   transform: scale(2.4); }
}

/* Respekt für Reduce-Motion: Übergang fast unsichtbar machen */
@media (prefers-reduced-motion: reduce) {
    .phase-overlay-bg,
    .phase-overlay-center,
    .phase-overlay-caption,
    .phase-ring {
        animation: phase-fade-in 0.1s ease-out forwards !important;
    }
}

/* HTTP-Fehler-Seiten (403/404/500) — gemeinsamer Look */
.error-card {
    max-width: 560px;
    margin: 48px auto;
    padding: 40px 32px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    text-align: center;
}
.error-meme {
    display: block;
    margin: 0 auto 18px;
    max-width: 320px;
    width: 100%;
    height: auto;
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
/* Byte-Sprite (Pixel-Art, transparent) auf Fehlerseiten — crisp skaliert,
   ohne Schatten/Radius (der wäre auf den transparenten Pixeln sichtbar). */
.error-byte {
    display: block;
    margin: 0 auto 16px;
    width: 180px;
    max-width: 60%;
    height: auto;
    image-rendering: pixelated;
}
.error-code {
    font-size: 64px;
    font-weight: 800;
    line-height: 1;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.04em;
    margin-bottom: 6px;
}
.error-title {
    margin: 0 0 14px;
    font-size: 22px;
    font-weight: 600;
    color: var(--text);
}
.error-text {
    margin: 0 auto 24px;
    max-width: 440px;
    color: var(--text-muted);
    line-height: 1.55;
}
.error-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
    flex-wrap: wrap;
}
.error-meta {
    margin-top: 28px;
    padding-top: 16px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--text-muted);
}

/* Pagination (Laravel default) */
nav[role="navigation"] svg { display: inline; vertical-align: middle; height: 14px; }
.pagination, nav[role="navigation"] > div:last-child { display: flex; gap: 4px; flex-wrap: wrap; align-items: center; }

/* Guest (login) */
.guest-body {
    background: linear-gradient(135deg, #fff1e6 0%, #f5f5f3 100%);
    display: flex; align-items: center; justify-content: center;
    min-height: 100vh; padding: 24px;
    position: relative; overflow: hidden;
}
.guest-particles {
    position: fixed;
    inset: 0;
    width: 100%; height: 100%;
    z-index: 0;
    pointer-events: none;
}
.guest-shell { width: 100%; max-width: 380px; position: relative; z-index: 1; }
/* Breitere Variante für Formular-Seiten (z.B. öffentliches Support-Portal). */
.guest-shell-wide { max-width: 560px; }
.guest-card {
    background: white;
    border-radius: var(--radius-lg);
    padding: 32px 28px;
    box-shadow: var(--shadow);
    border: 1px solid var(--border);
}
.guest-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 28px; }
.guest-logo { display: block; height: 44px; width: auto; max-width: 100%; }
.guest-suffix {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    padding-left: 10px;
    border-left: 2px solid var(--border);
    line-height: 1;
}

/* Ticket-Stoppuhr — vollständig im Popover-Block oben definiert
   (siehe .stopwatch-popover). Legacy-Sidebar-Styles wurden entfernt;
   nur die Puls-Animation für den Status-Dot bleibt hier global. */
@keyframes sw-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.9); }
}

/* ============================================================
   Dark-mode overrides for hardcoded color values.
   `html.is-dark` is set by the inline theme script when the
   effective theme is dark (explicit choice OR system+OS dark).
   ============================================================ */
html.is-dark .pill { background: #2a2f34; color: #d6d6d2; }
html.is-dark .pill-red    { background: #3a1d1d; color: #f0a4a4; }
html.is-dark .pill-yellow { background: #3a2f15; color: #ecc466; }
html.is-dark .pill-green  { background: #1a3424; color: #82d49a; }
html.is-dark .pill-blue   { background: #1c2a47; color: #94b3ec; }
html.is-dark .pill-gray   { background: #2a2f34; color: #b6b6b2; }

html.is-dark .alert-info    { background: #1c2a47; border-color: #2c3d62; color: #b6cdf2; }
html.is-dark .alert-success { background: #1a3424; border-color: #265838; color: #b1e3c1; }
html.is-dark .alert-error   { background: #3a1d1d; border-color: #5a2a2a; color: #f0a4a4; }

html.is-dark .tl-comment.is-internal .tl-card { background: #2f2818; }
html.is-dark .tc-duration { border-color: #5a3a1c; }

html.is-dark code { background: var(--surface-2); color: var(--text); }

/* ============================================================
   Stundentafel (timesheet week view)
   ============================================================ */
.ts-toolbar {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 14px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.ts-user-name { font-weight: 600; font-size: 15px; }
.ts-user-picker select {
    padding: 5px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 13px;
}
.ts-range { display: flex; align-items: center; gap: 6px; font-size: 14px; color: var(--text-muted); }
.ts-range-month { font-weight: 600; color: var(--text); }
.ts-range-sep { opacity: 0.5; }
.ts-total { margin-left: auto; font-weight: 700; font-size: 14px; color: var(--accent); }

/* Stundentafel — Optik vom Kalender-Wochen-Grid (cal-tw-*) übernommen:
   Gap-Trick für 1-px-Trennlinien, sticky Header, dezente Halbstunden-
   Linien. Funktional bleibt das ts-* Markup unangetastet, damit
   Drag-Edit / Resize / Split / Merge weiterlaufen.
*/
/* Scrollable Wrapper, damit der Header sticky bleibt — analog
   .cal-tw-scroll. Sitzt in einer card mit padding:0 + overflow:hidden,
   die das border-radius clippt. */
.ts-scroll {
    max-height: calc(100vh - 220px);
    min-height: 400px;
    overflow-y: auto;
    overflow-x: hidden;
}
.ts-grid {
    display: grid;
    grid-template-columns: 56px repeat(7, minmax(0, 1fr));
    grid-template-rows: 42px var(--ts-grid-height);
    background: var(--border);
    gap: 1px;
}
/* Header sticky am oberen Rand — analog Kalender. */
.ts-grid > .ts-head {
    position: sticky;
    top: 0;
    z-index: 5;
}
.ts-head {
    background: var(--surface);
    padding: 6px 10px;
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
    font-size: 11px; line-height: 1.2;
    color: var(--text-muted);
}
.ts-head-axis {
    background: var(--surface-2);
    font-weight: 600;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* Heute-Header: Akzent-Bar unten, keine flächige Tönung — sonst wirkt
   die Spalte abgedunkelt gegenüber den anderen. */
.ts-head.is-today {
    color: var(--accent);
    box-shadow: inset 0 -3px 0 var(--accent);
    background: var(--surface);
}
.ts-head.is-weekend { background: #fbfaf6; }
.ts-head-day { font-size: 18px; font-weight: 600; color: var(--text); margin: 0; }
.ts-head.is-today .ts-head-day { color: var(--accent); }
.ts-head-name { text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px; }

.ts-axis {
    background: var(--surface);
    position: relative;
    grid-row: 2;
    grid-column: 1;
    height: var(--ts-grid-height);
}
.ts-axis-row {
    box-sizing: border-box;
    border-bottom: 1px solid var(--border);
    position: relative;
    padding: 0;
}
.ts-axis-label {
    position: absolute;
    top: -8px;
    right: 6px;
    font-size: 10px;
    color: var(--text-muted);
    background: var(--surface);
    padding: 0 4px;
    font-variant-numeric: tabular-nums;
}
.ts-axis-row:first-child .ts-axis-label { display: none; }

.ts-day {
    background: var(--surface);
    position: relative;
    grid-row: 2;
    height: var(--ts-grid-height);
    overflow: hidden;
    cursor: crosshair;
}
.ts-day.is-today { background: var(--surface); }
.ts-day.is-weekend { background: #fbfaf6; }
.ts-day-row {
    box-sizing: border-box;
    border-bottom: 1px solid var(--border);
    background: transparent;
}
/* Dezenter Halbstunden-Strich für jedes zweite Stundenraster — gleich
   wie Kalender. Vorheriger Repeating-Gradient war zu kontrastreich. */
.ts-day-row:nth-child(2n) {
    border-bottom-color: rgba(0,0,0,0.04);
}
html.is-dark .ts-day-row:nth-child(2n) {
    border-bottom-color: rgba(255,255,255,0.04);
}

/* Block-Stil orientiert sich am cal-tw-event: dünner Akzent-Balken
   links, leicht getönter Background, kein voll umrandeter Kasten.
   Die per-Ticket-Palette aus inline-style (background + border-color)
   bleibt erhalten — färbt jetzt Akzent-Balken + Hintergrund. */
.ts-block {
    position: absolute;
    left: 2px;
    right: 2px;
    border-radius: 3px;
    padding: 3px 6px;
    font-size: 11px;
    line-height: 1.3;
    overflow: hidden;
    text-decoration: none;
    color: var(--text);
    border: 0;
    border-left: 3px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 1px;
    z-index: 2;
}
.ts-block-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-block-sub { color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 10px; }
.ts-block-dur { font-weight: 600; align-self: flex-end; margin-top: auto; font-size: 10px; opacity: 0.85; font-variant-numeric: tabular-nums; }
.ts-entry { cursor: grab; user-select: none; }
.ts-entry.is-dragging { cursor: grabbing; opacity: 0.85; box-shadow: 0 4px 14px rgba(0,0,0,0.18); z-index: 10; }
.ts-entry:hover { filter: brightness(0.96); color: var(--text); }
.ts-handle {
    position: absolute;
    left: 0; right: 0;
    height: 6px;
    cursor: ns-resize;
    background: transparent;
}
.ts-handle-top { top: 0; }
.ts-handle-bottom { bottom: 0; }
.ts-entry:hover .ts-handle { background: rgba(0, 0, 0, 0.08); }
html.is-dark .ts-entry:hover .ts-handle { background: rgba(255, 255, 255, 0.12); }

.ts-ghost {
    background: rgba(254, 89, 0, 0.18);
    border: 2px dashed var(--accent);
    pointer-events: none;
    z-index: 5;
    color: var(--accent-strong);
    font-weight: 600;
}
.ts-ghost .ts-time-label { display: block; }

.ts-floating-time {
    position: fixed;
    transform: translateX(-50%);
    background: var(--text);
    color: var(--surface);
    padding: 4px 10px;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 2px 8px rgba(0,0,0,0.25);
    z-index: 200;
    opacity: 0;
    transition: opacity 0.08s;
}
.ts-floating-time.is-visible { opacity: 1; }

.ts-menu {
    position: fixed;
    z-index: 100;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 160px;
}
.ts-menu a, .ts-menu button {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border: none;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    border-radius: 4px;
    text-decoration: none;
}
.ts-menu a:hover, .ts-menu button:hover { background: var(--surface-2); color: var(--accent); }
.ts-menu button[data-act="delete"]:hover { background: #fdecec; color: #b13333; }
html.is-dark .ts-menu button[data-act="delete"]:hover { background: #3a1d1d; color: #f0a4a4; }


/* ============================================================
   Device picker (tag-input style for linking devices to tickets)
   ============================================================ */
.device-picker {
    display: flex; flex-direction: column;
    gap: 6px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
}
.device-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.device-chips:empty { display: none; }
.device-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 6px 4px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 12px;
}
.device-chip code {
    background: transparent;
    padding: 0;
    font-weight: 600;
}
.device-chip-meta { color: var(--text-muted); font-size: 11px; }
.device-chip button[data-remove] {
    border: none;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    width: 18px; height: 18px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; line-height: 1;
    padding: 0;
}
.device-chip button[data-remove]:hover { background: #fdecec; color: #b13333; }
html.is-dark .device-chip button[data-remove]:hover { background: #3a1d1d; color: #f0a4a4; }
.device-picker-search { position: relative; }
.device-picker-input {
    border: none;
    padding: 4px 6px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 13px;
    outline: none;
    width: 100%;
}
.device-picker-suggestions {
    position: absolute; top: 100%; left: 0; right: 0;
    margin-top: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 8px 20px rgba(0,0,0,0.08);
    max-height: 280px; overflow-y: auto;
    z-index: 1000;
    padding: 4px 0;
}
.device-picker-item {
    display: flex; align-items: baseline; gap: 8px;
    padding: 6px 10px;
    cursor: pointer;
    font-size: 13px;
}
.device-picker-item code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-weight: 600;
    background: transparent;
    padding: 0;
}
.device-picker-item-meta { color: var(--text-muted); font-size: 12px; }
.device-picker-item:hover,
.device-picker-item.is-active { background: var(--surface-2); }
.device-picker-item.is-active { outline: 2px solid var(--accent); outline-offset: -2px; }
/* ============================================================
   Kategorie-Karten (admin/inventory)
   ============================================================ */
.category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 12px;
}
.category-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.category-card:hover { border-color: var(--accent); box-shadow: 0 2px 8px rgba(0,0,0,0.04); }
.category-card-view {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 6px;
    position: relative;
}
.category-card-icon {
    font-size: 36px; line-height: 1;
    margin: 4px 0 2px;
}
.category-card-name { font-weight: 600; font-size: 14px; }
.category-card-meta {
    display: flex; gap: 10px; align-items: center; justify-content: center;
    font-size: 11px; color: var(--text-muted);
}
.category-card-key code {
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-weight: 600;
    padding: 2px 6px;
    border-radius: 3px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.category-card-count { white-space: nowrap; }
.category-card-actions {
    position: absolute; top: -4px; right: -4px;
    display: flex; gap: 4px;
    opacity: 0;
    transition: opacity 0.12s;
}
.category-card:hover .category-card-actions,
.category-card:focus-within .category-card-actions { opacity: 1; }
.category-card-edit { padding-top: 4px; }

/* ============================================================
   Bearbeiter-Liste / Assignee-Picker
   ============================================================ */
.assignee-list { display: flex; flex-wrap: wrap; gap: 6px; }
.assignee-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 9px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 12px;
    font-size: 12px;
    line-height: 1.3;
}
.assignee-chip.is-primary {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent-strong);
    font-weight: 600;
}
.assignee-star { color: var(--accent); font-size: 13px; line-height: 1; }

.assignee-picker {
    display: flex; flex-direction: column; gap: 8px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
}
.assignee-picker .assignee-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.assignee-picker .assignee-chip {
    padding: 3px 4px 3px 4px;
    border-radius: 6px;
}
.assignee-star-btn {
    border: none; background: transparent;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 14px; line-height: 1;
    padding: 0 2px;
}
.assignee-star-btn:hover { color: var(--accent); }
.assignee-chip.is-primary .assignee-star-btn { color: var(--accent); }
.assignee-name { padding: 0 4px; }
.assignee-remove-btn {
    border: none; background: transparent;
    color: var(--text-muted); cursor: pointer;
    width: 18px; height: 18px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; line-height: 1; padding: 0;
}
.assignee-remove-btn:hover { background: #fdecec; color: #b13333; }
html.is-dark .assignee-remove-btn:hover { background: #3a1d1d; color: #f0a4a4; }
.assignee-search { position: relative; }
.assignee-picker-input {
    border: none; padding: 4px 6px;
    background: transparent; color: var(--text);
    font: inherit; font-size: 13px;
    outline: none; width: 100%;
}
.assignee-picker-suggestions {
    position: absolute; top: 100%; left: 0; right: 0;
    margin-top: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 8px 20px rgba(0,0,0,0.08);
    max-height: 240px; overflow-y: auto;
    z-index: 1000;
    padding: 4px 0;
}
.assignee-picker-item {
    padding: 6px 10px; font-size: 13px;
    cursor: pointer;
}
.assignee-picker-item:hover,
.assignee-picker-item.is-active { background: var(--surface-2); }
.assignee-picker-item.is-active { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ============================================================
   Bestell-Positionen — dynamische Reihen im PO-Form
   ============================================================ */
.po-items { display: flex; flex-direction: column; gap: 10px; }
.po-item-row {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    background: var(--surface-2);
}
.po-item-grid {
    display: grid;
    grid-template-columns: 1fr 140px 80px 30px;
    grid-template-areas:
        "product  art      qty     remove"
        "customer customer target  target"
        "address  address  address address";
    gap: 8px 10px;
    align-items: end;
}
.po-item-cell { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* Felder unter „Positionen" optisch identisch zu den Standard-Formular-
   feldern (.form-row), damit das Overlay durchgängig wirkt. */
.po-item-cell label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 500; }
.po-item-cell input,
.po-item-cell select {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
    font-family: inherit;
    background: var(--surface);
    color: var(--text);
    min-height: 36px;
    width: 100%;
    box-sizing: border-box;
}
.po-item-cell input:focus,
.po-item-cell select:focus {
    outline: none;
    border-color: var(--accent);
}
.po-item-product  { grid-area: product; }
.po-item-art      { grid-area: art; }
.po-item-qty      { grid-area: qty; }
.po-item-actions  { grid-area: remove; align-self: end; }
.po-item-customer { grid-area: customer; }
.po-item-target   { grid-area: target; }
.po-item-address  { grid-area: address; }
@media (max-width: 640px) {
    .po-item-grid {
        grid-template-columns: 1fr 80px 30px;
        grid-template-areas:
            "product  product remove"
            "art      qty     qty"
            "customer customer customer"
            "target   target  target"
            "address  address address";
    }
}

/* Abrechnen-Modal (po-bill-modal): pro Endkunde EIN Gruppenfeld als Default.
   Die Pro-Position-Felder sind nur ein Detail-Override und bleiben verborgen,
   bis der Nutzer „Einzelne Rechnungsnummern" einblendet (Gruppe .is-split).
   Versteckt bleibende Felder werden weiter vom Gruppenfeld befüllt und ganz
   normal mit abgeschickt (display:none unterdrückt kein Submit). */
.po-bill-item-field { display: none; }
.po-bill-group.is-split .po-bill-item-field { display: inline-block; }
.po-bill-split {
    margin-top: 2px; padding: 0; border: 0; background: none;
    color: var(--accent); font: inherit; font-size: 12px; cursor: pointer;
}
.po-bill-split:hover { text-decoration: underline; }

/* Abrechnen-Block am Ende eines Fakturierungs-Detail-Modals (Rechnungsnummer-
   Eingabe unter den Daten) — dezent vom Rest abgesetzt. */
.modal-bill-form { margin-top: 18px; border-top: 1px solid var(--border); padding-top: 14px; }

/* ============================================================
   Gerätegruppen — Multi-Picker auf Geräten + Tiles
   ============================================================ */
.device-group-picker {
    display: flex; flex-direction: column; gap: 6px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
}
.device-group-picker-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.device-group-picker-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 4px 3px 10px;
    background: #dbe9ff;
    color: #1e3a8a;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
}
html.is-dark .device-group-picker-chip { background: #1e3a8a; color: #dbe9ff; }
.device-group-picker-chip button {
    border: none; background: transparent;
    color: inherit; opacity: 0.6; cursor: pointer;
    width: 18px; height: 18px;
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 14px; line-height: 1; padding: 0;
}
.device-group-picker-chip button:hover { opacity: 1; background: rgba(0,0,0,0.1); }
.device-group-picker-input {
    border: none; padding: 4px 6px;
    background: transparent; color: var(--text);
    font: inherit; font-size: 13px;
    outline: none; width: 100%;
}

/* ============================================================
   IP-Adressen — Multi-Input und Anzeige-Badges
   ============================================================ */
.ip-list { display: flex; flex-direction: column; gap: 6px; }
.ip-row { display: flex; gap: 6px; align-items: center; }
.ip-row > input { flex: 1; }
.ip-display { display: flex; flex-wrap: wrap; gap: 6px; }
.ip-badge {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 2px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 12px;
}
.ip-badge code {
    background: transparent; padding: 0;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.ip-kind {
    font-size: 9px; font-weight: 700; letter-spacing: 0.05em;
    padding: 1px 5px; border-radius: 2px; text-transform: uppercase;
    background: var(--accent-soft); color: var(--accent-strong);
}

.device-list { display: flex; flex-direction: column; gap: 4px; }
.device-chip-link {
    text-decoration: none;
    color: inherit;
    transition: border-color 0.12s, background 0.12s;
}
.device-chip-link:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }

/* ============================================================
   Customer contacts list
   ============================================================ */
.contact-list { display: flex; flex-direction: column; gap: 8px; }
.contact-row {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 14px;
    background: var(--surface);
}
.contact-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.contact-role { color: var(--text-muted); font-size: 13px; }
.contact-meta { display: flex; flex-wrap: wrap; gap: 14px; font-size: 13px; color: var(--text-muted); margin-bottom: 4px; }
.contact-meta a { color: var(--text); }
.contact-meta a:hover { color: var(--accent); }
.contact-notes { font-size: 12px; color: var(--text-muted); margin-top: 4px; padding-top: 4px; border-top: 1px dashed var(--border); white-space: pre-wrap; }
.contact-form { margin-top: 12px; padding: 12px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px; }

/* Letzte Aktivitäten auf der Mitarbeiter-Seite */
.emp-activity-list { display: flex; flex-direction: column; gap: 8px; max-height: 380px; overflow-y: auto; }
.emp-activity-row { display: flex; gap: 8px; font-size: 12px; padding: 4px 0; border-bottom: 1px dashed var(--border); }
.emp-activity-row:last-child { border-bottom: none; }
.emp-activity-time { flex: none; width: 70px; color: var(--text-muted); font-size: 11px; padding-top: 2px; }
.emp-activity-body { flex: 1; min-width: 0; }

/* Mitarbeiter-Dokumentenablage */
.doc-folder-tree { display: flex; flex-direction: column; gap: 4px; margin-top: 12px; }
.doc-folder {
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface-2);
}
.doc-folder-head {
    list-style: none;
    cursor: pointer;
    padding: 8px 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
}
.doc-folder-head::-webkit-details-marker { display: none; }
.doc-folder-head::marker { content: ''; }
.doc-folder-head::before {
    content: '▸';
    color: var(--text-muted);
    font-size: 11px;
    transition: transform 0.15s;
    display: inline-block;
}
.doc-folder[open] > .doc-folder-head::before { transform: rotate(90deg); }
.doc-folder-icon { font-size: 16px; }
.doc-folder-name { font-weight: 600; flex: 1; }
.doc-folder-count {
    background: var(--surface);
    color: var(--text-muted);
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}
.doc-folder-actions { display: flex; gap: 4px; opacity: 0; transition: opacity 0.15s; }
.doc-folder-head:hover .doc-folder-actions { opacity: 1; }

.doc-list { display: flex; flex-direction: column; gap: 4px; padding: 4px 8px 8px; }
.doc-row {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 8px 10px;
}
.doc-row-view { display: flex; gap: 10px; align-items: flex-start; }
.doc-row-icon { font-size: 22px; flex: none; padding-top: 2px; }
.doc-row-body { flex: 1; min-width: 0; }
.doc-row-name {
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.doc-row-name a { color: var(--text); font-weight: 500; }
.doc-row-name a:hover { color: var(--accent); }
.doc-row-meta { font-size: 11px; color: var(--text-muted); margin-top: 2px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.doc-row-desc { font-size: 12px; color: var(--text-muted); margin-top: 4px; font-style: italic; }
.doc-row-actions { display: flex; gap: 4px; flex: none; }

/* Hardware-Zuordnung pro Mitarbeiter */
.hw-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.hw-row {
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px 10px;
    background: var(--surface-2);
}
.hw-row-head { display: flex; gap: 10px; align-items: flex-start; }
.hw-row-icon {
    font-size: 24px;
    text-decoration: none;
    flex: none;
    line-height: 1;
    padding-top: 2px;
}

/* Profilbild eines Ansprechpartners — quadratisch, rund maskiert */
.contact-avatar {
    flex: none;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.contact-avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: 0.04em;
}

/* Compact icon-only button used for delete actions in inline lists */
.btn-icon { padding: 4px 7px; font-size: 13px; min-width: 28px; }

/* Customer logo in master-data card */
.customer-logo {
    width: 56px; height: 56px;
    border-radius: 8px;
    object-fit: cover;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.customer-logo-placeholder {
    width: 56px; height: 56px;
    border-radius: 8px;
    background: var(--accent);
    color: white;
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 18px;
}

/* Customer file browser */
.cf-breadcrumbs {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    padding: 8px 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    margin-bottom: 12px;
    font-size: 13px;
}
.cf-breadcrumbs a { color: var(--accent); }
.cf-sep { color: var(--text-subtle); }
.cf-actions { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.cf-action-form { display: flex; gap: 6px; align-items: center; flex: 1; min-width: 240px; }
.cf-action-form input[type="text"], .cf-action-form input[type="file"] {
    flex: 1; padding: 6px 10px;
    border: 1px solid var(--border); border-radius: 6px;
    font-size: 13px; background: var(--surface); color: var(--text);
}

/* =====================================================================
   NOTIZ-DRAWER — Sticky-Note-Scratchpad mit FAB rechts unten.
   Folgt dem etablierten FAB-+-Slide-over-Drawer-Pattern der
   Benachrichtigungen. Container-Innenrand 18px gemäß §12.
===================================================================== */

/* FAB sitzt links vom Clock-FAB (24 + 56 + 8 = 88) + (88 + 56 + 8 = 152). */
.notes-fab {
    position: fixed;
    bottom: 24px; right: 152px;
    width: 56px; height: 56px;
    border-radius: 50%;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
    z-index: 9998;
    transition: transform 0.15s, box-shadow 0.15s, background 0.12s;
}
.notes-fab:hover {
    transform: scale(1.08);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
    background: var(--surface-2);
}
.notes-fab-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; line-height: 1;
}
.notes-fab-icon svg.icon { width: 24px; height: 24px; vertical-align: 0; }

/* Drawer — gleiche Floating-Card-Optik wie Notification-Drawer. */
.notes-drawer-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 9990;
    opacity: 0;
    transition: opacity 0.25s;
}
.notes-drawer-backdrop.is-open { opacity: 1; }

.notes-drawer {
    position: fixed;
    top: 12px; right: 12px; bottom: 12px;
    width: 400px; max-width: calc(100vw - 24px);
    background: var(--surface); color: var(--text);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.22);
    z-index: 9999;
    display: flex; flex-direction: column;
    overflow: hidden;
    transform: translateX(calc(100% + 24px));
    transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
.notes-drawer.is-open { transform: translateX(0); }

.notes-drawer-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.notes-drawer-title {
    margin: 0; font-size: 15px;
    flex: 1; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notes-drawer-actions { display: flex; gap: 4px; flex: none; }

/* Tab-Leiste unter dem Header — Meine / Geteilt / Alle */
.notes-drawer-tabs {
    display: flex; gap: 4px;
    padding: 10px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}
.notes-tab {
    flex: 1;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12px; font-weight: 500;
    cursor: pointer;
    transition: all 0.12s;
    display: inline-flex; align-items: center; justify-content: center; gap: 4px;
}
.notes-tab:hover { color: var(--text); }
.notes-tab.is-active {
    background: var(--accent);
    border-color: var(--accent);
    color: white;
}
.notes-tab-count {
    display: inline-block;
    padding: 0 6px;
    border-radius: 9px;
    font-size: 10px;
    background: rgba(0, 0, 0, 0.12);
}
.notes-tab.is-active .notes-tab-count { background: rgba(255, 255, 255, 0.25); }

/* Sichtbarkeits-Radio — wird sowohl in Edit-Mode-Karten als auch bei
   neuen Drafts verwendet. */
.notes-editor-visibility {
    display: flex; gap: 8px;
    font-size: 12px; color: var(--text-muted);
}
.notes-editor-visibility label {
    display: inline-flex; align-items: center; gap: 4px;
    cursor: pointer;
}
.notes-editor-visibility input[type="radio"] { margin: 0 2px 0 0; }

/* Body: scrollende Liste */
.notes-drawer-body { flex: 1; overflow-y: auto; }
.notes-empty { padding: 36px; text-align: center; color: var(--text-muted); font-size: 13px; }

.notes-item {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--text-muted);
    border-radius: var(--radius-lg);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
    padding: 12px 14px;
    margin: 10px 14px;
    display: flex; flex-direction: column; gap: 6px;
    transition: background 0.12s, box-shadow 0.12s;
}
.notes-item:hover {
    background: var(--surface-2);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.notes-item.is-shared { border-left-color: #5b8def; }
.notes-item.is-private { border-left-color: #8b8b8b; }
.notes-item.is-editing {
    background: var(--surface-2);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.notes-item-head {
    display: flex; align-items: center; gap: 8px;
}
.notes-item-title {
    flex: 1; min-width: 0;
    font-weight: 600; font-size: 13.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notes-item-title.is-untitled {
    color: var(--text-muted); font-weight: 500; font-style: italic;
}

/* Body wird per default auf 88px geclampt — lange Notizen sind eingeklappt.
   Der mehr/weniger-Toggle (JS) hängt `is-expanded` an die Karte und löst
   damit das clamp auf. */
.notes-item-body {
    font-size: 12.5px; line-height: 1.45;
    color: var(--text);
    white-space: pre-wrap; word-wrap: break-word;
    max-height: 88px;
    overflow: hidden;
    position: relative;
}
/* Fade-Out am unteren Rand wenn geclampt — nur sichtbar wenn der Body
   wirklich überläuft. `is-clampable` wird vom JS gesetzt. */
.notes-item-body.is-clampable::after {
    content: '';
    position: absolute; left: 0; right: 0; bottom: 0; height: 22px;
    background: linear-gradient(to bottom, transparent, var(--surface));
    pointer-events: none;
}
.notes-item:hover .notes-item-body.is-clampable::after {
    background: linear-gradient(to bottom, transparent, var(--surface-2));
}
.notes-item.is-expanded .notes-item-body {
    max-height: none;
}
.notes-item.is-expanded .notes-item-body::after { display: none; }

.notes-item-toggle {
    align-self: flex-start;
    padding: 2px 8px;
    background: transparent;
    border: none;
    color: var(--accent);
    font: inherit;
    font-size: 11px; font-weight: 600;
    cursor: pointer;
    border-radius: 4px;
}
.notes-item-toggle:hover { background: rgba(0, 0, 0, 0.04); }
.notes-item-toggle[hidden] { display: none; }

.notes-item-meta {
    display: flex; align-items: center; justify-content: space-between;
    gap: 8px; flex-wrap: wrap;
    font-size: 11px; color: var(--text-muted);
}
.notes-item-meta-left { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.notes-item-actions { display: flex; gap: 4px; }
.notes-item-actions .btn-icon { padding: 2px 5px; }

/* Edit-Mode: Titel + Body als Inputs INNERHALB derselben Karte —
   kein separates Editor-Feld mehr im Header. */
.notes-item-edit-title,
.notes-item-edit-body {
    width: 100%;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    box-sizing: border-box;
}
.notes-item-edit-body { resize: vertical; min-height: 80px; }
.notes-item-edit-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 8px; flex-wrap: wrap;
}
.notes-item-edit-actions { display: flex; gap: 6px; }

/* =====================================================================
   KALENDER — Layout (Kalender links + Sidebar rechts).
===================================================================== */
.cal-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 280px;
    gap: 14px;
    align-items: start;
}
.cal-main { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.cal-sidebar { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 70px; }
@media (max-width: 980px) {
    .cal-layout { grid-template-columns: 1fr; }
    .cal-sidebar { position: static; }
}

/* Sidebar-Listen */
.cal-side-list { list-style: none; margin: 0; padding: 0; }
.cal-side-event,
.cal-side-ticket {
    display: flex; flex-direction: column; gap: 1px;
    padding: 6px 8px;
    border-left: 3px solid var(--blue, #2e86de);
    background: rgba(46, 134, 222, 0.06);
    border-radius: 0 4px 4px 0;
    margin-bottom: 6px;
    font-size: 12px;
}
.cal-side-event.is-linked {
    border-left-color: var(--accent);
    background: rgba(254, 89, 0, 0.06);
}
.cal-side-time { font-weight: 600; font-variant-numeric: tabular-nums; }
.cal-side-title { font-weight: 500; word-break: break-word; }
.cal-side-loc { font-size: 11px; color: var(--text-muted); }
.cal-side-ticket a { display: flex; flex-direction: column; text-decoration: none; color: inherit; }
.cal-side-ticket a:hover { text-decoration: underline; }
.cal-side-num { font-size: 10px; font-weight: 600; color: var(--text-muted); }
.cal-side-due { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.cal-side-due.is-overdue { color: var(--red); font-weight: 600; }

/* Kalender-Bedienung sitzt jetzt im System-Topbar (page_actions-Slot).
   Hier nur die Layout-Helpers für die Gruppen — Datum + KW erscheinen
   im page_subtitle, also keine eigene Title-Komponente mehr. */
.cal-topbar-nav { display: inline-flex; gap: 4px; }
/* Kalender-/Aufgaben-/Users-View-Toggles nutzen den kanonischen .seg-toggle
   (§16) — die fruehere .cal-view-btn-Variante war kleiner und runder als die
   .btn-Controls daneben („zu niedrig") und wurde entfernt. */

/* =====================================================================
   KALENDER — Tag- und Wochen-Ansicht (Stunden-Grid mit Events).
   Lehnt sich optisch an .ts-grid aus dem Stundentafel-Modul an.
===================================================================== */
/* Container scrollt vertikal — 24-Stunden-Grid passt sonst nie auf
   den Bildschirm. JS scrollt initial zur aktuellen Stunde. */
.cal-tw-scroll {
    max-height: calc(100vh - 220px);
    min-height: 400px;
    overflow-y: auto;
    overflow-x: hidden;
}
.cal-tw-grid {
    display: grid;
    grid-template-columns: 56px repeat(var(--cal-day-count), minmax(0, 1fr));
    grid-template-rows: 42px var(--cal-grid-h);
    background: var(--border);
    gap: 1px;
}
/* Wenn ganztägige Termine vorhanden, kommt eine zusätzliche Reihe
   zwischen Header und Stunden-Grid — passt sich der Höhe der Chips an. */
.cal-tw-grid.has-allday {
    grid-template-rows: 42px auto var(--cal-grid-h);
}
/* Header sticky am oberen Rand des scrollbaren Containers */
.cal-tw-grid > .cal-tw-head {
    position: sticky;
    top: 0;
    z-index: 5;
}
/* All-Day-Row */
.cal-tw-allday-axis {
    /* Leere Zelle als Platzhalter für die Achs-Spalte — nur Optik,
       passt zum Stunden-Achs-Hintergrund darunter. */
    background: var(--surface-2);
    grid-row: 2;
    grid-column: 1;
    position: sticky; top: 42px; z-index: 4;
}
.cal-tw-allday {
    background: var(--surface);
    padding: 4px;
    display: flex; flex-direction: column; gap: 2px;
    min-height: 22px;
    grid-row: 2;
    position: sticky; top: 42px; z-index: 4;
}
.cal-tw-allday.is-weekend { background: #fbfaf6; }
.cal-tw-allday-event {
    border: 0;
    background: rgba(46, 134, 222, 0.14);
    color: #1c5aa3;
    border-left: 3px solid #2e86de;
    border-radius: 3px;
    padding: 2px 6px;
    font-size: 11px;
    line-height: 1.3;
    cursor: pointer;
    text-align: left;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cal-tw-allday-event:hover { background: rgba(46, 134, 222, 0.24); }
.cal-tw-allday-event.cal-ev-ticket {
    background: rgba(254, 89, 0, 0.14);
    color: #a3360c;
    border-left-color: var(--accent);
}
.cal-tw-allday-event.cal-ev-ticket:hover { background: rgba(254, 89, 0, 0.24); }
/* Wenn All-Day-Row aktiv, Axis + Day rutschen auf Row 3 */
.cal-tw-grid.has-allday .cal-tw-axis,
.cal-tw-grid.has-allday .cal-tw-day {
    grid-row: 3;
}
.cal-tw-head {
    background: var(--surface);
    padding: 6px 10px;
    display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
    font-size: 11px; line-height: 1.2;
    color: var(--text-muted);
}
.cal-tw-axis-head {
    background: var(--surface-2);
    font-weight: 600;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
/* Heute-Header: nur Akzent-Farbe + Border-Bottom, keine Background-
   Tönung — sonst wirkt die heutige Spalte im Vollbildmodus optisch
   abgedunkelt gegenüber den anderen Tagen. */
.cal-tw-head.is-today {
    color: var(--accent);
    box-shadow: inset 0 -3px 0 var(--accent);
}
.cal-tw-head.is-weekend { background: #fbfaf6; }
.cal-tw-head-name { text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px; }
.cal-tw-head-day { font-size: 18px; font-weight: 600; color: var(--text); }
.cal-tw-head.is-today .cal-tw-head-day { color: var(--accent); }

.cal-tw-axis {
    background: var(--surface);
    position: relative;
    grid-row: 2;
    grid-column: 1;
}
.cal-tw-axis-row {
    border-bottom: 1px solid var(--border);
    position: relative;
}
.cal-tw-axis-label {
    position: absolute;
    top: -8px;
    right: 6px;
    font-size: 10px;
    color: var(--text-muted);
    background: var(--surface);
    padding: 0 4px;
    font-variant-numeric: tabular-nums;
}
/* Erstes Label (00:00) komplett ausblenden — der Beginn der Stunden-
   achse ist implizit, ein Label dort wirkt redundant. */
.cal-tw-axis-row:first-child .cal-tw-axis-label {
    display: none;
}

.cal-tw-day {
    background: var(--surface);
    position: relative;
    cursor: crosshair;
    grid-row: 2;
}
/* Heute-Spalte: keine Background-Tönung mehr — wirkte sonst gegenüber
   den anderen Spalten "abgedunkelt". Akzent steckt im Header (s.o.). */
.cal-tw-day.is-weekend { background: #fbfaf6; }
.cal-tw-day-row {
    border-bottom: 1px solid var(--border);
}
.cal-tw-day-row:nth-child(2n) {
    border-bottom-color: rgba(0,0,0,0.04);
}

/* Event-Block in Tag/Wochen-Ansicht */
.cal-tw-event {
    position: absolute;
    left: 2px;
    right: 2px;
    background: rgba(46, 134, 222, 0.14);
    color: #1c5aa3;
    border-left: 3px solid #2e86de;
    border-radius: 3px;
    padding: 3px 6px;
    font-size: 11px;
    line-height: 1.3;
    cursor: pointer;
    overflow: hidden;
    z-index: 2;
}
.cal-tw-event:hover { background: rgba(46, 134, 222, 0.24); z-index: 3; }
.cal-tw-event-time { font-weight: 600; display: block; font-variant-numeric: tabular-nums; }
/* Titel: wenn das Event hoch genug ist, mehrzeilig umbrechen und am
   Ende mit Ellipsis abschneiden, statt mitten im Wort zu clippen. */
.cal-tw-event-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
    font-weight: 500;
    word-break: break-word;
}
.cal-tw-event-loc {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    line-clamp: 1;
    overflow: hidden;
    font-size: 10px;
    color: inherit;
    opacity: 0.7;
}

/* Kompakt-Variante für sehr kurze Termine (<=30 min): Zeit + Titel
   in einer Zeile, ohne extra Block-Umbruch. Sonst würde der Titel
   bei zu kleiner Box-Höhe komplett wegclippen. */
.cal-tw-event.is-compact {
    padding: 1px 6px;
    line-height: 1.15;
    white-space: nowrap;
}
.cal-tw-event.is-compact .cal-tw-event-time { display: inline; margin-right: 5px; }
.cal-tw-event.is-compact .cal-tw-event-title {
    display: inline;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: initial;
    line-clamp: initial;
}
.cal-tw-event.is-compact .cal-tw-event-loc { display: none; }

/* Off-Hours-Overlay: dezent abgedunkelte Bereiche außerhalb der
   Arbeitszeit. Liegt über den Stunden-Linien, unter den Events. */
.cal-tw-offhours {
    position: absolute;
    left: 0; right: 0;
    background: rgba(15, 23, 42, 0.05);
    pointer-events: none;
    z-index: 1;
}
:root[data-theme="dark"] .cal-tw-offhours { background: rgba(0, 0, 0, 0.22); }
@media (prefers-color-scheme: dark) {
    :root[data-theme="system"] .cal-tw-offhours { background: rgba(0, 0, 0, 0.22); }
}

/* Aktuelle-Zeit-Linie.
   In jeder Tagesspalte gerendert: heute volle Intensität (mit Punkt),
   Vergangenheit/Zukunft verblasst — bildet zusammen eine durch-
   gehende horizontale Linie über die ganze Wochenbreite. */
.cal-now-line {
    position: absolute;
    left: 0; right: 0;
    height: 2px;
    background: var(--accent);
    opacity: 0.25;
    z-index: 4;
    pointer-events: none;
}
.cal-now-line.is-today {
    opacity: 1;
}
.cal-now-line.is-today::before {
    content: '';
    position: absolute;
    left: -4px;
    top: -3px;
    width: 8px; height: 8px;
    background: var(--accent);
    border-radius: 50%;
}

/* Drag-to-create-Overlay */
.cal-drag-overlay {
    position: absolute;
    left: 2px; right: 2px;
    background: rgba(254, 89, 0, 0.22);
    border: 2px dashed var(--accent);
    border-radius: 3px;
    z-index: 5;
    pointer-events: none;
}

/* =====================================================================
   KALENDER — Monatsansicht mit KW-Spalte links.
===================================================================== */
.cal-month { display: flex; flex-direction: column; }
.cal-month-head {
    display: grid;
    grid-template-columns: 36px repeat(7, 1fr);
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.cal-month-kwhead {
    padding: 8px 6px;
    font-size: 10px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: center;
}
.cal-month-wd {
    padding: 8px 10px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
}
.cal-month-row {
    display: grid;
    grid-template-columns: 36px repeat(7, 1fr);
    border-bottom: 1px solid var(--border);
}
.cal-month-row:last-child { border-bottom: 0; }
.cal-month-kw {
    background: var(--surface-2);
    padding: 6px 6px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-align: center;
    font-variant-numeric: tabular-nums;
    border-right: 1px solid var(--border);
}

/* =====================================================================
   KALENDER — Jahresansicht (12 Mini-Monate als 3×4-Grid).
===================================================================== */
.cal-year-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}
@media (max-width: 980px) {
    .cal-year-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .cal-year-grid { grid-template-columns: 1fr; }
}
.cal-year-month {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
}
.cal-year-month-title {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    margin-bottom: 6px;
}
.cal-year-month-title:hover { color: var(--accent); }
.cal-year-weekdays {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
    font-size: 9px;
    color: var(--text-muted);
    text-align: center;
    margin-bottom: 4px;
}
.cal-year-days {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 1px;
}
.cal-year-day {
    aspect-ratio: 1;
    display: flex; align-items: center; justify-content: center;
    font-size: 10px;
    color: var(--text);
    text-decoration: none;
    border-radius: 3px;
}
.cal-year-day.is-other { color: var(--text-muted); opacity: 0.4; }
.cal-year-day.is-today { background: var(--accent); color: #fff; font-weight: 600; }
.cal-year-day.is-low  { background: rgba(46, 134, 222, 0.18); color: #1c5aa3; }
.cal-year-day.is-mid  { background: rgba(46, 134, 222, 0.40); color: #fff; }
.cal-year-day.is-high { background: rgba(46, 134, 222, 0.75); color: #fff; }
.cal-year-day:hover { outline: 2px solid var(--accent); }

/* =====================================================================
   KALENDER — Monats-Grid mit Event-Chips.
   Vanilla CSS-Grid, 7 Spalten × variable Zeilen. Keine externe Library.
===================================================================== */
.cal-day {
    background: var(--surface);
    padding: 6px;
    min-height: 110px;
    display: flex;
    flex-direction: column;
    gap: 3px;
    overflow: hidden;
    position: relative;
}
.cal-day.is-other-month { background: #fafaf8; }
.cal-day.is-other-month .cal-day-number { color: var(--text-muted); opacity: 0.5; }
.cal-day.is-weekend { background: #fbfaf6; }
.cal-day.is-weekend.is-other-month { background: #f7f6f2; }
.cal-day.is-today {
    background: rgba(254, 89, 0, 0.06);
    box-shadow: inset 0 0 0 2px var(--accent);
}
.cal-day.is-today .cal-day-number {
    color: var(--accent);
    font-weight: 700;
}
.cal-day-number {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    line-height: 1.2;
    margin-bottom: 2px;
}

/* Event-Chips: kompakt, klickbar, farblich nach showAs-Status. */
.cal-event {
    display: flex;
    align-items: baseline;
    gap: 4px;
    border: 0;
    background: rgba(46, 134, 222, 0.12);
    color: #1c5aa3;
    border-left: 3px solid #2e86de;
    border-radius: 3px;
    padding: 2px 6px;
    font-size: 11.5px;
    line-height: 1.3;
    cursor: pointer;
    text-align: left;
    width: 100%;
    overflow: hidden;
}
.cal-event:hover { background: rgba(46, 134, 222, 0.22); }
.cal-event-time {
    font-weight: 600;
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}
.cal-event-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}

/* Farb-Varianten nach showAs-Status */
.cal-ev-busy       { background: rgba(46, 134, 222, 0.12); color: #1c5aa3; border-left-color: #2e86de; }
.cal-ev-busy:hover { background: rgba(46, 134, 222, 0.22); }
.cal-ev-free       { background: rgba(120, 120, 120, 0.10); color: #555;    border-left-color: #888; }
.cal-ev-free:hover { background: rgba(120, 120, 120, 0.20); }
.cal-ev-tentative  { background: rgba(245, 188, 41, 0.14); color: #8a6d10; border-left-color: #f5bc29; }
.cal-ev-tentative:hover { background: rgba(245, 188, 41, 0.24); }
.cal-ev-oof        { background: rgba(170, 90, 200, 0.14); color: #6c3892; border-left-color: #aa5ac8; }
.cal-ev-oof:hover  { background: rgba(170, 90, 200, 0.24); }
.cal-ev-elsewhere  { background: rgba(54, 160, 122, 0.14); color: #1f6e54; border-left-color: #36a07a; }
.cal-ev-elsewhere:hover { background: rgba(54, 160, 122, 0.24); }
/* Ticket-Termine: oranger Akzent (Wyld-Brand) statt blau — sofort
   erkennbar dass das ein Wyld-MGMT-Termin ist, nicht ein zufälliger
   externer Outlook-Eintrag. */
.cal-ev-ticket     { background: rgba(254, 89, 0, 0.14); color: #a3360c; border-left-color: var(--accent); }
.cal-ev-ticket:hover { background: rgba(254, 89, 0, 0.24); }
.cal-tw-event.cal-ev-ticket { background: rgba(254, 89, 0, 0.14); color: #a3360c; border-left-color: var(--accent); }
.cal-tw-event.cal-ev-ticket:hover { background: rgba(254, 89, 0, 0.24); }

.cal-more {
    font-size: 10.5px;
    color: var(--text-muted);
    padding: 1px 6px;
    font-style: italic;
}

/* Mobile: kleinere Zellen, Events nur als Punkte */
@media (max-width: 720px) {
    .cal-grid { grid-auto-rows: minmax(70px, auto); }
    .cal-event { font-size: 10px; padding: 1px 4px; }
}

/* =====================================================================
   MODUL-EINSTELLUNGEN — Tiles auf der Admin-Übersichtsseite.
   App-Launcher-Stil: Icon links in einem getönten Accent-Chip,
   Label rechts. Wirkt deutlich präsenter als die alte schmale
   Border-only-Variante.
===================================================================== */
.module-settings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
}
.module-settings-tile {
    display: flex; align-items: center; gap: 14px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
    font-size: 14px; font-weight: 500;
    line-height: 1.3;
    box-shadow: 0 1px 2px rgba(34, 52, 57, 0.04);
    transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s, background 0.15s;
    position: relative;
    overflow: hidden;
}

/* Icon-Chip: weiches Accent-Quadrat links neben dem Label. */
.module-settings-tile .icon {
    width: 36px; height: 36px;
    flex-shrink: 0;
    padding: 8px;
    background: rgba(254, 89, 0, 0.10);
    color: var(--accent);
    border-radius: 8px;
    box-sizing: border-box;
    transition: background 0.15s, color 0.15s, transform 0.15s;
}

.module-settings-tile:hover {
    border-color: var(--accent);
    background: var(--surface);
    color: var(--text);
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(34, 52, 57, 0.10);
}
.module-settings-tile:hover .icon {
    background: var(--accent);
    color: #ffffff;
    transform: scale(1.05);
}
.module-settings-tile:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Modul-Einstellungen-Seite: konsistente Card-Sektionen.
   Header sitzt NICHT mehr als eigene Bar unter der Topbar — Icon, Titel und
   Beschreibung kommen direkt in die System-Topbar via page_title /
   page_subtitle / page_actions. Hier nur noch die Stat-Zeile + Placeholder. */
.modsetting-info-row {
    display: flex; flex-wrap: wrap; gap: 16px;
    padding: 10px 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 14px;
    font-size: 12px;
}
.modsetting-info-row > div { color: var(--text-muted); }
.modsetting-info-row > div strong { color: var(--text); font-weight: 600; }
.modsetting-placeholder {
    padding: 14px 18px;
    background: var(--surface-2);
    border: 1px dashed var(--border);
    border-radius: var(--radius);
    color: var(--text-muted);
    font-size: 12.5px;
    line-height: 1.55;
}

/* =====================================================================
   AUFGABEN-MODUL — Liste + Kanban + Subtask-Checkliste.
   Sidebar-Eintrag direkt unter Kalender. Konventionen: gleiche Pill-
   und Stat-Card-Optik wie der Rest des Systems, eigene Klassen nur
   für das wirklich Modul-spezifische (Kanban-Karten, Subtask-Zeilen).
===================================================================== */

/* Filter-UI nutzt den systemweiten <x-list-filter>-Popover (siehe
   resources/views/components/list-filter.blade.php) — kein eigenes
   Filter-Row-Layout für das Aufgaben-Modul nötig. */

/* --- Listen-Switcher als Topbar-Dropdown (native <details>-Popover) --- */
.task-lists-dropdown {
    position: relative;
}
.task-lists-dropdown > summary {
    list-style: none;             /* native marker entfernen */
    cursor: pointer;
    user-select: none;
    display: inline-flex; align-items: center; gap: 6px;
    max-width: 240px;
}
.task-lists-dropdown > summary::-webkit-details-marker { display: none; }
.task-lists-dropdown > summary::marker { content: ''; }
.task-lists-dropdown > summary > span:not(.icon-sm) {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    max-width: 180px;
}
.task-lists-dropdown[open] > summary {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: var(--accent);
}
.task-lists-popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    min-width: 280px;
    max-width: 340px;
    max-height: 70vh;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 6px;
    display: flex; flex-direction: column; gap: 1px;
    z-index: 50;
}
.task-lists-section {
    padding: 10px 10px 4px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-subtle);
    font-weight: 600;
}
.task-lists-divider {
    height: 1px;
    background: var(--border);
    margin: 6px 4px;
}
.task-list-new {
    border: 0; background: transparent;
    text-align: left;
    cursor: pointer;
    width: 100%;
    color: var(--accent);
    font: inherit;
}

.task-list-item-wrap {
    display: flex; align-items: stretch; gap: 2px;
    position: relative;
}
.task-list-item {
    flex: 1;
    display: flex; align-items: center; gap: 8px;
    padding: 7px 10px;
    border-radius: 6px;
    color: var(--text);
    text-decoration: none;
    font-size: 13px;
    transition: background 0.12s, color 0.12s;
}
.task-list-item:hover {
    background: var(--surface-2);
    color: var(--accent);
}
.task-list-item.is-active {
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
}
.task-list-item .icon {
    width: 16px; height: 16px;
    flex: 0 0 auto;
    color: var(--text-muted);
}
.task-list-item.is-active .icon { color: var(--accent); }
.task-list-item-name {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.task-list-item-count {
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 11px;
    padding: 1px 7px;
    border-radius: 10px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.task-list-item.is-active .task-list-item-count {
    background: var(--accent);
    color: #fff;
}
.task-list-vis-mini {
    color: var(--text-muted);
    font-size: 10px;
    display: inline-flex; align-items: center;
}
.task-list-vis-mini .icon { width: 12px; height: 12px; }
.task-list-edit-btn {
    background: transparent; border: 0;
    padding: 4px 6px;
    color: var(--text-subtle);
    cursor: pointer;
    border-radius: 4px;
    opacity: 0;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
}
.task-list-edit-btn .icon { width: 14px; height: 14px; }
.task-list-item-wrap:hover .task-list-edit-btn { opacity: 1; }
.task-list-edit-btn:hover {
    color: var(--accent);
    background: var(--surface-2);
}

/* Hauptbereich rechts (Stats + Liste/Kanban) */
.task-main {
    display: flex; flex-direction: column;
    gap: 14px;
}

/* Mitglieder-Auswahl im Listen-Modal */
.task-list-members-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 4px;
    max-height: 200px;
    overflow-y: auto;
    padding: 6px;
    background: var(--surface-2);
    border-radius: 6px;
}
.task-list-member-check {
    display: flex; align-items: center; gap: 6px;
    padding: 4px 6px;
    border-radius: 4px;
    font-size: 13px;
    cursor: pointer;
    transition: background 0.12s;
}
.task-list-member-check:hover { background: var(--surface); }
.task-list-member-check input { margin: 0; }

/* --- Listen-Ansicht: Quick-Action-Button + Prio-Badges --- */
.task-quick-action {
    background: transparent; border: 0; padding: 4px;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: 4px;
    transition: background 0.12s, color 0.12s;
}
.task-quick-action:hover { background: var(--accent-soft); color: var(--accent); }
.task-quick-action.is-done { color: var(--green); }
.task-quick-action .icon { width: 18px; height: 18px; }

.task-row-overdue td:first-child { box-shadow: inset 3px 0 0 #c0392b; }
.task-due-overdue { color: #c0392b; font-weight: 600; }

.task-subtask-badge {
    display: inline-flex; align-items: center; gap: 3px;
    margin-left: 8px;
    font-size: 11px; color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.task-subtask-badge .icon { width: 12px; height: 12px; }

.task-desc-snippet {
    font-size: 11px; color: var(--text-muted);
    margin-top: 2px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    max-width: 380px;
}

/* Prioritäts-Badges (klein, neutral) */
.task-prio {
    display: inline-block;
    padding: 1px 7px;
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: 3px;
    background: var(--surface-2);
    color: var(--text-muted);
}
.task-prio-high   { background: rgba(192, 57, 43, 0.12); color: #c0392b; }
.task-prio-normal { background: var(--surface-2); color: var(--text-muted); }
.task-prio-low    { background: rgba(40, 116, 166, 0.10); color: #2874a6; }

.task-link {
    color: var(--accent); text-decoration: none;
    display: inline-flex; align-items: center; gap: 4px;
}
.task-link:hover { text-decoration: underline; }
.task-link .icon { width: 12px; height: 12px; }

/* --- Subtask-Editor im Modal --- */
.task-items-list {
    display: flex; flex-direction: column; gap: 4px;
    padding: 6px;
    background: var(--surface-2);
    border-radius: 6px;
}
.task-item-row {
    display: flex; align-items: center; gap: 8px;
    background: var(--surface);
    padding: 4px 6px;
    border-radius: 4px;
}
.task-item-check { display: inline-flex; align-items: center; }
.task-item-input {
    flex: 1;
    border: 0; background: transparent;
    color: var(--text);
    padding: 4px 6px;
    font-size: 13px;
    outline: none;
}

/* --- Kanban-Board --- */
.task-kanban {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    align-items: start;
}
@media (max-width: 900px) {
    .task-kanban { grid-template-columns: 1fr; }
    /* Gestapelte Spalten brauchen keine 200px-Mindesthoehe (sonst viel
       Leerraum auf Mobil). */
    .task-kanban-col { min-height: 0; }
}
.task-kanban-col {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 10px;
    min-height: 200px;
    display: flex; flex-direction: column;
    gap: 8px;
    transition: background 0.12s;
}
.task-kanban-col.is-drop-target {
    background: var(--accent-soft);
    outline: 2px dashed var(--accent);
    outline-offset: -3px;
}
.task-kanban-col-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 2px 4px;
}
.task-kanban-count {
    font-size: 11px; color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}
.task-kanban-list {
    display: flex; flex-direction: column; gap: 8px;
    min-height: 60px;
}
.task-kanban-card {
    background: var(--surface-2);
    border-radius: 8px;
    padding: 10px 12px;
    cursor: grab;
    border-left: 3px solid transparent;
    transition: box-shadow 0.12s, transform 0.12s;
}
.task-kanban-card:hover {
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
}
.task-kanban-card.is-dragging { opacity: 0.5; cursor: grabbing; }
.task-kanban-card.task-prio-high-border   { border-left-color: #c0392b; }
.task-kanban-card.task-prio-normal-border { border-left-color: var(--border); }
.task-kanban-card.task-prio-low-border    { border-left-color: #2874a6; }
.task-kanban-card-title {
    font-weight: 600; font-size: 13.5px;
    color: var(--text);
    margin-bottom: 4px;
}
.task-kanban-card-desc {
    font-size: 11.5px; color: var(--text-muted);
    margin-bottom: 6px;
    line-height: 1.4;
}
.task-kanban-card-meta {
    display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
    font-size: 11px; color: var(--text-muted);
}
.task-kanban-card-meta .icon { width: 12px; height: 12px; }
.task-kanban-card-foot {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px dashed var(--border);
    display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
    font-size: 11px; color: var(--text-muted);
}
.task-kanban-card-foot .icon { width: 12px; height: 12px; }
.task-kanban-empty {
    padding: 20px 8px;
    text-align: center;
    font-size: 12px; color: var(--text-muted);
    font-style: italic;
}

/* =====================================================================
   ABRECHNUNG — Detail-Ansicht (billing/show)
   Aufgeräumte Mitarbeiter-Gruppen mit kompakter Zeiten-Tabelle.
   Aktionen (Bearbeiten/Zurückgeben) liegen im Modal, nicht inline.
===================================================================== */
.billing-user-group {
    margin-bottom: 18px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.billing-user-group:last-child { margin-bottom: 0; }
.billing-user-head {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 12px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.billing-user-avatar {
    width: 28px; height: 28px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: 11px; font-weight: 600;
    flex-shrink: 0; overflow: hidden;
}
.billing-user-avatar img { width: 100%; height: 100%; object-fit: cover; }
/* Nur der Name darf schrumpfen/kürzen — alle übrigen Kopf-Elemente
   behalten ihre Größe, damit beim Bestätigen nichts springt oder umbricht. */
.billing-user-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.billing-user-head > .pill { flex-shrink: 0; white-space: nowrap; }
.billing-user-head > form { flex-shrink: 0; }
.billing-user-meta { flex-shrink: 0; white-space: nowrap; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.billing-user-amount {
    flex-shrink: 0;
    font-weight: 700; font-size: 14px;
    min-width: 90px; text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}
/* table-layout: fixed → Spaltenbreiten richten sich AUSSCHLIESSLICH nach
   den <th>-Breiten, nicht nach dem Zellinhalt. Sonst verschob sich die
   Aktions-Spalte um ein paar Pixel, sobald eine Zeile von zwei Buttons
   (Freigeben + Bearbeiten) auf einen (Freigabe entziehen) wechselte. */
.billing-table { font-size: 13px; margin: 0; table-layout: fixed; width: 100%; }
.billing-table th { font-weight: 500; }
/* Standardmäßig bricht NICHTS um — Datum, Dauer, Beträge, Status-Pills
   bleiben einzeilig. Sonst zerbrach z.B. „Freigegeben" in der schmalen
   Status-Spalte mitten im Wort. */
.billing-table td { white-space: nowrap; }
/* Nur die Beschreibungs-/Artikel-Spalte darf umbrechen, damit lange Texte
   die feste Spaltenbreite nicht sprengen. */
.billing-table .billing-cell-wrap { white-space: normal; overflow-wrap: anywhere; }
.billing-row-muted { opacity: 0.55; }
.billing-reject-note {
    display: flex; align-items: flex-start; gap: 6px;
    margin-top: 5px;
    padding: 6px 9px;
    background: rgba(192, 57, 43, 0.07);
    border: 1px solid rgba(192, 57, 43, 0.2);
    border-radius: 6px;
    font-size: 11.5px;
    line-height: 1.4;
    color: var(--text);
}
.billing-reject-note .icon { color: #c0392b; flex-shrink: 0; margin-top: 1px; }
.billing-row-actions {
    display: flex; gap: 4px; justify-content: flex-end;
}

/* =====================================================================
   PAGE-BANNER-STACK (@push('banners')) — gleichmäßiger Abstand zwischen
   mehreren Bannern und ein Abstand zur Topbar darunter, aber NUR wenn
   tatsächlich ein Banner gepusht wurde (sonst klebte z.B. die Billing-
   „Wartet auf Freigabe"-Meldung direkt an der Topbar).
===================================================================== */
.page-banners {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.page-banners:has(> *) {
    margin-bottom: 14px;
}

/* ============================================================
   §Mobile-Nav (Phase 3) — iPhone Bottom-Tab-Leiste + Off-Canvas-Sidebar.
   Greift NUR <= 640px (mobile). Tablet (640-1024) und Desktop (>1024)
   bleiben unveraendert. Siehe docs/MOBILE-PWA-PLAN.md + UI-CONVENTIONS §19.
   ============================================================ */
.mobile-tabbar,
.mobile-nav-backdrop { display: none; }

@media (max-width: 640px) {
    /* Bottom-Tab-Leiste */
    .mobile-tabbar {
        display: flex;
        position: fixed; left: 0; right: 0; bottom: 0;
        z-index: var(--z-fab, 9990);
        background: var(--surface, #fff);
        border-top: 1px solid var(--border, #e5e7eb);
        padding-bottom: env(safe-area-inset-bottom);
    }
    .mtab {
        flex: 1 1 0; min-width: 0;
        display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
        padding: 7px 2px 5px; min-height: 50px;
        background: none; border: 0; font: inherit; cursor: pointer;
        color: var(--text-muted, #6b7280); text-decoration: none;
    }
    .mtab .icon, .mtab-icon { width: 22px; height: 22px; }
    .mtab-label {
        font-size: 10px; line-height: 1.1;
        max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .mtab.is-active { color: var(--accent, #fe5900); }

    /* Sidebar als Off-Canvas-Drawer (statt Grid-Spalte) */
    .layout,
    body.sidebar-collapsed .layout { grid-template-columns: 1fr !important; }
    .sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        width: min(84vw, 300px);
        transform: translateX(-100%);
        transition: transform .25s ease;
        z-index: var(--z-modal, 10500);
        overflow-y: auto;
        /* Drawer randet bündig am Bildschirm — scharfe 90°-Ecken (auch links),
           keine abgerundeten Karten-Ecken wie auf dem Desktop. */
        border-radius: 0;
    }
    body.mobile-nav-open .sidebar { transform: none; }
    .mobile-nav-backdrop {
        display: block; position: fixed; inset: 0;
        background: rgba(0, 0, 0, .45);
        z-index: calc(var(--z-modal, 10500) - 1);
        opacity: 0; visibility: hidden; transition: opacity .25s;
    }
    body.mobile-nav-open .mobile-nav-backdrop { opacity: 1; visibility: visible; }

    /* Drawer zeigt IMMER die volle Sidebar, auch wenn sidebar-collapsed
       (Desktop-Cookie) gesetzt ist. */
    body.sidebar-collapsed .nav-label,
    body.sidebar-collapsed .sidebar-quick-label { display: inline !important; }
    body.sidebar-collapsed .nav-section,
    body.sidebar-collapsed .user-meta { display: block !important; }
    body.sidebar-collapsed .badge { display: inline-flex !important; }
    body.sidebar-collapsed .nav-link { justify-content: flex-start !important; padding: 8px 12px !important; }
    body.sidebar-collapsed .sidebar-toggle { display: none !important; }

    /* ===== Sidebar-Drawer-Politur (Mobil) ===== */
    /* (1) Wortmarke (Schriftzug) statt Badge-Marke. */
    body.sidebar-collapsed .brand-logo-full { display: block !important; }
    body.sidebar-collapsed .brand-logo-mark { display: none !important; }
    /* (3) Volle Suchleiste (Lupe + „Suche"-Placeholder) statt Icon-only-Button. */
    body.sidebar-collapsed .sidebar-search input[type="search"],
    body.sidebar-collapsed .sidebar-search .sidebar-search-icon { display: block !important; }
    body.sidebar-collapsed .sidebar-search .sidebar-search-results:not([hidden]) { display: block !important; }
    body.sidebar-collapsed .sidebar-search-btn { display: none !important; }
    /* (2) Keine Trennlinien über/unter der Suche; engere Abstände. */
    .sidebar-brand { border-bottom: 0; margin-bottom: 4px; }
    body.sidebar-collapsed .sidebar-search { border-bottom: 0; margin-bottom: 4px; padding: 4px 12px 10px; }
    /* (4) User-Chip (Avatar/Name/Rolle) linksbündig. */
    body.sidebar-collapsed .user-chip { justify-content: flex-start; }
    /* (5) Logout + Design nebeneinander (wie Desktop) + Safe-Area unten, damit
       die Buttons nicht an die abgerundete Bildschirmecke / den Home-Indikator
       stoßen. */
    body.sidebar-collapsed .sidebar-actions { flex-direction: row; gap: 6px; }
    body.sidebar-collapsed .sidebar-action { padding: 8px; }
    .sidebar-foot,
    body.sidebar-collapsed .sidebar-foot { padding: 12px 12px calc(14px + env(safe-area-inset-bottom)); }

    /* Platz unten fuer Tab-Leiste (~66px) UND die schwebenden FABs (56px,
       Oberkante ~130px) — sonst bleibt das unterste Element hinter den Buttons. */
    .main-scroll { padding-bottom: calc(150px + env(safe-area-inset-bottom)) !important; }

    /* Schwebende FABs ueber die Tab-Leiste heben (sonst Ueberlappung). */
    .notification-fab,
    .clock-fab,
    .notes-fab { bottom: calc(74px + env(safe-area-inset-bottom)) !important; }
    .clock-popover { bottom: calc(140px + env(safe-area-inset-bottom)) !important; }

    /* Super-Admin-Toolbar (bottom-center) auf Mobil ausblenden — die
       Power-Tools (Zeitmaschine, Doppelgaenger, Party ...) sind Desktop-
       Werkzeuge und kollidieren sonst mit Tab-Leiste + FABs. */
    .admin-toolbar { display: none !important; }

    /* Drawer: Quick-Buttons (Notiz/Ticket/Zeit) nebeneinander statt
       gestapelt — der collapsed-Mode erzwingt sonst flex-direction: column. */
    body.sidebar-collapsed .sidebar-quick { flex-direction: row !important; padding: 8px 14px 12px !important; }
    body.sidebar-collapsed .sidebar-quick-btn { padding: 8px 4px !important; }

    /* Stat-Kacheln auf Mobil NICHT sticky (sonst blockieren sie das Scrollen
       zur Tabelle darunter) + kompakt: 2 Spalten, Hoehe nach Inhalt. */
    .content > .cards-grid:first-child:has(.stat-card) { position: static !important; }
    .cards-grid:has(.stat-card) { grid-template-columns: repeat(2, 1fr) !important; }
    .cards-grid:has(.stat-card) .stat-card { min-height: 0 !important; height: auto !important; }

    /* Mehrspaltige Karten-Grids OHNE Stat-Kacheln (z.B. Kunden-Detailseite:
       Standorte/Ansprechpartner/Bank in 3 Spalten via inline
       grid-template-columns + grid-column-Platzierung) auf dem iPhone
       einspaltig stapeln — sonst quetschen sich die Spalten ueber den Rand.
       Inline-Styles erzwingen !important; Platzierungen zuruecksetzen.
       Stat-Kachel-Grids bleiben 2-spaltig (Regel darueber). */
    .cards-grid:not(:has(.stat-card)) { grid-template-columns: 1fr !important; }
    .cards-grid > * { grid-column: auto !important; grid-row: auto !important; }

    /* Formular-Grids (auch mit inline repeat(3/4,1fr) in Modals) einspaltig. */
    .form-grid, .form-grid-3 { grid-template-columns: 1fr !important; }

    /* Karten-Tabellen: kein erzwungenes nowrap (inline) — sonst laufen die
       Zeilen aus der Karte heraus. */
    .table:has(> thead) > tbody > tr > td { white-space: normal !important; }

    .table-wrap .table thead th { top: 0 !important; }

    /* Topbar auf Mobil konsistent ab 640px umbrechen (statt erst 560) und die
       Aktionen kompakt + links-buendig halten — sonst stapeln sich die Buttons
       unuebersichtlich. Ziel: moeglichst eine ordentliche Reihe. */
    .topbar { flex-wrap: wrap; gap: 8px; }
    .topbar-titles-wrap { flex: 1 1 100%; min-width: 0; }
    .topbar-actions {
        flex: 1 1 100%;
        flex-wrap: wrap;
        justify-content: flex-start;
        align-items: center;
        gap: 6px;
        min-height: 0;
    }
    .topbar-actions .btn,
    .topbar-actions .list-filter > summary { white-space: nowrap; }
    .topbar-actions .btn { padding: 6px 10px; }

    /* Card-Header (Titel + Aktions-Buttons) auf Mobil umbrechen lassen, damit
       mehrere Buttons (z.B. „Gerät einbauen" + „+") den Titel nicht quetschen. */
    .card-header-row { flex-wrap: wrap; row-gap: 6px; }

    /* Daten-Tabellen MIT <thead> auf Mobil als Karten-Stapel statt breiter
       Tabelle — egal ob in .table-wrap oder roh in einer Karte (z.B. "Tage der
       Woche"). data-label wird per JS aus dem <th> befuellt (partials/
       mobile-tables). Tabellen OHNE <thead> bleiben unveraendert.
       Siehe docs/MOBILE-PWA-PLAN.md (Phase 4). */
    .table-wrap { overflow-x: visible; }
    .table:has(> thead),
    .table:has(> thead) > tbody { display: block; }
    .table:has(> thead) > thead { display: none; }
    .table:has(> thead) > tbody > tr {
        display: block;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 6px 12px;
        margin-bottom: 10px;
    }
    .table:has(> thead) > tbody > tr > td {
        display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
        padding: 5px 0; border: 0; text-align: right; white-space: normal;
    }
    .table:has(> thead) > tbody > tr > td::before {
        content: attr(data-label);
        flex: 0 0 42%; text-align: left;
        font-size: 12px; font-weight: 600; color: var(--text-muted);
    }
    /* Zellen ohne Label (z.B. Auswahl-Checkbox) bekommen keinen Label-Gutter. */
    .table:has(> thead) > tbody > tr > td:not([data-label])::before { display: none; }
    /* Primaer-/Titelspalte als Karten-Kopf (volle Breite, kein Label). */
    .table:has(> thead) > tbody > tr > td.cell-title {
        justify-content: flex-start; text-align: left;
        font-weight: 600; font-size: 15px;
        padding-bottom: 8px; margin-bottom: 4px; border-bottom: 1px solid var(--border);
    }
    .table:has(> thead) > tbody > tr > td.cell-title::before { display: none; }

    /* Modals (admin-modal-Pattern, §17) auf Mobil als Bottom-Sheet: volle
       Breite, unten angedockt, oben abgerundet. KEINE transform-Animation am
       offenen Sheet — sonst werden die position:fixed-Picker-Popovers (§16)
       eingefangen. Siehe docs/MOBILE-PWA-PLAN.md (Phase 5). */
    .admin-modal-backdrop { align-items: flex-end; }
    .admin-modal,
    .admin-modal-wide {
        max-width: 100%;
        width: 100%;
        max-height: 90vh;
        border-radius: 16px 16px 0 0;
        /* Sticky Kopf/Fuß: nur der Body scrollt, Titel + Buttons bleiben
           sichtbar (statt dass das ganze Sheet wegscrollt). Kein transform →
           position:fixed-Picker (§16) bleiben frei. */
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }
    .admin-modal-head { flex: 0 0 auto; }
    .admin-modal-body { flex: 1 1 auto; overflow-y: auto; }
    .admin-modal-foot {
        flex: 0 0 auto;
        padding-bottom: calc(12px + env(safe-area-inset-bottom));
    }

    /* iOS zoomt beim Fokus auf Inputs < 16px hinein — auf Mobil global 16px. */
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea { font-size: 16px; }
}

/* ============================================================
   iPad / Touch-Tablet: GLEICHE iOS-Shell wie das iPhone (Bottom-Tab-Leiste,
   Sidebar als Off-Canvas-Drawer, Safe-Area, FAB-Position) — ABER der Inhalt
   nutzt die Flaeche: die Schmal-Phone-Reflows (Tabelle->Karte, Grid-Zwangs-
   spalten, Vollbild-Bottom-Sheet) greifen hier bewusst NICHT, daher bleiben
   Tabellen Tabellen, Stat-/Karten-Grids mehrspaltig und Modale zentriert.
   Die iOS-Topbar/Edge-to-Edge/Statusbar-Regeln teilen sich die Media-Query
   mit <=640px (Komma-Liste oben/unten). Aktiv NUR auf echten Touch-Tablets:
   (pointer: coarse) + (hover: none) + 641-1366px → Desktop und Touch-Laptops
   (haben hover) sowie iPhone (<=640px) bleiben unberuehrt.
   Siehe docs/UI-CONVENTIONS.md §19.1 + docs/MOBILE-PWA-PLAN.md.
   ============================================================ */
@media (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    /* Bottom-Tab-Leiste (wie iPhone) */
    .mobile-tabbar {
        display: flex;
        position: fixed; left: 0; right: 0; bottom: 0;
        z-index: var(--z-fab, 9990);
        background: var(--surface, #fff);
        border-top: 1px solid var(--border, #e5e7eb);
        padding-bottom: env(safe-area-inset-bottom);
    }
    .mtab {
        flex: 1 1 0; min-width: 0;
        display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
        padding: 7px 2px 5px; min-height: 50px;
        background: none; border: 0; font: inherit; cursor: pointer;
        color: var(--text-muted, #6b7280); text-decoration: none;
    }
    .mtab .icon, .mtab-icon { width: 22px; height: 22px; }
    .mtab-label {
        font-size: 10px; line-height: 1.1;
        max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .mtab.is-active { color: var(--accent, #fe5900); }

    /* Sidebar als Off-Canvas-Drawer statt Grid-Spalte ("Mehr"-Tab oeffnet sie). */
    .layout,
    body.sidebar-collapsed .layout { grid-template-columns: 1fr !important; }
    .sidebar {
        position: fixed; top: 0; left: 0; bottom: 0;
        width: min(70vw, 320px);
        transform: translateX(-100%);
        transition: transform .25s ease;
        z-index: var(--z-modal, 10500);
        overflow-y: auto;
        border-radius: 0;
    }
    body.mobile-nav-open .sidebar { transform: none; }
    .mobile-nav-backdrop {
        display: block; position: fixed; inset: 0;
        background: rgba(0, 0, 0, .45);
        z-index: calc(var(--z-modal, 10500) - 1);
        opacity: 0; visibility: hidden; transition: opacity .25s;
    }
    body.mobile-nav-open .mobile-nav-backdrop { opacity: 1; visibility: visible; }

    /* Drawer zeigt IMMER die volle Sidebar (auch bei sidebar-collapsed); der
       Desktop-Einklapp-Pfeil entfaellt im Drawer. */
    .sidebar-toggle { display: none !important; }
    .sidebar-brand { border-bottom: 0; margin-bottom: 4px; }
    body.sidebar-collapsed .nav-label,
    body.sidebar-collapsed .sidebar-quick-label { display: inline !important; }
    body.sidebar-collapsed .nav-section,
    body.sidebar-collapsed .user-meta { display: block !important; }
    body.sidebar-collapsed .badge { display: inline-flex !important; }
    body.sidebar-collapsed .nav-link { justify-content: flex-start !important; padding: 8px 12px !important; }
    body.sidebar-collapsed .brand-logo-full { display: block !important; }
    body.sidebar-collapsed .brand-logo-mark { display: none !important; }
    body.sidebar-collapsed .sidebar-search input[type="search"],
    body.sidebar-collapsed .sidebar-search .sidebar-search-icon { display: block !important; }
    body.sidebar-collapsed .sidebar-search .sidebar-search-results:not([hidden]) { display: block !important; }
    body.sidebar-collapsed .sidebar-search-btn { display: none !important; }
    body.sidebar-collapsed .sidebar-search { border-bottom: 0; margin-bottom: 4px; padding: 4px 12px 10px; }
    body.sidebar-collapsed .user-chip { justify-content: flex-start; }
    body.sidebar-collapsed .sidebar-actions { flex-direction: row; gap: 6px; }
    body.sidebar-collapsed .sidebar-action { padding: 8px; }
    .sidebar-foot,
    body.sidebar-collapsed .sidebar-foot { padding: 12px 12px calc(14px + env(safe-area-inset-bottom)); }
    body.sidebar-collapsed .sidebar-quick { flex-direction: row !important; padding: 8px 14px 12px !important; }
    body.sidebar-collapsed .sidebar-quick-btn { padding: 8px 4px !important; }

    /* Schwebende FABs ueber die Tab-Leiste heben; Super-Admin-Toolbar aus
       (kollidiert mit Tab-Leiste/FABs). main-scroll-Polster kommt aus dem
       edge-to-edge-Block (body.m-native, ebenfalls auf iPad aktiv). */
    .notification-fab,
    .clock-fab,
    .notes-fab { bottom: calc(74px + env(safe-area-inset-bottom)) !important; }
    .clock-popover { bottom: calc(140px + env(safe-area-inset-bottom)) !important; }
    .admin-toolbar { display: none !important; }

    /* iOS zoomt beim Fokus auf Inputs < 16px hinein. */
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea { font-size: 16px; }
}

/* ============================================================
   Native Mobile-Chrome (scoped via body.m-native, global aktiv).
   Macht die Topbar zur schlanken iOS-Kopfleiste mit Icon-only-Aktionen —
   auf iPhone (< 640px) UND iPad/Touch-Tablet (Komma-Media, §19.1).
   Siehe docs/UI-CONVENTIONS.md §19, docs/MOBILE-PWA-PLAN.md.
   ============================================================ */
@media (max-width: 640px), (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    body.m-native .topbar {
        /* wrap (nicht nowrap): bei zu breiten Actions (z.B. Kalender-Toolbar)
           rutscht die Aktionsgruppe in eine eigene Zeile UNTER den Titel, statt
           den Titel zusammenzuquetschen. Index-Seiten mit 1-2 Icon-Buttons
           passen weiter in eine Zeile. */
        flex-wrap: wrap;
        align-items: center;
        gap: 8px;
        padding: 8px 12px;
    }
    body.m-native .topbar-titles-wrap { flex: 1 1 auto; min-width: 0; }
    body.m-native .page-title { font-size: 18px; }
    body.m-native .page-subtitle { display: none; }
    body.m-native .topbar-actions { flex: 0 0 auto; flex-wrap: wrap; gap: 4px; }
    /* §19 — einheitliche Topbar-Button-Höhe: ALLE Aktionen (auch text-haltige)
       teilen dieselbe Mindesthöhe, sonst rendern Text-Buttons niedriger als die
       fix dimensionierten Icon-Buttons. */
    body.m-native .topbar-actions .btn,
    body.m-native .topbar-actions .list-filter > summary { min-height: 36px; }
    /* Aktionen icon-only — aber nur Buttons MIT Icon; sonst wuerden text-only-
       Buttons (z.B. auf Detailseiten) zu leeren Quadraten. Text bleibt sichtbar. */
    body.m-native .topbar-actions .btn:has(.icon),
    body.m-native .topbar-actions .list-filter > summary {
        font-size: 0; gap: 0; padding: 0;
        width: 36px; height: 36px; justify-content: center;
    }
    body.m-native .topbar-actions .btn .icon,
    body.m-native .topbar-actions .list-filter > summary .icon {
        width: 18px; height: 18px; margin: 0;
    }
}

/* ============================================================
   §19.6 — Zu breite Topbar-Switcher auf Mobil durch ein kompaktes Dropdown
   ersetzen: Desktop-Control bekommt .m-hide-mobile (aus < 640px), daneben
   ein <select class="m-topbar-select"> (natives iOS-Dropdown, weiss auf
   Anthrazit). Genutzt von Kalender, Stempeluhr, Lieferanten.
   ============================================================ */
.m-topbar-select,
.m-only-mobile { display: none; }
@media (max-width: 640px), (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    .m-hide-mobile { display: none !important; }
    /* §19.6 — Gegenstück zu .m-hide-mobile: NUR auf Mobil sichtbar (z.B. das
       „Mehr"-Overflow-Dropdown der Zeiten-Topbar). */
    .m-only-mobile { display: inline-block; }
    /* §19 — Ansichts-Umschalter als 36px-Chevron-Icon-Button (konsistent zu den
       übrigen Topbar-Buttons), aber weiterhin ein natives <select> → der
       iOS-Auswahl-Picker bleibt erhalten. appearance:none entfernt den nativen
       Pfeil, color:transparent blendet den gewählten Wert aus, der Chevron kommt
       als Hintergrund-SVG (Dark-Mode-Variante darunter). */
    .m-topbar-select {
        -webkit-appearance: none; appearance: none;
        display: inline-block; width: 36px; min-height: 36px; padding: 0;
        color: transparent;
        background-color: var(--surface);
        border: 1px solid var(--border); border-radius: var(--radius);
        background-repeat: no-repeat; background-position: center; background-size: 18px;
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23374151' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    }
    .m-topbar-select option { color: var(--text); }
    html.is-dark .m-topbar-select {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d6d6d2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    }
    /* Report-Variante des nativen Pickers: Datei-Icon statt Chevron (z.B. der
       Ticket-Bericht-Picker), damit er nicht mit einem View-Toggle verwechselt wird. */
    .m-topbar-select-report {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23374151' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/%3E%3Cpath d='M14 2v4a2 2 0 0 0 2 2h4'/%3E%3Cpath d='M10 9H8'/%3E%3Cpath d='M16 13H8'/%3E%3Cpath d='M16 17H8'/%3E%3C/svg%3E");
    }
    html.is-dark .m-topbar-select-report {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d6d6d2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/%3E%3Cpath d='M14 2v4a2 2 0 0 0 2 2h4'/%3E%3Cpath d='M10 9H8'/%3E%3Cpath d='M16 13H8'/%3E%3Cpath d='M16 17H8'/%3E%3C/svg%3E");
    }
}

/* §19 — Detailseiten-Titel auf Mobil: lange Titel (z.B. Tickets) sprengen die
   schmale Kopfzeile. Die Topbar zeigt dort nur die kurze Nummer; der volle
   Titel steht als Überschrift oben im Inhalt (nur < 640px sichtbar). */
.detail-mobile-title { display: none; }
@media (max-width: 640px), (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    .detail-mobile-title {
        display: block; margin: 0 0 4px;
        font-size: 20px; font-weight: 700; line-height: 1.25;
    }
}

/* Aktiver Eintrag im Overflow-Dropdown (z.B. aktuelle Zeiten-Ansicht). */
.dropdown-menu-list a.is-active { color: var(--accent); font-weight: 600; }
/* Button im Ladezustand (z.B. während PDF-Fetch fürs Share-Sheet). */
.btn.is-loading { opacity: 0.6; pointer-events: none; }

/* ============================================================
   Native Mobil-Inhalte (body.m-native): iOS-Inset-Liste statt Tabelle.
   Generisch fuer alle nativen Mobil-Screens (< 640px). Row als <a> ODER
   <button> nutzbar. Siehe docs/MOBILE-PWA-PLAN.md.
   ============================================================ */
.m-list { display: none; }

@media (max-width: 640px) {
    /* Tabelle nur dort ausblenden, wo die Seite eine native Liste anbietet —
       sonst (Detailseiten etc.) wuerde Tabellen-Inhalt verschwinden. Seiten
       ohne .m-list behalten ihre Tabelle (greift dann das generische
       Karten-Pattern). */
    body.m-native .main-scroll:has(.m-list) .table-wrap { display: none; }
    body.m-native .m-list {
        display: block; background: var(--surface);
        border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
    }
    body.m-native .m-list-row {
        display: flex; align-items: center; gap: 10px; width: 100%;
        padding: 12px 14px;
        border: 0; border-bottom: 1px solid var(--border);
        background: none; font: inherit; text-align: left; color: inherit;
        text-decoration: none; cursor: pointer;
    }
    body.m-native .m-list-row:last-child { border-bottom: 0; }
    body.m-native .m-list-row:active { background: var(--surface-2, rgba(0,0,0,.04)); }
    body.m-native .m-list-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
    body.m-native .m-list-title { font-weight: 600; font-size: 15px; line-height: 1.25; }
    body.m-native .m-list-sub { font-size: 12px; color: var(--text-muted); display: flex; gap: 5px; flex-wrap: wrap; }
    body.m-native .m-list-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
    body.m-native .m-list-dur { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; }
    body.m-native .m-list-chevron { flex: 0 0 auto; color: var(--text-muted); display: flex; align-items: center; }
    body.m-native .m-list-chevron .icon { width: 18px; height: 18px; }
    body.m-native .m-list-empty { padding: 16px; text-align: center; color: var(--text-muted); }
}

/* ============================================================
   Native Mobil-Chrome: randlose, edge-to-edge Kopfleiste, die mit dem oberen
   Bildschirmrand verschmilzt (statt schwebender Karte). Loest auf m-native-
   Mobil den Floating-Frame auf. Siehe docs/MOBILE-PWA-PLAN.md.
   ============================================================ */
@media (max-width: 640px), (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    /* Floating-Frame aufloesen: kein Aussen-Padding, Main fuellt den Viewport. */
    body.m-native .layout { padding: 0; gap: 0; }
    body.m-native .main { margin: 0; }
    /* Default-Statusleiste ist opak und überlappt den Inhalt nicht — kein
       Safe-Area-Inset oben nötig. */
    body.m-native .main-fixed { padding: 0; }

    /* Heller, randloser edge-to-edge-Header — oben einheitlich weiß zur
       default-Statusleiste. KEINE Trennlinie unten: auf dem weißen Body wirkte
       sie als harte helle Linie. Die Abgrenzung zum Inhalt entsteht durch den
       Wechsel weiß (Topbar/Body) → grau (.main-scroll). Knappe vertikale
       Polsterung (4px) → kompakte ~44px-Standardhöhe; margin-bottom: 0, damit
       unter der Topbar kein zusätzlicher Leerraum bleibt. Einheitliche Höhe
       über ALLE Module dadurch, dass jede Topbar Buttons enthält (Dashboard:
       Quick-Buttons in der PWA, §19). */
    body.m-native .topbar {
        border: 0;
        border-radius: 0;
        box-shadow: none;
        background: var(--surface);
        padding: 4px 14px;
        margin-bottom: 0;
    }

    /* Unten genug Platz, damit der Inhalt UEBER die schwebenden FABs
       (Notizen/Zeiten/Notifications, Oberkante ~130px) und die Tab-Leiste
       hinausgescrollt werden kann — sonst bleibt das unterste hinter den FABs. */
    body.m-native .main-scroll {
        padding: 12px 14px calc(150px + env(safe-area-inset-bottom)) !important;
        /* #1 — iOS-Overscroll eindämmen: ohne dies kettet der Scroll-Schwung
           an seiner Grenze ans Dokument und zieht die ganze .main (inkl. der
           fixen Topbar) elastisch mit. contain hält den Bounce lokal, die
           Topbar bleibt statisch. */
        overscroll-behavior: contain;
    }
    /* Detailseiten: die rechte Meta-/Aktions-Sidebar ist auf Desktop sticky mit
       eigenem Scroll (max-height: calc(100vh-…)). Auf Mobil (einspaltig
       gestapelt) erzeugt das einen verschachtelten Scrollbereich — daher
       natürlich fließen lassen. !important schlägt auch die Inline-Styles
       (tickets-/billing-Show). */
    body.m-native .detail-sidebar {
        position: static !important;
        max-height: none !important;
        overflow: visible !important;
    }

    /* #1 — Topbar statisch: .main exakt auf die kleinste sichtbare Viewport-
       Höhe (svh) binden. 100vh ist auf iOS größer als der sichtbare Bereich;
       dadurch lief die ganze .main über und wirkte scrollbar (die fixe Topbar
       wanderte mit). svh ist stabil → .main-fixed (Topbar) bleibt oben fix,
       nur .main-scroll scrollt. */
    body.m-native .main { height: 100svh; }

    /* #1b — Dokument-Scroll komplett sperren: NUR .main-scroll scrollt.
       Ohne dies kann auf Views, deren Inhalt die .main-scroll nicht voll
       ausfuellt (oder an der Scroll-Grenze), die iOS-Rubber-Band-Geste das
       gesamte Dokument samt fixer Topbar UND Bottom-Tab-Leiste mitziehen —
       die wirkten dann "mitscrollbar". overflow:hidden auf <html> (nicht nur
       body) ist auf iOS noetig, da Safari das documentElement scrollt;
       overscroll-behavior:none unterbindet zusaetzlich den elastischen Bounce.
       Greift moduluebergreifend (eine Shell statt Pro-View-Fixes). */
    html:has(body.m-native),
    body.m-native {
        height: 100svh;
        overflow: hidden;
        overscroll-behavior: none;
    }

    /* #2 — Filter als zentriertes Modal (Look/Funktion wie .admin-modal, vgl.
       Ticket-Anlegen). Das 300px-Popover (right:0) ragte vorher links raus; ein
       Bottom-Sheet wurde unten von den FABs verdeckt. Zentriert sind Felder UND
       Aktionen frei bedienbar. Großer Spread-Shadow = Backdrop, bewusst klick-
       durchlässig → globaler Außenklick-Schließer (Layout-JS) schließt weiter. */
    .list-filter[open] > .list-filter-popover {
        position: fixed;
        top: 50%; left: 50%; right: auto; bottom: auto;
        transform: translate(-50%, -50%);
        width: calc(100vw - 32px); min-width: 0; max-width: 420px;
        max-height: calc(100svh - 96px); overflow-y: auto;
        border-radius: 12px; padding: 0;
        z-index: 9995;
        box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.5), 0 24px 64px rgba(0, 0, 0, 0.35);
    }
    /* Modal-Kopf nur hier (mobil) sichtbar; Formular bekommt Innenabstand,
       da das Popover selbst auf padding:0 steht. */
    .list-filter[open] > .list-filter-popover > .list-filter-modal-head { display: flex; }
    .list-filter[open] > .list-filter-popover > .list-filter-form { padding: 14px 16px 16px; }
}

/* Status-Bar: bewusst `default` (opak weiß, iOS-Standard) statt black-
   translucent — zuverlässig und kann nicht „verloren" gehen. Daher KEIN
   Anthrazit-Scrim mehr nötig; der obere Bereich ist einheitlich weiß. */

/* PWA-Standalone: Streifen HINTER der iOS-Statusleiste reinweiß.
   iOS färbt diesen Bereich mit dem Web-View-/Body-Hintergrund. html allein
   (Canvas) genügte am Gerät NICHT — der Body-Hintergrund schlägt durch. Daher
   Body explizit auf --surface (weiß); den grauen Seiten-Hintergrund (--bg)
   trägt stattdessen der Scroll-Bereich. Ergebnis: OBEN (Statusleiste + Topbar)
   komplett weiß, der Inhalt darunter bleibt grau abgesetzt. var(--surface)/
   var(--bg) decken Dark-Mode automatisch mit ab. Begrenzung auf <=1024px:
   nur Phone-/Tablet-PWA, nicht eine evtl. installierte Desktop-PWA. */
@media (display-mode: standalone) {
    html { background: var(--surface); }
}
@media (display-mode: standalone) and (max-width: 1366px) and (pointer: coarse) {
    body { background: var(--surface); }
    body.m-native .main-scroll { background: var(--bg); }
}


/* ============================================================
   FAB-Panels als Sheet/Modal auf Touch-Geräten  (Phase 10)
   Stech-/Stoppuhr · Benachrichtigungen · Notizen
   - iPhone (<=640px): Stechuhr = Bottom-Sheet (Peek oben, Griff,
     Wisch-zum-Schließen); Notizen/Notifs = Vollbild-Sheet (slide-up)
   - iPad / Touch-Tablet: zentriertes Modal (Look der admin-modals)

   WICHTIG: display in den Media-Regeln NUR via :not([hidden]) setzen, UND
   zusätzlich die [hidden]-Sicherheitsregel unten. Es gibt keine globale
   [hidden]{display:none}-Regel — nur den UA-Default (ohne !important) — und
   die Drawer-Basis-Regeln setzen display:flex hart. Ohne die Sicherheitsregel
   bliebe ein Panel beim Laden offen / ließe sich nicht schließen.
   Überschreibt die alten Eck-Positionen (.clock-popover{bottom:140px}
   bei 6768/6980) — steht bewusst zuletzt in der Datei.
   ============================================================ */

/* [hidden] ist verbindlich: ALLE Panels/Backdrops sind geschlossen display:none
   — egal welche display:flex-Regel (auch die Drawer-Basis-Regeln) sonst
   gewinnen würde. Greift erst NACH der Schließ-Animation, weil das hidden-
   Attribut zeitverzögert gesetzt wird (Clock 300ms, Notiz 280ms, Notif 300ms). */
.clock-popover[hidden],
.clock-popover-backdrop[hidden],
.notification-drawer[hidden],
.notification-drawer-backdrop[hidden],
.notes-drawer[hidden],
.notes-drawer-backdrop[hidden] { display: none !important; }

/* × nur auf Tablet (zentriertes Modal). Phone schließt per Wisch/Backdrop,
   Desktop per Außenklick. */
.clock-popover-close { display: none; }

/* Griff-Balken (Bottom-Sheet-Affordanz) — nur auf dem Phone sichtbar. */
.clock-popover-grip { display: none; }

/* Backdrop hinter Stechuhr-Sheet/Modal — nur Touch sichtbar (Desktop: nie). */
.clock-popover-backdrop {
    position: fixed; inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 10595;
    opacity: 0;
    transition: opacity .25s ease;
    display: none;
}

/* ---------- iPhone (<=640px) ---------- */
@media (max-width: 640px) {

    /* Stechuhr = Bottom-Sheet: unten verankert, inhaltshoch (kein Leerraum),
       runde Oberkante, Griff + Wisch-zum-Schließen. */
    .clock-popover:not([hidden]) {
        position: fixed !important;
        inset: auto 0 0 0 !important;                  /* unten verankert */
        width: auto !important; max-width: none !important;
        height: auto !important;
        max-height: calc(100svh - 56px) !important;     /* Peek oben sichtbar */
        margin: 0 !important;
        border: 0 !important;
        border-radius: 18px 18px 0 0 !important;
        box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.18) !important;
        z-index: 10600 !important;
        display: flex !important; flex-direction: column !important;
        overflow: hidden !important;
        padding: 0 !important;
        transform: translateY(100%);                    /* kein !important → Inline-Drag gewinnt */
        transition: transform .3s cubic-bezier(.16, 1, .3, 1);
        will-change: transform;
    }
    .clock-popover.is-open { transform: translateY(0); }

    .clock-popover-grip {
        display: flex !important; justify-content: center; align-items: center;
        flex: 0 0 auto;
        padding: 10px 0 6px;
        background: var(--surface);
        border-radius: 18px 18px 0 0;
        cursor: grab; touch-action: none;
    }
    .clock-popover-grip > span {
        display: block; width: 38px; height: 5px;
        border-radius: 999px; background: var(--border);
    }
    .clock-popover-head { flex: 0 0 auto; padding: 0 16px 8px !important; margin: 0 !important; }
    .clock-popover-body {
        flex: 1 1 auto; min-height: 0;
        overflow-y: auto; -webkit-overflow-scrolling: touch;
        display: flex; flex-direction: column; gap: 12px;
        padding: 12px 16px calc(16px + env(safe-area-inset-bottom));
    }
    /* Eigen-Margins der Sub-Blöcke aus — der flex-gap regelt jetzt den Abstand. */
    .clock-popover-day,
    .clock-popover-warning,
    .clock-popover-actions { margin-bottom: 0 !important; }
    .clock-popover-footer { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--border); }

    /* Backdrop auf dem Phone aktiv. */
    .clock-popover-backdrop:not([hidden]) { display: block; }
    .clock-popover-backdrop.is-shown { opacity: 1; }

    /* --- Notizen / Benachrichtigungen: Vollbild-Sheet, slide-up von unten --- */
    .notification-drawer:not([hidden]),
    .notes-drawer:not([hidden]) {
        position: fixed !important;
        inset: 0 !important;
        width: auto !important; max-width: none !important;
        height: auto !important; max-height: none !important;
        margin: 0 !important;
        border: 0 !important; border-radius: 0 !important;
        box-shadow: none !important;
        z-index: 10600 !important;
        display: flex !important; flex-direction: column !important;
        padding-top: env(safe-area-inset-top) !important;
        transform: translateY(100%);
        transition: transform .3s cubic-bezier(.16, 1, .3, 1);
    }
    .notification-drawer.is-open,
    .notes-drawer.is-open { transform: translateY(0); }

    .notification-drawer-head,
    .notes-drawer-head,
    .notes-drawer-tabs { flex: 0 0 auto !important; }
    .notification-drawer-body,
    .notes-drawer-body { flex: 1 1 auto !important; overflow-y: auto !important; min-height: 0 !important; }

    .notification-drawer-backdrop,
    .notes-drawer-backdrop { z-index: 10590 !important; }
}

/* ---------- iPad / Touch-Tablet: zentriertes Modal ---------- */
@media (min-width: 641px) and (max-width: 1366px) and (pointer: coarse) and (hover: none) {
    .clock-popover:not([hidden]),
    .notification-drawer:not([hidden]),
    .notes-drawer:not([hidden]) {
        position: fixed !important;
        top: 50% !important; left: 50% !important; right: auto !important; bottom: auto !important;
        transform: translate(-50%, -50%) scale(0.96) !important;   /* Start-Zustand (Einblenden) */
        opacity: 0;
        transition: opacity .2s ease, transform .2s cubic-bezier(.16, 1, .3, 1);
        width: min(560px, calc(100vw - 48px)) !important; max-width: none !important;
        height: auto !important; max-height: calc(100svh - 96px) !important;
        margin: 0 !important;
        border: 1px solid var(--border) !important; border-radius: 14px !important;
        box-shadow: 0 24px 64px rgba(0, 0, 0, 0.3) !important;
        z-index: 10600 !important;
        display: flex !important; flex-direction: column !important;
        overflow: hidden !important;
    }
    /* Eingeblendet: zentriert, voll sichtbar (sanftes Zoom/Fade über .is-open). */
    .clock-popover.is-open,
    .notification-drawer.is-open,
    .notes-drawer.is-open { transform: translate(-50%, -50%) scale(1) !important; opacity: 1; }
    .clock-popover-head { flex: 0 0 auto; }
    /* Eigen-Margins der Sub-Blöcke aus (wie Phone) — sonst doppelt mit flex-gap. */
    .clock-popover-day,
    .clock-popover-warning,
    .clock-popover-actions { margin-bottom: 0 !important; }
    .clock-popover-footer { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--border); }
    .clock-popover-body {
        flex: 1 1 auto; min-height: 0; overflow-y: auto;
        display: flex; flex-direction: column; gap: 12px; padding: 14px;
    }
    .notification-drawer-head,
    .notes-drawer-head,
    .notes-drawer-tabs { flex: 0 0 auto !important; }
    .notification-drawer-body,
    .notes-drawer-body { flex: 1 1 auto !important; overflow-y: auto !important; min-height: 0 !important; }
    .clock-popover-close { display: inline-flex !important; }

    /* Backdrop hinter dem zentrierten Stechuhr-Modal. */
    .clock-popover-backdrop:not([hidden]) { display: block; }
    .clock-popover-backdrop.is-shown { opacity: 1; }

    /* Drawer-Backdrops (Notizen/Notifs) über die Tab-Leiste (9990) heben,
       aber unter das zentrierte Modal (10600) — wie der Clock-Backdrop. */
    .notification-drawer-backdrop,
    .notes-drawer-backdrop { z-index: 10595 !important; }
}

/* ============================================================
   Button-Größen in den FAB-Panels (Notizen · Benachrichtigungen ·
   Stechuhr/Zeiten) auf System-Standard heben.
   Vorher durchgehend btn-sm / btn-icon+btn-sm (~26–28px) — laut
   §2 UI-CONVENTIONS „zu klein neben dem System-Standard" (.btn = 36px,
   Icon-only = 36×36 wie in der Topbar). Per Container gescoped, damit
   auch die JS-erzeugten Buttons (Stech-Aktionen, Notiz-Items) erfasst
   werden — gilt auf allen Breakpoints (kein @media).
   ============================================================ */

/* Header-Aktionen (Icon-only) = 36×36 wie die Topbar-Icon-Buttons. */
.notification-drawer-actions { gap: 6px; }
.notes-drawer-actions { gap: 6px; }
.notification-drawer-actions .btn,
.notes-drawer-actions .btn,
.clock-popover-head .clock-popover-close {
    width: 36px; height: 36px; min-width: 36px;
    padding: 0;
    justify-content: center;
    font-size: 20px; line-height: 1;   /* trägt das ×-Glyph */
}
.notification-drawer-actions .btn .icon,
.notes-drawer-actions .btn .icon {
    width: 18px; height: 18px; margin: 0;
}

/* Text-Aktionen = volle .btn-Größe (btn-sm neutralisieren):
   Einstechen/Pause/Ausstechen, Footer-Links, Notiz-Speichern, „Erlauben". */
.clock-popover-actions .btn,
.clock-popover-footer .btn,
.notes-item-edit-actions .btn,
.notification-perm-banner > button {
    padding: 7px 14px;
    font-size: 13px;
    min-height: 36px;
}

/* Inline-Aktionen je Notiz (Bearbeiten/Löschen) in der schmalen Meta-Zeile:
   kompakt, aber nicht mehr winzig (war padding 2px 5px ≈ 22px). */
.notes-item-actions { gap: 6px; }
.notes-item-actions .btn {
    width: 30px; height: 30px; min-width: 30px;
    padding: 0;
    justify-content: center;
    font-size: 16px; line-height: 1;
}
.notes-item-actions .btn .icon { width: 15px; height: 15px; margin: 0; }

/* Filter-Tabs etwas substanzieller, passend zu den größeren Buttons. */
.notes-drawer-tabs .notes-tab { padding: 8px 12px; font-size: 12.5px; }

/* ============================================================
   Portale — Linksammlung (read-only Desktop-Modal) + Admin-Logo-Thumbs.
   Geöffnet über den Sidebar-Fuß-Button (#links-modal). Logo-Kacheln mit
   Hover-Beschreibung, Kategorien einklappbar. Pflege: /admin/links.
   ============================================================ */

/* Großes Modal mit fixem Kopf + scrollendem Body. */
.portal-modal {
    max-width: min(960px, 94vw);
    display: flex; flex-direction: column;
    max-height: calc(100vh - 40px);
    overflow: hidden;
}
.portal-modal .admin-modal-head { flex: 0 0 auto; }
.portal-modal-body { flex: 1 1 auto; overflow-y: auto; }

/* Kategorie-Abschnitt (einklappbar). */
.portal-category { margin-bottom: 18px; }
.portal-category:last-child { margin-bottom: 0; }
.portal-cat-head {
    display: flex; align-items: center; gap: 8px;
    width: 100%;
    padding: 8px 4px;
    margin: 0 0 12px;
    background: none; border: 0;
    border-bottom: 1px solid var(--border);
    color: var(--text); font: inherit; font-weight: 600; font-size: 14px;
    cursor: pointer; text-align: left;
}
.portal-cat-head:hover { color: var(--accent); }
.portal-cat-chevron { width: 16px; height: 16px; flex: 0 0 auto; color: var(--text-muted); transition: transform .15s ease; }
.portal-category.is-collapsed .portal-cat-chevron { transform: rotate(-90deg); }
.portal-category.is-collapsed .portal-grid { display: none; }
.portal-cat-name { flex: 1 1 auto; min-width: 0; }
.portal-cat-count {
    flex: 0 0 auto;
    font-size: 11px; font-weight: 600; color: var(--text-muted);
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: 999px; padding: 1px 8px;
}

/* Kachel-Grid. */
.portal-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 12px;
}
.portal-tile {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    padding: 16px 12px;
    background: var(--surface); color: var(--text);
    border: 1px solid var(--border); border-radius: 12px;
    text-decoration: none; text-align: center;
    transition: border-color .12s, box-shadow .12s, transform .12s;
}
.portal-tile:hover {
    border-color: var(--accent);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.10);
    transform: translateY(-2px);
}
.portal-tile-logo {
    width: 56px; height: 56px; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: center;
}
.portal-tile-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.portal-tile-initials {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-2); border-radius: 12px;
    font-size: 20px; font-weight: 700; color: var(--text-muted);
}
.portal-tile-title {
    font-size: 13px; font-weight: 600; line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Hover-Beschreibung als sanft eingeblendetes Overlay über der Kachel. */
.portal-tile-desc {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    padding: 12px;
    background: var(--surface);
    color: var(--text); font-size: 12px; line-height: 1.4; text-align: center;
    border-radius: 12px;
    opacity: 0; pointer-events: none;
    transition: opacity .14s ease;
    overflow: hidden;
}
.portal-tile.has-desc:hover .portal-tile-desc { opacity: 1; }

/* Leerer Zustand. */
.portal-empty { text-align: center; color: var(--text-muted); padding: 40px 16px; }
.portal-empty .icon { width: 32px; height: 32px; opacity: 0.5; }
.portal-empty p { margin: 10px 0 14px; }

/* Admin-Liste: kleines Logo-Thumbnail + Initialen-Fallback. */
.link-logo-thumb {
    width: 30px; height: 30px; border-radius: 6px;
    object-fit: contain; background: var(--surface-2);
    border: 1px solid var(--border); flex: 0 0 auto;
}
.link-logo-thumb-fallback {
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; color: var(--text-muted);
}

/* Portale-Modal ist Desktop-only — auf dem Phone gar nicht anzeigen
   (der öffnende Button ist ohnehin m-hide-mobile). */
@media (max-width: 640px) {
    #links-modal { display: none !important; }
}

/* ============================================================
   Stempeluhr — Fortschrittsbalken „Arbeitszeit heute" (Ist gegen Tages-Soll).
   Verwendet im FAB-Popover (#clock-popover-day, via JS) und auf
   /arbeitszeiten (clock/_day-progress) in allen Ansichten.
   ============================================================ */
.clock-progress { display: flex; flex-direction: column; gap: 6px; }
.clock-progress-head {
    display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
    font-size: 12px;
}
.clock-progress-label {
    display: inline-flex; align-items: center; gap: 5px;
    color: var(--text-muted);
}
.clock-progress-label .icon { width: 14px; height: 14px; }
.clock-progress-figures { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text); }
.clock-progress-track {
    height: 8px; border-radius: 999px;
    background: var(--surface-2); overflow: hidden;
}
.clock-progress-bar {
    height: 100%; width: 0; border-radius: 999px;
    position: relative; overflow: hidden;
    /* Verlauf rot → grün, an der GESAMTEN Trackbreite verankert (--cp-pct =
       Füllgrad in %). So spiegelt die Farbe den Fortschritt: wenig = rot,
       fast voll = grün. background-size = 100/pct der Füllbreite = Trackbreite. */
    background-image: linear-gradient(90deg, #e5484d 0%, #e8a13a 48%, #2ea043 100%);
    background-repeat: no-repeat;
    background-size: calc(10000% / var(--cp-pct, 100)) 100%;
    transition: width .5s cubic-bezier(.16, 1, .3, 1);
}
/* Dezenter, langsam durchlaufender Glanz (kein JS), mit Pause zwischen Sweeps. */
.clock-progress-bar::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.3) 50%, transparent 100%);
    transform: translateX(-100%);
    animation: clock-progress-sheen 3s ease-in-out infinite;
}
@keyframes clock-progress-sheen {
    0%        { transform: translateX(-100%); }
    55%, 100% { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
    .clock-progress-bar::after { animation: none; opacity: 0; }
}
/* Soll erreicht: klar grün (überschreibt den Verlauf), Glanz läuft dezent weiter. */
.clock-progress-bar.is-complete { background-image: none; background-color: var(--green); }
.clock-progress-note { font-size: 11px; color: var(--text-muted); }

/* ============================================================
   Organigramm — top-down Baum mit Konnektoren (Organisation-Modul, README §30)
   Markup: <div class="org-chart-wrap"><ul class="org-chart"><li>
             <button class="org-node">…</button><ul>…Kinder…</ul></li></ul></div>
   ============================================================ */
.org-chart-wrap { overflow-x: auto; padding: 12px 0 4px; }
.org-chart, .org-chart ul { list-style: none; margin: 0; padding: 0; }
.org-chart { display: flex; justify-content: center; min-width: min-content; }
.org-chart ul { display: flex; justify-content: center; position: relative; padding-top: 22px; }
.org-chart li { position: relative; display: flex; flex-direction: column; align-items: center; padding: 22px 9px 0; }
/* horizontale Geschwister-Konnektoren */
.org-chart li::before, .org-chart li::after {
    content: ''; position: absolute; top: 0; right: 50%;
    width: 50%; height: 22px; border-top: 2px solid var(--border);
}
.org-chart li::after { right: auto; left: 50%; border-left: 2px solid var(--border); }
.org-chart li:only-child::before, .org-chart li:only-child::after { display: none; }
.org-chart li:only-child { padding-top: 0; }
.org-chart li:first-child::before, .org-chart li:last-child::after { border: 0 none; }
.org-chart li:last-child::before { border-right: 2px solid var(--border); border-radius: 0 6px 0 0; }
.org-chart li:first-child::after { border-radius: 6px 0 0 0; }
/* vertikaler Stiel vom Knoten zur Kinderreihe */
.org-chart ul::before {
    content: ''; position: absolute; top: 0; left: 50%;
    width: 0; height: 22px; border-left: 2px solid var(--border);
}
/* Wurzelreihe: keine Konnektoren oben */
.org-chart > li { padding-top: 0; }
.org-chart > li::before, .org-chart > li::after { display: none; }
/* Knoten-Box (klickbar → Profil-Modal) */
.org-node {
    display: inline-flex; align-items: center; gap: 9px;
    background: var(--surface); border: 1px solid var(--border); border-radius: 8px;
    padding: 8px 11px; min-width: 158px; max-width: 230px;
    font: inherit; color: inherit; text-align: left; cursor: pointer; appearance: none;
}
.org-node:hover { border-color: var(--accent); }
.org-node .avatar { width: 34px; height: 34px; font-size: 13px; flex: 0 0 auto; }
.org-node-text { min-width: 0; }
.org-node-name { display: block; font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.org-node-sub { display: block; color: var(--text-muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
