/**
 *
 * Dashboard (Kunden-Cockpit)
 *
 * Kopfkarten (Score-Schnitt, Verteilung der Seiten), Chart-Wrapper und
 * Domain-Filter. Nutzt die globalen CSS-Variablen aus assets/css/app.css
 * (Theme-faehig).
 *
 * Die Kopfkarten haben die sechs gleichen Kacheln abgeloest. Sechs Kacheln
 * in einer Reihe haben zwei verschiedene Dinge in dieselbe Form gepresst:
 * drei Scores auf einer Skala von 0 bis 100 und drei blosse Bestandszahlen.
 * In derselben Form gelesen sieht eine 82 neben einer 14 aus wie zwei
 * vergleichbare Groessen. Jetzt tragen die Scores Balken mit ihrer Skala,
 * die Bestandszahlen stehen als Fussleiste darunter.
 *
 * @version 2.0.0
 * @last-modified 16.09.2026
 *
 */

/* ========================================================================
   Farben der Kennzahlen
   ------------------------------------------------------------------------
   Die drei Kennzahlen sind Kategorien, keine Rangfolge - also drei Farbtoene
   und keine Helligkeitsrampe. Bewusst nicht Gruen/Gelb/Rot: das ist in
   dieser App die Bewertungsfarbe (score-chip, Abzeichen in der Tabelle). Eine
   Kennzahl dauerhaft in Gruen zu fuehren, wuerde eine Bewertung behaupten,
   die erst der Wert selbst traegt.

   Die dritte Kennzahl stand zuerst auf Rose (345) und lag damit keine 15 Grad
   neben dem Rot der Stufe "Schwach" in der Nachbarkarte. Magenta (313) haelt
   Abstand zu beiden Nachbarn und zum Rot - drei Kategorien muessen sich auch
   dann unterscheiden lassen, wenn sie nicht nebeneinander liegen.

   Dieselben drei Werte faerben die Balken der Karte und die Linien im
   Score-Verlauf. Karte und Diagramm sind damit dieselbe Zuordnung.

   Die Werte liegen hier und nicht im JS: Chart.js kennt die Theme-Umschaltung
   nicht, CSS schon. Das JS liest sie zur Zeichenzeit (dashboard.bw.js).
   ==================================================================== */
#dashboard {
      /* Dunkelmodus, geprueft gegen die Kartenflaeche #191C29 */
      --dash-m1: #a98ffb;
      /* PageSpeed  - Markenviolett 280 */
      --dash-m2: #5cc5db;
      /* Meta       - Cyan 190 */
      --dash-m3: #e58ed3;
      /* Qualitaet  - Magenta 313 */

      /* Flaeche hinter den Marken: liefert den Spalt zwischen den
         Ringsegmenten, so wie in der Keyword-Analyse. */
      --dash-surface: #191c29;

      --dash-ink: hsl(var(--foreground));
      --dash-ink-muted: hsl(var(--muted-foreground));
      --dash-grid: hsl(var(--border) / 0.55);
      --dash-axis: hsl(var(--border));

      /* Leere Spur der Balken */
      --dash-track: hsl(var(--muted-foreground) / 0.16);
}

html[data-theme='light'] #dashboard {
      /* Eigene Stufen, kein Abdunkeln der Dunkelmodus-Werte - die tragen
         auf Weiss nicht. */
      --dash-m1: #6532be;
      --dash-m2: #0f7a91;
      --dash-m3: #9b2f87;

      --dash-surface: #ffffff;
      --dash-track: hsl(var(--muted-foreground) / 0.2);
}

/* ========================================================================
   Kopfkarten
   ==================================================================== */

/* Links die Scores, rechts die Verteilung. Zwei Drittel zu einem Drittel:
   die Balken brauchen Laenge, sonst sind 82 % und 74 % zwei gleich lange
   Striche. */
#dashboard .dash-head {
      display: grid;
      grid-template-columns: minmax(0, 1fr);
      gap: var(--page-gap-block);
}

@media (min-width: 1024px) {
      #dashboard .dash-head {
            grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
      }
}

/* Beide Karten stehen nebeneinander und damit auf gleicher Hoehe. Der
   Koerper ist eine Spalte, in der die Fussnote unten andockt - sonst haengt
   sie in der kuerzeren Karte mitten in der Flaeche. */
#dashboard .dash-head .page-card {
      display: flex;
      flex-direction: column;
}

#dashboard .dash-card-body {
      display: flex;
      flex-direction: column;
      flex: 1 1 auto;
      padding: 1.25rem 1.25rem 1rem;
}

/* ------------------------------------------------------------------------
   Score-Zeilen
   ------------------------------------------------------------------------
   Zwei Zeilen je Kennzahl: oben Name, Wert und Veraenderung, darunter der
   Balken. Der Balken traegt die Skala, die der blossen Zahl fehlt - 82 sagt
   nichts, 82 von 100 mit der Marke bei 90 sagt alles.
   -------------------------------------------------------------------- */
#dashboard .dash-scores {
      display: flex;
      flex-direction: column;
      gap: 1.125rem;
}

#dashboard .dash-score {
      display: grid;
      grid-template-columns: 0.5rem minmax(0, 1fr) auto;
      grid-template-areas:
            'chip label value'
            'chip track track';
      align-items: center;
      column-gap: 0.75rem;
      row-gap: 0.5rem;
}

/* Der Farbstreifen laeuft ueber beide Zeilen und bindet Name und Balken
   zusammen - dieselbe Marke wie die Linie im Verlauf darunter. */
#dashboard .dash-score-chip {
      grid-area: chip;
      align-self: stretch;
      border-radius: 1px;
      background: var(--dash-hue);
}

#dashboard .dash-score-label {
      grid-area: label;
      font-size: 0.875rem;
      color: var(--dash-ink);
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
}

#dashboard .dash-score-figure {
      grid-area: value;
      display: flex;
      align-items: baseline;
      gap: 0.625rem;
      white-space: nowrap;
}

/* Zahlen in der Hausschrift fuer Code, mit Tabellenziffern: nur damit
   fluchten die drei Werte untereinander. */
#dashboard .dash-score-value {
      font-family: 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
      font-size: 1.5rem;
      font-weight: 600;
      line-height: 1;
      color: var(--dash-ink);
}

#dashboard .dash-score-unit {
      font-size: 0.875rem;
      font-weight: 400;
      color: var(--dash-ink-muted);
}

/* ------------------------------------------------------------------------
   Balken
   ------------------------------------------------------------------------
   Feste Skala 0..100 mit einer Haarlinie bei 90. Das ist dieselbe Schwelle,
   ab der die Score-Chips der Tabelle auf Gruen springen - die Marke macht
   aus dem Balken eine Aussage ueber das Ziel und nicht nur ueber den Wert.
   -------------------------------------------------------------------- */
#dashboard .dash-score-track {
      grid-area: track;
      position: relative;
      height: 0.5rem;
      border-radius: 1px;
      background: var(--dash-track);
      overflow: hidden;
}

#dashboard .dash-score-fill {
      display: block;
      height: 100%;
      width: var(--dash-fill, 0%);
      border-radius: 1px;
      background: var(--dash-hue);
}

/* Zwei Haarlinien nebeneinander, eine helle und eine dunkle. Eine einzelne
   Linie verschwindet je nach Fuellstand: ueber der gefuellten Strecke braucht
   sie den Gegenton der Kennzahlenfarbe, ueber der leeren den der Spur - und
   welche der beiden bei 90 liegt, haengt am Wert. So traegt immer eine der
   beiden, ohne dass die Marke dicker wirkt als ein Strich. */
#dashboard .dash-score-mark {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 90%;
      width: 2px;
      background: linear-gradient(90deg,
                  hsl(var(--background) / 0.85) 0 1px,
                  hsl(var(--foreground) / 0.5) 1px 2px);
}

/* ------------------------------------------------------------------------
   Veraenderung gegenueber der vorherigen Analyse
   -------------------------------------------------------------------- */
#dashboard .dash-trend {
      display: inline-flex;
      align-items: center;
      gap: 0.125rem;
      font-family: 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
      font-size: 0.75rem;
      font-weight: 600;
      /* Gleiche Breite fuer +4, -2 und ±0: sonst wandert der Balkenwert
         daneben von Zeile zu Zeile. */
      min-width: 3rem;
      justify-content: flex-end;
}

#dashboard .dash-trend svg {
      width: 0.875rem;
      height: 0.875rem;
}

#dashboard .dash-trend-up {
      color: hsl(var(--status-success-text));
}

#dashboard .dash-trend-down {
      color: hsl(var(--status-danger-text));
}

#dashboard .dash-trend-same {
      color: var(--dash-ink-muted);
}

/* ------------------------------------------------------------------------
   Bestandszahlen als Fussleiste
   ------------------------------------------------------------------------
   Analysen, offene Empfehlungen und Stand sind Begleitzahlen, keine Scores.
   Als Zeile unter dem Trennstrich stehen sie dort, wo sie hingehoeren - im
   Kachelraster haben sie ausgesehen wie gleichrangige Kennzahlen.
   -------------------------------------------------------------------- */
#dashboard .dash-figures {
      display: flex;
      flex-wrap: wrap;
      gap: 1.75rem;
      margin-top: auto;
      padding-top: 0.875rem;
      border-top: 1px solid hsl(var(--border));
}

#dashboard .dash-figure-label {
      display: block;
      font-size: 0.75rem;
      color: var(--dash-ink-muted);
}

#dashboard .dash-figure-value {
      font-family: 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
      font-size: 1.0625rem;
      font-weight: 600;
      color: var(--dash-ink);
}

/* Offene Empfehlungen sind der einzige Wert der Leiste, an dem Arbeit
   haengt. Er faerbt sich nur, wenn welche offen sind. */
#dashboard .dash-figure-value.is-open {
      color: hsl(var(--status-warning-text));
}

/* ------------------------------------------------------------------------
   Ring: Verteilung der Seiten auf die Bewertungsstufen
   ------------------------------------------------------------------------
   Gleiche Bauform wie das Ringdiagramm der Keyword-Analyse: schmaler Ring,
   die Gesamtzahl im Kern, daneben die Stufen als Liste mit Zahl und Anteil.
   Eine Rangfolge liest man als Liste, nicht als Wolke aus bunten Kaestchen.
   -------------------------------------------------------------------- */
#dashboard .dash-donut-wrap {
      display: grid;
      grid-template-columns: minmax(0, 160px) minmax(0, 1fr);
      align-items: center;
      align-content: center;
      gap: 1rem;
      flex: 1 1 auto;
}

@media (max-width: 480px) {
      #dashboard .dash-donut-wrap {
            grid-template-columns: minmax(0, 1fr);
      }
}

#dashboard .dash-donut-canvas {
      position: relative;
      height: 160px;
}

#dashboard .dash-donut-center {
      position: absolute;
      inset: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      pointer-events: none;
      text-align: center;
}

#dashboard .dash-total-value {
      font-family: 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
      font-size: 1.875rem;
      font-weight: 700;
      line-height: 1;
      color: var(--dash-ink);
}

#dashboard .dash-total-label {
      margin-top: 0.25rem;
      font-size: 0.75rem;
      color: var(--dash-ink-muted);
}

#dashboard .dash-bands {
      display: flex;
      flex-direction: column;
      gap: 0.125rem;
      min-width: 0;
}

#dashboard .dash-band {
      display: grid;
      grid-template-columns: 0.5rem minmax(0, 1fr) auto auto;
      align-items: center;
      gap: 0.625rem;
      padding: 0.375rem 0.5rem;
      border-radius: 0.375rem;
      border: 1px solid transparent;
      font-size: 0.8125rem;
      line-height: 1.2;
      transition: background-color 0.15s ease, border-color 0.15s ease;
}

#dashboard .dash-band.is-active {
      background: hsl(var(--primary) / 0.08);
      border-color: hsl(var(--primary) / 0.28);
}

/* Leere Stufen bleiben stehen: dass keine Seite schwach ist, ist selbst
   eine Aussage. Sie treten nur zurueck. */
#dashboard .dash-band.is-empty {
      opacity: 0.45;
}

#dashboard .dash-band-chip {
      width: 0.5rem;
      height: 1.5rem;
      border-radius: 1px;
      background: var(--dash-hue);
}

#dashboard .dash-band.is-empty .dash-band-chip {
      background: hsl(var(--border));
}

#dashboard .dash-band-label {
      color: var(--dash-ink);
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
}

#dashboard .dash-band-range {
      display: block;
      font-size: 0.6875rem;
      color: var(--dash-ink-muted);
}

#dashboard .dash-band-value,
#dashboard .dash-band-share {
      font-family: 'IBM Plex Mono', ui-monospace, monospace;
      font-variant-numeric: tabular-nums;
}

#dashboard .dash-band-value {
      color: var(--dash-ink);
      font-weight: 600;
}

#dashboard .dash-band-share {
      color: var(--dash-ink-muted);
      min-width: 3rem;
      text-align: right;
}

/* ------------------------------------------------------------------------
   Fussnote
   ------------------------------------------------------------------------
   Nennt die Regel, nach der die Zahl darueber zustande kommt. Ohne sie
   haelt jemand den Schnitt ueber die letzten Analysen fuer den Schnitt
   ueber alle.
   -------------------------------------------------------------------- */
#dashboard .dash-note {
      margin: 0.875rem 0 0;
      font-size: 0.75rem;
      line-height: 1.45;
      color: var(--dash-ink-muted, hsl(var(--muted-foreground)));
}

/* ========================================================================
   Score-Verlauf
   ==================================================================== */
#dashboard .dash-domain-select {
      background: hsl(0 0% 100% / 0.15);
      border: 1px solid hsl(0 0% 100% / 0.35);
      color: #fff;
      border-radius: 0.4rem;
      padding: 0.35rem 0.6rem;
      font-size: 0.85rem;
      max-width: 260px;
}

#dashboard .dash-domain-select option {
      color: #111;
}

#dashboard .dash-chart-wrap {
      position: relative;
      height: 320px;
      width: 100%;
}

/* ========================================================================
   Leerer Zustand
   ==================================================================== */
#dashboard .dash-cta {
      background: var(--gradient-primary);
      color: #fff;
      font-weight: 600;
      padding: 0.7rem 1.5rem;
      border-radius: 0.5rem;
      transition: opacity 0.2s ease;
}

#dashboard .dash-cta:hover {
      opacity: 0.9;
}

#dashboard .table-responsive {
      overflow-x: auto;
}

@media (max-width: 640px) {
      #dashboard .dash-chart-wrap {
            height: 260px;
      }

      #dashboard .dash-figures {
            gap: 1.25rem;
      }
}

/* Kein Wechselspiel beim Ueberfahren, wenn der Nutzer das abbestellt hat. */
@media (prefers-reduced-motion: reduce) {
      #dashboard .dash-band {
            transition: none;
      }
}
