@import './tokens.css';
@import './lernen.css';
@import './pruefung.css';
@import './ueber.css';
@import './hilfe.css';
@import './suche.css';

/* =====================================================================
   Grundlagen
   ===================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* Kein `font-size` in px auf <html>: die Nutzer-Schriftgröße des
     Browsers/Systems bleibt so wirksam. */
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--farbe-grund);
  color: var(--farbe-text);
  font-family: var(--schrift-familie);
  font-size: var(--schrift-basis);
  line-height: var(--zeilenhoehe-text);
  font-weight: var(--schriftstaerke-normal);

  /*
    Wort- und Zeichenabstand (WCAG 1.4.12).

    Beides vererbt sich, steht deshalb einmal hier statt an jedem Textträger.
    Ab Werk `normal` – sichtbar wird es erst über die Einstellung
    „Textdarstellung“ (siehe `tokens.css`, Abschnitt Textabstände).
  */
  word-spacing: var(--wortabstand);
  letter-spacing: var(--zeichenabstand);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;

  /*
    Ein zu langes Wort bricht um, statt die Seite breit zu machen.

    Der amtliche Katalog führt Wörter wie „waffenbesitzkartenpflichtigen"
    (29 Zeichen) und „Deaktivierungsdurchführungsverordnung" (37). Bei
    320 CSS-Pixeln – dem Prüffall von WCAG 1.4.10 – misst der Fragetext
    damit breiter als sein Kasten; nachgemessen 268 Pixel Überstand. Die
    Eigenschaft vererbt sich, deshalb steht sie einmal hier statt an
    jedem Textträger.

    Bewusst `break-word` und nicht `anywhere`: `anywhere` senkt zusätzlich
    die Mindestbreite (min-content) und ließe damit auch Tabellenspalten
    und Flex-Kästen bei gewöhnlicher Fensterbreite mitten im Wort
    umbrechen. Gebrochen wird so nur, wenn es sonst gar nicht passt.

    Kein `hyphens: auto` dazu: Chromium lädt Trennmuster als Komponente
    aus dem Netz nach, und diese Anwendung läuft offline – die Trennung
    käme also je nach Rechner oder gar nicht.
  */
  overflow-wrap: break-word;

  /* Textauswahl bleibt erlaubt – Lerntexte sollen kopierbar sein. */
}

/* Der Bildlauf liegt beim Dokument, nicht bei einem eigenen Kasten:
   `#wurzel` trägt darunter nur `min-height`, `display` und
   `flex-direction`. Der Kommentar behauptete bis Fassung 0.25.0 das
   Gegenteil. Es hängt daran mehr als eine Formulierung: Der Rückkehrfokus
   in `App.tsx` rollt über `scrollIntoView`, und das trifft den Knoten, der
   den Bildlauf wirklich trägt. */
#wurzel {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* =====================================================================
   Fokusindikator
   ---------------------------------------------------------------------
   `:focus-visible` statt `:focus`, damit Mausklicks keinen Ring erzeugen,
   Tastaturbedienung aber immer. Zweifarbig: kräftige Kontur plus
   Gegenfarbe, damit der Ring auf hellem UND dunklem Grund sichtbar ist.
   ===================================================================== */

:focus {
  /* Standard-Outline erst entfernen, ... */
  outline: none;
}

:focus-visible {
  /* ... und für Tastaturfokus durch den eigenen, kräftigeren Ring ersetzen. */
  outline: var(--fokus-breite) solid var(--farbe-fokus);
  outline-offset: var(--fokus-abstand);
  box-shadow: 0 0 0 calc(var(--fokus-abstand) + var(--fokus-breite) + var(--fokus-kontur-breite))
    var(--farbe-fokus-kontur);
  border-radius: var(--radius-s);
}

@media (forced-colors: active) {
  :focus-visible {
    outline: 3px solid Highlight;
    outline-offset: 2px;
    box-shadow: none;
  }
}

/* =====================================================================
   Skip-Link
   ---------------------------------------------------------------------
   Erster fokussierbarer Knoten im Dokument. Optisch versteckt, aber im
   Fokus sichtbar – nicht `display:none`, sonst wäre er nicht erreichbar.
   ===================================================================== */

.skip-link {
  position: absolute;
  top: var(--abstand-xs);
  left: var(--abstand-xs);
  z-index: 100;
  padding: var(--abstand-xs) var(--abstand-m);
  background-color: var(--farbe-akzent);
  color: var(--farbe-akzent-text);
  font-weight: var(--schriftstaerke-mittel);
  border-radius: var(--radius-s);
  text-decoration: none;

  /* Aus dem Sichtfeld schieben statt ausblenden. */
  transform: translateY(calc(-100% - var(--abstand-l)));
  transition: transform var(--uebergang-dauer) var(--uebergang-kurve);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* =====================================================================
   Nur für Screenreader
   ===================================================================== */

.nur-screenreader {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* =====================================================================
   Typografie
   ===================================================================== */

h1,
h2,
h3 {
  font-family: var(--schrift-familie-ueberschrift);
  line-height: var(--zeilenhoehe-eng);
  font-weight: var(--schriftstaerke-fett);
  margin: 0;
  text-wrap: balance;
}

/*
  Der leicht negative Zeichenabstand der Überschriften ist Feinsatz – bei
  großen Graden wirkt normaler Abstand auseinandergefallen. Er darf aber
  nicht gegen die Einstellung „Textdarstellung“ stehen: Wer mehr Luft
  braucht, braucht sie in der Überschrift erst recht. `max()` lässt den
  Feinsatz bei der Vorgabe wirken und tritt zurück, sobald jemand eine
  weitere Stufe wählt – dort ist `--zeichenabstand` eine positive Länge und
  gewinnt.
*/
h1 {
  font-size: var(--schrift-h1);
  letter-spacing: max(-0.015em, var(--zeichenabstand));
}

h2 {
  font-size: var(--schrift-h2);
  letter-spacing: max(-0.01em, var(--zeichenabstand));
}

h3 {
  font-size: var(--schrift-h3);
  font-weight: var(--schriftstaerke-mittel);
}

p {
  margin: 0;
  max-width: var(--textbreite-max);
  text-wrap: pretty;
  /* Absatzabstand nach 1.4.12: das 2-fache der Schriftgröße. Als
     zusätzlicher Abstand, damit vorhandene Abstände nicht verschwinden. */
  margin-block-end: var(--absatzabstand);
}

a {
  color: var(--farbe-akzent);
  text-underline-offset: 0.2em;
  text-decoration-thickness: max(1px, 0.06em);
}

code,
kbd,
samp {
  font-family: var(--schrift-familie-mono);
  font-size: 0.9em;
}

/* =====================================================================
   Layout
   ===================================================================== */

.seite {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--abstand-xl);
  /* siehe .seite:has(.kopfbereich--knapp) weiter unten */
  width: 100%;
  max-width: 62rem;
  margin-inline: auto;
  padding: var(--abstand-xl) var(--abstand-l) var(--abstand-2xl);
}

.kopfbereich {
  display: flex;
  flex-direction: column;
  gap: var(--abstand-s);
}

.kopfbereich__augenbraue {
  margin: 0;
  color: var(--farbe-text-leise);
  font-size: var(--schrift-klein);
  font-weight: var(--schriftstaerke-mittel);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/*
  Schlanker Kopf in Sitzung und Pruefung.

  Nachgemessen: Kopf und Fuss zusammen 324 von 1063 sichtbaren Pixeln. Die
  Ueberschrift bleibt - sie traegt die Dokumentstruktur und den Fenstertitel -,
  wird aber auf die Groesse einer Abschnittsueberschrift zurueckgenommen.
*/
/* Auch die Abstaende zwischen Kopf, Inhalt und Fuss ruecken zusammen. */
.seite:has(.kopfbereich--knapp) {
  gap: var(--abstand-m);
  padding-block: var(--abstand-m) var(--abstand-l);
}

/* In den Nebenansichten steht der Rueckweg unmittelbar unter der
   Anwendungsueberschrift - ohne Abstand, der ihn wieder wegschiebt. */
.kopfbereich--knapp + main > .zurueckleiste {
  margin-block-start: 0;
}

.kopfbereich--knapp h1 {
  font-size: var(--schrift-gross);
  margin: 0;
}

.fussbereich--knapp {
  padding-top: var(--abstand-s);
}

.einleitung {
  color: var(--farbe-text-leise);
  font-size: var(--schrift-gross);
}

.abschnitt {
  display: flex;
  flex-direction: column;
  gap: var(--abstand-m);
}

.karte {
  background-color: var(--farbe-flaeche);
  border: var(--rahmenbreite) solid var(--farbe-rahmen);
  border-radius: var(--radius-l);
  padding: var(--abstand-l);
  box-shadow: var(--schatten-flaeche);
}

/* Der Rueckweg, ganz oben und in jeder Nebenansicht an derselben Stelle. */
.zurueckleiste {
  margin-block-end: var(--abstand-m);
}

.knopf--zurueck {
  padding-inline: var(--abstand-m);
}

.fussbereich {
  border-top: var(--rahmenbreite) solid var(--farbe-rahmen);
  padding-top: var(--abstand-m);
  color: var(--farbe-text-leise);
  font-size: var(--schrift-klein);
}

/* Der Weg zur Hilfe – in jeder Ansicht der erste Eintrag im Fussbereich
   (WCAG 3.2.6). Die Schriftgroesse kommt vom Knopf, nicht vom Fussbereich:
   Was man anklickt, soll nicht kleiner sein als der Text daneben. */
.fussbereich__hilfe {
  margin-block-end: var(--abstand-s);
  font-size: var(--schrift-basis);
}

/* =====================================================================
   Theme-Umschalter (ARIA-Radiogruppe)
   ===================================================================== */

.themawahl__optionen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--abstand-s);
  margin-top: var(--abstand-m);
}

.themawahl__option {
  display: flex;
  align-items: center;
  gap: var(--abstand-xs);
  min-height: var(--klickflaeche-min);
  padding: var(--abstand-xs) var(--abstand-m);
  background-color: var(--farbe-flaeche);
  color: var(--farbe-text);
  border: var(--rahmenbreite-stark) solid var(--farbe-rahmen-kraeftig);
  border-radius: var(--radius-m);
  font: inherit;
  font-weight: var(--schriftstaerke-mittel);
  cursor: pointer;
  transition:
    background-color var(--uebergang-dauer) var(--uebergang-kurve),
    border-color var(--uebergang-dauer) var(--uebergang-kurve),
    color var(--uebergang-dauer) var(--uebergang-kurve);
}

.themawahl__option:hover {
  background-color: var(--farbe-akzent-leise);
  border-color: var(--farbe-akzent);
}

.themawahl__option[aria-checked='true'] {
  background-color: var(--farbe-akzent);
  border-color: var(--farbe-akzent);
  color: var(--farbe-akzent-text);
}

/* Der Zustand darf nicht nur über Farbe erkennbar sein (WCAG 1.4.1).
   Deshalb zusätzlich ein Markierungsglyph. */
.themawahl__marke {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25em;
  flex: none;
  font-weight: var(--schriftstaerke-fett);
}

@media (forced-colors: active) {
  .themawahl__option[aria-checked='true'] {
    background-color: Highlight;
    color: HighlightText;
    border-color: Highlight;
    forced-color-adjust: none;
  }
}

.themawahl__hinweis {
  margin-top: var(--abstand-m);
  color: var(--farbe-text-leise);
  font-size: var(--schrift-klein);
}

/* =====================================================================
   Statusanzeige (Laufzeitinformationen)
   ===================================================================== */

.statusliste {
  display: grid;
  grid-template-columns: minmax(10rem, auto) 1fr;
  gap: var(--abstand-xs) var(--abstand-m);
  margin: 0;
}

.statusliste dt {
  color: var(--farbe-text-leise);
  font-weight: var(--schriftstaerke-mittel);
}

.statusliste dd {
  margin: 0;
  font-family: var(--schrift-familie-mono);
  overflow-wrap: anywhere;
}

.statusabzeichen {
  display: inline-block;
  padding: 0 var(--abstand-xs);
  border: var(--rahmenbreite-stark) solid currentcolor;
  border-radius: var(--radius-s);
  font-family: var(--schrift-familie);
  font-size: var(--schrift-klein);
  font-weight: var(--schriftstaerke-mittel);
}

.statusabzeichen--ok {
  color: var(--farbe-erfolg);
}

.statusabzeichen--fehler {
  color: var(--farbe-fehler);
}

@media (max-width: 40rem) {
  .statusliste {
    grid-template-columns: 1fr;
    gap: 0 0;
  }

  .statusliste dd {
    margin-bottom: var(--abstand-s);
  }
}

/* =====================================================================
   Sehr schmale Anzeige (WCAG 2.2 – 1.4.10 Reflow)
   ---------------------------------------------------------------------
   Ab hier gilt der Prüffall 320 CSS-Pixel. Die Abstände und die
   Überschriftenskala rücken bereits in tokens.css zusammen; was hier
   steht, betrifft das Umbruchverhalten.

   `anywhere` statt des sonst geltenden `break-word`: Nur `anywhere`
   senkt auch die **Mindestbreite** eines Kastens (min-content). Ohne das
   kann ein Flex- oder Rasterkasten mit langem Wort nicht unter dieses
   Wort schrumpfen und läuft seitlich hinaus – nachgemessen an der
   Antwortoption mit „Munitionsverpackungseinheit": 36 Pixel Überstand,
   obwohl `min-inline-size: 0` gesetzt war. Bei gewöhnlicher Breite bleibt
   es bei `break-word`, damit Tabellenspalten und Flex-Kästen nicht
   vorzeitig mitten im Wort umbrechen.
   ===================================================================== */
@media (width <= 30rem) {
  body {
    overflow-wrap: anywhere;
  }

  /*
    Die Ausnahme: eine Tabelle.

    Ihre Spaltenbreiten hängen an der Mindestbreite des Inhalts. Mit
    `anywhere` quetschte sich jede Spalte auf wenige Zeichen zusammen,
    statt den eigenen Rollbereich zu benutzen – und genau der ist für
    Tabellen ausdrücklich zulässig (1.4.10 nimmt Inhalte aus, die eine
    zweidimensionale Anordnung brauchen).
  */
  .verlauf__tabelle {
    overflow-wrap: break-word;
  }
}
