/* ══════════════════════════════════════════════════
   v2 BASE — Typografie, Links, Sections, Utilities
   Destilliert aus Zeile 163-247 (Ueberschriften/Links) und 499-504 (Sections)
   des Prototyps.
   ══════════════════════════════════════════════════ */
h1, .h1 {
  font-size: var(--ms-text-h1);
  font-weight: var(--ms-weight-bold);
  /* 1.1 (Prototyp-Wert) schneidet Unterlaengen ab (z.B. kleines "g") —
     bewusste Abweichung, mit Nutzer abgestimmt. */
  line-height: 1.2;
  letter-spacing: -0.03em;
  color: var(--ms-text-primary);
  margin-bottom: var(--ms-space-5);
}
h2, .h2 {
  font-size: var(--ms-text-h2);
  font-weight: var(--ms-weight-bold);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ms-text-primary);
  margin-bottom: var(--ms-space-5);
}
h3, .h3 {
  font-size: var(--ms-text-h3);
  font-weight: var(--ms-weight-semibold);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ms-text-primary);
  margin-bottom: var(--ms-space-4);
}
h4, .h4 {
  font-size: var(--ms-text-h4);
  font-weight: var(--ms-weight-semibold);
  line-height: 1.25;
  letter-spacing: 0;
  color: var(--ms-text-primary);
  margin-bottom: var(--ms-space-5);
}
/* NUR auf Nicht-<h1>-Elemente anwenden (z.B. <div>). Im Prototyp selbst ist
   diese Klasse auf einem <h1> faktisch wirkungslos: die generische Regel
   `h1 { font-size/-weight/line-height/letter-spacing: ... !important }`
   (Zeile 168 im Prototyp) gewinnt gegen die dortige Inline-Angabe, egal ob
   Inline-Style oder Klasse — !important schlaegt beides. Dashboard-Beispiel
   im Prototyp: das Inline-`--mkpi-text-display` (72px bei breiten Viewports)
   wird nie sichtbar, gemessen wird tatsaechlich `--mkpi-text-h1` (60px) samt
   dessen Gewicht/Zeilenhoehe/Sperrung — per Browser nachgemessen. */
.hero-text-headline {
  font-size: var(--ms-text-display);
  font-weight: var(--ms-weight-extrabold);
  line-height: 1.05;
  letter-spacing: -0.04em;
}

p {
  font-size: var(--ms-text-body);
  font-weight: var(--ms-weight-regular);
  line-height: 1.6;
  color: var(--ms-text-primary);
  margin-bottom: var(--ms-space-4);
}
.subline, .lead {
  font-size: var(--ms-text-lead);
  font-weight: var(--ms-weight-regular);
  line-height: 1.5;
  color: var(--ms-text-secondary);
}
.text-secondary { color: var(--ms-text-secondary); }
.text-caption, small { font-size: var(--ms-text-small); color: var(--ms-text-secondary); line-height: 1.5; }
strong, b { font-weight: var(--ms-weight-semibold); }

/* DER VERLAUF GEHOERT DER ZEICHENKETTE UND NICHT DER ZEILE (Befund des
   Betreibers, 2026-09-16).

   `background-clip: text` schneidet den Verlauf auf die Glyphen zu — gemalt
   wird er aber ueber den HINTERGRUNDKASTEN des Elements, und der ist bei einem
   Block die volle Breite der Arbeitsflaeche. Gemessen auf der Kundenstartseite:
   Kasten 1092px, Name „Marina Groessl" 337px. Der Name bekam damit die ersten
   31% des Verlaufs ab und blieb durchgehend blau; das Tuerkis lag 750px weiter
   rechts auf leerer Flaeche. Und weil der Anteil von der LAENGE des Namens
   abhaengt, sah er bei jedem Kunden anders aus — ein kurzer Name ganz blau,
   ein sehr langer erst mit Farbwechsel.

   `width: fit-content` zieht den Kasten auf die Zeichenkette zusammen, und
   damit laeuft der Verlauf immer ueber den ganzen Namen, egal wie lang er ist.
   `fit-content` und nicht `inline-block`: das Element bleibt ein Block mit
   seinen Aussenabstaenden, und bei einem Namen, der laenger ist als die
   Flaeche, bricht die Zeile weiter um (`fit-content` deckelt bei der
   verfuegbaren Breite). */
.gradient-text {
  background: var(--ms-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  width: fit-content;
}
.section-label {
  font-size: var(--ms-text-caption);
  font-weight: var(--ms-weight-semibold);
  color: var(--ms-text-secondary);
  letter-spacing: 0.02em;
  margin-bottom: var(--ms-space-4);
}

/* --- Links ---
   Bewusste Abweichung vom Prototyp (mit Nutzer abgestimmt): der Prototyp
   setzt eine globale `a { color: ... !important }`, die in der letzten
   Umsetzung jede einzelne Link-Komponente (Nav, Dropdown-Item, Filter-Pill,
   Karten-Link) zu einer eigenen !important-Gegenregel gezwungen hat. Hier
   gilt die Link-Farbe nur fuer echten Fliesstext; jedes Bauteil mit <a>
   (navigation.css, data-display.css, pages.css) bekommt seine Farbe direkt
   vom eigenen Klassennamen, ohne globale Regel dagegen ankaempfen zu lassen. */
.prose a, .body-text a {
  color: var(--ms-link);
  text-decoration: underline;
  transition: color var(--ms-transition-fast);
}
.prose a:hover, .body-text a:hover { color: var(--ms-accent-hover); }

/* ── Textverweis ──────────────────────────────────────────────────────────
   DER EINE VERWEIS IM TEXT. Ein Wort oder eine kurze Wendung, die woanders
   hinfuehrt — „Zuruecksetzen", „Loeschen", der Name einer Firma neben einem
   Kontakt, der Rueckweg aus einer Maske.

   WARUM DAS BAUTEIL NOETIG WAR: es gab KEINE Regel fuer `a` ohne Klasse.
   Zwoelf Verweise standen damit im Browser-Standard — knallblau und
   unterstrichen, in einer Oberflaeche, deren Verweisfarbe --ms-link ist.
   Auffallen konnte das kaum, weil es nie zwei davon nebeneinander gab.

   ABGRENZUNG, damit nicht wieder drei Dinge dasselbe tun:
     .text-link   ein Verweis IM Text — dieses Bauteil.
     .prose a     Verweise INNERHALB eines Fliesstextblocks; die brauchen
                  keine Klasse, weil der Block sie traegt.
     .btn-text    eine Handlung, die wie ein Verweis aussieht, mit
                  nachlaufendem Pfeil („weiter zu …"). Ein Aufruf, kein Bezug.
     .cell-link   ein Verweis in einer Tabellenzelle; dort traegt die ZEILE
                  die Farbe und der Verweis bleibt ruhig, bis man ihn beruehrt.

   Bauform nach myOFFICE (`.mo-textlink`): funktioniert an `<a>` UND an
   `<button>`, weil ein „Loeschen", das nichts oeffnet, ein Knopf sein muss
   und trotzdem wie ein Verweis aussehen soll. Deshalb der Knopf-Ruecksetzer
   und `font: inherit` — sonst traegt ein <button> die Systemschrift.

   OHNE Unterstreichung im Ruhezustand: in Masken mit vielen kurzen Verweisen
   (Werkzeugleiste, Fusszeilen) wird daraus sonst ein Strichmuster. Beim
   Beruehren kommt sie dazu — das ist die Zusicherung fuer alle, die Farbe
   allein nicht unterscheiden koennen (WCAG 1.4.1: Farbe darf nicht das
   einzige Mittel sein; der Fokusring und die Unterstreichung liefern das
   zweite). */
.text-link {
  display: inline-flex; align-items: center; gap: var(--ms-space-1);
  background: none; border: none; padding: 0; margin: 0;
  font: inherit;
  font-weight: var(--ms-weight-medium);
  color: var(--ms-link);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--ms-transition-fast);
}
.text-link:hover { color: var(--ms-accent-hover); text-decoration: underline; }
.text-link:focus-visible {
  outline: 2px solid var(--ms-accent);
  outline-offset: 2px;
  border-radius: var(--ms-radius-sm);
}
/* Eine Stufe leiser, wo der Verweis eine Nebenangabe ist und nicht mit dem
   Hauptinhalt um Aufmerksamkeit ringen soll — dieselbe Rolle wie
   .cell-link--muted, nur ausserhalb der Tabelle. */
.text-link--muted { color: var(--ms-text-secondary); font-weight: var(--ms-weight-regular); }
.text-link--muted:hover { color: var(--ms-text-primary); }

/* ── Sections ── */
.section-white { background: var(--ms-bg-primary); padding: var(--ms-section-padding) 0; }
.section-gray { background: var(--ms-bg-secondary); padding: var(--ms-section-padding) 0; }
.container { max-width: var(--ms-content-width); margin: 0 auto; padding: 0 var(--ms-space-5); }
.container-narrow { max-width: var(--ms-content-medium); margin: 0 auto; padding: 0 var(--ms-space-5); }
/* Ohne Obergrenze — fuer Uebersichten, deren Tabelle die ganze Fensterbreite
   nutzen soll (Muster .mo-content aus myOFFICE). Der WAAGERECHTE Innenabstand
   bleibt derselbe wie bei .container: die Tabelle soll breiter werden, nicht
   an der Fensterkante kleben. Wer sie einsetzt, uebernimmt damit auch die
   Pflicht, lange Textzellen zu kuerzen (.cell-name in data.css) — sonst
   schiebt ein langer Name die Zahlenspalten aus dem Blick.

   Warum das nicht der Regelfall ist: eine Maske mit zwanzig Feldern wird auf
   einem 3440px-Schirm nicht besser, sondern unlesbar. Volle Breite ist die
   Antwort auf viele SPALTEN, nicht auf viel Platz. */
.container-full { max-width: none; margin: 0; padding: 0 var(--ms-space-5); }

/* ── Utilities ──
   Bewusst KEIN Utility-Framework: hier stehen genau die Klassen, die im
   Projekt gebraucht werden, und keine auf Vorrat. Sie sind aus den 70
   Inline-Styles entstanden, die zuvor in den Vorlagen standen — geerbt aus dem
   Prototyp, der als einzelne Attrappen-Datei alles inline gesetzt hat. Die
   Website macht es anders (0–10 Inline-Styles je Seite, sonst Klassen), und die
   Website ist die Vorgabe.

   Regel fuer Neues: wiederkehrende GESTALT gehoert als Bauteil-Klasse in
   pages.css/components, nicht als weitere Utility hierher. Utilities sind nur
   fuer wirklich generische Einzelwerte gedacht.

   Raster, Abstaende, Anzeige, Textausrichtung und Textfarben stehen NICHT
   hier, sondern in grid.css — sie bilden dort einen vollstaendigen Satz fuer
   die Verwaltungsmasken, und zwei Fassungen derselben Klasse waeren die
   schlimmste aller Loesungen. `.text-center`, `.text-end`, `.text-danger`,
   `.min-w-0`, `.m-0`, `.mt-*`, `.mb-*` und `.d-none` sind deshalb von hier
   dorthin gewandert. */
.text-small { font-size: var(--ms-text-small); }
/* Text auf eine feste Zeilenzahl kuerzen UND diese Zeilen reservieren.
   Zwei Aufgaben in einer Klasse, weil sie nur zusammen funktionieren: kappen
   allein macht Karten mit kurzem Text flacher, reservieren allein laesst
   langen Text ueberlaufen.

   Das Bauteil setzt --ms-clamp (Zeilenzahl) und --ms-clamp-lh (Zeilenhoehe);
   beide Werte gehen in dieselbe Rechnung, deshalb kommt auch die
   `line-height` von hier — sonst koennten reservierte und tatsaechliche
   Zeilenhoehe auseinanderlaufen und die Reservierung waere falsch.

   Wer gekuerzten Text vollstaendig lesbar machen will, haengt zusaetzlich
   data-controller="text-overflow" data-v2-toggle="tooltip" an das Element —
   derselbe Controller bedient das waagerechte .text-truncate (grid.css). */
.text-clamp {
  --ms-clamp: 3;
  --ms-clamp-lh: 1.5;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--ms-clamp);
  line-clamp: var(--ms-clamp);
  overflow: hidden;
  line-height: var(--ms-clamp-lh);
  min-height: calc(var(--ms-clamp) * var(--ms-clamp-lh) * 1em);
}
.flex-1 { flex: 1; }
/* Zeilenzahl fuer .text-clamp, wenn kein Bauteil sie vorgibt (Tabellenzellen
   mit Freitext). Die Zeilenhoehe bleibt der Vorgabewert des Bauteils. */
.clamp-1 { --ms-clamp: 1; }
.clamp-2 { --ms-clamp: 2; }
/* Reihe kleiner Knoepfe, die auf schmalen Schirmen umbricht. Zweimal gebraucht
   (Band in Schritt 1, Adress-Werkzeuge in Schritt 6) und generisch genug, um
   nicht je Seite eigene Klassen zu rechtfertigen. */
/* `align-items: center` fuer Zeilen, in denen ein Textknopf neben einem
   gefuellten steht: der Textknopf ist niedriger und saesse sonst auf der
   Grundlinie statt auf der Mittellinie. Bei gleich hohen Knoepfen ohne Wirkung. */
.button-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ms-space-2); }
/* Zeile mit Inhalt links und Handlungen rechts, die auf schmalen Schirmen
   umbricht. Der Maskenkopf der Verwaltung (.admin-header) baut darauf auf und
   ergaenzt nur seinen Abstand nach unten — vorher trugen drei Stellen im
   Backend den Kopf-Klassennamen fuer eine Zeile, die kein Kopf war
   (designsystem.md, Regel 9). */
.split-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--ms-space-4);
}
/* ── Fuellgrad ──
   EIN Satz Stufen fuer alles, was einen Anteil zeigt: Bestandsbalken der
   Produktkarte (Breite), Saeulen des Auswertungsdiagramms (Hoehe),
   Fortschrittsbalken einer Bestellung (Breite). Die Klasse setzt nur den Wert
   in --ms-fill; ob daraus Breite oder Hoehe wird, entscheidet das Bauteil.

   WARUM Klassen und kein `style="width:…"`: der Anteil ist der einzige Wert
   dieser Bauteile, der aus Daten kommt — im Prototyp steht er deshalb inline.
   Ein Inline-Style waere hier aber die Ausnahme, die die Regel aushoehlt
   (designsystem.md, Abschnitt 3).

   WARUM 5-Prozent-Schritte: bei 4 bis 6px Balkenhoehe und Saeulen von 240px
   ist der Unterschied zu exakten Werten nicht zu sehen. Abgerundet, damit ein
   fast voller Bestand nie als voll erscheint und ein fast fertiger Vorgang
   nicht als fertig.

   WARUM ein gemeinsamer Satz: vorher hatte allein der Bestandsbalken 21 eigene
   Klassen; Diagramm und Fortschritt haetten je 21 weitere gebraucht. Der
   gemeinsame Satz ist die Verallgemeinerung, die HeroUI als „Meter" fuehrt. */
.fill-0   { --ms-fill:   0%; }
.fill-5   { --ms-fill:   5%; }
.fill-10  { --ms-fill:  10%; }
.fill-15  { --ms-fill:  15%; }
.fill-20  { --ms-fill:  20%; }
.fill-25  { --ms-fill:  25%; }
.fill-30  { --ms-fill:  30%; }
.fill-35  { --ms-fill:  35%; }
.fill-40  { --ms-fill:  40%; }
.fill-45  { --ms-fill:  45%; }
.fill-50  { --ms-fill:  50%; }
.fill-55  { --ms-fill:  55%; }
.fill-60  { --ms-fill:  60%; }
.fill-65  { --ms-fill:  65%; }
.fill-70  { --ms-fill:  70%; }
.fill-75  { --ms-fill:  75%; }
.fill-80  { --ms-fill:  80%; }
.fill-85  { --ms-fill:  85%; }
.fill-90  { --ms-fill:  90%; }
.fill-95  { --ms-fill:  95%; }
.fill-100 { --ms-fill: 100%; }

.hidden { display: none !important; }
/* `show-ordered-products_controller.js` schaltet diese Klasse hart verdrahtet
   um (kein Bootstrap-Bezug mehr noetig, nur derselbe Klassenname). */
.d-none { display: none !important; }
/* Fuer Screenreader/Tastatur erreichbar, visuell aber weg — kein
   Bootstrap-Erbe, sondern ein etablierter, framework-unabhaengiger Name. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
