/* Die Bauschritt-Seite.
 *
 * Gebaut fuer zwei Geraete und keine dazwischen: den Laptop auf dem Tisch
 * neben dem Brett und das Handy in der Hand. Unter 700 px klebt die
 * Fortschrittsleiste am unteren Rand, damit "wo bin ich" nie weiter als einen
 * Blick entfernt ist.
 *
 * Nichts hier braucht JavaScript. Beide Fotos der Buehne stehen immer da, und
 * wo sie stehen, entscheidet allein dieses Blatt: ab 900 px nebeneinander,
 * darunter untereinander. Was erst mit `js/schritt.js` dazukommt, haengt an
 * einem Haken, den nur das Modul setzt: `.feld--besucht` in der Leiste. Ohne
 * Skript greift die eine Regel nicht, und es fehlt auch nichts.
 *
 * Zur Farbregel: --orange traegt auf Weiss nur 3,50:1 und ist erst ab 24 px
 * oder 19 px fett erlaubt. Die Aufklapper-Ueberschrift ist 17 px und nimmt
 * deshalb --orange-text. Als Flaeche (die erledigten Felder der Leiste) gilt
 * die Regel nicht — dort ist nichts zu lesen.
 */

.schritt {
  padding-top: 1.25rem;
}

/* --- Zaehler --------------------------------------------------------------
 *
 * Die erste der drei Fragen: wo bin ich. Links der Schritt, rechts das
 * Kapitel. Unter 480 px stehen sie untereinander — gestapelt, nicht umgebrochen.
 */

.zaehler {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.125rem 1rem;
  margin: 0 0 1rem;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.25;
}

.zaehler-schritt {
  font-size: 1.5rem;
  font-weight: 700;
}

.zaehler-kapitel {
  color: var(--grau);
  font-size: 0.9375rem;
}

@media (max-width: 479.98px) {
  .zaehler {
    display: block;
  }

  .zaehler-schritt {
    display: block;
    font-size: 1.375rem;
  }

  .zaehler-kapitel {
    display: block;
    font-size: 0.875rem;
  }
}

/* --- Vorlesen -------------------------------------------------------------
 *
 * Taste und Tempo, direkt unter dem Zaehler. Beim Usertest am 25. August 2026
 * hoerte der Leser ab Schritt 10 auf zu lesen und liess sich die Seite von
 * Safari vorlesen; danach fragte er nach einer Geschwindigkeit.
 *
 * Zwei Dinge stehen hier:
 *
 *   1. **Leer bleibt unsichtbar.** Ohne JavaScript und in jedem Browser ohne
 *      Sprachausgabe fuellt niemand den Platz. Er darf dann keine Hoehe und
 *      keinen Abstand haben: die Seite soll aussehen wie vorher, und nicht
 *      wie eine mit einer Luecke.
 *   2. **Umrandet, nicht gefuellt.** Die gefuellte rote Flaeche gehoert hier
 *      schon jemand anderem: auf allen 38 Seiten der Weiter-Taste im Fuss
 *      (`.taste-weiter`), auf den fuenf Pruefpunkten zusaetzlich der
 *      Hoerprobe (`.synth-taste` in synth.css). Diese Taste hier steht oben und
 *      spricht, sie spielt nicht ab. Gross genug fuer einen Finger ist sie
 *      trotzdem: 44 px, dieselbe Hoehe wie die Hoerprobe-Taste.
 *
 * **Kein eigener Fokusring, und das ist gemessen.** Beide Bedienelemente
 * bekommen den Ring der Website aus `basis.css` (`:focus-visible`). An
 * /bauen/33/ mit echten Tabulator-Druecken nachgesehen: Halt 7 ist die Taste,
 * Halt 8 der Schieber, und beide zeigen `solid 2px rgb(202, 28, 17)` bei
 * `outline-offset: 2px` — dasselbe wie die sieben Halte davor. Auf der
 * umrandeten Taste steht der Ring als zweites Rechteck mit weissem Abstand um
 * den roten Rand herum. Eine eigene Regel hier waere eine zweite Fassung
 * derselben Sache.
 */

.vorlesen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin: 0 0 1.25rem;
}

.vorlesen:empty {
  display: none;
  margin: 0;
}

.vorlesen-taste {
  min-height: 44px;
  padding: 0.375rem 1.125rem;
  border: 2px solid var(--rot);
  border-radius: 6px;
  background: transparent;
  color: var(--rot);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.vorlesen-taste:hover {
  background: var(--rot);
  color: var(--papier);
}

.vorlesen-tempofeld {
  flex: 1 1 12rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  max-width: 20rem;
}

.vorlesen-tempo-name {
  color: var(--grau);
  font-size: 0.9375rem;
}

.vorlesen-tempo {
  flex: 1 1 auto;
  min-width: 6rem;
  min-height: 44px;
  accent-color: var(--rot);
}

/* --- Achtung-Band ---------------------------------------------------------
 *
 * Nicht wegklickbar, ueber dem Bild, kein Aufklapper. Einen Aufklapper
 * oeffnet genau der nicht, der aus Routine handelt — und bei Encoder 4 ist
 * Routine der Fehler.
 */

.achtung {
  margin: 0 0 1.25rem;
  padding: 0.875rem 1rem 1rem;
  border: 2px solid var(--rot);
  border-radius: 10px;
  background: #fcf1ef;
}

.achtung-marke {
  margin: 0 0 0.25rem;
  color: var(--rot);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.achtung h2 {
  margin: 0 0 0.5rem;
  font-size: 1.0625rem;
}

.achtung p:last-child {
  margin-bottom: 0;
}

.achtung .zeichnung {
  margin: 0.875rem 0 0;
}

.achtung .zeichnung-svg {
  max-width: 24rem;
}

/* --- Das Teilefoto ueber der Buehne ---------------------------------------
 *
 * Auf sechs der 33 Bauschritt-Seiten steht zwischen Zaehler und Buehne das
 * Foto des Teils, das jetzt in die Hand genommen wird. Es liegt **neben**
 * seiner Unterschrift und nicht darueber: die Unterschrift ist ein Halbsatz
 * ("Das brauchst du jetzt: der Chip ..."), und ein Halbsatz unter einem
 * 240 px breiten Bild sieht aus wie eine Bildunterschrift der Buehne. Neben
 * dem Bild liest er sich als das, was er ist: eine Ansage.
 *
 * Die 240 px und die 120 px am Handy stehen genauso in `TEILBILD_BREITEN`
 * (vorlagen/schritt.mjs) als `sizes`, und die Grenze ist dieselbe 900 px, an
 * der die Buehne umstellt. Wer eine der Zahlen aendert, aendert sie dort mit,
 * sonst holt der Browser die falsche der beiden Bilddateien. */
.teilbild {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  margin: 0 0 1rem;
}

.teilbild img {
  display: block;
  flex: 0 0 auto;
  width: 120px;
  height: auto;
  border-radius: 6px;
  background: #f4f4f4;
}

.teilbild figcaption {
  font-size: 1rem;
  line-height: 1.4;
}

@media (min-width: 900px) {
  .teilbild {
    width: 876px;
    margin-right: calc((100% - 876px) / 2);
    margin-left: calc((100% - 876px) / 2);
  }

  .teilbild img {
    width: 240px;
  }

  .teilbild figcaption {
    font-size: 1.0625rem;
  }
}

/* --- Buehne ---------------------------------------------------------------
 *
 * Zwei Fotos, und beide sind immer zu sehen: die Uebersicht mit den gelben
 * Ringen und die Nahaufnahme des fertig gesteckten Bauteils. Bis Aufgabe 8
 * lag die zweite hinter einem Umschalter; der Usertest vom 25. August 2026
 * hat gezeigt, dass ein Kind sie dort nicht findet.
 *
 * Am Handy laufen sie von Rand zu Rand und stehen untereinander. Ab 900 px
 * stehen sie nebeneinander, in einer Flaeche, die breiter ist als die
 * Textspalte: **876 px = 516 + 16 + 344.** Drei Fuenftel fuer die Uebersicht,
 * 1 rem Luft, zwei Fuenftel fuer die Nahaufnahme.
 *
 * Warum die Uebersicht die breitere Haelfte bekommt: sie zeigt das ganze
 * Brett mit 63 Spalten nebeneinander, und jede Spalte, die schmaler wird,
 * kostet Erkennbarkeit. Die Nahaufnahme zeigt eine Handvoll Loecher.
 *
 * `align-items: flex-start` macht die Oberkanten buendig — und nur die. Die
 * Uebersicht ist auf 16:9 beschnitten, die Nahaufnahme bleibt 4:3; bei
 * 516 zu 344 px Breite ist die eine 290 px hoch und die andere 258. Die
 * Unterkanten muessen also auseinandergehen duerfen.
 *
 * Hat ein Schritt keine Nahaufnahme, nimmt die Uebersicht die ganzen 876 px:
 * `flex-grow: 1` an ihr fuellt die freie Haelfte auf. Von den 33
 * Bauschritt-Seiten trifft das zwei, die Schritte 1 und 2; nur sie fuehren in
 * steps.json `bilder.nah: null`. (Die vier Pruefpunkte 10, 17, 24 und 31 tun
 * das auch, bekommen aber gar keine Buehne.)
 *
 * **Drei Breiten, und `sizes` kennt alle drei.** 516, 344 und 876 stehen
 * ebenso in `website/vorlagen/schritt.mjs`; welche davon an ein Bild kommt,
 * entscheidet dort dieselbe Bedingung, die hier ueber die Aufteilung
 * entscheidet. Wer eine der Zahlen hier aendert, aendert sie dort mit, sonst
 * holt der Browser die falsche der beiden Bilddateien.
 */

.buehne {
  margin: 0 -1rem 1.25rem;
}

.bild {
  margin: 0 0 1rem;
}

.bild:last-child {
  margin-bottom: 0;
}

@media (min-width: 900px) {
  .buehne {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    width: 876px;
    margin-right: calc((100% - 876px) / 2);
    margin-left: calc((100% - 876px) / 2);
  }

  .bild {
    margin-bottom: 0;
  }

  .bild[data-bildslot="ziel"] {
    flex: 1 1 516px;
  }

  .bild[data-bildslot="nah"] {
    flex: 0 1 344px;
  }
}

/* Der Rahmen um das Bild ist ein Verweis auf die 2560er Datei.
 *
 * Ein Kind, das eine Lochreihe abzaehlen will, kommt so an die grosse
 * Aufnahme.
 *
 * `display: block`, damit der Verweis einen sichtbaren Fokusring bekommt.
 * Gefahren bei 1280 px mit echten Tabulator-Schritten, bis der Verweis den
 * Fokus hat, und die obere linke Ecke sechsfach vergroessert aufgenommen: als
 * Block liegt der rote Ring aus basis.css da, mit `display: inline` ist die
 * Aufnahme bildpunktgleich mit der unfokussierten. Durchgang 2 der Abnahme
 * geht die ganze Anleitung nur mit der Tastatur. */
.bild-gross {
  display: block;
}

/* max-height statt fester Hoehe, und width/height auf auto: nur so bleibt das
 * Seitenverhaeltnis erhalten.
 *
 * Wo die Deckelung greift, ist gefahren und nicht gerechnet: bei neun von
 * zehn gefahrenen Fenstergroessen greifen die 62vh hier nicht. Im flachen
 * Fenster greifen sie — bei 1280 x 450 halten sie die Uebersicht auf 279 px
 * statt 290, bei 1280 x 470 nicht mehr. Wo die 52vh der Nahaufnahme greifen,
 * steht unten. */
.bild img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 62vh;
  margin: 0 auto;
  background: #f4f4f4;
}

/* Das Uebersichtsfoto wird auf 16:9 beschnitten.
 *
 * Alle 102 Aufbaufotos sind 4:3, und das Brett liegt in allen 33 markierten
 * Uebersichten als waagerechter Streifen in der Mitte: oben und unten stehen
 * je gut zwei Zehntel Untergrund. Der Schnitt nimmt davon je ein Achtel weg
 * (aus 1280 x 960 wird 1280 x 720, also 120 Bildpunkte oben und 120 unten).
 *
 * Nachgefahren an allen 33 Uebersichten der Bauschritt-Seiten, Bildpunkt fuer
 * Bildpunkt: in den beiden weggeschnittenen Streifen (oberste und unterste
 * 120 Zeilen) liegt kein einziger gelber Punkt. Dass die Zaehlung nicht blind
 * ist, sagt dieselbe Messung am ganzen Bild — jede der 33 Aufnahmen bringt
 * zwischen 378 und 21418 gelbe Punkte. Beschnitten wird in der Anzeige, nicht
 * an der Datei: Anleitung/web/ bleibt unberuehrt.
 *
 * Seit Aufgabe 8 steht die Nahaufnahme daneben, und der Schnitt verdient sich
 * ein zweites Mal. Gefahren bei 1280 x 900, einmal mit und einmal ohne diese
 * Regel: mit ihr ist die Uebersicht 290 px hoch neben 258 px Nahaufnahme,
 * ohne sie 387 px — also 129 px ueber der Nachbarin, und die Ansage beginnt
 * 97 px weiter unten (563 statt 466).
 *
 * Die Nahaufnahme behaelt ihre 4:3 — dort fuellt das Motiv das Bild. Sie ist
 * dafuer flacher gedeckelt, und dieser Deckel arbeitet: gefahren bei
 * 899 x 900 haelt er sie auf 468 px statt 552 und zieht damit die Ansage auf
 * 1102 px statt 1186. Bei 375 x 812 greift er nicht, dort ist die Aufnahme
 * 281 px hoch. */
.bild[data-bildslot="ziel"] img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  object-position: center;
}

.bild[data-bildslot="nah"] img {
  max-height: 52vh;
}

.bild figcaption {
  margin: 0.375rem 0 0;
  padding: 0 1rem;
  color: var(--grau);
  font-size: 0.875rem;
}

@media (min-width: 900px) {
  .bild img {
    border-radius: 8px;
  }

  .bild figcaption {
    padding: 0;
  }
}

/* --- Die Lupe -------------------------------------------------------------
 *
 * Der Rahmen um jedes Foto ist ein Verweis auf die 2560er Datei (oben,
 * `.bild-gross`). Bis zum 8. September 2026 fuehrte ein Klick darauf aus der
 * Anleitung heraus auf das nackte Bild, und zurueck kam man nur mit dem
 * Zurueck-Knopf des Browsers. Seither faengt `js/lupe.js` den Klick ab und
 * legt das grosse Bild als `<dialog>` ueber die Seite.
 *
 * **Ohne JavaScript steht hier nichts.** Das Overlay entsteht erst beim
 * ersten Oeffnen; im ausgelieferten HTML kommt keine dieser Klassen vor. Wer
 * kein JavaScript hat, folgt weiter dem Verweis.
 *
 * **Was hier gerechnet wird und was in js/lupe.js:** Die Groesse des grossen
 * Bildes rechnet das Modul (`lupengroesse`) und schreibt sie als `width` und
 * `height` an das Bild; nur so kennt der Flug sein Ziel, bevor er anfaengt.
 * Die Regeln hier sind die Auffanglinie fuer den Fall, dass die Rechnung
 * nichts geliefert hat: `max-width`, `max-height` und `object-fit: contain`
 * halten das Bild dann im Fenster, ohne es zu verziehen.
 *
 * Die 8 px `gap` stehen als `LUFT` auch in `js/lupe.js`: die Rechnung zieht
 * sie zusammen mit der Hoehe der Unterschrift von der Fensterhoehe ab. Wer
 * die eine Zahl aendert, aendert die andere mit, sonst laeuft das Bild unter
 * die Unterschrift.
 *
 * Bewegt werden nur `transform` und `opacity`, und der Massstab im `transform`
 * ist in beiden Richtungen derselbe. `prefers-reduced-motion: reduce`
 * schaltet die Bewegung ab und die Lupe nicht: die Regel in basis.css nimmt
 * jedem Uebergang die Dauer, und das Modul laesst den Flug dann von
 * vornherein aus.
 *
 * **Warum zwei Bilder uebereinander liegen.** Das Uebersichtsfoto steht auf
 * der Seite auf 16:9 beschnitten (oben, `.bild[data-bildslot="ziel"] img`),
 * die Datei ist 4:3. Der Flug muss also nicht nur wachsen, sondern den
 * Schnitt oeffnen. Ein einzelnes Bild kann das nur mit einem ungleichen
 * Massstab, und der verzieht das Foto: gemessen bei 1280 x 900, Uebergang auf
 * 4 s verlangsamt, lief das Seitenverhaeltnis des fliegenden Bildes von
 * 1,724 ueber 1,420 nach 1,333 — es kam nicht als der Ausschnitt an, den das
 * kleine Bild zeigt, sondern als das ganze Foto, in den 16:9-Kasten
 * gestaucht.
 *
 * Deshalb fliegen zwei Ebenen mit **demselben** gleichmaessigen Massstab:
 *
 *   - `.lupe-bild` ist das ganze Foto und blendet auf (`opacity`).
 *   - `.lupe-ausschnitt` liegt darueber, ist deckend und zeigt mit
 *     `object-fit: cover` genau den Streifen, den das kleine Bild zeigt. Sein
 *     Kasten hat dessen Seitenverhaeltnis; `js/lupe.js` bemisst ihn so, dass
 *     beide Ebenen das Foto in **derselben** Groesse an **derselben** Stelle
 *     zeigen (`deckungsfaktor`).
 *
 * Im ersten Augenblick sieht man damit den Ausschnitt des kleinen Bildes und
 * sonst nichts; waehrend beide wachsen, blenden die Streifen oben und unten
 * auf. Kein Bildpunkt wird dabei je verzogen. Wenn der Flug gelandet ist,
 * verschwindet die obere Ebene ohne Uebergang (`transition: opacity 0s` mit
 * einer Verzoegerung von der Laenge des Fluges) — sie liegt dann auf
 * denselben Bildpunkten, die darunter stehen, und niemand sieht den Wechsel.
 *
 * **Wo der rote Fokusring in der offenen Lupe liegt.** Am grossen Foto:
 * `js/lupe.js` gibt `.lupe-bild` dafuer `tabindex="-1"` und setzt den Fokus
 * dorthin. Hier steht deshalb keine eigene Regel dafuer — nachgemessen an
 * /bauen/12/ in Chrome, mit dem Tabulator geoeffnet: Der Ring kommt aus
 * `basis.css` (`solid 2px rgb(202, 28, 17)`, Abstand 2 px), und die 8 px
 * `border-radius` von oben behalten dabei die Oberhand ueber die 2 px, die
 * die Regel in `basis.css` mitbringt. Beide Regeln sind gleich spezifisch,
 * und dieses Blatt kommt spaeter. Eine Regel hier waere eine zweite Fassung
 * derselben Sache und ginge beim naechsten Umbau auseinander.
 *
 * **Warum `100dvh` und nicht `100vh`.** `js/lupe.js` rechnet die Bildgroesse
 * aus `fenster.innerHeight`. Auf Telefonen mit einfahrender Adressleiste ist
 * `100vh` das grosse Sichtfeld und `innerHeight` das gerade sichtbare; die
 * Unterschrift stuende dann unter der Schirmkante. `100dvh` ist genau das,
 * was `innerHeight` meldet. Die `100vh`-Zeile davor bleibt fuer Browser ohne
 * `dvh` stehen: sie ueberschreiben die Zeile danach nicht, und dort gilt
 * weiter, was bis zum 8. September 2026 ueberall galt.
 */

.lupe {
  --flugdauer: 0.26s;

  width: 100vw;
  max-width: 100vw;
  height: 100vh;
  height: 100dvh;
  max-height: 100vh;
  max-height: 100dvh;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
}

/* Der Grund dahinter faehrt mit hoch. Ohne den Uebergang klappt die Seite
 * hart auf dunkel um, waehrend das Bild noch fliegt.
 *
 * Bewegt wird die Deckung und nicht die Farbe: ein Farbuebergang ueber die
 * ganze Fensterflaeche zeichnet jedes Bild neu, statt auf dem Compositor zu
 * laufen, und genau das ruckelt auf einem schwachen Geraet. Das Ergebnis ist
 * dasselbe — nachgemessen als Bildschirmfoto der offenen Lupe: alle vier
 * Ecken srgb(54, 50, 49), vorher wie nachher. */
.lupe::backdrop {
  background-color: rgba(26, 22, 20, 0.88);
  opacity: 0;
  transition: opacity 0.24s ease;
}

.lupe.zeigt::backdrop {
  opacity: 1;
}

/* Zwei Zeilen: die Buehne nimmt allen Platz, den die Unterschrift uebrig
 * laesst. Sie ist damit hoch bemessen, und erst dadurch greifen die
 * `max-height: 100%` der beiden Bilder darin.
 *
 * `--rand` schreibt `js/lupe.js` an den Dialog; es ist dieselbe Zahl, die die
 * Rechnung dort als `RAND` von der Fensterhoehe abzieht (24 px). Sie steht
 * hier nicht ein zweites Mal, sondern kommt von dort — der Wert hinter dem
 * Komma faengt nur den Fall, dass das Modul gar nicht gelaufen ist. Ohne
 * diesen Rand stiesse die Unterschrift an die untere Schirmkante. */
.lupe-rahmen {
  display: grid;
  grid-template-rows: 1fr auto;
  justify-items: center;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding-block: var(--rand, 24px);
  margin: 0;
}

.lupe-buehne {
  position: relative;
  width: 100%;
  height: 100%;
}

/* `inset: 0` mit `margin: auto` haelt beide Ebenen in der Mitte der Buehne —
 * mit der Groesse, die `js/lupe.js` anschreibt, und ohne sie mit der, die
 * `max-width` und `max-height` uebrig lassen. Das ist die Auffanglinie fuer
 * den Fall, dass die Rechnung nichts geliefert hat. */
.lupe-bild,
.lupe-ausschnitt {
  position: absolute;
  inset: 0;
  margin: auto;
  display: block;
  max-width: 100%;
  max-height: 100%;
  border-radius: 8px;
  transform-origin: 50% 50%;
}

.lupe-bild {
  object-fit: contain;
  opacity: 0;
  transition:
    transform var(--flugdauer) cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity var(--flugdauer) ease;
}

.lupe.zeigt .lupe-bild {
  opacity: 1;
}

.lupe-ausschnitt {
  object-fit: cover;
  object-position: center;
  opacity: 1;
  transition: transform var(--flugdauer) cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Nach dem Flug ist die obere Ebene fertig: schlagartig weg, um genau eine
 * Flugdauer verzoegert. Beim Schliessen ist sie ebenso schlagartig wieder da,
 * denn dann faellt die Verzoegerung mit der Klasse weg. */
.lupe.zeigt .lupe-ausschnitt {
  opacity: 0;
  transition:
    transform var(--flugdauer) cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 0s linear var(--flugdauer);
}

/* Weiss auf dem dunklen Grund, und nicht var(--tinte): unter dem Overlay ist
 * das Papier weg. */
.lupe-unterschrift {
  max-width: var(--breite);
  padding: 0 1rem;
  color: #ffffff;
  font-size: 0.9375rem;
  text-align: center;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.lupe.zeigt .lupe-unterschrift {
  opacity: 1;
}

/* --- Ansage, Zusatz, Pin-Angabe ------------------------------------------
 *
 * Die zweite Frage: was mache ich jetzt. Die Ansage ist der eine Satz, den
 * ein Kind wirklich liest; der Zusatz steht immer offen darunter — dort
 * stehen die Ausrichtungsangaben und die Erklaerung des Wortes "Pin".
 */

.ansage {
  margin: 0 0 0.625rem;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.35;
  text-wrap: pretty;
}

.zusatz {
  margin: 0 0 0.75rem;
}

.pinangabe {
  margin: 0 0 1.5rem;
  color: var(--grau);
  font-size: 0.875rem;
}

/* --- Aufklapper ----------------------------------------------------------- */

.aufklapper {
  margin: 0 0 1.5rem;
  padding: 0.125rem 0;
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
}

.aufklapper summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0;
  color: var(--orange-text);
  font-size: 1.0625rem;
  font-weight: 700;
  list-style: none;
  cursor: pointer;
}

.aufklapper summary::-webkit-details-marker {
  display: none;
}

.aufklapper summary::before {
  content: "";
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 120ms ease;
}

.aufklapper[open] summary::before {
  transform: rotate(45deg);
}

.aufklapper-inhalt {
  padding-bottom: 0.5rem;
}

.aufklapper-inhalt p:last-child {
  margin-bottom: 0;
}

/* --- Zeichnungen ----------------------------------------------------------
 *
 * Inline im Dokument, nie als <img>: in einem <img> loesen sich die
 * CSS-Variablen nicht auf und die Zeichnung liefe grau aus.
 */

/* Die Breite deckelt das Bild, nicht die Bildunterschrift: eine
 * Bildunterschrift, die in einer schmaleren Spalte umbricht als der Text
 * darueber, sieht aus wie ein Fehler. */
.zeichnung {
  margin: 1rem 0 0;
}

.zeichnung-svg {
  display: block;
  width: 100%;
  max-width: 30rem;
  height: auto;
}

.zeichnung figcaption {
  max-width: 34rem;
  margin-top: 0.375rem;
  color: var(--grau);
  font-size: 0.875rem;
}

/* --- Beruhigung -----------------------------------------------------------
 *
 * Steht auf allen fuenf Pruefpunkten und auf der Vorbereitungsseite und sagt
 * jedes Mal dasselbe: es kann nichts kaputtgehen. Ein Kind, dessen Geraet still
 * bleibt, liest zuerst, dass es nichts zerstoert hat.
 *
 * Die Regel steht hier und nicht in pruefpunkt.css, weil zwei der vier
 * Seitenarten sie zeigen und beide dieses Blatt laden. Zweimal dieselbe Regel
 * waere die zweite Gelegenheit, auseinanderzulaufen — und dann saehe derselbe
 * Satz auf zwei Seiten verschieden aus.
 */

.beruhigung {
  margin: 0 0 1.5rem;
  padding: 0.875rem 1rem;
  border-radius: 10px;
  background: #f6f3f1;
}

/* --- Fortschrittsleiste ---------------------------------------------------
 *
 * 38 Felder, jedes ein Verweis. Erledigt orange, aktuell in --tinte, offen
 * grau. Die fuenf Pruefpunkte sind doppelt so breit und magenta; erreichte
 * sind gefuellt, spaetere nur umrandet — so sieht ein Kind, wie weit es bis
 * zur naechsten Hoerprobe noch ist.
 *
 * Die Felder sind selbst die Flex-Kinder. Ein <li> dazwischen wuerde jedes
 * flex-grow an der falschen Stelle wirksam machen; die Breite der Pruefpunkte
 * stuende dann in einer Regel, die nichts tut.
 */

.leiste {
  display: flex;
  gap: 2px;
  margin: 0 -1rem;
  padding: 0.75rem 1rem;
  background: var(--papier);
}

.feld {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: 22px;
  border-radius: 3px;
  background: var(--linie);
  text-decoration: none;
}

.feld--offen {
  background: var(--linie);
}

/* Schon einmal offen gewesen, aber noch nicht erledigt.
 *
 * Nur mit JavaScript, und nur fuer Felder **hinter** dem aktuellen Schritt:
 * davor faerbt der Server ohnehin "erledigt". Ein Kind, das schon bei 20 war
 * und Schritt 5 noch einmal nachschlaegt, sieht so, dass der Weg bis dahin
 * kein neuer ist. Blasses Orange, nicht das volle — "war ich schon" ist eine
 * schwaechere Aussage als "habe ich gebaut". */
.feld--besucht {
  background: #f7d7c2;
}

.feld--erledigt {
  background: var(--orange);
}

.feld--aktuell {
  background: var(--tinte);
}

.feld--pruefpunkt {
  flex-grow: 2;
  border: 2px solid var(--magenta);
  background: transparent;
}

.feld--pruefpunkt.feld--erreicht {
  background: var(--magenta);
}

/* Ein Pruefpunkt, an dem das Kind schon einmal war, ohne dass er von hier aus
 * erreicht waere. Ohne diese Zeile faerbt der transparente Grund darueber,
 * und die fuenf Pruefpunkte waeren die einzigen Luecken im schon gegangenen
 * Weg. Steht nach .feld--pruefpunkt, sonst gewinnt dessen Grund. */
.feld--pruefpunkt.feld--besucht {
  background: #f4d8ea;
}

/* Der Griff ist groesser als der Strich: 22 px hoch waere fuer eine Maus zu
 * wenig, ein hoeheres Feld dagegen ein Balken statt einer Leiste.
 *
 * Am Handy faellt er weg, siehe unten — dort ist die Leiste kein Beruehrziel
 * mehr, und ein unsichtbarer Griff, der 8 px in den Text darueber ragt, faenge
 * dann nur noch Tipper ab, die dem Text galten. */
.feld::after {
  content: "";
  position: absolute;
  inset: -8px 0;
}

/* --- Fuss der Seite -------------------------------------------------------
 *
 * Links der Tastaturhinweis, rechts die Weiter-Taste. Der Zurueck-Verweis
 * daneben ist bewusst leise: er ist fuer das Kind, das gerade gemerkt hat,
 * dass es einen Schritt zu weit ist.
 */

.schrittfuss {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  padding-top: 1rem;
  background: var(--papier);
}

.tastaturhinweis {
  max-width: 24rem;
  margin: 0;
  color: var(--grau);
  font-size: 0.875rem;
}

.tasten {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0 0 0 auto;
}

.taste-zurueck {
  color: var(--grau);
  font-size: 0.9375rem;
  text-decoration: none;
}

.taste-zurueck:hover {
  text-decoration: underline;
}

.taste-weiter {
  display: inline-block;
  padding: 0.625rem 1.25rem;
  border-radius: 999px;
  background: var(--rot);
  color: var(--papier);
  font-size: 1.0625rem;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}

.taste-weiter:hover {
  background: #a91710;
}

/* --- Handy ----------------------------------------------------------------
 *
 * Die Leiste klebt am unteren Rand. Sie steht im Fluss vor dem Fuss, also
 * zieht `bottom: 0` sie vom ersten Bildlauf an nach oben ins Bild und gibt
 * sie erst am Ende wieder frei — dann rutscht der Fuss darueber (z-index).
 */
@media (max-width: 699.98px) {
  .leiste {
    position: sticky;
    bottom: 0;
    z-index: 1;
    gap: 1px;
    padding: 0.625rem 1rem;
    border-top: 1px solid var(--linie);
  }

  /* Und was klebt, muss beim Rollen freigehalten werden.
   *
   * Beim Tabulator rollt der Browser das fokussierte Element an die Unterkante
   * des Ansichtsfensters — und dort klebt die Leiste darueber. `scrollIntoView`
   * weiss von `position: sticky` nichts. Gemessen ohne diese Zeile, bei
   * 375 x 667 auf /bauen/17/: der Schieber der Hoerprobe liegt zu 100 %
   * hinter der Leiste. Ein Kind, das nur die Tastatur hat, steht dann auf
   * einem Knopf, den es nicht sieht — das ist der Fall, den WCAG 2.2
   * SC 2.4.11 ausdruecklich verbietet.
   *
   * Die Zahl ist die Hoehe der Leiste (0,625rem oben + 22px Feld +
   * 0,625rem unten + 1px Strich = 43px) plus 0,5rem Luft fuer den Fokusring
   * (2px Strich mit 2px Versatz). In rem gerechnet, damit sie mitwaechst,
   * wenn die Leiste es tut.
   *
   * Sie gilt fuer alle 44 Seiten, nicht nur fuer die 38 mit Leiste. Ein
   * `html:has(.leiste)` waere genauer — schritt.css laedt jede Seite, kleben
   * tut die Leiste nur auf den Bauschritten —, aber es haengt an einer
   * Auswahlregel, deren Fehlen die ganze Behebung STILL zurueckdreht: die
   * Seite saehe unveraendert aus, nur der Fokus verschwaende wieder hinter der
   * Leiste. Nachgemessen ist ausserdem, dass die weite Fassung mehr kann: auf
   * den sechs Seiten OHNE Leiste sind sonst acht Fokusringe vom unteren
   * Bildschirmrand angeschnitten, mit ihr keiner. Wo keine Leiste klebt,
   * kostet das Polster nichts als etwas Luft unter dem angesprungenen
   * Element. Festgehalten in test/browser.test.mjs ("kein Tabulator-Halt
   * verschwindet hinter der klebenden Leiste").
   */
  html {
    scroll-padding-bottom: calc(1.25rem + 23px + 0.5rem);
  }

  /* Am Handy ist die Leiste eine **Anzeige** und kein Bedienelement.
   *
   * Gemessen ueber CDP mit `Emulation.setDeviceMetricsOverride`, auf
   * /bauen/12/: bei 375 x 812 und bei 375 x 667 ist ein Feld **6,64 px** breit
   * und 22 px hoch, der Mittenabstand betraegt **7,64 px**, und
   * `elementFromPoint` auf dem Mittelpunkt traf **38 von 38** Feldern. Es war
   * also ein Beruehrziel, und zwar eins von 6,64 px — WCAG 2.2 SC 2.5.8 (AA)
   * verlangt 24 x 24 px, und die Spacing-Ausnahme greift nicht: 24-px-Kreise
   * ueberlappen bei 7,64 px Mittenabstand.
   *
   * **In einer Reihe geht es nicht — das ist Arithmetik.** 38 Ziele zu je
   * 24 px brauchen 912 px nebeneinander; ein Handy hat 375. Auch die Ausnahme
   * ueber den Abstand verlangt dieselben 912 px. Ein groesserer `::after`
   * haette nur 38 uebereinanderliegende Kaesten ergeben und den Fehlgriff
   * nicht behoben, sondern verdeckt.
   *
   * **Ueber mehrere Reihen ginge es — das hier ist eine Abwaegung.**
   * Nachgemessen bei 375 x 812 auf /bauen/12/: der Innenraum der Leiste ist
   * **343 px** breit, der Abstand zwischen zwei Feldern 1 px;
   * `floor((343 + 1) / (24 + 1))` = **13** konforme Ziele je Reihe, 38 also in
   * **drei** Reihen. Mit `flex-wrap: wrap`, `gap: 1px` und
   * `min-width/height: 24px` gemessen: 38 von 38 Feldern anfassbar, jedes
   * genau 24 x 24 px — SC 2.5.8 waere erfuellt.
   *
   * Der Preis, ebenso gemessen: die Leiste klebt unten am Bild und waere dann
   * **95 px** hoch statt **43 px** — knapp ein Achtel des Handybildschirms
   * (812 px) statt gut einem Zwanzigstel, dauerhaft weg von dem Text, den ein
   * Kind gerade abarbeitet. Dagegen steht ein Gewinn, den der Absatz unten kleinrechnet:
   * ein gezielter Sprung war hier ohnehin keiner. Deshalb steht Fassung 1 da.
   * Sie ist nicht die einzig moegliche, sondern die gewollte — und die Probe
   * in `test/browser.test.mjs` laesst beide zu; rot wird sie nur bei einem
   * Feld, das anfassbar und kleiner als 24 x 24 px ist.
   *
   * **Und die Bedienung war ohnehin keine.** Eine Fingerkuppe deckt rund 9 mm
   * ab, also gut 34 px: Wer Schritt 12 treffen will, trifft vier bis fuenf
   * Felder gleichzeitig und landet irgendwo. Was hier weggenommen wird, ist
   * kein Sprung zwischen Schritten, sondern ein Zufallsgenerator, der einem
   * Kind seinen Platz nimmt.
   *
   * **Was bleibt**, alles bei 375 px nachgemessen: die Weiter-Taste
   * (279 x 46 px) und die Zurueck-Taste fuer den Schritt davor und dahinter,
   * und "Bauen" in der Kopfzeile fuer die Uebersicht. Dort ist die
   * Weiter-machen-Taste 343 x 46 px, und die fuenf Kapitelverweise sind zwar
   * nur 22 px hoch, stehen aber 173 bis 199 px auseinander — damit greift fuer
   * sie die Spacing-Ausnahme, fuer die Leiste bei 7,64 px nicht.
   *
   * Die Tastatur verliert nichts: `pointer-events` gilt nur fuer Zeiger, und
   * SC 2.5.8 auch. Nachgemessen bei 375 x 812: Feld 5 fokussiert, Enter
   * gedrueckt, die Seite steht danach auf /bauen/5/ — ein echter Tipper auf
   * dieselbe Stelle laesst sie auf /bauen/12/ stehen.
   *
   * Ab 700 px bleibt alles, wie es war — dort ist die Leiste ein
   * Bedienelement. Festgehalten in test/browser.test.mjs ("am Handy ist kein
   * Feld der Leiste ein zu kleines Zeigerziel, am Schirm bleibt sie
   * bedienbar"), in beide Richtungen. */
  .feld {
    pointer-events: none;
  }

  .feld::after {
    content: none;
  }

  .schrittfuss {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .tastaturhinweis {
    max-width: none;
  }

  .tasten {
    margin-left: 0;
    justify-content: space-between;
  }

  .taste-weiter {
    flex: 1 1 auto;
    text-align: center;
  }
}
