/* ══════════════════════════════════════════════════
   v2 DATA DISPLAY — Badge
   .badge/.badge-info/.badge-success 1:1 aus Zeile 655-661 des Prototyps.
   .badge-warning/.badge-danger sind eigene Ergaenzungen im selben Muster
   (rgba-Hintergrund + Volltonfarbe) — die App hat 5 Bestellstatus
   (App\Enum\OrderPhase + canceled), der Prototyp kennt nur zwei Badge-Farben.
   ══════════════════════════════════════════════════ */
/* EINE STUFE KLEINER ALS DER TEXT DANEBEN (2026-09-03, auf Wunsch des
   Betreibers): --ms-text-caption (12px) statt --ms-text-small (14px). Das ist
   der naechste und letzte Schritt der Skala nach unten; darunter gibt es
   keinen Token.

   Ein Abzeichen ist ein ETIKETT und kein Satz — es steht in derselben Stufe wie
   Tabellenkoepfe und Beizeilen (.cell-meta), und auf einem 14-Zoll-Schirm gab
   die alte Groesse einer Zeile mit zwei Abzeichen mehr Gewicht als ihrem
   Inhalt. Das waagerechte Polster geht mit: bei 12px wirkte --ms-space-3 wie
   eine Kapsel um zwei Woerter. */
.badge {
  display: inline-flex; padding: var(--ms-space-1) var(--ms-space-2);
  border-radius: var(--ms-radius-pill);
  font-size: var(--ms-text-caption); font-weight: var(--ms-weight-medium);
}
/* `hidden` muss auch hier verbergen. Das Attribut wirkt nur ueber die Regel des
   Browsers (`display: none`), und die verliert gegen jede Regel aus diesem
   System — die Zeile darueber eingeschlossen. Ein `<span class="badge" hidden>`
   stand deshalb sichtbar da; aufgefallen am Etikett „Inaktiv" neben der
   Ueberschrift der Kontaktmaske, das der Statusschalter ein- und ausblendet.
   Ueber die Spezifitaet geloest und nicht mit `!important`: eine Ausnahme von
   der Kaskade waere hier eine Ausnahme zu viel. */
.badge[hidden] { display: none; }
/* EIN ABZEICHEN, DAS EIN VERWEIS IST (seit 2026-09-07). Fuer `a` gibt es
   bewusst keine globale Regel, also braucht ein verweisendes Abzeichen seine
   eigene — sonst erbt es die Vorgabefarbe des Browsers. Es sieht aus wie ein
   Abzeichen und verhaelt sich wie ein Verweis: kein Unterstrich in Ruhe, aber
   ein sichtbarer Wechsel beim Ueberfahren.

   Gebraucht in der Trefferliste der Lagersuche: der Ortsschluessel ist die
   Antwort auf „wo", und ein Klick soll dorthin fuehren. */
.badge-link {
  align-items: center;
  gap: var(--ms-space-1);
  background: var(--ms-bg-secondary);
  color: var(--ms-link);
  text-decoration: none;
}
.badge-link:hover,
.badge-link:focus-visible {
  background: var(--ms-tint);
  color: var(--ms-accent-hover);
}
/* DIE SCHRIFTFARBE IST NICHT DIE SIGNALFARBE.
   Ein Abzeichen setzt die Signalfarbe abgeschwaecht als FLAECHE und braucht
   darauf eine Schrift, die man lesen kann. Die Volltonfarbe auf ihrer eigenen
   Tint-Flaeche ist genau das nicht — nachgerechnet:

       .badge-success  #198754 auf #D1E7DD  3,49:1
       .badge-danger   #FF3B30 auf #FFE5E3  2,97:1
       .badge-warning  #FF9500 auf #FFF1DA  1,97:1   ← praktisch unlesbar
       .badge-info     #0072E3 auf 8% Akzent 4,16:1

   Alle vier unter den 4,5:1, die WCAG 1.4.7 fuer Text dieser Groesse verlangt
   (14px, --ms-text-small). Die -text-Abwandlungen sind genau dafuer da und
   erreichen 7,21 / 5,47 / 6,10; fuer den Hinweis-Ton ist es --ms-link mit
   4,65:1. Die FLAECHEN bleiben unveraendert — die Farbe traegt die Bedeutung
   weiter, nur der Text ist jetzt lesbar. Aufgefallen beim Umbau des
   Anmeldeprotokolls, wo Erfolg und Fehlschlag als Abzeichen nebeneinander
   stehen. */
.badge-info { background: rgba(var(--ms-accent-rgb), var(--ms-tint)); color: var(--ms-link); }
.badge-success { background: var(--ms-success-muted); color: var(--ms-success-text); }
.badge-warning { background: var(--ms-warning-muted); color: var(--ms-warning-text); }
.badge-danger { background: var(--ms-error-muted); color: var(--ms-error-text); }
.badge-neutral { background: var(--ms-bg-secondary); color: var(--ms-text-secondary); }
/* TUERKIS: DIE EINE FARBE, DIE KEINEN ZUSTAND MEINT (2026-09-22).
   Befund des Betreibers an der Artikelliste: „wir haben jetzt Bestand niedrig
   und Verbrauchsartikel beides als Warnbutton." Die Artikelart trug `warning`,
   und seit das Bestandsabzeichen am selben Tag ebenfalls gelb wurde, standen in
   EINER Zeile zwei orange Abzeichen, die Verschiedenes meinten.

   Vier der fuenf Abzeichenfarben sind vergeben: `info` sagt „Hinweis",
   `success` „in Ordnung", `warning` „Aufmerksamkeit", `danger` „hier stimmt
   etwas nicht". Fuer eine EINORDNUNG ist keine davon wahr. Tuerkis ist der
   Markenton und benennt seit dem 2026-09-16 ausdruecklich KEINEN Zustand mehr
   (siehe --ms-teal-text in tokens.css, der seither ohne Verwender dasteht) —
   damit ist es die einzige Farbe im System, die einordnen darf, ohne etwas zu
   behaupten.

   `--ms-teal-text` UND NICHT `--ms-teal`: der Vollton erreicht als Schrift auf
   Weiss nur 2,61:1. Die Paarung hier ist nachgerechnet — 4,61:1 im Hellen
   (Tint 8 %) und 6,00:1 im Dunkeln (Tint 20 %), also in beiden Fassungen ueber
   AA und im Dunkeln sogar besser als `.badge-info`. Gebaut wie jenes, damit es
   dieselbe Bauart hat und nicht eine zweite. */
.badge-teal { background: rgba(var(--ms-teal-rgb), var(--ms-tint)); color: var(--ms-teal-text); }

/* Der Hinweis "JavaScript ist deaktiviert" im Seitenkopf nutzt die Warnfarben
   des Abzeichens, ist aber ein durchgehendes Band ueber die ganze Breite —
   deshalb blockweise, mittig und ohne die Pillenrundung. Zuvor standen diese
   drei Werte inline in layout.html.twig. */
.badge-banner {
  display: block;
  text-align: center;
  border-radius: 0;
}

/* ── Ladeanzeige ──
   `.spinner` und nicht `.loader`: der Name im Markup der Bestelldetailseite
   war ins Leere gesetzt — `.loader` ist in KEINER Datei des Projekts
   definiert, auch nicht im Alt-Stylesheet. Der Ladebereich des Turbo-Frames
   war damit ein 150px hoher leerer Kasten, waehrend die Dateiliste nachlud. */
.spinner {
  width: 24px; height: 24px;
  border: 2px solid var(--ms-border-light);
  border-top-color: var(--ms-accent);
  border-radius: 50%;
  animation: ms-spin 0.8s linear infinite;
}
@keyframes ms-spin { to { transform: rotate(360deg); } }
/* Bei reduzierter Bewegung NICHT anhalten, nur verlangsamen: ein stehender
   Kreis sagt nichts mehr aus, und etwas muss ja anzeigen, dass geladen wird. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.4s; }
}

/* ── Saeulendiagramm ──────────────────────────────────────────────────────
   Ein schmuckloses Balkendiagramm aus Tokens, SERVERSEITIG gezeichnet: die
   Hoehe kommt als Klasse `.fill-<n>` (base.css) und nicht als Inline-Angabe
   im Attribut — die faellt in bin/design-check. Daher das Fuenferraster:
   23 % gibt es nicht, 20 % schon.

   Es gibt bewusst keine Diagrammbibliothek. Die eine Darstellung, die diese
   Anwendung braucht (eine Groesse ueber der Zeit), sind vier Regeln; eine
   Bibliothek waere ein zweites Farbsystem im Haus, das nichts von den Tokens
   weiss und im Dunkelmodus danebenliegt.

   Stand hier bis zum 9. September 2026 als `.report-chart-*` im Seitenblock
   der Auswertung. Ein Diagramm ist kein Merkmal EINER Seite, deshalb hier.

   Aufbau:
     .chart-bars > .chart-col > (.chart-value, .chart-track > .chart-bar,
                                 .chart-label)
   Kopfzeile und Reiter kommen aus dem System (`.card-title`, `.nav-tabs`). */
.chart-bars {
  display: flex; align-items: flex-end; gap: var(--ms-space-1);
  /* Feste Hoehe: die Saeulen sind Prozente davon. Ohne sie haette der
     hoechste Balken die Hoehe seines Inhalts und das Diagramm keine
     gemeinsame Skala. */
  height: 240px;
  padding-top: var(--ms-space-5);
}
.chart-col {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: var(--ms-space-1);
  height: 100%;
  justify-content: flex-end;
}
/* Eigene Bahn fuer den Balken, und zwar zwingend.
   Die Balkenhoehe ist ein Prozentwert — er braucht einen Bezug, der NUR fuer
   den Balken da ist. Ohne diese Bahn galten die Prozente fuer die ganze
   Spalte, in der aber auch Wert und Monatsbeschriftung sitzen: gemessen
   ergaben fill-95 und fill-100 dieselben 170px, weil beide am Platz
   anstiessen, der nach den Beschriftungen uebrig war. Damit war der obere
   Teil der Skala nicht mehr unterscheidbar — und der hoechste Monat ist
   immer fill-100, also war IMMER der wichtigste Balken betroffen.
   `flex: 1` gibt der Bahn genau den Rest der Spalte, damit 0 bis 100 Prozent
   linear bleiben. */
.chart-track {
  flex: 1;
  width: 100%; max-width: 48px;
  display: flex; align-items: flex-end;
  justify-content: center;
}
.chart-bar {
  width: 100%;
  /* Hoehe aus demselben Fuellgrad-Satz wie Bestands- und Fortschrittsbalken:
     `.fill-<n>` setzt NUR die Variable --ms-fill, verbraucht wird sie hier.
     Wer die Zeile weglaesst, bekommt zwoelf 2px-Striche und keinen Fehler —
     genau das ist beim Verschieben dieses Blocks am 9. September 2026
     passiert. */
  height: var(--ms-fill, 0%);
  min-height: 2px;
  border-radius: var(--ms-radius-sm) var(--ms-radius-sm) 0 0;
  background: var(--ms-accent);
  transition: height var(--ms-transition-slow), background var(--ms-transition-fast);
}
.chart-col:hover .chart-bar { background: var(--ms-accent-hover); }
.chart-value {
  font-size: var(--ms-text-caption);
  font-weight: var(--ms-weight-semibold);
  color: var(--ms-text-secondary);
  font-variant-numeric: tabular-nums;
}
.chart-label {
  font-size: var(--ms-text-caption);
  color: var(--ms-text-secondary);
  font-weight: var(--ms-weight-medium);
  white-space: nowrap;
}
/* Leerer Zeitraum: eine Karte ohne Saeulen wirkt wie ein Ladefehler. */
.chart-empty {
  padding: var(--ms-space-8) 0;
  text-align: center;
  color: var(--ms-text-secondary);
  font-size: var(--ms-text-small);
}
@media (max-width: 900px) {
  /* Der Wert je Saeule faellt weg — bei zwoelf Monaten stehen die Zahlen
     sonst uebereinander. Der Balken bleibt lesbar, die genauen Werte stehen
     in der Tabelle darueber und in der aria-Beschriftung. */
  .chart-value { display: none; }
}
@media (max-width: 767px) {
  /* Zwoelf Monate auf einem Telefon: die Monatsbeschriftungen liefen
     ineinander und lasen sich als „1/262/263/26" (gemessen bei 390px). Die
     Saeulen bekommen deshalb eine Mindestbreite und rollen in IHRER eigenen
     Bahn — dieselbe Antwort, die das Haus einer zu breiten Tabelle gibt
     (`.table-responsive`), und nicht das Weglassen jeder zweiten
     Beschriftung: eine Zeitachse mit Luecken liest sich falsch. */
  .chart-bars { overflow-x: auto; }
  .chart-col { flex: 0 0 2.75rem; }
}
