/* ============================================================
   vault-theme.css — Vault Design System "Candy Apple"
   Retro-modern (50er–70er Automotive), hell + dunkel, 2 Dichtestufen.
   Signatur: #E8452D
   Einbinden: <link rel="stylesheet" href="/vault-theme.css"> als ERSTES
   Stylesheet, danach app-eigene Regeln. Die alten Token-Namen (--bg,
   --accent, --panel, --tx, --text-primary …) sind bewusst mit-definiert,
   damit bestehende Apps ohne Umschreiben die neue Palette bekommen.
   Umschalter: <html data-theme="light|dark" data-density="comfort|compact">
   ============================================================ */

/* ---- Schriften -------------------------------------------------
   Archivo, Instrument Sans, DM Mono (Google Fonts, OFL) liegen selbst gehostet
   in /fonts/ — kein externer Request, funktioniert offline und im Flugmodus.
   Subsets latin / latin-ext / vietnamesisch, erzeugt aus der Google-Fonts-CSS.
   Fehlt eine Datei, greift automatisch der System-Fallback aus den Stacks
   weiter unten.                                                  */
@font-face{font-family:"Archivo";font-style:normal;font-weight:400 900;font-stretch:62% 125%;font-display:swap;src:url(/fonts/Archivo-400900-viet.woff2) format('woff2');unicode-range:U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB}
@font-face{font-family:"Archivo";font-style:normal;font-weight:400 900;font-stretch:62% 125%;font-display:swap;src:url(/fonts/Archivo-400900-latinext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Archivo";font-style:normal;font-weight:400 900;font-stretch:62% 125%;font-display:swap;src:url(/fonts/Archivo-400900-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/DMMono-400-latinext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/DMMono-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/DMMono-500-latinext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"DM Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/DMMono-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:400 700;font-stretch:100%;font-display:swap;src:url(/fonts/InstrumentSans-400700-latinext.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
@font-face{font-family:"Instrument Sans";font-style:normal;font-weight:400 700;font-stretch:100%;font-display:swap;src:url(/fonts/InstrumentSans-400700-latin.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

:root{
  /* Flächen */
  --bg:#F2ECE1; --surface:#FFFCF6; --sunken:#EDE5D8; --sunken2:#F8F3EA;
  --bd:#E5DACA; --bd-soft:#F3EBDF; --field-bd:#C7BCAB;
  /* Schrift
     --mut/--mut2 sind die gedämpften Töne (Beschriftungen, Zähler, Zeitangaben,
     Platzhalter). Sie standen bis 14.08.2026 auf #8E8377/#9C9083 und erreichten
     damit auf --sunken nur 2,97:1 bzw. 2,50:1 — WCAG AA verlangt für Schrift
     unter 18,66 px aber 4,5:1. Da beide fast ausschließlich KLEINE Schrift
     tragen, war das quer durch alle Apps der häufigste Kontrastfehler.
     Die Werte hier halten 4,5:1 auf allen vier Flächen (bg/surface/sunken/
     sunken2). Der Preis: zwischen --mut und --mut2 liegt nur noch ein Hauch —
     unter AA ist für zwei Dämpfungsstufen kein Platz. Wer stärker dämpfen
     will, macht die Schrift größer, nicht blasser. */
  --ink:#1B1613; --ink2:#5A5049; --mut:#6A6259; --mut2:#6E665D;
  /* Signatur + Status
     --signal ist EINSTELLBAR: vault-accent.js überschreibt die vier
     Signal-Token (und --on-signal) als Inline-Stil auf <html>, sobald
     eine eigene Farbe gewählt wurde. Die Werte hier sind die Vorgabe
     „Candy Apple" und gelten, solange nichts umgestellt ist.
     --signal-rgb ist dasselbe Rot als „r,g,b" — für die Stellen, an
     denen eine eigene Deckkraft gebraucht wird: rgba(var(--signal-rgb),.14).
     --on-signal ist die Schrift AUF der Signalfarbe; sie kippt auf
     Dunkel, sobald Weiß auf der gewählten Farbe unlesbar würde. */
  /* --signal-deep ist die Schrift-Variante; #C4331D blieb mit 4,38:1 knapp
     unter AA, daher minimal nachgedunkelt. */
  --signal:#E8452D; --signal-deep:#C0321C; --signal-soft:rgba(232,69,45,.10);
  --signal-rgb:232,69,45; --on-signal:#FFF9F2;
  /* Gefüllte Fläche, auf der die Schrift WEISS bleiben soll — so weit
     nachgedunkelt, dass 4,5:1 stehen. Für Flächen, die nicht auf die
     Schriftumkehr von --on-signal umstellen dürfen (VaultShare-Gästeseite).
     ⚠️ Das ist das Token für JEDE gefüllte Fläche, die Text trägt.
     --signal selbst ist eine FLÄCHENfarbe (3:1 für Nicht-Text): mit
     --on-signal darauf stehen nur 3,78:1, also unter AA. Und --signal-deep
     ist die SCHRIFT-Variante — im Dunkeln ist sie heller als --signal
     (#F2694F) und als Unterlage mit 2,91:1 noch schlechter. Nur
     --signal-solid ist gegen die Schrift gerechnet statt gegen die Seite
     und hält deshalb in BEIDEN Themen. Gemessen am 21.09.2026. */
  --signal-solid:#B45530; --signal-solid-hover:#9E4523;
  /* Die Schrift auf --signal-solid. Bleibt IMMER hell, in beiden Themen —
     anders als --on-signal, das auf Dunkel kippt, sobald Weiß auf der
     gewählten Signalfarbe unlesbar würde. Genau dieses Kippen wäre hier
     falsch: --signal-solid ist gegen die HELLE Schrift nachgedunkelt, eine
     dunkle Schrift darauf ergäbe dunkel auf dunkel (bei einem gelben
     Akzent gemessene 3,69:1). Deshalb ein eigenes Token statt --on-signal. */
  --on-solid:#FFF9F2;
  --ok:#2E7D53; --warn:#C98A16; --danger:#C0281B;
  /* Statusfarben als SCHRIFT. --ok und --warn sind für Flächen gemacht
     (Punkte, Bänder, gefüllte Plaketten) und halten als Text auf hellem
     Grund nur 4,02:1 bzw. 2,36:1 — Ocker auf Creme ist der schlechteste
     Fall im ganzen Theme. Deshalb dieselbe Trennung wie bei --signal /
     --signal-deep: Fläche behält den satten Ton, Schrift nimmt den tiefen.
     Im dunklen Modus sind die Grundtöne als Schrift schon über AA, dort
     zeigen die -text-Token einfach auf sie. */
  --ok-text:#2B744D; --warn-text:#8A5F0F; --danger-text:var(--danger);
  /* Material — flach, kein Farbverlauf */
  --chrome:#FFFCF6;
  --grain:repeating-linear-gradient(0deg,rgba(27,22,19,.022) 0 1px,transparent 1px 3px);
  --shadow:rgba(27,22,19,.05); --shadow-card:0 1px 2px rgba(27,22,19,.05);
  --shadow-lift:0 6px 18px rgba(27,22,19,.10); --shadow-modal:0 14px 40px rgba(27,22,19,.20);
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.7);
  /* Form */
  --r-card:14px; --r-field:10px; --r-pill:999px;
  --pad-card:14px; --gap:10px; --fs-body:13.5px; --fs-title:13.5px; --ctl-h:38px;
  /* Typo-Stacks */
  --font-display:'Archivo','Archivo Expanded','Helvetica Neue',Helvetica,Arial,sans-serif;
  --font-ui:'Instrument Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --font-mono:'DM Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  /* --- Alt-Token (Kompatibilität mit den bestehenden Apps) --- */
  --bg-sec:var(--sunken); --card:var(--surface); --panel:var(--surface); --panel2:var(--sunken);
  --bd-light:var(--bd-soft); --accent:var(--signal); --acc:var(--signal);
  --accent-hover:var(--signal-deep); --accent-soft:var(--signal-soft);
  --tx:var(--ink); --text-primary:var(--ink); --text-secondary:var(--ink2); --text-muted:var(--mut);
  --bg-primary:var(--bg); --bg-secondary:var(--sunken); --bg-card:var(--surface);
  --border:var(--bd); --border-light:var(--bd-soft); --red:var(--danger);
  --shadow-hover:rgba(27,22,19,.10); --shadow-lift-legacy:var(--shadow-lift);
  color-scheme:light;
}
[data-theme="dark"]{
  --bg:#151210; --surface:#1F1A17; --sunken:#1A1512; --sunken2:#251E1A;
  --bd:#332B25; --bd-soft:#2A2320; --field-bd:#43382F;
  /* --mut/--mut2: siehe :root — im Dunkeln aufgehellt statt nachgedunkelt,
     kritisch ist hier die HELLSTE Fläche (--sunken2). */
  --ink:#F6F0E7; --ink2:#BCB1A4; --mut:#948B81; --mut2:#8C857C;
  --signal:#E8452D; --signal-deep:#F2694F; --signal-soft:rgba(232,69,45,.16);
  --signal-rgb:232,69,45; --on-signal:#FFF9F2;
  /* ⚠️ Der Hover geht auch im Dunkeln nach UNTEN, nicht nach oben. Aufhellen
     wäre hier die gewohnte Geste, aber --signal-solid ist bereits so weit
     nachgedunkelt, dass die helle Schrift gerade 4,69:1 hält — jede Stufe
     heller frisst genau diesen Rest auf (das frühere #C4684A: 3,70:1, unter
     AA, und das im Zustand, den man aktiv ansteuert). Dunkler bleibt lesbar
     und ist als Rückmeldung genauso deutlich. Gemessen am 21.09.2026. */
  --signal-solid:#B45530; --signal-solid-hover:#9E4523;
  --on-solid:#FFF9F2;
  --ok:#4FA97A; --warn:#DBA83A; --danger:#E8452D;
  /* Im Dunkeln tragen die Grundtöne als Schrift schon 5,7:1 bzw. 7,6:1 —
     hier braucht es keine eigene Variante. --danger-text nimmt --signal-deep,
     weil --danger (#E8452D) auf --sunken2 nur 4,16:1 hält. */
  --ok-text:var(--ok); --warn-text:var(--warn); --danger-text:var(--signal-deep);
  --chrome:#251E1A;
  --grain:repeating-linear-gradient(0deg,rgba(255,255,255,.014) 0 1px,transparent 1px 3px);
  --shadow:rgba(0,0,0,.4); --shadow-card:0 1px 2px rgba(0,0,0,.3);
  --shadow-lift:0 6px 18px rgba(0,0,0,.45); --shadow-modal:0 14px 40px rgba(0,0,0,.55);
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.05);
  color-scheme:dark;
}
[data-density="compact"]{
  --pad-card:10px; --gap:7px; --fs-body:12.5px; --fs-title:12.5px; --ctl-h:34px;
  --r-card:11px;
}
/* ---- Lesbarkeit: Untergrenze 14 px (30.09.2026) ----------------------------
   Bis hierhin trugen Beschriftungen, Plaketten, Spaltenköpfe und Metazeilen
   8,5–11,5 px, Knöpfe und Felder 12,5–13 px. Über alle Apps gemessen lag in
   den meisten der größte Teil der Schrift unter 14 px (Dashboard 333 von 433
   Textstellen, Mini-CRM alle 49). Yannick ist sehbehindert, seine Regel ist
   ≥ 14 px — und die einzige App, die sie hielt (Habits, seit 16.09.2026), ist
   die, von der er sagt: „passt".
   Deshalb tragen die kleinen Größen in diesem Theme ein Token MIT RÜCKFALL,
   `font-size:var(--fs-label,10px)`. Gesetzt werden die Tokens nur hier: in der
   Dichte „Kompakt" und im Vault-Browser (Yannicks Wunsch: dort nichts anfassen,
   vault-shell.js setzt data-vs-app) bleiben sie leer — dort gilt exakt der
   alte Wert. Rangfolge ohne Größe: Gewicht, Versalien, Farbe. Mono-Versalien
   bekommen weniger Sperrung (--ls-label), sonst wachsen sie doppelt in die
   Breite. App-eigenes CSS mit kleineren Werten zieht jede App selbst nach. */
html:not([data-density="compact"]):not([data-vs-app="vault-browser"]){
  --fs-body:15px; --fs-title:15px;
  --fs-ui:14px; --fs-meta:14px; --fs-label:14px; --fs-h3:14px;
  --ls-label:.05em;
  /* Untergrenze für App-eigenes CSS: dort steht jede kleinere Angabe als
     `font-size:max(11px,var(--fs-min,0px))` — leer (Kompakt, Vault-Browser)
     ergibt das exakt den alten Wert. Umgestellt am 30.09.2026 in 58 Apps. */
  --fs-min:14px;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
body{
  margin:0;font-family:var(--font-ui);font-size:var(--fs-body);color:var(--ink);
  background-color:var(--bg);background-image:var(--grain);
  -webkit-font-smoothing:antialiased;transition:background-color .2s,color .2s;
}
a{color:var(--signal-deep);text-decoration:none}
a:hover{color:var(--signal)}
::selection{background:var(--signal-solid);color:var(--on-solid)}
:focus-visible{outline:2px solid var(--signal);outline-offset:2px}

/* Display-Typo: Kühlergrill-Wortmarke */
h1,h2,h3,.display{font-family:var(--font-display);font-stretch:118%;font-weight:800;
  text-transform:uppercase;letter-spacing:-.01em;line-height:1;margin:0}
h1{font-size:22px} h2{font-size:15px;letter-spacing:.02em} h3{font-size:var(--fs-h3,13px);letter-spacing:.02em}
.top h1 .dot,h1 .dot{color:var(--signal)}
.stripe{display:flex;gap:3px;align-items:center}
.stripe i{display:block;height:3px;background:var(--signal)}
.stripe i:first-child{width:34px} .stripe i+i{width:14px}
.mono,.num{font-family:var(--font-mono);font-weight:500}
.label{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10px);letter-spacing:var(--ls-label,.14em);
  text-transform:uppercase;color:var(--mut)}

/* --- Fließtext-Bereiche: .v-prose ------------------------------------------
   Die Wortmarken-Typografie oben gilt für die OBERFLÄCHE. Wo Nutzer-Inhalte
   gerendert werden (Markdown aus dem Vault, E-Mail-Text, Notizvorschau), sind
   Überschriften ganze Sätze — und „keine Versalien für Sätze" ist Grundregel 01.
   Solche Container bekommen .v-prose (oder mappen ihren eigenen Selektor auf
   dieselben Werte). Referenz: .v-doc benutzt es bereits.                    */
.v-prose h1,.v-prose h2,.v-prose h3,.v-prose h4,.v-prose h5,.v-prose h6{
  font-family:var(--font-ui);font-stretch:normal;text-transform:none;
  letter-spacing:-.01em;line-height:1.3}

/* Steuerelemente */
button,input,select,textarea{font-family:inherit}
/* min-height wie bei den Feldern weiter unten: ein Knopf mit fester Höhe
   drückt seine Beschriftung heraus, sobald die Schrift wächst (bei 20 px
   Schrift standen 216 Knöpfe quer durch den Vault über ihrer eigenen Pille).
   .icon-btn behält bewusst height — der ist quadratisch und trägt nur ein
   Symbol, dort wäre eine wachsende Höhe ohne wachsende Breite falsch.      */
.btn-ghost,.btn,.btn-primary{display:inline-flex;align-items:center;gap:7px;min-height:var(--ctl-h);padding:0 15px;
  border-radius:var(--r-pill);border:1px solid var(--bd);background:var(--chrome);color:var(--ink2);
  font-weight:600;font-size:var(--fs-ui,12.5px);cursor:pointer;flex:none;white-space:nowrap}
.btn svg,.btn-ghost svg,.btn-primary svg{width:15px;height:15px;flex:none}
.btn-ghost:hover,.btn:hover{color:var(--ink);border-color:var(--field-bd)}
.btn-primary{border:0;background:var(--signal-solid);color:var(--on-solid);font-weight:700;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
.btn-primary:hover{background:var(--signal-solid-hover);color:var(--on-solid)}
.icon-btn{width:var(--ctl-h);height:var(--ctl-h);display:inline-flex;align-items:center;justify-content:center;
  padding:0;flex:none;border-radius:var(--r-pill);border:1px solid var(--bd);background:var(--chrome);
  color:var(--ink2);cursor:pointer}
.icon-btn:hover{color:var(--ink);border-color:var(--field-bd)}
.icon-btn svg{width:17px;height:17px}
.theme-toggle .icon-sun{display:none}
[data-theme="dark"] .theme-toggle .icon-moon{display:none}
[data-theme="dark"] .theme-toggle .icon-sun{display:block}
#syncBadge{font-family:var(--font-mono)!important;font-size:var(--fs-label,10px)!important;letter-spacing:var(--ls-label,.08em);
  text-transform:uppercase;font-weight:500!important}

/* ⚠️ min-height, NIE height. Diese eine Zeile war der häufigste sichtbare
   Fehler im ganzen Vault: die Apps setzen fast alle ein eigenes SENKRECHTES
   Polster auf ihre Felder (typisch padding:10px 12px), überschreiben damit das
   Polster von hier, lassen die Höhe aber stehen. Bei fester Höhe bleibt dann
   38 − 2 Rahmen − 20 Polster = 16 px Inhaltskasten, während eine Textzeile
   18 px braucht — das Klappmenü schneidet seinen Text unten ab, ohne eine
   Fehlermeldung. Und weil die Höhe in Pixeln festgenagelt ist, die Schrift aber
   wächst, wird es mit jeder Vergrößerung schlimmer: bei 20 px Schrift fehlen
   8 von 24 px, also das untere Drittel der Zeile. Mit min-height wächst der
   Kasten mit — das zusätzliche Polster macht das Feld höher statt den Text
   unlesbar. Gemessen am 17.09.2026: 231 Felder auf 36 Seiten hingen hier dran.
   Bewacht von der Testgruppe `felder` in web/tests/portal.test.js.            */
input[type=text],input[type=search],input[type=password],select,textarea{
  min-height:var(--ctl-h);padding:0 13px;border-radius:var(--r-field);border:1px solid var(--field-bd);
  background:var(--surface);color:var(--ink);font-size:var(--fs-ui,13px);outline:none;box-shadow:inset 0 1px 2px var(--shadow)}
/* min-height:0 statt des früheren height:auto — hält das Verhalten von
   textarea bitgleich wie vorher (die Höhe kommt aus `rows` bzw. der App).   */
textarea{min-height:0;padding:10px 13px}
input:focus,select:focus,textarea:focus{border-color:var(--signal)}
input::placeholder{color:var(--mut2)}

/* Suchfeld */
.search{position:relative;margin-bottom:14px}
.search input{width:100%;min-height:42px;padding-left:42px;border-radius:var(--r-pill);border-color:var(--bd)}
.search .ic{position:absolute;left:15px;top:50%;transform:translateY(-50%);color:var(--mut);display:flex}
.search .ic svg{width:15px;height:15px}

/* Segmentierter Schalter */
.seg{display:inline-flex;flex:none;gap:2px;padding:3px;border-radius:var(--r-pill);background:var(--sunken);border:1px solid var(--bd)}
.seg button{border:0;background:transparent;color:var(--mut);cursor:pointer;white-space:nowrap;
  min-height:calc(var(--ctl-h) - 8px);padding:0 13px;border-radius:var(--r-pill);
  font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,11px);letter-spacing:var(--ls-label,.06em);text-transform:uppercase}
.seg button.active{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-card)}

/* Sektionslabel mit Haarlinie */
.sec{display:flex;align-items:center;gap:9px;margin:22px 0 11px;
  font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10px);letter-spacing:var(--ls-label,.14em);
  text-transform:uppercase;color:var(--mut)}
.sec::after{content:"";flex:1;height:1px;background:var(--bd)}

/* Chips / Badges */
.badge{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);letter-spacing:var(--ls-label,.06em);
  text-transform:uppercase;color:var(--mut);background:var(--sunken);border-radius:4px;padding:2px 7px}
.badge.signal{color:var(--signal-deep);background:var(--signal-soft)}

/* Banner / Hinweise */
/* Schrift dunkel, das Signal tragen Rahmen und Tönung: --signal-deep auf
   --signal-soft hielt nur 4,26:1 (unter AA), gemessen am 30.09.2026. */
.banner{background:var(--signal-soft);border:1px solid var(--signal);color:var(--ink);
  border-radius:12px;padding:12px 14px;font-size:var(--fs-ui,12.5px);margin-bottom:18px}
.banner a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--signal);text-decoration-thickness:2px;font-weight:600;cursor:pointer}
.empty{color:var(--mut);font-size:var(--fs-ui,13.5px);padding:34px 4px;text-align:center}
.edit-hint{display:none;font-size:var(--fs-meta,12px);line-height:1.55;color:var(--ink2);background:var(--sunken2);
  border:1px dashed var(--bd);border-radius:12px;padding:11px 13px;margin-bottom:14px}
.editing-mode .edit-hint{display:block}

/* Modal */
.modal-overlay{position:fixed;inset:0;background:rgba(27,22,19,.55);display:none;align-items:flex-start;
  justify-content:center;padding:max(24px,env(safe-area-inset-top)) 16px 40px;z-index:100;overflow-y:auto}
.modal-overlay.open{display:flex}
[data-theme="dark"] .modal-overlay{background:rgba(0,0,0,.68)}
.modal{background:var(--surface);border:1px solid var(--bd);border-radius:16px;box-shadow:var(--shadow-modal);
  width:100%;max-width:480px;margin-top:4vh;animation:modalIn .16s ease}
@keyframes modalIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
/* Die Kopfzeile darf umbrechen: bei 375 px und Zoom 1,6 ragte „Schließen" in
   Foodspots 25 px aus dem Bild, das × in Aufzüge bei langen Stationsnamen bis
   77 px. Die Mindestbreite des Titels bleibt auto — sie löst den Umbruch aus;
   max-width kappt sie nur am Dialogrand (18px = rechtes Polster: ein Wort, das
   bloß ins Polster ragt, bleibt ganz), break-word bricht, was breiter ist als
   der Dialog. Nach rechts rückt nur, was DIREKT hinter dem Titel steht —
   margin-left:auto auf jedem Knopf risse zwei Knöpfe in der neuen Zeile auseinander. */
.modal-head{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:15px 18px;border-bottom:1px solid var(--bd-soft);
  position:sticky;top:0;background:var(--surface);border-radius:16px 16px 0 0}
.modal-head h2{flex:1;font-size:14px;max-width:calc(100% + 18px);overflow-wrap:break-word}
.modal-head > h2 + *{margin-left:auto}
.modal-close{width:28px;height:28px;border:0;border-radius:8px;background:var(--sunken);color:var(--mut);
  font-size:18px;line-height:1;cursor:pointer}
.modal-close:hover{background:var(--sunken2);color:var(--ink)}
.cfg-body{padding:16px 18px 20px}
.cfg-body label{display:block;margin-bottom:7px;font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);
  letter-spacing:var(--ls-label,.12em);text-transform:uppercase;color:var(--mut)}
.cfg-body input{width:100%}
/* Felder IN einer Beschriftung erbten deren Mono-Versalien: Klappmenüs standen
   in Mono und schnitten ab („UNBEKANNT — NOCH NICHT NAC…", Foodspots). Die
   Beschriftung bleibt Etikett, das Feld zeigt den Inhalt, wie er ist. */
.cfg-body label :is(input,select,textarea){font-family:var(--font-ui);text-transform:none;letter-spacing:normal;font-weight:400}
/* Blanke Buttons im Modalkörper sind Primäraktionen — egal wie tief verschachtelt.
   Ausgenommen wird nach Komponenten-Zugehörigkeit, nicht nach Baumtiefe.
   .vs-ac-s1 = eine Farbkachel des Farbwählers: sie trägt ihre Farbe im Punkt
   und muss neutral bleiben, sonst stünden dort zehn ausgefüllte Primärknöpfe. */
.cfg-body button:not(.seg *):not(.v-switch):not(.v-check):not(.btn):not(.btn-ghost):not(.btn-primary):not(.icon-btn):not(.modal-close):not(.neutral):not(.vs-ac-s1){
  margin-top:10px;min-height:var(--ctl-h);padding:0 16px;border:0;border-radius:var(--r-pill);
  background:var(--signal-solid);color:var(--on-solid);font-size:var(--fs-ui,12.5px);font-weight:700;cursor:pointer;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
.cfg-body button:not(.seg *):not(.v-switch):not(.v-check):not(.btn):not(.btn-ghost):not(.btn-primary):not(.icon-btn):not(.modal-close):not(.neutral):not(.vs-ac-s1):hover{background:var(--signal-solid-hover)}
.cfg-body button.neutral{margin-top:10px;min-height:var(--ctl-h);padding:0 16px;border:1px solid var(--bd);
  border-radius:var(--r-pill);background:var(--chrome);color:var(--ink2);font-size:var(--fs-ui,12.5px);font-weight:600;
  cursor:pointer;box-shadow:none}
.cfg-body button.neutral:hover{color:var(--ink);border-color:var(--field-bd)}
.cfg-body .ok{color:var(--ok-text);font-size:var(--fs-meta,12px);margin-left:10px;font-family:var(--font-mono)}
.cfg-body .cfg-sep{border:0;border-top:1px solid var(--bd-soft);margin:18px 0}
.cfg-body .note{color:var(--mut);font-size:var(--fs-meta,11.5px);line-height:1.5;margin-top:9px}
.cfg-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}

/* ===================== Launcher (body.hub) ===================== */
.hub{padding:max(22px,env(safe-area-inset-top)) 16px calc(40px + env(safe-area-inset-bottom))}
.hub .wrap{max-width:820px;margin:0 auto}
.hub .top{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.hub .top h1{margin-right:2px}
.hub .top .stripe{margin-right:auto}
.hub .viewbar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 18px}
.hub .viewbar .segs{display:flex;gap:8px;flex-wrap:wrap}
.hub .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:var(--gap)}
[data-density="compact"] .hub .grid{grid-template-columns:repeat(auto-fill,minmax(136px,1fr))}
.hub a.card{display:flex;flex-direction:column;gap:8px;padding:var(--pad-card);border-radius:var(--r-card);
  background:var(--surface);border:1px solid var(--bd);color:var(--ink);
  box-shadow:var(--inset-hi),var(--shadow-card);transition:transform .12s,border-color .12s,box-shadow .12s}
.hub a.card:hover{border-color:var(--signal);transform:translateY(-1px);box-shadow:var(--shadow-lift)}
.hub a.card:active{transform:translateY(0)}
.hub a.card .icon{width:30px;height:30px;border-radius:var(--r-pill);background:var(--signal-soft);
  color:var(--signal-deep);display:flex;align-items:center;justify-content:center}
.hub a.card .icon svg{width:17px;height:17px}
.hub a.card .t{font-weight:600;font-size:var(--fs-title);line-height:1.25}
.hub a.card .g{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);letter-spacing:var(--ls-label,.1em);
  text-transform:uppercase;color:var(--mut2)}
[data-density="compact"] .hub a.card .g{display:none}

/* Kompakt-Ansicht: Gruppenkarten mit Chips */
.hub .cg{background:var(--surface);border:1px solid var(--bd);border-radius:var(--r-card);
  margin-bottom:10px;box-shadow:var(--inset-hi),var(--shadow-card)}
.hub .cg-head{display:flex;align-items:center;gap:9px;padding:12px 14px;cursor:pointer;user-select:none;-webkit-user-select:none}
.hub .cg-head .chev{color:var(--mut);font-size:var(--fs-label,10px);width:1.2em;text-align:center;transition:transform .15s}
.hub .cg.closed .cg-head .chev{transform:rotate(-90deg)}
.hub .cg-title{flex:1;min-width:0;font-weight:600;font-size:var(--fs-ui,13.5px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hub .cg-count{flex:none;font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10.5px);color:var(--mut);
  background:var(--sunken);border:1px solid var(--bd);border-radius:var(--r-pill);padding:1px 9px}
.hub .cg-act{display:none;gap:4px;flex:none}
.hub.editing-mode .cg-act{display:inline-flex}
.hub .cg-act button{min-width:28px;height:28px;padding:0 7px;border:1px solid var(--bd);background:var(--chrome);
  color:var(--ink2);border-radius:8px;cursor:pointer;font-family:var(--font-mono);font-size:var(--fs-label,10px);
  letter-spacing:var(--ls-label,.06em);text-transform:uppercase}
.hub .cg-act button:hover{color:var(--ink);border-color:var(--field-bd)}
.hub .cg-act button.gdel:hover{color:var(--danger-text);border-color:var(--danger)}
.hub .cg-body{display:flex;flex-wrap:wrap;gap:8px;padding:2px 14px 14px;min-height:20px}
.hub .cg.closed .cg-body{display:none}
.hub .cg.ghidden{border-style:dashed;opacity:.6}
.hub .cg.ghidden .cg-title{text-decoration:line-through}
.hub a.chip{display:inline-flex;align-items:center;gap:8px;padding:8px 13px;border-radius:var(--r-pill);
  border:1px solid var(--bd);background:var(--sunken2);color:var(--ink);font-size:var(--fs-ui,12.5px);font-weight:600;
  line-height:1.2;max-width:100%}
.hub a.chip:hover{border-color:var(--signal);color:var(--ink)}
.hub a.chip .ci{flex:none;display:flex;color:var(--signal-deep)}
.hub a.chip .ci svg{width:15px;height:15px}
.hub a.chip .cn{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hub a.chip .chip-btn{display:none;align-items:center;justify-content:center;width:21px;height:21px;
  margin:-2px -5px -2px 2px;padding:0;border:0;border-radius:50%;background:var(--sunken);color:var(--mut);
  cursor:pointer;flex:none}
.hub a.chip .chip-btn svg{width:11px;height:11px}
.hub.editing-mode a.chip{touch-action:none;cursor:grab;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.hub.editing-mode a.chip .chip-btn{display:inline-flex}
.hub a.chip .chip-hide:hover{background:var(--danger);color:#FFF9F2}
.hub a.chip .chip-pin:hover{background:var(--ok);color:#FFF9F2}
.hub a.chip .chip-pin.on{background:var(--signal-soft);color:var(--signal-deep)}
.hub a.chip.drag-src{opacity:.35;border-style:dashed}
.chip-ghost{position:fixed;left:0;top:0;z-index:999;pointer-events:none;opacity:.94;box-shadow:var(--shadow-lift)}
.hub .cg.hiddengrp{border-style:dashed;background:transparent;box-shadow:none}
.hub .cg.hiddengrp .cg-head{cursor:default}
.hub .cg.hiddengrp a.chip{opacity:.6;cursor:pointer;touch-action:auto}
.hub .cg.hiddengrp a.chip:hover{opacity:1;border-color:var(--ok)}
.hub .addgrp{display:none;gap:8px;align-items:center;border:1px dashed var(--bd);border-radius:var(--r-card);
  padding:10px 14px;margin-bottom:12px}
.hub.editing-mode .addgrp{display:flex}
.hub .addgrp input{flex:1;min-width:0}
.hub .addgrp button{height:var(--ctl-h);padding:0 15px;border:0;border-radius:var(--r-pill);background:var(--signal-solid);
  color:var(--on-solid);font-size:var(--fs-ui,12px);font-weight:700;cursor:pointer;white-space:nowrap;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
#editBtn.on{border-color:var(--signal);color:var(--signal-deep)}

@media (max-width:520px){
  .hub .top{flex-wrap:wrap}
  .hub .top .stripe{order:9;flex-basis:100%;margin:2px 0 0}
  .hub .grid{grid-template-columns:repeat(2,1fr)}
}


/* ============================================================
   KOMPONENTEN-EBENE — Bausteine für alle Vault-Apps.
   Klassen sind mit v- geprefixt und kollidieren nicht mit
   bestehendem App-CSS. Referenz-Umsetzung: vault-master.html
   ============================================================ */

/* --- App-Rahmen: Sidebar + Inhalt (Desktop) --- */
.v-app{display:flex;min-height:100vh}
.v-side{box-sizing:border-box;width:212px;flex:none;padding:18px 14px;background:var(--sunken);
  border-right:1px solid var(--bd);display:flex;flex-direction:column;gap:4px}
.v-side .label{margin:14px 0 6px}
.v-side .label:first-of-type{margin-top:4px}
.v-nav-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:var(--r-field);
  color:var(--ink2);font-size:var(--fs-ui,12.5px);font-weight:500;cursor:pointer;text-decoration:none}
.v-nav-item svg{width:15px;height:15px;flex:none}
.v-nav-item .n{margin-left:auto;font-family:var(--font-mono);font-size:var(--fs-label,9.5px);color:var(--mut)}
.v-nav-item:hover{background:var(--sunken2);color:var(--ink)}
.v-nav-item.active{background:var(--signal-solid);color:var(--on-solid);font-weight:600;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22)}
.v-nav-item.active .n{color:var(--on-solid);opacity:.85}
.v-main{flex:1;min-width:0;padding:20px 24px 28px}
.v-head{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px;row-gap:10px;margin-bottom:16px}
.v-head .v-title{min-width:0;flex:1 1 auto}
.v-head .v-title h1{font-size:22px}
.v-head .sub{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);letter-spacing:var(--ls-label,.12em);
  text-transform:uppercase;color:var(--mut2);margin-top:5px}
.v-head .spacer{flex:1 1 0;min-width:0}

/* --- Karte / Panel --- */
.v-card{background:var(--surface);border:1px solid var(--bd);border-radius:var(--r-card);
  padding:var(--pad-card);box-shadow:var(--shadow-card)}
.v-card.flat{box-shadow:none}
.v-hr{border:0;border-top:1px solid var(--bd-soft);margin:16px 0}

/* --- Statuspunkt --- */
.v-dot{width:6px;height:6px;border-radius:50%;background:var(--mut);flex:none;display:inline-block}
.v-dot.ok{background:var(--ok)} .v-dot.warn{background:var(--warn)}
.v-dot.bad{background:var(--danger)} .v-dot.signal{background:var(--signal)}
.v-status{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-weight:500;
  font-size:var(--fs-label,10px);letter-spacing:var(--ls-label,.08em);text-transform:uppercase;color:var(--mut)}
.v-status.ok{color:var(--ok-text)} .v-status.warn{color:var(--warn-text)} .v-status.bad{color:var(--danger-text)}

/* --- Schalter --- */
.v-switch{width:44px;height:26px;flex:none;border:0;padding:3px;border-radius:var(--r-pill);
  background:var(--bd);display:flex;align-items:center;cursor:pointer;box-shadow:inset 0 1px 2px var(--shadow)}
.v-switch i{width:20px;height:20px;border-radius:50%;background:var(--surface);
  box-shadow:0 1px 2px rgba(0,0,0,.18);transition:transform .14s}
.v-switch[aria-checked="true"]{background:var(--signal)}
.v-switch[aria-checked="true"] i{transform:translateX(18px)}

/* --- Runder Check (Tasks) --- */
.v-check{width:22px;height:22px;flex:none;border:2px solid var(--field-bd);border-radius:50%;
  background:transparent;padding:0;cursor:pointer;display:flex;align-items:center;justify-content:center}
.v-check svg{width:0;height:0}
.v-check:hover{border-color:var(--signal)}
.v-check[aria-checked="true"]{background:var(--ok);border-color:var(--ok)}
.v-check[aria-checked="true"] svg{width:13px;height:13px;stroke:var(--surface);stroke-width:2.8}
[data-density="compact"] .v-check{width:18px;height:18px}
[data-density="compact"] .v-check[aria-checked="true"] svg{width:11px;height:11px}

/* --- Task-Zeile / Task-Karte --- */
.v-task{display:flex;gap:11px;align-items:flex-start;background:var(--surface);border:1px solid var(--bd);
  border-radius:var(--r-card);padding:var(--pad-card);box-shadow:var(--shadow-card)}
.v-task.due{border-left:3px solid var(--signal)}
.v-task .tt{font-weight:600;font-size:var(--fs-title);line-height:1.35;color:var(--ink)}
.v-task .td{font-size:var(--fs-meta,12px);line-height:1.45;color:var(--ink2);margin-top:5px}
.v-task .tm{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.v-task.done .tt{color:var(--mut);text-decoration:line-through;font-weight:500}
.v-task.done .td{display:none}
[data-density="compact"] .v-task{border-radius:0;border-width:0 0 1px 0;box-shadow:none;background:transparent;
  align-items:center;padding:7px 2px;gap:8px}
[data-density="compact"] .v-task .td{display:none}
[data-density="compact"] .v-task .tm{margin:0 0 0 auto}

/* --- Board --- */
.v-board{display:flex;gap:12px;align-items:flex-start;overflow-x:auto;padding-bottom:6px}
.v-col{box-sizing:border-box;width:270px;flex:none;background:var(--sunken);border:1px solid var(--bd);
  border-radius:var(--r-card);padding:11px;display:flex;flex-direction:column;gap:8px}
.v-col-head{display:flex;align-items:center;gap:8px;margin-bottom:2px}
.v-col-head .k{width:9px;height:9px;border-radius:2px;background:var(--mut);flex:none}
.v-col-head .t{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10.5px);letter-spacing:var(--ls-label,.1em);
  text-transform:uppercase;color:var(--ink2)}
.v-col-head .c{margin-left:auto;font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10.5px);color:var(--mut);
  background:var(--surface);border:1px solid var(--bd);border-radius:var(--r-pill);padding:1px 9px}
.v-add{padding:9px;border:1px dashed var(--field-bd);border-radius:var(--r-field);background:transparent;
  color:var(--mut2);cursor:pointer;font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,11px);
  letter-spacing:var(--ls-label,.08em);text-transform:uppercase}
.v-add:hover{border-color:var(--signal);color:var(--signal-deep)}

/* --- Tabelle --- */
.v-table{width:100%;border-collapse:collapse;background:var(--surface);border:1px solid var(--bd);
  border-radius:var(--r-card);overflow:hidden;box-shadow:var(--shadow-card)}
.v-table thead th{text-align:left;padding:10px 16px;background:var(--sunken2);border-bottom:1px solid var(--bd);
  font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);letter-spacing:var(--ls-label,.12em);text-transform:uppercase;color:var(--mut)}
.v-table td{padding:12px 16px;border-bottom:1px solid var(--bd-soft);font-size:var(--fs-ui,13px);color:var(--ink)}
.v-table tbody tr:last-child td{border-bottom:0}
.v-table tbody tr:hover td{background:var(--sunken2)}
.v-table .num,.v-table th.num{text-align:right;font-family:var(--font-mono);font-weight:500}
.v-table .date{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-meta,11.5px);color:var(--mut)}
.v-table .name{font-weight:600}
.v-table tfoot td{padding:12px 16px;background:var(--sunken2);border-top:1px solid var(--bd);
  font-family:var(--font-mono);font-weight:500}
[data-density="compact"] .v-table td{padding:7px 12px}
[data-density="compact"] .v-table thead th{padding:7px 12px}

/* --- Instrument (Rundanzeige) --- */
.v-gauge{--val:0;--col:var(--signal);width:118px;height:118px;border-radius:50%;flex:none;
  background:conic-gradient(var(--col) 0 calc(var(--val) * 1%),var(--sunken) calc(var(--val) * 1%) 100%);
  display:flex;align-items:center;justify-content:center}
.v-gauge > span{width:88px;height:88px;border-radius:50%;background:var(--surface);display:flex;
  flex-direction:column;align-items:center;justify-content:center;text-align:center}
.v-gauge .g-v{font-family:var(--font-mono);font-weight:500;font-size:27px;line-height:1;color:var(--ink)}
.v-gauge .g-v small{font-size:14px;color:var(--mut2)}
.v-gauge .g-l{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,8.5px);letter-spacing:var(--ls-label,.12em);
  text-transform:uppercase;color:var(--mut2);margin-top:3px}
.v-metric{display:flex;flex-direction:column;align-items:center;gap:10px}
.v-metric .cap{font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,9.5px);letter-spacing:var(--ls-label,.1em);
  text-transform:uppercase;color:var(--mut)}
.v-big{font-family:var(--font-mono);font-weight:500;font-size:30px;line-height:1;color:var(--ink)}
.v-big small{font-size:15px;color:var(--mut)}
.v-bars{display:flex;align-items:flex-end;gap:5px;height:64px}
.v-bars i{flex:1;background:var(--bd);border-radius:2px;display:block}
.v-bars i.on{background:var(--signal)}
.v-streak{display:grid;grid-template-columns:repeat(14,1fr);gap:4px}
.v-streak i{height:26px;border-radius:4px;background:var(--sunken);display:block}
.v-streak i.on{background:var(--signal)} .v-streak i.half{background:var(--signal-soft)}
.v-prog{height:5px;border-radius:3px;background:var(--sunken);overflow:hidden}
.v-prog i{display:block;height:100%;background:var(--signal)}

/* --- Editor / Notiz --- */
.v-doc{background:var(--surface);border:1px solid var(--bd);border-radius:var(--r-card);
  padding:20px 22px;box-shadow:var(--shadow-card);max-width:72ch}
.v-doc p{margin:9px 0 0;font-size:var(--fs-body,13.5px);line-height:1.65;color:var(--ink2);text-wrap:pretty}
.v-doc h2{margin-top:0}
.v-doc mark{background:rgba(201,138,22,.16);color:inherit;padding:1px 4px;border-radius:3px}
[data-theme="dark"] .v-doc mark{background:rgba(219,168,58,.2)}
.v-quote{margin-top:14px;padding:12px 14px;border-left:3px solid var(--signal);background:var(--sunken2);
  border-radius:0 var(--r-field) var(--r-field) 0;font-size:var(--fs-ui,13px);line-height:1.6;color:var(--ink2);font-style:italic}
.v-wikilink{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;border-radius:var(--r-pill);
  border:1px solid var(--bd);background:var(--sunken);color:var(--ink2);font-size:var(--fs-ui,11.5px);font-weight:500}
.v-wikilink svg{width:13px;height:13px;color:var(--signal-deep)}
.v-wikilink:hover{border-color:var(--signal);color:var(--ink)}
.v-tick{display:flex;gap:10px;align-items:center;padding:3px 0;font-size:var(--fs-ui,13px);color:var(--ink)}
.v-tick i{width:16px;height:16px;flex:none;border:1.7px solid var(--field-bd);border-radius:4px;display:block}
.v-tick.on{color:var(--mut);text-decoration:line-through}
.v-tick.on i{background:var(--ok);border-color:var(--ok)}

/* --- Login --- */
.v-login{max-width:420px;margin:0 auto;background:var(--surface);border:1px solid var(--bd);
  border-radius:var(--r-card);overflow:hidden;box-shadow:var(--shadow-lift)}
.v-login-top{position:relative;overflow:hidden;background:var(--signal-solid);padding:32px 30px 28px;color:var(--on-solid)}
.v-login-top .grille{position:absolute;left:0;right:0;bottom:0;height:104px;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.10) 0 3px,transparent 3px 9px)}
.v-login-top h1{position:relative;font-size:40px;font-weight:900;font-stretch:122%;letter-spacing:-.02em;color:var(--on-signal)}
.v-login-top h1 .dot{color:var(--ink)}
[data-theme="dark"] .v-login-top h1 .dot{color:#151210}
.v-login-top .stripe{position:relative;margin-top:12px}
.v-login-top .stripe i{height:4px;background:var(--on-signal)}
.v-login-top .stripe i:first-child{width:52px} .v-login-top .stripe i+i{width:20px}
.v-login-top .sub{position:relative;margin-top:14px;font-family:var(--font-mono);font-weight:500;font-size:var(--fs-label,10px);
  letter-spacing:var(--ls-label,.16em);text-transform:uppercase;color:var(--on-signal);opacity:.82}
.v-login-body{padding:24px 30px 28px}
.v-login-body .btn-primary{width:100%;justify-content:center;height:46px;border-radius:12px;font-size:14px}

/* --- Mobile Bottom-Nav --- */
.v-tabbar{display:flex;gap:4px;padding:9px 12px calc(9px + env(safe-area-inset-bottom));
  background:var(--sunken);border-top:1px solid var(--bd)}
.v-tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;padding:6px 0;
  border:0;border-radius:var(--r-field);background:transparent;color:var(--mut);cursor:pointer}
.v-tab svg{width:19px;height:19px}
.v-tab span{font-family:var(--font-mono);font-weight:600;font-size:var(--fs-label,8.5px);letter-spacing:var(--ls-label,.1em);text-transform:uppercase}
.v-tab.active{background:var(--signal-soft);color:var(--signal-deep)}
/* Hit-Targets: mobil nie unter 44 px */
@media (max-width:520px){
  .v-app{flex-direction:column}
  .v-side{width:100%;border-right:0;border-bottom:1px solid var(--bd)}
  .v-main{padding:16px}
  .btn,.btn-ghost,.btn-primary,.icon-btn{min-height:44px}
  .v-check{width:26px;height:26px}
  .v-col{width:100%}
}
