/* public/css/style.css */

/* Ubuntu Font (lokal gehostet) */
@font-face {
    font-family: 'Ubuntu';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/Ubuntu-Regular.woff2') format('woff2');
}

@font-face {
    font-family: 'Ubuntu';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/Ubuntu-Medium.woff2') format('woff2');
}

@font-face {
    font-family: 'Ubuntu';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/Ubuntu-Bold.woff2') format('woff2');
}

/* Material Symbols Outlined (lokal gehostet) */
@font-face {
    font-family: 'Material Symbols Outlined';
    src: url('../fonts/MaterialSymbolsOutlined.woff2') format('woff2');
    font-weight: 100 700;
    font-style: normal;
    font-display: block;
}

.material-symbols-outlined {
    font-family: 'Material Symbols Outlined';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    -webkit-font-feature-settings: 'liga';
    font-feature-settings: 'liga';
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* ===== Aurora Ring — CSS-Animationen (kein GSAP) ===== */

/* Rotation (Desktop 8s, Mini 10s) */
.aurora-ring-svg {
    animation: auroraRotation 8s linear infinite;
    transform-origin: 50% 50%;
}
.aurora-ring-svg-mini {
    animation: auroraRotation 10s linear infinite;
    transform-origin: 50% 50%;
}
@keyframes auroraRotation {
    to { transform: rotate(360deg); }
}

/* Ring-Stroke Opacity + Width Puls (yoyo-Effekt via alternate) */
.aurora-ring {
    animation: auroraRingPuls 2.5s ease-in-out infinite alternate;
}
.aurora-ring-mini {
    animation: auroraRingPulsMini 2s ease-in-out infinite alternate;
}
@keyframes auroraRingPuls {
    from { opacity: 0.8; stroke-width: 2.5; }
    to   { opacity: 0.5; stroke-width: 2; }
}
@keyframes auroraRingPulsMini {
    from { opacity: 0.8; stroke-width: 2; }
    to   { opacity: 0.5; stroke-width: 1.5; }
}

/* Gradient-Farb-Morph — 4 Farbsets, 12s Zyklus */
.aurora-gradient stop:nth-child(1) { animation: auroraS1 12s ease-in-out infinite; }
.aurora-gradient stop:nth-child(2) { animation: auroraS2 12s ease-in-out infinite; }
.aurora-gradient stop:nth-child(3) { animation: auroraS3 12s ease-in-out infinite; }
.aurora-gradient stop:nth-child(4) { animation: auroraS4 12s ease-in-out infinite; }

@keyframes auroraS1 {
    0%, 100% { stop-color: #a78bfa; }
    25%      { stop-color: #818cf8; }
    50%      { stop-color: #e879f9; }
    75%      { stop-color: #6ee7b7; }
}
@keyframes auroraS2 {
    0%, 100% { stop-color: #e879f9; }
    25%      { stop-color: #6ee7b7; }
    50%      { stop-color: #f472b6; }
    75%      { stop-color: #a78bfa; }
}
@keyframes auroraS3 {
    0%, 100% { stop-color: #818cf8; }
    25%      { stop-color: #a78bfa; }
    50%      { stop-color: #c084fc; }
    75%      { stop-color: #e879f9; }
}
@keyframes auroraS4 {
    0%, 100% { stop-color: #a78bfa; }
    25%      { stop-color: #818cf8; }
    50%      { stop-color: #e879f9; }
    75%      { stop-color: #6ee7b7; }
}

/* Glow — box-shadow Puls */
.aurora-hue-glow {
    animation: auroraGlow 3s ease-in-out infinite alternate;
}
.aurora-hue-glow-mini {
    animation: auroraGlowMini 3s ease-in-out infinite alternate;
}
@keyframes auroraGlow {
    from { box-shadow: 0 0 10px 2px rgba(129,140,248,0.2), 0 0 20px 4px rgba(167,139,250,0.08); }
    to   { box-shadow: 0 0 20px 4px rgba(167,139,250,0.4), 0 0 40px 8px rgba(232,121,249,0.15); }
}
@keyframes auroraGlowMini {
    from { box-shadow: 0 0 6px 1px rgba(129,140,248,0.15), 0 0 12px 2px rgba(167,139,250,0.05); }
    to   { box-shadow: 0 0 12px 2px rgba(167,139,250,0.3), 0 0 24px 4px rgba(232,121,249,0.1); }
}

/* ===== Zeit-Tracker Glow — emerald-Variante von aurora-hue-glow-mini =====
   Zeiterfassungs-Modul (Welle Zeiterfassung Stufe 1). Wird vom
   ZeitTrackerHeader an seinem Button-Element gesetzt, wenn ein Eintrag
   laeuft. Pausiert-State halbiert die Intensitaet (visuelles "atmet
   ruhiger"-Signal). */
.tracker-glow-aktiv {
    animation: trackerGlowAktiv 2.5s ease-in-out infinite alternate;
}
.tracker-glow-pausiert {
    animation: trackerGlowPausiert 4s ease-in-out infinite alternate;
}
@keyframes trackerGlowAktiv {
    from { box-shadow: 0 0 6px 1px rgba(16,185,129,0.20), 0 0 12px 2px rgba(52,211,153,0.08); }
    to   { box-shadow: 0 0 14px 3px rgba(16,185,129,0.45), 0 0 28px 6px rgba(52,211,153,0.18); }
}
@keyframes trackerGlowPausiert {
    from { box-shadow: 0 0 4px 1px rgba(148,163,184,0.10), 0 0 8px 2px rgba(148,163,184,0.05); }
    to   { box-shadow: 0 0 8px 2px rgba(148,163,184,0.22), 0 0 16px 3px rgba(148,163,184,0.10); }
}

/* Reduced Motion — alle Aurora-Animationen stoppen */
@media (prefers-reduced-motion: reduce) {
    .aurora-ring-svg, .aurora-ring-svg-mini,
    .aurora-ring, .aurora-ring-mini,
    .aurora-gradient stop,
    .aurora-hue-glow, .aurora-hue-glow-mini,
    .tracker-glow-aktiv, .tracker-glow-pausiert {
        animation: none;
    }

    /* Micro-Animationen-Welle: Modal/Container/Card-Lifecycle nur Hard-Cut.
       Aufrufer pruefen prefersReducedMotion in JS und ueberspringen den
       await-Pfad — die CSS-Regel ist nur Doppelsicherung. */
    .modal-overlay-enter, .modal-overlay-leave,
    .modal-content-enter, .modal-content-leave,
    .anim-container-enter, .anim-container-leave,
    .anim-slide-in, .anim-card-leave {
        animation: none;
    }
}

/* Page Visibility / PWA-Pause — alle CSS-Animationen einfrieren.
   Klasse wird von fx/motion.js auf <html> getoggelt. */
.animationen-pausiert *  {
    animation-play-state: paused !important;
}

/* Liquid Glass Utilities */
.liquid-glass {
    background: linear-gradient(135deg, rgba(49, 53, 60, 0.4) 0%, rgba(16, 20, 26, 0.6) 100%);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
}

/* Dichtere Variante fuer Dropdowns/Popover, die ueber Text liegen — die
   transparente liquid-glass-Optik wird durch Text dahinter zu unruhig.
   Behaelt Blur fuer Tiefen-Effekt, opacity ~0.92/0.95. (Etappe 4b) */
.liquid-glass-solid {
    background: linear-gradient(135deg, rgba(31, 35, 41, 0.95) 0%, rgba(16, 20, 26, 0.97) 100%);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
}

.glow-accent-primary {
    box-shadow: 0 0 40px -10px rgba(110, 229, 145, 0.2);
}

.glow-accent-error {
    box-shadow: 0 0 40px -10px rgba(255, 180, 171, 0.2);
}

.glow-accent-tertiary {
    box-shadow: 0 0 40px -10px rgba(249, 200, 0, 0.2);
}

/* Hide scrollbar for kanban board */
.scrollbar-hide::-webkit-scrollbar {
    display: none;
}
.scrollbar-hide {
    -ms-overflow-style: none; /* IE and Edge */
    scrollbar-width: none; /* Firefox */
}

/* Typography Overrides */
html, body {
    font-family: 'Ubuntu', sans-serif;
    background-color: var(--color-background);
    color: var(--color-on-background);
}

/* Crisp Gamified Animations */
/* Welle 7b / B7: completeTada + .anim-task-complete entfernt — Erfolgs-
   animation laeuft jetzt ueber fx/erfolgAnimation.js (GSAP + Sparkles,
   reduced-motion-Fallback). */

@keyframes crispSlideIn {
    0% { opacity: 0; transform: translateY(15px) scale(0.98); }
    100% { opacity: 1; transform: translateY(0) scale(1); }
}

.anim-slide-in {
    animation: crispSlideIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes containerFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes containerFadeOut {
    from { opacity: 1; }
    to   { opacity: 0; }
}

.anim-container-enter {
    animation: containerFadeIn 0.2s ease-out forwards;
}

.anim-container-leave {
    animation: containerFadeOut 0.12s ease-in forwards;
}

/* Card verabschiedet sich vor Hard-Delete: opacity raus, leichter Sink. */
@keyframes cardLeave {
    from { opacity: 1; transform: scale(1) translateY(0); }
    to   { opacity: 0; transform: scale(0.95) translateY(6px); }
}

.anim-card-leave {
    animation: cardLeave 0.22s cubic-bezier(0.4, 0, 1, 1) forwards;
}

/* Modal Animations */
@keyframes modalFadeIn {
    from { opacity: 0; backdrop-filter: blur(0px); }
    to { opacity: 1; backdrop-filter: blur(20px); }
}

@keyframes modalScaleIn {
    from { transform: scale(0.95) translateY(10px); opacity: 0; }
    to { transform: scale(1) translateY(0); opacity: 1; }
}

@keyframes modalFadeOut {
    from { opacity: 1; backdrop-filter: blur(20px); }
    to   { opacity: 0; backdrop-filter: blur(0px); }
}

@keyframes modalScaleOut {
    from { transform: scale(1) translateY(0); opacity: 1; }
    to   { transform: scale(0.96) translateY(4px); opacity: 0; }
}

.modal-overlay-enter {
    animation: modalFadeIn 0.2s ease-out forwards;
}

.modal-content-enter {
    animation: modalScaleIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.modal-overlay-leave {
    animation: modalFadeOut 0.18s ease-in forwards;
}

.modal-content-leave {
    animation: modalScaleOut 0.18s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

/* Toast-Animationen (components/Toast.js) */
@keyframes toastSlideDown {
    from { opacity: 0; transform: translateY(-16px) scale(0.96); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes toastSlideUp {
    from { opacity: 1; transform: translateY(0) scale(1); }
    to   { opacity: 0; transform: translateY(-12px) scale(0.96); }
}
.toast-enter { animation: toastSlideDown 0.25s cubic-bezier(0.16, 1, 0.3, 1) forwards; }
.toast-leave { animation: toastSlideUp 0.2s ease-in forwards; }

/* Nav-Button Farbsystem: jeder Button hat sein eigenes --tab-color
   (gesetzt inline via style="--tab-color: R,G,B"). Fallback: --theme-color. */
.nav-btn { --tab-color: var(--theme-color, 148, 163, 184); }

/* Aktiver Tab: Titel + Icon in Tab-Farbe, dezenter Hintergrund.
   .nav-btn.nav-active erhöht Spezifität über Tailwind text-slate-400. */
.nav-btn.nav-active {
    background-color: rgba(var(--tab-color), 0.15);
    color: rgb(var(--tab-color));
}

/* Desktop Hover: Button nimmt die Farbe des gehoverten Tabs an */
#sidebar-modul-nav .nav-btn:not(.nav-active):hover {
    color: rgb(var(--tab-color));
    background-color: rgba(var(--tab-color), 0.08);
}

/* Fixed UI-Elemente (Header, FAB) duerfen keine Scroll-Geste
   auf der Appshell ausloesen, wenn der Finger darauf liegt. Ohne
   touch-action:none interpretiert der Browser einen Swipe ueber diese
   Elemente als Body-Scroll — besonders irritierend in Modals. */
header.sticky.top-0 {
    touch-action: none;
}

/* ---------------------------------------------------------------------
   PWA Safe-Area-Handling (v1.0.15)
   ---------------------------------------------------------------------
   `env(safe-area-inset-*)` ist in iOS Safari **dynamisch**: solange die
   Browser-Chrome (URL-Bar unten) sichtbar ist, liefert der Bottom-Inset
   0. Beim Scrollen verschwindet die Chrome, und der Wert springt auf
   ~34px (Home-Indicator). Dieser Sprung macht eine fixe Bottom-Nav
   springen — haesslich und inkonsistent.

   Loesung: Safe-Area-Padding NUR im standalone-Modus (installierte PWA)
   anwenden. Dort ist der Wert stabil. Im Browser bleibt alles bei einem
   fixen, bequemen Padding, unabhaengig vom Chrome-State.

   Android profitiert gratis mit: in Chrome-Browser und Android-PWA ist
   der Bottom-Inset ohnehin meistens 0 (Gesten-Bar via Systembar
   gerendert), nur bei Geraeten mit klassischer Navigationsbar springt
   er ein — dann aber stabil. Selbe Logik gilt fuer Top.
   --------------------------------------------------------------------- */
@media (display-mode: standalone) {
    /* Notch-Zone halbiert (analog zur Bottom-Loesung): der volle
       safe-area-inset-top macht den Header auf notched iPhones
       unnoetig hoch. Die halbe Hoehe plus ein kleines Basis-Padding
       reicht, damit die Statusbar lesbar bleibt. Gilt generisch fuer
       ALLE sticky-Header der App (index.php, einstellungen, admin,
       archiv, feedback, aufgaben-einstellungen).

       max(...) als Floor: auf Desktop-PWA (Chrome/Edge installiert) ist
       safe-area-inset-top = 0, dadurch wuerde die -15px-Korrektur das
       Padding ins Negative druecken. Der Floor garantiert, dass das
       Basis-Padding nie unterschritten wird. */
    header.sticky.top-0 {
        padding-top: max(0.75rem, calc(env(safe-area-inset-top) + 0.75rem - 15px));
    }
    /* Profil-Drawer hat keinen sticky-Header sondern ein eigenes
       Header-Div — gleiche Safe-Area-Behandlung wie die Seiten-Header. */
    #profil-drawer > div:first-child {
        padding-top: max(1.5rem, calc(env(safe-area-inset-top) + 1.5rem - 15px));
    }
    /* Stufe 3b: FAB sitzt ueber der Floating Pill auf Mobile.
       4.2rem Basis + Safe-Area fuer Home-Indicator. */
    @media (max-width: 767px) {
        .fab-btn {
            bottom: calc(4.2rem + env(safe-area-inset-bottom) / 2) !important;
        }
    }
    /* Modals: Wrapper bekommt Bottom-Padding damit der Content nicht in
       den Home-Indicator-Bereich ragt. Max-Hoehe der Content-Box zieht
       beide Safe-Area-Insets ab, damit das Modal auf notched iPhones
       vollstaendig im sichtbaren Bereich sitzt und scrollbar bleibt. */
    .modal-safe-wrapper {
        padding-bottom: env(safe-area-inset-bottom);
    }
    .modal-safe-content {
        max-height: calc(100dvh - env(safe-area-inset-top) + 15px - env(safe-area-inset-bottom) - 2rem);
    }
    .toast-container {
        top: max(1rem, calc(env(safe-area-inset-top) + 1rem - 15px));
    }
}
/* iOS Safari Legacy: `window.navigator.standalone === true` setzt via
   JS die Klasse `.ios-standalone` auf <html>, weil nicht alle iOS-
   Versionen die display-mode media query zuverlaessig matchen. */
html.ios-standalone header.sticky.top-0 {
    padding-top: max(0.75rem, calc(env(safe-area-inset-top) + 0.75rem - 15px));
}
html.ios-standalone #profil-drawer > div:first-child {
    padding-top: max(1.5rem, calc(env(safe-area-inset-top) + 1.5rem - 15px));
}
@media (max-width: 767px) {
    html.ios-standalone .fab-btn {
        bottom: calc(4.2rem + env(safe-area-inset-bottom) / 2);
    }
}
html.ios-standalone .modal-safe-wrapper {
    padding-bottom: env(safe-area-inset-bottom);
}
html.ios-standalone .modal-safe-content {
    max-height: calc(100dvh - env(safe-area-inset-top) + 15px - env(safe-area-inset-bottom) - 2rem);
}
html.ios-standalone .toast-container {
    top: max(1rem, calc(env(safe-area-inset-top) + 1rem - 15px));
}

/* Mobile: Modals scrollen wenn der Inhalt laenger ist als der Viewport
   (z.B. Aufgaben-Detail mit allen Sektionen ausgeklappt). Auf Desktop
   behalten die Modals overflow-visible, damit Picker-Popover wie
   KundePicker oder Kategorie-Wechsel ueber den Modal-Rand hinausragen
   duerfen — bei dem viel groesseren Viewport ist Inner-Scroll dort
   praktisch nie noetig. */
@media (max-width: 767px) {
    .modal-safe-content {
        overflow-y: auto;
        overscroll-behavior: contain;
    }
}

/* === FLOATING PILL (Mobile Sub-Navigation, Stufe 3b) === */
/* Picker/Slider-Mechanik: Items gleiten durch eine feste Mitte.
   Lens-Vergroesserung + Spotlight-Glow am Zentrum. Alle visuellen
   Zustaende werden live per JS Custom Properties gesteuert:
   --pill-scale, --pill-opacity, --pill-glow (0..1). */

.floating-pill {
    position: fixed;
    bottom: 0.7rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 55;
    max-width: 78vw;
    border-radius: 9999px;
    /* Liquid-glass Basis + farbiger Tint/Border/Glow per Modul-Farbe.
       --pill-modul-farbe wird per JS auf die Farbe des zentrierten Items gesetzt.
       Konvexe Woelbung: Lichtgradient oben, Schattengradient unten. */
    --pill-modul-farbe: 148, 163, 184;
    background:
        /* Lichteinfall: obere Haelfte heller (konvexe Oberseite) */
        linear-gradient(to bottom,
            rgba(255, 255, 255, 0.07) 0%,
            rgba(255, 255, 255, 0.02) 40%,
            transparent 55%,
            rgba(0, 0, 0, 0.08) 80%,
            rgba(0, 0, 0, 0.12) 100%),
        /* Farbiger Modul-Tint */
        linear-gradient(135deg,
            rgba(var(--pill-modul-farbe), 0.06) 0%,
            rgba(var(--pill-modul-farbe), 0.03) 100%),
        /* Glass-Basis */
        linear-gradient(135deg, rgba(49, 53, 60, 0.5) 0%, rgba(16, 20, 26, 0.68) 100%);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    /* Border transparent — reflektiver Rand via ::before */
    border: 1px solid transparent;
    box-shadow:
        0 0 20px rgba(var(--pill-modul-farbe), 0.12),
        0 0 6px rgba(var(--pill-modul-farbe), 0.08),
        0 8px 32px rgba(0, 0, 0, 0.4);
    padding: 4px;
    touch-action: pan-x;
    /* position: fixed oben reicht — ::before braucht keinen extra Kontext */
    /* Spotlight im Inneren — Farbe per JS */
    --spotlight-farbe: 148, 163, 184;
    --spotlight-intensitaet: 0;
}
/* Reflektiver Border: oben hell (Lichtquelle), unten dunkel (Schatten).
   Pseudo-Element weil border-image + border-radius nicht zusammen geht. */
.floating-pill::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(to bottom,
        rgba(255, 255, 255, 0.20) 0%,
        rgba(var(--pill-modul-farbe), 0.12) 30%,
        rgba(var(--pill-modul-farbe), 0.05) 70%,
        rgba(0, 0, 0, 0.10) 100%);
    -webkit-mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    mask:
        linear-gradient(#fff 0 0) content-box,
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    z-index: 0;
}
.floating-pill-spotlight {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 5rem;
    height: 100%;
    border-radius: 9999px;
    background: radial-gradient(
        ellipse at center,
        rgba(var(--spotlight-farbe), calc(var(--spotlight-intensitaet) * 0.35)) 0%,
        rgba(var(--spotlight-farbe), calc(var(--spotlight-intensitaet) * 0.08)) 50%,
        transparent 80%
    );
    pointer-events: none;
    touch-action: pan-x;
    z-index: 1;
}
.floating-pill-scroller {
    display: flex;
    align-items: center;
    gap: 2px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    touch-action: pan-x;
    /* Edge-Padding: damit erstes/letztes Item in die Mitte snappen kann */
    padding: 0 calc(50% - 2.5rem);
    position: relative;
    z-index: 2;
}
.floating-pill-scroller::-webkit-scrollbar {
    display: none;
}
.floating-pill-item {
    --pill-scale: 0.85;
    --pill-opacity: 0.35;
    --pill-glow: 0;
    flex-shrink: 0;
    scroll-snap-align: center;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 16px;
    border-radius: 9999px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    border: none;
    cursor: pointer;
    touch-action: pan-x;
    /* Alle visuellen States ueber Custom Properties */
    color: rgba(226, 232, 240, var(--pill-opacity));
    background: rgba(var(--pill-farbe), calc(var(--pill-glow) * 0.18));
    transform: scale(var(--pill-scale));
    /* Kein transition — wird per scroll-frame gesetzt */
    transition: none;
    will-change: transform;
}
.floating-pill-icon {
    font-size: 18px;
}
.floating-pill-item.pill-focused .floating-pill-icon {
    font-variation-settings: 'FILL' 1;
}

/* Safe-Area fuer Floating Pill im Standalone-Modus */
@media (display-mode: standalone) {
    .floating-pill {
        bottom: calc(0.7rem + env(safe-area-inset-bottom) / 2);
    }
}
html.ios-standalone .floating-pill {
    bottom: calc(0.7rem + env(safe-area-inset-bottom) / 2);
}

/* Pill-Clearance: Bottom-Padding fuer scrollbare Page-Container, damit die
   Floating Pill (mobile Sub-Nav) Inhalte am unteren Rand nicht verdeckt.
   - Desktop (md+): Pill ist versteckt, --pill-clearance entspricht pb-8.
   - Mobile: Pill-Bottom (0.7rem) + Pill-Hoehe (~48px) + Atmen (1rem) + safe-area.
   - Standalone-PWA (iOS): zusaetzlich halber safe-area-Anteil, weil die Pill
     selbst auch nach oben gerueckt ist. */
:root {
    --pill-clearance: 2rem;
}
@media (max-width: 767px) {
    :root {
        --pill-clearance: calc(0.7rem + 48px + 1rem + env(safe-area-inset-bottom));
    }
}
html.ios-standalone {
    --pill-clearance: calc(0.7rem + env(safe-area-inset-bottom) / 2 + 48px + 1rem);
}
.pb-pill {
    padding-bottom: var(--pill-clearance);
}

/* Reduced Motion: kein smooth-scroll */
@media (prefers-reduced-motion: reduce) {
    .floating-pill-scroller {
        scroll-behavior: auto;
    }
}

/* === FARBWELTEN PRO BEREICH === */

/* --------------------------------------------------------------------- */
/* Workspace-Theme (dynamisch via CSS Custom Properties von JS gesetzt)   */
/* Die Custom Properties --theme-color und --theme-color-secondary        */
/* werden von `setzeThemeFuerWorkspace(ws)` auf document.body gesetzt.    */
/* Fixe Module (anrufe, einkaufsliste, archiv) ueberschreiben via         */
/* hoehere Specificity weiter unten.                                      */
/* --------------------------------------------------------------------- */
body {
    --theme-color: 168, 85, 247;
    --theme-color-secondary: 139, 92, 246;
}
.board-title { color: rgb(var(--theme-color)); }
.kategorie-name { color: rgb(var(--theme-color)) !important; }
.accent-blob-1 { background: rgba(var(--theme-color), 0.1); }
.accent-blob-2 { background: rgba(var(--theme-color-secondary), 0.1); }
.fab-btn {
    background: linear-gradient(135deg, rgb(var(--theme-color)), rgb(var(--theme-color-secondary)));
    box-shadow: 0 10px 30px rgba(var(--theme-color), 0.4);
    /* Touch auf dem FAB darf keine Scroll-Geste auf der Appshell ausloesen.
       Ohne touch-action:none interpretiert der Browser einen Finger-Swipe
       ueber den fixed-positioned Button als Body-Scroll. */
    touch-action: none;
}
.btn-neue-kat:hover { color: rgb(var(--theme-color)); }
.modal-submit-btn {
    background: linear-gradient(135deg, rgb(var(--theme-color)), rgb(var(--theme-color-secondary)));
    box-shadow: 0 5px 15px rgba(var(--theme-color), 0.3);
}
/* Anrufe = Orange */
.theme-anrufe { --theme-color: 251, 146, 60; }
.theme-anrufe .board-title { color: rgb(251, 146, 60); }
.theme-anrufe .accent-blob-1 { background: rgba(251, 146, 60, 0.1); }
.theme-anrufe .accent-blob-2 { background: rgba(245, 158, 11, 0.1); }
.theme-anrufe .fab-btn {
    background: linear-gradient(135deg, rgb(251, 146, 60), rgb(245, 158, 11));
    box-shadow: 0 10px 30px rgba(251, 146, 60, 0.4);
}
/* Einkaufsliste = Hellblau */
.theme-einkaufsliste { --theme-color: 56, 189, 248; }
.theme-einkaufsliste .board-title { color: rgb(56, 189, 248); }
.theme-einkaufsliste .accent-blob-1 { background: rgba(56, 189, 248, 0.1); }
.theme-einkaufsliste .accent-blob-2 { background: rgba(14, 165, 233, 0.1); }
.theme-einkaufsliste .fab-btn {
    background: linear-gradient(135deg, rgb(56, 189, 248), rgb(14, 165, 233));
    box-shadow: 0 10px 30px rgba(56, 189, 248, 0.4);
}
/* Archiv = Grau */
.theme-archiv { --theme-color: 148, 163, 184; }
.theme-archiv .board-title { color: rgb(148, 163, 184); }
.theme-archiv .accent-blob-1 { background: rgba(148, 163, 184, 0.05); }
.theme-archiv .accent-blob-2 { background: rgba(100, 116, 139, 0.05); }

/* Einkaufsliste Masonry Layout */
.einkauf-masonry {
    columns: 1;
    column-gap: 1rem;
}
@media (min-width: 768px) {
    .einkauf-masonry {
        columns: 2;
        column-gap: 1.5rem;
    }
}
.einkauf-card {
    break-inside: avoid;
    transition: box-shadow 0.3s ease, border-color 0.3s ease;
}
.einkauf-card:hover {
    border-color: rgba(255,255,255,0.08);
    box-shadow: 0 8px 32px -8px var(--card-glow, rgba(56,189,248,0.1)),
                0 0 0 1px rgba(255,255,255,0.03);
}

/* Einkauf-Listen: Notizblock-Polish ueber den ChecklistManager.
   Rein visuell — gesamte Logik bleibt die globale ChecklistManager-Logik. */
.einkauf-card .checklist-list {
    gap: 0;
}
.einkauf-card .checklist-item {
    padding-top: 7px;
    padding-bottom: 7px;
    border-radius: 0;
    /* Zarte Notizblock-Linie unten — "durchgeschimmerte" Lineatur */
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
}
.einkauf-card .checklist-item:last-child {
    border-bottom: none;
    box-shadow: none;
}
.einkauf-card .checklist-item:hover {
    background: rgba(255, 255, 255, 0.02);
}
.einkauf-card .checklist-item-text {
    /* Groesser als Tasks-Checkliste (12px) — Listen-Modul will man aus der Entfernung lesen */
    font-size: 14px !important;
    line-height: 1.45;
    color: rgb(203, 213, 225); /* slate-300 — kraeftiger als slate-400 bei Tasks */
}
.einkauf-card .checklist-item-text.line-through {
    color: rgb(71, 85, 105); /* slate-600 */
}

/* Profil Slide-In Drawer */
.profil-drawer {
    transform: translateX(-100%);
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
.profil-drawer.open {
    transform: translateX(0) !important;
}
.profil-drawer-backdrop {
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}
.profil-drawer-backdrop.open {
    opacity: 1;
    pointer-events: auto;
}

/* Date Input Styling */
.date-input {
    color-scheme: dark;
    appearance: none;
    -webkit-appearance: none;
}
.date-input::-webkit-calendar-picker-indicator {
    filter: invert(0.5) brightness(1.5);
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.2s ease;
}
.date-input::-webkit-calendar-picker-indicator:hover {
    opacity: 1;
}
/* Detail-Faelligkeit: kein Rahmen, kein natives Icon */
#detail-faellig-datum,
#detail-faellig-uhrzeit,
#detail-faellig-am {
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
    outline: none !important;
    -webkit-appearance: none !important;
    -moz-appearance: textfield !important;
    appearance: none !important;
    color-scheme: dark;
}
#detail-faellig-datum::-webkit-calendar-picker-indicator,
#detail-faellig-uhrzeit::-webkit-calendar-picker-indicator,
#detail-faellig-am::-webkit-calendar-picker-indicator {
    display: none !important;
    -webkit-appearance: none !important;
    opacity: 0 !important;
    width: 0 !important;
    height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
}
#detail-faellig-am::-webkit-date-and-time-value {
    text-align: left;
}
#detail-faellig-am::-webkit-inner-spin-button,
#detail-faellig-am::-webkit-clear-button,
#detail-faellig-am::-webkit-date-edit-fields-wrapper + * {
    display: none !important;
}

/* Priority Glow — dezenter LED-Dot oben rechts */
.task-prio-dot {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    z-index: 20;
    pointer-events: none;
}
.task-prio-dot.prio-rot {
    background: rgb(255, 120, 110);
    --prio-glow-ruhe: 0 0 4px 1px rgba(255, 120, 110, 0.3);
    --prio-glow-puls: 0 0 10px 3px rgba(255, 120, 110, 0.5), 0 0 20px 6px rgba(255, 120, 110, 0.15);
    box-shadow: var(--prio-glow-ruhe);
    animation: prioPuls 3.5s ease-in-out infinite;
}
.task-prio-dot.prio-gelb {
    background: rgb(249, 200, 0);
    --prio-glow-ruhe: 0 0 4px 1px rgba(249, 200, 0, 0.25);
    --prio-glow-puls: 0 0 10px 3px rgba(249, 200, 0, 0.5), 0 0 20px 6px rgba(249, 200, 0, 0.15);
    box-shadow: var(--prio-glow-ruhe);
    animation: prioPuls 3.5s ease-in-out infinite;
}
.task-prio-dot.prio-gruen {
    background: rgb(110, 229, 145);
    box-shadow: 0 0 4px 1px rgba(110, 229, 145, 0.2);
}

/* Prio-Dot Glow-Puls — rein CSS, kein JS pro Frame */
@keyframes prioPuls {
    0%, 100% { box-shadow: var(--prio-glow-ruhe); }
    50%      { box-shadow: var(--prio-glow-puls); }
}

/* Urgent-Angle als animierbare CSS Custom Property */
@property --urgent-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

@keyframes urgentRotation {
    to { --urgent-angle: 360deg; }
}

@media (prefers-reduced-motion: reduce) {
    .task-prio-dot.prio-rot,
    .task-prio-dot.prio-gelb {
        animation: none;
    }
    .task-urgent {
        animation: none;
    }
}

/* Urgent Task — High Priority + heute/ueberfaellig: animierter Gradient-Rahmen */
.task-urgent {
    animation: urgentRotation 14s linear infinite;
    position: relative;
    border-color: transparent !important;
    overflow: visible;
}
.task-urgent::before {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    padding: 1px;
    background: conic-gradient(
        from var(--urgent-angle, 0deg),
        rgba(251, 146, 60, 0.6),
        rgba(245, 158, 11, 0.15),
        rgba(255, 200, 60, 0.5),
        rgba(251, 146, 60, 0.1),
        rgba(245, 158, 11, 0.6),
        rgba(255, 200, 60, 0.15),
        rgba(251, 146, 60, 0.6)
    );
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    z-index: 0;
}
/* Dezenter aeusserer Glow */
.task-urgent::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: inherit;
    background: conic-gradient(
        from var(--urgent-angle, 0deg),
        rgba(251, 146, 60, 0.12),
        transparent,
        rgba(255, 200, 60, 0.1),
        transparent,
        rgba(251, 146, 60, 0.12),
        transparent,
        rgba(251, 146, 60, 0.12)
    );
    filter: blur(6px);
    pointer-events: none;
    z-index: -1;
}

/* Task Card Expand */
.task-expand-area {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height 0.25s ease, opacity 0.25s ease;
}
.task-expand-area.expanded {
    max-height: 400px;
    opacity: 1;
}

/* Expand Button Icon Rotation */
.task-expand-btn .material-symbols-outlined.rotated {
    transform: rotate(180deg);
}

/* Globaler Focus-Reset fuer Form-Elemente.
   Tailwind's forms-Plugin (siehe layout.php) zeichnet einen blauen Fokus-Ring
   (#2563eb) ueber Attribut-Selektoren wie [type='text']:focus mit hoher
   Spezifitaet. Den ueberschreiben wir hier global, weil er nicht zur App-
   Optik passt (siehe STYLING.md: kein blauer Browser-Fokusrahmen).
   Tastatur-Fokus auf <button>/<a> bleibt unberuehrt. */
[type='text']:focus,
[type='email']:focus,
[type='url']:focus,
[type='password']:focus,
[type='number']:focus,
[type='date']:focus,
[type='datetime-local']:focus,
[type='month']:focus,
[type='search']:focus,
[type='tel']:focus,
[type='time']:focus,
[type='week']:focus,
[multiple]:focus,
textarea:focus,
select:focus,
input:focus,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    --tw-ring-color: transparent !important;
    --tw-ring-shadow: 0 0 #0000 !important;
    --tw-ring-offset-shadow: 0 0 #0000 !important;
    box-shadow: none !important;
    outline: none !important;
    border-color: rgba(255, 255, 255, 0.18) !important;
}

/* InlineEdit-Placeholder fuer leere editierbare Felder (Beschreibung, Anruf-Grund).
   Wird per `data-placeholder`-Attribut am Element aktiviert und erscheint nur,
   wenn der Text leer ist. WICHTIG: ::before statt textContent, sonst wuerde der
   Hinweistext beim Doppelklick in den Edit-Input wandern (Bug: "Hint im Feld"). */
[data-placeholder]:empty::before {
    content: attr(data-placeholder);
    color: rgb(100 116 139);  /* slate-500 — nur fuer den Placeholder, nicht das Feld */
    pointer-events: none;
}

/* Field-Edit — Letterpress fuer Inline-Edit-Inputs.
   Default-Look fuer JEDES editierbare Eingabefeld. Wird von components/InlineEdit
   automatisch gesetzt und sollte ueberall genutzt werden, wo Text inline editiert
   wird (siehe STYLING.md). KEIN blauer Browser-Fokusrahmen — der Letterpress-
   Hintergrund + blinkender Cursor sind die einzige Indikation des Edit-Modus. */
.field-edit {
    background: rgba(20, 20, 25, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.45),
                inset 0 -1px 0 rgba(255, 255, 255, 0.03);
    padding: 1px 6px;
    margin: 0;
    transition: background 0.15s ease, border-color 0.15s ease;
    /* Schrift/Farbe erbt vom Eltern-Element — keine Groessenaenderung */
    font: inherit;
    color: inherit;
    line-height: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    text-align: inherit;
    width: 100%;
    box-sizing: border-box;
}
.field-edit:focus,
.field-edit:focus-visible {
    outline: none;
    border-color: rgba(255, 255, 255, 0.12);
    background: rgba(20, 20, 25, 0.7);
}

/* Flat-Variante fuer InlineEdit-Felder, die bereits in einem gepolsterten
   Container sitzen (z.B. Task-Beschreibung, Anruf-Grund — beide in
   `p-4 rounded-xl border bg-...`-Boxen). Kein eigener Rahmen und keine
   Polsterung, damit nicht zwei Rahmen ineinander sichtbar werden. */
.field-edit-flat {
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    text-align: inherit;
    width: 100%;
    box-sizing: border-box;
    resize: none;
}
.field-edit-flat:focus,
.field-edit-flat:focus-visible {
    outline: none;
}

/* Checklist Radio — Letterpress / Embossed */
.checklist-radio {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: rgba(20, 20, 25, 0.8);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(255, 255, 255, 0.04);
    transition: all 0.25s ease;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.checklist-radio.checked {
    background: rgba(110, 229, 145, 0.9);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 8px rgba(110, 229, 145, 0.4), 0 0 2px rgba(110, 229, 145, 0.6);
}
.checklist-radio.checked::after {
    content: '';
    width: 7px;
    height: 7px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center/contain no-repeat;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,0.3));
}

/* Priority Radio-Buttons — Letterpress Style */
.prio-radio-btn {
    padding: 2px;
    border-radius: 50%;
    transition: transform 0.15s ease;
    line-height: 0;
}
.prio-radio-btn:hover .prio-radio {
    transform: scale(1.15);
}
.prio-radio {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: rgba(20, 20, 25, 0.8);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5), 0 1px 1px rgba(255, 255, 255, 0.04);
    transition: all 0.25s ease;
}
.prio-radio-gruen.active {
    background: rgba(110, 229, 145, 0.9);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 6px rgba(110, 229, 145, 0.5);
}
.prio-radio-gelb.active {
    background: rgba(249, 200, 0, 0.9);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 6px rgba(249, 200, 0, 0.5);
}
.prio-radio-rot.active {
    background: rgba(255, 120, 110, 0.9);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 6px rgba(255, 120, 110, 0.5);
}

/* Checklist Undo-State */
.checklist-item-pending {
    text-decoration: line-through;
    opacity: 0.4;
    transition: opacity 0.2s;
}

/* Drag & Drop */
.drag-active {
    opacity: 0.4;
    cursor: grabbing;
}

.task-drag-placeholder {
    min-height: 60px;
    border: 2px dashed rgba(110, 229, 145, 0.3);
    background: rgba(110, 229, 145, 0.05);
    border-radius: 1rem;
    transition: all 0.2s ease;
}

.drag-placeholder {
    min-height: 100px;
    border: 2px dashed rgba(110, 229, 145, 0.3);
    background: rgba(110, 229, 145, 0.05);
    border-radius: 0.75rem;
    transition: all 0.2s ease;
}

/* Aufgabe-Karte: Status-Icon mit gefuelltem Material-Symbol */
.task-status-icon {
    font-variation-settings: 'FILL' 1;
}

/* Modul-Farben fuer Einstellungen/Dangerzone-Icons */
.modul-icon-aufgaben   { color: rgba(110, 229, 145, 1); }
.modul-icon-anrufe     { color: rgba(251, 146, 60, 1); }
.modul-icon-einkauf    { color: rgba(56, 189, 248, 1); }

/*
 * Material-Symbols-Groessen
 * Googles Fonts-CSS setzt .material-symbols-outlined { font-size: 24px } unlayered.
 * Tailwind v4 legt seine Utilities in @layer utilities — layered Styles verlieren
 * im Cascade IMMER gegen unlayered. Seit dem v4-Build (a1b2ff4) greifen die
 * text-[..] Utilities daher nicht mehr auf Icons. Wir setzen die ueblichen
 * Groessen hier unlayered + mit hoeherer Spezifitaet zurueck.
 */
.material-symbols-outlined.text-\[12px\] { font-size: 12px; }
.material-symbols-outlined.text-\[13px\] { font-size: 13px; }
.material-symbols-outlined.text-\[14px\] { font-size: 14px; }
.material-symbols-outlined.text-\[15px\] { font-size: 15px; }
.material-symbols-outlined.text-\[16px\] { font-size: 16px; }
.material-symbols-outlined.text-\[18px\] { font-size: 18px; }
.material-symbols-outlined.text-sm   { font-size: 0.875rem; }
.material-symbols-outlined.text-base { font-size: 1rem; }
.material-symbols-outlined.text-lg   { font-size: 1.125rem; }
.material-symbols-outlined.text-xl   { font-size: 1.25rem; }
.material-symbols-outlined.text-2xl  { font-size: 1.5rem; }
.material-symbols-outlined.text-3xl  { font-size: 1.875rem; }
.material-symbols-outlined.text-4xl  { font-size: 2.25rem; }
.material-symbols-outlined.text-5xl  { font-size: 3rem; }
.material-symbols-outlined.text-6xl  { font-size: 3.75rem; }

/* =======================================================================
   Sidebar Collapse (nur Desktop) — Icon-Only-Modus fuer mehr Arbeitsflaeche.
   Wird per body.sidebar-collapsed geschaltet (app-shell.js), Zustand liegt
   in localStorage. Mobile (md:hidden Bottom-Nav) ist nicht betroffen.
   ======================================================================= */
@media (min-width: 768px) {
    /* Sanfte, synchrone Transitions fuer Sidebar + Main-Content, damit
       der Ausklapp-Wechsel nicht hackelt. Aside hat zwar `transition-all`
       von Tailwind (150ms), aber Main hat gar keine Transition — deshalb
       springt der Content instant. Wir ueberschreiben beide auf eine
       gemeinsame, laengere Kurve. */
    aside.md\:flex {
        transition:
            width 380ms cubic-bezier(0.4, 0, 0.2, 1),
            padding 380ms cubic-bezier(0.4, 0, 0.2, 1) !important;
        overflow-x: hidden;
    }
    main.md\:ml-80 {
        transition: margin-left 380ms cubic-bezier(0.4, 0, 0.2, 1);
    }
    body.sidebar-collapsed > aside {
        width: 5rem;
        padding-left: 0;
        padding-right: 0;
        align-items: center;
    }
    body.sidebar-collapsed > main {
        margin-left: 5rem;
    }

    /* Profilbild-Zeile: Titel + Spruch ausblenden, Bild bleibt und wird
       horizontal zentriert. */
    body.sidebar-collapsed #desktop-profilbild-container ~ div {
        display: none;
    }
    body.sidebar-collapsed aside > div:first-child {
        justify-content: center;
        margin-bottom: 2rem;
    }

    /* Nav-Buttons: quadratischer Icon-Only-Button, damit der runde
       Aktiv-Hintergrund wirklich rund bleibt (statt zum vertikalen Pill
       zu werden). */
    body.sidebar-collapsed #sidebar-modul-nav {
        align-items: center;
        overflow: hidden;
    }
    body.sidebar-collapsed #sidebar-modul-nav .nav-btn {
        width: 44px;
        height: 44px;
        padding: 0;
        gap: 0;
        justify-content: center;
    }
    body.sidebar-collapsed #sidebar-modul-nav .nav-btn > span:not(.material-symbols-outlined) {
        display: none;
    }

    /* Sidebar-Summary zusammenklappen. */
    body.sidebar-collapsed #sidebar-summary {
        display: none;
    }

    /* Collapse-Handle: schwebende Liquid-Dark-Glass Tab halb hinter der
       Sidebar-Kante. Folgt der Sidebar-Breite ueber CSS-Transition. */
    /* Sidebar-Collapse-Handle — Frosted-Glass Micro-Rail.
       Schmale vertikale Lasche, die zur Haelfte hinter der Sidebar liegt.
       Kein fetter Gradient, kein Drop-Shadow-Overkill — stattdessen echtes
       frosted glass: hoher Blur, minimale Tinting-Opacity, eine einzelne
       haarfeine Lichtkante rechts, und ein winziger Akzent-Dot der als
       "Seelen-Licht" hinter dem Chevron glimmt.
       z-index bewusst UNTER der Sidebar (z-60), damit die linke Haelfte
       verdeckt wird und nur eine schmale Glas-Kante rausschaut. */
    .sidebar-collapse-handle {
        position: fixed;
        left: 20rem;
        top: 50%;
        z-index: 55;
        width: 24px;
        height: 180px;
        margin-left: -12px;
        transform: translateY(-50%);
        display: flex;
        align-items: center;
        justify-content: flex-end;
        padding-right: 3px;
        border: none;
        border-radius: 0 10px 10px 0;
        /* Dunkler als die Sidebar — wirkt wie eine Schicht dahinter. */
        background:
            radial-gradient(
                ellipse 60% 40% at 100% 50%,
                rgba(167, 139, 250, 0.06),
                transparent 70%
            ),
            rgba(10, 12, 16, 0.92);
        /* Nur die rechte, sichtbare Kante bekommt einen Stroke — das fuehlt
           sich an wie eine echte Glaskante im Licht. */
        box-shadow:
            inset -1px 0 0 rgba(255, 255, 255, 0.18),
            inset 0 1px 0 rgba(255, 255, 255, 0.06),
            inset 0 -1px 0 rgba(255, 255, 255, 0.04),
            0 0 24px -6px rgba(0, 0, 0, 0.4);
        color: rgba(226, 232, 240, 0.6);
        cursor: pointer;
        overflow: hidden;
        transition:
            left 380ms cubic-bezier(0.4, 0, 0.2, 1),
            background 400ms ease,
            color 250ms ease,
            box-shadow 400ms ease;
    }
    /* Feine vertikale Lichtlinie an der rechten Glaskante — wandert beim
       Hover per GSAP, sorgt fuer den "lebendigen" futuristischen Touch. */
    .sidebar-collapse-handle::before {
        content: '';
        position: absolute;
        right: 0;
        top: 20%;
        height: 60%;
        width: 1px;
        background: linear-gradient(
            to bottom,
            transparent,
            rgba(255, 255, 255, 0.5) 50%,
            transparent
        );
        opacity: 0.6;
        pointer-events: none;
    }
    /* Winziger Glow-Dot hinter dem Chevron — wirkt wie ein Indikator-LED
       unter Milchglas. */
    .sidebar-collapse-handle::after {
        content: '';
        position: absolute;
        right: 9px;
        top: 50%;
        width: 16px;
        height: 16px;
        transform: translateY(-50%);
        background: radial-gradient(
            circle,
            rgba(167, 139, 250, 0.35),
            transparent 70%
        );
        filter: blur(4px);
        opacity: 0.5;
        pointer-events: none;
        transition: opacity 300ms ease, background 300ms ease;
    }
    .sidebar-collapse-handle:hover {
        background:
            radial-gradient(
                ellipse 70% 50% at 100% 50%,
                rgba(167, 139, 250, 0.12),
                transparent 70%
            ),
            rgba(0, 0, 0, 0.55);
        color: rgba(255, 255, 255, 0.95);
        box-shadow:
            inset -1px 0 0 rgba(255, 255, 255, 0.28),
            inset 0 1px 0 rgba(255, 255, 255, 0.08),
            inset 0 -1px 0 rgba(255, 255, 255, 0.05),
            0 0 32px -4px rgba(167, 139, 250, 0.25);
    }
    .sidebar-collapse-handle:hover::after {
        opacity: 1;
        background: radial-gradient(
            circle,
            rgba(192, 170, 255, 0.55),
            transparent 70%
        );
    }
    body.sidebar-collapsed .sidebar-collapse-handle {
        left: 5rem; /* folgt der eingeklappten Sidebar-Breite */
    }
    /* Icon sitzt absolut zentriert im sichtbaren 12px-Bereich (rechte
       Haelfte der 24px-Handle). Rotation wird per GSAP gesteuert, damit
       sie sich sauber mit dem Hover-Scale kombiniert. */
    .sidebar-collapse-icon {
        font-size: 14px !important;
        width: 14px;
        height: 14px;
        line-height: 14px;
        position: absolute;
        right: -1px;
        top: 50%;
        margin-top: -7px;
        z-index: 1;
        pointer-events: none;
    }
}

/* Honeypot-Felder: visuell unsichtbar, fuer Bots aber im DOM. */
.honeypot-feld {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ===== Endlos-Animationen ueber CSS (ARCHITEKTUR.md §5.4) =====
   GSAP ist nur fuer One-Shot, Endlos-Effekte laufen browser-intern. */

/* StreakBadge — sanftes Glow-Pulsieren um das Flammen-Icon, wenn Streak aktiv ist. */
@keyframes streak-glow {
    0%, 100% { filter: drop-shadow(0 0 0 rgba(251, 146, 60, 0)); }
    50%      { filter: drop-shadow(0 0 6px rgba(251, 146, 60, 0.7)); }
}
.streak-badge-icon--aktiv {
    animation: streak-glow 1.6s ease-in-out infinite;
}

/* Sidebar-Collapse-Toggle — dezentes Idle-"Atmen" nach rechts. */
@keyframes sidebar-toggle-idle {
    0%, 100% { transform: translateX(0); }
    50%      { transform: translateX(2px); }
}
.sidebar-collapse-toggle--idle {
    animation: sidebar-toggle-idle 2.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .streak-badge-icon--aktiv,
    .sidebar-collapse-toggle--idle {
        animation: none;
    }
}
