/*
  DAILY DASHBOARD / MORNING BRIEFING (V5.0) — neue Komponentenschicht für die Übersichtsseite.
  Eigene Datei statt Erweiterung von components.css: nur auf der Übersichtsseite geladen (Punkt
  39, keine unnötig große CSS-Last auf anderen Seiten), aber bewusst mit denselben Design-Tokens
  und demselben visuellen Vokabular (Panel/Border/Radius/Badge-System) wie components.css gebaut
  — kein paralleles Designsystem, sondern eine Erweiterung davon (Punkt 52: später auf andere
  Seiten übertragbar).
*/

/* ============================================================
   LAYOUT — V5.2: vertikaler Informationsfluss (Nutzerauftrag "UX/Design/IA Polishing", Teil A/B).
   Root Cause der V5.1-Asymmetrie: die GESAMTE Seite lag in einem zweispaltigen Grid, wodurch
   thematisch unabhängige Karten (links: Training/Briefing/Woche, rechts: Readiness/Wetter/Long
   Run/Marathon Progress) um Spaltenlänge konkurrierten — die rechte Spalte war strukturell länger.
   Jetzt ist NUR die Hero-Zone (drei tatsächlich zusammengehörige Elemente: Today's Training,
   Readiness, Running Conditions) zweispaltig; alles andere ist eine einzige, durchgehende Spalte
   (.dashboard-flow) mit stabiler Reihenfolge (This Week -> Marathon Readiness -> Training
   Capability -> Deep Analytics).
   ============================================================ */
/* V6.2 (Mandat Teil H/I, Punkt 44/49): .hero-zone besaß bisher ein EIGENES margin-bottom
   (var(--space-4), 16px) — obwohl das Element mittlerweile ausschließlich innerhalb von
   .dash-zone-stack verwendet wird, dessen eigener `gap` (var(--card-gap), ebenfalls 16px) bereits
   den Abstand zur nächsten Karte/Grid steuert. Beide zusammen erzeugten real 32px statt der
   beabsichtigten 16px zwischen Training/Wetter-Grid und der Coaching-Gruppe darunter — genau die
   Art doppelter Section/Card-Abstand, die die goldene Spacing-Regel verbietet ("ein Child-Widget
   darf nicht zusätzlich den Abstand zur nächsten Section erzeugen"). margin-bottom entfernt —
   .dash-zone-stack ist ab jetzt die EINZIGE Stelle, die diesen Abstand bestimmt. */
.hero-zone {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
}
.hero-zone-side { display: flex; flex-direction: column; gap: var(--space-4); }
/* V6.2.2 (UI-Konsistenz-Mandat, Punkt 14/17): spiegelt .hero-zone-main .hero-card{flex:1} (unten)
   für die Wetter-Seite — ohne diese Regel würde #weather-section (und damit .weather-card) trotz
   .hero-zone-side als gestrecktem Grid-Item nicht automatisch die volle verfügbare Höhe der Row
   ausfüllen (eine Flex-Spalte streckt Kinder standardmäßig nur in der Breite, nicht in der Höhe). */
#weather-section { display: flex; flex-direction: column; flex: 1; }
@media (min-width: 900px) {
  /* V6.1 (Mandat "Dein Tag", Punkt 21): Training deutlich schwerer gewichtet als Wetter
     (ca. 60/40 statt der bisherigen 1.6fr/1fr ≈ 62/38 — bewusst auf ein rundes, im Mandat
     explizit genanntes 3fr/2fr-Verhältnis vereinheitlicht, siehe auch .dashboard-grid--daily).
     align-items:stretch kommt seit V6.2.2 bereits von der gemeinsamen .dashboard-grid-Basisregel
     (dieses Element trägt beide Klassen) — hier nicht mehr redundant wiederholt, um genau die Art
     von zwei-Stellen-Konflikt zu vermeiden, die vorher real dazu führte, dass die spätere
     .dashboard-grid-Regel (align-items:start) diese Zeile trotz Media-Query überschrieb. */
  .hero-zone { grid-template-columns: 3fr 2fr; }
  .hero-zone-main { display: flex; }
  .hero-zone-main .hero-card { flex: 1; }
}

/* V6.2 (Mandat Teil H, Punkt 47, "goldene Spacing-Regel"): .dashboard-flow trug bisher selbst
   einen `gap` (var(--space-5), 20px) zusätzlich zum margin-bottom, das jede darin liegende
   .dashboard-section bereits selbst mitbringt (var(--zone-gap), 32px Desktop) — beide addierten
   sich zu 52px statt der beabsichtigten 32px zwischen Zonen. Die goldene Regel (SECTION
   entscheidet den Außenabstand zur nächsten Section, sonst niemand) bedeutet: .dashboard-flow ist
   nur noch ein reiner Container ohne eigenen Spacing-Beitrag — .dashboard-section allein steuert
   den Zonen-Rhythmus, exakt wie bei den Zonen in #overview-top (die ebenfalls ohne umschließenden
   Flow-Gap auskommen). */
.dashboard-flow { display: flex; flex-direction: column; }

/* ============================================================
   A. MORNING HEADER
   ============================================================ */
.morning-header { margin-bottom: 4px; }
.morning-header .greeting {
  font-family: var(--font-display); font-size: 26px; font-weight: 600; letter-spacing: -0.01em;
  margin-bottom: 2px;
}
.morning-header .date-line {
  font-family: var(--font-body); font-size: 12.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em;
  margin-bottom: 10px;
}
.morning-header .status-sentence {
  font-size: 15px; color: var(--text-muted); line-height: 1.5;
}
.morning-header .status-sentence b { color: var(--text); font-weight: 600; }
@media (max-width: 480px) {
  .morning-header .greeting { font-size: 22px; }
}

/* ============================================================
   B. HERO TRAINING CARD — erweitert .today-session (components.css) um
   Completed-/Rest-/Adaptation-Varianten statt sie zu duplizieren.
   ============================================================ */
.hero-card {
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius);
  overflow: hidden; position: relative;
  /* Platform Finish II (Part F §48/49): .hero-card hatte bisher als einzige der grossen Card-Typen
     KEINEN box-shadow (im Unterschied zu .dash-card, das bereits var(--shadow-raised) traegt, siehe
     components.css) — im Light Mode las sich das als die staerkste Flaechen-vs-Hintergrund-
     Unschaerfe der ganzen Seite. var(--shadow-raised) ist in beiden Themes bereits abgestimmt
     (Dark Mode: identisch zum bestehenden .dash-card-Wert, keine neue Optik dort), daher
     themeuebergreifend hinzugefuegt statt nur Light-Mode-gescoped. */
  box-shadow: var(--shadow-raised);
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
}
.hero-card.state-completed { border-color: rgba(47, 217, 196, 0.35); }
.hero-card.state-rest { border-color: var(--border-soft); }
.hero-card.state-substituted { border-color: var(--amber); }
.hero-head {
  padding: 22px 24px 18px 24px; border-left: 4px solid var(--stc, var(--teal));
}
.hero-eyebrow-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.hero-type {
  font-family: var(--font-body); font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--stc, var(--teal)); font-weight: 600;
}
.hero-completed-pill {
  font-family: var(--font-body); font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  padding: 4px 10px; border-radius: var(--radius-pill); background: var(--teal-dim); color: var(--teal);
}
.hero-plan-pill {
  font-family: var(--font-body); font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em;
  padding: 4px 10px; border-radius: var(--radius-pill);
}
.hero-plan-pill.pill-adapted { background: var(--amber-dim); color: var(--amber); }
.hero-plan-pill.pill-confirmed { background: var(--neutral-chip-bg); color: var(--text-dim); }
/* Visual Redesign Execution Pass §18 ("Intelligence Stage must become the visual centerpiece"):
   this line IS the answer to "what does TALVAXO want me to know and do today" -- the single most
   important piece of text on Overview, previously sized like a card title (26px) rather than the
   page's actual headline. */
.hero-title { font-family: var(--font-display); font-size: 36px; font-weight: 700; margin-bottom: 12px; line-height: 1.1; letter-spacing: -0.005em; }
@media (max-width: 640px) {
  .hero-title { font-size: 28px; }
}
.hero-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; font-family: var(--font-body); font-size: 13px; color: var(--text-muted); }
.hero-meta .hm-item { display: flex; align-items: center; gap: 5px; }
.hero-meta .hm-label { color: var(--text-dim); }

.hero-body { padding: 0 24px 22px 24px; }
.hero-structure { list-style: none; padding: 0; margin: 14px 0 0 0; display: flex; flex-direction: column; gap: 6px; }
.hero-structure li {
  background: var(--panel-alt); border-radius: 8px; padding: 9px 12px; font-size: 13px; color: var(--text-muted);
  border-left: 2px solid var(--border);
}

.hero-purpose {
  margin-top: 14px; padding: 12px 14px; background: var(--panel-alt); border-radius: 8px;
  font-size: 13px; color: var(--text-muted); line-height: 1.55;
}
.hero-purpose b { color: var(--text); }
.hero-body-empty { padding-top: 22px; }
/* V6.1: EIN Abstandswert (--space-3, 12px) für zusätzliche Info-Blöcke innerhalb der Hero-Card
   statt bisher drei verschiedener, per Inline-Style gesetzter Werte (8px/12px/14px). */
.hero-block-gap { margin-top: var(--space-3); }
.hcs-value-sm { font-size: 13px; }

.hero-why-toggle {
  margin-top: 12px; font-family: var(--font-body); font-size: 11.5px; color: var(--text-dim);
}
.hero-why-toggle summary {
  cursor: pointer; color: var(--teal); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600;
  list-style: none;
}
.hero-why-toggle summary::-webkit-details-marker { display: none; }
.hero-why-toggle summary::before { content: '▸ '; }
.hero-why-toggle[open] summary::before { content: '▾ '; }
.hero-why-body { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.hero-why-row { display: flex; gap: 10px; font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.hero-why-row .hw-label { flex-shrink: 0; width: 92px; color: var(--text-dim); font-family: var(--font-body); font-size: 10.5px; text-transform: uppercase; padding-top: 1px; }

/* Adaptation banner — deutlich, aber nicht alarmistisch (Punkt 11) */
.adaptation-banner {
  margin-top: 14px; padding: 12px 14px; border-radius: 8px;
  background: var(--amber-dim); border-left: 3px solid var(--amber);
}
.adaptation-banner .ab-label {
  font-family: var(--font-body); font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--amber); margin-bottom: 6px;
}
.adaptation-banner .ab-row { display: flex; gap: 16px; font-size: 13px; color: var(--text-muted); flex-wrap: wrap; }
.adaptation-banner .ab-row b { color: var(--text); }
.ab-row-label { color: var(--text-dim); }
.adaptation-banner .ab-reason { margin-top: 6px; font-size: 12.5px; color: var(--text-muted); }

/* Completed state: Soll/Ist */
.hero-completed-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 14px;
}
@media (min-width: 480px) { .hero-completed-grid { grid-template-columns: repeat(4, 1fr); } }
.hero-completed-stat { background: var(--panel-alt); border-radius: 8px; padding: 10px 12px; }
.hero-completed-stat .hcs-label { font-family: var(--font-body); font-size: 10px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 4px; }
.hero-completed-stat .hcs-value { font-family: var(--font-display); font-size: 17px; font-weight: 600; }

/* ============================================================
   B.1 TALVAXO MORNING BRIEFING (Beta 9.0, Punkt 10-19/125) — steht ganz oben, siehe overview.js
   renderTop(). Chrome kommt von .dash-card (identisches Muster wie .briefing-card unten).
   ============================================================ */
.morning-briefing-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: var(--talvaxo-gradient);
}
/* Beta 9.3 Completion Pass (P1, "Morning Hero dunkler Balken" — Bugfix, kein Redesign): die
   "goldene Spacing-Regel" (siehe .dashboard-flow-Kommentar oben, "SECTION entscheidet den
   Außenabstand zur nächsten Section, sonst niemand") galt hier bisher nur für .daily-hero
   (margin-bottom weiter unten), nicht für diese Card direkt davor — #overview-top selbst hat
   bewusst keinen eigenen Flow-Gap. Beide Karten lagen dadurch mit 0px Abstand aneinander: die
   dunklere .daily-hero-modules-Gradientfläche (--surface-hero, deutlich dunkler als --panel)
   begann exakt an der Unterkante von .morning-briefing-card, direkt hinter deren "Guten
   Morgen/Abend"-Text — sichtbar als ein durchgehender dunkler horizontaler Balken. Behoben durch
   genau denselben Rhythmus, den .daily-hero bereits für den nächsten Übergang verwendet (kein
   neues Spacing-Konzept, keine Redesign-Änderung an Inhalt/Layout dieser Karte selbst). */
/* v10.2 "APP VISUAL EXPERIENCE" (Mandat Teil 31, "less like another generic card") + v10.2.1 Teil 5/6
   ("Morning Briefing no longer competes with the Stage, move it below"): jetzt NACH der Stage (siehe
   overview.js renderTop) -- der enge --space-4-Abstand sitzt seit v10.2.1 auf .daily-hero selbst
   (die Stage bindet die Briefing-Karte engt an sich), diese Karte traegt jetzt wieder den vollen
   Zonen-Abstand zur naechsten echten Zone. Der leichtere Schatten (statt --shadow-raised wie normale
   .dash-cards) bleibt -- die Karte soll weiterhin redaktionell/kompakt wirken, nicht wie eine vierte
   gleich schwere Card. */
.morning-briefing-card { position: relative; overflow: hidden; margin-bottom: var(--zone-gap); box-shadow: var(--shadow-sm); }
@media (max-width: 900px) { .morning-briefing-card { margin-bottom: var(--zone-gap-tablet); } }
@media (max-width: 480px) { .morning-briefing-card { margin-bottom: var(--zone-gap-mobile); } }
.mb-greeting { font-family: var(--font-display); font-size: 15px; font-weight: 600; margin-bottom: 10px; color: var(--text); }
.mb-rows { display: flex; flex-direction: column; gap: 8px; }
.mb-row { display: flex; gap: 10px; font-size: 13.5px; line-height: 1.5; }
.mb-label { flex-shrink: 0; width: 84px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: var(--ls-label); color: var(--text-dim); padding-top: 2px; }
.mb-value { color: var(--text); }
.mb-confidence-note { margin-top: 10px; font-size: 11px; color: var(--text-dim); }
.mb-why-toggle { margin-top: 10px; }

/* ============================================================
   B.2 TALVAXO DAILY READINESS CARD (Beta 9.0, Punkt 20-28/130-131) — bewusst KEIN Ring (siehe
   overview/talvaxo-readiness-card.js Moduldoku), lebt in .hero-zone-side neben der Wetterkarte.

   v10.2.1 (Mandat Teil 9/11/12, "must NOT look like a duplicate Hero Readiness component" /
   "smaller contextual intelligence surface"): deutlich kleinere Zahl als der Stage-Ring
   (34px -> 22px, gegenueber --fs-display:40px im Ring), plus ein Violet-Akzentrand -- derselbe
   Farbcode wie die "TALVAXO Entscheidung" im Stage (--accent-adaptive), da beides TALVAXOs EIGENE
   Interpretation ist, nicht der externe Garmin-Wert. Macht auf den ersten Blick sichtbar: "das ist
   ein anderes, kleineres, TALVAXO-eigenes Signal", nicht "eine zweite grosse Bereitschaftszahl".
   ============================================================ */
.talvaxo-readiness-card { gap: 4px; border-left: 3px solid var(--accent-adaptive); }
.talvaxo-readiness-card .dash-card__title { color: var(--accent-adaptive); }
.tr-engine-tag { font-family: var(--font-mono); font-size: 9.5px; color: var(--text-dim); font-weight: 400; letter-spacing: 0; margin-left: 2px; opacity: 0.7; }
.tr-score-row { display: flex; align-items: baseline; gap: 10px; margin-top: 2px; }
.tr-score-value { font-family: var(--font-display); font-size: 22px; font-weight: 600; line-height: 1; color: var(--text); }
.tr-score-status { font-family: var(--font-mono); font-size: 11px; letter-spacing: var(--ls-label); text-transform: uppercase; padding: 3px 8px; border-radius: 999px; }
.tr-status-high, .tr-status-good { color: var(--status-good); background: var(--status-good-dim); }
.tr-status-moderate { color: var(--status-warn); background: var(--status-warn-dim); }
.tr-status-low { color: var(--status-bad); background: var(--status-bad-dim); }
.tr-bar-track { margin-top: 10px; height: 5px; background: var(--panel-alt); border-radius: 3px; overflow: hidden; }
.tr-bar-fill { display: block; height: 100%; border-radius: 3px; transition: width var(--transition-base); }
.tr-bar-fill.tr-status-high, .tr-bar-fill.tr-status-good { background: var(--status-good); }
.tr-bar-fill.tr-status-moderate { background: var(--status-warn); }
.tr-bar-fill.tr-status-low { background: var(--status-bad); }
.tr-explainer { margin-top: 9px; font-size: 11.5px; line-height: 1.5; color: var(--text-muted); }
.tr-confidence-note { margin-top: 8px; font-size: 11px; color: var(--text-dim); }
.tr-why-toggle { margin-top: 8px; }

/* ============================================================
   C. DAILY COACH BRIEFING
   ============================================================ */
/* V6.2 (Mandat Teil H, Punkt 51-54): Chrome (background/border/radius/padding/shadow/hover)
   kommt jetzt ausschließlich von .dash-card (DOM trägt beide Klassen, siehe
   overview/coach-briefing-card.js) — die frühere eigene Deklaration hier war eine reine
   1:1-Dopplung derselben Werte und wurde entfernt. */
.briefing-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.briefing-item { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: var(--text-muted); }
.briefing-dot { flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; margin-top: 5px; }
.briefing-item.tone-good .briefing-dot,
.briefing-headline.tone-good .briefing-dot,
.briefing-recommendation.tone-good .briefing-dot { background: var(--teal); box-shadow: 0 0 6px rgba(47,217,196,0.5); }
.briefing-item.tone-warn .briefing-dot,
.briefing-headline.tone-warn .briefing-dot,
.briefing-recommendation.tone-warn .briefing-dot { background: var(--amber); box-shadow: 0 0 6px rgba(240,169,78,0.5); }
.briefing-item.tone-bad .briefing-dot,
.briefing-headline.tone-bad .briefing-dot,
.briefing-recommendation.tone-bad .briefing-dot { background: var(--crimson); box-shadow: 0 0 6px rgba(239,91,107,0.5); }
.briefing-item.tone-neutral .briefing-dot,
.briefing-headline.tone-neutral .briefing-dot,
.briefing-recommendation.tone-neutral .briefing-dot { background: var(--text-dim); }
.briefing-item b { color: var(--text); }
/* Beta 7.5 (Punkt 80-83): Headline/Key-Recommendation/Support-Points-Hierarchie ueber die bereits
   priorisierte Reihenfolge aus coach-briefing.js — reine Typografie, keine neue Bewertung. */
.briefing-headline {
  display: flex; gap: 10px; align-items: flex-start; font-family: var(--font-display);
  font-size: 15.5px; font-weight: 600; line-height: 1.4; color: var(--text); margin-bottom: 10px;
}
.briefing-headline .briefing-dot { margin-top: 6px; width: 9px; height: 9px; }
.briefing-recommendation {
  display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: var(--text-muted);
  padding: 9px 10px; margin-bottom: 10px; background: rgba(122, 92, 255, 0.07);
  border-left: 2px solid var(--talvaxo-violet); border-radius: 0 var(--talvaxo-radius-sm) var(--talvaxo-radius-sm) 0;
}
.briefing-support { padding-top: 2px; border-top: 1px solid var(--border-soft); }
.briefing-support .briefing-item { font-size: 12.5px; color: var(--text-dim); }

/* ============================================================
   D. READINESS / BODY STATUS
   ============================================================ */
.readiness-card {
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 20px 22px;
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
}
.readiness-central { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.readiness-badge {
  font-family: var(--font-display); font-size: 20px; font-weight: 700; letter-spacing: -0.01em;
  padding: 10px 18px; border-radius: var(--radius-pill); flex-shrink: 0;
}
.readiness-badge.status-good { background: var(--teal-dim); color: var(--teal); }
.readiness-badge.status-warn { background: var(--amber-dim); color: var(--amber); }
.readiness-badge.status-bad { background: var(--crimson-dim); color: var(--crimson); }
.readiness-badge.status-neutral { background: var(--neutral-chip-bg); color: var(--text-muted); }
.readiness-summary-text { font-size: 13px; color: var(--text-muted); line-height: 1.5; }

.readiness-drivers { display: flex; flex-direction: column; gap: 6px; margin-bottom: 4px; }
.readiness-driver { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; padding: 6px 0; border-top: 1px solid var(--border-soft); }
.readiness-driver:first-child { border-top: none; }
.readiness-driver .rd-label { color: var(--text-muted); }
.readiness-driver .rd-value { font-family: var(--font-body); color: var(--text-dim); text-align: right; }

/* ============================================================
   Metric context cards (health metrics with baseline + sparkline)
   ============================================================ */
.metric-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
@media (min-width: 480px) and (max-width: 899px) { .metric-grid { grid-template-columns: repeat(3, 1fr); } }
.metric-card {
  background: var(--panel-alt); border-radius: 8px; padding: 12px 14px;
}
.metric-card .mc-label { font-family: var(--font-body); font-size: 10px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; }
.metric-card .mc-value { font-family: var(--font-display); font-size: 20px; font-weight: 600; line-height: 1; margin-bottom: 4px; }
.metric-card .mc-value .mc-unit { font-size: 11px; color: var(--text-dim); font-weight: 400; margin-left: 3px; }
.metric-card .mc-context { font-size: 11px; color: var(--text-muted); }
.metric-card .mc-unavailable { font-size: 11px; color: var(--text-dim); font-style: italic; }
.metric-card .mc-spark { margin-top: 6px; }
.mc-spark svg { display: block; }

/* ============================================================
   E. WEATHER / RUNNING CONDITIONS
   ============================================================ */
/* V6.2: Chrome jetzt via .dash-card (siehe overview/weather-card.js), Dopplung entfernt. */
.weather-current { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.weather-temp { font-family: var(--font-display); font-size: 32px; font-weight: 600; }
.weather-temp .wt-feels { font-size: 12px; color: var(--text-dim); font-weight: 400; display: block; font-family: var(--font-body); }
.weather-desc { flex: 1; }
.weather-desc .wd-condition-label { font-size: 14px; color: var(--text); font-weight: 600; }
.weather-desc .wd-sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.weather-condition-pill {
  font-family: var(--font-body); font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 5px 10px; border-radius: var(--radius-pill); flex-shrink: 0;
}
.weather-condition-pill.cond-excellent, .weather-condition-pill.cond-good { background: var(--teal-dim); color: var(--teal); }
.weather-condition-pill.cond-warm, .weather-condition-pill.cond-cold, .weather-condition-pill.cond-windy, .weather-condition-pill.cond-rain_risk { background: var(--amber-dim); color: var(--amber); }
.weather-condition-pill.cond-hot, .weather-condition-pill.cond-difficult { background: var(--crimson-dim); color: var(--crimson); }

.weather-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-bottom: 14px; }
.weather-stat { text-align: center; }
.weather-stat .ws-label { font-family: var(--font-body); font-size: 9.5px; text-transform: uppercase; color: var(--text-dim); }
.weather-stat .ws-value { font-size: 13px; color: var(--text-muted); margin-top: 2px; }

.best-window {
  background: var(--panel-alt); border-radius: 8px; padding: 12px 14px; margin-bottom: 10px;
}
.best-window .bw-label { font-family: var(--font-body); font-size: 10px; text-transform: uppercase; color: var(--text-dim); margin-bottom: 4px; }
.best-window .bw-time { font-family: var(--font-display); font-size: 17px; font-weight: 600; color: var(--teal); }
.best-window .bw-note { font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }

.weather-advice {
  font-size: 12.5px; color: var(--text-muted); line-height: 1.5; padding-top: 8px; border-top: 1px solid var(--border-soft);
}

.weather-unavailable {
  text-align: center; padding: 20px 10px; color: var(--text-dim); font-size: 12.5px;
}
.weather-unavailable .wu-icon { font-size: 22px; margin-bottom: 8px; display: block; }
.weather-unavailable button { margin-top: 10px; }

.weather-stale-note {
  font-size: 11.5px; color: var(--amber); background: var(--amber-dim); border-radius: 8px;
  padding: 7px 10px; margin-bottom: 12px;
}
.weather-precision-note {
  font-size: 11px; color: var(--text-dim); margin-top: 8px;
}

/* ============================================================
   F. WEEK PROGRESS
   ============================================================ */
/* V6.2: Chrome jetzt via .dash-card (siehe overview/week.js), Dopplung entfernt. */
/* Beta 7.5 (Punkt 76-79, "Weekly Progress / Marathon Readiness rebuild" — dieselbe visuelle Familie
   wie .goal-card, aber erkennbar eigener Card-Typ statt zweier optisch identischer .dash-card): Week
   Progress bekommt einen Blue/Cyan-Top-Akzent (Trainings-/Fortschrittsthema, siehe .week-card::before
   unten), Marathon Readiness (H) einen Violet/Blue-Akzent (Ziel-/Prognosethema). */
.week-card { position: relative; overflow: hidden; }
.week-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--talvaxo-blue), var(--talvaxo-cyan));
}
/* Beta 7.8 (Punkt 55-60, Design-Vorschlag "Wochenfortschritt" uebernommen): horizontaler Fortschritts-
   balken statt Ring (Marathon Readiness behaelt den Ring — zwei sichtbar unterschiedliche
   Darstellungsformen in derselben Card-Familie statt zweier fast identischer Ringe). */
.wk-progress-row { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 8px; }
.wk-progress-value { font-family: var(--font-display); font-weight: 700; font-size: 20px; }
.wk-progress-unit { font-family: var(--font-body); font-weight: 400; font-size: 13px; color: var(--text-dim); }
.wk-progress-pct { font-family: var(--font-display); font-weight: 700; font-size: 16px; color: var(--talvaxo-cyan); }
.wk-progress-bar { height: 8px; border-radius: 4px; background: var(--wk-progress-track); overflow: hidden; margin-bottom: 14px; }
.wk-progress-bar-fill {
  height: 100%; width: 0; border-radius: 4px; transition: width 0.8s ease;
  background: linear-gradient(90deg, var(--talvaxo-blue), var(--talvaxo-cyan), var(--talvaxo-violet));
}
.wk-ring-focus { font-size: 12px; color: var(--text-muted); line-height: 1.45; margin-bottom: 4px; }
.wk-ring-focus b { color: var(--talvaxo-cyan); }
.wk-ring-quality { font-size: 11.5px; color: var(--text-dim); margin-bottom: 12px; }
.wk-ring-quality b { color: var(--text-muted); }

/* v10.2.2 "Deine Woche" day cells (Mandat §6-19) — jeder Tag zeigt Tag/Datum, Training-oder-Ruhetag,
   Trainingsdetail, Wetter (nur heute/Zukunft, echte Open-Meteo/wttr.in-Daten aus weather.js) und
   einen restraint Completion-/Adaptations-Indikator. Ersetzt die vorherigen schmalen km-Balken
   (.wk-daybar-*, entfernt) — dieselbe dayStatusClass-Klassifikation, jetzt als vollstaendige
   Tageskarte statt eines reinen Hoehenbalkens, damit Wetter/Titel/Distanz uebrhaupt Platz haben. */
.week-strip-label { font-size: 10px; letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-dim); margin-bottom: 8px; }
/* v10.3.7 UX addendum bugfix (Nutzer-Feedback nach zwei rejizierten Workarounds -- Text weder
   kuerzen noch mitten im Wort ohne Trennzeichen brechen lassen): eine starre repeat(7, 1fr) auf der
   Kartenbreite, die sich "Diese Woche" mit "Race Readiness" teilt (.dash-zone-row--week-goal, ca.
   50% der Content-Breite), ergab Spalten von nur ~54-72px -- zu schmal fuer einen Titel wie "(Basis
   aufbau)" (13 Zeichen) auf einer Zeile bei lesbarer Schriftgroesse, egal welche Wrap-Strategie
   (hyphens:auto UND ein manuell eingefuegtes Soft-Hyphen-Zeichen rendern in diesem Chromium-Build
   nachweislich beide keinen sichtbaren Trennstrich). Verallgemeinert stattdessen dieselbe, bereits
   bewaehrte Mobile-Loesung (siehe die bisherige @media max-width:480px-Regel weiter unten, jetzt
   hier zusammengefuehrt) auf JEDE Breite: eine garantierte Mindestbreite pro Tag (minmax(108px,1fr))
   plus horizontales Scrollen innerhalb des Streifens, sobald selbst diese Mindestbreite x 7 nicht in
   die verfuegbare Kartenbreite passt -- Woche-vs-Race-Readiness-Nebeneinander (Nutzerwunsch, siehe
   .dash-zone-row--week-goal) bleibt dadurch erhalten, ohne die Tagesspalten wieder zu quetschen.
   Ist die Karte breit genug (z.B. allein auf einer Zeile, oder auf sehr breiten Monitoren), wachsen
   die Spalten ueber 108px hinaus und zeigen alle 7 nebeneinander ohne Scroll -- dasselbe minmax(…,
   1fr)-Verhalten, das die alte Mobile-Regel bereits nutzte. */
.wk-day-row {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(108px, 1fr);
  gap: 6px; align-items: stretch; overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: 4px; margin: 0 -4px; padding-left: 4px; padding-right: 4px;
  /* Reale, live gefundene Nebenwirkung: overflow-x:auto laesst den Browser (CSS Overflow Module,
     "visible computes to auto"-Regel) overflow-y ebenfalls auf "auto" berechnen, auch wenn hier nie
     overflow-y gesetzt wurde -- explizites overflow-y:visible aendert daran NICHTS, dieselbe Regel
     greift trotzdem. Als Flex-Kind von .week-card (.dash-card ist display:flex;flex-direction:
     column) macht ein nicht-"visible" overflow in der Hauptachse min-height:auto zu 0 (Flexbox-Spec,
     "automatic minimum size") -- sobald .week-card per height:100% auf die Hoehe der kuerzeren
     Race-Readiness-Karte nebenan gestreckt wird (.dash-zone-row--week-goal), schrumpfte GENAU dieses
     eine Kind (0 statt inhaltsbasiert) auf ~4px zusammen, waehrend die anderen Geschwister (Fokus-
     Zeile etc., ohne dieses Overflow-Verhalten) ihre normale Groesse behielten. flex-shrink:0 macht
     das unabhaengig vom berechneten min-height explizit: dieser Streifen darf nie unter seine
     inhaltsbasierte Hoehe schrumpfen, egal wie stark .week-card sonst gestreckt/gestaucht wird. */
  flex-shrink: 0;
}
.wk-day-cell {
  display: flex; flex-direction: column; gap: 6px; padding: 8px 6px; border-radius: var(--radius-sm);
  background: var(--panel-alt); border: 1px solid transparent; min-width: 0;
  scroll-snap-align: start;
}
/* Bugfix (Nutzer-Screenshot, echter gefundener Bug): align-items:baseline richtete das
   HEUTE-Label (ein gepaddetes, abgerundetes Pill-Badge, nicht reiner Fliesstext) an der
   Text-Baseline seiner Geschwister (.wk-day-dow/.wk-day-date, deutlich unterschiedliche
   Schriftgroessen 11px/10px) aus -- dadurch ragte das Badge sichtbar ueber die obere Kante der
   Tageskarte hinaus. align-items:center ist robust gegen genau diese Mischung aus reinem Text und
   einem eigenen, vertikal gepaddeten Badge. */
/* Bugfix (Nutzer-Screenshot, echter gefundener Bug: "geht ueber das Feld hinaus"): eine 7-spaltige
   Grid-Zelle ist zu schmal, um "So" + "06.09." + das "Heute"-Badge nebeneinander auf einer Zeile
   unterzubringen (gemessen: ~89px benoetigt vs. ~56px verfuegbare Zellenbreite) -- ohne flex-wrap
   ragte das Badge sichtbar rechts ueber die Kartenkante hinaus (.wk-day-cell hat overflow:visible).
   flex-wrap:wrap laesst "Heute" bei Platzmangel auf eine eigene Zeile faellen, statt zu ueberlaufen;
   betrifft nur die eine Zellenhoehe des aktuellen Tages, kein Layout-Sprung bei den anderen sechs. */
.wk-day-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; flex-wrap: wrap; }
.wk-day-dow { font-family: var(--font-body); font-weight: 600; font-size: 11px; color: var(--text-muted); }
.wk-day-date { font-size: 10px; color: var(--text-dim); }
/* Mandat §9 "Today Highlight" — subtiler Cyan-Outline + Label, kein Glow. */
.wk-day-today { border-color: var(--talvaxo-cyan); background: var(--surface-raised); }
.wk-day-today-label {
  font-family: var(--font-body); font-size: 8.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--talvaxo-cyan); background: color-mix(in srgb, var(--talvaxo-cyan) 16%, transparent); border-radius: 3px; padding: 1px 4px;
}
/* Nutzer-Screenshot ("Text ist abgeschnitten"): lange, unteilbare Woerter/Klammer-Kombinationen wie
   "Long Run (Basisaufbau) · 11 km" konnten in einer zu schmalen Spalte per overflow-wrap:break-word
   MITTEN im Wort brechen ("Basisauf" / "bau)"), ohne Trennzeichen -- sah wie abgeschnittener/
   korrupter Text aus. Die eigentliche Behebung ist strukturell (.wk-day-row/.wk-day-cell oben
   garantieren jetzt eine Mindestspaltenbreite, siehe dortiger Kommentar) -- hyphens:auto bleibt
   zusaetzlich als Best-Effort stehen (schadet nicht, greift aber nachweislich nicht in jedem
   Chromium-Build, siehe week.js-Kommentar; kein Verlass allein darauf). */
.wk-day-training { font-size: 11px; line-height: 1.35; color: var(--text); min-height: 2.6em; overflow-wrap: break-word; hyphens: auto; }
.wk-day-is-rest .wk-day-training { color: var(--text-dim); font-style: italic; }
/* v10.3.7 UX addendum (Mandat SS20-34, "This Week" day strip visual hierarchy): Today bleibt der
   bereits bestehende, restraint Cyan-Outline-Look (.wk-day-today oben, unveraendert) -- past days
   werden hier NEU dezent gedaempft (nur Deckkraft, kein Content entfernt/versteckt, weiterhin voll
   lesbar), zukuenftige Tage bleiben unveraendert klar/voll deckend (kein expliziter Klassenzusatz
   noetig, das ist bereits der Default-Zustand jeder .wk-day-cell). */
.wk-day-past { opacity: 0.72; }
.wk-day-foot { display: flex; align-items: center; justify-content: space-between; gap: 4px; min-height: 20px; flex-wrap: wrap; }
.wk-day-weather { display: inline-flex; align-items: center; gap: 3px; font-size: 10.5px; color: var(--text-muted); }
.wk-day-weather .weather-icon-svg { width: 13px; height: 13px; }
.wk-day-weather-temp { font-weight: 600; }
.wk-day-weather-loading, .wk-day-weather-missing { color: var(--text-dim); font-size: 10.5px; }
/* Mandat §10 "Completed State" — Check-Icon + gedaempfter Erfolgsstatus, kein flaechiges Gruen. */
.wk-day-badge {
  display: inline-flex; align-items: center; gap: 2px; font-size: 9.5px; font-weight: 600; border-radius: 3px; padding: 1px 4px;
}
.wk-day-badge-icon { width: 9px; height: 9px; }
.wk-day-badge-completed { color: var(--status-good); background: color-mix(in srgb, var(--status-good) 14%, transparent); }
/* Mandat §11 "Adapted State" — restraint Violet-Marker statt eines vollflaechig lilanen Tages. */
.wk-day-badge-adapted { color: var(--talvaxo-violet); background: color-mix(in srgb, var(--talvaxo-violet) 14%, transparent); }
/* Nutzeranfrage (v10.3.1-Folgefix): ausgelassene Einheit — bewusst Amber/--color-attention statt
   Crimson/--color-warning, um keine Warn-/Fehler-Konnotation zu erzeugen (dieses Projekt bewertet
   ausgelassene Trainings nirgends moralisch, siehe week.js-Kommentar). */
.wk-day-badge-missed { color: var(--color-attention); background: color-mix(in srgb, var(--color-attention) 14%, transparent); }
.wk-day-completed { border-color: color-mix(in srgb, var(--status-good) 30%, transparent); }
.wk-day-adapted { border-color: color-mix(in srgb, var(--talvaxo-violet) 30%, transparent); }
.wk-weather-unavailable { font-size: 11px; color: var(--text-muted); }
.wk-weather-retry-btn {
  background: none; border: none; color: var(--talvaxo-cyan); font-size: 11px; cursor: pointer; padding: 0; text-decoration: underline;
}
/* Mandat §14 "Mobile Weekly View" — kein erzwungenes 7-Spalten-Gequetsche: horizontaler
   Scroll-Snap-Streifen statt sieben winziger Saeulen, aktueller Tag bleibt sofort sichtbar (Beginn
   der Reihe), Touch-Scroll ist der offensichtliche Interaktionsmodus. Bleibt LOKAL auf das Modul
   begrenzt (overflow-x hier, nicht auf Seitenebene) — kein Page-Level-Overflow (Mandat §14 Ende).
   v10.3.7 Folgefix: dieses Verhalten ist jetzt die BASISREGEL oben (nicht mehr nur <480px) -- ein
   eigener Mobile-Media-Query hier waere seitdem redundant, siehe Kommentar bei .wk-day-row. Auf
   Mobile bleibt scroll-snap-type dabei bewusst weiterhin "mandatory" (fester Einrastpunkt beim
   Touch-Swipe), waehrend die Basisregel "proximity" nutzt (weniger aufdringlich bei Maus/Trackpad-
   Scroll auf Desktop/Tablet). */
@media (max-width: 480px) {
  .wk-day-row { scroll-snap-type: x mandatory; }
}

/* ============================================================
   G0. WEEKLY MODULE STRUCTURE (v10.3.7 UX addendum, Mandat SS20-34) — "Your Week" is now THREE
   visually distinct stacked modules (This Week / Running Today / Next Key Session) instead of one
   monolithic card with the weather collapsed inside a <details> and the next key session as a
   bottom-of-card afterthought. .wk-modules-stack is the ONLY direct child #week-card-slot's
   .dashboard-grid--week now renders (see overview/week.js renderWeekCard) — a plain flex column, no
   card chrome of its own, so it slots into the existing single-card grid/flex-row rules below
   (.dashboard-grid--week > .dash-card, .dash-zone-row--week-goal ...) without duplicating them; each
   module inside it is its own real .dash-card, same design system, same radius/border/shadow as
   every other card on this page (Mandat: "structural refinement, not a visual redesign").
   ============================================================ */
.wk-modules-stack { display: flex; flex-direction: column; gap: var(--card-gap); min-width: 0; }
/* Reale, live gefundene Nebenwirkung (derselbe Mechanismus wie beim .wk-day-row-Fix oben): jedes der
   3 Module ist ein .dash-card, und .dash-card's app-weite Basisregel setzt height:100% (fuer den
   generischen "Karte fuellt ihre Grid-Zelle"-Fall, siehe dortiger Kommentar) -- innerhalb dieses
   Flex-Stacks konkurrieren dadurch alle 3 Module gleichzeitig um 100% DER STACK-Hoehe, waehrend der
   Stack selbst wiederum per .dash-zone-row--week-goal auf die Hoehe der (oft kuerzeren) Race-
   Readiness-Karte gestreckt wird. Wird die Summe der 3 natuerlichen Modul-Hoehen dadurch grosser als
   diese gestreckte Stack-Hoehe (z.B. seit der Tagesstreifen breitere, aber dadurch auch hoehere
   Spalten bekam), schrumpft der Flex-Algorithmus eines oder mehrere Module unter ihre eigentlich
   benoetigte Hoehe -- sichtbar NICHT als Ueberlauf, sondern als stille Kappung durch .week-card's
   eigenes overflow:hidden (dort nur fuer den Akzentstreifen-Pseudo-Element gedacht, nicht als
   Content-Clip). height:auto+flex-shrink:0 gibt jedem Modul stattdessen immer seine eigene,
   inhaltsbasierte Groesse -- die gestreckte Stack-Hoehe bleibt nur noch eine Zielgroesse, kein
   Zwang, der einzelne Module unter ihren Inhalt quetschen darf. */
.wk-modules-stack > .week-card, .wk-modules-stack > .weather-card, .wk-modules-stack > .next-key-card { height: auto; flex-shrink: 0; }

/* MODULE 2 "Running Today" — reuses the .weather-card class purely for the shared radius-uplift
   rule (see the big ALLER-Karten-Klassennamen selector list further below) and gets its own subtle
   teal/cyan top accent, the same visual device .week-card already uses for its own accent, just in
   the weather palette instead of the training palette — a distinct module, not a copy of Module 1. */
.dash-card.weather-card { position: relative; overflow: hidden; }
.dash-card.weather-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--teal), var(--talvaxo-cyan));
}
/* A. "At a glance" — same content/markup as before (.weather-current), now simply the FIRST thing
   in Module 2 instead of appearing after the best-window block (Mandat internal order A→B→C→D). */
/* B. Best Running Window keeps .best-window/.best-window-prominent unchanged. The honest "no truly
   ideal window today" state (Mandat SS17-19) reuses the same sub-surface treatment instead of the
   block silently disappearing, which was the old (buggy) behaviour. */
.rt-no-window { background: var(--panel-alt); border-radius: 8px; padding: 12px 14px; margin-bottom: 10px; font-size: 12px; color: var(--text-muted); line-height: 1.5; }
/* C. "Today's Recommendation" — promoted out of the old bare .weather-advice footnote (which sat
   silently after the D-tier stats with no heading) into its own labelled, readable block so it is
   not buried (Mandat: "own readable block, not buried"). */
.rt-recommendation { background: var(--panel-alt); border-radius: 8px; padding: 12px 14px; margin-bottom: 10px; }
.rt-recommendation .rt-label { margin-bottom: 4px; }
.rt-recommendation-text { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
/* D. Weather Details (Wind/Rain/Humidity) + the hourly strip — deliberately the LOWEST visual
   priority section in the module (smallest label, no sub-surface background), same
   .weather-stats/.weather-timeline markup as before, just moved to the end. */
.rt-details { padding-top: 8px; border-top: 1px solid var(--border-soft); }
.rt-label { font-family: var(--font-body); font-size: 10px; text-transform: uppercase; color: var(--text-dim); letter-spacing: 0.04em; margin-bottom: 6px; }
/* Optional balanced two-column layout on wide screens (Mandat: "Running Today MAY use a two-column
   layout if it fits the existing design — do not force it if it reduces readability"): current
   conditions + recommendation on the left, best window + hourly strip on the right. Same 1100px
   threshold as .dashboard-grid--week's own max-width cap above -- below it the module's card isn't
   reliably wide enough for two readable columns, so it stays a single stacked column (also always
   the case on mobile/tablet, never forced there). */
@media (min-width: 1100px) {
  /* A and C keep DOM order (source order A, B, C, D, see overview/weather-card.js
     renderWeatherDetailContent) but are pinned to column 1 via .rt-col-left; B and D to column 2
     via .rt-col-right -- grid auto-placement stacks same-column items in source order (A above C,
     B above D) without needing an explicit grid-row on each, and without reordering the DOM itself
     (so the mobile/stacked case below 1100px keeps the required A->B->C->D reading order for free,
     since .rt-body isn't a grid at all there). */
  .rt-body { display: grid; grid-template-columns: 1fr 1fr; gap: 0 20px; align-items: start; }
  .rt-body .rt-col-left { grid-column: 1; min-width: 0; }
  .rt-body .rt-col-right { grid-column: 2; min-width: 0; }
}

/* MODULE 3 "Next Key Session" — its own compact card (Mandat: "own compact mini-card, removed from
   the bottom of the Weather module since it's Training context, not Weather detail"), same
   .nki-*-content as the previous inline footer, just no longer glued to the bottom of another card.
   Violet/blue accent, matching how this project already marks adapted/plan-related surfaces
   (.wk-day-badge-adapted etc.) elsewhere, distinct from both Module 1's blue/cyan and Module 2's
   teal/cyan accents. */
.dash-card.next-key-card { position: relative; overflow: hidden; }
.dash-card.next-key-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--talvaxo-violet), var(--talvaxo-blue));
}
/* Card title (dash-card__title) now carries the "Next Key Session" label itself (Mandat: own
   compact mini-card, consistent header with Modules 1/2) -- .nki-body is just the session content
   below it, left-aligned like every other card's body text (previously right-aligned to balance
   against a second, now-removed inline label on the same row). */
.next-key-inline { display: flex; }
.next-key-inline .nki-body { display: flex; flex-direction: column; }
.next-key-inline .nki-title { font-size: 13px; font-weight: 600; color: var(--text); }
.next-key-inline .nki-meta { font-size: 11.5px; color: var(--text-muted); margin-top: 1px; }

/* ============================================================
   H. MARATHON GOAL
   ============================================================ */
/* V6.2: Chrome jetzt via .dash-card (siehe overview/marathon-readiness.js), Dopplung entfernt. */
.goal-card { position: relative; overflow: hidden; }
.goal-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--talvaxo-violet), var(--talvaxo-blue));
}
.goal-card .gc-race-name { font-family: var(--font-display); font-size: 16px; font-weight: 600; margin-bottom: 2px; }
.goal-card .gc-race-date { font-family: var(--font-body); font-size: 11.5px; color: var(--text-dim); margin-bottom: 14px; }
/* Beta 7.6 (Punkt 102-106): ein zusammenhaengender Stat-Streifen statt 3 getrennter Zeilentypen —
   der Countdown ("Tage") bleibt als "Hero"-Chip optisch fuehrend, die uebrigen 3 Chips gleichrangig. */
.gr-stat-strip { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 14px; }
@media (min-width: 380px) { .gr-stat-strip { grid-template-columns: repeat(4, 1fr); } }
.gr-stat {
  background: var(--panel-alt); border: 1px solid var(--border-soft); border-radius: var(--talvaxo-radius-sm);
  padding: 9px 8px; text-align: center;
}
.gr-stat-hero { background: rgba(122, 92, 255, 0.09); border-color: rgba(122, 92, 255, 0.28); }
.gr-stat-value { font-family: var(--font-display); font-weight: 700; font-size: 20px; color: var(--talvaxo-violet); line-height: 1.15; }
.gr-stat-value-sm { font-size: 13px; color: var(--text); }
.gr-stat-label { font-size: 9px; text-transform: uppercase; letter-spacing: var(--ls-label); color: var(--text-dim); margin-top: 3px; }
.goal-readiness-row { display: flex; justify-content: space-between; align-items: center; padding-top: 12px; border-top: 1px solid var(--border-soft); }
.goal-readiness-row .gr-label { font-size: 12px; color: var(--text-muted); }
.goal-readiness-row .gr-value { font-family: var(--font-body); font-size: 13px; font-weight: 700; }

/* Race Readiness 2.0 — Fortschrittsring + Dimensions-Balken (Teil 34-37, aus coach-engine.js) */
.rr2-overall { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-top: 1px solid var(--border-soft); margin-bottom: 4px; }
.dash-empty-tight { margin-top: 4px; }
.rr2-ring { position: relative; width: 64px; height: 64px; flex-shrink: 0; --pct: 0; }
.rr2-ring svg { width: 64px; height: 64px; transform: rotate(-90deg); }
.rr2-ring-track { fill: none; stroke: var(--border-soft); stroke-width: 6; }
.rr2-ring-fill {
  fill: none; stroke: var(--teal); stroke-width: 6; stroke-linecap: round;
  stroke-dasharray: 175.9; stroke-dashoffset: calc(175.9 - (175.9 * var(--pct, 0) / 100));
  transition: stroke-dashoffset 0.8s ease;
}
.rr2-ring-pct { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: 15px; font-weight: 700; }
.rr2-overall-label { font-size: 13px; color: var(--text); font-weight: 600; }
.rr2-overall-conf { font-family: var(--font-body); font-size: 10.5px; color: var(--text-dim); margin-top: 2px; }
.dim-bars { display: flex; flex-direction: column; gap: 7px; margin-bottom: 10px; }
.dim-bar-row { display: grid; grid-template-columns: 108px 1fr 34px; align-items: center; gap: 8px; font-size: 11px; }
.dim-bar-row .db-label { font-family: var(--font-body); font-size: 9.5px; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.02em; }
.dim-bar-track { height: 6px; background: var(--panel-alt); border-radius: 3px; overflow: hidden; }
.dim-bar-fill { height: 100%; width: var(--fill, 0%); background: var(--indigo); border-radius: 3px; transition: width 0.6s ease; }
.dim-bar-row .db-value { font-family: var(--font-body); font-size: 10.5px; color: var(--text-dim); text-align: right; }
.limiter-note { font-size: 12px; color: var(--amber); background: var(--amber-dim); border-radius: 8px; padding: 8px 10px; margin-bottom: 10px; }

/* Goal Outlook / Goal Probability Details (Teil AL-AN) — Prozentzahl bewusst nur im
   eingeklappten Detail, nie als primäre Aussage (keine Scheingenauigkeit). */
.goal-probability-detail { margin-top: 6px; font-size: 11.5px; color: var(--text-dim); }
.goal-probability-detail summary { cursor: pointer; color: var(--text-muted); }
.goal-probability-detail summary::-webkit-details-marker { display: none; }
.goal-probability-detail summary::before { content: '▸ '; }
.goal-probability-detail[open] summary::before { content: '▾ '; }
.goal-probability-detail .gpd-body { margin-top: 6px; line-height: 1.5; }

/* ============================================================
   I. Fueling hint (kompakt)
   ============================================================ */
.fueling-hint {
  display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 8px;
  background: var(--moss-dim); font-size: 12.5px; color: var(--moss); margin-top: 12px;
}

/* ============================================================
   J. TRAINING CAPABILITY (Section 6, Nutzerauftrag "Capability Semantik verbessern", Teil Q-X)
   ============================================================ */
/* V6.2: Chrome jetzt via .dash-card (siehe overview/capability.js), Dopplung entfernt. */
.capability-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-4); }
@media (min-width: 700px) { .capability-grid { grid-template-columns: repeat(2, 1fr); } }
.cap-block { background: var(--panel-alt); border-radius: var(--radius-sm); padding: var(--space-4); }
.cap-block-title { font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin-bottom: var(--space-3); }
.cap-metrics { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); margin-bottom: var(--space-3); }
.cap-metric { display: flex; flex-direction: column; gap: 2px; }
.cap-metric.cap-metric-wide { grid-column: 1 / -1; }
.cap-metric .cm-label { font-family: var(--font-mono); font-size: 9px; text-transform: uppercase; color: var(--text-dim); letter-spacing: 0.02em; }
.cap-metric .cm-value { font-family: var(--font-display); font-size: 15px; font-weight: 600; color: var(--text); }
.cap-note { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; }
.cap-note b { color: var(--text); }

/* ============================================================
   K. DEEP ANALYTICS (Section 7) — Progressive Disclosure, Links auf Detailseiten
   ============================================================ */
.analytics-section {
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius); padding: 4px;
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
}
.analytics-summary {
  cursor: pointer; list-style: none; padding: 14px 18px; display: flex; flex-direction: column; gap: 2px;
  transition: background var(--transition-fast);
}
.analytics-summary::-webkit-details-marker { display: none; }
.analytics-summary > span:first-child { font-family: var(--font-display); font-size: 14.5px; font-weight: 600; color: var(--text); }
.analytics-summary::before { content: '▸ '; color: var(--text-dim); }
.analytics-section[open] .analytics-summary::before { content: '▾ '; }
.analytics-summary-hint { font-size: 12px; color: var(--text-dim); }
.analytics-summary:hover { background: var(--panel-alt); border-radius: var(--radius-sm); }
.analytics-links { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-2); padding: 4px 14px 14px; }
@media (min-width: 700px) { .analytics-links { grid-template-columns: repeat(3, 1fr); } }
.analytics-link {
  display: flex; flex-direction: column; gap: 2px; padding: var(--space-3); border-radius: var(--radius-sm);
  background: var(--panel-alt); text-decoration: none; border: 1px solid transparent;
  transition: transform var(--transition-fast), border-color var(--transition-fast), background var(--transition-fast);
}
.analytics-link .al-label { font-size: 13px; font-weight: 600; color: var(--text); }
.analytics-link .al-desc { font-size: 11px; color: var(--text-muted); }
.analytics-link:hover { transform: translateY(var(--card-lift-hover)); border-color: var(--teal); background: var(--panel-raised); }
.analytics-link:active { transform: scale(var(--card-scale-press)); }
.analytics-link:focus-visible { outline: 2px solid var(--teal); outline-offset: 2px; }

/* ============================================================
   L. HOVER / CLICK / FOCUS MICROINTERACTIONS (Nutzerauftrag Teil F-I, AX)
   Gilt für alle "großen" Dashboard-Karten, die entweder klickbar sind (Kalender-Link-artig) oder
   ein <details>-Drilldown enthalten — dezente Anhebung + Border/Surface-Änderung, NIE eine
   komplette Farbänderung (Teil G). Karten ohne Interaktion (z.B. reine Anzeige-Cards ohne Klick-
   ziel) bleiben bewusst ohne Hover-Effekt, um nicht "klickbar" vorzutäuschen (Teil AX-Prinzip:
   visuelles Signal muss der tatsächlichen Interaktivität entsprechen).
   ============================================================ */
/* V6.2: weather-card/briefing-card/week-card/goal-card/capability-card jetzt aus dieser Liste
   entfernt — ihre Transition kommt bereits vollständig (inkl. background) von .dash-card, das sie
   seit V6.2 im DOM tragen. hero-card/readiness-card nutzen (noch) kein .dash-card (hero-card hat
   ein eigenes, inkompatibles Padding-Modell mit .hero-head/.hero-body statt Card-weitem Padding —
   siehe Moduldoku weiter unten bei .hero-card), behalten deshalb ihre eigene Transition-Regel. */
.hero-card, .readiness-card {
  transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
}
.hero-why-toggle summary, .goal-probability-detail summary, .rpe-btn, .action-btn {
  transition: transform var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.rpe-btn:hover { border-color: var(--teal); color: var(--teal); }
.rpe-btn:active { transform: scale(var(--card-scale-press)); }
.rpe-btn:focus-visible, .action-btn:focus-visible, .hero-why-toggle summary:focus-visible {
  outline: 2px solid var(--teal); outline-offset: 2px;
}

/* Tageskontext-Betonung (Teil AV/N/O) — verändert NUR Betonung innerhalb der stabilen Struktur,
   nie die Reihenfolge der Sections. Quality-/Long-Run-Tage bekommen eine sichtbar angehobene
   Hero-Card (die farbliche Unterscheidung selbst kommt bereits über --stc/session-type-*); an
   einem Ruhetag mit auffälligen Signalen wird stattdessen die Readiness-Karte betont. */
.hero-zone[data-day-context="quality"] .hero-zone-main .hero-card,
.hero-zone[data-day-context="long_run"] .hero-zone-main .hero-card,
.hero-zone[data-day-context="post_workout"] .hero-zone-main .hero-card {
  box-shadow: var(--shadow-md);
}
.hero-zone[data-day-context="rest"] .hero-zone-side .readiness-card.emphasis {
  box-shadow: var(--shadow-md);
}
.readiness-card.emphasis { border-color: rgba(240, 169, 78, 0.4); }
.readiness-card.emphasis.status-bad-emphasis { border-color: rgba(239, 91, 107, 0.45); }

/* Skeleton loading primitives moved to assets/css/components.css (TALVAXO UX/Performance Update)
   — dashboard.css is only loaded on overview.html, but Training/Health/Coach also need
   page-shaped skeletons and load components.css instead. See components.css for the rules. */

/* ============================================================
   Empty / error states
   ============================================================ */
.dash-empty {
  text-align: center; padding: 24px 16px; color: var(--text-dim); font-size: 12.5px;
  background: var(--panel-alt); border-radius: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; }
  .wk-progress-bar-fill { transition: none; }
  .rr2-ring-fill, .dim-bar-fill { transition: none; }
  .hero-card, .readiness-card,
  .analytics-link, .rpe-btn, .action-btn, .hero-why-toggle summary, .goal-probability-detail summary,
  .info-dot::after {
    transition: none;
  }
}

/* ============================================================================================
   V5.2 VISUAL REBUILD — komplett neu gebaute Komponentenschicht (Nutzerauftrag "Full Visual
   Rebuild of the Overview/Daily Dashboard"). Ergänzt die obigen, bestehenden Klassen (die aus
   Test-/Rückwärtskompatibilitätsgründen im DOM erhalten bleiben) um eine sichtbar neue
   Oberfläche: Daily Status Hero, interaktive Metric Tiles, Segment-Bar, Range-Bar, Wetter-Icon/
   Timeline sowie ein durchgängiges Animations-/Hover-/Depth-System.
   ============================================================================================ */

/* ---------------------------------------------------------------------------
   ZONE A — DAILY STATUS HERO (Punkt 3/4) — neue volle-Breite-Komponente, der
   klare Einstiegspunkt der Seite. Großer Readiness-Ring, Statuston als Glow/
   Border, Coach-Entscheidung, primäre CTA.
   --------------------------------------------------------------------------- */
/* V6.2 (Mandat Teil H, Punkt 50): margin-bottom folgt jetzt demselben zentralen Zonen-Rhythmus
   (--zone-gap, responsiv) wie .dashboard-section statt eines unabhängigen, fest auf 20px
   verdrahteten Werts — Daily Hero ist die einzige Zone ohne eigenen .dashboard-section-Wrapper
   (siehe overview.js renderTop), muss den Rhythmus zur nächsten Zone deshalb hier exakt
   nachbilden, damit der Übergang Daily Hero -> Gesundheit denselben Abstand hat wie alle übrigen
   Zonenübergänge. */
/* Beta 7.5 (Punkt 60-67, "Hero-Rekomposition" — P1): .daily-hero ist jetzt nur noch die lose
   AEUSSERE Huelle (schwaecherer eigener Rahmen/Schatten) um drei eigenstaendige Module
   (.dh-module-training/.dh-module-readiness/.dh-module-recovery, siehe unten) — bewusst KEIN
   einzelnes grosses Rechteck mehr wie in Beta 7.4 (dort trug .daily-hero selbst Border+Shadow+
   Glow, die Module waren nur Flex-Kinder ohne eigene Kartenoptik). */
/* v10.2.1: .daily-hero (die Stage) wird jetzt IMMER direkt von .morning-briefing-card gefolgt
   (Reihenfolge getauscht, siehe overview.js renderTop) -- der Abstand dazwischen ist bewusst der
   ENGERE --space-4-Rhythmus (vorher trug .morning-briefing-card selbst diesen engen Wert, als sie
   noch VOR der Stage stand), nicht der volle Zonen-Abstand. Der volle Zonen-Abstand zur naechsten
   ECHTEN Zone (Gesundheit & Bereitschaft) sitzt jetzt auf .morning-briefing-card selbst (siehe dort). */
.daily-hero {
  border-radius: var(--radius-lg);
  padding: var(--space-4) 0 0;
  margin-bottom: var(--space-4);
  background: transparent;
  border: none;
  position: relative;
  overflow: visible;
  box-shadow: none;
}
@media (max-width: 480px) { .daily-hero { padding: var(--space-2) 0 0; } }
/* Der zuvor hier sitzende "sehr dezente" radiale Glow hinter dem Modul-Verbund wurde entfernt
   (Nutzer-Feedback 2026-08-29, per Screenshot): die weiche Aufhellung blieb gegen den dunklen
   Hintergrund als sichtbarer, rechteckiger Fleck ueber die runden Kartenecken hinaus sichtbar
   (".daily-hero" ist bewusst "overflow: visible", der Glow per negativem inset groesser als die
   Karte selbst) statt wie beabsichtigt unauffaellig zu wirken. Keine Ersatz-Deko hier — die Karte
   traegt ihre eigene Optik bereits ueber .daily-hero-modules. */
/* Beta 7.8 (Punkt 34-35, "Hero soll wie EIN Hero wirken, nicht wie drei zufaellige Cards"): die
   Referenz-Skizze zeigt Today-Training/Readiness/Recovery als EINE zusammenhaengende Surface mit
   duennen internen Trennlinien statt drei einzeln umrandeter/beschatteter Karten mit Luecken
   dazwischen (Beta 7.5-7.7-Zustand). Struktur (grid-template-areas je Breakpoint) bleibt
   unveraendert — nur Border/Shadow/Background wandern von den einzelnen .dh-module auf die
   gemeinsame .daily-hero-modules-Flaeche, Trennung erfolgt ueber duenne interne border-Linien. */
/* v10.2 "APP VISUAL EXPERIENCE" (Mandat Teil 10, "TALVAXO Intelligence Stage"): --radius-lg ->
   --radius-xl (grosszuegigerer Radius fuer die Stage-Flaeche, Mandat Teil 22 "large Intelligence
   surfaces -> larger radius") + position:relative, damit .dh-stage-x (Dynamic X, siehe unten) sich
   an dieser Flaeche ausrichten kann. */
/* v10.2.1 (Mandat Teil 34-37, "Light Mode... too many white/light-grey cards... insufficient
   perceived depth"): die Stage nutzte bisher dieselbe --surface-hero-Flaeche wie JEDE andere Karte
   -- im Dark Mode reicht der Kontrast zu --bg dafuer aus (Nutzer-Feedback: Dark Stage wirkt bereits
   premium), im Light Mode nicht (beide sind Grautoene aehnlicher Helligkeit). --surface-stage ist ein
   NEUER, NUR von der Stage genutzter Token -- im Dark Mode identisch zu --surface-hero (kein
   Aenderungsbedarf dort), im Light Mode ein sichtbar kuehlerer/helleres Blau-Weiss statt des
   generischen Graus (siehe tokens-light.css). */
.daily-hero-modules {
  position: relative; z-index: 1; display: grid; grid-template-columns: 1fr; gap: 0;
  grid-template-areas: "header" "training" "readiness" "decision";
  background: var(--surface-stage); border: 1px solid var(--border-soft); border-radius: var(--radius-xl);
  box-shadow: var(--shadow-raised); overflow: hidden;
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
}
.daily-hero-modules::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none; z-index: 2;
  background: var(--talvaxo-gradient);
}
/* Dynamic X als Stage-Signatur (Mandat Teil 17/18/62): dieselbe freigestellte, offizielle X-Grafik
   wie ueberall sonst im Produkt (assets/brand/talvaxo-x-mark.png, siehe .pub-brand-reflect auf der
   Public Website / .pub-think-core) -- KEIN CSS-nachgebautes X, KEIN neues Symbol. Rein statisches
   background-image (kein <img>, kein Animations-/Mousemove-Layer, keine zusaetzliche Canvas/RAF-
   Schleife, Mandat Teil 39/41) bei sehr niedriger Deckkraft, oben rechts anschnitten -- bewusst kein
   voll sichtbares zentriertes Logo (das waere "noch ein Logo-Placement", Mandat Teil 17), sondern
   raeumliche Markenidentitaet im Hintergrund. ~6-7% wahrgenommene Intensitaet (Mandat Teil 17:
   "5-10%"), unter jeglichem Text (z-index:0, alle Module haben z-index:1). */
.dh-stage-x {
  position: absolute; z-index: 0; top: -8%; right: -6%; width: 46%; aspect-ratio: 1314 / 1197;
  background-image: url(/assets/brand/talvaxo-x-mark.png);
  background-size: contain; background-repeat: no-repeat; background-position: center;
  opacity: 0.07; pointer-events: none;
}
@media (prefers-reduced-motion: reduce), (max-width: 900px) { .dh-stage-x { opacity: 0.05; } }
.dh-stage-header { grid-area: header; position: relative; z-index: 1; padding: var(--space-5) var(--space-5) 0; }
.daily-hero-modules--no-decision { grid-template-areas: "header" "training" "readiness"; }
.dh-module-readiness, .dh-module-decision { border-top: 1px solid var(--border-soft); }
@media (min-width: 720px) {
  .daily-hero-modules { grid-template-columns: 1.6fr 1fr; grid-template-areas: "header header" "training readiness" "decision decision"; }
  .daily-hero-modules--no-decision { grid-template-areas: "header header" "training readiness"; }
  .dh-module-readiness { border-top: none; border-left: 1px solid var(--border-soft); }
  .dh-module-decision { border-top: 1px solid var(--border-soft); }
}
@media (min-width: 1100px) {
  .daily-hero-modules { grid-template-columns: 1.5fr 1fr 1fr; grid-template-areas: "header header header" "training readiness decision"; }
  .daily-hero-modules--no-decision { grid-template-columns: 1.6fr 1fr; grid-template-areas: "header header" "training readiness"; }
  .dh-module-decision { border-top: none; border-left: 1px solid var(--border-soft); }
}
/* Mandat Teil 46/47 ("Mobile Intelligence Stage", Prioritaet Greeting -> Readiness -> Decision ->
   Training): reine CSS `order` auf den Grid-Items unter 720px -- DOM-Reihenfolge/Markup-Semantik
   in hero.js bleibt unveraendert (Screenreader-Reihenfolge bleibt die inhaltlich sinnvolle Training-
   vor-Readiness-vor-Decision-Reihenfolge; nur die VISUELLE Reihenfolge auf schmalen Screens
   priorisiert Readiness/Decision vor den Trainingsdetails, wie im Mandat gefordert). */
@media (max-width: 719px) {
  .dh-stage-header { order: 1; }
  .dh-module-readiness { order: 2; }
  .dh-module-decision { order: 3; }
  .dh-module-training { order: 4; }
}
.dh-module {
  background: transparent; border: none; border-radius: 0; z-index: 1;
  padding: var(--space-5); box-shadow: none; position: relative; overflow: hidden;
}
.dh-module-training { grid-area: training; }
.dh-module-readiness { grid-area: readiness; display: flex; align-items: center; justify-content: center; }
.dh-module-decision { grid-area: decision; }
.dh-module-title { font-size: 10.5px; letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-dim); margin-bottom: var(--space-3); }
/* Violet-Akzent (Mandat Teil 16: "Use Violet selectively to identify adaptive output") -- NUR der
   Titel dieses einen Moduls traegt die Adaptive-Entscheidungsfarbe, nicht die gesamte Karte (Mandat
   Teil 8/61: nicht jedes Element gleich stark betonen). */
.dh-module-title--decision { color: var(--accent-adaptive); }
.dh-decision-status {
  display: inline-block; font-family: var(--font-display); font-size: 15px; font-weight: 600;
  margin-bottom: 6px;
}
.dh-decision-status--confirmed { color: var(--text); }
.dh-decision-status--adapted { color: var(--accent-adaptive); }
.dh-decision-line { font-size: var(--fs-body); color: var(--text-muted); line-height: var(--lh-normal); margin-bottom: var(--space-3); }
.dh-decision-why { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px dashed var(--hairline); }
.dh-decision-why-label { font-size: 9.5px; letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-dim); margin-bottom: 6px; }
.daily-hero-text { flex: 1; min-width: 0; text-align: center; }
@media (min-width: 720px) { .daily-hero-text { text-align: left; } }
/* Stage-Kopfzeile (Begruessung + Datum) -- war vorher Teil des Training-Moduls, steht jetzt EINMAL
   ueber allen drei Modulen (Mandat Teil 11: "GUTEN MORGEN" oben, nicht Teil des Trainingsblocks) UND
   wurde aus der Morning-Briefing-Karte darueber entfernt (siehe morning-briefing-card.js), die
   vorher wortgleich "Guten Tag." zeigte. */
.dh-greeting { font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 600; letter-spacing: -0.01em; color: var(--text); text-align: center; }
@media (min-width: 720px) { .dh-greeting { text-align: left; } }
.dh-date { font-family: var(--font-body); font-size: var(--fs-small); color: var(--text-dim); text-transform: uppercase; letter-spacing: var(--ls-label); margin-top: 2px; text-align: center; }
@media (min-width: 720px) { .dh-date { text-align: left; } }
.dh-training-line { font-family: var(--font-body); font-size: 10.5px; letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-dim); margin-bottom: var(--space-4); }
.dh-training-main { display: block; font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 600; color: var(--text); letter-spacing: -0.01em; text-transform: none; margin-top: 4px; }
.dh-cta {
  display: inline-flex; align-items: center; gap: 6px; padding: 10px 18px; border-radius: var(--radius-pill);
  background: var(--surface-interactive); color: var(--text); text-decoration: none; font-size: 13px; font-weight: 600;
  border: 1px solid var(--border-soft); transition: transform var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast);
}
.dh-cta:hover { background: var(--surface-selected); border-color: var(--color-primary); transform: translateY(var(--card-lift-hover)); }
.dh-cta:active { transform: scale(var(--card-scale-press)); }
.dh-cta:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }

/* Beta 7.4 Punkt 63-65: Ring etwas groesser/praesenter (148px -> 168px), damit die Readiness-Zone
   im neu getrennten rechten Hero-Bereich mehr visuelles Gewicht traegt. */
.daily-hero-ring { display: flex; flex-direction: column; align-items: center; width: 100%; }
.dh-ring { position: relative; width: 168px; height: 168px; --pct: 0; }
.dh-ring > svg { width: 168px; height: 168px; transform: rotate(-90deg); }
.dh-ring-track { fill: none; stroke: var(--hairline); stroke-width: 8; }
/* Mandat Teil 12 ("Readiness must become a hero metric... TALVAXO Cyan/Blue treatment"): der
   Ready/Normal-Zustand (kein Grund zur Vorsicht) nutzt jetzt die Marken-Intelligenzfarbe Cyan statt
   eines generischen Gruens -- staerkt die Markenbindung genau an der Stelle, die der Mandat als
   "Hero Metric" hervorheben soll. Caution/Recovery bleiben bewusst auf den bestehenden semantischen
   Warn-/Gefahrenfarben (Mandat Teil 7: "Status colors remain semantic", keine Vermischung mit den
   Markenfarben fuer echte Warnzustaende). */
.dh-ring-fill {
  fill: none; stroke: currentColor; stroke-width: 8; stroke-linecap: round; color: var(--accent-intelligence);
  stroke-dasharray: 326.7; stroke-dashoffset: calc(326.7 - (326.7 * var(--pct, 0) / 100));
  transition: stroke-dashoffset var(--transition-ring);
}
.hero-tone-warn .dh-ring-fill { color: var(--color-attention); }
.hero-tone-bad .dh-ring-fill { color: var(--color-warning); }
.dh-ring-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
.dh-ring-icon { font-size: 16px; color: var(--text-muted); }
.dh-ring-pct { font-family: var(--font-display); font-size: var(--fs-display); font-weight: 700; line-height: var(--lh-tight); }
.dh-ring-label { font-family: var(--font-body); font-size: 10px; letter-spacing: var(--ls-label); color: var(--text-muted); text-transform: uppercase; }
/* Kein Ersatzwert im Ring, Track bleibt sichtbar aber ohne Fill-Kreis (kein 0%-Balken, der wie
   ein echter Messwert aussehen könnte). */
.dh-ring-missing .dh-ring-track { opacity: 0.55; }
.dh-ring-dash { font-family: var(--font-display); font-size: var(--fs-display); font-weight: 700; color: var(--text-dim); }
.dh-trend-missing { color: var(--text-dim); }
/* Design-System-Update Punkt 47-49: der grosse Ring zeigt Garmins natives Training-Readiness-Wert
   (kein TALVAXO-Composite, siehe hero.js-Moduldoku) — bisher war das nur im aufgeklappten
   "Warum?"-Drawer erklaert, nicht direkt am Ring sichtbar. Klein/dezent, keine neue Datenquelle,
   nur eine Attributions-Beschriftung, damit dieser Wert nicht mit "Marathon Readiness"/"Race
   Readiness" (eigene TALVAXO-Kennzahl weiter unten auf der Seite) verwechselt wird. */
.dh-ring-source {
  margin-top: var(--space-2); text-align: center; font-family: var(--font-body); font-size: 9.5px;
  letter-spacing: 0.06em; color: var(--text-dim); text-transform: uppercase;
}

/* Daily Triad sitzt jetzt UNTER dem neuen Hero (eigene Sektion, siehe Layout-Kommentar oben in
   dieser Datei) — bekommt zusätzlich etwas Abstand nach oben für den Anchor-Scroll (#daily-triad). */
.daily-triad { scroll-margin-top: var(--space-5); }

/* ---------------------------------------------------------------------------
   TRAININGSSTRUKTUR — SEGMENT BAR (Punkt 12/13)
   --------------------------------------------------------------------------- */
.segment-bar { display: flex; gap: 3px; height: 10px; border-radius: 5px; overflow: hidden; margin-top: 14px; }
.segment-chip { flex: 1; min-width: 4px; background: var(--panel-alt); transition: transform var(--transition-fast); }
.segment-chip.seg-easy { background: var(--color-recovery); opacity: 0.55; }
.segment-chip.seg-main { background: var(--color-training); opacity: 0.4; }
.segment-chip.seg-hard { background: var(--color-primary); }
.segment-chip.seg-recovery { background: var(--color-recovery); }
.segment-chip:hover { transform: scaleY(1.6); }

/* ---------------------------------------------------------------------------
   DAILY METRICS — METRIC TILES (Punkt 7-9) — ersetzt visuell status-strip NUR
   auf der Übersicht (siehe overview.js renderMetricTiles).
   --------------------------------------------------------------------------- */
/* v10.2.1 "OVERVIEW REFINEMENT" (Mandat Teil 13-16, "7 equal cards" -> contextual groups): ZWEI
   benannte Kontext-Gruppen (Erholungskontext/Belastungskontext, siehe overview/metric-tiles.js)
   statt einer losen "Weitere Signale"-Unterueberschrift. Jede Gruppe ist EINE gemeinsame Flaeche
   (--surface-section -- bestehender, bisher kaum genutzter Token, genau fuer diese "Sekundaerflaeche
   zwischen Stage und einzelner Karte"-Rolle gedacht) statt sieben unabhaengiger Karten mit je
   eigenem Rand/Schatten/backdrop-filter (siehe .context-group .metric-tile weiter unten fuer die
   dazu passende Kachel-Verschlankung -- spart nebenbei 7 backdrop-filter-Instanzen, Mandat Teil 53). */
.context-groups { display: flex; flex-direction: column; gap: var(--space-4); }
.context-group {
  background: var(--surface-section); border: 1px solid var(--border-soft); border-radius: var(--radius-lg);
  padding: var(--space-4);
}
.context-group__header { margin-bottom: var(--space-3); }
.context-group__label {
  font-family: var(--font-body); font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-dim);
}
.metric-tiles {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-3);
}
@media (min-width: 560px) { .metric-tiles { grid-template-columns: repeat(4, 1fr); } }
/* Beta 7.5 (Punkt 68-73, "Health Priority System" — P1): Primary (4 Kacheln: Bereitschaft/Schlaf/
   Body-Battery/Erholungszeit) und Secondary (3 Kacheln: Stress/Belastungsbalance/Belastungssprung)
   sind zwei getrennte Grids -- Primary bleibt bei max. 4 Spalten (bewusst nicht breiter, damit die
   Karten selbst gross bleiben statt nur die Reihe zu fuellen), Secondary bekommt ab 700px 3 Spalten
   (passt zu ihren 3 Elementen). */
@media (min-width: 700px) { .metric-tiles--secondary { grid-template-columns: repeat(3, 1fr); } }
/* Kacheln INNERHALB einer Kontext-Gruppe verlieren ihre eigene Kartenoptik (kein eigener Hintergrund-
   Gradient, kein backdrop-filter, kein Schatten) -- die Gruppe selbst traegt jetzt die Flaeche, die
   Kacheln werden zu kompakten, durch Typografie/Abstand getrennten Signalen (Mandat Teil 16: "Avoid
   embedding each metric inside another heavy card"). Primary-Kacheln behalten ihre blaue Tönung UND
   den oberen Farbverlaufs-Akzent (Markenidentitaet bleibt), nur auf der leichteren --panel-alt-Basis
   statt --surface-hero+Blur. */
.context-group .metric-tile {
  background: var(--panel-alt); border: 1px solid transparent; border-radius: var(--radius-sm);
  backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none;
}
.context-group .metric-tile:hover { background: var(--surface-raised); border-color: var(--border-soft); box-shadow: none; }
.context-group .metric-tile--primary { background: radial-gradient(140% 100% at 0% 0%, rgba(0, 128, 255, 0.08), transparent 60%), var(--panel-alt); }
/* Beta 7.4 (Punkt 68-73, "Health Metric Card Redesign", P1.3): echte neue visuelle Hierarchie
   statt der bisherigen gleichgewichteten Zeilen — grosser Hauptwert dominiert, Label/Status/Trend
   treten bewusst zurueck. Status wird jetzt als kompakter Badge (mt-word) + kleiner Dot am Icon
   dargestellt statt als volle linke Statusfarb-Leiste ueber die gesamte Kartenhoehe (Punkt 72:
   "Statusfarbe nicht zwingend als komplette Border"). */
.metric-tile {
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 14px var(--space-3) var(--space-3); text-align: left; cursor: pointer; font-family: inherit; color: inherit;
  display: flex; flex-direction: column; gap: 6px; position: relative; overflow: hidden;
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
  transition: transform var(--transition-fast), box-shadow var(--transition-fast), border-color var(--transition-fast), background var(--transition-fast);
}
.metric-tile::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px; pointer-events: none;
  background: linear-gradient(90deg, rgba(255,255,255,0.10), rgba(255,255,255,0));
}
.metric-tile:hover { transform: translateY(var(--card-lift-hover)); border-color: var(--border); background: var(--surface-raised); box-shadow: var(--shadow-hover); }
.metric-tile:active { transform: scale(var(--card-scale-press)); }
.metric-tile:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.metric-tile.is-expanded { background: var(--surface-selected); border-color: var(--color-primary); }
.mt-top { display: flex; align-items: center; gap: 7px; }
.mt-icon {
  font-size: 12px; color: var(--text-dim); width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  background: var(--neutral-chip-bg); border: 1px solid var(--border-soft); position: relative;
}
/* Statuspunkt am Icon-Rand statt voller Farbleiste (Punkt 72) */
.mt-icon::after {
  content: ''; position: absolute; bottom: -1px; right: -1px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-dim); border: 2px solid var(--surface-card);
}
.metric-tile.mt-good .mt-icon::after { background: var(--color-success); }
.metric-tile.mt-warn .mt-icon::after { background: var(--color-attention); }
.metric-tile.mt-bad .mt-icon::after { background: var(--color-warning); }
/* Beta 9.3 (Mandat "Health Card UX", Phase 13): Kartentitel bisher 9.5px/--text-dim — kaum
   lesbar neben dem sehr grossen --mt-value. Angehoben auf --fs-label (11px)/--text-muted (heller
   als --text-dim), bleibt damit klar UNTER dem Section-Titel (.dashboard-section__title,
   --fs-h2/20px) — keine Konkurrenz zur Zonen-Ueberschrift, nur innerhalb der Kachel besser lesbar. */
.mt-label { font-family: var(--font-body); font-size: var(--fs-label); text-transform: uppercase; letter-spacing: var(--ls-label); color: var(--text-muted); }
/* Hauptwert (Punkt 70: "deutlich wichtiger als Label") — deutlich groesser als vorher (20px -> 26px). */
.mt-value { font-family: var(--font-display); font-size: 26px; font-weight: 700; line-height: 1; letter-spacing: -0.01em; margin: 2px 0 1px; }
.mt-value .mt-unit { font-size: 11px; color: var(--text-dim); font-weight: 400; margin-left: 2px; }
/* Status als kompakter Badge statt dominanter Farbtext (Punkt 71: "klar, aber nicht dominant"). */
.mt-word {
  font-size: 10px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.04em;
  padding: 2px 7px; border-radius: var(--talvaxo-radius-sm); background: var(--neutral-chip-bg); display: inline-block; width: fit-content;
}
.metric-tile.mt-good .mt-word { color: var(--color-success); background: var(--status-good-dim); }
.metric-tile.mt-warn .mt-word { color: var(--color-attention); background: var(--status-warn-dim); }
.metric-tile.mt-bad .mt-word { color: var(--color-warning); background: var(--status-bad-dim); }
.mt-detail {
  font-size: 11.5px; color: var(--text-muted); line-height: 1.5; max-height: 0; overflow: hidden; opacity: 0;
  transition: max-height var(--transition-base), opacity var(--transition-base), margin-top var(--transition-base);
}
.metric-tile.is-expanded .mt-detail { max-height: 160px; opacity: 1; margin-top: 4px; }

/* Beta 7.5 (Punkt 68-73, "Health Priority System" — P1): Primary-Kacheln (Bereitschaft, Schlaf,
   Body Battery, Erholungszeit — "wie bereit bin ich jetzt") bekommen echtes visuelles Gewicht statt
   nur einer Sonderfarbe auf einer einzelnen Kachel wie in Beta 7.4 (dort nur "readiness"); Secondary
   (Stress, Belastungsbalance/TSB, Belastungssprung/ACWR — Last-/Trendsignale) bleiben bewusst
   kompakter, damit der Blick zuerst auf Primary faellt. */
/* Beta 7.7 (Punkt 47-49, "Primary Metric Polish"): die volle .surface-selected-Blaufläche (dieselbe
   Farbe wie ein aktiv angeklickter/ausgewählter Zustand anderswo im UI, siehe .nav-link.active)
   erzeugte ein "Button/Selected"-Gefühl statt reiner Prioritäts-Kennzeichnung. Blauflächenanteil um
   ca. 25% zurückgenommen (schwache radiale Tönung statt Vollflächen-Gradient), Priorität kommt
   stattdessen ueber staerkeren Wert (Glow-Text-Shadow), einen oberen Akzentrand und ein groesseres
   Icon — dieselben Signale wie bei Hero/Weekly/Marathon-Karten (Top-Akzent-Konvention). */
.metric-tile--primary {
  padding: var(--space-4) var(--space-3) var(--space-3);
  background: radial-gradient(140% 100% at 0% 0%, rgba(0, 128, 255, 0.10), transparent 60%), var(--surface-hero);
  position: relative;
}
.metric-tile--primary::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, var(--talvaxo-blue), var(--talvaxo-cyan)); opacity: 0.7;
}
.metric-tile--primary .mt-icon { width: 26px; height: 26px; font-size: 13px; }
.metric-tile--primary .mt-value { font-size: var(--fs-metric); text-shadow: 0 0 14px rgba(0, 170, 255, 0.20); }
.metric-tile--primary .mt-label { font-size: 11.5px; }
.metric-tile--secondary {
  padding: 10px var(--space-3) var(--space-3);
  background: var(--surface-hero);
}
.metric-tile--secondary .mt-icon { width: 19px; height: 19px; font-size: 10.5px; }
.metric-tile--secondary .mt-value { font-size: 20px; }
.metric-tile--secondary .mt-label { font-size: 10px; }

/* ---------------------------------------------------------------------------
   TRAINING CAPABILITY — RANGE BAR (Punkt 19/20)
   --------------------------------------------------------------------------- */
.range-bar { margin: var(--space-3) 0; }
.range-bar-track { position: relative; height: 8px; background: var(--panel); border-radius: 4px; }
.range-bar-fill { position: absolute; top: 0; height: 100%; background: rgba(139, 149, 246, 0.35); border-radius: 4px; }
.range-bar-marker { position: absolute; top: -3px; width: 2px; height: 14px; transform: translateX(-1px); }
.range-bar-marker-typical { background: var(--color-primary); }
.range-bar-marker-peak { background: var(--color-attention); }
.range-bar-legend { display: flex; gap: var(--space-3); margin-top: 6px; font-size: 10px; color: var(--text-dim); }
.range-bar-legend span { display: flex; align-items: center; gap: 4px; }
.rbl-dot { width: 7px; height: 7px; border-radius: 2px; display: inline-block; }
.rbl-dot.rbl-typical { background: var(--color-primary); }
.rbl-dot.rbl-range { background: rgba(139, 149, 246, 0.35); }
.rbl-dot.rbl-peak { background: var(--color-attention); }

/* ---------------------------------------------------------------------------
   WEATHER — ICON + TIMELINE (Punkt 21-23)
   --------------------------------------------------------------------------- */
.weather-icon { font-size: 30px; line-height: 1; flex-shrink: 0; }
.weather-timeline { display: flex; gap: 4px; margin-top: var(--space-3); overflow-x: auto; }
.wtl-hour { flex: 1; min-width: 34px; text-align: center; padding: 6px 2px; border-radius: 6px; background: var(--panel); }
.wtl-hour.wtl-best { background: var(--teal-dim); }
.wtl-time { font-family: var(--font-mono); font-size: 9px; color: var(--text-dim); }
.wtl-temp { font-size: 11.5px; color: var(--text); margin-top: 2px; font-weight: 600; }
.wtl-hour.wtl-best .wtl-temp { color: var(--teal); }

/* ---------------------------------------------------------------------------
   ANIMATE-IN / MICROINTERACTIONS (Punkt 31-36) — Fade/Slide beim Laden, verstärkte
   Hover-States gegenüber V5.1/frühem V5.2 (deutlicher Lift/Shadow statt nur Border).
   --------------------------------------------------------------------------- */
/* V6.2: weather-card/briefing-card/week-card/goal-card/capability-card entfernt — Shadow/Hover
   kommt vollständig von .dash-card (siehe dortige Regel). hero-card/readiness-card behalten ihre
   eigene Regel (kein .dash-card, siehe Begründung oben). */
.hero-zone .hero-card, .hero-zone .readiness-card {
  box-shadow: var(--shadow-raised);
}
.hero-zone .hero-card:hover, .hero-zone .readiness-card:hover {
  box-shadow: var(--shadow-hover); border-color: var(--border);
}
/* Reine CSS-Keyframe-Animation (kein JS-Trigger nötig, läuft automatisch beim Einfügen ins DOM) —
   bewusst NUR auf den neuen Hero-/Tile-Komponenten, damit ein evtl. JS-Fehler niemals bestehende,
   bereits verifizierte Karten unsichtbar lassen kann (Inhalte dürfen nie von JS-Erfolg abhängen). */
@keyframes dashFadeInUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.daily-hero { animation: dashFadeInUp var(--transition-slow) ease both; }
.metric-tile { animation: dashFadeInUp var(--transition-slow) ease both; }
.metric-tiles .metric-tile:nth-child(1) { animation-delay: 0ms; }
.metric-tiles .metric-tile:nth-child(2) { animation-delay: 30ms; }
.metric-tiles .metric-tile:nth-child(3) { animation-delay: 60ms; }
.metric-tiles .metric-tile:nth-child(4) { animation-delay: 90ms; }
.metric-tiles .metric-tile:nth-child(5) { animation-delay: 120ms; }
.metric-tiles .metric-tile:nth-child(6) { animation-delay: 150ms; }
.metric-tiles .metric-tile:nth-child(7) { animation-delay: 180ms; }

@media (prefers-reduced-motion: reduce) {
  .dh-ring-fill, .segment-chip, .metric-tile, .mt-detail, .dh-cta { transition: none; }
  .daily-hero, .metric-tile { animation: none; }
}

/* ============================================================================================
   V5.3 — READY SCORE BREAKDOWN + 7 DAILY METRICS DIREKT IN DER HERO-ZONE
   (Nutzerauftrag "Full Visual Daily Dashboard Rebuild", Punkt 5-16, 8-9, 17-21)
   ============================================================================================ */
.dh-trend {
  margin-top: var(--space-2); text-align: center; font-family: var(--font-body); font-size: 11px;
  color: var(--text-muted);
}
/* V5.7 Morning vs Current Readiness — dezenter Kontext-Badge + Morgenwert-Zeile, nur sichtbar wenn
   Garmin heute tatsächlich mehr als einen Readiness-Context geliefert hat. */
.dh-context-badge {
  margin-top: var(--space-2); text-align: center; font-family: var(--font-body); font-size: 9.5px;
  letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--color-attention);
}
.dh-morning-readout {
  margin-top: 4px; text-align: center; font-family: var(--font-body); font-size: 11px; color: var(--text-dim);
}
.dh-morning-readout b { color: var(--text-muted); }
.dh-drivers {
  position: relative; margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--hairline);
  display: flex; flex-direction: column; gap: 6px;
}
.dh-driver { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; line-height: 1.5; }
.dh-driver .dhd-sign { flex-shrink: 0; width: 16px; height: 16px; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 11px; margin-top: 1px; }
.dh-driver-positive .dhd-sign { background: rgba(47, 217, 196, 0.18); color: var(--color-success); }
.dh-driver-positive .dhd-text { color: var(--text-muted); }
.dh-driver-limiting .dhd-sign { background: rgba(239, 91, 107, 0.16); color: var(--color-warning); }
.dh-driver-limiting .dhd-text { color: var(--text-muted); }

.dh-why-toggle { position: relative; margin-top: var(--space-3); font-family: var(--font-body); font-size: 11px; }
.dh-why-toggle summary { cursor: pointer; color: var(--text-muted); list-style: none; }
.dh-why-toggle summary::-webkit-details-marker { display: none; }
.dh-why-toggle summary::before { content: '▸ '; }
.dh-why-toggle[open] summary::before { content: '▾ '; }
.dh-why-body { margin-top: var(--space-3); display: flex; flex-direction: column; gap: 10px; font-family: var(--font-body); font-size: 12.5px; color: var(--text-muted); line-height: 1.55; }
.dh-why-row b { color: var(--text); }
.dh-why-note { padding-top: 8px; border-top: 1px dashed var(--hairline); font-size: 11.5px; }
.dh-why-factors { display: flex; flex-direction: column; gap: 6px; }
.dh-why-factor { display: grid; grid-template-columns: 90px 1fr 36px; align-items: center; gap: 8px; }
.dwf-label { font-size: 11px; color: var(--text-dim); }
.dwf-bar-track { height: 6px; background: var(--panel-alt); border-radius: 3px; overflow: hidden; }
.dwf-bar-fill { display: block; height: 100%; background: var(--color-primary); border-radius: 3px; }
.dwf-pct { font-family: var(--font-body); font-size: 10.5px; color: var(--text-dim); text-align: right; }

/* 7 Daily Metrics — jetzt direkt Teil der Hero-Zone (Punkt 8/58/59: "ganz oben", nicht weiter
   unten). metric-tiles-wrap ersetzt die frühere separate, weiter unten liegende DOM-Sektion.
   V6.2 (Mandat Teil H, Punkt 48): margin-bottom entfernt — .metric-tiles-wrap ist seit V6.1 der
   einzige Inhalt von Zone 2 (.dashboard-section__content), deren eigenes margin-bottom
   (var(--zone-gap)) den Abstand zur nächsten Zone bereits vollständig steuert. Der zusätzliche
   Innenabstand hier addierte sich real zu 52px statt der beabsichtigten 32px zwischen "Gesundheit
   & Bereitschaft" und "Dein Tag". */
.metric-tiles-wrap { }
.mt-group-label {
  font-family: var(--font-body); font-size: 10.5px; text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); margin-bottom: var(--space-2); display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline;
}
.metric-tile { position: relative; }
.mt-word-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mt-trend { font-family: var(--font-body); font-size: 10px; color: var(--text-dim); }
.mt-trend-good { color: var(--color-success); }
.mt-trend-warn { color: var(--color-attention); }
.mt-trend-bad { color: var(--color-warning); }
/* Dezente Zusatzzeile je Kachel, z.B. "Letzte Nacht"/"Aktuell" — verifiziert je Metrik anhand der
   tatsächlichen Datenquelle, keine pauschale Kopie eines Textmusters. */
.mt-time-context { font-family: var(--font-body); font-size: 9px; color: var(--text-dim); letter-spacing: 0.02em; }

.sync-freshness-line {
  font-family: var(--font-body); font-size: 10.5px; color: var(--text-dim); margin-bottom: var(--space-3);
}

/* V5.6 Category Freshness — bewusst dezent (kleine Zeile, eingeklappte Details), nur bei echten
   Problemen (STALE/FAILED/NEVER_SYNCED) optisch hervorgehoben (Punkt 68: keine Debug-Konsole für
   normale Nutzer). */
.sync-freshness-details { margin-bottom: var(--space-3); font-family: var(--font-mono); font-size: 10.5px; }
.sync-freshness-details summary { cursor: pointer; color: var(--text-dim); list-style: none; }
.sync-freshness-details summary::-webkit-details-marker { display: none; }
.sync-freshness-details summary::before { content: '▸ '; }
.sync-freshness-details[open] summary::before { content: '▾ '; }
.sync-freshness-details.has-problems summary { color: var(--color-attention); }
.sync-cat-list { margin-top: 6px; display: flex; flex-direction: column; gap: 3px; padding-left: 10px; }
.sync-cat-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; color: var(--text-dim); }
.sync-cat-row.sync-cat-stale, .sync-cat-row.sync-cat-failed, .sync-cat-row.sync-cat-never_synced { color: var(--color-attention); }

/* ============================================================================================
   Beta 7.6 (Punkt 117-121, "Topbar tatsaechlich bearbeiten" — P1): echte Hierarchie Page Title /
   Date-Context / Sync Status statt einer einzelnen, alles gleichgewichtenden Statuszeile. Transparent
   auf dem Seiten-Hintergrund (Punkt 121 — keine zusaetzliche Surface-Flaeche noetig, die Zeile ist
   bereits die oberste Ebene der Seite), klare Baseline-Trennung nach unten.
   ============================================================================================ */
.app-topbar {
  display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap;
  gap: 6px 16px; padding-bottom: var(--space-3); margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-soft);
  /* CURRENT UPDATE addendum (Nutzer-Screenshot, "rechts sind die einzelnen Elemente uebereinander"):
     diese Zeile kann bei breiten Viewports bis nah an den rechten Rand von .app-main laufen (flex,
     kein max-width) -- der neue, fixed-positionierte .talvaxo-topbar-Cluster (Theme/Bell/Avatar,
     siehe components.css) haengt IMMER oben rechts ueber dem Content, unabhaengig vom Dokumentfluss.
     Reserviert daher Platz in exakt der Cluster-Breite, damit die Sync-Chips/der Sync-Button nie
     wieder darunter verschwinden -- reale, live gemessene Kollision bei 1920px Breite, nicht nur
     eine Vermutung.
     v10.3.7 UX addendum Folgefix (erneuter Nutzer-Screenshot, "buttons und schrift ueberlagert
     sich"): derselbe Bug ist zurueckgekehrt, weil der Cluster selbst breiter wurde -- Sprache
     (DE|EN) und "Zur Webseite" zogen aus dem Profil-Menue in genau diesen Cluster (siehe
     topbar-utility-report.md), wodurch er von ~140px (Theme/Bell/Avatar) auf ~284px (Theme/
     Sprache/Website/Bell/Avatar) waechst -- dieses padding-right wurde beim Verbreitern nie
     nachgezogen. Live an drei Breiten (1440px/800px/390px) nachgemessen: der Cluster braucht dort
     tatsaechlich 276px/250px/250px Platz, nicht mehr die alten 170px/140px -- beide Werte jetzt mit
     Sicherheitsabstand auf die reale, gemessene Cluster-Breite angehoben, statt erneut nur eine
     Vermutung nachzutragen. */
  padding-right: 300px;
}
@media (max-width: 900px) {
  .app-topbar { padding-right: 270px; }
}
.topbar-page { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.topbar-page-title { font-family: var(--font-display); font-size: 15px; font-weight: 600; color: var(--text); }
.topbar-page-date { font-size: 11.5px; color: var(--text-dim); }

/* ============================================================================================
   V6.0 — SYSTEM HEALTH BAR + MANUAL SYNC (Mandat Teil C/D/N). Bewusst kompakt (Punkt 33/107):
   ein Ein-Zeilen-Status by default, technische Tiefe (3 getrennte Zeitquellen, Kategorie-Liste)
   ausschließlich im <details>-Bereich darunter.
   ============================================================================================ */
.system-health-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px; font-family: var(--font-body);
  font-size: 10.5px; color: var(--text-dim); margin-bottom: 0;
}
/* Beta 7.8 (Punkt 80, "kompakte Status-Gruppen"): Garmin/Auto-Sync stehen jetzt als eigene kleine
   Chips statt loser, durch "·" getrennter Inline-Textfragmente — dieselben Texte/Farben wie zuvor
   (keine neue Heuristik), nur visuell gruppiert. */
.sh-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  background: var(--panel-alt); border: 1px solid var(--border-soft); border-radius: var(--radius-pill);
}
.sh-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; flex-shrink: 0; }
.sh-dot-green { background: var(--teal, #2dd4bf); }
.sh-dot-amber { background: var(--amber, #f59e0b); }
.sh-dot-red { background: var(--color-attention); }
.sh-dot-dim { background: var(--text-dim); opacity: 0.5; }
.sh-status-text { letter-spacing: 0.03em; }
.sh-sep { opacity: 0.4; }
.sh-last-sync { color: var(--text-dim); }
.sh-detail-row { color: var(--text-dim); margin-bottom: 3px; }

.sh-global-sync-btn, .sync-cat-btn {
  font-family: var(--font-body); font-size: 10px; text-transform: uppercase; letter-spacing: var(--ls-label);
  background: var(--panel-alt); border: 1px solid var(--border-soft); border-radius: var(--radius-pill);
  color: var(--text-muted); padding: 3px 10px; cursor: pointer;
  transition: border-color var(--transition-fast, 0.15s ease), color var(--transition-fast, 0.15s ease);
}
.sh-global-sync-btn:hover, .sync-cat-btn:hover { border-color: var(--color-primary); color: var(--text); }
.sh-global-sync-btn:disabled, .sync-cat-btn:disabled { opacity: 0.6; cursor: default; }
.sh-global-sync-btn { margin-left: 4px; }
.sync-cat-btn { flex-shrink: 0; padding: 2px 8px; font-size: 9px; }
/* v10.2.2 (Mandat §31 "Updated Categories") — nur sichtbar, wenn renderManualSyncButtonState
   (overview.js) tatsaechlich echte categoriesSatisfied hat; sonst leer (kein reservierter,
   sichtbar leerer Platz). */
.sync-detail-line { display: block; font-size: 9.5px; color: var(--text-dim); margin-top: 2px; }
.sync-detail-line:empty { display: none; }

@media (prefers-reduced-motion: reduce) {
  .sh-global-sync-btn, .sync-cat-btn { transition: none; }
}
.sync-cat-label { color: var(--text-muted); }

/* ============================================================================================
   V5.4 — DASHBOARD REFINEMENT (Nutzerauftrag "Ready Score Integrity, Visual Polish, Information
   Reduction, UX Consistency"). Ergänzt V5.2/V5.3 um: konsistentes SVG-Icon-System (ersetzt Emoji/
   Unicode-Mix), echte Sparklines, vereinheitlichten Ready-Score-Drawer (Garmin-Faktoren getrennt
   von Tageskontext), größeren Marathon-Readiness-Ring, Number-Count-Up, Session-Type-Akzente im
   Wochenstrip. KEIN erneuter Full Rebuild — reine Verfeinerung der V5.3-Struktur.
   ============================================================================================ */

/* ---------------------------------------------------------------------------
   ICON SYSTEM (Punkt 20/21) — EIN durchgängiges SVG-Outline-System für Metric-Tile-Icons, den
   Hero-Ring-Statusicon und Wetter-Icons, ersetzt die bisherige Unicode-/Emoji-Mischung.
   --------------------------------------------------------------------------- */
.tile-icon-svg, .status-icon-svg, .weather-icon-svg, .mt-spark-svg {
  fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
.tile-icon-svg { width: 15px; height: 15px; }
.mt-icon { display: inline-flex; }
.status-icon-svg { width: 18px; height: 18px; color: currentColor; }
.weather-icon-svg { width: 30px; height: 30px; color: var(--text-muted); }
.wu-icon .weather-icon-svg { width: 26px; height: 26px; color: var(--text-dim); }
/* Beta 9.3 (Phase 13, "Health Card UX"): 18px -> 28px. Nutzerauftrag (Redesign-Variante A,
   "Glow-Ribbon" -- per Mockup mit drei Optionen abgestimmt): 28px -> 56px, deutlich praesenter
   statt einer duennen Linie am Kartenrand (siehe shared.js sparklineSvg fuer Flaechenfuellung +
   groesseres viewBox). */
.mt-spark-svg { width: 100%; height: 56px; stroke-width: 2.2; color: var(--text-dim); display: block; }
.metric-tile.mt-good .mt-spark-svg { color: var(--color-success); }
.metric-tile.mt-warn .mt-spark-svg { color: var(--color-attention); }
.metric-tile.mt-bad .mt-spark-svg { color: var(--color-warning); }
/* Leucht-Effekt beim Hover/Focus der ganzen Kachel (nicht nur der SVG-Flaeche selbst) -- dieselbe
   Geste wie jeder andere Hover-Zustand dieser Karten (siehe .metric-tile:hover weiter oben),
   damit Maus/Tastatur/Touch-Fokus konsistent denselben Effekt ausloesen. drop-shadow statt box-
   shadow, weil es der tatsaechlichen Linienform folgt statt eines rechteckigen Kastens. */
.mt-spark-line { transition: filter 200ms ease; }
.mt-spark-dot { transition: r 200ms ease; }
.metric-tile:hover .mt-spark-line, .metric-tile:focus-visible .mt-spark-line { filter: drop-shadow(0 0 5px currentColor); }
.metric-tile:hover .mt-spark-dot, .metric-tile:focus-visible .mt-spark-dot { r: 4; }
@media (prefers-reduced-motion: reduce) { .mt-spark-line, .mt-spark-dot { transition: none; } }
/* v10.4.4 (Independent Review Teil 15, "sieben dezente Saeulen fuer Schlaf/Body Battery/Stress"):
   dieselbe Groesse/Farbe wie .mt-spark-svg (dashboard.css oben), aber Balken statt Linie -- der
   heutige (letzte) Balken bleibt voll deckend, die 6 vorangehenden Tage laufen dezent ab, damit
   "heute" auch ohne den Linien-Endpunkt-Dot sofort erkennbar bleibt. Ein fehlender Kalendertag
   (kein <rect> an dieser Position, siehe shared.js barChartSvg()) zeigt bewusst eine echte Luecke,
   keinen Nullbalken. */
.mt-bar { opacity: 0.45; transition: opacity 200ms ease; }
.mt-bar-last { opacity: 1; }
.metric-tile:hover .mt-bar, .metric-tile:focus-visible .mt-bar { opacity: 0.65; }
.metric-tile:hover .mt-bar-last, .metric-tile:focus-visible .mt-bar-last { opacity: 1; filter: drop-shadow(0 0 4px currentColor); }
@media (prefers-reduced-motion: reduce) { .mt-bar { transition: none; } }
.mt-spark { margin-top: 4px; position: relative; }
/* Hover-/Tap-Tooltip (Phase 13) — derselbe bewaehrte Mechanismus wie .info-dot (components.css),
   hier auf die gesamte Sparkline-Flaeche angewendet statt auf einen kleinen Info-Punkt. Per Hover
   ODER Tastatur-/Touch-Fokus erreichbar (tabindex auf dem Wrapper in metric-tiles.js), Positionierung
   linksbuendig statt zentriert, da die Sparkline am unteren Kartenrand sitzt und ein zentrierter
   Tooltip auf schmalen Mobile-Kacheln seitlich abgeschnitten werden koennte. */
.mt-spark[data-tooltip] { cursor: help; }
.mt-spark[data-tooltip]::after {
  content: attr(data-tooltip); position: absolute; left: 0; bottom: calc(100% + 8px);
  width: max-content; max-width: 240px; padding: 8px 10px; border-radius: 8px;
  background: var(--panel-raised); border: 1px solid var(--border-soft); color: var(--text-muted);
  font-family: var(--font-body); font-size: 11.5px; line-height: 1.45; text-transform: none; letter-spacing: normal;
  box-shadow: 0 8px 20px rgba(0,0,0,0.28); opacity: 0; visibility: hidden; pointer-events: none; z-index: 20;
  transition: opacity 150ms ease, transform 150ms ease, visibility 150ms ease; transform: translateY(4px);
}
.mt-spark[data-tooltip]:hover::after, .mt-spark[data-tooltip]:focus-visible::after { opacity: 1; visibility: visible; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .mt-spark[data-tooltip]::after { transition: none; } }
@media (max-width: 480px) { .mt-spark[data-tooltip]::after { max-width: min(240px, calc(100vw - 48px)); } }

/* Subtiler Status-Indikator (Punkt 19): dezenter linker Accent statt volle Kartenfarbe. */
/* Bugfix (V5.4, Screenshot-QA bei 1024px): Grid-/Flex-Items schrumpfen per Spezifikation nicht
   unter den Min-Content ihrer Kinder ("BELASTUNGSSPRUNG" als ein zusammenhängendes Wort) — das
   sprengte bei 7 Spalten die gesamte Kachel-Zeile und damit die Seite horizontal. min-width:0
   erlaubt echtes Schrumpfen, overflow-wrap erlaubt der Beschriftung einen Zeilenumbruch statt
   abgeschnitten oder erzwungen breit zu werden. */
/* Beta 7.4: die volle linke Statusfarb-Leiste entfaellt (Punkt 72) -- Status kommt jetzt vom
   Icon-Dot + Badge (siehe oben), min-width:0/overflow-wrap-Fix bleibt unveraendert noetig. */
.metric-tile { min-width: 0; }
.mt-top { min-width: 0; }
.mt-label { min-width: 0; overflow-wrap: break-word; }
/* Missing State — Kachel bleibt an ihrer Grid-Position, wirkt aber sichtbar zurückgenommen (kein
   Statusfarben-Akzent, gedämpfter Wert) statt zu verschwinden oder "0" zu zeigen. */
.metric-tile.mt-missing { opacity: 0.6; }
.metric-tile.mt-missing .mt-value { color: var(--text-dim); }
.metric-tile.mt-missing .mt-word { color: var(--text-dim); }

/* ---------------------------------------------------------------------------
   HERO "WARUM?"-DRAWER — vereinheitlicht (Punkt 10/11/22): zwei klar benannte Sektionen statt
   einer separaten Readiness-Karte darunter.
   --------------------------------------------------------------------------- */
.dh-why-section + .dh-why-section { margin-top: 4px; padding-top: 12px; border-top: 1px dashed var(--hairline); }
.dh-why-section-title {
  font-family: var(--font-body); font-size: 10px; text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); margin-bottom: 8px;
}

/* ---------------------------------------------------------------------------
   BEST RUNNING WINDOW — deutlich hervorgehoben (Punkt 32/33), steht jetzt zuerst im Weather-Card.
   --------------------------------------------------------------------------- */
.best-window-prominent {
  background: linear-gradient(135deg, var(--teal-dim), var(--panel-alt)); border: 1px solid rgba(47,217,196,0.25);
  padding: 14px 16px; margin-bottom: 14px;
}
.best-window-prominent .bw-time { font-size: 22px; }

/* ---------------------------------------------------------------------------
   MARATHON READINESS RING — vergrößert (Punkt 42/43, Richtwert 120-140px), Layout links Ring /
   rechts Status+Limiter+Goal-Outlook, responsive: stapelt unter 480px.
   --------------------------------------------------------------------------- */
.rr2-overall { align-items: flex-start; flex-wrap: wrap; gap: var(--space-4); }
.rr2-ring { width: 128px; height: 128px; }
.rr2-ring svg { width: 128px; height: 128px; }
.rr2-ring-pct { font-size: 22px; }
.rr2-overall-meta { display: flex; flex-direction: column; gap: 6px; min-width: 160px; max-width: 320px; flex: 1 1 240px; }
.rr2-overall-meta .limiter-note {
  font-size: 11.5px; color: var(--amber); background: var(--amber-dim); border-radius: 8px; padding: 7px 9px; margin: 2px 0 0;
}
.rr2-overall-meta .goal-readiness-row {
  border-top: none; padding-top: 4px; margin-top: 2px;
}
@media (max-width: 420px) {
  .rr2-overall { flex-direction: column; align-items: center; text-align: center; }
  .rr2-overall-meta { align-items: center; }
}


/* ============================================================================================
   V5.9 — HEUTE BEACHTEN, ZONE HEADERS, TRENDS/INSIGHTS, PERSONAL RECORDS (Mandat Teil B)
   Balanced Grid (Punkt 106-112): .dashboard-two-col nutzt auto-fit/minmax + align-items:start
   statt fixer 2-Spalten-mit-stretch — dieselbe Root-Cause-Lehre wie oben bei .hero-zone (V5.2):
   ungleich lange Karten sollen NICHT künstlich auf gleiche Höhe gezwungen werden, dürfen aber bei
   ausreichender Breite nebeneinander stehen, wenn ihr Inhalt tatsächlich vergleichbar ist.
   ============================================================================================ */
/* V6.1: .zone-header trug bisher eine NEGATIVE untere Margin (4px 0 -6px), um den
   nachfolgenden Card-Abstand manuell zu "reparieren" (Mandat Teil A Punkt 4: genau das ist
   verboten). Ersetzt durch den echten Section-Header-Abstand (--zone-header-gap, positiv) —
   .zone-header bleibt als Klasse für Rückwärtskompatibilität mit älteren Tests bestehen, ist
   aber inhaltlich jetzt ein Alias für .dashboard-section__eyebrow (siehe V6.1-Block unten). */
.zone-header {
  font-family: var(--font-body); font-size: 11px; text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); margin: 0 0 var(--zone-header-gap); padding-left: 2px;
}
.dashboard-two-col {
  display: grid; grid-template-columns: 1fr; gap: var(--space-4); align-items: start;
}
@media (min-width: 760px) {
  .dashboard-two-col { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
}

/* V6.2: Chrome jetzt via .dash-card (siehe overview/hero.js renderTodayAttention), Dopplung
   inkl. Hover/Transition entfernt. */
.today-attention-title {
  font-family: var(--font-body); font-size: 11px; text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); margin: 0 0 10px;
}
.today-attention-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ta-item { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px; line-height: 1.4; }
.ta-sign { font-weight: 700; flex-shrink: 0; width: 14px; text-align: center; }
.ta-limiting .ta-sign { color: var(--amber); }
.ta-positive .ta-sign { color: var(--teal); }
.ta-text { color: var(--text-muted); }
/* Beta 7.5 (Punkt 80-83): erster (wichtigster) Punkt als Headline, Rest als kompakte Support-Liste
   — dieselbe Hierarchie-Idee wie beim Coach Briefing (.briefing-headline/.briefing-support). */
.ta-headline { font-family: var(--font-display); font-size: 14.5px; font-weight: 600; color: var(--text); margin-bottom: 9px; }
.ta-headline .ta-sign { width: 16px; }
.ta-headline .ta-text { color: var(--text); }
.ta-support { padding-top: 8px; border-top: 1px solid var(--border-soft); }
.ta-support .ta-item { font-size: 12.5px; }
.ta-support .ta-text { color: var(--text-dim); }

/* V6.2: Chrome jetzt via .dash-card/.dash-card--compact (siehe overview/insights-card.js),
   Dopplung inkl. Hover/Transition entfernt. */
.insights-title, .pr-title {
  font-family: var(--font-body); font-size: 11px; text-transform: uppercase; letter-spacing: var(--ls-label);
  color: var(--text-dim); margin: 0 0 12px;
}
.insights-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.insight-item { display: flex; flex-direction: column; gap: 2px; }
.insight-text { font-size: 13.5px; line-height: 1.45; color: var(--text-muted); }
.insight-meta { font-family: var(--font-body); font-size: 10.5px; color: var(--text-dim); }

/* Beta 9.2 (Punkt 116-119, Trend Card) */
.trend-rows { display: flex; flex-direction: column; gap: 10px; }
.trend-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.trend-label { font-size: 13px; color: var(--text); font-weight: 600; }
.trend-value { font-size: 12.5px; color: var(--text-muted); flex: 1; text-align: right; margin-right: 8px; }
/* Complete Visual Redesign Mandat §27/§74 ("one integrated Health Readiness story... fewer
   equally weighted cards"): on the Health page specifically, this is the only card that already
   synthesizes a real trend story (HRV/RHR/Sleep direction + confidence) rather than a single raw
   number -- elevated to read as the page's dominant element instead of a same-weight card
   floating above the 4 vitals tiles. Scoped to #health-content so Coach/other pages that may reuse
   the shared .overview-trend-card class keep their own (already appropriate) weight. */
.health-trend-block {
  background: linear-gradient(180deg, var(--surface-section) 0%, var(--surface-base) 100%);
  border: 1px solid var(--border-soft); border-radius: var(--radius-lg, 20px);
  padding: 24px 26px; margin-bottom: var(--zone-gap, 24px);
}
.health-trend-block .overview-trend-card { background: none; border: none; padding: 0; margin: 0; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.health-trend-block .dash-card__title { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; color: var(--talvaxo-cyan); text-transform: uppercase; margin-bottom: 16px; }
.health-trend-block .trend-label { font-size: 15px; }
.health-trend-block .trend-value { font-size: 13.5px; }
/* FINAL VISUAL FINISHING Mandat §13 ("TRAINING IMPLICATION" as the third element of the primary
   health story, alongside current state and trend). */
.health-trend-implication { margin: 18px 0 0; padding-top: 16px; border-top: 1px solid var(--border-soft); font-size: 14px; line-height: 1.6; color: var(--text-muted); max-width: 70ch; }

.pr-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.pr-item { background: var(--panel-alt); border-radius: 8px; padding: 10px 12px; }
.pr-value { font-family: var(--font-display); font-size: 17px; font-weight: 600; }
.pr-label { font-family: var(--font-body); font-size: 10px; text-transform: uppercase; letter-spacing: var(--ls-label); color: var(--text-dim); margin-top: 2px; }
.pr-source { font-size: 9.5px; color: var(--text-dim); opacity: 0.7; margin-top: 3px; }

/* V6.2: reduced-motion für diese Karten läuft jetzt über die gemeinsame .dash-card-Regel weiter
   unten (alle drei tragen die Klasse) — eigene Dopplung entfernt. */

/* ============================================================================================
   V6.1 — ECHTER VISUAL-/LAYOUT-REBUILD DER OVERVIEW (Mandat "Version 6.1", Teil A-L).
   Zentraler Dashboard Section Contract + Card-Typ-System + semantische Grid-Varianten. Ersetzt
   NICHT die bestehenden Karten-Render-Funktionen (deren Fachlogik bleibt unangetastet), sondern
   die Art, wie sie in Zonen gruppiert, betitelt und mit Abstand versehen werden — vorher: pro
   Karte ein individuelles <div class="section-head"> mit Inline-Styles (margin-bottom:14px/12px/
   10px/2px/0, font-size:15px), zusätzlich UNABHÄNGIG davon .zone-header/.today-attention-title/
   .insights-title/.pr-title/.mt-group-label mit je eigener Optik. Jetzt: EIN Header-System
   (.dashboard-section__eyebrow/__title), EIN Card-Padding-System (--card-pad/--card-pad-compact
   über .dash-card), EIN Section-Abstand (--zone-gap), EIN Card-Gap (--card-gap).
   ============================================================================================ */

/* ---------------------------------------------------------------------------
   DASHBOARD SECTION CONTRACT (Teil A) — <section class="dashboard-section"><header>...</header>
   <div class="dashboard-section__content">...</div></section>. Jede Hauptzone der Overview
   (Health/Dein Tag/Deine Woche/Entwicklung/Weitere Details) nutzt diese Hülle.
   --------------------------------------------------------------------------- */
/* v10.3.7 UX addendum: User Menu shortcuts deep-link to #athlete-data/#connected-services on
   account.html -- scroll-margin-top keeps the anchored section clear of the fixed top-right
   .talvaxo-topbar cluster instead of landing partially hidden underneath it. */
.dashboard-section { margin-bottom: var(--zone-gap); scroll-margin-top: 88px; }
.dashboard-section:last-child { margin-bottom: 0; }
@media (max-width: 900px) { .dashboard-section { margin-bottom: var(--zone-gap-tablet); } }
@media (max-width: 480px) { .dashboard-section { margin-bottom: var(--zone-gap-mobile); } }

/* Complete Visual Redesign Mandat §17/§18/§71 ("ONE PRIMARY INTELLIGENCE STAGE and THREE PRIMARY
   CONTENT ZONES maximum", "reduced card dependence"): ov-zone-1 gives the Decision hero + today's
   action + morning context ONE shared, elevated surface instead of three separate free-floating
   cards -- the page should read as one dominant stage, not a stack of equal-weight boxes. Zones 2
   (this week + marathon readiness) and 3 (health & readiness tiles) stay visually quiet by
   contrast -- no added surface, just breathing room -- so the hierarchy is unmistakable at a
   glance: one stage, two supporting zones. */
.ov-zone-1 {
  background: linear-gradient(180deg, var(--surface-section) 0%, var(--surface-base) 100%);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg, 20px);
  padding: 28px 28px 8px;
  margin-bottom: var(--zone-gap);
}
.ov-zone-1 > * { margin-bottom: 0; }
.ov-zone-2 { margin-top: 4px; }
.ov-zone-3 { margin-top: var(--zone-gap); }
@media (max-width: 900px) {
  .ov-zone-1 { padding: 20px 18px 4px; border-radius: 16px; margin-bottom: var(--zone-gap-tablet); }
  .ov-zone-3 { margin-top: var(--zone-gap-tablet); }
}
@media (max-width: 480px) {
  .ov-zone-1 { padding: 16px 14px 2px; }
  .ov-zone-3 { margin-top: var(--zone-gap-mobile); }
}

.dashboard-section__header {
  display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-3);
  flex-wrap: wrap; margin-bottom: var(--zone-header-gap);
}
.dashboard-section__heading { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dashboard-section__eyebrow {
  font-family: var(--font-body); font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-dim);
}
.dashboard-section__title {
  font-family: var(--font-display); font-size: var(--fs-h2); font-weight: 600; color: var(--text);
  letter-spacing: -0.005em;
}
.dashboard-section__desc { font-size: 12.5px; color: var(--text-muted); margin-top: 1px; }
.dashboard-section__actions { flex-shrink: 0; display: flex; align-items: center; gap: var(--space-2); }
.dashboard-section__content { min-width: 0; }

/* ---------------------------------------------------------------------------
   CARD SYSTEM (Teil C) — .dash-card ist die gemeinsame Basis (Radius/Border/Background/Padding/
   Shadow/Hover/Transition zentral definiert); Typ-Modifier steuern nur noch Padding-Skala und
   Titelgewicht statt jede Karte eigene Werte zu geben. Bestehende, funktionale Klassennamen
   (.week-card, .goal-card, ...) bleiben zusätzlich am selben Element (Tests/bestehendes CSS
   bleiben gültig) — .dash-card überschreibt/ergänzt sie nur um die Padding-/Radius-Angleichung.
   --------------------------------------------------------------------------- */
/* V6.2.2 (UI-Konsistenz-Mandat, Punkt 26-28): .dash-card ist außerdem der EINZIGE Ort, der die
   Karte zu einer Flex-Spalte macht und ihre Höhe auf 100% des Grid-Zellen-Platzes setzt. Damit
   entscheidet ausschließlich das umgebende Grid (siehe .dashboard-grid align-items:stretch weiter
   unten) über die AUSSENHÖHE zweier gleichrangiger Karten — die Karte selbst füllt diese Höhe nur
   noch aus, statt sie über ihren eigenen Inhalt zu bestimmen. flex-direction:column ändert am
   visuellen Ergebnis für normalen Blockinhalt (divs/ul/p) nichts, ermöglicht aber optional
   margin-top:auto für einen unten ausgerichteten Footer/Status (siehe z.B. .week-card, Punkt 29). */
.dash-card {
  position: relative;
  display: flex; flex-direction: column; height: 100%;
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: var(--card-pad);
  box-shadow: var(--shadow-raised);
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
  transition: transform var(--transition-base), border-color var(--transition-base), background var(--transition-base);
}
/* TALVAXO Next Core Update (Chrome Performance, Workstream C — Mandat "Hover Effects reagieren
   verzoegert"): .dash-card ist die gemeinsame Basisklasse fast jeder Dashboard-Karte — ein direktes
   `box-shadow`-Transition auf :hover (vorher hier) zwingt Chrome bei JEDEM animierten Zwischenschritt
   zu einem echten Repaint (Schatten muss neu berechnet/geblurrt werden), nicht nur zu einem
   guenstigen Compositor-Schritt, und das gleichzeitig mit der Wave-Canvas, die im Hintergrund
   permanent neu zeichnet (siehe CHROME_PERFORMANCE_AUDIT.md). Fix, OHNE das sichtbare Ergebnis zu
   aendern: derselbe Hover-Schatten (--shadow-hover) liegt jetzt auf einem eigenen ::after-Layer,
   einmalig gemalt, und wird per opacity ein-/ausgeblendet — opacity ist eine reine
  Compositor-Eigenschaft (kein Repaint pro Frame). transform bleibt ohnehin schon compositor-
  freundlich; border-color/background sind deutlich guenstigere Repaints als box-shadow und bleiben
  unveraendert direkt auf dem Element. */
.dash-card::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  box-shadow: var(--shadow-hover); opacity: 0; transition: opacity var(--transition-base);
}
.dash-card:hover {
  transform: translateY(var(--card-lift-hover)); border-color: var(--border);
  background: var(--card-surface-hover);
}
.dash-card:hover::after { opacity: 1; }
.dash-card--compact { padding: var(--card-pad-compact); box-shadow: none; }
.dash-card--compact::after { box-shadow: var(--shadow-raised); }
.dash-card--compact:hover { transform: none; }
.dash-card--flat { box-shadow: none; }

/* Card-Titel-System (Teil B, Punkt 8/11) — EIN Titelstil für alle Karteninhalte statt
   .section-head+h2 mit Inline-font-size (vorher überall 15px hart als style="" gesetzt) und
   parallel dazu .insights-title/.pr-title/.today-attention-title mit je eigener Deklaration.
   Alle drei münden jetzt in dieselbe Klasse. */
.dash-card__title {
  font-family: var(--font-display); font-size: 15px; font-weight: 600; color: var(--text);
  display: flex; align-items: center; gap: 8px; margin: 0 0 var(--space-3);
}
.dash-card__title .title-arrow { color: var(--text-dim); font-size: 12px; font-weight: 400; }
/* V6.2 (Mandat Teil I, Punkt 59): vorher zog .dash-card__desc sich per negativem margin-top
   (-6px) an den Titel heran, um dessen vollen --space-3-Abstand zu "reparieren" — genau die Art
   Spacing-Hack, die entfernt werden soll. Jetzt explizit positiv: der Titel bekommt NUR dann einen
   kleineren, dedizierten Title->Description-Abstand (--space-1), wenn tatsächlich eine
   Beschreibung folgt (per :has(), degradiert in nicht unterstützten Engines sicher auf den vollen
   --space-3-Abstand — kein Bruch, nur etwas mehr Weißraum). Titel ohne Description behalten den
   vollen --space-3-Abstand zum Karteninhalt. */
.dash-card__title:has(+ .dash-card__desc) { margin-bottom: var(--space-1); }
.dash-card__desc { font-size: 12.5px; color: var(--text-muted); margin-top: 0; margin-bottom: var(--space-3); }
.dash-card--compact .dash-card__title {
  font-family: var(--font-body); font-size: var(--fs-label); text-transform: uppercase;
  letter-spacing: var(--ls-label); color: var(--text-dim); font-weight: 600;
}

/* V6.2: die vorherige Sammel-Override-Regel für Card-Padding ist jetzt überflüssig — .dash-card/
   .dash-card--compact sitzen seit V6.2 direkt im DOM dieser Karten (siehe overview/*.js) und
   liefern Padding/Chrome unmittelbar, keine Klassenliste hier mehr nötig. */

/* ---------------------------------------------------------------------------
   SEMANTISCHE GRID-VARIANTEN (Teil E, Punkt 29/30) — ersetzen die blinde Wiederverwendung von
   .dashboard-two-col (auto-fit/minmax, für ALLE Inhaltstypen identisch) durch content-bewusste
   Kompositionen. .dashboard-two-col bleibt als Basis-Fallback bestehen (Rückwärtskompatibilität),
   wird aber in der neuen Overview-Struktur nicht mehr direkt verwendet.
   --------------------------------------------------------------------------- */
/* V6.2.2 (UI-Konsistenz-Mandat, Punkt 1-3/12/26): war bisher align-items:start — dadurch bestimmte
   JEDE Karte einer Row ihre Außenhöhe unabhängig aus ihrem eigenen Inhalt, obwohl gleichrangige
   Karten (Wochenfortschritt/Marathon Readiness, Heute Beachten/Coach Briefing, ...) auf Desktop
   nebeneinander als zusammengehöriges Paar wirken sollen. Root Cause: diese eine, generische
   Basisregel überschrieb (spätere CSS-Regel gleicher Spezifität gewinnt) sogar die für die
   Training/Wetter-Row bereits vorhandene .hero-zone{align-items:stretch}-Regel weiter oben in
   dieser Datei. stretch ist jetzt die Grid-weite Grundregel — jede Row aus gleichrangigen
   .dash-card-Elementen bekommt dadurch automatisch dieselbe Außenhöhe (siehe .dash-card
   height:100%), ohne dass jede einzelne Karte das selbst regeln müsste. */
/* v10.2.1 "OVERVIEW REFINEMENT" (Mandat Teil 18/19, "lower Overview surfaces still resemble the
   previous dashboard generation... larger composition areas, fewer hard boxes"): EIN gemeinsamer
   Radius-Uplift fuer jede grosse Karte unterhalb der Stage (--radius/10px -> --radius-lg/14px) --
   naehert die Rundung an die Stage (--radius-xl/22px) an, ohne eine zweite, komplett neue
   Kartenoptik zu erfinden (Mandat Teil 21: "maintain consistency, do NOT create dozens of unique
   card styles"). Rein additive Selektorliste ALLER bereits bestehenden, Overview-exklusiven
   Karten-Klassennamen -- .dash-card selbst (app-weit von Training/Health/Coach mitgenutzt) bleibt
   unangetastet, keine dieser Klassen existiert ausserhalb von overview.html. */
.hero-card, .weather-card, .talvaxo-readiness-card, .week-card, .next-key-card, .goal-card, .overview-trend-card,
.capability-card, .insights-card, .pr-card, .briefing-card, .today-attention-card,
.morning-briefing-card {
  border-radius: var(--radius-lg);
}
.dashboard-grid { display: grid; gap: var(--card-gap); align-items: stretch; }
@media (max-width: 480px) { .dashboard-grid { gap: var(--card-gap-mobile); } }

/* Stapelt mehrere Grids/Karten INNERHALB einer Zone (z.B. "Dein Tag": Training/Wetter-Grid +
   Coaching-Grid darunter) mit dem regulären Card-Gap statt vollem Zone-Abstand dazwischen. */
.dash-zone-stack { display: flex; flex-direction: column; gap: var(--card-gap); }

/* Dein Tag: Training deutlich schwerer als Wetter (Punkt 21: ca. 60/40 statt 50/50). */
.dashboard-grid--daily { grid-template-columns: 1fr; }
@media (min-width: 900px) { .dashboard-grid--daily { grid-template-columns: 3fr 2fr; } }

/* Coaching: Heute-Beachten + Coach-Briefing gehören zum selben Kontext (Punkt 22/23) — auf
   Desktop nebeneinander, sobald beide Karten vorhanden sind, sonst füllt die einzelne Karte die
   volle Breite (kein leeres Halbfeld). */
.dashboard-grid--coaching { grid-template-columns: 1fr; }
@media (min-width: 760px) {
  /* .is-double wird in JS gesetzt, sobald tatsächlich beide Karten (Heute Beachten + Coach
     Briefing) vorhanden sind — robuster als :has() gegen ältere/eingebettete Browser-Engines. */
  .dashboard-grid--coaching.is-double { grid-template-columns: 1fr 1fr; }
}

/* v10.2.2 (Mandat §20-23 "Race Readiness must not duplicate the weekly schedule"): "Deine Woche"
   und "Road to Goal" sind jetzt zwei eigene Sections statt eines gemeinsamen 1fr/1fr-Grids (siehe
   overview.js renderDashboard) — jede traegt genau eine Karte, die die volle Zonenbreite nutzt,
   aber auf breiten Screens nicht unlesbar in die Breite gezogen wird. */
.dashboard-grid--week { grid-template-columns: 1fr; align-items: start; }
.dashboard-grid--goal { grid-template-columns: 1fr; align-items: start; }
.dashboard-grid--week > .dash-card, .dashboard-grid--goal > .dash-card,
.dashboard-grid--week > .wk-modules-stack { height: auto; align-self: start; }
@media (min-width: 1100px) {
  .dashboard-grid--week > .dash-card, .dashboard-grid--goal > .dash-card,
  .dashboard-grid--week > .wk-modules-stack { max-width: 760px; }
}

/* Nutzerwunsch: "Diese Woche" (Deine Woche) und "Race Readiness — Marathon-Modell" (Road to Goal)
   nebeneinander statt gestapelt, mit gleicher Höhe. Bleibt bis 1100px einspaltig gestapelt (deckt
   sich mit der bereits bestehenden 1100px-Schwelle oben für dieselben zwei Kartentypen) — Reihenfolge
   Woche-vor-Ziel bleibt dabei erhalten (Mandat: mobile Reihenfolge muss die Desktop-Hierarchie
   spiegeln). .dash-zone-row--week-goal übernimmt hier bewusst die Außenabstands-Rolle einer
   .dashboard-section (siehe "goldene Spacing-Regel" oben) für den nächsten Zonenübergang, da die
   beiden echten .dashboard-section-Elemente jetzt innerhalb dieses Wrappers liegen statt direkt in
   .dashboard-flow. */
.dash-zone-row--week-goal { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--zone-gap); margin-bottom: var(--zone-gap); }
@media (max-width: 900px) { .dash-zone-row--week-goal { gap: var(--zone-gap-tablet); margin-bottom: var(--zone-gap-tablet); } }
@media (max-width: 480px) { .dash-zone-row--week-goal { gap: var(--zone-gap-mobile); margin-bottom: var(--zone-gap-mobile); } }
/* v10.4.2 (Independent Review Teil 10, real reproduced bug: at 1280px the week card showed only
   441px visible width against an 800px-wide 7-day row -- forced horizontal scroll on an ordinary
   desktop viewport). Root cause: a rigid 1100px min-width switched this row to an EQUAL 50/50
   split, but .wk-day-row needs >=792px (7 x minmax(108px,...) + 6x6px gaps, see that rule's own
   comment) plus the week card's 2x20px padding (--card-pad) plus its 2x1px border = >=834px just
   for itself -- an equal half of the content column never reliably clears that at common desktop
   widths (a 50/50 split only stops being too narrow once the viewport is close to 1980px). Fixed
   two ways together: (1) minmax(840px, 1fr) guarantees the week column NEVER drops below the
   width its own day-row needs (840 rounds the 834px bare minimum up for safety margin against
   subpixel/scrollbar-gutter rounding), whatever else shares the row -- no more magic-number
   coincidence between "half the screen" and "wide enough for 7 columns". (2) the breakpoint moves
   to 1480px, comfortably above the width where 840px (week) + 280px (a still-usable minimum for
   the Road-to-Goal column) + the 32px zone-gap actually fit; below it the row stays single-column/
   full-width instead (still zero scroll -- the full content width comfortably clears 840px well
   below 1480px, confirmed at the reviewer's own 1280px test width). Verified live in-browser at
   1280px/1440px/1480px/1920px: .wk-day-row's scrollWidth never exceeds its clientWidth at any of
   them (no forced horizontal scroll). */
@media (min-width: 1480px) {
  .dash-zone-row--week-goal { grid-template-columns: minmax(840px, 1fr) minmax(280px, 1fr); align-items: stretch; }
}
/* min-width:0 an jedem Glied dieser neuen Flex/Grid-Kette: sowohl Flex- als auch Grid-Kinder
   erhalten browser-seitig standardmäßig min-width:auto (= ihre intrinsische Inhaltsbreite) statt 0
   — ohne diese Overrides würde .wk-day-row's absichtlich in sich geschlossenes horizontales
   Scrollen (siehe .wk-day-row Mobile-Regel oben, minmax(108px,1fr) x 7 Spalten) nach oben durch
   .dashboard-grid--week/.dashboard-section__content/.dashboard-section durchschlagen und die ganze
   Zeile auf schmalen Screens seitwärts aus dem Viewport schieben, statt nur innerhalb der Wochenkarte
   zu scrollen. */
.dash-zone-row--week-goal > .dashboard-section { margin-bottom: 0; display: flex; flex-direction: column; min-width: 0; }
.dash-zone-row--week-goal > .dashboard-section > .dashboard-section__content { flex: 1; display: flex; min-width: 0; }
.dash-zone-row--week-goal .dashboard-grid--week,
.dash-zone-row--week-goal .dashboard-grid--goal { flex: 1; display: flex; min-width: 0; }
.dash-zone-row--week-goal .dashboard-grid--week > .dash-card,
.dash-zone-row--week-goal .dashboard-grid--goal > .dash-card,
.dash-zone-row--week-goal .dashboard-grid--week > .wk-modules-stack { height: 100%; align-self: stretch; flex: 1; max-width: none; min-width: 0; }

/* Entwicklung: Smart Insights + Capability nebeneinander (Punkt 28, Capability jetzt Teil dieser
   Zone statt einer eigenen "Weitere Details"-Sektion). */
.dashboard-grid--trends { grid-template-columns: 1fr; }
@media (min-width: 760px) { .dashboard-grid--trends { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); } }

/* Beta 7.5 (Punkt 68-73): abgeloest durch das generelle Primary/Secondary-Tiering unten
   (.metric-tile--primary/--secondary) — Readiness ist jetzt eine von vier Primary-Kacheln statt
   der einzigen hervorgehobenen, siehe PRIMARY_KEYS in assets/js/overview/metric-tiles.js. */

/* ---------------------------------------------------------------------------
   ENTRANCE ANIMATION (Teil L, Punkt 63) — dezentes Fade/Translate beim initialen Laden, auf
   Section-Ebene statt nur bei Hero/Tiles (vorher). Kurz (220-260ms), kein Bounce, kein Pulse.
   --------------------------------------------------------------------------- */
.dashboard-section { animation: dashFadeInUp 260ms ease both; }
.dashboard-section:nth-of-type(1) { animation-delay: 0ms; }
.dashboard-section:nth-of-type(2) { animation-delay: 40ms; }
.dashboard-section:nth-of-type(3) { animation-delay: 80ms; }
.dashboard-section:nth-of-type(4) { animation-delay: 120ms; }
.dashboard-section:nth-of-type(5) { animation-delay: 160ms; }
.dashboard-section:nth-of-type(6) { animation-delay: 200ms; }

@media (prefers-reduced-motion: reduce) {
  .dashboard-section { animation: none; }
  .dash-card, .dash-card:hover { transition: none; transform: none; }
}

/* ---------------------------------------------------------------------------
   SYSTEM HEALTH — Teil H/I Statusstufen (Punkt 43) + globaler Button immer verfügbar, aber
   dezent bei aktuellen Daten (Punkt 47/48).
   --------------------------------------------------------------------------- */
.sh-global-sync-btn.sh-subtle { opacity: 0.55; border-style: dashed; }
.sh-global-sync-btn.sh-subtle:hover { opacity: 1; }
.sh-global-sync-btn.sh-attention { border-color: var(--color-attention); color: var(--color-attention); opacity: 1; }
/* V6.2 (Mandat Teil E, Punkt 24/43) — Timeout-Warnung, wenn ein Manual-Sync-Request länger als
   MANUAL_TIMEOUT_MINUTES in PENDING/QUEUED/RUNNING hängt (Worker/Executor haben ihn nicht
   rechtzeitig übernommen). */
.sync-cat-btn-timeout, .sh-global-sync-btn.sync-cat-btn-timeout { border-color: var(--color-warning); color: var(--color-warning); }

/* ---------------------------------------------------------------------------
   ACCOUNT & SECURITY REDESIGN (v10.3, Mandat §26-59) — reuses the same tokens/card system as the
   rest of this file (.dash-card/.dashboard-section above) instead of a second design vocabulary
   (Mandat §56). Buttons follow .dh-cta's existing pill shape; only a primary/danger color variant
   and a ghost (low-emphasis) variant are new, since no non-login-page form/button system existed
   anywhere in this project before (verified by search) to reuse instead.
   --------------------------------------------------------------------------- */
.acct-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 18px; border-radius: var(--radius-pill); font-size: 13px; font-weight: 600;
  border: 1px solid var(--border-soft); background: var(--surface-interactive); color: var(--text);
  cursor: pointer; transition: transform var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast);
}
.acct-btn:hover { background: var(--surface-selected); border-color: var(--color-primary); transform: translateY(var(--card-lift-hover)); }
.acct-btn:active { transform: scale(var(--card-scale-press)); }
.acct-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.acct-btn:disabled { opacity: 0.55; cursor: default; transform: none; }
.acct-btn--primary { background: linear-gradient(135deg, var(--talvaxo-blue), var(--talvaxo-cyan)); color: #fff; border-color: transparent; }
.acct-btn--primary:hover { filter: brightness(1.08); background: linear-gradient(135deg, var(--talvaxo-blue), var(--talvaxo-cyan)); border-color: transparent; }
.acct-btn--ghost { background: transparent; }
.acct-btn--danger { color: var(--crimson); border-color: var(--crimson-dim); background: transparent; }
.acct-btn--danger:hover { background: var(--crimson-dim); border-color: var(--crimson); }
.acct-btn--danger-text { color: var(--crimson); }
/* Ohne dies gewinnt obiges "display:inline-flex" (Klassen-Selektor) gegen den UA-Default fuer
   [hidden] (dieselbe, bereits zweimal in components.css behobene Ursache — real gefunden beim
   Live-Test des neuen Avatar-Entfernen-Buttons, der trotz hidden-Attribut sichtbar blieb). */
.acct-btn[hidden] { display: none; }

/* Form fields — Mandat §57 "clear labels, never a placeholder as the only label". */
.acct-form { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.acct-field { display: flex; flex-direction: column; gap: 5px; width: 100%; max-width: 360px; }
.acct-field-row { display: flex; gap: 14px; flex-wrap: wrap; width: 100%; }
.acct-field-row .acct-field { flex: 1 1 160px; }
.acct-label { font-size: 12px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-label); }
.acct-input {
  font-family: var(--font-body); font-size: 14px; color: var(--text); background: var(--panel-alt);
  border: 1px solid var(--border-soft); border-radius: var(--radius-sm); padding: 10px 12px;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
.acct-input:focus-visible { outline: none; border-color: var(--color-primary); background: var(--surface-interactive); }
.acct-input--inline { max-width: 200px; }
.acct-field-source { font-size: 11px; color: var(--text-dim); }

/* v10.3.5 (Member Directory, Mandat §17-19): ein echtes <input type="checkbox">, nur vergroessert
   und per accent-color eingefaerbt statt eines komplett handgebauten Slider-Widgets -- bleibt damit
   automatisch tastatur-/screenreader-korrekt (Mandat §68 "accessible badges... keyboard
   navigation"), ohne eigene ARIA-Nachbildung. */
.acct-toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; width: 100%; padding: 10px 0; border-bottom: 1px solid var(--hairline); }
.acct-toggle-row:last-of-type { border-bottom: none; }
.acct-toggle-row-text { display: flex; flex-direction: column; gap: 3px; max-width: 420px; }
.acct-switch { flex-shrink: 0; width: 40px; height: 22px; accent-color: var(--talvaxo-cyan); cursor: pointer; }

/* Profile header + avatar */
/* Visual Redesign Execution Pass §32-33 ("Athlete Profile — full redesign required... premium
   Athlete Identity, not a settings-page header"): avatar and name enlarged for real presence,
   account-type badge added (see profile-header-type-badge below, wired in account.js) so this
   header actually answers "who is this athlete in TALVAXO" at a glance, not just "whose settings
   are these". Kept restrained per the same mandate's own "not social-media-like" instruction --
   no cover photo, no follower counts, just a clearer identity than a 20px name label provided. */
.acct-profile-header { flex-direction: row; align-items: center; gap: var(--space-5); flex-wrap: wrap; margin-bottom: var(--zone-gap); }
.acct-avatar-wrap { display: flex; flex-direction: column; align-items: center; gap: 8px; flex-shrink: 0; }
.acct-avatar {
  position: relative; width: 104px; height: 104px; border-radius: 50%; overflow: hidden;
  background: linear-gradient(135deg, var(--talvaxo-blue), var(--talvaxo-violet));
  display: flex; align-items: center; justify-content: center; border: 2px solid var(--border-soft);
  box-shadow: var(--shadow-raised);
}
.acct-avatar-initials { font-family: var(--font-display); font-size: 34px; font-weight: 700; color: #fff; }
.acct-avatar img#acct-avatar-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.acct-avatar-actions { display: flex; gap: 8px; }
.acct-avatar-hint { font-size: 11px; color: var(--text-dim); text-align: center; margin: 0; }
.acct-profile-header-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.acct-profile-name-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.acct-profile-name { font-family: var(--font-display); font-size: 32px; font-weight: 700; color: var(--text); line-height: 1.1; }
.acct-profile-type-badge {
  flex-shrink: 0; display: inline-flex; align-items: center; font-family: var(--font-mono);
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; border-radius: var(--radius-pill);
  padding: 4px 11px;
}
.acct-profile-type-badge[hidden] { display: none; }
/* Same color roles as .topbar-profile-menu-badge--*/.mem-badge--* (nav.js/members.css) -- same
   meaning, same account_type field, intentionally not a fourth invented color set. */
.acct-profile-type-badge--founder { color: var(--talvaxo-violet); background: color-mix(in srgb, var(--talvaxo-violet) 16%, transparent); }
.acct-profile-type-badge--beta_tester { color: var(--talvaxo-cyan); background: color-mix(in srgb, var(--talvaxo-cyan) 14%, transparent); }
.acct-profile-type-badge--member { color: var(--text-muted); background: var(--panel-alt); }
.acct-profile-type-badge--demo { color: var(--color-attention); background: color-mix(in srgb, var(--color-attention) 14%, transparent); }
.acct-profile-type-badge--test { color: var(--text-dim); background: var(--status-neutral-dim); }
.acct-profile-goal { font-size: 14px; color: var(--text-muted); }
/* v10.3.1 (Mandat §5-7): kompakter, echter Konto-Kontext -- ersetzt die entfernte generische
   Tagesleistungs-Kachelleiste. Bewusst klein/zurueckhaltend (Mandat §7 "do not make this area
   unnecessarily tall"), reine Text+Badge-Paare, keine neue Kartenoptik. */
.acct-context-row { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; }
.acct-context-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-dim); }

/* Complete Visual Redesign Mandat §33-35 (Profile structural rebuild: "Profile Overview plus
   segmented subnavigation"). Tab bar styling is the exact same recipe as .admin-tabs
   (admin.css) -- same already-light-mode-audited --teal-on-panel active state, deliberately not
   a second visual language for what is functionally the same component on a different page. */
.acct-tabs { display: flex; gap: 4px; flex-wrap: wrap; background: var(--panel-alt); border-radius: var(--radius-sm); padding: 4px; margin-bottom: 20px; }
.acct-tabs button { font-family: var(--font-body); font-size: 13px; font-weight: 600; padding: 9px 16px; border-radius: 6px; background: transparent; border: none; color: var(--text-muted); cursor: pointer; white-space: nowrap; }
.acct-tabs button.active { background: var(--panel-raised); color: var(--teal-on-panel); }
.acct-tabs button:hover:not(.active) { color: var(--text); }
.acct-tabs button:focus-visible { outline: 2px solid var(--teal-on-panel); outline-offset: 2px; }
@media (max-width: 640px) { .acct-tabs { overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; } }

/* Profile Overview tab: a navigational card grid, not a settings form (Mandat §35 "Profile
   Overview should be readable, not form-heavy... detailed editing belongs inside Athlete/
   Training/Services/Privacy/Account"). Each card jumps straight to its tab (account.js
   setupAcctTabs/data-acct-jump). */
.acct-overview-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; margin-bottom: 20px; }
.acct-overview-card {
  display: flex; flex-direction: column; gap: 6px; text-align: left; text-decoration: none;
  background: var(--surface-hero); border: 1px solid var(--border-soft); border-radius: var(--radius);
  padding: 18px 20px; cursor: pointer; transition: border-color 160ms ease, transform 160ms ease;
  backdrop-filter: blur(20px) saturate(130%); -webkit-backdrop-filter: blur(20px) saturate(130%);
}
.acct-overview-card:hover { border-color: var(--teal-on-panel); transform: translateY(-2px); }
.acct-overview-card:focus-visible { outline: 2px solid var(--teal-on-panel); outline-offset: 2px; }
.acct-overview-card-eyebrow { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.06em; color: var(--talvaxo-cyan); text-transform: uppercase; }
.acct-overview-card-title { font-family: var(--font-display); font-size: 16.5px; font-weight: 700; color: var(--text); }
.acct-overview-card-desc { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }

/* Rows (label/value pairs, replaces the old .account-row) */
/* Visual Redesign Execution Pass §36: same left-edge accent-bar language already established on
   TALVAXO Operations (.admin-panel) -- a data-source connection card, not another settings panel. */
.svc-connection-card { position: relative; padding-left: 30px; }
.svc-connection-card::before {
  content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px; border-radius: 2px;
  background: var(--accent-data); opacity: 0.55;
}
.acct-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--hairline); flex-wrap: wrap; }
.acct-row:last-of-type { border-bottom: none; }
.acct-row-label { font-size: 13px; color: var(--text-muted); }
.acct-row-value { font-size: 13.5px; color: var(--text); font-weight: 600; }
.acct-code { font-family: var(--font-mono); color: var(--text); background: var(--panel-alt); padding: 2px 6px; border-radius: 4px; word-break: break-all; }

/* v10.3.1 (Account Finalization, Mandat §17-19/§38 "2FA QR CODE"): ein QR-Code muss unabhaengig
   vom aktuellen Theme immer hohen Schwarz-auf-Weiss-Kontrast behalten (Scanner-Zuverlaessigkeit
   geht vor Theme-Konsistenz) -- deshalb bewusst ein fester weisser Rahmen statt Theme-Tokens,
   in BEIDEN Themes identisch. */
.acct-mfa-qr { display: block; width: 176px; height: 176px; margin: 10px 0 14px; padding: 10px; background: #fff; border-radius: var(--radius-sm); box-shadow: 0 0 0 1px var(--hairline); }
.acct-mfa-manual-key { margin: 0 0 16px; }
.acct-mfa-manual-key summary { cursor: pointer; font-size: 12.5px; color: var(--talvaxo-cyan); }
.acct-mfa-manual-key .auth-hint { margin: 8px 0 0; }
@media (max-width: 480px) { .acct-mfa-qr { width: 152px; height: 152px; } }

.acct-badge { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 700; letter-spacing: 0.02em; background: var(--status-neutral-dim); color: var(--text-muted); }
.acct-badge--neutral { background: var(--status-neutral-dim); color: var(--text-dim); }
.acct-badge--good { background: var(--status-good-dim); color: var(--status-good); }
.acct-badge--bad { background: var(--status-bad-dim); color: var(--status-bad); }
.acct-badge--warn { background: var(--status-warn-dim); color: var(--status-warn); }

.acct-security-stack { display: flex; flex-direction: column; gap: var(--space-3); }

/* Personal Records mini-grid */
.acct-records-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-3); margin-bottom: 12px; }
.acct-record-item { display: flex; flex-direction: column; gap: 2px; }
.acct-record-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: var(--ls-label); }
.acct-record-value { font-family: var(--font-mono); font-size: 18px; font-weight: 700; color: var(--text); }
.acct-record-source { font-size: 11px; color: var(--text-dim); }
.acct-records-empty { color: var(--text-muted); font-size: 13px; }
.acct-link { font-size: 13px; color: var(--talvaxo-cyan); text-decoration: none; font-weight: 600; }
.acct-link:hover { text-decoration: underline; }

/* Danger Zone — Mandat §48: must not look like a normal primary action. */
.acct-danger-zone { border-color: var(--crimson-dim); margin-top: var(--space-3); }
.acct-danger-title { color: var(--crimson); }

@media (max-width: 640px) {
  .acct-profile-header { flex-direction: column; align-items: flex-start; text-align: left; }
  .acct-field-row { flex-direction: column; }
  .acct-input { width: 100%; }
}
