/* Kopf, Fuss und Abschnitt.

   NICHT in versatile.css: Solange kein SCSS-Compiler auf dieser Maschine
   laeuft, muesste dort jede Aenderung doppelt gepflegt werden (CLAUDE.md).

   Es stehen hier KEINE Zahlen, die eine Bedeutung haben — nur Properties aus
   Tokens.php und die Rueckfaelle fuer den Fall, dass eine noch nicht erzeugt
   wird. Wer eine Zahl sucht, findet sie im Theme-Formular. */
@layer versatile {

  /* == Die Seite =========================================================== */
  /* DER FUSS STEHT UNTEN (J. S., 16. 9.): Eine kurze Seite liess ihn in der
     Mitte haengen, darunter Weiss. Die Seite ist eine Flex-Spalte mit der
     Fensterhoehe als Mindestmass, `main` nimmt den Rest — der Fuss sitzt
     damit am unteren Rand, und eine lange Seite scrollt wie bisher.

     `svh` und nicht `vh`: Auf dem Handy zaehlt die kleine Fensterhoehe, sonst
     schiebt die Adressleiste den Fuss unter den Rand.

     FLEX, NICHT GRID: `.seite` traegt `cq`, also `container-type: inline-size`,
     und Grid am selben Element bricht in Safari (fallstricke.md). Die
     Flex-Spalte misst nur die Blockachse, die der Container nicht einschliesst
     — gemessen in Chrome, in Safari nachzusehen. */
  .seite {
    min-block-size: 100svh;
    display: flex;
    flex-direction: column;
  }
  .seite > main { flex: 1 0 auto; }

  /* == PROVISORIUM: Punktraster (J. S., 17. 9.) ============================ */
  /* Vier Muster als Klassen, bis das Muster eine EIGENSCHAFT DES AUSSEHENS
     im Theme-Formular ist (Muster · Punktfarbe · Dichte · Teilung, je Stufe,
     aus Tokens.php). Dann fallen diese Klassen weg; `muster:` im Frontmatter
     bleibt. Alles zwischen den beiden Marken ist abloesbar.

     Die Farbe der Punkte ist `--icon` — die Iconfarbe des Aussehens, mit
     currentColor als Rueckfall (Tokens.php). Ein Raster ist eine Zeichnung
     auf der Flaeche, keine Linie; deshalb nicht `--rule`. Der Grund ist
     `--surface`, damit Tag und Nacht mitdrehen.

     Die Zahlen stammen aus dem Farbpaletten-Bogen vom 16. 9.:
       fein   20 % auf 16 px    offen  26 % auf 20 px
       dicht  34 % auf 14 px    grob   36 % auf 24 px
     Zwei versetzte radial-gradients ergeben das Halbtonraster. */
  /* DOPPELT SELEKTIERT, mit Absicht (gemessen 17. 9.): Die Flaechenklasse
     setzt `background` als KURZFORM und liegt in versatile.css, die zuletzt
     geladen wird — bei gleicher Spezifitaet loeschte sie das Muster. Zwei
     Attributselektoren schlagen eine Klasse, ohne !important. */
  [class*="muster--punkte"][class*="muster--punkte"] {
    --muster-farbe: var(--icon, currentColor);
    background-color: var(--surface);
    /* EINE KACHEL MIT ZWEI PUNKTEN, um eine Viertelteilung eingerueckt
       (J. S., 17. 9., „die Punkte sind an den Kanten angeschnitten"): Vorher
       lag ein Punkt genau in der Ecke der Kachel und wurde an jeder Kante
       halbiert. Jetzt sitzen die beiden Punkte bei 25 % und 75 % einer
       doppelt so grossen Kachel, und `background-repeat: round` streckt die
       Kachel so, dass eine ganze Zahl in die Flaeche passt — an keiner
       Kante ein halber Punkt. Der Radius ist ein Anteil der halben Kachel
       (closest-side), er muss unter 25 % bleiben, sonst beruehren sich die
       Punkte an der Kante wieder. */
    background-image:
      radial-gradient(circle closest-side at 25% 25%, var(--muster-farbe) var(--muster-punkt), transparent calc(var(--muster-punkt) + 2%)),
      radial-gradient(circle closest-side at 75% 75%, var(--muster-farbe) var(--muster-punkt), transparent calc(var(--muster-punkt) + 2%));
    /* Die Kachel IST die Teilung (korrigiert 17. 9.): zwei Punkte je Kachel,
       versetzt — wie im Bogen. Vorher war sie doppelt so gross, und die
       Punkte standen doppelt so weit auseinander. */
    background-size: var(--muster-teilung) var(--muster-teilung);
    background-repeat: round;
  }
  /* Punktgroesse in Prozent der HALBEN Kachel; Teilung = Abstand der Punkte. */
  /* Punktgroesse in Prozent von einer VIERTEL Kachel (closest-side eines
     Kreises bei 25 %); 100 % waere ein Punkt, der die Kante beruehrt. Die
     Werte entsprechen dem Bogen vom 16. 9. (dort Prozent von farthest-corner,
     Faktor 2,83): dicht 34 % → 96 %, offen 26 % → 74 %, fein 20 % → 57 %. */
  .muster--punkte-feinst { --muster-punkt: 60%; --muster-teilung: 10px; }
  .muster--punkte-fein   { --muster-punkt: 57%; --muster-teilung: 16px; }
  .muster--punkte-offen  { --muster-punkt: 74%; --muster-teilung: 20px; }
  .muster--punkte-dicht  { --muster-punkt: 96%; --muster-teilung: 14px; }
  .muster--punkte-grob   { --muster-punkt: 96%; --muster-teilung: 24px; }
  /* Text auf einem Raster braucht einen Halt — JE ZEILE ein Grund (J. S.,
     17. 9., nach Lichthof und Wortkaesten): Titel, Untertitel und die
     Absaetze des Fliesstexts laufen inline, der Grund des Aussehens liegt
     darunter, um ein Stueck ausgestellt; `box-decoration-break: clone`
     schliesst jede Zeile fuer sich. Kein zusaetzliches Markup. */
  /* `.halt` statt des Titels selbst (gemessen 17. 9.): Titel und Untertitel
     sind Rasterkinder des Eintrags und damit IMMER Bloecke — `display:
     inline` greift dort nicht, der Grund lief ueber die ganze Zelle. Das
     Template legt auf Musterkacheln ein <span class="halt"> um den Text. */
  /* PADDING, NICHT box-shadow (J. S., 17. 9.): Chrome malt den Schatten des
     zweiten Zeilenfragments NACH dem Text des ersten — die Unterlaengen von
     Zeile 1 lagen unter dem Grund von Zeile 2. Padding gehoert zum
     Hintergrund, und alle Hintergruende eines Inline-Elements liegen vor
     allem Text. Der negative Rand holt den Ausstand links wieder ein. */
  [class*="muster--punkte"] :is(.halt, .eintrag__text p, .eintrag__text li, .abschnitt__titel .halt) {
    display: inline;
    background: var(--surface);
    padding: .08em var(--muster-halt, .22em);
    margin-inline-start: calc(-1 * var(--muster-halt, .22em));
    border-radius: .06em;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }
  /* Inline-Elemente stapeln nicht von selbst — der Eintrag ist ein Grid,
     jedes Teil bleibt in seiner Zeile; der Abstand kommt weiter vom gap. */

  /* GERECHNET (theme/js/muster.js, 17. 9.): Sobald das Skript das Gitter
     kennt, legt es je Zeilenkasten einen Grund, der auf die Zwischenlinien
     der Punkte faellt. Dann faellt der Inline-Grund oben weg, und der Text
     steht ueber den Gruenden (z-index 1); der Kachel-Link (z-index 2) bleibt
     klickbar, die Gruende fangen keinen Klick. */
  .muster--gerechnet { position: relative; }
  .muster--gerechnet :is(.halt, .eintrag__text p, .eintrag__text li, .abschnitt__titel .halt) {
    background: none;
    padding: 0;
    margin-inline-start: 0;
    position: relative;
    z-index: 1;
  }
  .muster__grund {
    position: absolute;
    z-index: 0;
    background: var(--surface);
    pointer-events: none;
  }
  /* == ENDE PROVISORIUM Punktraster ======================================= */

  /* == Der Kopf ============================================================ */
  /* Der Kopf ist selbst ein Container: Ob die Links nebeneinander passen,
     haengt von SEINER Breite ab, nicht von der des Fensters. */
  .kopf {
    container-type: inline-size;
    /* HAFTEND (J. S., 4. 9.). `sticky` und nicht `fixed`: Der Kopf bleibt im
       Fluss und behaelt seinen Platz — `--kopf-hoehe` und die Buehne, die
       damit rechnet (liste.css), stimmen unveraendert weiter. Bei `fixed`
       waere der Kopf aus dem Fluss, der erste Abschnitt ruecke darunter, und
       jede Buehnenhoehe waere um die Kopfhoehe daneben.

       DER GRUND MUSS SEIN (gemessen 4. 9.): Ohne ihn ist der Kopf
       durchsichtig, und beim Scrollen laeuft der Text der Seite durch die
       Menuepunkte. `var(--surface)` und kein fester Wert — der body setzt sie
       auf `--surface-default`, und damit folgt der Kopf dem Nachtmodus von
       selbst.

       z-index 10 reicht: Auf der Seite gibt es nichts Gestapeltes ausser dem
       Schleier eines Buehnenbildes, und der sitzt in seinem eigenen Kontext. */
    position: sticky;
    inset-block-start: 0;
    z-index: 10;
    background: var(--surface);
    /* DIE ICONGROESSE LAEUFT MIT (J. S., 3. 9. abends). Sie springt nicht
       zwischen Stufen, sie waechst — `clamp()` zwischen zwei Stuetzstellen
       mit `cqi` dazwischen, genau die Bauart, die Tokens.php fuer die Schrift
       erzeugt. `cqi` und nicht `vw`, weil ein Icon zur Schrift gehoert und
       Schrift den PLATZ misst, nicht die Seite (CLAUDE.md, „Zwei Achsen").
       Gemessen im Kopf: 17 px bei 390, 24 px bei 768, 26 px ab ~1100.
       Sobald das Theme `--icon-groesse` liefert, gilt sie und diese Rampe
       faellt weg — der Reiter „Icons" ist noch offen. */
    /* `--kopf-icon`, NICHT `--icon` (4. 9.): Tokens.php setzt `--icon` auf
       jeder Flaechenklasse als FARBE. Hier stand dieselbe Property als
       LAENGE — solange `.kopf` keine Flaechenklasse traegt, faellt das nicht
       auf; sobald doch, waere entweder das Icon farblos oder der Burger
       0 px breit. Ein Name, zwei Bedeutungen, und beide still. */
    /* DAS ZEICHEN MISST SICH AN DER MARKE (J. S., 23. 9.): Burger und
       Nachtschalter tragen die Schriftgroesse der Wortmarke — eine Quelle
       statt zweier Rampen, die nebeneinander herlaufen. `--marke-size` steht
       hier als Grundwert und wird von `kopf.marke: gross` ueberschrieben;
       liefert das Theme spaeter `--icon-groesse`, gilt wieder diese.
       GRENZE: im Fuss gilt das nicht — dort setzt `.fuss .wortmarke` ihre
       eigene Groesse und es gibt kein Zeichen daneben. */
    --marke-size: clamp(1.4rem, 3.4cqi, 2rem);
    --kopf-icon: var(--icon-groesse, var(--marke-size));
    /* KEINE KANTE (J. S., 3. 9. abends). Der Kopf steht ohne Strich auf der
       Seite: Was ihn absetzt, ist der Weissraum unter der Marke und die
       Flaeche, die darunter beginnt — nicht eine Linie. Am 3. 9. gab es hier
       nacheinander Weiss auf 30 %, `--line` und deckendes Weiss; entschieden
       ist, dass gar nichts steht. Wer eine Kante zurueckholt, holt eine
       Entscheidung zurueck, nicht nur eine Zeile. */
  }
  .kopf__inhalt {
    /* VOLLE BREITE DES FENSTERS (J. S., 17. 9.): Der Kopf lief bis --page-max
       (1920) und war auf einem breiten Bildschirm schmaler als ein Abschnitt
       in `breite: voll`. Er nimmt jetzt immer das ganze Fenster, Marke ganz
       links, Schalter ganz rechts. */
    max-inline-size: none;
    margin-inline: auto;
    padding-inline: var(--page-margin);
    padding-block: calc(var(--gutter) * .8);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--gutter);
  }
  /* `display: block` ist hier KEIN Geschmack (gemessen 3. 9. abends): Als
     inline-Element haengt ein Link an der GRUNDLINIE seiner Zeile, und die
     Zeile erbt ihre Hoehe von der Laufschrift — nicht von der Rolle, in der
     der Link steht. Die Menuepunkte sassen dadurch 3 px tiefer als Marke und
     Schalter, obwohl `align-items: center` am Kopf steht: Zentriert wurde die
     Zeilenbox, und in der sass der Text unten. Als Block bestimmt der Link
     seine eigene Box, und alle drei Teile haben dieselbe Mitte.

     SPAETER EINSTELLBAR (J. S., 3. 9. abends): Ob der Kopf seine Teile mittig,
     an der Oberkante oder an der Grundlinie ausrichtet, gehoert ins
     Theme-Formular. Heute steht es hier fest auf mittig. */
  .kopf__marke { text-decoration: none; flex: 0 0 auto; display: block; }
  /* Die Marke misst den Platz, nicht das Fenster. Das Seitenverhaeltnis steht
     im viewBox, deshalb genuegt die Breite. */
  .marke {
    display: block;
    inline-size: clamp(6.5rem, 20cqi, 10rem);
    block-size: auto;
    color: var(--on-surface, currentColor);
  }
  /* Die Wortmarke (J. S., 3. 9.): zwei Teile in zwei Schnitten — leicht und
     fett — in der Laufschrift der Seite. Welche Woerter, sagt site.marke im
     Kundenrepo; das Theme kennt nur die Form. Groesse und Laufweite stehen
     hier fest: Eine Marke ist keine Textrolle, sie folgt keiner Leiter. Die
     Schrift kommt ueber --body-font, nicht ueber eine Gattung.
     NICHT .marke: Die gibt es in versatile.css schon als kleine Vorzeile
     (label, Versalien, gedaempft) — ein anderes Ding, anderer Name. */
  .wortmarke {
    display: inline-block;
    font-family: var(--body-font);
    font-size: var(--marke-size, clamp(1.4rem, 3.4cqi, 2rem));
    line-height: 1;
    /* ETWAS OFFENER (J. S., 3. 9. abends): Vorher -.01em, also leicht
       zusammengezogen — das war fuer eine Schrift gedacht, die enger laeuft.
       Neue Haas Unica setzt in dieser Groesse von selbst dicht; ein Hauch
       Luft (.01em, rund 0.3 px bei 32 px) laesst die beiden Woerter
       auseinandertreten, ohne dass die Marke gesperrt wirkt. */
    letter-spacing: .01em;
    white-space: nowrap;
    color: var(--on-surface, currentColor);
  }
  .wortmarke__leicht { font-weight: 200; }
  .wortmarke__stark  { font-weight: 700; }
  /* ETWAS LUFT ZWISCHEN DEN BEIDEN WOERTERN (J. S., 17. 9.): Der leichte und
     der fette Schnitt stossen sonst aneinander — das e laeuft in das L. In
     `em`, damit der Abstand mit der Marke waechst; gilt in Kopf und Fuss. */
  .wortmarke__leicht + .wortmarke__stark { margin-inline-start: .06em; }
  /* Stufenanzeige, Provisorium 17. 9. (kopf.html.twig). */
  .kopf__stufe {
    margin-inline-start: var(--gutter);
    padding: .15em .5em;
    border: 1px solid currentColor;
    border-radius: .3em;
    opacity: .7;
    white-space: nowrap;
  }
  .kopf__rechts {
    display: flex;
    align-items: center;
    gap: calc(var(--gutter) * .6);
    order: 3;
  }
  .kopf__weg ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--gutter);
  }
  /* Die Schrift kommt aus rolle--label (Klasse im Template) — nicht aus
     einzelnen Properties: Eine Klasse traegt die Rolle vollstaendig, auch die
     Neigung. Sonst erbt der Kopf still die kursive Laufschrift. */
  .kopf__weg a {
    display: block;
    /* NAVIGATION IST KEIN LINK IM TEXT (J. S., 29. 9.): Seit der Kopf ein
       Aussehen traegt, gaelte dessen Linkfarbe (bei „Standard“ `akzent`).
       Menue und Marke stehen in der Schriftfarbe des Aussehens. */
    color: var(--on-surface, currentColor);
    text-decoration-color: transparent;
    transition: text-decoration-color var(--motion-base, .2s) var(--motion-ease, ease);
  }
  .kopf__weg a:hover,
  .kopf__weg a[aria-current="page"] { text-decoration-color: currentColor; }

  /* Der Burger — nur, solange die Links nicht nebeneinander passen.

     OHNE KASTEN (3. 9., Abend): Vorher trugen Burger und Nachtschalter je
     einen Rahmen aus `--rule`. Die Property gibt es nicht, der Rueckfall war
     `currentColor` — also zwei schwarze Kaestchen rechts im Kopf, lauter als
     die Marke links. Beide sind jetzt reine Zeichen; die Flaeche zum Tippen
     bleibt (2.4em) und ist nur nicht mehr gezeichnet. Die Rueckmeldung
     kommt aus der Deckkraft, wie bei den Menuepunkten die Unterstreichung. */
  .kopf__burger,
  .nachtschalter {
    display: grid;
    place-items: center;
    /* KNOPF GLEICH ZEICHEN (J. S., 23. 9.): Bis heute war der Knopf das
       Anderthalbfache, damit der Finger mehr Flaeche trifft. Er ist jetzt
       genau so gross wie das SVG — die Marke daneben misst sich auch an
       ihrer Schrift und nicht an einem Kasten darum.
       GRENZE: Damit ist die Tippflaeche so gross wie `--kopf-icon`, auf
       schmalen Stufen rund 32 px. Das ist weniger als die ueblichen 44 px;
       wer das zurueckdreht, setzt hier wieder einen Faktor. */
    inline-size: var(--kopf-icon);
    block-size: var(--kopf-icon);
    padding: 0;
    background: transparent;
    border: 0;
    color: currentColor;
    cursor: pointer;
    transition: opacity var(--motion-base, .2s) var(--motion-ease, ease);
  }
  /* DER BURGER STEHT IN VOLLER FARBE (J. S., 23. 9.): Die 70 Prozent waren
     Zurueckhaltung gegenueber der Marke — sie mischen aber die Schriftfarbe
     mit dem Grund, und was im Formular eingestellt ist, kam nie so heraus.
     Wer ihn leiser will, nimmt ihm die Farbe im Aussehen, nicht die Deckkraft.
     Der Nachtschalter behaelt seine: er ist ein Zustandsknopf, keine Marke. */
  .nachtschalter { opacity: .7; }
  /* DER BURGER BLEIBT BEIM HOVER, WIE ER IST (J. S., 23. 9.): Seine Farbe
     soll sich nicht aendern — sie kommt aus dem Aussehen und wird dort
     entschieden, nicht durch eine Deckkraft hier. Der Nachtschalter behaelt
     seine Rueckmeldung. */
  .nachtschalter:hover { opacity: 1; }
  .kopf__burger .zeichen,
  .nachtschalter .zeichen {
    inline-size: var(--kopf-icon);
    block-size: var(--kopf-icon);
  }
  /* `kopf.nachtschalter: aus` (site.yaml): im Markup, aber nicht zu sehen. */
  .kopf--nachtschalter-aus .nachtschalter { display: none; }
  .burger--auf { display: none; }
  .kopf--offen .burger--zu  { display: none; }
  .kopf--offen .burger--auf { display: initial; }

  /* Schmaler Kopf: Die Links liegen unter der Zeile und klappen auf. */
  /* WEICH AUFKLAPPEN (J. S., 17. 9.): `display: none` laesst sich nicht
     ueberblenden, und eine Hoehe `auto` auch nicht. Deshalb ist das Menue ein
     Raster mit EINER Zeile, die von 0fr auf 1fr laeuft — der Browser rechnet
     die Zielhoehe selbst, es steht keine Zahl im CSS. Chrome 107, Safari
     16, Firefox 66.
     `visibility` haelt die Links im geschlossenen Zustand aus Tabfolge und
     Vorleser; sie schaltet beim Schliessen erst NACH der Fahrt (die
     Verzoegerung), beim Oeffnen sofort.
     `overflow-y: clip` statt `hidden`: schneidet nur senkrecht, der Fokusring
     bleibt seitlich ganz — `hidden` kann die Achsen nicht trennen. */
  .kopf__weg {
    order: 4;
    flex-basis: 100%;
    display: grid;
    grid-template-rows: 0fr;
    visibility: hidden;
    transition: grid-template-rows var(--motion-slow, .35s) var(--motion-ease, ease),
                visibility 0s linear var(--motion-slow, .35s);
  }
  .kopf--offen .kopf__weg {
    grid-template-rows: 1fr;
    visibility: visible;
    transition-delay: 0s;
  }
  .kopf__weg ul {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
    min-block-size: 0;
    overflow-y: clip;
  }

  /* Breiter Kopf: alles in einer Zeile, kein Burger. Die Schwelle misst den
     KOPF, nicht das Fenster — @container, nie @media. */
  @container (min-width: 40rem) {
    .kopf__burger { display: none; }
    .kopf__weg {
      order: 2;
      flex-basis: auto;
      display: block;
      visibility: visible;
      margin-inline-start: auto;
    }
    .kopf__weg ul { flex-direction: row; flex-wrap: wrap; gap: var(--gutter); overflow-y: visible; }
    .kopf__rechts { order: 3; }

    /* NUR BURGER (J. S., 16. 9.): `kopf.menue: burger` in site.yaml. Die
       Links bleiben auch breit hinter dem Knopf — dieselben Regeln wie im
       schmalen Kopf, ausdruecklich wiederholt, weil die Container-Abfrage
       sie sonst aufhebt. Kein zweites Menue, kein zweites Markup. */
    .kopf--burger .kopf__burger { display: grid; }
    .kopf--burger .kopf__weg {
      order: 4;
      flex-basis: 100%;
      display: grid;
      visibility: hidden;
      margin-inline-start: 0;
    }
    .kopf--burger.kopf--offen .kopf__weg { visibility: visible; }
    .kopf--burger .kopf__weg ul { flex-direction: column; flex-wrap: nowrap; gap: 0; overflow-y: clip; }
  }

  /* DAS AUFGEKLAPPTE MENUE (J. S., 17. 9.): Die Eintraege stehen in der
     Groesse der Laufschrift, nicht in `label` — eine Liste zum Tippen, keine
     Beschriftung. Ueber jedem liegt eine feine Linie (`--line`, wie am Fuss),
     ueber dem ersten und unter dem letzten die Luft eines Abschnitts —
     dieselbe Rechnung wie an `.abschnitt__band`, samt dem Viertel mehr unten.

     DIE ROLLE BLEIBT, IHRE WERTE WECHSELN: Der Link traegt `rolle--label`
     (Template). Statt deren Properties zu ueberschreiben, bekommt er hier
     die Werte der Laufschrift in die Tokens der Rolle gelegt. Eine Rolle
     `body` als Klasse gibt es noch nicht (CLAUDE.md, „Offen").

     OHNE `kopf--offen`: Hinge das Aussehen am Zustand, spraengen Schrift,
     Linien und Luft beim Schliessen weg, waehrend das Menue noch faehrt.
     Deshalb gilt es fuer die Klappform immer — und die Zeilenform (breit,
     ohne Burger) nimmt es unten ausdruecklich zurueck.

     Die Luft ist der RAND DER EINTRAEGE, nicht das Polster des Menues: Ein
     Polster liesse sich nicht auf null zusammenfahren. */
  /* Die Farbe aus „Striche darin“ des Kopf-Aussehens (J. S., 29. 9.) — wie die
     Linien im Aufklapper. Leer heisst dort 18 %, also derselbe Wert wie `--line`. */
  .kopf__weg li { border-block-start: 1px solid var(--rule, var(--line, currentColor)); }
  .kopf__weg li:first-child { margin-block-start: var(--band); }
  .kopf__weg li:last-child  { margin-block-end: calc(var(--band) * var(--band-unten, 1.25)); }
  .kopf__weg a {
    --label-font: var(--body-font);
    --label-size: var(--body-size);
    --label-leading: var(--body-leading);
    --label-weight: var(--body-weight, 400);
    --label-tracking: var(--body-tracking, normal);
    --label-style: var(--body-style, normal);
    padding-block: calc(var(--gutter) * .4);
    /* GRUND STATT STRICH (J. S., 17. 9.): In der Klappform ist die ganze
       Zeile das Ziel, nicht das Wort — deshalb keine Unterstreichung, sondern
       ein ganz leichter Grund ueber die Zeile — 5 % der Schriftfarbe, folgt
       Flaeche und Nachtmodus von selbst. EIGENER WERT: Das Theme fuehrt als
       leiseste Stufe `--line-subtle` (10 %), die war hier zu dunkel. Der
       Fokusring des Themes bleibt.
       DER GRUND IST BUENDIG MIT DEN LINIEN, der Text steht in Ruhe in der
       Flucht der Marke. Beim Hover rueckt er um eine halbe Rinne nach rechts
       — das Polster faehrt mit derselben Bewegung wie der Grund ein, damit
       der Text nicht an dessen Kante klebt. */
    text-decoration-line: none;
    padding-inline-start: 0;
    transition: background-color var(--motion-base, .2s) var(--motion-ease, ease),
                padding-inline-start var(--motion-base, .2s) var(--motion-ease, ease);
  }
  .kopf__weg a:hover:not([aria-current="page"]) {
    background-color: color-mix(in oklab, currentColor 5%, transparent);
    padding-inline-start: calc(var(--gutter) * .5);
  }
  /* DIE AKTUELLE SEITE IST NUR HALBFETT (J. S., 29. 9.), nicht der eingefrorene
     Hover: Grund und Einzug gehoeren der Bewegung, der Ort ist ein Zustand.
     Sie reagiert auch nicht auf Hover — wohin man schon ist, dahin fuehrt
     kein Weg. Ueber das Token der Rolle,
     nicht ueber `font-weight` — die Rolle traegt ihr Gewicht selbst. */
  .kopf__weg a[aria-current="page"] { --label-weight: var(--halbfett, 500); }
  /* Die Zeilenform nimmt es zurueck. `inherit` holt den Wert des Themes vom
     Elternelement — `initial` wuerde die Property leeren, und die Rolle fiele
     auf ihren Rueckfall statt auf den eingestellten Wert. */
  @container (min-width: 40rem) {
    .kopf:not(.kopf--burger) .kopf__weg ul { gap: var(--gutter); }
    .kopf:not(.kopf--burger) .kopf__weg li { border-block-start: 0; margin-block: 0; }
    .kopf:not(.kopf--burger) .kopf__weg a {
      --label-font: inherit; --label-size: inherit; --label-leading: inherit;
      --label-weight: inherit; --label-tracking: inherit; --label-style: inherit;
      padding: 0;
      text-decoration-line: underline;
    }
    .kopf:not(.kopf--burger) .kopf__weg a:hover { background-color: transparent; padding-inline-start: 0; }
  }

  /* DIE MARKE EINE STUFE GROESSER (J. S., 16. 9.): `kopf.marke: gross`.
     Dieselbe Bauart wie die Grundgroesse — clamp zwischen zwei Stuetzstellen,
     cqi dazwischen —, nur die Stuetzstellen sind hoeher. Die Zeile gibt ihre
     Hoehe von selbst mit, der Kopf misst sie (partials/kopf.html.twig). */
  .kopf--marke-gross .marke     { inline-size: clamp(9rem, 28cqi, 15rem); }
  .kopf--marke-gross { --marke-size: clamp(2rem, 5cqi, 3rem); }

  /* == Der Abschnitt ======================================================= */
  /* Die Seite hat weder Rand noch Breite — beides setzt der Abschnitt.
     Sonst muesste jedes vollflaechige Bild den Seitenrand mit negativen
     Margins aufheben (ebenen.md, 30. 8.). */
  /* UNTEN MEHR ALS OBEN (J. S., 30. 8. beschlossen, Zahl am 4. 9. gesetzt).
     Optischer Ausgleich, kein Geschmack: Oben fuellen Versalhoehe und
     Oberlaengen die Luecke bis zum Text, unten endet die letzte Zeile auf der
     Grundlinie. Bei gleichem Wert wirkt der untere Abstand deshalb kleiner —
     der Abschnitt sitzt "zu tief" in seiner Flaeche.

     Ein VIERTEL mehr, als Property: Wer es nicht will, setzt `--band-unten: 1`
     und hat wieder symmetrische Abstaende. Der Faktor multipliziert, statt
     einen zweiten Wert zu setzen — sonst verstellt eine Aenderung der Luft
     nur die eine Haelfte, und das Verhaeltnis kippt still.

     GRENZE: `polster-keines` bleibt bei null — nichts mal 1.25 ist nichts,
     und ein Block bis an die Kante soll dort auch bleiben. */
  .abschnitt__band {
    margin-inline: auto;
    padding-inline: var(--page-margin);
    padding-block: var(--band) calc(var(--band) * var(--band-unten, 1.25));
  }
  .abschnitt--inhalt .abschnitt__band { max-inline-size: var(--page-max); }
  .abschnitt--schmal .abschnitt__band { max-inline-size: calc(var(--measure) * 1.5); }
  .abschnitt--voll   .abschnitt__band { max-inline-size: none; }

  /* Ein benanntes Ergebnis, kein freier Wert: kein Innenabstand UND kein
     Rand — der Block geht bis an die Kante (ebenen.md). */
  .abschnitt--polster-keines .abschnitt__band {
    padding-inline: 0;
    padding-block: 0;
    max-inline-size: none;
  }
  /* RINNE STATT SEITENRAND (J. S., 17. 9., der Teppich auf Home): Laeuft ein
     Teppich ueber die volle Breite, soll sein Rand zur Kante so breit sein
     wie die Rinne zwischen den Kacheln — links und rechts die Rinne, oben
     und unten weiterhin das Band. Ein benanntes Ergebnis wie `keines` und
     `eng`, kein freier Wert. */
  .abschnitt--polster-rinne .abschnitt__band {
    padding-inline: var(--gutter);
    max-inline-size: none;
  }
  .abschnitt--polster-eng .abschnitt__band {
    padding-block: calc(var(--band) * .5)
                   calc(var(--band) * .5 * var(--band-unten, 1.25));
  }
  /* OBEN KEINES · OBEN RINNE (J. S., 17. 9., Provisorium bis zur Blockphase):
     Der Teppich direkt unter dem Kopf braucht oben nicht das ganze Band —
     `rinne` gibt ihm oben denselben Rand wie seitlich und zwischen den
     Kacheln, `keines` gar keinen. Unten und seitlich gilt weiter das Polster.
     GRENZE: nicht fuer Abschnitte mit Titel — der klebte an der Kante.
     Steht NACH den Polstern und mit -start, damit es jedes davon schlaegt. */
  .abschnitt--oben-keines .abschnitt__band { padding-block-start: 0; }
  .abschnitt--oben-rinne  .abschnitt__band { padding-block-start: var(--gutter); }

  .abschnitt__titel,
  .abschnitt__untertitel { margin-block: 0 calc(var(--gutter) * var(--titel-luft, 1)); }
  .abschnitt__titel--mit-zeile { margin-block-end: 0; }
  /* `titel_mittig: xs | s` (abschnitte.html.twig): solange der Bandinhalt
     schmaler ist als die naechste Stufe. Der Container ist `.abschnitt__band`. */
  @container (max-width: 479.98px) {
    .abschnitt--titel-mittig-xs :is(.abschnitt__titel, .abschnitt__untertitel) { text-align: center; }
  }
  @container (max-width: 767.98px) {
    .abschnitt--titel-mittig-s :is(.abschnitt__titel, .abschnitt__untertitel) { text-align: center; }
  }
  /* Der Abstand ZWISCHEN Bloecken gehoert dem Abschnitt, nicht dem Block —
     ein Block kennt seine Nachbarn nicht. */
  .abschnitt__bloecke > * + * { margin-block-start: calc(var(--band) * .5); }
  /* EIN ADRESSBLOCK SCHLIESST AN (J. S., 24. 9.): Zwischen zwei Bloecken steht
     ein halbes Band — nach einer Ueberschrift ist das eine Luecke, kein
     Abstand. Die Anschrift gehoert zum Titel darueber, also traegt sie den
     Zeilenabstand des Fliesstexts.
     HIER und nicht im Block: Die Beziehung zwischen zwei Bloecken entscheidet
     der Abschnitt (ebenen.md) — ein Block kennt seine Nachbarn nicht. */
  .abschnitt__bloecke > * + .liste--kontakt { margin-block-start: var(--flow, 1em); }

  /* DAS RASTER AM ABSCHNITT (J. S., 29. 9.): `spalten:` am Abschnitt, `spannt:`
     am Block (abschnitte.html.twig). Dieselbe Rinne wie die Masonry-Liste,
     damit die Spaltenkanten ueber die Seite hinweg dieselben sind.
     Der Abstand zwischen Bloecken wird hier zur ZEILENluft: Stehen zwei Zellen
     nebeneinander, darf die zweite keinen Rand oben tragen.
     GRENZE: Der Adressblock-Anschluss oben greift im Raster nicht — dort ist
     die Zelle das Kind, nicht der Block.
     `--gutter` und nicht `--rinne` (Befund 29. 9.): `--rinne` entsteht erst an
     `.liste` und ist hier undefiniert — der Spaltenabstand war 0. `--gutter`
     ist ihr Grundwert (Faktor 1), also dieselbe Kante wie in der Liste. */
  .abschnitt--raster .abschnitt__bloecke {
    display: grid;
    grid-template-columns: repeat(var(--abschnitt-spalten, 12), minmax(0, 1fr));
    column-gap: var(--gutter);
    row-gap: calc(var(--band) * .5);
  }
  .abschnitt--raster .abschnitt__bloecke > * { margin-block-start: 0; }
  .abschnitt__zelle {
    --zelle: var(--zelle-xs, var(--abschnitt-spalten, 12));
    grid-column: span min(var(--zelle), var(--abschnitt-spalten, 12));
    min-inline-size: 0;
  }
  @container (min-width: 480px)  { .abschnitt__zelle { --zelle: var(--zelle-s,  var(--zelle-xs, var(--abschnitt-spalten, 12))); } }
  @container (min-width: 768px)  { .abschnitt__zelle { --zelle: var(--zelle-m,  var(--zelle-s,  var(--zelle-xs, var(--abschnitt-spalten, 12)))); } }
  @container (min-width: 1024px) { .abschnitt__zelle { --zelle: var(--zelle-l,  var(--zelle-m,  var(--zelle-s, var(--zelle-xs, var(--abschnitt-spalten, 12))))); } }
  @container (min-width: 1440px) { .abschnitt__zelle { --zelle: var(--zelle-xl, var(--zelle-l,  var(--zelle-m, var(--zelle-s, var(--zelle-xs, var(--abschnitt-spalten, 12)))))); } }

  /* == Der Fuss ============================================================ */
  .fuss {
    border-block-start: 1px solid var(--line, currentColor);
  }
  .fuss__inhalt {
    max-inline-size: var(--page-max);
    margin-inline: auto;
    padding-inline: var(--page-margin);
    padding-block: var(--band);
    display: flex;
    flex-wrap: wrap;
    gap: var(--gutter);
    justify-content: space-between;
    /* Die Bloecke oben ausrichten, nicht mittig: Der Adressblock ist
       mehrzeilig, die anderen einzeilig — mittig haengt das Jahr in der
       Mitte der Adresse und sieht aus wie ein Versehen. */
    align-items: start;
  }
  /* Kein Aussenabstand: Der Abstand zwischen den Bloecken ist die Rinne. */
  .fuss__block { margin: 0; font-style: normal; }
  /* Der Name steht in `meta` (Klasse im Template) und ist damit groesser als
     die Zeilen darunter. `display: block` gibt ihm seine eigene Zeilenhoehe —
     als inline-Element haette er die der Anschrift und saesse zu eng. */
  /* Der Name ist ein <p> in der Laufschrift — die Rollenklasse ist entfallen
     (3. 9. abends). `margin: 0` hebt den Absatzabstand auf; der eine, den es
     hier braucht, steht darunter. */
  .fuss__name { margin: 0 0 .35em; font-weight: 500; max-inline-size: none; }
  /* Die Wortmarke im Fuss (J. S., 17. 9.): dieselbe Form wie im Kopf, aber
     kleiner — dieselbe Bauart, tiefere Stuetzstellen. Sie darf umbrechen: Mit
     dem Zusatz ist sie laenger als im Kopf, und der Fuss hat schmale Spalten. */
  .fuss .wortmarke { font-size: clamp(1.25rem, 2.8cqi, 1.7rem); white-space: normal; }
  /* Als Marke ist der Name groesser als die Zeilen darunter und braucht mehr
     Luft nach unten als der schlichte Name (.35em). */
  .fuss__name--marke { margin-block-end: .8em; }
  .fuss__anschrift { margin: 0; max-inline-size: none; }
  /* Telefon und Mail stehen UNTER der Anschrift, nicht darin (J. S., 3. 9.
     abends): Sie sind eine andere Art von Angabe — anklickbar statt nur
     lesbar. Der Abstand macht das sichtbar, ohne dass es ein zweiter Block
     mit eigener Ueberschrift sein muesste. */
  /* Ein eigener ABSATZ, nicht nur eine Leerzeile (J. S., 3. 9. abends): Der
     Abstand ist die Rinne — dasselbe Mass, das ueberall auf der Seite zwei
     Dinge trennt, die zusammengehoeren, aber nicht dasselbe sind. */
  .fuss__erreichbar { display: block; margin-block-start: var(--gutter); }
  /* Das Jahr steht rechts UND UNTEN BUENDIG (J. S., 3. 9. abends).
     `align-self: end` hebt das `align-items: start` des Fusses fuer diesen
     einen Block auf: Die Adresse beginnt oben, das Zeichen schliesst unten
     ab — beide an derselben Kante wie der Text daneben. */
  .fuss__jahr { margin-inline-start: auto; align-self: end; }
  /* Links im Fuss tragen keinen Strich, bis man sie meint — der Fuss ist
     eine Angabe, kein Fliesstext voller Verweise. */
  .fuss a {
    color: inherit;
    text-decoration-color: transparent;
    transition: text-decoration-color var(--motion-base, .2s) var(--motion-ease, ease);
  }
  .fuss a:hover { text-decoration-color: currentColor; }
}

@layer versatile {
  /* == Tag und Nacht ======================================================= */
  /* Der Schalter zeigt genau EIN Zeichen — das des aktuellen Zustands.
     Gesteuert wird das ueber data-theme-wahl am <html>, nicht ueber Klassen
     am Knopf: So kennt der Knopf den Zustand nicht, er loest ihn nur aus. */
  /* Form und Groesse stehen oben bei .kopf__burger — beide sind dasselbe
     Ding: ein Zeichen ohne Kasten. Hier steht nur, was den Schalter
     unterscheidet. */
  .nachtschalter { flex: 0 0 auto; }
  /* DAS ZEICHEN ZEIGT DEN ZUSTAND (J. S., 3. 9. abends, zweiter Entscheid):
     Am Tag steht die Sonne da, nachts der Mond. Das Zeichen sagt also, WO
     man ist — die Beschriftung sagt, was ein Klick tut („Auf Nachtdarstellung
     wechseln"). Beides zusammen ist eindeutig; das Zeichen allein waere es in
     keiner der beiden Lesarten.
     Der Geraetemodus ist ganz weg; Tag ist die Vorgabe, auch ohne
     JavaScript und ohne gespeicherte Wahl. */
  .zeichen--tag, .zeichen--nacht { display: none; }
  :root[data-theme-wahl="light"] .zeichen--tag,
  :root[data-theme-wahl="dark"] .zeichen--nacht,
  :root:not([data-theme-wahl]) .zeichen--tag { display: initial; }
}

@layer versatile {
  /* == Die Lesebreite ist eine OBERgrenze ================================== */
  /* `max-inline-size: var(--measure)` allein reicht nicht: Ist der Container
     schmaler als das Mass, wird aus der Obergrenze eine Mindestbreite, und
     der Absatz laeuft aus der Seite. Gemessen am 3. 9. bei 390 px — die
     ganze Seite bekam einen waagrechten Ueberlauf und schob den Kopf mit.

     Das gehoert eigentlich in `--measure` selbst; solange kein
     SCSS-Compiler laeuft, steht die Korrektur hier. */
  /* KEIN `:where()` HIER, UND DAS IST DER PUNKT (gemessen 3. 9. abends):
     `versatile.css:220` setzt `p { max-inline-size: var(--measure) }` — ein
     ELEMENTselektor (0-0-1), und die Datei wird ZULETZT geladen (gemessen an
     der Reihenfolge der <link>-Tags, obwohl sie mit hoeherer Prioritaet
     angemeldet ist). Ein `:where(p)` hat Spezifitaet null und verliert
     doppelt: schwaecher UND frueher.

     Die Folge war still: Die Korrektur vom 3. 9. — `min(measure, 100%)` statt
     nur `measure`, gegen den waagrechten Ueberlauf bei 390 px — hat nie
     gewirkt. Sie stand da und wurde ueberschrieben.

     Deshalb steht hier eine Klasse davor. Das hebt die Spezifitaet auf 0-1-1
     und schlaegt den Elementselektor unabhaengig von der Ladereihenfolge. */
  body :where(p) { max-inline-size: min(var(--measure), 100%); }

  /* DER LEAD LAEUFT SCHMALER (J. S., 3. 9. abends).
     `--measure` ist in `ch` gemessen und waechst mit der Schrift mit: Bei der
     groesseren Lead-Groesse sind es dieselben 65 Zeichen, aber deutlich mehr
     Pixel — gemessen 947 px bei 27.5 px Schrift. Ein Vorspann vertraegt
     WENIGER Zeichen je Zeile als ein Fliesstext, nicht dieselben.

     Die Regel gilt der ROLLE, nicht einer Stelle: ueberall, wo `rolle--lead`
     steht, in jedem Block. */
  .rolle--lead, .rolle--lead p {
    max-inline-size: min(var(--measure-lead, 46ch), 100%);
  }
  .abschnitt--schmal .abschnitt__band { max-inline-size: min(calc(var(--measure) * 1.5), 100%); }

  /* Keine Seite darf waagrecht laufen. Ein Ueberlauf ist ein Fehler, kein
     Merkmal — hier faellt er wenigstens nicht dem Besucher auf die Fuesse. */
  body { overflow-x: hidden; }
}

@layer versatile {
  /* == Tastaturnavigation, vorerst aus ===================================== */
  /* EIN SCHALTER, KEINE AENDERUNG AM MARKUP (J. S., 3. 9.): Das Attribut
     `data-tastatur="aus"` am <body> nimmt die Fokusringe weg und legt die
     Tabreihenfolge stumm. Nichts davon ist geloescht — wer das Attribut
     entfernt, hat alles zurueck.

     WAS ES KOSTET, damit es nicht vergessen geht: Ohne Tastaturnavigation ist
     die Seite fuer alle unbedienbar, die keine Maus benutzen, und fuer
     Screenreader. Das ist fuer einen Prototyp vertretbar und vor dem Livegang
     ein Fehler. Der Fokusring selbst ist im Theme geregelt und einstellbar
     (`--focus`, Staerke im Formular) — er ist nicht das Problem, er wird hier
     nur voruebergehend stummgeschaltet. */
  [data-tastatur="aus"] :focus,
  [data-tastatur="aus"] :focus-visible,
  [data-tastatur="aus"] :focus-visible::after {
    outline: none;
  }
}

@layer versatile {
  /* == Die Laufschrift nimmt ihre Laufweite ================================ */
  /* `body` in versatile.css setzt Familie, Groesse, Gewicht, Neigung und Zeile
     — aber kein letter-spacing. Die Property gab es bis zum 3. 9. gar nicht;
     jetzt erzeugt Tokens.php sie, und hier wird sie gelesen.

     WARUM HIER UND NICHT IN versatile.css: Die Datei ist aus scss/ erzeugt,
     und solange kein Compiler auf dieser Maschine laeuft, waere jede Aenderung
     dort doppelt zu pflegen (CLAUDE.md). Sobald der Kompilierweg entschieden
     ist, gehoert diese Regel zurueck zu den uebrigen body-Regeln. */
  body { letter-spacing: var(--body-tracking, 0); }
}
