@layer layout {
/* ══════════════════════════════════════════════════════════════════════════
   v3/shell.css — Layout der neuen Shell
   Dashboard-v3 WP6, 27.07.2026

   Liegt im Layer `layout`, also NACH `legacy`. Damit schlaegt jede Regel hier
   die Legacy-Sheets bei normalen Deklarationen - ohne ein einziges !important
   und unabhaengig von Spezifitaet. `#header{padding:0 1.5rem}` in legacy
   (1,0,0) verliert gegen `#header{padding:0 var(--sp-5)}` hier (1,0,0, aber
   spaeterer Layer). Genau dafuer ist die Layer-Ordnung da.

   NIEMALS `order:` auf .nav-tab verwenden: die von phase-v.js zur Laufzeit
   injizierten Buttons (channels, canvas) haetten order:0 und sprangen an den
   Anfang der Rail. DOM-Reihenfolge IST die Gruppenreihenfolge.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Die Dichte-Kur ──────────────────────────────────────────────────────────
   html{font-size} ist in v3 NUR noch der Legacy-Multiplikator. Die neue
   Typografie steht in absoluten px (--fs-*) und ist davon unberuehrt - das ist
   die Aufloesung der rem-Falle: nicht "die richtige Basis finden", sondern die
   neue Skala aus der Multiplikation herausnehmen.

   Bei 17px landet die dominante Legacy-Wolke im lesbaren Band:
     0.70rem (65x)  10.5px -> 11.9px
     0.72rem (55x)  10.8px -> 12.2px
     0.78rem (63x)  11.7px -> 13.3px
     0.85rem (49x)  12.8px -> 14.5px

   Unter 720px nur 16px: dort skaliert der Multiplikator auch Legacy-PADDING,
   und +13% Innenabstand ist auf 375px zu viel. Die Textgroesse bleibt dank
   px-basierter --fs-* identisch - genau die gewuenschte Asymmetrie.
   Der 2400px-Zweig neutralisiert shell-mobile.css (ex mobile.css:674), das
   dort selbst 17px setzt; in v3 ist diese Haelfte gar nicht geladen, die Regel
   steht nur zur Sicherheit. */
html { font-size: 17px; }
@media (max-width: 720px)  { html { font-size: 16px; } }
@media (min-width: 2400px) { html { font-size: 17px; } }

/* ── Grundgerüst ─────────────────────────────────────────────────────────── */
body { overflow: hidden; }

#app { display: flex; flex-direction: column; min-height: 100vh; }

#dashboard {
  display: none;                 /* shell-core.js schaltet auf flex */
  flex-direction: column;
  height: 100vh;
  height: var(--app-vh, 100vh);  /* setupKeyboardDetect in shell-core.js */
}

/* ── Topbar ──────────────────────────────────────────────────────────────────
   Deutlich ruhiger als v1: 56px, eine Haarlinie, kein Schatten. Sie traegt nur
   noch Marke, Live-Puls, Uhr und die Aktionen rechts - die Navigation ist in
   die Rail gewandert. */
#header {
  position: relative;
  /* WP10b — ueber die Pinnwand. sticky-notes.css legt Notizen auf z 150/160/190;
     bei --z-header (50) schoben sie sich vor Uhr, Suche und Umschalter. Notizen
     sollen ueber dem INHALT schweben, nicht ueber der Bedienung. 195 liegt
     darueber und weiter unter dem Modal-Layer (200). */
  z-index: 195;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  height: var(--header-h);
  padding: 0 var(--sp-5);
  padding-left: calc(var(--rail-w) + var(--sp-5));
  background: var(--surface-canvas);
  border-bottom: 1px solid var(--line-1);
  box-shadow: none;
  transition: padding-left var(--dur-4) var(--ease-standard);
}

#header .header-brand { display: flex; align-items: center; gap: var(--sp-2); }

#header .logo {
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--tr-lg);
  color: var(--text-1);
}

#header .header-right {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--text-2);
}

/* Zahlen in Mono, weil Daten. Prosa bleibt Sans. */
#header .header-stats, #header .clock { font-family: var(--font-num); }

/* Der Sparkle wird von akhilius-imagery.js zu #header-sparkle-trigger
   umgebaut und kann dabei aus dem Fluss kippen. Hier sauber einbinden. */
#header .logo-icon,
#header #header-sparkle-static,
#header #header-sparkle-trigger {
  position: relative;
  flex: 0 0 auto;
  width: 22px; height: 22px;
  object-fit: contain;
}
#header .header-sparkle-live { flex: 0 0 auto; width: 22px; height: 22px; }

/* ── Rail ────────────────────────────────────────────────────────────────────
   Fixiert, damit die Expansion den Inhalt nie umbricht: #main-content hat
   permanent margin-left: var(--rail-w), und nur das Anpinnen aendert den Token.
   Ein Token, zwei Zustaende.

   #tab-nav bleibt FLACH (Vertrag 1.2) - die Gruppen entstehen visuell ueber
   .rail-group-label als Geschwister, nicht ueber Wrapper. */
#tab-nav {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: var(--rail-w);
  padding: var(--sp-2) var(--sp-1);
  gap: 2px;
  background: var(--surface-1);
  border-right: 1px solid var(--line-1);
  border-bottom: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;   /* mobile-perfect.js:65 will horizontal scrollen */
  overscroll-behavior: contain;
  transition: width var(--dur-4) var(--ease-standard);
}

/* Gruppen-Label: im kollabierten Zustand nur ein Trenner mit Icon-Hinweis,
   im aufgeklappten eine Caps-Zeile. */
.rail-group-label {
  flex: 0 0 auto;
  margin: var(--sp-2) 0 var(--sp-1);
  padding: 0 var(--sp-2);
  font-family: var(--font-sans);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  letter-spacing: var(--tr-2xs);
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
  /* WP10b — NICHT auf height:0 kollabieren. Mit overflow:hidden wurde damit
     auch die Trennlinie im ::before weggeschnitten, und die 26 Icons standen
     als eine ununterscheidbare Kolonne da. Stattdessen nur den TEXT
     wegnehmen (font-size:0); die Linie traegt das Pseudoelement und bleibt. */
  font-size: 0;
  line-height: 0;
  transition: font-size var(--dur-2) var(--ease-standard);
}
.rail-group-label:first-child { margin-top: 0; }

/* Rail-Item. Kollabiert nur das Icon, zentriert, 44px Touch-Target. */
#tab-nav .nav-tab {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 40px;
  padding: 0 var(--sp-2);
  border: 0;
  border-bottom: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text-2);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-normal);
  letter-spacing: 0;
  text-transform: none;     /* v1 hatte uppercase */
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-standard),
              color var(--dur-1) var(--ease-standard);
}

#tab-nav .nav-tab .tab-icon {
  flex: 0 0 auto;
  width: 18px; height: 18px;
  margin: 0 auto;            /* kollabiert: zentriert */
  transition: margin var(--dur-2) var(--ease-standard);
}

/* Label. In v1 war das ein nackter Textknoten hinter dem SVG; der Generator
   wickelt ihn in dieses Span, weil CSS einen Textknoten nicht adressieren kann
   und im kollabierten Zustand sonst der erste Buchstabe durchblutet. */
#tab-nav .nav-tab .v3-rail-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0;
  width: 0;
  transition: opacity var(--dur-2) var(--ease-standard);
}

#tab-nav .nav-tab:hover { background: var(--surface-2); color: var(--text-1); }

/* Aktiv: Flaeche plus ein GERADER 2px-Balken links. Ersetzt die wellige
   clip-path-Underline aus v1 (index.html:255) - v4 will gerade Linien. */
#tab-nav .nav-tab.active {
  background: var(--accent-wash);
  color: var(--accent-1);
  font-weight: var(--fw-medium);
}
#tab-nav .nav-tab.active::after {
  content: '';
  position: absolute;
  left: 0; top: 6px; bottom: 6px;
  width: 2px;
  border-radius: var(--r-pill);
  background: var(--accent-1);
  clip-path: none;           /* Legacy-Wellenlinie explizit abbestellen */
  height: auto;
  animation: none;
}

/* Aufgeklappt (gepinnt): Labels sichtbar, Icons linksbuendig. */
:root[data-rail="pinned"] { --rail-w: var(--rail-w-open); }
:root[data-rail="pinned"] .rail-group-label { font-size: var(--fs-2xs); line-height: 1.4; }
:root[data-rail="pinned"] #tab-nav .nav-tab .tab-icon { margin: 0; }
:root[data-rail="pinned"] #tab-nav .nav-tab { padding: 0 var(--sp-3); }
:root[data-rail="pinned"] #tab-nav .nav-tab .v3-rail-label { opacity: 1; width: auto; }

/* ── Inhaltsfläche ───────────────────────────────────────────────────────── */
#main-content {
  flex: 1 1 auto;
  position: relative;
  min-height: 0;
  margin-left: var(--rail-w);
  overflow: hidden;
  transition: margin-left var(--dur-4) var(--ease-standard);
}

.tab-view {
  display: none;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--pad-view);
  animation: none;           /* v1 hatte fadeIn 200ms */
}
.tab-view.active { display: block; }

/* Legacy-Sheets setzen auf .tab-view.active > * eine gestaffelte
   Entry-Animation mit opacity-Startwert. Ohne laufende Animation bliebe der
   Inhalt unsichtbar - deshalb hier explizit auf sichtbar. */
.tab-view.active > * { opacity: 1; transform: none; animation: none; }

/* Lesebreite: der Grund, warum Perplexity ruhig wirkt. Container statt
   randlos volle Breite. */
.tab-view > .v3-container { max-width: var(--measure-wide); margin-inline: auto; }

/* ── Mobile: die Rail ist keine Rail ────────────────────────────────────────
   Unter 720px wird sie zur Bottom-Bar. Der Daumen erreicht unten, nicht links,
   und 26 Eintraege sind auf 375px ein Listen-, kein Leistenproblem.
   Die vollstaendige Interaktion (Sheet, Flyout) kommt in WP7. */
@media (max-width: 720px) {
  #tab-nav {
    top: auto; left: 0; right: 0; bottom: 0;
    flex-direction: row;
    width: auto;
    height: var(--bottombar-h);
    padding: var(--sp-1) var(--sp-2);
    padding-bottom: max(var(--sp-1), env(safe-area-inset-bottom));
    gap: var(--sp-1);
    border-right: 0;
    border-top: 1px solid var(--line-1);
    overflow-x: auto;
    overflow-y: hidden;
  }
  .rail-group-label { display: none; }
  #tab-nav .nav-tab { width: auto; min-width: 44px; min-height: 44px; }
  #tab-nav .nav-tab .tab-icon { margin: 0 auto; }
  #tab-nav .nav-tab.active::after { left: 6px; right: 6px; top: auto; bottom: 0;
                                    width: auto; height: 2px; }
  #header { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  #main-content { margin-left: 0; margin-bottom: var(--bottombar-h); }
}

/* ── Hover-Aufklappen ───────────────────────────────────────────────────────
   Reines CSS und bewusst OHNE Reflow: die Breite wird auf #tab-nav gesetzt,
   NICHT auf dem Token --rail-w. #main-content behaelt seinen margin-left, die
   Rail ueberlagert also den Inhalt. Nur das Anpinnen aendert den Token, und
   dann folgt der Inhalt absichtlich.

   Intent-Verzoegerung ohne JS: die Grundregel hat 250ms Verzoegerung (Verlassen),
   der Hover-Zustand 150ms (Betreten). Damit flackert nichts, wenn die Maus die
   Rail nur diagonal durchquert. */
#tab-nav {
  transition: width var(--dur-3) var(--ease-standard) 250ms;
}
#tab-nav:hover,
#tab-nav:focus-within {
  width: var(--rail-w-open);
  box-shadow: var(--shadow-2);
  transition-delay: 150ms;
}
#tab-nav:hover .rail-group-label,
#tab-nav:focus-within .rail-group-label { font-size: var(--fs-2xs); line-height: 1.4; }
#tab-nav:hover .nav-tab,
#tab-nav:focus-within .nav-tab { padding: 0 var(--sp-3); }
#tab-nav:hover .nav-tab .tab-icon,
#tab-nav:focus-within .nav-tab .tab-icon { margin: 0; }
#tab-nav:hover .nav-tab .v3-rail-label,
#tab-nav:focus-within .nav-tab .v3-rail-label { opacity: 1; width: auto; }

/* Im kollabierten Zustand trennt eine Haarlinie die Gruppen, damit die 26
   Icons nicht als eine Kolonne verschwimmen. */
.rail-group-label::before {
  content: '';
  display: block;
  height: 1px;
  margin: 0 calc(var(--sp-1) * -1) var(--sp-2);
  background: var(--line-1);
}
#tab-nav:hover .rail-group-label::before,
#tab-nav:focus-within .rail-group-label::before,
:root[data-rail="pinned"] .rail-group-label::before { margin-bottom: var(--sp-1); }
.rail-group-label:first-child::before { display: none; }

/* Der kollabierte Zustand darf die Trennlinien zeigen, obwohl das Label
   ausgeblendet ist - deshalb Hoehe 0 nur fuer den TEXT, nicht fuer das ::before.
   (opacity/height stehen in shell.css auf .rail-group-label selbst; hier wird
   die Linie ueber ein Pseudoelement getragen, das davon unberuehrt bleibt.) */
.rail-group-label { display: block; }

/* ── Pin-Knopf ──────────────────────────────────────────────────────────────
   Sitzt bewusst NICHT in #tab-nav: der Container muss flach bleiben und nur
   .nav-tab plus Gruppen-Labels als direkte Kinder haben, sonst zaehlt die
   Flachheits-Zusicherung falsch und phase-v.js koennte daneben einfuegen. */
.v3-rail-pin {
  position: fixed;
  left: var(--sp-1);
  bottom: var(--sp-2);
  z-index: calc(var(--z-rail) + 1);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: calc(var(--rail-w) - var(--sp-2));
  min-height: 34px;
  padding: 0 var(--sp-2);
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text-3);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  cursor: pointer;
  overflow: hidden;
  white-space: nowrap;
  transition: background var(--dur-1) var(--ease-standard),
              color var(--dur-1) var(--ease-standard),
              width var(--dur-3) var(--ease-standard);
}
.v3-rail-pin svg { flex: 0 0 auto; margin: 0 auto; }
.v3-rail-pin .v3-rail-label { opacity: 0; width: 0; overflow: hidden; }
.v3-rail-pin:hover { background: var(--surface-2); color: var(--text-1); }
.v3-rail-pin[aria-pressed="true"] { color: var(--accent-1); }
:root[data-rail="pinned"] .v3-rail-pin { width: calc(var(--rail-w-open) - var(--sp-2)); }
:root[data-rail="pinned"] .v3-rail-pin svg { margin: 0; }
:root[data-rail="pinned"] .v3-rail-pin .v3-rail-label { opacity: 1; width: auto; }
@media (max-width: 720px) { .v3-rail-pin { display: none; } }

/* ── Ask-Bar ────────────────────────────────────────────────────────────────
   Das visuelle Zentrum der Startseite. Sitzt ganz oben in #tab-overview, VOR
   dem Editorial-Hero - injiziert von v3/askbar.js, damit v1 sie nicht bekommt. */
/* WP10b — die Leiste teilt sich die Container-Breite mit dem Inhalt darunter
   und sitzt an DERSELBEN linken Kante. Vorher war sie auf --measure zentriert,
   der Inhalt auf --measure-wide: zwei verschiedene linke Kanten, was als
   Fehlausrichtung liest. Eine durchgehende Kante ist der eigentliche
   Perplexity-Griff. */
.v3-ask-wrap {
  max-width: var(--measure-wide);
  margin: 0 auto var(--sp-8);
  padding-top: var(--sp-4);
}
.v3-ask, .v3-chips { max-width: var(--measure); }

.v3-ask {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  min-height: var(--askbar-h);
  padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-xl);
  box-shadow: none;
  transition: border-color var(--dur-2) var(--ease-standard),
              box-shadow var(--dur-2) var(--ease-standard);
}
.v3-ask:focus-within {
  border-color: var(--accent-line);
  box-shadow: var(--shadow-focus);
}

.v3-ask-input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 38px;
  max-height: 132px;
  padding: var(--sp-2) 0;
  border: 0;
  background: transparent;
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-md);
  resize: none;
  outline: none;
  overflow-y: auto;
}
.v3-ask-input::placeholder { color: var(--text-3); }

.v3-ask-send {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 36px; height: 36px;
  border: 0;
  border-radius: var(--r-md);
  background: var(--accent-1);
  color: var(--accent-on);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-standard);
}
.v3-ask-send:hover { background: var(--accent-2); }

.v3-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.v3-chip {
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line-1);
  border-radius: var(--r-pill);
  background: var(--surface-1);
  color: var(--text-2);
  font-family: var(--font-sans);
  font-size: var(--fs-xs);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-standard),
              color var(--dur-1) var(--ease-standard);
}
.v3-chip:hover { border-color: var(--accent-line); color: var(--text-1); }

@media (max-width: 720px) {
  .v3-ask-wrap { margin-bottom: var(--sp-5); }
  .v3-chips { overflow-x: auto; flex-wrap: nowrap; padding-bottom: var(--sp-1); }
  .v3-chip { flex: 0 0 auto; }
}


/* ── Morphologie: Gestalt aus Zustand (docs/dashboard/MORPHOLOGIE.md) ───────
   Keine eigene Farbe, kein eigener Farbkreis - ausschliesslich die
   Akzentfamilie. Bringt sie eine neue Farbe mit, ist sie wieder ein Etikett.
   Sitzt im Header-Brand neben dem Sparkle; der Rail-Fuss aus dem Konzept
   existiert nicht (Rail laeuft auf jedem Schirm ueber, gemessen 30.07.). */
.v3-morph {
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  display: block;
  /* Die Form darf ueber ihre Box hinausragen - bei hoher Unruhe franst der
     Rand aus, und das soll man sehen, statt es abzuschneiden. */
  overflow: visible;
  opacity: 0.9;
}
.v3-morph svg { display: block; overflow: visible; }
.v3-morph-path {
  /* Weder Fuellung noch Schatten: die Aussage steckt in der KONTUR.
     KEIN non-scaling-stroke: die Strichstaerke traegt die Gedaechtnisdichte,
     und die ist PROPORTIONAL gemeint - wie schwer die Linie im Verhaeltnis
     zur Form ist. In Bildschirmpixeln fixiert war sie bei 26 px knapp
     viermal zu dick (gemessen: 3,17 px auf 26 px, die Form wurde zum
     Klumpen) und bei 200 px zu duenn. In viewBox-Einheiten stimmt das
     Verhaeltnis bei jeder Groesse. */
  transition: stroke var(--dur-3) var(--ease-standard);
}
@media (max-width: 720px) {
  /* Auf dem Telefon ist der Header knapp; die Gestalt ist Beiwerk und weicht
     den Bedienelementen. */
  .v3-morph { display: none; }
}


/* ── ANMELDEMASKE: zwei Defekte, beide breitenunabhaengig ───────────────────
   shell-core.js:64 setzt display:flex INLINE - damit gilt der Standard
   flex-direction:row, und die neun Kinder legen sich nebeneinander (zusammen
   1194 px). Am Desktop bricht dadurch der Titel mitten im Wort um, auf dem
   Telefon lagen Passwortfeld, Token-Feld und Knopf ausserhalb des Schirms.
   Der Inline-Stil setzt nur `display`; `flex-direction` bleibt frei. */
#login-screen {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
}
#login-screen > input,
#login-screen > button,
#login-screen > #login-error {
  width: 100%;
  max-width: 340px;
}
#login-screen h1, #login-screen p { text-align: center; }

/* #login-error hat beim ersten Laden KEINEN Inline-Stil, also galt der
   Standard display:block: "Benutzername oder Passwort falsch." stand da,
   bevor jemand etwas eingegeben hatte. shell-core.js steuert die Zeile per
   Inline-Stil (:79 aus, :90/:102 an) und schlaegt diese Regel damit korrekt. */
#login-error { display: none; }

}
