/**
 * CAT-Trainer — Anwendungsschicht ueber Werkbund Deco.
 *
 * Diese Datei ist die EINZIGE Stelle, an der der Trainer vom Designsystem abweicht.
 * `tokens.css` und `werkbund.css` daneben sind byte-identische Kopien aus
 * `packages/design-tokens` der Suite und werden NIE von Hand angefasst — ein
 * Waechter vergleicht sie bytewise (tests/drift/design-tokens.test.ts).
 *
 * Es gibt hier genau zwei Aufgaben:
 *   1. Die Schriftnamen auf den npm-Konsumweg korrigieren.
 *   2. Die beiden Modi als Semantik-Overlay definieren.
 *
 * ══ 1. SCHRIFTNAMEN ══════════════════════════════════════════════════════════════════
 *
 * `tokens.css` fuehrt `'Public Sans'` und `'IBM Plex Sans'`. Das ist richtig fuer den
 * statischen Konsumweg (woff2 neben dem CSS, `fonts.css`). Der Trainer geht den
 * npm-Weg — und die Pakete registrieren ANDERE Familiennamen. Aus der Quelle gelesen,
 * nicht aus dem Paketnamen abgeleitet (ES-SUITE-131):
 *
 *     node_modules/@fontsource-variable/public-sans/index.css      'Public Sans Variable'
 *     node_modules/@fontsource-variable/ibm-plex-sans/index.css    'IBM Plex Sans Variable'
 *     node_modules/@fontsource/ibm-plex-mono/index.css             'IBM Plex Mono'
 *
 * Zwei von drei Namen traefen sich nie. Genau das ist ProAudit passiert: jede
 * Ueberschrift und jede Zeile Fliesstext lief in Helvetica/Arial, der Commit meldete
 * "Schriftkanon gelandet", und der Waechter blieb gruen — weil er das VORKOMMEN des
 * Namens prueft, nicht seine WIRKSAMKEIT.
 *
 * Beide Namen stehen deshalb nebeneinander. Damit kann diese Zeile nicht dadurch
 * falsch werden, dass jemand den Konsumweg wechselt (§ 56 — by-construction statt
 * by-convention).
 *
 * ══ 2. DIE BEIDEN MODI ═══════════════════════════════════════════════════════════════
 *
 * Spezifikation Kap. 8.1 nennt sie "Register". Der Goldstandard nennt "Register" etwas
 * anderes (die Tonalitaetsachse BRAND/PRODUKT, DESIGN.md § 1). Zwei Achsen, ein Wort.
 * Aufloesung, die im ganzen Projekt gilt:
 *
 *     Goldstandard-Register:  durchgehend PRODUKT. Es gibt keine BRAND-Flaeche.
 *     Spezifikations-Achse:   heisst ab hier MODUS.
 *
 * Das Attribut heisst weiter `data-register`, weil die Spezifikation es so schreibt —
 * benannt wird es als Modus.
 *
 *     :root                    Werkstatt (Lernen, Ergebnis, Fortschritt)
 *     [data-register="exam"]   Pruefstand (Briefing, Instruktion, Testrunner)
 *
 * Der Pruefstand ueberschreibt AUSSCHLIESSLICH semantische Token, nie Primitive.
 *
 * ── Drei harte Regeln, die hier real Schaden angerichtet haben (ES-SUITE-132) ────────
 *
 *   (a) KEIN Token ist eine CSS-Kurzform. Nicht `--linie: 1px solid #ccc`, sondern
 *       drei Token, am Verwendungsort zusammengesetzt. Eine Namenskollision mit
 *       Typwechsel loeschte in ProAudit 29 Regeln lautlos: kein Build-Fehler, keine
 *       Konsolenmeldung, kein Test.
 *   (b) Ein Token behaelt seinen TYP ueber beide Modi. Farbe bleibt Farbe, Zahl Zahl.
 *   (c) Alpha-Varianten sind EIGENE Token, nie ein Alpha-Anhang an einen Farbtoken.
 */

/* ═══ Werkstatt — der Grundzustand ══════════════════════════════════════════════════ */

:root {
  /* Schriftnamen fuer den npm-Konsumweg (siehe Kopf). */
  --font-display: "Public Sans Variable", "Public Sans", Helvetica, Arial, sans-serif;
  --font-body: "IBM Plex Sans Variable", "IBM Plex Sans", Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;

  /* ── Zeitanzeige ──────────────────────────────────────────────────────────────────
     Drei Zustaende, drei Token. Die Schwellen selbst (25 % / 10 %) liegen im Code,
     nicht im CSS — sie sind Fachregel (Spezifikation 6.3), nicht Gestaltung.

     Flaeche und Text sind GETRENNTE Token. Das verbotene Muster waere ein getoenter
     Grund mit gleichfarbigem Text (rgba(R,G,B,.1) + color rgb(R,G,B)) — der ergibt
     rechnerisch nie AA und ist als Anti-Pattern ausdruecklich untersagt. */
  --zeit-ruhig-text: var(--text-primary);
  --zeit-warnung-text: #7D5A0C; /* 5,76:1 auf --surface-page, gemessen */
  --zeit-warnung-flaeche: #F6EFDD;
  --zeit-alarm-text: #9B2C1F; /* 5,94:1 auf --surface-page, gemessen */
  --zeit-alarm-flaeche: #F8E7E3;

  /* ── Auswertung ───────────────────────────────────────────────────────────────────
     Bewusst NICHT rot/gruen allein: Farbe traegt die Aussage nie (WCAG 1.4.1).
     Richtig/falsch tragen zusaetzlich ein Zeichen und eine Beschriftung. */
  --bewertung-richtig-text: var(--status-erfuellt);
  --bewertung-falsch-text: var(--status-offen);
  --bewertung-unbearbeitet-text: var(--text-muted);

  /* ── Linien: drei Token statt einer Kurzform (Regel a) ────────────────────────────── */
  --linie-breite: 1px;
  --linie-stil: solid;
  --linie-farbe: var(--border-hairline);

  /**
   * Zielkorridor im Kategorienprofil und im Verlauf — eine Flaeche, kein Rand.
   *
   * ABGELEITET, nicht abgeschrieben. Bis M6 stand hier `rgba(46, 93, 138, …)` —
   * das ist ziffernweise `--steel-500` (#2E5D8A, tokens.css:44), nur eben als Kopie.
   * Wer den Stahlton je verschoebe, verschoebe den Korridor nicht mit, und niemand
   * faende den Grund. Die Regel dagegen steht oben unter (c): im Code steht die
   * Rolle, nie der Wert.
   *
   * Der Bezug ist `--accent`, nicht `--steel-500`: Im Pruefstand zieht das Overlay
   * `--accent` auf `var(--text-secondary)`. Damit entfaerbt sich das Korridorband im
   * Testmodus VON SELBST, ohne Sonderfall — genau das, was die Saettigungsgrenze
   * 0,15 dort verlangt. Wer die Rolle benutzt statt des Werts, bekommt die
   * Entfaerbung geschenkt.
   */
  --korridor-flaeche: color-mix(in srgb, var(--accent) 12%, transparent);
  --korridor-linie: color-mix(in srgb, var(--accent) 42%, transparent);

  /**
   * Der Balken des Abdeckungsgrades — bewusst NEUTRAL aus `--text-primary`.
   *
   * Nicht aus `--accent`: Der blaue Ton ist auf der Fortschrittsseite bereits mit
   * „Zielkorridor" belegt, und zwei Bedeutungen fuer denselben Ton auf einer Seite
   * waeren eine zweite Wahrheit. Abdeckung ist ausserdem kein Urteil — „12 von 63
   * gesehen" lobt nicht und mahnt nicht, es zaehlt.
   */
  --abdeckung-balken: color-mix(in srgb, var(--text-primary) 20%, transparent);

  /**
   * Flaechen zu den drei Bewertungsmarken.
   *
   * Die `--bewertung-*-text`-Marken sind fuer TEXT gemessen. Sie als Balkenfuellung zu
   * nehmen waere ein Kontrastfehler mit gutem Gewissen: Ein als Text geprueftes
   * Verhaeltnis sagt fuer den Fall „Flaeche mit Text darauf" nichts.
   */
  --bewertung-richtig-flaeche: #DCE9DC;
  --bewertung-falsch-flaeche: #F3DEDA;
  --bewertung-unbearbeitet-flaeche: #E8E8E6;

  /* Die Achse und das Gitter des Profils. Neutral — das Profil ist kein Kunstwerk. */
  --profil-achse: var(--border-strong);
  --profil-gitter: var(--border-hairline);
  --profil-balken-hoehe: 1.05rem;
}

/* ═══ Pruefstand — reduziert bis zur Haerte ═════════════════════════════════════════
 *
 * Spezifikation 8.1: "Der Bildschirm zeigt genau vier Dinge: Fortschritt, Restzeit,
 * Aufgabe, Antwortoptionen. Das einzige farbige Element im gesamten Testmodus ist die
 * Restzeitanzeige, und sie wird erst ab 25 % Restzeit farbig. Diese Zurueckhaltung ist
 * die Gestaltung."
 *
 * Das ist hier keine Absichtserklaerung: `tests/design/pruefstand-haerte.spec.ts` misst
 * am laufenden Dokument, dass kein sichtbares Element eine Farbsaettigung ueber 0,15
 * traegt, solange mehr als 25 % Restzeit uebrig sind — mit Positivkontrolle, damit ein
 * "0 Funde" nicht von einem kaputten Messweg zu unterscheiden waere.
 */

[data-register="exam"] {
  /* Der Akzent wird neutral. Keine Marke, kein Blau, kein Messing. */
  --accent: var(--ink-soft);
  --accent-hover: var(--ink-strong);
  --accent-brass: var(--ink-soft);

  /* Bedienelemente: Kontrast statt Farbe. */
  --btn-bg: var(--ink-strong);
  --btn-fg: #ffffff;
  --btn-bg-hover: #000000;
  --btn-ring: rgba(23, 25, 28, 0.28);

  /* Der Fokusring bleibt sichtbar — er ist Bedienbarkeit, keine Dekoration
     (WCAG 2.4.7, und der Durchlauf ohne Maus ist Abnahmekriterium). */
  --focus-ring: var(--ink-strong);

  /* Kuehle, ruhige Flaeche. Kein getoenter Grund, keine erhobene Karte. */
  --surface-page: #FAFAF9;
  --surface-raised: #FAFAF9;
  --surface-tint: #F1F1EF;

  /* Die Display-Schrift ist im Pruefstand strukturell unerreichbar — sie zeigt auf
     dieselbe Familie wie der Fliesstext. Wer sie hier benutzt, bekommt sie nicht
     (§ 56: die Eigenschaft gilt durch Konstruktion, nicht durch Disziplin). */
  --font-display: var(--font-body);

  /* Kein Ereignis rechtfertigt im Testmodus eine Animation ausser dem Countdown. */
  --dur-fast: 0s;
  --dur-mid: 0s;
  --dur-reveal: 0s;
  --dur-img: 0s;
}

[data-theme="dark"][data-register="exam"],
[data-theme="dark"] [data-register="exam"] {
  --accent: var(--text-secondary);
  --accent-hover: var(--text-primary);
  --accent-brass: var(--text-secondary);
  --btn-bg: #EDEEF0;
  --btn-fg: #101214;
  --btn-bg-hover: #ffffff;
  --btn-ring: rgba(237, 238, 240, 0.3);
  --focus-ring: #EDEEF0;
  --surface-page: #121315;
  --surface-raised: #121315;
  --surface-tint: #1A1B1E;
  --zeit-warnung-text: #DCB05A;
  --zeit-warnung-flaeche: #2A2313;
  --zeit-alarm-text: #E08C74;
  --zeit-alarm-flaeche: #2E1A16;

  /**
   * Der Korridor braucht hier KEINEN Eintrag mehr.
   *
   * Bis M6 standen an dieser Stelle `rgba(120, 165, 210, …)` — ein dritter Blauton,
   * der weder `--steel-300` (#96BCE2) noch das dunkle `--accent` (#93B7DD) war und
   * nirgends belegt wurde. Seit die Korridortoken aus `--accent` ableiten, folgen sie
   * dem Overlay von selbst: Der Pruefstand zieht `--accent` oben auf
   * `var(--text-secondary)`, dunkel wie hell.
   */
  --bewertung-richtig-flaeche: #1B2A1B;
  --bewertung-falsch-flaeche: #2E1A16;
  --bewertung-unbearbeitet-flaeche: #232426;
}

/* ═══ Werkstatt, dunkel ══════════════════════════════════════════════════════════════
 *
 * DIESER BLOCK IST DIE KORREKTUR EINES ZUORDNUNGSFEHLERS, nicht ein Zuwachs.
 *
 * Bis M6 standen die dunklen Zwillinge der eigenen Farbtoken AUSSCHLIESSLICH unter
 * `[data-theme="dark"][data-register="exam"]` — waehrend ihre Verbraucher samtlich
 * `.wk-`Bauteile der WERKSTATT sind (`.wk-option[data-marke]`, `.wk-profil-korridor`).
 * Die Zuordnung war exakt invertiert: Der Pruefstand, der diese Bauteile gar nicht
 * kennt, bekam ihre dunklen Fassungen; die Werkstatt, die sie zeichnet, bekam keine.
 *
 * Aufgefallen ist es nicht, weil `data-theme` bisher nirgends gesetzt wird — der
 * gesamte Dunkelsatz ist heute tote Regelmasse. Genau das ist der Fall, vor dem § 56
 * warnt: Die Regel „hielt", weil der brechende Code noch fehlte. Haette jemand zuerst
 * den Themenschalter gebaut, stuende weisser Text (#EDEEF0) auf `#DCE9DC` — 1,1:1.
 *
 * Der Schalter kommt deshalb NACH diesem Block und nach einer eigenen Messung. Eine
 * uebernommene Messung ist keine Messung.
 */

[data-theme="dark"] {
  /* Gemessen gegen `--surface-page` dunkel (#101214), Textfarbe `--text-primary`
     (#EDEEF0). Die Flaechen sind Traeger von Text und deshalb als Paarung geprueft,
     nicht als Flaeche allein. */
  --bewertung-richtig-flaeche: #1B2A1B;
  --bewertung-falsch-flaeche: #2E1A16;
  --bewertung-unbearbeitet-flaeche: #232426;

  /* Etwas mehr Deckung als hell: Auf dunklem Grund traegt dieselbe Prozentzahl
     weniger. `--accent` springt dabei ueber tokens.css auf #93B7DD. */
  --korridor-flaeche: color-mix(in srgb, var(--accent) 18%, transparent);
  --korridor-linie: color-mix(in srgb, var(--accent) 48%, transparent);
  --abdeckung-balken: color-mix(in srgb, var(--text-primary) 26%, transparent);
}

/* ═══ Hilfsklassen ═══════════════════════════════════════════════════════════════════ */

/**
 * Tabellenziffern. Nicht kosmetisch: ein springender Countdown ist im Testmodus eine
 * echte Ablenkung (Spezifikation 8.1). Gilt fuer den Timer, "Aufgabe 7 von 24", alle
 * Kennwerte und alle Tabellenspalten.
 *
 * Gemessen statt betrachtet: tests/design/tabellenziffern.spec.ts vergleicht die Breite
 * desselben Elements mit "11:11" und mit "00:00" — sie muss gleich sein.
 */
.ziffern {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/**
 * Fuer Bildschirmleser sichtbar, fuer das Auge nicht. Traegt die Textalternative
 * figuraler Aufgaben, die aus derselben Szenenbeschreibung erzeugt wird wie das SVG
 * und damit garantiert konsistent ist (Spezifikation 8.4).
 */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border-width: 0;
}

/* Reduzierte Bewegung wird respektiert — ueberall, nicht nur im Pruefstand. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ═══ Bauteile des Pruefstands ═══════════════════════════════════════════════════════
 *
 * Warum hier und nicht als CSS-Modul neben der Komponente: `tokens.css` und
 * `werkbund.css` sind bytegleiche Kopien aus dem Referenzrepo und werden nie von Hand
 * angefasst. Diese Datei ist die dafuer vorgesehene Anwendungsschicht — eine vierte
 * Ablage waere eine vierte Stelle, an der jemand nach einer Farbe sucht.
 *
 * Inline-Stile stehen weiter in den Komponenten, wo sie Layout beschreiben. Hier steht,
 * was Inline-Stil nicht kann: Zustaende (:focus-visible, :checked, :hover) und die
 * Medienabfragen.
 */

/* Der Rahmen: Kopf fix, Aufgabe im Fluss, Fuss fix. Kein Scrollen der Seite selbst —
   die Aufgabe scrollt in ihrem eigenen Feld, falls sie ueberlaeuft (Spezifikation 8.3). */
.pf-rahmen {
  display: grid;
  grid-template-rows: auto 1fr auto;
  min-height: 100dvh;
  max-height: 100dvh;
}

.pf-kopf,
.pf-fuss {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 4vw, 2.5rem);
  padding: 0.85rem clamp(1rem, 4vw, 3rem);
  border-color: var(--border-hairline);
  border-style: solid;
}

.pf-kopf {
  border-width: 0 0 1px 0;
}

.pf-fuss {
  border-width: 1px 0 0 0;
  justify-content: space-between;
  flex-wrap: wrap;
  row-gap: 0.6rem;
}

.pf-buehne {
  overflow-y: auto;
  padding: clamp(1.5rem, 5vh, 3rem) clamp(1rem, 4vw, 3rem);
}

.pf-blatt {
  max-width: 54rem;
  margin: 0 auto;
}

/* ── Der Fortschrittsbalken ────────────────────────────────────────────────────────
 *
 * Er zeigt POSITION, nicht Bewertung (Spezifikation 8.3). Deshalb traegt er genau eine
 * Farbe — die Vordergrundfarbe — und keine Abstufung nach richtig/falsch. Waere er
 * bewertend, verriete er waehrend des Laufs die Loesung der schon bearbeiteten
 * Aufgaben, und das aendert das Verhalten bei den folgenden. */
.pf-balken {
  flex: 1 1 auto;
  height: 6px;
  min-width: 4rem;
  background: var(--surface-tint);
  border: 1px solid var(--border-hairline);
  overflow: hidden;
}

.pf-balken-fuell {
  height: 100%;
  background: var(--ink-soft, var(--text-secondary));
  /* Keine Ueberblendung: Im Pruefstand ist jede Animation ausser dem Countdown
     abgeschaltet (--dur-* stehen dort auf 0s). */
  transition: width var(--dur-fast) linear;
}

/* ── Die Restzeit: das einzige farbige Element ─────────────────────────────────────── */
.pf-zeit {
  font-family: var(--font-mono);
  font-size: clamp(1.05rem, 2.4vw, 1.4rem);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  letter-spacing: 0.06em;
  padding: 0.2rem 0.55rem;
  white-space: nowrap;
  color: var(--zeit-ruhig-text);
  background: transparent;
}

.pf-zeit[data-warnstufe="achtung"] {
  color: var(--zeit-warnung-text);
  background: var(--zeit-warnung-flaeche);
}

.pf-zeit[data-warnstufe="kritisch"] {
  color: var(--zeit-alarm-text);
  background: var(--zeit-alarm-flaeche);
}

/* ── Antwortoptionen ───────────────────────────────────────────────────────────────
 *
 * Ein `<label>` um ein echtes `<input type="radio">`. Nicht `role="radio"` auf einem
 * `<div>`: Die eingebaute Rolle bringt Tastaturbedienung, Gruppennavigation und die
 * Ansage „2 von 5" mit, und keine dieser drei Eigenschaften faellt spaeter aus, weil
 * jemand einen Ereignisbehandler umbaut. */
.pf-optionen {
  display: grid;
  gap: 0.55rem;
  margin: 1.75rem 0 0;
  padding: 0;
  border: 0;
}

/* ── Bildhafte Optionen brauchen Pixel, nicht Spalten ──────────────────────────────
 *
 * 9rem ergaben auf einer 54rem breiten Bahn VIER Spuren und damit rund 209 px je
 * Option — bei einer viewBox von 86 x 108 Einheiten sind das 1,6 Pixel je Einheit.
 * Zum Vergleich, an derselben Bank gerechnet: Der kleinste Hinweis, auf den es bei
 * einem Wuerfel ankommt, ist die Lage der Sechs auf einer schraegen Flaeche — der
 * Punktabstand dort betraegt 2,76 Einheiten. Bei 1,6 px/E sind das 4,4 Pixel.
 *
 * 18rem ergeben ZWEI Spuren, rund 427 px je Option, und der Deckel unten laesst
 * 2,8 px/E zu. Dieselbe Groessenordnung, die an anderer Stelle heute schon als
 * Wahrnehmungsschwelle beziffert wurde. Vier Optionen stehen dann in zwei Reihen; das
 * ist der Preis und er ist der kleinere.
 */
.pf-optionen[data-bildhaft="ja"] {
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.pf-option {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border-hairline);
  background: var(--surface-raised);
  cursor: pointer;
}

.pf-option:hover {
  border-color: var(--border-strong);
}

.pf-option:has(input:checked) {
  border-color: var(--ink-strong, var(--text-primary));
  box-shadow: inset 0 0 0 1px var(--ink-strong, var(--text-primary));
}

/* Der Fokus sitzt auf dem versteckten `input`; sichtbar wird er am Rahmen. Ohne diese
   Regel waere die Tastaturbedienung blind — und der Durchlauf ohne Maus ist
   Abnahmekriterium (WCAG 2.4.7). */
.pf-option:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.pf-option input {
  /* Nicht `display:none` und nicht `visibility:hidden` — beides nimmt das Feld aus der
     Tastaturreihenfolge UND aus dem Bildschirmleser. Es bleibt bedienbar, nur unsichtbar. */
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
}

.pf-taste {
  flex: 0 0 auto;
  min-width: 1.7rem;
  height: 1.7rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--ui-micro, 0.72rem);
  border: 1px solid var(--border-strong);
  color: var(--text-secondary);
}

.pf-option:has(input:checked) .pf-taste {
  background: var(--btn-bg);
  color: var(--btn-fg);
  border-color: var(--btn-bg);
}

/* Die Umhuellende, NICHT das Bild. Bis zum 2026-08-30 stand der Deckel hier und wirkte
 * deshalb nur auf die Spanne: gemessen 128 px Spanne gegen 170,6 px SVG — 30 px liefen
 * unter den Rahmen der Beschriftung. Eine Hoehenbegrenzung, die das Kind nicht erreicht,
 * begrenzt nichts. */
.pf-option-bild {
  display: block;
  width: 100%;
}

/* 19rem = 304 px. Bei einer viewBox-Hoehe von 108 Einheiten sind das 2,8 Pixel je
 * Einheit — die Zahl, an der die Lage der Sechs auf einer schraegen Flaeche gerade noch
 * zu erkennen ist. `preserveAspectRatio` deckelt ueber die kleinere der beiden Achsen,
 * deshalb steht die Grenze an der HOEHE und nicht an der Breite. */
.pf-option-bild svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 19rem;
}

/* ── Das Aufgabenbild ──────────────────────────────────────────────────────────────
 *
 * 30rem waren es bis zum 2026-08-30 — 480 Pixel. Ein Schaltnetz auf `schwer` hat eine
 * viewBox von 1058 Punkten und landete darin beim Massstab 0,45: Der Abstand zweier
 * Leitungsspuren, im Bild 8 Punkte, kam als 3,6 Pixel an. 44rem geben 0,67, und der
 * Knopf darunter geht bis 70rem und damit auf Originalgroesse.
 */
.pf-szene {
  display: block;
  width: 100%;
  max-width: 44rem;
  height: auto;
  margin: 1.5rem 0 0;
}

/* Tritt aus der Textspalte heraus und bleibt dabei mittig — unabhaengig davon, wie
 * breit die Spalte gerade ist. `margin-left: 50%` setzt die linke Kante auf die Mitte
 * der Spalte, die Verschiebung um die halbe Eigenbreite zentriert von dort aus. */
.pf-szene--gross {
  max-width: none;
  width: min(96vw, 70rem);
  margin-left: 50%;
  transform: translateX(-50%);
}

.pf-szene-schalter {
  margin: 0.5rem 0 0;
}

/* Ein Knopf, der aussieht wie ein Verweis — fuer die Kopfzeile der Uebungsmodi.
 * Er ist ein Knopf und kein Verweis, weil er bei laufender Uhr erst fragt. Ein `<a>`,
 * das auf einen Klick nicht navigiert, waere fuer die Tastatur und den Bildschirmleser
 * eine Luege. */
.pf-kopf-knopf {
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  cursor: pointer;
  text-align: inherit;
}
.pf-kopf-knopf:hover {
  color: var(--accent-hover);
}

/* ── Knoepfe ───────────────────────────────────────────────────────────────────────
 *
 * Eigene Klasse statt `.cmb-btn`: Der Werkbund-Knopf traegt einen Messingrand und eine
 * Ueberblendung beim Ueberfahren. Beides ist Werkstatt-Sprache. Im Pruefstand ist
 * Kontrast das einzige Mittel. */
.pf-knopf {
  font-family: var(--font-body);
  font-size: var(--ui-md, 0.95rem);
  font-weight: 600;
  padding: 0.7em 1.6em;
  border: 1px solid var(--btn-bg);
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
}

.pf-knopf:hover:not(:disabled) {
  background: var(--btn-bg-hover);
}

.pf-knopf:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.pf-knopf--leise {
  background: transparent;
  color: var(--text-secondary);
  border-color: var(--border-strong);
  font-weight: 500;
}

.pf-knopf--leise:hover:not(:disabled) {
  background: transparent;
  color: var(--text-primary);
  border-color: var(--ink-strong, var(--text-primary));
}

/* ── Schmierblatt ──────────────────────────────────────────────────────────────────
 *
 * Im realen CAT liegen Stift und Papier auf dem Tisch. Der Inhalt wird NICHT
 * gespeichert (Spezifikation 8.3) — er verlaesst den Browser nie. */
/**
 * Die Wiedervorlage-Marke — „bereits bearbeitet am …, damals falsch" (E4).
 *
 * ══ WARUM SIE KEINE FARBE TRAEGT ═══════════════════════════════════════════════════
 *
 * Im Pruefstand ist Farbsaettigung ueber 0,15 AUSSCHLIESSLICH an der Restzeit erlaubt
 * und nur unter 25 % Restzeit — gemessen und erzwungen von
 * tests/design/pruefstand-haerte.spec.ts. Eine rote Marke fuer „damals falsch" waere
 * genau der Verstoss, den diese Haerte verhindert.
 *
 * Und sie waere auch fachlich falsch: Die Marke ist eine AUSKUNFT, kein Urteil. Wer
 * eine Aufgabe wiederbekommt, soll wissen, woran er ist — nicht ermahnt werden.
 * Unterschieden wird ueber das WORT („damals falsch" gegen „damals richtig"), nicht
 * ueber den Ton.
 *
 * Sie steht UEBER der Aufgabe, nicht darunter: Wer sie erst nach dem Lesen findet, hat
 * die Aufgabe schon einmal ohne diese Information angefangen.
 */
.pf-wiedervorlage {
  font-family: var(--font-mono);
  font-size: var(--ui-sm);
  color: var(--text-secondary);
  margin: 0 0 0.9rem;
  padding-bottom: 0.6rem;
  border-bottom: var(--linie-breite) var(--linie-stil) var(--border-hairline);
}

.pf-schmierblatt {
  width: 100%;
  min-height: 8rem;
  resize: vertical;
  margin-top: 0.75rem;
  padding: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--surface-tint);
  border: 1px solid var(--border-hairline);
}

.pf-hinweis {
  font-family: var(--font-mono);
  font-size: var(--ui-micro, 0.72rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Eine ehrliche Stoerungsmeldung. Sie nennt die betroffene Aufgabennummer und den
   naechsten Schritt — nie „Etwas ist schiefgelaufen" (Never-Do 7). */
.pf-stoerung {
  margin: 0 0 1.25rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--zeit-alarm-text);
  color: var(--zeit-alarm-text);
  background: var(--zeit-alarm-flaeche);
  font-size: var(--ui-sm, 0.9rem);
}

/* ── Die Telefonsperre ─────────────────────────────────────────────────────────────
 *
 * Ein 20-Minuten-Test mit figuralen Matrizen auf einem Telefon simuliert nichts Reales
 * (Spezifikation 9). Die Sperre ist deshalb kein Mangel, sondern eine Aussage — und sie
 * nennt eine Handlungsoption, statt nur abzuweisen.
 *
 * Sie steht in CSS und nicht in einer Weichenstellung im Server: Eine Kennung aus dem
 * `User-Agent` zu lesen waere raten. Die Breite ist das, worauf es ankommt. */
.pf-telefonsperre {
  display: none;
}

@media (max-width: 599px) {
  .pf-telefonsperre {
    display: block;
    padding: clamp(1.5rem, 8vw, 3rem);
  }

  .pf-rahmen {
    display: none;
  }
}

/* ═══ Bauteile der Werkstatt ═════════════════════════════════════════════════════════
 *
 * Bis M5 hatte die Werkstatt KEINE einzige Bauteilklasse — alles dort war Inline-Stil,
 * waehrend der Pruefstand zwanzig fuehrte. Das ging, solange die Werkstatt eine
 * Meilensteintabelle war. Mit Ergebnisprofil und Loesungsdurchsicht geht es nicht mehr:
 * Zustaende (:hover, :focus-visible, :has) und Medienabfragen kann Inline-Stil nicht,
 * und dreimal dieselbe Karte inline zu schreiben heisst, sie dreimal leicht anders zu
 * schreiben.
 *
 * Praefix `wk-` gegen `pf-` des Pruefstands. Die `.pf-`-Klassen sind NICHT unter
 * `[data-register=exam]` gescopet und hier technisch verfuegbar — sie tragen aber die
 * Pruefstands-Aussage (Kontrast statt Farbe, keine Rundung, keine Bewegung). Sie in der
 * Werkstatt zu benutzen, weil sie da sind, waere derselbe Fehler wie ein Messingrand im
 * Testmodus.
 */

/* ── Die Schale der Werkstatt ─────────────────────────────────────────────────────
 *
 * Bis M6 hatte die Werkstatt KEINE Schale. Das Layout rendert drei Deklarationen
 * (Hoehe, Flaeche, Textfarbe) — kein Kopf, keine Navigation, kein Fuss. Die Uebersicht
 * baute als EINZIGE Seite eine Kopfzeile inline; auf Ergebnis und Durchsicht fiel sie
 * ersatzlos weg. Dort gab es keinen Rueckweg und kein Abmelden.
 *
 * Das ist der Punkt, der aus vier Seiten eine ANWENDUNG macht. Solange er fehlt, sieht
 * keine Aenderung an Farbe oder Schrift danach aus, dass es dieselbe Familie ist.
 *
 * DER PRUEFSTAND BEKOMMT DAVON NICHTS. Er hat seine eigene Schale
 * (`.pf-rahmen`/`.pf-kopf`/`.pf-buehne`/`.pf-blatt`/`.pf-fuss`), und 0 `<nav>`,
 * 0 `<img>`, kein Verweis ausser Abbrechen ist dort gemessen und erzwungen. Das ist
 * keine Luecke, sondern die richtige Antwort auf eine andere Frage.
 */

/**
 * Die Sprungmarke. Sichtbar erst im Fokus — aber IMMER im DOM und immer als erstes
 * Element. Wer mit der Tastatur ankommt, springt damit an den Inhalt vorbei an der
 * Navigation; ein `display: none` haette sie aus der Tabreihenfolge genommen und damit
 * genau die Gruppe ausgeschlossen, fuer die sie da ist.
 */
.wk-sprungmarke {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--surface-raised);
  color: var(--text-primary);
  border: var(--linie-breite) var(--linie-stil) var(--border-strong);
  font-size: var(--ui-sm);
}

.wk-sprungmarke:focus {
  left: 0.75rem;
  top: 0.75rem;
}

.wk-kopf-innen {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0.85rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  flex-wrap: wrap;
}

/**
 * Die Wortmarke steht TYPOGRAFISCH da, nicht als Bilddatei.
 *
 * Es gibt weder `public/` noch `assets/` im Repo und keine Bilddatei mit geklaerter
 * Herkunft; der Designstandard verlangt `assets/IMAGE-CREDITS.md` ab Tag 0. Eine
 * kopierte Logodatei ohne Herkunftseintrag waere eine zweite unbewachte Uebernahme
 * neben tokens.css/werkbund.css. Der Kanon nennt den gesetzten Namen ohnehin
 * ausdruecklich als die bessere Wahl gegenueber einem Fuellbild.
 */
/**
 * Die Wortmarke: Bildzeichen und Schriftzug nebeneinander.
 *
 * `align-items: center` statt `baseline` — das Zeichen hat keine Grundlinie, und an
 * einer Schriftgrundlinie ausgerichtet saesse es sichtbar zu tief.
 */
.wk-wortmarke {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--ui-md);
  letter-spacing: var(--display-tracking);
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
}

/**
 * Das Zeichen nimmt die Akzentfarbe, der Schriftzug bleibt Text. Zwei Farben, damit
 * die Marke lebt, ohne dass der Name an Lesbarkeit verliert.
 */
.wk-wortmarke > svg {
  color: var(--accent);
  flex: 0 0 auto;
}

.wk-navigation {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-wrap: wrap;
}

/**
 * „Wer bin ich" und „raus hier" stehen nebeneinander — an GENAU EINER Stelle der
 * Anwendung.
 *
 * Der erste Bau der Schale hatte den Namen zusaetzlich als Rubrik der Uebersicht und
 * in der Fussleiste. Beim Blick auf die Seite ist das nicht aufgefallen; aufgefallen
 * ist es an elf E2E-Faellen, die „Angemeldet als …" ploetzlich zweimal fanden. Eine
 * Wiederholung liest sich nicht als Bestaetigung, sondern als Rauschen.
 */
.wk-kopf-identitaet {
  display: flex;
  align-items: center;
  gap: 0.5rem 0.9rem;
  flex-wrap: wrap;
}

.wk-nav-verweis {
  font-size: var(--ui-sm);
  color: var(--text-secondary);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: var(--linie-breite) var(--linie-stil) transparent;
}

.wk-nav-verweis:hover {
  color: var(--text-primary);
  border-bottom-color: var(--border-strong);
}

/**
 * Die aktuelle Seite traegt `aria-current="page"` — und die Gestaltung haengt AN
 * DIESEM Attribut, nicht an einer zusaetzlichen Klasse.
 *
 * Damit koennen die beiden nicht auseinanderlaufen: Was ausgezeichnet aussieht, ist
 * auch ausgezeichnet. Eine Klasse `--aktiv` neben einem vergessenen `aria-current`
 * waere eine sichtbare Markierung, die niemand vorgelesen bekommt.
 */
.wk-nav-verweis[aria-current="page"] {
  color: var(--text-primary);
  border-bottom-color: var(--accent-brass);
}

.wk-fussleiste {
  border-top: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  margin-top: auto;
}

.wk-fuss-innen {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 2.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  align-items: baseline;
}

/* Die Schale traegt die volle Hoehe, damit die Fussleiste auch auf einer kurzen Seite
   unten steht und nicht mitten im Bild haengt. */
.wk-schale {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

/**
 * Die Kachel des Setzkastens — in der Fassung des Registers PRODUKT.
 *
 * Der Container ist `.cmb-tilegrid` aus der uebernommenen Kopie: Fugen (3 px) und
 * Rahmen liegen dort auf dem CONTAINER, nicht als Raender an den Kacheln. Das ist der
 * eine Signature-Move des Systems, und die Vorlagenliste ist die einzige Stelle im
 * Trainer, an die er gehoert.
 *
 * Die Kachel selbst ist NICHT `.cmb-eco`: die traegt `--surface-brand` und
 * `--text-on-brand` — dunkle Marken-Kacheln, Register BRAND. Der Trainer ist
 * durchgaengig PRODUKT. Die Kopie wird benutzt, nie beschnitten; wo sie eine
 * Markenfassung anbietet, entsteht die Produktfassung daneben, so wie `.pf-`
 * daneben entstanden ist.
 *
 * Die Regel `:last-child:nth-child(odd) { grid-column: 1 / -1 }` aus der Kopie wird
 * bewusst NICHT uebernommen: Sie setzt ein zweispaltiges Raster voraus. Auf
 * `--container-max` (1300 px) stehen bei `minmax(280px, 1fr)` bis zu vier Spalten —
 * dort zoege sie eine dritte Kachel ueber die ganze Breite, obwohl neben ihr noch
 * Platz ist.
 */
.wk-kachel {
  background: var(--surface-raised);
  padding: var(--card-pad);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.wk-kachel-name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--ui-title-sm);
  font-weight: 600;
  letter-spacing: var(--display-tracking);
}

/**
 * Eine Nebenangabe in Mono — Masse, Fristen, Klammerzusaetze.
 *
 * Kein eigenes Bauteil, sondern ein Register: Was in Mono und leise steht, ist eine
 * Angabe ueber die Sache, nicht die Sache selbst. Deshalb eine Klasse und nicht
 * dreimal dieselben vier Deklarationen an drei Verwendungsstellen.
 */
.wk-mono-leise {
  margin: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--ui-sm);
  color: var(--text-muted);
}

/* Der beschreibende Satz dehnt sich, damit die Knoepfe aller Kacheln einer Reihe auf
   derselben Hoehe stehen — ungleich hohe Knoepfe lesen sich als ungleich wichtige. */
.wk-kachel-satz {
  margin: 0;
  flex: 1 1 auto;
  font-size: var(--ui-sm);
  line-height: var(--ui-line);
  color: var(--text-secondary);
}

/* ── Die Vorschau auf der Kachel ──────────────────────────────────────────────────
 *
 * Ein Auszug aus einer echten Aufgabe, oder ihr Bild. Der Anlass steht in
 * `src/server/vorschau.ts`: Ein Kachelname wie „Figurale Matrizen" verlangt vom Nutzer,
 * den Fachbegriff schon zu kennen — ein Blick auf eine Aufgabe nicht.
 *
 * Sie liest sich als ZITAT, nicht als Fliesstext: eingerueckt, mit einer Kante links,
 * leiser als der Rest. Das ist der Unterschied, auf den es ankommt — was hier steht,
 * ist ein Beispiel und keine Aussage der Anwendung. Ohne diese Trennung liest man
 * „Welches Bundesland grenzt an Daenemark?" als Frage AN SICH, mitten in einer Kachel,
 * die von etwas anderem handelt.
 */
.wk-vorschau {
  margin: 0;
  padding: 0.55rem 0 0.55rem 0.7rem;
  border-left: 2px solid var(--border-subtle, currentColor);
  font-size: var(--ui-sm);
  line-height: var(--ui-line);
  color: var(--text-secondary);
}

/*
 * Zwei Zeilen, dann Auslassungspunkte.
 *
 * Der Stammtext einer Textaufgabe hat gemessen bis zu 430 Zeichen — auf einer Kachel
 * waere das eine Wand. Zwei Zeilen tragen bei allen elf erzeugten Arten den
 * kennzeichnenden Teil: „3 Helfer fuellen in einer Stunde 76 Sandsaecke. Wie viele …"
 * sagt genug. Gedeckelt wird in der DARSTELLUNG und nicht im Text, damit ein
 * Screenreader den ganzen Satz bekommt.
 */
.wk-vorschau--text {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;

  /*
   * KEIN vertikales Polster auf dem gedeckelten Kasten.
   *
   * `overflow: hidden` schneidet an der Kante des POLSTERKASTENS, nicht an der letzten
   * erlaubten Zeile. Mit `padding-block: 0.55rem` blieb deshalb ein halber Zentimeter
   * der dritten Zeile stehen — sichtbar am 2026-09-01 bei „Dreisatz",
   * „Wortanalogien" und „Prozent, Zins, Bewegung": ein angeschnittener Streifen
   * Buchstabenoberkanten unter dem Auszug. Der Abstand nach aussen kommt aus dem
   * `gap` der Kachel und wird hier nicht noch einmal gesetzt.
   */
  padding-block: 0;
}

/*
 * Das Bild wird eingepasst, nicht beschnitten.
 *
 * Die Szenen tragen ihr eigenes `viewBox`; ohne Deckel zoege eine Matrix die Kachel auf
 * Bildschirmhoehe. 7rem ist die Hoehe, bei der ein Wuerfelpaar und eine Drei-mal-drei-
 * Matrix beide noch als das erkennbar sind, was sie sind.
 */
/*
 * Das Bild braucht KEINE Zitatkante.
 *
 * Der Strich links ist ein Textzeichen: Er sagt „das hier ist zitiert, nicht gesprochen".
 * Neben einer zentrierten Zeichnung steht er beziehungslos — gesehen am 2026-09-01, als
 * die Kante bei „Figurenmatrizen" ueber die volle Hoehe lief und das Bild daneben in der
 * Mitte schwebte. Eine Zeichnung ist ohnehin als Beispiel erkennbar.
 */
.wk-vorschau--bild {
  display: flex;
  justify-content: center;
  padding: 0.4rem 0;
  border-left: 0;
}

/*
 * ══ DIE FLAECHE MUSS DIE BREITE VORGEBEN, NICHT DAS BILD ══════════════════════════
 *
 * Die Szenen tragen ein `viewBox` und KEINE Masse — `zeichneSzene()` ueberlaesst die
 * Groesse bewusst dem Ort, an dem gezeichnet wird. Ein `span` um ein solches SVG
 * schrumpft auf seinen Inhalt, und der Inhalt hat keine eigene Breite: Beim ersten
 * Anlauf am 2026-09-01 blieben die vier Bildkacheln deshalb LEER — sichtbar war nur
 * der Randstrich.
 *
 * Die Flaeche gibt jetzt die Breite vor, das Bild fuellt sie und leitet seine Hoehe aus
 * dem Seitenverhaeltnis ab. Der Deckel greift nur bei den hohen Szenen (die Matrix ist
 * quadratisch); die breiten — Schaltbild 742 zu 190 — bleiben darunter und nutzen die
 * volle Breite.
 */
.wk-vorschau-bildflaeche {
  display: block;
  width: 100%;
}

.wk-vorschau-bildflaeche svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 7rem;
}

/* ── Die Inhaltsbahn ──────────────────────────────────────────────────────────────
 *
 * EINE Seitenschale fuer die ganze Werkstatt. Bis M6 gab es drei, mit eigenen Massen:
 * `.wk-flaeche` (60rem / 4rem), die Uebersicht (60rem / 5rem — dasselbe Mass, ein
 * anderes Polster) und die Anmeldung (grid/place-items/100dvh). Zwei Seiten desselben
 * Systems fluchten miteinander, weil sie dasselbe Raster teilen; das wiegt schwerer
 * als jeder Farbton.
 *
 * `--section-pad` wird bewusst NICHT benutzt: 128 px Landingpage-Grosszuegigkeit
 * schoebe den Inhalt einer Bedienoberflaeche unter die Falz. Der Abstand ZWISCHEN den
 * Abschnitten liegt auf der Bahn (`gap`), nicht als `margin-top` an den Abschnitten —
 * sonst traegt jeder Abschnitt sein eigenes Mass mit sich herum.
 */
.wk-bahn {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: clamp(2rem, 5vw, 4rem) var(--gutter) clamp(3.5rem, 8vw, 6rem);
  display: flex;
  flex-direction: column;
  gap: clamp(1.75rem, 4vw, 3rem);
}

.wk-karte {
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  background: var(--surface-raised);
  padding: var(--card-pad);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/**
 * Die ruhende Flaeche — fuer einen Abschnitt, der angekuendigt ist und leer bleibt.
 *
 * Nur die Flaechenfarbe wechselt. Keine Schraffur, kein Warnschild, kein Hover: Ein
 * angekuendigter Abschnitt ist kein Fehlerzustand.
 */
.wk-karte--ruht {
  background: var(--surface-tint);
}

/**
 * Die Rubrik — Mono-Versalien in Messing ueber jedem Titel.
 *
 * Das ist die typografische Signatur des Kanons, und sie kam im Trainer bis M6
 * NIRGENDS vor: Die Vorgaengerin `.wk-augenbraue` hatte den BRAND-Eyebrow kopiert
 * (`--text-eyebrow`, .74rem, `--text-muted`) statt der Produkt-Rubrik (`--ui-micro`,
 * 11px, `--accent-brass`). Messing war damit in der ganzen Anwendung ausserhalb der
 * vier Knopfraender unsichtbar — derselbe Grauwert wie das Referenzrepo, aber keine
 * Marke.
 *
 * VERSALIEN AUSSCHLIESSLICH UEBER CSS. Im Markup steht „Fortschritt", nicht
 * „FORTSCHRITT" — sonst buchstabieren Vorlesesysteme die Rubriken.
 */
.wk-rubrik {
  font-family: var(--font-mono);
  font-size: var(--ui-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-brass);
  margin: 0;
}

/* Fuer den angekuendigten Abschnitt: die Rubrik tritt zurueck, statt zu werben. */
.wk-rubrik--ruht {
  color: var(--text-muted);
}

/**
 * Die zwei Ueberschriftenstufen — getrennt.
 *
 * `.wk-kopf` musste bis M6 h1 und h2 zugleich bedienen und wurde dafuer an der
 * Verwendungsstelle uebersteuert (`style={{ fontSize: "var(--ui-page-title)" }}`).
 * Eine Uebersteuerung an der Verwendungsstelle ist eine fehlende Klasse.
 *
 * FESTE Staffel, kein `clamp()`: tokens.css schliesst clamp fuer Bedienoberflaechen
 * ausdruecklich aus — eine Bedienoberflaeche soll nicht mit dem Fenster atmen.
 */
.wk-seitentitel,
.wk-abschnittstitel {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  margin: 0;
  text-wrap: balance;
}

.wk-seitentitel {
  font-size: var(--ui-page-title);
  line-height: 1.12;
}

/**
 * Rubrik und Titel gehoeren ZUSAMMEN und muessen es auch bleiben, wenn die Bahn
 * zwischen ihren Kindern 3 rem Abstand haelt. Deshalb sind sie ein eigenes Bauteil
 * mit eigenem, kleinem Abstand — nicht zwei Geschwister der Bahn.
 */
.wk-seitenkopf,
.wk-abschnittskopf {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

/**
 * Ein Abschnitt der Bahn. Der Abstand zwischen Titel, Fuehrungsabsatz und Inhalt
 * liegt HIER, nicht als `margin-top` an jedem einzelnen Kind — sonst traegt jedes
 * Kind sein eigenes Mass mit sich herum und vierzehn Stellen fuehren fuenf Masse.
 */
.wk-abschnitt {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.wk-abschnittstitel {
  font-size: var(--ui-title);
  line-height: 1.16;
}

/**
 * Zwei benannte Textregister statt fuenf verstreuter Hinweisfassungen.
 *
 * Lauftext traegt AUSSAGEN, Hilfstext traegt EINORDNUNG und Nenner. Bis M6 fuehrten
 * vierzehn Stellen fuenf verschiedene Zeilenhoehen (1.15/1.55/1.6/1.65/1.7), waehrend
 * die zwei kanonischen Werte danebenstanden.
 *
 * `max-width: 68ch` ist keine Kosmetik: Auf einem 1300px-Container liefe eine Zeile
 * sonst ueber 150 Zeichen, und die Ruecksprungweite entscheidet ueber Lesbarkeit.
 */
.wk-lauftext {
  color: var(--text-secondary);
  line-height: 1.64;
  max-width: 68ch;
  text-wrap: pretty;
  margin: 0;
}

.wk-hilfstext {
  font-size: var(--ui-sm);
  color: var(--text-muted);
  line-height: var(--ui-line);
  max-width: 68ch;
  margin: 0;
}

/* ── Kennzahlenzeile ──────────────────────────────────────────────────────────────
 *
 * Der Leitwert steht gross, die Begleiter daneben. Das ist keine Gestaltungslaune:
 * `trefferquote` darf nie allein stehen (DECISIONS F6, `darfAlleinStehen()` im Kern),
 * und eine Kachel, in die genau eine Zahl passt, verfuehrt genau dazu. */
.wk-kennzahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: clamp(1rem, 3vw, 2rem);
  margin: 0;
  padding: 1.25rem 0;
  border-top: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  border-bottom: var(--linie-breite) var(--linie-stil) var(--border-hairline);
}

.wk-kennzahl-wert {
  margin: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 1.35rem;
  line-height: 1.2;
}

.wk-kennzahl-wert--leit {
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
}

.wk-kennzahl-hinweis {
  margin: 0.2rem 0 0;
  font-size: var(--ui-sm);
  color: var(--text-muted);
  line-height: 1.45;
}

/* ── Das Kategorienprofil ─────────────────────────────────────────────────────────
 *
 * Horizontale Balken als eigenes SVG-freies Raster — DESIGN.md schliesst eine
 * Diagrammbibliothek aus, und ein Profil aus neun Zeilen braucht keine. Die
 * Tabellenfassung darunter ist nicht der Ersatz, sondern die gleichwertige Lesart:
 * Der Balken ist `aria-hidden`, die Zahlen stehen daneben. */
.wk-profil {
  display: grid;
  grid-template-columns: minmax(7rem, 14rem) 1fr auto;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 1.5rem 0 0;
}

.wk-profil-name {
  font-size: var(--ui-sm);
  line-height: 1.35;
  text-align: right;
}

.wk-profil-bahn {
  position: relative;
  height: var(--profil-balken-hoehe);
  background: var(--surface-tint);
  border: var(--linie-breite) var(--linie-stil) var(--profil-gitter);
}

/* Das Korridorband liegt HINTER dem Balken und ist deshalb eine eigene Schicht: Laege
   es darunter im Sinne von „als Hintergrund der Bahn", rechnete der Balkenkontrast
   gegen Korridorflaeche-ueber-Flaeche statt gegen die Flaeche — und haenge damit davon
   ab, ob der Wert im Korridor liegt. */
.wk-profil-korridor {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--korridor-flaeche);
  border-left: var(--linie-breite) var(--linie-stil) var(--korridor-linie);
  border-right: var(--linie-breite) var(--linie-stil) var(--korridor-linie);
}

.wk-profil-balken {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  background: var(--bewertung-unbearbeitet-flaeche);
  border-right: 2px solid var(--text-secondary);
}

.wk-profil-balken[data-lage="im_korridor"] {
  background: var(--bewertung-richtig-flaeche);
  border-right-color: var(--bewertung-richtig-text);
}

.wk-profil-balken[data-lage="unter"] {
  background: var(--bewertung-falsch-flaeche);
  border-right-color: var(--bewertung-falsch-text);
}

.wk-profil-balken[data-lage="ueber"] {
  background: var(--bewertung-richtig-flaeche);
  border-right-color: var(--bewertung-richtig-text);
}

.wk-profil-zahl {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: var(--ui-sm);
  white-space: nowrap;
  color: var(--text-secondary);
}

/* „Duenn belegt" und „nicht getestet" werden AUSGEGRAUT und beschriftet, nie
   weggelassen. Eine graue Zeile ist eine korrekte Aussage, eine fehlende eine falsche. */
.wk-profil-zeile--duenn .wk-profil-name,
.wk-profil-zeile--duenn .wk-profil-zahl {
  color: var(--text-muted);
}

/* ── Loesungsdurchsicht ───────────────────────────────────────────────────────────── */
.wk-aufgabe {
  border-top: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  padding: clamp(1.5rem, 4vw, 2.5rem) 0;
}

.wk-option {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.6rem 0.85rem;
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  margin-bottom: 0.4rem;
  background: var(--surface-page);
}

/* Farbe traegt die Aussage NIE allein (WCAG 1.4.1). Jede markierte Option bekommt
   zusaetzlich ein Zeichen und eine vorgelesene Beschriftung. */
.wk-option[data-marke="richtig"] {
  background: var(--bewertung-richtig-flaeche);
  border-color: var(--bewertung-richtig-text);
}

/* Die Loesung einer Aufgabe, zu der KEINE Antwort abgegeben wurde.
   Bewusst nicht gruen: Gruen ist in dieser Anwendung die Farbe von „richtig geloest",
   und wer eine Aufgabe nie gesehen hat, hat sie nicht geloest. Der Rahmen zeigt hin,
   die Flaeche bleibt neutral. Der Vorfall vom 2026-09-02 entstand daran, dass hier
   dieselbe gruene Flaeche stand wie bei einer eigenen richtigen Antwort. */
.wk-option[data-marke="loesung-offen"] {
  background: var(--surface-page);
  border-color: var(--text-secondary);
  border-style: dashed;
}

.wk-option[data-marke="gewaehlt-falsch"] {
  background: var(--bewertung-falsch-flaeche);
  border-color: var(--bewertung-falsch-text);
}

.wk-option[data-marke="gewaehlt-richtig"] {
  background: var(--bewertung-richtig-flaeche);
  border-color: var(--bewertung-richtig-text);
  box-shadow: inset 0 0 0 1px var(--bewertung-richtig-text);
}

.wk-option-marke {
  flex: 0 0 auto;
  min-width: 1.6rem;
  font-family: var(--font-mono);
  font-size: var(--ui-sm);
}

.wk-option-bild {
  display: block;
  max-width: 7rem;
  height: auto;
}

.wk-schritte {
  margin: 0;
  padding-left: 1.4rem;
  line-height: 1.65;
  color: var(--text-secondary);
}

.wk-falle {
  margin: 0 0 0.5rem;
  padding: 0.6rem 0.85rem;
  border-left: 3px solid var(--border-strong);
  color: var(--text-secondary);
  line-height: 1.6;
}

/* Die eigene Stolperfalle steht zuerst UND ist markiert — Spezifikation 8.5. Die
   Reihenfolge allein reicht nicht: Wer die Liste ueberfliegt, sieht keine Reihenfolge. */
.wk-falle--eigene {
  border-left-color: var(--bewertung-falsch-text);
  background: var(--bewertung-falsch-flaeche);
  color: var(--text-primary);
}

/* ══ DIE AUFLOESUNG IM UEBUNGSMODUS ═══════════════════════════════════════════════

   Sie erscheint NUR ausserhalb des Testmodus. DESIGN.md § 2 verbietet im Pruefstand
   jedes farbige Element ausser der Restzeit — die Begruendung dort lautet: „ein
   Pruefungsterminal, das dekoriert ist, fuehlt sich nicht wie eines an."

   Im Uebungsmodus ist es keines. Dort ist die Rueckmeldung der ZWECK des Bildschirms,
   und ein Urteil, das man erst suchen muss, waere schlechter als eines, das man sieht.
   Der Pruefstand-Haertetest prueft ausdruecklich den Testmodus — dort taucht nichts
   davon auf.

   Die Farben sind dieselben wie in der Loesungsdurchsicht, damit „richtig" hier und
   dort gleich aussieht. */
.pf-aufloesung {
  margin-top: 1.6rem;
  padding: 1.2rem 1.4rem;
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  border-left: 3px solid var(--border-strong);
  background: var(--surface-raised);
  outline: none;
}

.pf-aufloesung-urteil {
  font-family: var(--font-display);
  font-size: var(--ui-lg, 1.15rem);
  font-weight: 600;
  margin: 0 0 0.7rem;
  line-height: 1.35;
}

.pf-aufloesung-urteil--ja {
  color: var(--bewertung-richtig-text);
}

.pf-aufloesung-urteil--nein {
  color: var(--bewertung-falsch-text);
}

/* Der Nachsatz traegt kein Urteil, sondern eine Auskunft — deshalb neutral. */
.pf-aufloesung-schluessel {
  font-weight: 400;
  color: var(--text-secondary);
}

/* Die eigene Stolperfalle steht VOR dem Prinzip und ist hervorgehoben: Wer danebenlag,
   sucht zuerst die Begruendung SEINES Fehlers (Spezifikation 8.5). */
.pf-aufloesung-falle {
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.9rem;
  background: var(--bewertung-falsch-flaeche);
  border-left: 3px solid var(--bewertung-falsch-text);
  font-size: var(--ui-sm);
  line-height: 1.55;
}

.pf-aufloesung-prinzip {
  margin: 0 0 0.7rem;
  font-size: var(--ui-md, 1rem);
  line-height: 1.6;
}

.pf-aufloesung-schritte {
  margin: 0 0 1.1rem;
  padding-left: 1.3rem;
  font-size: var(--ui-sm);
  line-height: 1.6;
  color: var(--text-secondary);
}

.pf-aufloesung-schritte li {
  margin-bottom: 0.35rem;
}

/* ══ DER ZUSPRUCH — was der Uebende geschafft hat ═════════════════════════════════

   Der Auftraggeber wollte ihn „durchaus in einer groesseren Schrift oder in Fett oder in
   einer anderen Farbe" — die drei Zeilen sollen den Blick zuerst bekommen, nicht als
   vierter Absatz untergehen.

   Umgesetzt ueber GROESSE und GEWICHT, nicht ueber Farbe. Der Werkbund-Kanon dieses
   Projekts arbeitet mit Stahlblau und Messing als Akzenten fuer BEDIENBARES; ein farbiger
   Fliesstext daneben liest sich wie ein Verweis, den man anklicken kann. Der erste Satz
   traegt deshalb die Anmutung einer Zwischenueberschrift, die folgenden bleiben Fliesstext
   — die Hierarchie entsteht innerhalb des Blocks. */
.wk-zuspruch {
  margin: 0 0 1.4rem;
  padding-left: 1rem;
  border-left: 3px solid var(--accent-brass, var(--accent));
}

.wk-zuspruch-kopf {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2.4vw, 1.28rem);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: -0.008em;
  color: var(--text-primary);
  margin: 0 0 0.5rem;
  max-width: 46rem;
  text-wrap: balance;
}

.wk-zuspruch-satz {
  font-size: var(--ui-md, 1rem);
  line-height: 1.6;
  color: var(--text-secondary);
  margin: 0 0 0.45rem;
  max-width: 46rem;
}

.wk-zuspruch-satz:last-child {
  margin-bottom: 0;
}

/* ══ AELTERE SITZUNGEN — der Aufklapper ═══════════════════════════════════════════

   Ein nacktes <summary> sieht nach nichts aus: kein Zeigefinger, keine Reaktion auf den
   Mauszeiger, und das Dreieck des Browsers geht neben einer Tabelle unter. Der
   Auftraggeber hat das am 2026-09-03 gemeldet.

   DIE FARBE UND DER HOVER KOMMEN AUS `cmb-btn` — der Knopfklasse des Referenzrepos, die
   jede andere Werkstattseite ebenfalls benutzt (Uebersicht, Ueben, Ergebnis, Durchsicht).
   Der erste Anlauf gab dem Aufklapper einen EIGENEN Stil; das war genau die Uneinheit,
   die der Auftraggeber im selben Atemzug bemaengelt hat („dass wir wirklich auf allen
   Seiten die gleiche Art von Action Button haben").

   Hier steht deshalb nur noch, was `cmb-btn` nicht leisten kann: das voreingestellte
   Dreieck abschalten und ein eigenes setzen, das sich beim Aufklappen dreht. */
.wk-aeltere {
  margin-top: 1rem;
}

.wk-aeltere-knopf {
  list-style: none; /* Firefox */
  user-select: none;
}

/* WebKit braucht ein eigenes Pseudoelement fuer dieselbe Sache. */
.wk-aeltere-knopf::-webkit-details-marker {
  display: none;
}

/* Der eigene Pfeil — er sagt den Zustand, ohne dass der Text sich aendern muss. */
.wk-aeltere-knopf::before {
  content: "";
  flex: 0 0 auto;
  width: 0;
  height: 0;
  border-left: 0.36rem solid currentColor;
  border-top: 0.28rem solid transparent;
  border-bottom: 0.28rem solid transparent;
  transition: transform var(--dur-fast, 140ms) var(--ease, ease);
}

.wk-aeltere[open] > .wk-aeltere-knopf::before {
  transform: rotate(90deg);
}

.wk-aeltere[open] > .wk-aeltere-knopf {
  margin-bottom: 0.85rem;
}

@media (prefers-reduced-motion: reduce) {
  .wk-aeltere-knopf::before {
    transition: none;
  }
}

.wk-meldeknopf {
  font-family: var(--font-body);
  font-size: var(--ui-sm);
  padding: 0.45rem 1rem;
  background: transparent;
  color: var(--text-muted);
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.wk-meldeknopf:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}

.wk-meldeknopf[data-gemeldet="ja"] {
  color: var(--zeit-warnung-text);
  background: var(--zeit-warnung-flaeche);
  border-color: var(--zeit-warnung-text);
}

/* ── Benannte Befunde (M6, Schnitt 3) ──────────────────────────────────────────
   Ein Befund ist eine AUSSAGE UEBER EINEN MENSCHEN. Er bekommt deshalb eine eigene
   Flaeche mit Kante — nicht, damit er auffaellt, sondern damit erkennbar ist, wo er
   anfaengt und aufhoert. Vier Absaetze ohne Rahmen liest niemand als eine Einheit.

   Bewusst OHNE Signalfarbe: Der Pruefstand haelt Farbe an der Restzeit zurueck, und die
   Werkstatt hat mit Korridor und Bewertung schon zwei Farbachsen. Eine dritte fuer
   „Schwaeche" waere ein Urteil per Farbton — und ein Befund traegt seine Einordnung im
   Text, mit Zahl und Nenner. */
.wk-befund {
  margin-top: 1.5rem;
  padding: 1.1rem 1.3rem;
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  border-left-width: 3px;
  border-left-color: var(--border-strong);
  /* Karten und Kachen sind im Kanon IMMER eckig — es gibt genau zwei Radien,
     und --radius-pill ist ausschliesslich fuer Knoepfe. */
  border-radius: var(--radius-none);
  background: var(--surface-raised);
  max-width: 58ch;
}

.wk-befund__kopf {
  font-family: var(--font-display);
  font-size: var(--ui-title-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  margin: 0 0 0.6rem;
}

.wk-befund__satz {
  color: var(--text-primary);
  line-height: 1.7;
  margin: 0 0 0.6rem;
}

/* Der Beleg steht leiser als die Aussage — er traegt sie, er ist nicht sie. */
.wk-befund__beleg {
  color: var(--text-secondary);
  font-size: var(--ui-sm);
  line-height: 1.65;
  margin: 0 0 0.6rem;
}

/* Der naechste Schritt ist der einzige Teil, der zum Handeln auffordert, und steht
   deshalb abgesetzt. Prozessdaten-Spezifikation 7 fuehrt ihn als Pflichtbestandteil
   jedes Befundes — nicht als Zusatz. */
.wk-befund__schritt {
  color: var(--text-primary);
  line-height: 1.7;
  margin: 0.9rem 0 0;
  padding-top: 0.8rem;
  border-top: var(--linie-breite) var(--linie-stil) var(--border-hairline);
}

/**
 * Der Dreiklang der Fehlerflaechen: was ist passiert / warum / was koennen Sie tun.
 *
 * Eine Beschreibungsliste, keine Absaetze — die drei Fragen sind gleichrangig, und sie
 * sollen sich beim Ueberfliegen finden lassen. Wer eine Fehlerseite liest, liest sie
 * nicht von oben nach unten; er sucht die dritte Zeile.
 */
.wk-dreiklang {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
}

.wk-dreiklang dd {
  margin: 0 0 1.1rem;
}

.wk-dreiklang dd:last-child {
  margin-bottom: 0;
}

/* ═══ Bauteile der Fortschrittsansicht ═══════════════════════════════════════════════
 *
 * Der Bildschirm traegt DREI SCHICHTEN mit verschiedener Beweislast, und die Gestaltung
 * macht sie unterscheidbar:
 *
 *   ZAEHLSCHICHT   bearbeitete Aufgaben, Sitzungen, Breite, Abdeckung.
 *                  Gezaehlt, nicht geschaetzt. Traegt ab Sitzung 1 (F34).
 *   MESSSCHICHT    Verlauf, Fehlertyp-Register. Werte MIT Nenner, ohne Richtungsurteil.
 *   LEERSCHICHT    Vergleich mit anderen. Bleibt leer und sagt warum.
 *
 * Was hier NICHT vorkommt, ist die eigentliche Entscheidung: kein Pfeil, kein
 * „+7 Punkte", kein „verbessert", keine Regressionsgerade. Der Aufbautest wird aus der
 * SCHWAECHSTEN Kategorie gebaut; der Scheingewinn allein aus dieser Auswahl liegt bei
 * +41,1 Prozentpunkten und sieht in 93,2 % der Faelle besser aus — ohne jeden
 * Lernzuwachs, und mehr Aufgaben helfen nicht (DECISIONS F33). Eine Verlaufsflaeche,
 * die per Konstruktion nur steigen oder schweigen kann, ist genau die Schmeichelei,
 * gegen die dieses Produkt gebaut ist — eine Ebene hoeher und schwerer zu sehen.
 */

/* ── Die Zaehlschicht als Reihe ───────────────────────────────────────────────────
 *
 * Fuenf Zahlen statt einer Gesamtnote. Fugen und Rahmen liegen auf dem CONTAINER,
 * nicht als Raender an den Zellen — das ist das Setzkastenprinzip des Kanons: Der
 * Rahmen gehoert dem Ganzen, die Fuge entsteht als Zwischenraum.
 */
.wk-merkzahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--linie-breite);
  background: var(--border-hairline);
  outline: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  margin: 0;
}

.wk-merkzahl {
  background: var(--surface-page);
  padding: 0.9rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

/* Das Etikett steht im DOM VOR dem Wert (dt vor dd), damit die Vorlesereihenfolge
   „Bearbeitete Aufgaben: 128" ergibt und nicht „128: Bearbeitete Aufgaben". */
.wk-merkzahl-etikett {
  font-family: var(--font-mono);
  font-size: var(--ui-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}

.wk-merkzahl-wert {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--ui-page-title);
  letter-spacing: var(--display-tracking);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  margin: 0;
}

/* Eine Null steht IMMER leise. Eine Null in Signalfarbe lobt fuer nichts oder
   schreit ohne Anlass — sie ist an dieser Stelle eine gemessene Zaehlung, kein
   Befund. */
.wk-merkzahl-wert[data-null="ja"] {
  color: var(--text-muted);
}

.wk-merkzahl-nenner {
  font-family: var(--font-mono);
  font-size: var(--ui-md);
  color: var(--text-muted);
  letter-spacing: 0;
}

/* ── Tabelle ──────────────────────────────────────────────────────────────────────
 *
 * Die erste Tabellenklasse des Trainers. Die bis M6 einzige echte `<table>` war Zelle
 * fuer Zelle inline gesetzt (Briefing, `<th>` mit sieben Inline-Deklarationen).
 *
 * Das Scrollen liegt im RAHMEN (`overflow-x: auto`), nie im Body. Ein waagerecht
 * scrollender Body ist auf einem Telefon der Unterschied zwischen „eng" und „kaputt".
 */
.wk-tabellenrahmen {
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  background: var(--surface-raised);
  overflow-x: auto;
}

.wk-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--ui-md);
  line-height: var(--ui-line);
}

.wk-tabelle caption {
  text-align: left;
  font-family: var(--font-mono);
  font-size: var(--ui-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 0.85rem var(--card-pad-sm);
}

.wk-tabelle th,
.wk-tabelle td {
  text-align: left;
  padding: 0.75rem var(--card-pad-sm);
  border-bottom: var(--linie-breite) var(--linie-stil) var(--border-hairline);
  vertical-align: top;
}

.wk-tabelle thead th {
  font-family: var(--font-mono);
  font-size: var(--ui-micro);
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

.wk-tabelle tbody tr:last-child th,
.wk-tabelle tbody tr:last-child td {
  border-bottom: 0;
}

/* Zahlenspalten rechtsbuendig mit Tabellenziffern: Damit fluchten die Stellen
   untereinander und „12 von 63" bricht nicht in zwei Zeilen. */
.wk-spalte-zahl {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/**
 * Eine Textmarke — ein WORT, kein Badge.
 *
 * Kein Hintergrund, kein Rahmen, kein Radius, und ausdruecklich KEINE Signalfarbe.
 * Eine Bewertungsmarke in Rot oder Gruen waere ein Urteil per Farbton — dieselbe
 * Begruendung, aus der `.wk-befund` auf Signalfarbe verzichtet. Unterschieden wird
 * ueber `--text-primary` gegen `--text-muted` und ueber das Wort selbst.
 */
.wk-marke {
  font-family: var(--font-mono);
  font-size: var(--ui-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-muted);
}

.wk-marke--gilt {
  color: var(--text-primary);
}

.wk-marke--ruht {
  color: var(--text-muted);
}

/**
 * Der Leerzustand — der Zustand, in dem JEDER neue Nutzer diesen Bildschirm zuerst
 * sieht.
 *
 * Er traegt keine eigene Optik: keine graue Box, kein Symbol, kein Platzhalterbild.
 * Er besteht aus ausformulierten Saetzen in normaler Groesse. Eine leere Liste, die
 * wie ein Fehler aussieht, wird als Fehler gelesen.
 */
.wk-leerzustand {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* ── Verlauf je Kategorie ─────────────────────────────────────────────────────────
 *
 * Setzkastenraster wie die Merkzahlen: Fugen und Rahmen auf dem Container.
 */
.wk-verlauf {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--linie-breite);
  background: var(--border-hairline);
  outline: var(--linie-breite) var(--linie-stil) var(--border-hairline);
}

.wk-verlauf-feld {
  background: var(--surface-page);
  padding: var(--card-pad-sm);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.wk-verlauf-name {
  font-size: var(--ui-md);
  font-weight: 600;
  margin: 0;
}

/**
 * Das Bild skaliert UNIFORM: `viewBox` plus `width`/`height` als Attribute, hier
 * `width: 100%` und `height: auto`. `preserveAspectRatio` bleibt unangetastet —
 * `none` verzerrte die Punkte zu Ellipsen und die Strichstaerke ungleichmaessig.
 */
.wk-verlauf-bild {
  display: block;
  width: 100%;
  height: auto;
}

/**
 * FARBE KOMMT AUS KLASSEN, NIE AUS ATTRIBUTEN.
 *
 * Ein `fill="#2E5D8A"` im Markup waere im Dunkelmodus tot — und zwar lautlos, weil
 * ein Attributwert keine Kaskade kennt und kein Token aufloest.
 */
.wk-verlauf-band {
  fill: var(--korridor-flaeche);
}

.wk-verlauf-bandkante {
  stroke: var(--korridor-linie);
  stroke-width: 1;
}

.wk-verlauf-linie {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.wk-verlauf-punkt {
  fill: var(--surface-page);
  stroke: var(--accent);
  stroke-width: 1.5;
}

.wk-verlauf-zeile {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--ui-sm);
  color: var(--text-secondary);
  margin: 0;
}

/* ── Abdeckungsgrad je Subkategorie ───────────────────────────────────────────────
 *
 * DREI Bauformen, nicht drei Farben. Farbe traegt die Aussage nie allein (WCAG 1.4.1),
 * und hier kommt eine zweite Regel dazu: „keine Aufgaben vorhanden" darf nicht
 * BERUHIGENDER aussehen als ein niedriger Wert. Eine leere Bahn liest sich sonst wie
 * eine erledigte.
 */
.wk-abdeckung {
  display: grid;
  grid-template-columns: minmax(9rem, 18rem) 1fr auto;
  align-items: center;
  gap: 0.55rem 1rem;
  margin: 0;
}

/* `display: contents` laesst die Spalten des Elternrasters durchfluchten. Ersetzt das
   `style={{ display: "contents" }}` aus dem Kategorienprofil durch eine Klasse. */
.wk-abdeckung-zeile {
  display: contents;
}

.wk-abdeckung-name {
  font-size: var(--ui-sm);
  line-height: 1.35;
  margin: 0;
}

.wk-abdeckung-bahn {
  position: relative;
  height: var(--profil-balken-hoehe);
  background: var(--surface-tint);
  border: var(--linie-breite) var(--linie-stil) var(--profil-gitter);
}

.wk-abdeckung-balken {
  position: absolute;
  inset: 0 auto 0 0;
  background: var(--abdeckung-balken);
  border-right: 2px solid var(--text-secondary);
}

/* Hohl und gestrichelt: „hier war noch niemand" — ein Zustand, keine Menge. */
.wk-abdeckung-bahn--nicht-getestet {
  background: transparent;
  border-style: dashed;
  border-color: var(--border-strong);
}

/* Schraffiert: „hier gibt es nichts zu holen". Die Aussage betrifft die BANK, nicht
   den Nutzer — deshalb traegt diese Bauform zusaetzlich einen eigenen Satz. */
.wk-abdeckung-bahn--ohne-bank {
  background: repeating-linear-gradient(
    45deg,
    transparent 0 5px,
    var(--border-hairline) 5px 7px
  );
  border-color: var(--border-strong);
}

.wk-abdeckung-zahl {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-secondary);
  font-size: var(--ui-sm);
  margin: 0;
}

.wk-abdeckung-satz {
  grid-column: 1 / -1;
  font-size: var(--ui-sm);
  color: var(--text-muted);
  margin: 0;
}

.wk-abdeckung-zeile--duenn .wk-abdeckung-name,
.wk-abdeckung-zeile--duenn .wk-abdeckung-zahl {
  color: var(--text-muted);
}

.wk-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  font-size: var(--ui-sm);
  color: var(--text-secondary);
  list-style: none;
  padding: 0;
  margin: 0;
}

.wk-legende-eintrag {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* Die Probe behaelt ihre Hoehe auch im Umbruch — sonst waeren die drei Bauformen
   genau dort nicht mehr unterscheidbar, wo der Platz knapp ist. */
.wk-legende-probe {
  position: relative;
  display: block;
  flex: 0 0 auto;
  width: 2.25rem;
  height: var(--profil-balken-hoehe);
}

/**
 * Unter 600 px WECHSELT das Abdeckungsraster die Form, statt zu schrumpfen: Name und
 * Zahl in die erste Zeile, die Bahn darunter ueber die volle Breite.
 *
 * Eine 4 rem breite Bahn ist keine Bahn mehr. Typografie, Abstand und Layout passen
 * sich an — sie schrumpfen nicht nur.
 */
@media (max-width: 600px) {
  .wk-abdeckung {
    grid-template-columns: 1fr auto;
  }

  .wk-abdeckung-bahn {
    grid-column: 1 / -1;
  }
}

/**
 * Die Stufenwahl im gezielten Ueben.
 *
 * Sie ist eine NAVIGATION, kein Formular: Jede Stufe ist eine eigene Adresse
 * (`/ueben?stufe=schwer`), damit die Kachelzahlen zur Wahl passen und die Wahl das
 * Zurueckblaettern ueberlebt. Die Auszeichnung haengt wie ueberall im Haus an
 * `aria-current="page"` und nicht an einer zusaetzlichen Klasse — was ausgezeichnet
 * aussieht, ist damit auch ausgezeichnet.
 */
.wk-stufenwahl {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.75rem 0 0.5rem;
}

.wk-stufenwahl a {
  font-size: var(--ui-sm);
  color: var(--text-secondary);
  text-decoration: none;
  padding: 0.3rem 0.9rem;
  border: var(--linie-breite) var(--linie-stil) var(--border-hairline);
}

.wk-stufenwahl a:hover {
  color: var(--text-primary);
  border-color: var(--border-strong);
}

.wk-stufenwahl a[aria-current="page"] {
  color: var(--text-primary);
  border-color: var(--accent-brass);
  font-weight: 600;
}

/**
 * Ein abgeschalteter Kanon-Knopf sieht abgeschaltet aus.
 *
 * `.cmb-btn` kommt aus `werkbund.css` und fuehrt dort keine `:disabled`-Regel — ein
 * abgeschalteter Knopf war deshalb von einem bedienbaren nicht zu unterscheiden, samt
 * Schwebe-Animation. Der Auftraggeber hat das am 2026-09-06 an der Kachel „Auf Sie
 * zugeschnitten" gemeldet: „genauso animiert wie alle … und dann passiert gar nichts."
 *
 * Der Kanon wird nicht von Hand geaendert (Drift-Waechter haelt ihn byte-gleich mit dem
 * Referenzrepo). Die Regel steht deshalb hier im eigenen Overlay — mit denselben Werten,
 * die `.pf-knopf:disabled` weiter oben schon benutzt, statt einen zweiten Stil zu
 * erfinden.
 *
 * `:disabled` statt einer Klasse: Was abgeschaltet AUSSIEHT, ist damit auch abgeschaltet.
 * Eine Klasse `--aus` neben einem vergessenen Attribut waere ein Knopf, der grau ist und
 * trotzdem reagiert — dieselbe Ueberlegung wie bei `aria-current` in der Navigation.
 */
.cmb-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Und die Schwebe-Wirkung bleibt aus — sonst verspricht die Bewegung, was der Klick
   nicht haelt. Der Kanon setzt sie ohne `:not(:disabled)`, deshalb hier zuruecknehmen. */
.cmb-btn:disabled:hover {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}
