/* ═══════════════════════════════════════════════════════════════════
   Window Navigation (.wn-*) — generic left sidebar inside app windows.

   Visual reference: pages/email-inbox.php (the .email-mbx-sidebar).
   Markup is rendered by includes/WindowNav.php → WindowNav::render().
   The wrapper layout (.wn-page-flex) is injected by index.php in
   embedded mode when WindowNav::hasNavForPage($page) is true.

   DESIGN (Florian 2026-09-11, Vorschlag „Dunkel komplett / Best-of"): dunkle Fläche, blauer
   Wisch-Hover, aktiver Eintrag in Markenfarbe mit Einrücken, gestaffeltes Einblenden beim Öffnen.
   BREITE: Nutzer-Zustand je Fenster — der Griff rechts (.wn-splitter, windownav.js) setzt --wn-w.
   ═══════════════════════════════════════════════════════════════════ */

/* Layout wrapper: sidebar + main content side-by-side, full window height. */
.wn-page-flex {
    display: flex !important;
    flex-direction: row !important;
    padding: 0 !important;
    margin: 0 !important;
    height: 100vh !important;
    min-height: 100vh;
    max-height: 100vh;
    gap: 0 !important;
    align-items: stretch;
    overflow: hidden;
}
/* NUR für die alleinstehende Seite (ERP-Einbettung), NIE auf dem Desktop: dort liegt die Rail in einem Fenster,
   und diese Regel sperrte das ganze Dokument auf Viewport-Höhe mit overflow:hidden — sobald irgendein Fenster
   offen war, liess sich die Arbeitsfläche nicht mehr scrollen (Florian 12./13.09.2026: „Dashboard soll scrollbar
   sein … hast du komplett ignoriert"). Lokal fiel es nicht auf, weil beim Test kein Fenster offen war. */
body:not(.cc-desktop):has(.wn-page-flex) {
    margin: 0 !important;
    padding: 0 !important;
    overflow: hidden !important;
    height: 100vh !important;
}
html:has(> body:not(.cc-desktop) .wn-page-flex) {
    overflow: hidden !important;
    height: 100vh !important;
}
body:not(.cc-desktop):has(.wn-page-flex) .container-fluid,
body:not(.cc-desktop):has(.wn-page-flex) > .container-fluid,
body:not(.cc-desktop):has(.wn-page-flex) .row,
body:not(.cc-desktop):has(.wn-page-flex) .embedded-page-content,
body:not(.cc-desktop):has(.wn-page-flex) main.embedded-page-content {
    padding: 0 !important;
    margin: 0 !important;
    max-width: 100% !important;
    width: 100% !important;
    height: 100vh !important;
}
/* `:not(.mage-page)` is critical: `.mage-page.page-content` carries its own
   `padding: 1rem 0 0 0 !important` from mage-page.css for the top-of-page
   breathing room. Without the exclusion this rule wins by load-order and
   the page sticks to the window's top edge. */
body:not(.cc-desktop):has(.wn-page-flex) .page-content:not(.mage-page) { padding: 0 !important; margin: 0 !important; }

/* Läuft die Sidebar-Seite in einem Fenster (.cc-win-body), ist „volle Höhe" die FENSTERhöhe, nicht
   der Viewport: .cc-win-body ist ein flex:1-Kind im Spalten-Flex-Fenster → hat eine definite Höhe,
   also füllt height:100% sie exakt. 100vh (Standalone-Fall) würde übers Fenster hinausragen.
   (Diese Fenster↔Sidebar-Brücke lebt hier, weil die windownav-Sidebar IM Fenster rendert →
   windownav requires window; die Umkehrung würde einen Dependency-Zirkel erzeugen.) */
/* NUR wenn .wn-page-flex das PRIMÄRE Fenster-Layout ist (direktes Kind der Body-Wurzel), nicht wenn
   es bloss als eingebetteter Demo-Block tief drinsteckt (z.B. die Komponenten-Kitchen-Sink) — sonst
   würde das GANZE Fenster randlos und alles klebt am Rand. Deshalb Child-Kombinator `>`. */
.cc-win-body > .wn-page-flex { height: 100% !important; min-height: 0 !important; max-height: 100% !important; }
/* Body randlos + oberen ::before-Spacer aus, damit die Sidebar bis an die Fensterkanten reicht und
   voll hoch wird. Gescrollt wird intern (die main-col), nicht der ganze Body — sonst scrollt die
   „feste" Sidebar mit weg. */
.cc-win-body:has(> .wn-page-flex) { padding: 0 !important; overflow: hidden; }
.cc-win-body:has(> .wn-page-flex)::before { display: none; }

.wn-main-col {
    flex: 1 1 0;
    min-width: 0;
    overflow: auto;
    display: flex;
    flex-direction: column;
    /* Restore the horizontal breathing room that bootstrap's .col-12 used to
       provide. .page-controls and .mage-page intentionally omit their own
       side-padding (they were designed to bleed into the parent's 1rem
       padding) — without this, content sits flush against the window edge. */
    padding-left: var(--sp-7);
    padding-right: var(--sp-7);
    padding-bottom: var(--sp-7);
    /* Oberer Abstand zum Fensterrand — EINMAL hier, für jedes Rail-Fenster gleich (Vorbild Kontakte).
       Vorher setzte jedes Modul `.xx-main{padding-top:var(--sp-7)}` selbst; wer es vergass
       (Controlling, Extensions, Stimmung), klebte am Fensterkopf. */
    padding-top: var(--sp-7);
}

/* Sidebar shell — RUHIGE HELLE FLÄCHE (Florian 13.09.2026: „linke sidebar in allen windows:
   background f6f6f7, genauso wie jeder sidebar header … typo farbe entsprechend anpassen, weil man
   sonst die texte nicht mehr sieht"). Die Fläche kommt aus dem Kern-Token --chrome, damit Rail und
   Sidebar-Kopf denselben Wert tragen und das Dunkel-Thema beide zusammen umstellt.
   Die Hilfsvariablen sind die FARBROLLEN der Rail: alles darin greift auf sie zu, damit ein
   Flächenwechsel an EINER Stelle passiert und nicht in dreissig Regeln. */
.wn-sidebar {
    --wn-fg: var(--ink);                                              /* Schrift auf der Fläche */
    /* Die Fläche hebt --muted eine Stufe an: JEDER Kern-Baustein in der Leiste (Leerzustand,
       Hinweis, Kennung, Zeitangabe) wird damit lesbar, ohne dass ein Modul etwas umfärbt.
       Der Kern-Ton --muted trägt auf dieser Fläche nur Kontrast 2,35. */
    --muted: var(--grey-500);
    --wn-fg-soft: var(--grey-500);                                    /* Gruppentitel, Icons, Pfeile — NICHT --muted:
                                                                          das ist auf f6f6f7 mit Kontrast 2,35 zu blass */
    --wn-line: var(--border);
    --wn-soft: color-mix(in srgb, var(--ink) 8%, transparent);
    --wn-hover: color-mix(in srgb, var(--info) 12%, transparent);
    /* Breite: ohne gezogenen Wert gilt die Normalbreite (220, höchstens 260 — wie bisher);
       mit gezogenem Wert (--wn-w, windownav.js) steht die Rail genau so breit. */
    width: var(--wn-w, var(--sz-220));
    min-width: var(--wn-w, var(--sz-220));
    max-width: var(--wn-w, var(--sz-260));
    background: var(--chrome);
    color: var(--wn-fg);
    border-right: 0;
    overflow-y: auto;
    overflow-x: hidden;   /* der aktive Eintrag rückt ein — das darf keinen Querbalken erzeugen */
    /* Innenluft oben+unten gehört dem KERN (eine Regel für ALLE Sidebars): die Fläche klebt bündig
       an den Fensterkanten, der INHALT (erster Button/Gruppenkopf) aber nicht. Kein Modul setzt
       dafür eigenes Padding. Links 0 — die Items bringen ihr Links-Padding selbst mit. */
    padding: var(--sp-6) var(--sp-3);
    font-size:var(--fs-sm);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    scrollbar-width: thin;
    scrollbar-color: var(--wn-soft) transparent;
}
.wn-sidebar::-webkit-scrollbar { width: var(--sz-6); }
.wn-sidebar::-webkit-scrollbar-thumb { background: var(--wn-soft); }

/* Ziehgriff zwischen Rail und Inhalt (Kern-Baustein .cc-splitter; windownav.js hängt ihn an).
   Optik „grau, beim Zeigen/Ziehen orange" kommt vom layout-Kern; hier nur die Lage. */
.wn-splitter { position: relative; z-index: var(--z-raised); }
/* Im Ruhezustand trägt der Griff die FARBE DER RAIL — früher der dunkle Verlauf, seit der hellen
   Fläche eben diese (Florian 12.09.2026: „die helle Linie zerstört das Design" — der Grund bleibt
   derselbe: der Griff darf die Rail nicht zerschneiden). Beim Zeigen/Ziehen bleibt er orange wie
   überall. Zwei Klassen, damit die Regel unabhängig von der Ladereihenfolge gegen .cc-splitter aus
   dem layout-Kern gewinnt. */
.cc-splitter.wn-splitter { background: var(--chrome); opacity: 1; }
.cc-splitter.wn-splitter:hover, .cc-splitter.wn-splitter.cc-splitting { background: var(--o); }

/* "Alle"-style top block. */
.wn-all {
    padding:var(--sp-4) var(--sp-4) var(--sp-4);
    border-bottom: 1px solid var(--wn-line);
    margin-bottom:var(--sp-5);
}
.wn-all-link {
    font-weight:var(--fw-bold);
}
/* Fuss-Gruppe der Rail (z.B. „Einstellungen" ganz unten) — durch eine Linie abgesetzt. */
.wn-folders.wn-folders-foot { margin-top: var(--sp-6); border-top: 1px solid var(--wn-line); padding-top: var(--sp-3); }

/* Group block (header + items). */
.wn-group {
    padding: 0 var(--sp-4);
    margin-bottom:var(--sp-6);
}
.wn-group-head {
    display: flex;
    align-items: center;
    gap:var(--sp-3);
    padding:var(--sp-2) var(--sp-1) var(--sp-3);
    font-weight:var(--fw-heavy);
    font-size:var(--fs-2xs);
    text-transform: uppercase;
    letter-spacing:var(--tracking);
    color: var(--wn-fg-soft);
    border-bottom: 1px solid var(--wn-acc, var(--wn-line));
    margin-bottom:var(--sp-2);
}
.wn-dot {
    width:var(--sz-8);
    height:var(--sz-8);
    border-radius: 50%;
    background: var(--wn-acc, var(--muted));
    flex-shrink: 0;
}
.wn-group-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Flat list (no header). Top breathing room matches the "Alle"-block (.wn-all)
   so flat sub-navs (Ticketing, Monitoring, …) sit identically to Kontakte. */
.wn-flat {
    padding:var(--sp-4) var(--sp-4);
}
/* Sichtbarer Trenner zwischen aufeinanderfolgenden flat-Gruppen (Ticketing-Nav-Sektionen). */
.wn-flat + .wn-flat {
    border-top: 1px solid var(--wn-line);
    padding-top:var(--sp-5);
}

/* Item row. */
.wn-folders { padding:0; }   /* KEIN Links-Nudge: sonst stehen Item-Boxen um --sp-1 rechts vom Gruppen-Divider (wn-group-head-Border), der bündig am Sidebar-Innen-Padding sitzt. Beide teilen jetzt exakt das --sp-3 der .wn-sidebar. */
.wn-item {
    cursor: pointer;   /* Nav-Items sind klickbar — Kern-Verhalten, kein Modul flickt das selbst */
    /* railItem rendert ein <button> (a11y: fokussierbar + Enter/Space) — Button-Chrome zurücksetzen. */
    width: 100%;
    border: 0;
    text-align: left;
    font-family: inherit;
    display: flex;
    align-items: center;
    gap:var(--sp-3);
    padding:var(--sp-2) var(--sp-4);
    margin:var(--sp-0) 0;
    border-radius:var(--radius);
    color: var(--wn-fg);
    text-decoration: none;
    font-size:var(--fs-sm);
    /* Hover: eine blaue Tönung wischt von links herein (Hintergrundgrösse 0 → 100 %). */
    background: linear-gradient(var(--wn-hover), var(--wn-hover)) no-repeat left / 0% 100%;
    transition: background-size var(--dur-slow) ease, color var(--dur-fast), transform var(--dur) ease, box-shadow var(--dur) ease;
    position: relative;
}
.wn-item:hover {
    background-color: transparent;
    background-size: 100% 100%;
    color: var(--wn-fg);
}
.wn-item:hover i { color: var(--info); }
.wn-item.active {
    background: var(--wn-acc, var(--o));
    color: var(--surface);
    transform: translateX(var(--sp-1));
    box-shadow: var(--shadow-md);
}
.wn-item.active i { color: var(--surface); }
.wn-item i {
    color: var(--wn-fg-soft);
    width:var(--sz-14);
    text-align: center;
    flex-shrink: 0;
    font-size:var(--fs-base);
}
/* Echte App-Icons (klein) in der Rail — dieselben Bilder wie auf den App-Seiten */
.wn-app-ico {
    width:var(--sz-18);
    height:var(--sz-18);
    object-fit: contain;
    flex-shrink: 0;
    border-radius:var(--radius);
    display: block;
}
/* Farbiges Integrations-Icon (Einstellungen-Rail) — Farbe via inline style.
   Höhere Spezifität als `.wn-item > span { flex:1 }`, sonst streckt sich das
   Icon-Span zur vollbreiten Leiste statt 18px-Quadrat zu bleiben. */
.wn-item > .wn-int-ico {
    flex: 0 0 var(--sz-18);
    width:var(--sz-18);
    height:var(--sz-18);
    border-radius:var(--radius);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--surface);
    font-size:var(--fs-2xs);
}
/* Glyph weiss erzwingen — sonst greift `.wn-item i { color:var(--grey-500) }` und das
   Icon verschwindet auf der farbigen Box. */
.wn-item > .wn-int-ico i,
.wn-item.active > .wn-int-ico i { color: var(--surface); }
.wn-item-avatar {
    width:var(--sz-18);
    height:var(--sz-18);
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--grey-200);
}
.wn-item-avatar-fb {
    width:var(--sz-18);
    height:var(--sz-18);
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--grey-500);
    color: var(--surface);
    font-size:var(--fs-2xs);
    font-weight:var(--fw-heavy);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    letter-spacing:var(--tracking);
}
.wn-item > span {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Dritter Fall derselben Falle (nach .wn-count und .wn-int-ico): der Ladekreis ist ebenfalls ein
   direktes span-Kind und erbte sonst flex-grow:1. Gemessen 116 × 14 px statt 14 × 14 — als Ellipse
   mit border-radius:50% wischte der drehende Rand quer über die Einträge. spinner.css sperrt grow
   bereits selbst, `.wn-item > span` gewinnt dort aber über die Spezifität. */
.wn-item > .mage-spinner { flex: 0 0 auto; }

.wn-item > .wn-count {
    /* Higher specificity than `.wn-item > span { flex: 1 }` above —
       otherwise the count badge inherits flex-grow:1 and stretches to fill. */
    flex: 0 0 auto;
    font-size:var(--fs-2xs);
    font-weight:var(--fw-bold);
    line-height: 1.4;
    color: var(--wn-fg);
    background: var(--wn-soft);
    padding: 0 var(--sp-1);
    border-radius:var(--radius);
    min-width:var(--sz-14);
    text-align: center;
}
.wn-item.active .wn-count {
    background: var(--glass-soft);
    color: var(--surface);
}

/* Gestaffeltes Einblenden beim ERSTEN Aufbau der Rail (windownav.js setzt .wn-enter kurz) —
   nachgeladene Einträge (Zähler, Filter) springen nicht jedes Mal neu herein. */
.wn-sidebar > :nth-child(2) { --wn-gi: 1; }
.wn-sidebar > :nth-child(3) { --wn-gi: 2; }
.wn-sidebar > :nth-child(n+4) { --wn-gi: 8; }
.wn-item:nth-child(2) { --wn-ii: 1; }   .wn-item:nth-child(3) { --wn-ii: 2; }   .wn-item:nth-child(4) { --wn-ii: 3; }
.wn-item:nth-child(5) { --wn-ii: 4; }   .wn-item:nth-child(6) { --wn-ii: 5; }   .wn-item:nth-child(7) { --wn-ii: 6; }
.wn-item:nth-child(8) { --wn-ii: 7; }   .wn-item:nth-child(9) { --wn-ii: 8; }   .wn-item:nth-child(10) { --wn-ii: 9; }
.wn-item:nth-child(11) { --wn-ii: 10; } .wn-item:nth-child(12) { --wn-ii: 11; } .wn-item:nth-child(n+13) { --wn-ii: 12; }
.wn-sidebar.wn-enter .wn-item {
    animation: wn-item-in var(--dur-slow) ease both;
    animation-delay: calc((var(--wn-gi, 0) * 3 + var(--wn-ii, 0)) * 18ms);
}
@keyframes wn-item-in { from { opacity: 0; transform: translateX(calc(-1 * var(--sp-4))); } }
@media (prefers-reduced-motion: reduce) {
    .wn-sidebar.wn-enter .wn-item { animation: none; }
    .wn-item, .wn-item.active { transition: none; transform: none; }
}

/* Footer button (e.g. "Konten" in email). */
.wn-footer {
    margin-top: auto;
    padding:var(--sp-4);
    border-top: 1px solid var(--wn-line);
    background: var(--chrome);
    flex-shrink: 0;
}
.wn-footer-btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap:var(--sp-2);
    padding:var(--sp-3) var(--sp-4);
    background: transparent;
    border: 1px solid var(--border);
    border-radius:var(--radius);
    color: var(--wn-fg);
    font-size:var(--fs-sm);
    font-weight:var(--fw-bold);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--dur) ease, border-color var(--dur) ease,
                color var(--dur) ease, box-shadow var(--dur) ease, transform var(--dur-fast) ease;
}
.wn-footer-btn:hover {
    background: var(--o);
    border-color: var(--o);
    color: var(--surface);
    box-shadow:var(--shadow-md);
    text-decoration: none;
}
.wn-footer-btn:active { transform: translateY(1px); }
.wn-footer-btn i { font-size:var(--fs-md); transition: transform var(--dur) ease; }
.wn-footer-btn:hover i { transform: rotate(15deg); }

/* Compact mode for small viewports. */
@media (max-width:900px) {
    .wn-sidebar { width:var(--sz-56); min-width:var(--sz-56); max-width:var(--sz-56); }
    .wn-splitter { display: none; }
    .wn-item span,
    .wn-group-name,
    .wn-count { display: none; }
    .wn-group-head { justify-content: center; }
}

/* ── Aufklappbarer Knoten (Design::railNode): Eintrag MIT Unterebene, z.B. Kunde → seine Projekte.
   Ein Klick auf den Knoten filtert (Modul-Sache) UND klappt auf (Kern-Sache, windownav.js). ── */
.wn-node { display: block; }
.wn-node > .wn-children {
    display: none;
    margin: var(--sp-0) 0 var(--sp-2) var(--sp-6);
    border-left: 1px solid var(--wn-line);
    padding-left: var(--sp-2);
}
.wn-node.open > .wn-children { display: block; }
.wn-item-parent > .wn-caret {
    flex: 0 0 auto;
    font-size: var(--fs-2xs);
    color: var(--wn-fg-soft);
    transition: transform var(--dur-fast) ease;
    width: auto;
}
.wn-node.open > .wn-item-parent > .wn-caret { transform: rotate(90deg); }
.wn-item.active > .wn-caret { color: var(--surface); }
/* Unter-Einträge etwas kleiner — die Hierarchie muss man sehen, ohne sie zu raten. */
.wn-children > .wn-item { font-size: var(--fs-xs); padding-top: var(--sp-1); padding-bottom: var(--sp-1); }


/* Schmales Fenster: die Inhaltsspalte MUSS schrumpfen dürfen (Flex-Vorgabe ist min-width:auto),
   sonst schiebt eine breite Tabelle samt Werkzeugleiste über den Fensterrand hinaus. */
.wn-page-flex > .wn-main-col, .wn-page-flex > .wn-sidebar { min-width: 0; }
.wn-main-col > * { max-width: 100%; }

/* Kennzeichen hinter dem Label (Design::railItem ['tag'=>…]): Umgebung eines Projekts (Live/Staging/Test). */
.wn-item .wn-tag { flex: none; margin-left: var(--sp-2); font-size: var(--fs-2xs); }
.wn-item.active .wn-tag { background: color-mix(in srgb, var(--surface) 25%, transparent) !important; color: var(--surface); }

/* Klappbarer Gruppentitel (Design::railGroup ['toggle'=>true]) — der Pfeil dreht beim Zuklappen. */
.wn-group-toggle { cursor: pointer; user-select: none; }
.wn-group-toggle:hover { color: var(--wn-fg); }
.wn-group-chev { transition: transform var(--dur); flex: 0 0 auto; }
.wn-group-toggle[aria-expanded="false"] .wn-group-chev { transform: rotate(-90deg); }
/* Untergruppe (Design::railGroup ['sub'=>true]) — kleiner Titel ohne Linie, z.B. „Ordner (29)" in einem Konto. */
.wn-subgroup-head { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-2) var(--sp-1);
                    color: var(--wn-fg-soft); font-size: var(--fs-2xs); text-transform: uppercase; letter-spacing: var(--tracking); }
/* Zeilen-Aktion im Rail-Eintrag (Design::railItem ['action'=>…]) — kleines X hinter dem Zähler. */
.wn-item > .wn-item-act { flex: none; margin-left: var(--sp-1); display: inline-flex; cursor: pointer; }
.wn-item > .wn-item-act:hover i { color: var(--o); }
/* Inaktiver Eintrag (Design::railItem ['off'=>true]) — noch nicht übernommenes Programm, abgeschaltetes Modul:
   dezente Schrift; Zeigen hebt ihn wie jeden Eintrag hervor. */
.wn-item.wn-item-off:not(:hover):not(.active) { color: var(--wn-fg-soft); }
