/**
 * css/grafik.css — Das Aussehen der Diagramme
 *
 * Gehoert zu js/grafik.js. Wird von index.php geladen.
 *
 * Jede Farbe kommt aus `--f`, das der Baustein je Diagramm setzt. Hier steht
 * NIE eine Datenfarbe — sonst haette dieselbe Sache zwei Wahrheiten.
 * Abstaende, Radien und Schriftgroessen aus css/system.css.
 *
 * ══ WARUM DIE LINIEN SO DUENN SIND ══════════════════════════════════════
 * 2 px, und `vector-effect: non-scaling-stroke`. Die Verlaeufe werden ueber
 * `preserveAspectRatio="none"` in die Breite gezogen — ohne diese Angabe
 * zoege es die Linienstaerke mit, und dieselbe Linie waere in einer breiten
 * Karte dick und in einer schmalen duenn. Bei nebeneinanderliegenden Karten
 * faellt das sofort auf.
 */

/* ── Verlauf ───────────────────────────────────────────────────────────── */
.gr-verlauf-huelle { position: relative; width: 100%; }
.gr-verlauf { width: 100%; height: 100%; display: block; overflow: visible; }
.gr-linie { fill: none; stroke: var(--f); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.gr-band  { fill: var(--f); opacity: .10; }

/* Der leuchtende Endpunkt — „hier stehst du jetzt", ohne Beschriftung.
   Als eigenes Element und nicht im SVG: dort wuerde ihn die ungleiche
   Streckung zur Ellipse ziehen. */
.gr-punkt {
  position: absolute;
  width: 9px; height: 9px;
  margin: calc(-1 * var(--nv-s1)) 0 0 calc(-1 * var(--nv-s1));
  border-radius: 50%;
  background: var(--f);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--f) 22%, transparent),
              0 0 12px color-mix(in srgb, var(--f) 55%, transparent);
  pointer-events: none;
}

/* ── Kennzahl: Zahl links gross, Bild rechts ───────────────────────────── */
.gr-kennzahl { display: flex; align-items: center; gap: var(--nv-s4, var(--nv-s4)); }
.gr-kennzahl-links { flex: 0 0 auto; min-width: 0; }
.gr-kennzahl-rechts { flex: 1 1 auto; min-width: 0; }

.gr-kennzahl-wert {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.05;
  color: var(--k-text);
  font-variant-numeric: tabular-nums;
}
/* Das eine Wort, das die Zahl einordnet („Unter dem Ziel"). Es traegt die
   Farbe, nicht die Zahl: die Zahl soll lesbar sein, die Deutung auffallen. */
.gr-kennzahl-deutung {
  font-size: var(--k-fs-body);
  font-weight: 600;
  color: var(--f);
  margin-top: 2px;
}
.gr-kennzahl-label {
  font-size: var(--k-fs-caption);
  color: var(--k-text3);
  margin-top: 2px;
}

/* ── Balken mit Ziellinie ──────────────────────────────────────────────── */
.gr-balken { position: relative; display: flex; flex-direction: column; }
.gr-balken-reihe {
  flex: 1 1 auto;
  display: flex;
  align-items: flex-end;
  gap: var(--nv-s1);
  min-height: 0;
}
.gr-balken-saeule { flex: 1 1 0; height: 100%; display: flex; align-items: flex-end; }
.gr-balken-fuellung {
  width: 100%;
  border-radius: var(--nv-r-marke) var(--nv-r-marke) 2px 2px; /* Nacht 4 (Stefan 21): Balkenkopf auf der Marke, Fuss bleibt 2 */
  background: color-mix(in srgb, var(--f) 28%, transparent);
  transition: height .3s cubic-bezier(.22, 1, .36, 1);
}
/* Der letzte Balken ist „heute" — voll gesaettigt, damit man ihn ohne
   Beschriftung findet. */
.gr-balken-saeule.ist-jetzt .gr-balken-fuellung {
  background: var(--f);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--f) 40%, transparent);
}

.gr-ziel {
  position: absolute;
  left: 0; right: 0;
  border-top: 1.5px dashed color-mix(in srgb, var(--f) 60%, transparent);
  pointer-events: none;
}
/* Die Beschriftung steht LINKS. Rechts liegt der juengste Balken — und der
   ist der hervorgehobene, den man sehen soll. Nachgesehen im Bildschirmfoto:
   „Ziel 1200" lag genau auf dem Samstags-Balken. */
.gr-ziel-wert {
  position: absolute;
  left: 0; top: -8px;
  font-size: var(--k-fs-caption);
  font-weight: 700;
  color: var(--f);
  background: var(--k-bg2, var(--nv-flaeche-erhoben));
  padding: 0 var(--nv-s1);
  border-radius: var(--nv-r-marke);
}

.gr-balken-achse {
  display: flex;
  gap: var(--nv-s1);
  margin-top: var(--nv-s1);
}
.gr-balken-achse span {
  flex: 1 1 0;
  text-align: center;
  font-size: var(--k-fs-micro);
  color: var(--k-text3);
  white-space: nowrap;
  overflow: hidden;
}

/* ── Anteile: ein Band ─────────────────────────────────────────────────── */
.gr-anteile-band {
  display: flex;
  height: 12px;
  border-radius: var(--nv-r-kapsel);
  overflow: hidden;
  gap: 2px;
  background: var(--k-bg3, rgba(0, 0, 0, .05));
}
.gr-anteil { background: var(--f); transition: width .35s cubic-bezier(.22, 1, .36, 1); }
.gr-anteil:first-child { border-radius: var(--nv-r-kapsel) 0 0 var(--nv-r-kapsel); }
.gr-anteil:last-child  { border-radius: 0 var(--nv-r-kapsel) var(--nv-r-kapsel) 0; }
.gr-anteil:only-child  { border-radius: var(--nv-r-kapsel); }

.gr-legende { display: flex; flex-direction: column; gap: var(--nv-s2); margin-top: var(--nv-s3, var(--nv-s3)); }
.gr-legende-punkt { display: flex; align-items: center; gap: var(--nv-s2); }
.gr-legende-farbe { width: 10px; height: 10px; border-radius: var(--nv-r-marke); background: var(--f); flex: 0 0 auto; } /* Nacht 4 (Stefan 21): Marke 6 px, war 3 */
.gr-legende-text {
  flex: 1 1 auto;
  font-size: var(--k-fs-body);
  color: var(--k-text2, var(--k-text));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gr-legende-wert {
  font-size: var(--k-fs-body);
  font-weight: 700;
  color: var(--k-text);
  font-variant-numeric: tabular-nums;
}
.gr-legende-wert small { font-weight: 500; color: var(--k-text3); margin-left: 2px; }

/* ── Ring ──────────────────────────────────────────────────────────────── */
.gr-ring-huelle { display: flex; flex-direction: column; align-items: center; gap: var(--nv-s2); }
.gr-ring { position: relative; width: 80px; height: 80px; }
.gr-ring svg { width: 100%; height: 100%; }
.gr-ring circle { fill: none; stroke-width: 8; stroke-linecap: round; }
.gr-ring-spur  { stroke: var(--k-bg3, rgba(0, 0, 0, .07)); }
.gr-ring-fuell {
  stroke: var(--f);
  transition: stroke-dasharray .45s cubic-bezier(.22, 1, .36, 1);
}
.gr-ring-mitte {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  pointer-events: none;
}
.gr-ring-wert {
  font-size: var(--k-fs-hervor); font-weight: 700; letter-spacing: -.02em;
  color: var(--k-text); font-variant-numeric: tabular-nums;
}
.gr-ring-unter { font-size: var(--k-fs-micro); color: var(--k-text3); }
.gr-ring-label { font-size: var(--k-fs-caption); font-weight: 600; color: var(--f); }

/* ── Rangliste: wer wieviel ────────────────────────────────────────────── */
.gr-rangliste { display: flex; flex-direction: column; gap: var(--nv-s3, var(--nv-s3)); }
.gr-rang-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: var(--nv-s2); margin-bottom: var(--nv-s1); }
.gr-rang-name {
  font-size: var(--k-fs-body); font-weight: 600; color: var(--k-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gr-rang-wert {
  font-size: var(--k-fs-body); font-weight: 700; color: var(--f);
  font-variant-numeric: tabular-nums; flex: 0 0 auto;
}
.gr-rang-spur {
  position: relative;
  height: 8px;
  border-radius: var(--nv-r-kapsel);
  background: var(--k-bg3, rgba(0, 0, 0, .05));
  overflow: hidden;
}
/* ══ VOLLTON, KEIN FARBVERLAUF ═══════════════════════════════════════════
   Hier stand ein Verlauf von „65 % Farbe, Rest durchsichtig" zur vollen
   Farbe. Ueber der grauen Spur ergab das eine gemischte Farbe: Orange wurde
   braun, Gruen wurde oliv. Nachgesehen im Bildschirmfoto — die Balken der
   Mitarbeiterinnen unter Ziel sahen schmutzig aus, nicht warnend.
   Eine Datenfarbe muss die Farbe sein, die sie meint. */
.gr-rang-fuell {
  height: 100%;
  border-radius: var(--nv-r-kapsel);
  background: var(--f);
  transition: width .4s cubic-bezier(.22, 1, .36, 1);
}
/* Die Ziellinie liegt UEBER der Fuellung, sonst verschwindet sie unter ihr,
   sobald jemand das Ziel uebertrifft — und dann sieht man nicht mehr, dass
   er es uebertroffen hat. */
.gr-rang-ziel {
  position: absolute; top: -2px; bottom: -2px;
  width: 2px;
  background: var(--k-text3);
  opacity: .55;
}
.gr-rang-unter { font-size: var(--k-fs-caption); color: var(--k-text3); margin-top: var(--nv-s1); }
.gr-rang.ist-unter-ziel .gr-rang-name::after {
  content: '';
  display: inline-block;
  width: 6px; height: 6px;
  margin-left: var(--nv-s2);
  border-radius: 50%;
  background: var(--f);
  vertical-align: middle;
}

/* ── Vergleich: dieser Monat vs. Vormonat ──────────────────────────────── */
.gr-vergleich-label {
  font-size: var(--k-fs-caption); font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--k-text3); margin-bottom: var(--nv-s2, var(--nv-s2));
}
.gr-vergleich-zeilen { display: flex; flex-direction: column; gap: var(--nv-s2); }
.gr-vergleich-zeile { display: flex; align-items: center; gap: var(--nv-s2); }
.gr-vergleich-name {
  flex: 0 0 92px;
  font-size: var(--k-fs-caption);
  color: var(--k-text3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gr-vergleich-spur {
  flex: 1 1 auto;
  height: 10px;
  border-radius: var(--nv-r-kapsel);
  background: var(--k-bg3, rgba(0, 0, 0, .05));
  overflow: hidden;
}
.gr-vergleich-fuell {
  display: block; height: 100%;
  border-radius: var(--nv-r-kapsel);
  background: color-mix(in srgb, var(--f) 35%, transparent);
  transition: width .4s cubic-bezier(.22, 1, .36, 1);
}
.gr-vergleich-zeile.ist-jetzt .gr-vergleich-fuell { background: var(--f); }
.gr-vergleich-wert {
  flex: 0 0 auto;
  font-size: var(--k-fs-body);
  font-weight: 700;
  color: var(--k-text);
  font-variant-numeric: tabular-nums;
}
.gr-vergleich-zeile:not(.ist-jetzt) .gr-vergleich-wert { font-weight: 500; color: var(--k-text3); }
.gr-vergleich-diff {
  display: flex; align-items: center; gap: var(--nv-s1);
  margin-top: var(--nv-s2, var(--nv-s2));
  font-size: var(--k-fs-body);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.gr-vergleich-diff .material-symbols-rounded { font-size: var(--k-fs-hervor); }

/* ── Fortschritt ───────────────────────────────────────────────────────── */
.gr-fortschritt-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: var(--nv-s2); margin-bottom: var(--nv-s1); }
.gr-fortschritt-name { font-size: var(--k-fs-body); color: var(--k-text2, var(--k-text)); }
.gr-fortschritt-wert {
  font-size: var(--k-fs-body); font-weight: 700; color: var(--f);
  font-variant-numeric: tabular-nums;
}
.gr-fortschritt-spur {
  height: 8px; border-radius: var(--nv-r-kapsel);
  background: var(--k-bg3, rgba(0, 0, 0, .05));
  overflow: hidden;
}
.gr-fortschritt-fuell {
  height: 100%; border-radius: var(--nv-r-kapsel);
  background: var(--f);   /* Vollton — Begruendung bei .gr-rang-fuell */
  transition: width .4s cubic-bezier(.22, 1, .36, 1);
}

/* ── Kein Datum ────────────────────────────────────────────────────────── */
/* Ein ruhiger Platzhalter statt einer Linie auf null. Eine Null-Linie sieht
   aus wie ein Messwert — einer der wenigen Wege, mit einem Diagramm zu
   luegen, ohne eine falsche Zahl zu schreiben. */
.gr-leer {
  display: grid;
  place-items: center;
  border-radius: var(--nv-r-s, 12px);
  background: var(--k-bg3, rgba(0, 0, 0, .03));
  color: var(--k-text3);
  font-size: var(--k-fs-caption);
}

/* ══ EINWACHSEN (Stefan 2026-08-02: „soll sehr visuell sein, animationen
   aufweisen beim laden, smooth sein") ═══════════════════════════════════

   Die Bilder erschienen fertig, sobald die Daten da waren — ein Sprung.
   Jetzt wachsen sie in ihre Groesse hinein.

   ══ WARUM NUR EINMAL UND NUR KURZ ══════════════════════════════════════
   Die Bewegung hat eine Aufgabe: sie zeigt, dass die Zahl gerade
   eingetroffen ist, und sie fuehrt das Auge von null zum Wert. Danach ist
   sie fertig. Eine Grafik, die dauernd wackelt, macht die Zahl schwerer
   lesbar und ist nach dem dritten Mal nur noch laestig.

   350–450 ms mit einer Kurve, die spaet abbremst (`cubic-bezier(.22,1,.36,1)`)
   — dasselbe Zeitgefuehl wie die Blaetter und die Pille, damit sich die App
   nach EINER Sache anfuehlt.

   ══ WARUM `transform` UND NICHT `height`/`width` ═══════════════════════
   `transform` und `opacity` laufen auf der Grafikkarte; `height` zwingt den
   Browser, bei jedem Bild neu zu rechnen, wo alles liegt. Bei einer Liste
   mit zwanzig Balken ist das der Unterschied zwischen fluessig und ruckelig.
   Die Balken skalieren deshalb aus ihrer Grundlinie heraus.
*/
@keyframes gr-wachsen-hoch { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes gr-wachsen-breit { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes gr-auftauchen { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.gr-balken-fuellung {
  transform-origin: bottom;
  animation: gr-wachsen-hoch .42s cubic-bezier(.22, 1, .36, 1) both;
}
.gr-rang-fuell, .gr-vergleich-fuell, .gr-fortschritt-fuell, .gr-anteil {
  transform-origin: left;
  animation: gr-wachsen-breit .45s cubic-bezier(.22, 1, .36, 1) both;
}

/* Die Linie zeichnet sich. `pathLength="1"` waere sauberer, wird aber nicht
   ueberall unterstuetzt — eine grosszuegige Strichlaenge tut es auch: sie
   ist laenger als jeder Pfad hier und laeuft damit sicher durch. */
@keyframes gr-zeichnen { from { stroke-dashoffset: 2000; } to { stroke-dashoffset: 0; } }
.gr-linie {
  stroke-dasharray: 2000;
  animation: gr-zeichnen .9s cubic-bezier(.22, 1, .36, 1) both;
}
/* Der leuchtende Punkt kommt ZULETZT — er ist das Ziel der Linie, nicht ihr
   Begleiter. Er erscheint, wenn sie angekommen ist. */
.gr-punkt { animation: gr-auftauchen .3s ease-out .55s both; }

/* Der Ring bekommt hier BEWUSST nichts.
   Sein Wert steht als `stroke-dasharray`-ATTRIBUT am Element (js/grafik.js).
   Eine CSS-Regel auf dieselbe Eigenschaft schlaegt jedes
   Praesentations-Attribut — ein `stroke-dasharray: 0 999` haette also jeden
   Ring auf null gesetzt, egal welchen Wert er zeigen soll. (Genau das war der
   erste Wurf dieser Datei; aufgefallen beim Nachmessen.)
   Seine Bewegung macht der `transition` weiter oben. */

/* Zahlen und Legenden folgen der Grafik mit leichtem Versatz — erst das
   Bild, dann die Beschriftung. Andersherum liest man Zahlen, die sich noch
   bewegen. */
.gr-legende-punkt { animation: gr-auftauchen .3s ease-out both; }
.gr-legende-punkt:nth-child(1) { animation-delay: .10s; }
.gr-legende-punkt:nth-child(2) { animation-delay: .16s; }
.gr-legende-punkt:nth-child(3) { animation-delay: .22s; }
.gr-legende-punkt:nth-child(4) { animation-delay: .28s; }
.gr-legende-punkt:nth-child(n+5) { animation-delay: .34s; }

.gr-rang { animation: gr-auftauchen .34s ease-out both; }
.gr-rang:nth-child(1) { animation-delay: .04s; }
.gr-rang:nth-child(2) { animation-delay: .09s; }
.gr-rang:nth-child(3) { animation-delay: .14s; }
.gr-rang:nth-child(4) { animation-delay: .19s; }
.gr-rang:nth-child(n+5) { animation-delay: .24s; }

/* ══ WER BEWEGUNG NICHT MAG, BEKOMMT KEINE ═════════════════════════════
   Nicht Zierde, sondern Bedienbarkeit: fuer Menschen mit vestibulaeren
   Beschwerden ist Bewegung auf dem Bildschirm koerperlich unangenehm. iOS
   und Android haben dafuer einen Schalter; hier wird er beachtet.
   Wichtig: `animation: none` allein wuerde die Elemente auf ihrem
   Anfangswert stehen lassen (`both` haelt den from-Zustand). Deshalb wird
   auch die Ausgangslage zurueckgesetzt. */
@media (prefers-reduced-motion: reduce) {
  .gr-balken-fuellung, .gr-anteil, .gr-ring-fuell,
  .gr-rang-fuell, .gr-vergleich-fuell, .gr-fortschritt-fuell { transition: none; }
  .gr-balken-fuellung, .gr-rang-fuell, .gr-vergleich-fuell,
  .gr-fortschritt-fuell, .gr-anteil, .gr-punkt, .gr-legende-punkt, .gr-rang {
    animation: none;
    transform: none;
    opacity: 1;
  }
  .gr-linie { stroke-dasharray: none; animation: none; }
}
