/* ============================================================================
   GENERIERT - NICHT VON HAND EDITIEREN (#431, Gestalt-Schicht #557)
   Brand: slf
   Quelle (SoT): web-engine/assets/blog.css (geteilte Schicht: Struktur+Rhythmus)
               + web-engine/brands/slf/blog-tokens.css (Token-Bruecke)
               + web-engine/brands/slf/blog-gestalt.css (die Handschrift)
               + web-engine/brands/slf/blog-overrides.css (optional, laedt zuletzt)
   Neu erzeugen: python web-engine/tools/sync_blog_css.py
   Drift-Check:  python web-engine/tools/sync_blog_css.py --check
   Quell-Hash: 2143ed7f6605
   ============================================================================ */

/* slf Token-Bruecke — GENERIERT (#552) aus
   brand-engine bzw. Kunden-Akte: assets/manifest.yaml `colors:`/`fonts:`.
   Neu erzeugen: python web-engine/tools/blog_tokens.py generiere slf --schreiben
   Pruefen:      python web-engine/tools/blog_tokens.py pruefe slf
   Gescoped auf .post-layout, damit nichts in die Site-Styles leckt.
   Der @import oben laedt die Marken-Schriften auch auf ALT-Posts, deren
   eingebackener <head> sie nicht anfordert (#611, ohne Republish). */
@import url('https://fonts.googleapis.com/css2?family=Anton:wght@400;700;800;900&family=Archivo:wght@400;500;600&family=Archivo+Narrow:wght@400;500;700&display=swap');

.post-layout{
  --accent:#ffe11a;
  --accent-dark:#f5c400;
  --accent-soft:rgba(255,225,26,.12);
  --accent-tint:rgba(255,225,26,.2);
  --ink:#15161a;
  --body:#22242b;
  --muted:#22242b;
  --paper:#f4f1e9;
  --rule:rgba(21,22,26,.16);
  --rule-strong:rgba(21,22,26,.34);
  --gutter:24px;
  --font-head:'Anton',sans-serif;
  --font-body:'Archivo',sans-serif;
  --font-mono:'Archivo Narrow',sans-serif;
}

/* ============================================================================
   BLOG.CSS — GETEILTE BLOG-SCHICHT (SoT, web-engine · #431)
   ============================================================================
   Die EINE Wahrheit fuer das Blog-Post-Layout aller Brand-Sites (Blueprint #422,
   auf Seonar bewiesen). Die Engine (seo-engine/engine/publish.py) emittiert das
   Markup brand-agnostisch; diese Datei ist die Web-Schicht dazu.

   VERTEILUNG: Sites halten GENERIERTE Kopien (<Site>/assets/blog.css) =
   Header + Brand-Token-Bruecke (web-engine/brands/<slug>/blog-tokens.css) + diese Datei.
     Neu erzeugen: python web-engine/tools/sync_blog_css.py
     Drift-Check:  python web-engine/tools/sync_blog_css.py --check

   TOKEN-VERTRAG (was diese Schicht von der Site erwartet — nativ oder via Bruecke,
   Bruecke gescoped auf .post-layout, damit nichts in die Site-Styles leckt):
     Farben:  --accent --accent-dark --accent-soft(Tint-Hintergrund!) --accent-tint
              --ink --body --muted --paper --rule --rule-strong
     Fonts:   --font-head --font-body --font-mono
     Layout:  --gutter
   ============================================================================ */

/* ============================================================================
   ARTIKEL-BASIS-TYPO (#431 aus dem Post-Inline-<style> des Seonar-Blueprints gehoben)
   Die Grund-Typografie des Engine-Markups (build_article_html): Hero/Meta/Titel/Lead
   + Body-Fluss (p/h2/a/Listen/blockquote) + Doktrin-Elemente Pull-Quote ([!PULL]) und
   MERKEN-Box ([!MERKEN]). Vorher trug jeder Post sie im eigenen <style>-Block (Donor-
   Vererbung) — neue Brands hatten sie damit NICHT. Seonar-Alt-Posts tragen sie noch
   doppelt inline (identische Werte, harmlos; Entschlackung = spaeterer Republish).
   ============================================================================ */
.article__hero{padding:40px 0 48px;text-align:left}
/* #559 LESBARKEITS-REGEL DIESER SCHICHT (Wurzel-Fix, gemessen ueber alle 11):
   Die geteilte Schicht faerbt TEXT nie mit einer Signal- oder Dekor-Farbe der Marke.
   Sie nutzt ausschliesslich ink-abgeleitete Toene (ink, body, oder eine Mischung aus
   ink und paper) — die sind per Definition lesbar, weil ink die Textfarbe AUF paper ist.
   Wer einen anderen Ton will, deklariert ihn in web-engine/brands/<slug>/blog-gestalt.css.

   WARUM (der Befund, blog_tokens.py status vor diesem Fix): --accent ist ein SIGNAL,
   keine Textfarbe. Als Textfarbe auf paper gemessen: slf 1.16 · hypnosolve 1.53 ·
   mentivo 2.65 · seonar 3.77 — vier von elf Brands mit unlesbaren Fliesstext-Links.
   Dasselbe bei --muted (dekorativer Zweitton der Marke, als Meta-Text benutzt):
   hypnosolve 1.85 · trovely 3.15 · mut-im-kopf 3.63 · reset-box 3.65 · signex 4.44.
   Das ist kein Ton-Problem einzelner Marken, sondern eine falsche Zuweisung in DIESER
   Datei: sie hat Farben, die fuer Flaechen und Akzente gedacht sind, an Text gehaengt.

   NICHT gemacht (bewusst): die Toene der Marken nachdunkeln. blog_tokens.py haelt seit
   #552 fest, dass der Generator KEINEN Design-Entscheid ersetzt — reicht ein Ton nicht,
   entscheidet Esteban den Ton. Diese Regel hier faellt keinen Ton-Entscheid, sie nimmt
   nur die Dekor-Farben aus der Text-Rolle heraus. --muted bleibt verfuegbar.

   #560 — DIE REGEL WAR NUR ZUR HAELFTE DURCHGEZOGEN. #559 hat fuenf Stellen entfaerbt
   und SIEBEN weitere stehen lassen. Nicht aus Nachlaessigkeit, sondern weil die Suche am
   Fliesstext hing: die uebrigen sassen im Abschluss-CTA, in der rechten Sidebar und in
   den Bausteinen (Stat-Zahl, Checklisten-Haken) — Stellen, die im gerade betrachteten
   Post gar nicht vorkamen. Gemessen ueber alle 11 Brands (Token-Ebene, jedes Paar
   gerechnet statt nur die im Post sichtbaren): 23 Verstoesse ueber 6 Brands.
   Die schlimmste war der Such-Knopf: WEISSER Pfeil auf Signalflaeche, hartkodiert #fff.
   Er faellt bei SECHS Brands durch (slf 1.31 · runthesim 1.49 · hypnosolve 1.65 ·
   signalfabrik 2.73 · mentivo 3.06 · seonar 3.77) und verletzt bei slf zusaetzlich eine
   ausdrueckliche Marken-Regel (konzept.md: «Gelb + Weiss verboten»).
   LEHRE, die ueber diese Datei hinausgeht: eine Regel gilt erst, wenn sie an der VOLLEN
   Grundgesamtheit ihrer Stellen durchgezogen ist — nicht an denen, die man gerade sieht.
   Das ist Apex-Prinzip 4a (volle Grundgesamtheit) auf eine Design-Regel angewandt.

   Ab #560 gilt fuer die geteilte Schicht zusaetzlich: auch eine FLAECHE, die Text traegt,
   wird aus ink/paper gebaut, nicht aus dem Akzent. Der Akzent bleibt fuer Kanten, Raender,
   Flaechen OHNE Text und die Brand-Gestalt. */
.article__meta{display:flex;gap:16px;flex-wrap:wrap;font-family:var(--font-mono);font-size:11px;letter-spacing:0.16em;text-transform:uppercase;color:color-mix(in srgb, var(--ink) 74%, var(--paper));font-weight:600;margin-bottom:32px}
/* Der hervorgehobene Teil der Meta-Zeile (Kategorie): strukturell staerker, nicht farbig.
   Die Farbe ist Gestalt — z.B. traegt runthesim hier sein Magenta (#559). */
.article__meta .accent{color:var(--ink);font-weight:700}
.article__title{font-family:var(--font-head);font-weight:900;font-size:clamp(36px,5vw,56px);line-height:1.05;letter-spacing:-0.03em;color:var(--ink);-webkit-text-stroke:0.4px var(--ink);margin-bottom:32px;max-width:24ch}
.article__lead{font-family:var(--font-body);font-weight:400;font-size:19px;line-height:1.6;color:var(--body);max-width:58ch;border-left:3px solid var(--accent);padding-left:18px}
.article__body{padding:40px 0 96px;font-family:var(--font-body);font-size:18px;line-height:1.75;color:var(--body)}
/* #611 (Esteban-Befund M2, bei SIGNEX/Seonar/trovely/esteban wortgleich «zu viel Whitespace
   zwischen Kurzfassung und erstem Uebertitel»): der Abstand war eine ADDITION, die niemand so
   entschieden hat. Das Padding des Koerpers (32px) und der obere Rand der ersten Ueberschrift
   (64px) stossen aneinander, ohne zu kollabieren — dazwischen liegt Padding, und Padding
   unterbricht das Margin-Collapsing. Gemessen also 96px, wo 40px gemeint waren.
   Der Reset gilt fuer JEDES erste Kind, nicht nur h2: faengt denselben Fall, wenn der Post mit
   einer Merken-Box, einer Stat-Karte oder einem Absatz beginnt.

   WARUM ER AUF `.post-layout .article__body` STEHT UND NICHT AUF `.article__body` (Nachbesserung #611):
   Als `.article__body > *:first-child` kompiliert der Reset zu Spezifitaet (0,2,0) — und JEDE
   Handschrift-Regel schlaegt ihn: `.post-layout .article__body element` ergibt (0,2,1), `.post-layout .article__body .klasse`
   ergibt (0,3,0), und bei Gleichstand gewinnt die Handschrift ohnehin, weil sie spaeter
   laedt. Gemessen wirkte der Reset darum bei 3 von 11 Marken und bei 8 nicht; genau die
   acht, bei denen Esteban den Weissraum bemaengelt hat.
   Auf `.post-layout .article__body` sind es (0,3,0) — die zusaetzliche Pseudoklasse `:first-child` zaehlt wie
   eine Klasse — und er schlaegt `.post-layout .article__body element` (0,2,1).

   ZWISCHENSTAND, DER GENAU DAS BEWEIST, warum man am Blatt misst und nicht im Kopf rechnet:
   der erste Anlauf schrieb `.post-layout .post-layout .article__body > *:first-child`, in der Absicht, die Spezifitaet
   noch weiter zu heben. Das war falsch: `.post-layout .article__body` ENTHAELT `.post-layout` bereits (es loest zu
   `.post-layout .article__body` auf), die Regel verlangte also ZWEI verschachtelte
   `.post-layout` und matchte in keinem einzigen Post. Der Reset war damit fuer alle elf
   Marken tot, und M2 war zurueck — ohne dass irgendein Gate rot geworden waere. Gefunden hat
   es der signalfabrik-Strang, per Laufzeit-Injektion gegengeprueft (mit Reset 40px, ohne
   88px). Eine hoehere Spezifitaet nuetzt nichts, wenn der Selektor nichts trifft.

   Das ist bewusst die EINZIGE Stelle, an der die Basis die Handschrift ueberstimmt, und sie
   ist es zu Recht: dass das erste Element im Fliesstext-Bereich seinen oberen Rand auf das
   Container-Padding addiert, ist keine Gestaltungs-Entscheidung, die eine Marke treffen
   wollen koennte — es ist immer falsch, in jeder Marke, auf jedem Seitentyp. Alles andere am
   Rhythmus (wie WEIT die Ueberschriften atmen) bleibt Sache der Handschrift; sie kann es
   ueber `gestalt_abweichungen:` sogar deklariert abweichend halten. */
.post-layout .article__body > *:first-child{margin-top:0}
/* #611 (derselbe Befund, zweite Haelfte — Seonar nennt ihn MITTEN im Text, an zwei
   Zwischentiteln): 64px oberer Rand bei 32px Schriftgrad sind das Doppelte dessen, was der
   Rhythmus traegt. Zwischen Absatz und Ueberschrift kollabieren die Raender zu max(24, 64),
   der Leser sieht also 64px Leere und verliert den Zusammenhang zum Abschnitt darueber.
   48px = 1.5x Schriftgrad; die Ueberschrift bleibt klar abgesetzt (20px darunter), ohne dass
   der Text in Inseln zerfaellt. */
.article__body h2{font-family:var(--font-head);font-weight:900;font-size:32px;line-height:1.15;letter-spacing:-0.025em;color:var(--ink);-webkit-text-stroke:0.35px var(--ink);margin:48px 0 20px}
.article__body p{margin-bottom:24px}
.article__body strong{color:var(--ink);font-weight:700}
/* #557: `text-decoration:none` ist hier PFLICHT, nicht Geschmack. Diese Schicht zeichnet die
   Link-Linie selbst als `border-bottom` (damit sie in Akzentfarbe und Staerke steuerbar ist);
   die Site-Unterstreichung kam ungefragt dazu -> gemessen ZWEI Linien unter jedem Fliesstext-
   Link bei 8 von 11 Brands. Eine Linie, und zwar die deklarierte. */
/* #559: KEINE Farbe hier (Lesbarkeits-Regel oben). Der Link ist strukturell erkennbar —
   staerkeres Gewicht + eine deklarierte Linie in der eigenen Textfarbe. Die Handschrift
   (Akzent-Unterstreichung, Markierung, Ink-auf-Gelb) kommt aus der Brand-Gestalt. */
/* #611: die Kurzfassung gehoert MIT in die Link-Rolle. Der Lead sitzt im Artikel-Kopf, also
   ausserhalb des Fliesstext-Bereichs, und war damit von KEINER Schicht gedeckt: weder von der
   Basis (die auf `.article__body`, also den Koerper, zielt) noch von den Handschriften (die dieselbe
   Grenze erben). Gemessen am signalfabrik-Blatt ueber alle vier Posts: der Link in der
   Kurzfassung fiel auf die nackte Browser-/Site-Unterstreichung zurueck, waehrend derselbe
   Link zwei Absaetze weiter unten die Marken-Linie trug. Das ist Estebans M7-Befund im
   Wortlaut — «der Link ist eine andere Farbe wie normalerweise, diese Unterschreibung» —, und
   er betraf ALLE Marken, nicht nur die eine, an der er ihn gesehen hat.
   `.article__lead` ist typ-eigenes Schalen-Markup (eine Landing-Page hat keine Kurzfassung);
   ein eigener Platzhalter dafuer waere Vorrat, solange es genau einen Seitentyp mit Lead gibt
   (Apex Prinzip 1). Kommt der zweite, wird daraus ein `@lead`. */
.article__body a, .post-layout .article__lead a{color:inherit;font-weight:600;text-decoration:none;border-bottom:1px solid color-mix(in srgb, currentColor 42%, transparent);transition:border-color .2s}
.article__body a:hover, .post-layout .article__lead a:hover{border-bottom-color:currentColor}
.article__body ul, .article__body ol{margin:0 0 24px 24px;padding:0}
.article__body ul li, .article__body ol li{padding-left:8px;margin-bottom:8px}
.article__body ul{list-style:disc}
.article__body ol{list-style:decimal}
.article__body blockquote{margin:32px 0;padding:24px 28px;background:var(--accent-soft);border-left:3px solid var(--accent);font-style:italic;font-size:17px;line-height:1.6}
.article__body blockquote p:last-child{margin-bottom:0}
/* Pull-Quote ([!PULL], Doktrin) — #559: Farbe raus (Lesbarkeits-Regel oben).
   accent-dark stand hier als Textfarbe: slf 1.46 auf Creme, praktisch unlesbar.
   ink ist der strukturelle Default; die Handschrift kommt aus der Brand-Gestalt. */
.post-pull{font-family:var(--font-head);font-weight:900;font-size:26px;line-height:1.3;letter-spacing:-0.02em;color:var(--ink);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:28px 0;margin:40px 0;text-align:center}

/* ----------------------------------------------------------------------------
   MERKEN-Box ([!MERKEN], Doktrin) — STRUKTUR + RHYTHMUS, BEWUSST KEIN LOOK (#557)
   ----------------------------------------------------------------------------
   ESTEBAN-DIREKTIVE #557: jede Brand bekommt eine EIGENE, dedizierte Gestalt —
   kein geteilter Look, auch kein Katalog zum Auswaehlen. Begruendung: solange die
   geteilte Schicht einen Default-Look liefert, sieht jede Brand ohne eigene Gestalt
   gleich aus, und genau das war der #552-Befund («alle sehen gleich aus»).
   Darum steht hier nur noch, was die Box zum Element macht:
     - position:relative  -> Anker fuer ein evtl. absolut gesetztes Etikett
     - content:var(--label-merken) -> DASS ein Etikett moeglich ist; der TEXT ist
       brand-eigen (und damit auch sprach-faehig, D5). Ist die Variable nicht
       deklariert, wird gar kein Etikett erzeugt — ein lautes, sichtbares Fehlen
       statt eines stillen deutschen Defaults auf einer englischen Lane.
     - margin-bottom:0 am letzten Absatz -> Lesefluss
   Flaeche, Kante, Radius, Polsterung, Typografie und die Etikett-Gestalt leben in
   web-engine/brands/<slug>/blog-gestalt.css.
   Waechter: python web-engine/tools/blog_gestalt.py status
   ---------------------------------------------------------------------------- */
.post-highlight{position:relative;margin:36px 0}
.post-highlight::before{content:var(--label-merken)}
.post-highlight p{margin-bottom:0}
@media(max-width:900px){
  .article__hero{padding:48px 0 32px}
  .article__body{padding:16px 0 64px;font-size:17px}
  .article__body h2{font-size:26px;margin:48px 0 16px}
  .post-pull{font-size:21px}
}

/* ============================================================================
   BLOG-MERKEN-BOX (#419 als Float-Randnotiz; #422 zurück auf VOLLE BREITE, Esteban)
   Die [!MERKEN]-Box läuft im Lesefluss, volle Breite, links. Der #419-Float-Aside quetschte
   den Body rechts daneben und wirkte "nach rechts geschoben" (Esteban #422).
   Hier NUR Rhythmus + die NEUTRALISIERTE Alt-Klasse .post-highlight--aside (bestehende Posts
   tragen --aside noch im HTML -> so rendern auch sie voll-breit statt gefloatet).
   #557: die Polsterung ist von hier weg — sie ist Gestalt, nicht Rhythmus, und gehoert in
   web-engine/brands/<slug>/blog-gestalt.css (sonst haette eine Brand ihre eigene Polsterung
   gegen einen geteilten Wert durchsetzen muessen).
   ============================================================================ */
.article__body .post-highlight{clear:both;margin:36px 0}
.article__body .post-highlight--aside{float:none;width:auto;max-width:none;margin:36px 0}

/* Blog-Hero-Cover (#419, t-0609): brand-Cover als Banner oben im Artikel (zugleich og:image) */
/* #552: KEIN aspect-ratio hier. Die Zahl 1200/630 war eine KOPIE des OG-Formats und wurde
   falsch, als das Muster-System (#526) Titelbilder in 1536x1024 zu liefern begann — object-fit
   ist per Default `fill`, also wurde jedes Cover ~27% in die Breite gestreckt (alle 11 Brands,
   jeder Post). Ein Format gehoert NICHT in die CSS: `width:100%` + `height:auto` uebernimmt das
   echte Verhaeltnis der Datei, welches Format auch immer kommt (Apex Prinzip 3, eine Wahrheit).
   Gegen Layout-Sprung liefert publish.py die ECHTEN Masse als width/height-Attribute mit.
   object-fit:cover bleibt als Netz, falls eine Site-Regel doch einmal eine Hoehe erzwingt. */
.article__cover{width:100%;height:auto;object-fit:cover;border-radius:12px;border:1px solid var(--rule);margin-bottom:36px;display:block}

/* ============================================================================
   BLOG-GRAFIKEN (#419, t-0609) — brand-stilige In-Content-Visuals (grafik.py)
   split-bar = SVG (Proportion); stat + checkliste = HTML (Text bleibt KI-extrahierbar).
   ============================================================================ */
.article__body .post-figure{clear:both;margin:40px 0}
.article__body .post-figure svg{border:1px solid var(--rule,#e2e8f0);border-radius:10px;background:var(--paper,#fff);padding:24px 26px}
.article__body .post-figure figcaption{margin-top:12px;font-size:13px;line-height:1.55;color:color-mix(in srgb, var(--ink) 74%, var(--paper));font-style:italic}
/* stat-card: grosse Zahl + Kontext + Quelle */
.article__body .post-stat{display:grid;grid-template-columns:auto 1fr;gap:24px;align-items:center;border:1px solid var(--rule);border-left:4px solid var(--accent);border-radius:0 10px 10px 0;background:var(--accent-soft);padding:24px 28px}
/* #560 Lesbarkeits-Regel: accent-dark raus. Die Zahl ist der groesste Text des ganzen
   Bausteins; als Signalfarbe gemessen slf 1.46 und hypnosolve 1.72 auf ihrem Papier.
   Wirkung kommt hier aus GROESSE und Gewicht, nicht aus Farbe — und wer die Zahl farbig
   will, faerbt sie in seiner blog-gestalt.css mit einem Ton, den er gemessen hat. */
.article__body .post-stat__num{font-family:var(--font-head);font-weight:900;font-size:clamp(40px,6vw,60px);line-height:1;letter-spacing:-0.03em;color:var(--ink)}
.article__body .post-stat__label{font-weight:700;color:var(--ink);margin:0 0 6px}
.article__body .post-stat__ctx{font-size:15px;line-height:1.55;color:var(--body);margin:0}
.article__body .post-stat__src{display:block;margin-top:10px;font-family:var(--font-mono);font-size:11px;letter-spacing:0.04em;color:color-mix(in srgb, var(--ink) 74%, var(--paper))}
.article__body .post-stat figcaption{grid-column:1 / -1}
/* branded Checkliste: Akzent-Haken statt Bullet */
.article__body .post-checkliste{border:1px solid var(--rule);border-radius:10px;background:var(--paper);padding:24px 28px}
.article__body .post-checkliste__titel{font-family:var(--font-head);font-weight:900;font-size:19px;color:var(--ink);margin:0 0 14px}
.article__body .post-checkliste__list{list-style:none;margin:0;padding:0}
.article__body .post-checkliste__list li{position:relative;padding:9px 0 9px 32px;border-top:1px solid var(--rule);font-size:16px;line-height:1.55;color:var(--body)}
.article__body .post-checkliste__list li:first-child{border-top:none}
/* #560: der Haken ist ein Glyph, also Text — er faellt unter dieselbe Regel (slf 1.16,
   hypnosolve 1.53, mentivo 2.65). Ein Haken, den man nicht sieht, erfuellt seinen Zweck
   nicht; die farbige Fassung gehoert in die Brand-Gestalt. */
.article__body .post-checkliste__list li::before{content:"✓";position:absolute;left:4px;top:9px;color:var(--ink);font-weight:900}
@media(max-width:640px){
  .article__body .post-stat{grid-template-columns:1fr;gap:10px}
}

/* ============================================================================
   BLOG-TABELLE (#422) — harte Regeln statt Inline-Style-Zufall.
   Kopfzellen brechen NICHT um (Esteban: "über" landete auf einer eigenen Zeile). Konsistenter
   Rhythmus + Rahmen. Neue Posts sind klassen-basiert (.post-table) -> diese Regeln greifen voll;
   der Content-Auftrag hält Tabellen-Header kurz, damit nowrap auf Desktop nie überläuft.
   ============================================================================ */
.article__body .post-table{width:100%;border-collapse:collapse;margin:36px 0;font-size:16px}
/* #611 (Esteban-Befund M6, RunTheSim woertlich: «die Uebertitel von der Tabelle sind zu wenig
   markant, man checkt gar nicht, was das Uebertitel sind»): der Kopf unterschied sich vom
   Koerper nur durch `font-weight:700` — dasselbe Gewicht, das im Fliesstext jedes `strong`
   traegt. Bei einer Tabelle mit kurzen Zellen ist das kein Unterschied, den ein Auge im
   Ueberfliegen findet.
   Die Auszeichnung ist bewusst STRUKTURELL und farb-frei (Versalien + Sperrung + kraeftigere
   Linie), nicht farbig: Farbe waere Handschrift der Marke, und die Basis-Schicht faerbt seit
   der Lesbarkeits-Regel #559 keinen Text mehr. Dieselbe Auszeichnung, die der Quellen-Block
   schon traegt — ein Rezept, nicht zwei. Eine Marke kann sie in ihrer Handschrift jederzeit
   ueberschreiben. */
.article__body .post-table th{white-space:nowrap;text-align:left;padding:11px 14px;border-bottom:2.5px solid var(--rule-strong);font-family:var(--font-head,inherit);font-size:12.5px;letter-spacing:0.08em;text-transform:uppercase;font-weight:700;color:var(--ink)}
.article__body .post-table td{padding:12px 14px;border-bottom:1px solid var(--rule);vertical-align:top;line-height:1.55}
.article__body .post-table tbody tr:last-child td{border-bottom:none}
@media(max-width:640px){
  .article__body .post-table{font-size:15px}
  .article__body .post-table th{white-space:normal}
}

/* ============================================================================
   BLOG-TYPOGRAFIE + LISTEN (#422) — kein einzelnes Wort allein auf der letzten Zeile.
   Esteban: "immer ein Wort auf der zweiten Zeile, sieht mega unschön aus" = Orphan/Widow.
   text-wrap:pretty bricht Absätze UND Bullets so um, dass die letzte Zeile nie ein Einzelwort
   ist (vererbte Property -> greift auf alle Body-Elemente). Plus: Body-Listen atmen (.post-list).
   ============================================================================ */
.article__body{text-wrap:pretty}
.article__body ul.post-list, .article__body ol.post-list{margin:0 0 28px 22px;padding:0}
/* balance (statt pretty) auf den kurzen Bullets: gleicht die Zeilen gleich lang aus -> nie ein
   Einzelwort auf der letzten Zeile (pretty allein liess "Fach-Jargon." noch orphan stehen). */
.article__body ul.post-list li, .article__body ol.post-list li{margin-bottom:14px;padding-left:6px;line-height:1.65;text-wrap:balance}
.article__body ul.post-list li:last-child, .article__body ol.post-list li:last-child{margin-bottom:0}

/* ============================================================================
   BLOG-LAYOUT 3-SPALTIG + SIDEBAR (#422) — Struktur der letsreachsuccess-Referenz.
   Artikel-Hauptspalte (max ~720px) + linke TOC-Leiste + rechte, sticky Sidebar (Suche +
   Verwandte Beiträge + faktische Betreiber-Info). Engine emittiert das Markup brand-agnostisch
   (publish.build_article_html + blog_sidebar_html); diese Klassen sind die Web-Schicht
   (seit #431 GETEILT: SoT web-engine/assets/blog.css, Kopien pro Site generiert).
   Mobile: Sidebar stapelt UNTER den Artikel.
   ============================================================================ */
/* 3-spaltig (#422, Esteban: rechts war zu viel los): LINKE TOC-Leiste (Navigation) + Artikel (Inhalt) +
   rechte Sidebar (Meta). Klare Hierarchie, beide Leisten sticky. Unter 1080px -> einspaltig, TOC oben. */
/* #552 KRITISCH — `color` als Basis der Scope-Wurzel. Vorher fehlte sie, und damit erbte JEDES
   Element, das blog.css nicht ausdruecklich einfaerbt (TOC, Sidebar-Bloecke, Blockquote,
   Pull-Zitat), die Textfarbe der SITE. Auf dunkel gestalteten Sites ist das ein helles Creme —
   und das landete auf dem hellen --paper des Artikels: gemessenes Kontrastverhaeltnis 1.00 bei
   mentivo (4 Elemente) und reset-box, 1.15 bei signalfabrik. Unsichtbarer Text auf zwei
   Kunden-Sites. Die Token-Bruecken waren dabei korrekt — sie wurden nur von der Vererbung
   umgangen. Eine Scope-Wurzel, die Tokens setzt, muss auch die Basis-Farbe setzen, sonst
   regieren die Tokens nur dort, wo zufaellig eine explizite Regel steht. */
/* #618 KRITISCH — die ANDERE Haelfte desselben Satzes: auch die FLAECHE.
   Der #552-Fix setzte die Tinte (`color:var(--body)`) und liess die Flaeche offen. Damit war
   die Paarung immer noch dem Zufall ueberlassen: die Tinte kam aus der Token-Bruecke, der Grund
   kam von der Spender-Site. Solange beide hell sind, faellt nichts auf. Bei den zwei Marken mit
   DUNKLER Site brach es in beide Richtungen, live gemessen am DOM (#618):
     signalfabrik  --body #0a0d0c (dunkel) auf `body.halle` = linear-gradient(#090c0a …)  -> 1.01
     mentivo       --body #F4EEE2 (hell)   auf `div.blatt`  = #F4EEE2 (die Site malt hell,
                                                              die Bruecke erwartet #2D2D2B)  -> 1.00
   Beide Male stimmten die Token; es fehlte, dass die Schicht ihr eigenes Papier auch AUFTRAEGT.
   Regel ab hier: **wer die Tinte setzt, setzt die Flaeche mit.** Danach ist die Lesbarkeit eine
   Eigenschaft der Blog-Schicht und keine Eigenschaft des Donors mehr — genau das ist der Punkt
   einer geteilten Schicht. Bewacht: `blog_mappe.py` misst gerendert ueber ALLE Marken. */
/* #557: die LESESPALTE hat Vorrang vor den Nebenspalten.
   Vorher standen 220px und 210px FIX. Das ging so lange gut, wie die Schicht die vollen
   1320px bekam — bei einem Donor, der den Artikel in eine engere Huelle wickelt, nicht mehr:
   mentivos `.blatt` ist 1116px breit, also blieben dem Text 461px, ein unlesbares Band.
   Die alte `@media(max-width:900px)`-Weiche griff nie, weil sie das FENSTER misst (1440),
   nicht den verfuegbaren Platz.
   Jetzt bekommt die Mitte ein Minimum und die Nebenspalten geben nach; `min(100%,...)`
   verhindert Ueberlauf, wenn der Platz auch dafuer nicht reicht. Brand-agnostisch: es gilt
   fuer jede Site und jeden kuenftigen Donor, ohne dass jemand eine Zahl nachpflegen muss. */
.post-layout{max-width:1320px;margin:0 auto;padding:0 var(--gutter);display:grid;
  grid-template-columns:minmax(0,220px) minmax(min(100%,600px),1fr) minmax(0,210px);
  column-gap:44px;align-items:start;color:var(--body);background:var(--paper)}
.post-main{min-width:0;max-width:720px}
.post-main .article__hero{padding-top:8px}
.post-main .article__body{padding-bottom:64px}
/* Beide Leisten oben angeheftet (#422, Esteban: passt oben besser) */
/* Sticky-Abstand als TOKEN (#557). Die 96px waren geraten: sie unterstellen, dass die Site
   entweder keinen klebenden Kopf hat oder einen niedrigeren als 96px. Bei hypnosolve ist der
   `header.site-header` selbst sticky und 125px hoch — die Spalte sass damit 29px IM Kopf
   (Esteban: «es verbaut sich oben in die Navigation»).
   Die Marke deklariert ihren Wert in IHRER HANDSCHRIFT (`<brand_home>/gestalt/elemente.css`,
   an `.post-layout`), nicht in `blog-overrides.css` — korrigiert #611. Der Wert haengt an der
   Site-Schale der Marke, nicht am Kanal Blog: eine kuenftige Landing-Page traegt dieselbe
   Navigation und erbt ihn ueber `.post-layout` automatisch mit, waehrend eine Blog-Override-Datei
   ihn nie weitergeben koennte (design-engine/ZIELARCHITEKTUR.md §1b-2). Ohne Deklaration
   bleibt es beim geratenen 96px-Default, und der ist bei keiner gemessenen Marke richtig.
   Faustregel: Hoehe des klebenden Kopfes + ~16px Luft. */
.post-toc{position:sticky;top:var(--blog-sticky-top,96px)}
.blog-sidebar{position:sticky;top:var(--blog-sticky-top,96px);display:flex;flex-direction:column;gap:24px}
/* TOC groesser (primaere Navigation), rechte Sidebar etwas kleiner (#422) */
.post-toc .sidebar-block__title{font-size:12px}
.post-toc .sb-toc a{font-size:15px}   /* #557: padding-left ist raus — es gehoert zum Marker
                                          (Balken/Punkt/Klammer) und damit in die Brand-Gestalt */
.post-toc .sb-toc li{margin-bottom:13px}
.blog-sidebar .sidebar-block__title{font-size:10px}
.blog-sidebar .sb-related a{font-size:13px}
.blog-sidebar .sb-search__form input{font-size:13px;padding:8px 10px}
.blog-sidebar .sb-betreiber__avatar{width:44px;height:44px}
.blog-sidebar .sb-betreiber__id strong{font-size:14px}
.blog-sidebar .sb-betreiber__mail{font-size:12px}
/* ----------------------------------------------------------------------------
   SIDEBAR-TITEL + INHALTSVERZEICHNIS — STRUKTUR + RHYTHMUS, KEIN LOOK (#557)
   ----------------------------------------------------------------------------
   Zweite Anwendung der Gestalt-Trennung (nach der Merken-Box). Estebans Befund: das
   «In diesem Artikel» sah bei allen 11 Brands identisch aus. Schrift, Farbe, Linien,
   Marker und Zustaende (hover/aktiv) leben ab jetzt in
   web-engine/brands/<slug>/blog-gestalt.css; hier bleibt nur, was die Navigation
   funktionieren laesst: Abstaende, Listen-Reset, Groessen-Hierarchie der zwei Spalten.
   ---------------------------------------------------------------------------- */
.sidebar-block__title{margin:0 0 12px}

/* Navigations-Links der beiden Spalten tragen KEINE Text-Unterstreichung (#557, Esteban).
   Das war ein LECK, keine Gestaltung: die Blog-Schicht sagte zur `text-decoration` nichts,
   also entschied die jeweilige Site — gemessen unterstrichen 8 von 11 Brands links UND
   rechts, und die drei sauberen waren es nur zufaellig (ihre Site-CSS schaltet es ab).
   Dieselbe Klasse wie die fehlende Basis-Farbe in #552: was der Blog-Scope nicht
   deklariert, erbt er ungefragt.
   Inhaltsverzeichnis und Sidebar sind NAVIGATION, keine Fliesstext-Links — der Zustand
   (aktiv/hover) wird ueber Farbe, Marker, Kante oder Flaeche gezeigt, das entscheidet die
   Brand-Gestalt. Eine Brand, die hier bewusst eine Linie will, setzt sie dort als
   `border-bottom` (so macht es hypnosolve) und ist damit unabhaengig von der Site. */
.sb-toc a, .blog-sidebar a{text-decoration:none}
/* Suche */
.sb-search__form{display:flex;gap:8px}
.sb-search__form input{flex:1;min-width:0;padding:10px 12px;border:1px solid var(--rule-strong);border-radius:8px;font-family:var(--font-body);font-size:14px;background:var(--paper);color:var(--ink)}
.sb-search__form input:focus{outline:none;border-color:var(--accent)}
/* #560 — der schlimmste Fund der Runde: `background:var(--accent); color:#fff`.
   Ein hartkodiertes Weiss auf einer Flaeche, deren Farbe JEDE Brand selbst bestimmt,
   kann gar nicht verlaesslich lesbar sein. Gemessen faellt es bei SECHS von elf durch
   (slf 1.31 · runthesim 1.49 · hypnosolve 1.65 · signalfabrik 2.73 · mentivo 3.06 ·
   seonar 3.77), und bei slf verletzt es zusaetzlich eine ausdrueckliche Marken-Regel.
   Der Knopf wird deshalb aus dem EIGENEN lesbaren Paar der Marke gebaut: ink-Flaeche,
   paper-Glyph. Dieses Paar ist per Definition lesbar, denn es traegt den Fliesstext.
   Wer den Akzent auf dem Knopf will, deklariert ihn in blog-gestalt.css — dort
   entscheidet ein Mensch, welcher Ton darauf lesbar ist, statt dass diese Datei es raet. */
.sb-search__form button{flex-shrink:0;width:42px;border:none;border-radius:8px;background:var(--ink);color:var(--paper);font-size:18px;font-weight:700;cursor:pointer;transition:opacity .2s}
.sb-search__form button:hover{opacity:0.82}
/* Verwandte Beiträge */
.sb-related ul{list-style:none;margin:0;padding:0}
.sb-related li{margin-bottom:14px;line-height:1.4}
.sb-related li:last-child{margin-bottom:0}
.sb-related a{color:var(--ink);font-weight:600;font-size:14px;border-bottom:1px solid transparent;transition:color .2s,border-color .2s}
/* #560: der Hover faerbte den Text in den Akzent (slf 1.16 · hypnosolve 1.53 · mentivo
   2.65 · seonar 3.77) — ausgerechnet im Moment der Interaktion wurde der Titel unlesbar.
   Jetzt bleibt die Textfarbe und die Linie kommt in der eigenen Farbe dazu. */
.sb-related a:hover{border-bottom-color:currentColor}
/* Betreiber-Info (faktisch, Tool-Frame) */
.sb-betreiber__id{display:flex;align-items:center;gap:12px;margin-bottom:10px;text-decoration:none;color:inherit}
.sb-betreiber__id:hover strong{text-decoration:underline;text-underline-offset:3px}
.sb-betreiber__avatar{width:52px;height:52px;border-radius:50%;object-fit:cover;object-position:center top;flex-shrink:0}
.sb-betreiber__id strong{font-family:var(--font-head);font-weight:900;font-size:15px;color:var(--ink);line-height:1.2}
/* #560: die Mail-Adresse stand im Akzent (slf 1.16 · hypnosolve 1.53 · mentivo 2.65 ·
   seonar 3.77). Eine Kontaktadresse ist die Stelle, an der Unlesbarkeit am teuersten ist.
   Sie erbt jetzt die Textfarbe und bleibt als Link an der Linie erkennbar. */
.sb-betreiber__mail{font-size:13px;color:inherit;font-weight:600;border-bottom:1px solid color-mix(in srgb, currentColor 42%, transparent)}
.sb-betreiber__mail:hover{border-bottom-color:currentColor}
/* Inhaltsverzeichnis (#422): Sprung-Links zu den Kapiteln (wie RunTheSim) */
.sb-toc ul{list-style:none;margin:0;padding:0}
.sb-toc li{margin-bottom:10px;line-height:1.35}
.sb-toc li:last-child{margin-bottom:0}
.sb-toc a{display:block;font-size:13.5px;transition:color .2s,border-color .2s,background-color .2s}
/* Scroll-Spy (#422): aktuell gelesenes Kapitel hervorgehoben */
/* Der AKTIVE Eintrag ist ein Zustand, kein Look: wie er sich zeigt (Farbe, Marker,
   Gewicht, Flaeche), entscheidet die Brand-Gestalt. Hier bleibt nichts. */
/* Sprung-Ziele unter der sticky Nav ausrichten + sanftes Scrollen
   (scroll-behavior steht auch in Site-CSS mancher Brands — doppelt ist harmlos) */
html{scroll-behavior:smooth}
/* #611: die 96 waren eine ZWEITE Kopie des geratenen Sticky-Defaults und folgten dem Token
   nicht. Sobald eine Marke ihren echten Wert setzt (seonar 81px bei 65px Nav-Hoehe), landete
   ein Klick im Inhaltsverzeichnis den Zwischentitel 96px tief statt 16px unter der Nav — die
   Sprungmarke zeigte auf eine Stelle, die es so nicht mehr gab. Zwei Wahrheiten ueber
   denselben Datenpunkt (Apex Prinzip 3); jetzt rechnet die Sprungmarke aus dem Token.
   OHNE Zuschlag: der Token traegt die Luft unter dem Kopf bereits (Faustregel Kopfhoehe +
   ~16px), ein zweiter Zuschlag wuerde sie verdoppeln. Am Blatt gemessen (hypnosolve, Kopf
   122px, Token 165px): mit dem rohen Token landet die Ueberschrift 43px unter der
   Kopf-Unterkante, mit Zuschlag 59px — die erste Zahl ist die gewollte. */
.article__body h2{scroll-margin-top:var(--blog-sticky-top,96px)}
@media(max-width:1080px){
  .post-layout{grid-template-columns:1fr;column-gap:0;max-width:720px}
  .post-main{max-width:none}
  .post-toc{position:static;transform:none;margin-bottom:8px}
  .blog-sidebar{position:static;transform:none;margin-top:56px;padding-top:40px;border-top:1px solid var(--rule)}
}

/* Dieselbe Weiche noch einmal — aber am verfuegbaren PLATZ statt am Fenster (#557).
   Die Media-Query oben misst das Browser-Fenster. Wickelt ein Donor den Artikel in eine
   engere Huelle (mentivo: `.blatt`, 1116px bei 1440px Fenster), feuert sie NIE, und die drei
   Spalten quetschen sich in den Rest: gemessen 145 / 600 / 145 px — Nebenspalten, die zu
   schmal sind, um zu nuetzen.
   `:has(> .post-layout)` haelt den Container-Kontext exakt am Blog-Artikel — kein anderes
   <article> der Site wird beruehrt.

   DREI STUFEN AM VERFUEGBAREN PLATZ (mittlere Stufe NEU #560, Esteban-Entscheid):
     > 1080px      drei Spalten (TOC links · Text · Sidebar rechts)
     950-1080px    ZWEI Spalten (TOC links · Text), Sidebar unter den Artikel
     < 950px       stapeln (TOC oben · Text · Sidebar unten)

   WARUM DIE MITTLERE STUFE (gemessen #560 an mentivo, Playwright, Fenster 1440):
   mentivos Kette ist `.wrap` 1180px minus 2x32px Rand = `.blatt` 1116px, minus dessen
   Innenrand 2x44px+2x1px = **1026px fuer den <article>**. Damit greift die Stapel-Stufe,
   und mentivo war die einzige Brand ohne Spalten. Drei Spalten passen dort ARITHMETISCH
   nicht: 1026 - 48 Innenabstand = 978px, davon mindestens 600px fuer den Text und 88px
   fuer zwei Zwischenraeume — fuer beide Seitenspalten blieben ~145px, exakt der in #557
   gemessene und verworfene Wert (TOC-Eintraege brechen dort auf 4-5 Zeilen).
   Zwei Spalten passen dagegen exakt: 200 + 44 + 734 = 978px, `.post-main` deckelt bei 720px.
   Bewusst brand-agnostisch statt als mentivo-Sonderfall (Esteban #557: Wurzel statt
   Einzelfall) — jeder kuenftige Donor mit engerer Huelle bekommt dasselbe, ohne dass
   jemand eine Zahl nachpflegt.
   Verworfen: mentivos Blatt fuer die Blog-Seite auf ~1400px weiten. Das Blatt ist ein
   bewusstes Gestaltungs-Element der Site; die Blog-Seite waere dann breiter als der Rest.

   Die mittlere Stufe haengt zusaetzlich an `@media (min-width:1081px)`: sie soll NUR den
   Fall «weites Fenster, enge Huelle» treffen. Ist das FENSTER selbst schmal, bleibt es
   beim bisherigen Stapeln (Zeile 287) — das Antwort-Verhalten der uebrigen zehn Brands
   aendert sich dadurch nicht. */
article:has(> .post-layout){container-type:inline-size}

@media (min-width:1081px){
  @container (min-width:950px) and (max-width:1080px){
    .post-layout{grid-template-columns:minmax(0,200px) minmax(min(100%,600px),1fr);column-gap:44px}
    .post-main{max-width:720px}
    /* Die Sidebar wandert unter den Artikel und legt ihre Bloecke NEBENEINANDER —
       als schmale Saeule waere sie auf ~978px Breite ein einsamer Streifen. */
    .blog-sidebar{
      grid-column:1 / -1;
      position:static;transform:none;
      flex-direction:row;flex-wrap:wrap;align-items:flex-start;gap:32px;
      margin-top:56px;padding-top:40px;border-top:1px solid var(--rule);
    }
    .blog-sidebar > .sidebar-block{flex:1 1 240px;min-width:0}
  }
}

@container (max-width:949.98px){
  .post-layout{grid-template-columns:1fr;column-gap:0;max-width:720px}
  .post-main{max-width:none}
  .post-toc{position:static;transform:none;margin-bottom:8px}
  .blog-sidebar{position:static;transform:none;margin-top:56px;padding-top:40px;border-top:1px solid var(--rule)}
}

/* Abschluss-CTA ([!CTA]-Block der Engine, .post-cta) — #514/E4: war NIRGENDS definiert,
   rendert sonst als nackter kleiner Absatz. Token-basiert (Brand-Farben via blog-tokens.css). */
/* #611 (Esteban-Befund M2, Seonar: «zwischen Quellen und Call to Action ist zu viel Abstand,
   der CTA kann ein bisschen hoeher»): 56px oben trennten den Abschluss vom Text, obwohl der
   Quellen-Block darueber schon eine Trennlinie plus 44px Eigenabstand mitbringt. 40px. */
.post-cta{margin:40px 0 8px;padding:28px 32px;background:var(--accent-tint,rgba(0,0,0,0.04));border:1px solid var(--accent,#0a0a0a);border-left:6px solid var(--accent,#0a0a0a);font-family:var(--font-head,inherit);font-weight:700;font-size:20px;line-height:1.5;color:var(--ink,inherit)}
/* #560: der Quellen-Block war in DIESER Datei ueberhaupt nicht deklariert — also entschied die
   jeweilige Site ueber seine Textfarbe. Genau die Leck-Klasse t-1106 («was der Blog-Scope nicht
   deklariert, erbt er ungefragt»), diesmal beim vierten Vorkommen: bei reset-box gemessen 3.41,
   unter der Schwelle. Er bekommt jetzt denselben ink-abgeleiteten Ton wie die Meta-Zeile.
   NACHTRAG im selben Lauf: mit `.article__body .post-sources` (zwei Klassen) gewann bei
   reset-box weiterhin die Site-Regel — 3.41 blieb stehen. Erst die Scope-Wurzel `.post-layout`
   davor setzt sich durch. Dieselbe Spezifitaets-Stufe, die auch die Brand-Gestalt benutzt.

   #561-BEFUND: genau dieser Nachtrag stand ausserhalb des Kommentars — der Block war eine
   Zeile darueber schon geschlossen, die Prosa danach stand nackt im Stylesheet. Der Parser
   las sie als SELEKTOR und verwarf die Regel darunter: die #560-Farbregel war nie im
   Browser. Gegen tinycss2 gemessen, der Selektor hiess woertlich «NACHTRAG im selben Lauf:
   mit .article__body .post-sources …».
   ZWEITE LEHRE, beim Reparieren selbst getreten: ein Kommentar-Ende-Zeichen IM Kommentartext
   schliesst den Block ebenfalls vorzeitig — beim Beschreiben des Fehlers also nie das Zeichen
   selbst schreiben. Beide Male meldet nichts einen Fehler; nur der Parser zeigt es. */
.post-layout .article__body .post-sources{color:color-mix(in srgb, var(--ink) 82%, var(--paper));font-size:13.5px;line-height:1.6}
.post-layout .article__body .post-sources a{color:inherit}

/* #561: die Struktur-Basis der drei entstylten Elemente. Vorher stand sie als `style=` im
   Post-HTML und war damit fuer die Brand-Gestalt unerreichbar (Inline schlaegt jede Regel) —
   eine Brand konnte nur umfaerben, nicht umformen. Hier steht bewusst NUR Rhythmus und
   Grundstruktur (Abstand, Polsterung, Aufzaehlungs-Mechanik); alles Charakterbildende
   (Kante, Flaeche, Radius, Polaritaet, Schrift) gehoert in blog-gestalt.css der Brand.
   Massstab ist die Merken-Box: geteilte Struktur, eigenes Geraet je Marke. */
.post-layout .article__body .post-sources{margin:44px 0 0;padding:14px 0 0;border-top:1px solid var(--rule)}
.post-layout .article__body .post-sources__label{font-size:10px;letter-spacing:0.14em;text-transform:uppercase;font-weight:700;margin-bottom:8px}
.post-layout .article__body .post-sources__list{margin:0;padding-left:16px;list-style:disc}
.post-layout .article__body .post-sources__item{margin-bottom:4px}
.post-layout .article__body .post-sources__item:last-child{margin-bottom:0}
/* Der CTA-Text erbt Schrift und Farbe vom Block (.post-cta), damit eine Brand mit EINER Regel
   die Polaritaet drehen kann (helles Panel <-> dunkles Panel) — genau das, was slfs Bauchbinde
   tut und was der alte Inline-Style unmoeglich machte. */
.post-layout .article__body .post-cta__text{margin:0;font:inherit;color:inherit}

/* #560: Farbe raus (Lesbarkeits-Regel). Gemessen als Akzent auf Papier: hypnosolve 1.53,
   mentivo 2.65, seonar 3.77. Der CTA-Link ist ohnehin schon strukturell hervorgehoben
   (fetter Block, Akzent-Kante links) und bleibt durch die Unterstreichung als Link kenntlich. */
.post-cta a{color:inherit;text-decoration:underline;text-underline-offset:3px}
.post-cta a:hover{text-decoration-thickness:2px}
/* #611 (Esteban-Befund M1, bei sieben von elf Marken: «kein richtiger Knopf, es ist einfach
   ein Text wo man dann darauf drueckt»). Die Basis hatte fuer den Handlungs-Slot des CTA
   (`-> [Text](Link)`, seit #566 von `next_content.md_to_html` als `.post-cta__knopf`
   gerendert) UEBERHAUPT KEINE Regel — gemessen 0 Treffer in dieser Datei. Acht der elf
   Handschriften gestalten ihn, drei nicht; eine Marke ohne Handschrift-Regel zeigte also
   einen nackten Link mit der Fliesstext-Unterlinie, und genau danach sieht ein Knopf nicht aus.

   Zwei Dinge muss die Basis leisten, und nur diese zwei:
   1. Ihn zum KNOPF machen — als Form, nicht als Farbe: eigener Block, echte Klickflaeche,
      sichtbare Kante. `currentColor` haelt das farb-neutral, damit die Lesbarkeits-Regel #559
      gilt und jede Marke ihre eigene Farbe darueberlegen kann.
   2. Ihm die LINK-LINIE nehmen. `.article__body a` zeichnet unter jeden Fliesstext-Link eine
      `border-bottom` — die traf bisher auch den Knopf und war der Grund, warum er selbst dort
      wie Text aussah, wo eine Marke ihn gestaltet hatte. Diese Regel ist spezifischer und
      loescht sie. */
.article__body .post-cta__knopf{display:inline-block;margin-top:20px;padding:13px 26px;border:2px solid currentColor;border-bottom:2px solid currentColor;font-family:var(--font-head,inherit);font-weight:700;font-size:16px;line-height:1.2;text-decoration:none;color:inherit}
/* Der Hover fuellt die Flaeche NICHT mit `currentColor` — das waere Schrift auf sich selbst
   und damit unsichtbar. Die Marke setzt eine Fuellung samt Gegenfarbe in ihrer Handschrift;
   bis dahin verstaerkt sich nur die Kante, und der Knopf bleibt in jedem Fall lesbar. */
.article__body .post-cta__knopf:hover{border-width:3px;padding:12px 25px}
@media (max-width:680px){.post-cta{padding:20px 22px;font-size:18px}}


/* ---------------- Brand-Gestalt (die Handschrift dieser Marke im Artikel;
   SoT: web-engine/brands/slf/blog-gestalt.css) ---------------- */
/* slf (Stadtlandschiri) — BLOG-GESTALT: die Handschrift dieser Marke im Artikel.

   HERGELEITET AUS DEM BRAND-MATERIAL, nicht erfunden:
     brand-engine/brands/slf/essenz.md   «Die Karte ist das Urteil» · «Der Schiri hat das
                                          letzte Wort» · Karten leicht rotiert (+-7-8 Grad),
                                          Hard-Shadow drunter · Broadcast/Stadion/Schiedsrichter
     brand-engine/brands/slf/konzept.md  Schiedsrichter-Streifen (das Kern-Pattern) ·
                                          Hard-Offset-Schatten 5px 5px 0 (kein Blur) ·
                                          Borders 2.5-3px ink, hart · Radius klein (4px) ·
                                          Kicker = Archivo 800, letter-spacing .14em
     brand-engine/brands/slf/pairing.md  «verspielte Huelle, todernster Spruch»

   DIE IDEE: die Merken-Box IST die Schiri-Karte. Der Absatz, den man behalten soll, ist der
   Entscheid — also bekommt er das Verdict-Device der Marke: eine hart umrandete Karte mit
   Offset-Schatten, dem Streifen-Band an der Kante und der hochgehaltenen gelben Karte als
   Etikett. Darum heisst das Etikett auch nicht «MERKEN», sondern «DER SCHIRI SAGT».

   NEBENBEI REPARIERT (Kontrast, gemessen #557): das Etikett stand vorher in accent-dark auf
   paper = Signalgelb auf Creme, Verhaeltnis 1.46 — praktisch unlesbar, und es verletzte die
   Marken-Regel aus konzept.md («Signal-Gelb traegt nur Ink-Text drauf»). Jetzt traegt die
   gelbe Flaeche den Ink-Text, wie es die Marke verlangt.

   ── DIE FARB-REGEL DIESER MARKE, IN BEIDE RICHTUNGEN (festgeschrieben #611) ──────────────
   konzept.md regelt bisher nur EINE Richtung: «Signal-Gelb traegt nur Ink-Text drauf, Gelb +
   Weiss verboten». Die UMKEHRUNG war nirgends geregelt, und genau sie hat dreimal Schaden
   gemacht (#557 Etikett 1.46 · #559 Fliesstext-Link 1.16 · #559 Pull-Zitat 1.46): Signalgelb
   ALS SCHRIFT auf Kreide. Rechnerisch ist das unvermeidbar — #ffe11a gegen #f4f1e9 kann gar
   nie ueber 1.2 kommen, weil beide fast gleich hell sind. Es gibt keine Groesse und kein
   Gewicht, die das retten.

   Darum gilt in dieser Handschrift, fuer JEDEN Seitentyp:
     **Gelb TRAEGT, es schreibt nie.** Signalgelb ist Flaeche, Kante, Marker, Schatten oder
     Chip — nie die Farbe eines Buchstabens. Wo Gelb Flaeche ist, steht Ink darauf (13.81),
     nie Weiss. Wo Text auf Kreide steht, ist er Ink (16.02) oder body (13.73).
   Das ist eine LESBARKEITS-Regel, kein Ton-Entscheid: die Marken-Toene selbst sind
   unveraendert (accent #ffe11a, accent-dark #f5c400, ink #15161a, paper #f4f1e9) — geregelt
   ist nur, welcher Ton welche ROLLE traegt. Die kanonische Heimat der Regel ist konzept.md;
   dort gehoert sie von Esteban nachgezogen, hier steht sie als bindende Arbeits-Fassung.

   GEGENGEMESSEN #611 am gerenderten Blatt (Musterbogen + Live-Post, Alpha komponiert, nicht
   aus Hex gerechnet): alle 30 auffindbaren Text-Rollen auf oder ueber Norm, schlechteste
   13.73. Die 1.16/1.46 aus #605 stammen aus der Rollen-Tabelle des Waechters, nicht vom Blatt.

   Pruefen:   python web-engine/tools/blog_gestalt.py status
              python web-engine/tools/blog_tokens.py pruefe slf
   Ausrollen: python web-engine/tools/sync_blog_css.py --nur slf   (danach die Site deployen!)
*/

.post-layout{--label-merken:"DER SCHIRI SAGT"}

/* Abstand der klebenden Leisten (TOC links, Sidebar rechts) unter der Navigation.
   WARUM HIER UND NICHT IM POST: der Wert haengt an der NAVIGATION DIESER MARKE, also gehoert
   er in ihre Handschrift — dann erbt ihn jeder kuenftige Seitentyp (Landing, Lead-Magnet), der
   eine klebende Spalte hat. Bisher stand er als `:root{--blog-sticky-top:102px}` im <style>
   JEDES einzelnen Posts, gegossen beim Veroeffentlichen: eine Landing-Page haette ihn nicht
   bekommen, und eine Nav-Aenderung haette jeden Post neu erzeugen muessen.

   DER WERT IST GERENDERT GEMESSEN (#611, nicht gerechnet, nicht uebernommen):
   Die SLF-Nav ist zweistufig und schrumpft beim Scrollen.
     oben (scrollY 0)   124px  = 6px Streifen + 2x14px Polster + 88px Logo + 2px Kante
     gescrollt          88px   = 6px Streifen + 2x8px  Polster + 64px Logo + 2px Kante
   Massgeblich ist die GESCROLLTE Hoehe, denn nur dann klebt ueberhaupt etwas: 88px.
   Die alten 102px (#605) waren gerechnet statt gemessen: 6+16+64 = 86, die 2px-Kante fehlte
   in der Rechnung, dazu 16px Luft. Gerendert blieben davon 14px — sichtbar zu knapp, genau
   Estebans «zu nahe an der Navigation».
   88 + 24 = 112px. Die 24px sind kein geratener Wert, sondern `--gutter` dieser Marke: die
   Luft unter der Nav ist damit dieselbe wie zwischen den Spalten. Gerendert nachgemessen:
   Nav-Unterkante 88, TOC- und Sidebar-Oberkante 112, also genau 24px Luft.

   ZWEITER VERBRAUCHER, BEWUSST NICHT NACHGEREGELT (gemessen #611): die geteilte Schicht leitet
   seit heute auch den Anker-Versatz daraus ab (`h2{scroll-margin-top:calc(var(--blog-sticky-top)
   + 16px)}`). Bei einer Marke mit SCHRUMPFENDER Nav geht diese Rechnung nicht auf: der Browser
   springt, solange die Nav noch 124px hoch ist, danach faellt sie auf 88px und das Dokument
   rutscht um genau diese 36px nach oben. Gemessen landet ein angeklickter Zwischentitel darum
   4px unter der Nav statt 40px. Das ist trotzdem besser als vorher (mit dem harten 96er-Default
   sass er 28px HINTER der Nav), aber es ist nicht gut. Der Token bleibt hier auf seinem eigenen
   Zweck (klebende Spalten, gerendert richtig); die Kompensation fuer schrumpfende Navigationen
   gehoert in die geteilte Schicht, nicht in eine Marken-Handschrift. Gemeldet, nicht gefixt. */
.post-layout{--blog-sticky-top:112px}

/* Die Karte: Chalk-Flaeche, harte Ink-Kante, Offset-Schatten ohne Blur, kleiner Radius.
   Kein Gelb als Flaeche (Marken-Regel: Signal-Gelb nie dekorativ flaechig). */
.post-layout .post-highlight{
  background:var(--paper);
  border:3px solid var(--ink);
  border-radius:4px;
  box-shadow:5px 5px 0 var(--ink);
  padding:30px 30px 26px;
}

/* KEIN Schiedsrichter-Streifen-Band. Drei Fassungen gebaut und am gerenderten Bild geprueft:
   senkrecht an der linken Kante (las als Filmstreifen-Perforation), waagrecht oben mit 10px
   und mit 19px Hoehe (las beide Male als Klebeband-Zacken, nicht als Trikot). Das Muster
   braucht Flaeche — auf 19px Hoehe wird aus dem Streifen eine Zackenreihe, und sie tritt in
   Konkurrenz zum Etikett, das der eigentliche Marken-Traeger ist.
   Nach dem Visual-Iterations-Limit (max 3, CLAUDE.md) verworfen statt weiter geschraubt.
   Die Marke traegt hier ueber die Karten-Anmutung: harte Kante, Offset-Schatten, kleiner
   Radius — und ueber die hochgehaltene gelbe Karte. Der Streifen bleibt den Flaechen
   vorbehalten, die ihn tragen koennen (Nav-Strip, Ticker, Hero). */

/* Das Etikett = die hochgehaltene gelbe Karte: rotiert, harter Schatten, Ink auf Signalgelb. */
.post-layout .post-highlight::before{
  position:absolute;
  z-index:1;
  top:-15px; right:24px;
  transform:rotate(-7deg);
  font-family:var(--font-body);
  font-size:11px;
  font-weight:800;
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--ink);
  background:var(--accent);
  padding:6px 12px 5px;
  border:2.5px solid var(--ink);
  border-radius:3px;
  box-shadow:3px 3px 0 var(--ink);
}

.post-layout .post-highlight p{
  font-family:var(--font-body);
  font-size:16.5px;
  line-height:1.6;
  font-weight:500;
  color:var(--ink);
}

@media(max-width:640px){
  .post-layout .post-highlight{padding:26px 20px 22px;box-shadow:4px 4px 0 var(--ink)}
  .post-layout .post-highlight::before{right:16px;font-size:10px}
}

/* ---- «In diesem Artikel»: die Anzeigetafel -------------------------------------
   Broadcast/Scoreboard-Sprache der Marke: Anton-Versalien als Titel, die Eintraege als
   Tafel-Zeilen mit harter Ink-Kante. Der aktive Eintrag wird GESETZT wie eine Anzeige:
   Signalgelb hinterlegt, Ink-Text — dieselbe Regel wie bei der Karte (Gelb traegt nur
   Ink-Text, nie Weiss). */
.post-layout .sidebar-block__title{
  font-family:var(--font-head); font-size:12px; font-weight:400;
  letter-spacing:0.06em; text-transform:uppercase; color:var(--ink);
  border-bottom:2px solid var(--ink); padding-bottom:6px;
}
.post-layout .post-toc .sb-toc a{
  font-family:var(--font-body); font-size:13px; font-weight:700;
  color:var(--body); border-left:3px solid var(--rule-strong); padding:2px 0 2px 12px;
}
.post-layout .post-toc .sb-toc a:hover{border-left-color:var(--ink); color:var(--ink)}
.post-layout .post-toc .sb-toc a.is-active{
  background:var(--accent); color:var(--ink);
  border-left-color:var(--ink); padding-right:8px;
}

/* ---- Links im Fliesstext: der Marker-Strich ------------------------------------
   GEMESSEN #557/#559: vorher Signalgelb als SCHRIFT auf Creme = 1.16. Unlesbar, und
   ein direkter Verstoss gegen konzept.md («Signal-Gelb nie dekorativ flaechig, nur als
   Akzent/Aktion» + «Signal-Gelb traegt nur Ink-Text drauf, Gelb + Weiss verboten»).
   Dieselbe Regel, die schon die Merken-Box gerettet hat, gilt hier: das Gelb TRAEGT,
   es schreibt nicht. Der Link ist Ink-Text mit einem dicken Signalgelb-Strich darunter —
   der Marker-Strich des Schiris auf dem Spielbericht, nicht eine gelbe Schrift.
   Kontrast damit: Ink auf Creme = 16.02 (der Strich ist Dekor, nicht Text). */
.post-layout .article__body a{
  color:var(--ink);
  font-weight:700;
  border-bottom:4px solid var(--accent);
  padding-bottom:1px;
  transition:background-color .15s;
}
/* #566 (Esteban: «wenn man mit der Maus darueber geht, wird es fast weniger hell»).
   Er hat den Fehler genau beschrieben: der Hover hat die Marke WEGGENOMMEN statt sie zu
   verstaerken. Der Strich war Signalgelb und wurde beim Darueberfahren zu Ink - also von der
   hellsten Farbe der Marke zur dunkelsten -, und der Hintergrund kam auf `--accent-tint`, das
   bei dieser Marke rechnerisch `#ffe11a14` ist, also fast durchsichtig. Sichtbar passierte
   damit: Gelb weg, kaum Flaeche da. Genau umgekehrt gedacht.
   Jetzt waechst der Marker-Strich in die volle Flaeche: aus dem Strich des Schiris wird die
   ausgemalte Stelle. Ink-Text auf Signalgelb, also die Marken-Regel «Gelb traegt, es schreibt
   nie» - und der Kontrast steigt beim Hovern, statt zu fallen. */
.post-layout .article__body a:hover{
  background:var(--accent);
  border-bottom-color:var(--accent);
  color:var(--ink);
}

/* ---- Pull-Zitat: der Entscheid an der Kante ------------------------------------
   GEMESSEN #557/#559: vorher accent-dark als Schrift auf Creme = 1.46. Unlesbar.
   Die Marke spricht hier in ihrem Karten-Vokabular (harte Ink-Kante, kein Blur):
   Ink-Text, links das Signalgelb als breite Kante — die hochgehaltene Karte am Rand
   des Zitats. Keine gelbe Schrift, keine gelbe Flaeche unter Text.

   `color:var(--ink)` ist heute deckungsgleich mit der Basis und bleibt trotzdem stehen (geprueft
   #611): es ist nicht Deko, sondern der TRAEGER des Lesbarkeits-Entscheids. Wer ihn streicht,
   macht die Marke davon abhaengig, welchen Ton die geteilte Schicht gerade fuehrt — und genau so
   ist der Wert 1.46 ueberhaupt entstanden. Ein Duplikat, das eine Regel haelt, ist kein Duplikat. */
.post-layout .post-pull{
  color:var(--ink);
  text-align:left;
  border-top:none;
  border-bottom:none;
  border-left:8px solid var(--accent);
  padding:10px 0 10px 22px;
  /* #566, erste Runde (Esteban: «die Schrift ist wie zu nahe, du musst ein bisschen Abstand
     zwischen den einzelnen Zeilen»): Zeilenhoehe auf 1.5. */
  line-height:1.5;
  /* #566, zweite Runde - PRAEZISIERT (Esteban: «zwischen den einzelnen BUCHSTABEN den Text
     weiter auseinandermachen»). Ich hatte beim ersten Mal nur die Zeilen auseinandergezogen;
     gemeint war die Laufweite. Das Pull-Zitat stand auf 0 und damit so eng wie Fliesstext,
     obwohl es ein herausgehobener Satz ist - herausgehobene Saetze vertragen und brauchen
     mehr Laufweite, sonst wirken sie gedraengt statt gesetzt. */
  /* Dritte Runde: 0.045em war zu viel (Esteban: «zu viel Unterschied zwischen den Buchstaben,
     ein bisschen in die andere Richtung»). Auf die Haelfte zurueck - genug Luft, damit der Satz
     gesetzt wirkt, ohne dass die Woerter auseinanderfallen. */
  letter-spacing:0.022em;
  word-spacing:0.03em;
}

/* ===================================================================
   #560 — TABELLEN + RECHTE SIDEBAR brand-eigen (Esteban E + D3)
   Fortsetzung des Motivs, das oben schon fuer Merken-Box und Inhalts-
   verzeichnis steht. Nur Tokens, keine hartkodierten Farben; die Signal-
   farbe traegt keinen Text (Lesbarkeits-Regel #559/#560).
   =================================================================== */
/* ---- Tabelle = DER SPIELZETTEL -------------------------------------------------
   NEUBAU #566 (Esteban: «Tabelle aendern»). Vorher war sie eine Karte mit gelbem Kopfband,
   Zebra-Zeilen, Rahmen, Radius und Offset-Schatten - also dasselbe Geraet wie die Merken-Box,
   nur breiter. Genau der Befund «bei allem eine viereckige Box».

   Jetzt der Spielzettel aus der Bildsprache («der Spielzettel mit Kategorien-Zeilen»):
   kein Aussenrahmen, keine Flaeche, kein Schatten. Die Struktur traegt die LINIE - ein fetter
   Ink-Strich oben, der Kopf in Archivo Narrow versal darunter, Kategorien-Zeilen mit
   Haarlinien, Abschluss wieder fett. Die erste Spalte ist die Kategorie und steht in Anton
   versal, wie auf dem echten Zettel. Signalgelb erscheint nur noch als kurzer Marker unter
   dem Kopf, nicht als Flaeche. */
.post-layout .article__body .post-table{
  border:0; border-top:4px solid var(--ink); border-radius:0;
  box-shadow:none; background:none; border-collapse:collapse;
}
.post-layout .article__body .post-table th{
  background:none; color:var(--ink);
  /* #566 (Esteban: «die Titel von Ort und Was dort zaehlt sind zu klein, sieht man nicht gut»).
     11.5px in Archivo Narrow versal mit 0.12em Sperrung war als Spalten-Label gedacht und im
     Ergebnis kleiner als jede andere Schrift im Artikel. Ein Spaltenkopf muss man lesen koennen,
     bevor man die Spalte liest. Jetzt Anton versal in Lese-Groesse, wie die Kategorie darunter -
     der Zettel spricht in EINER Schrift, der Kopf ist nur der Anfang der Spalte. */
  font-family:var(--font-head); font-size:16px; font-weight:400;
  letter-spacing:0.02em; text-transform:uppercase;
  padding:10px 16px 9px 0; text-align:left;
  border-bottom:3px solid var(--ink);
}
.post-layout .article__body .post-table th:last-child{padding-right:0}
/* Der gelbe Marker unter der ersten Kopfzelle: der Strich des Schiris, der die Spalte
   anzeichnet - kurz, nicht als Band ueber die ganze Breite. */
.post-layout .article__body .post-table th:first-child{position:relative}
.post-layout .article__body .post-table th:first-child::after{
  content:""; position:absolute; left:0; bottom:-3px; width:56px; height:3px;
  background:var(--accent);
}
.post-layout .article__body .post-table td{
  background:none; border-bottom:1px solid var(--rule);
  padding:12px 16px 12px 0; font-weight:500; vertical-align:top;
}
.post-layout .article__body .post-table td:last-child{padding-right:0}
.post-layout .article__body .post-table td:first-child{
  font-family:var(--font-head); font-weight:400; text-transform:uppercase;
  letter-spacing:0.02em; color:var(--ink); white-space:nowrap;
}
.post-layout .article__body .post-table tbody tr:last-child td{
  border-bottom:4px solid var(--ink);
}

/* ---- Sidebar: Karten mit harter Kante ------------------------------------------ */
.post-layout .sb-search__form input{border:2.5px solid var(--ink);border-radius:3px}
.post-layout .sb-search__form button{border-radius:3px;box-shadow:2px 2px 0 var(--ink)}
.post-layout .sb-betreiber{border:2.5px solid var(--ink);border-radius:4px;box-shadow:4px 4px 0 var(--ink);padding:12px}
.post-layout .sb-betreiber__avatar{border-radius:3px;border:2px solid var(--ink)}
.post-layout .sb-related a{font-weight:700}
.post-layout .sb-related li{border-bottom:2px solid var(--rule);padding-bottom:9px}

/* Die Zebra-Zeile aus #560 ist mit dem Spielzettel-Neubau entfallen: sie setzte voraus, dass
   die Tabelle eine Flaeche ist. Auf einem Zettel gibt es keine gefaerbten Zeilen, nur Linien. */

/* ===================================================================
   #560 NEUBAU — jedes Element ein EIGENES Geraet, nicht dieselbe Karte
   Esteban: «du kannst nicht bei allem eine viereckige Box hinklatschen».
   Die Welt der Marke hat mehr als ein Device: Karte, Tafel, Durchsage,
   Spielbericht, Regelwerk, Bauchbinde. Jedes Element bekommt seines.
   Regel bleibt: Gelb TRAEGT, es schreibt nie (konzept.md).
   =================================================================== */

/* ---- Blockquote = DIE FREMDE STIMME --------------------------------------------
   NEUBAU #566 (Esteban: «Blockquote aendern»). Die alte Fassung setzte fremde Rede in
   Anton-VERSALIEN zwischen zwei Ink-Balken - also in der lautesten Schrift der Marke. Das ist
   die Stimme des Schiris, nicht die des Zitierten; ein Zitat, das schreit, klingt wie eine
   eigene Ansage. Dazu kollidierte es mit dem Pull-Zitat, das ebenfalls zwischen Kanten sass.

   Jetzt: das Zitat spricht in der LESE-Schrift (Archivo), gross und ruhig, eingerueckt hinter
   einem gekippten gelben Karten-Chip mit dem Anfuehrungszeichen - der Marke ihr Karten-Motiv,
   aber klein und als Herkunfts-Marke, nicht als Urteil. Ink auf Gelb, wie die Regel es
   verlangt (Gelb traegt, es schreibt nie). */
.post-layout .article__body blockquote{
  background:none; border:0; border-radius:0;
  position:relative; padding:4px 0 4px 56px; margin:38px 0;
  font-style:normal; font-family:var(--font-body); font-weight:500;
  font-size:19px; line-height:1.55; color:var(--ink); text-transform:none;
}
.post-layout .article__body blockquote::before{
  content:"\201C";                       /* das oeffnende Anfuehrungszeichen */
  position:absolute; left:0; top:2px;
  display:grid; place-items:center;
  width:34px; height:34px;
  background:var(--accent); color:var(--ink);
  border:2.5px solid var(--ink); border-radius:3px;
  box-shadow:3px 3px 0 var(--ink);
  transform:rotate(-6deg);
  font-family:var(--font-head); font-size:26px; line-height:1;
  padding-top:9px;                       /* die Glyphe haengt oben, das schiebt sie in die Mitte */
}
.post-layout .article__body blockquote p{margin-bottom:0}

/* ---- Stat-Karte = DER ANGESTRICHENE WERT ---------------------------------------
   NEUBAU #566 (Esteban: «Statkarte aendern»). Die alte Fassung war eine SCORE-ANZEIGE, ein
   dunkles Stadion-Panel mit leuchtender Zahl. Sie muss weg, und zwar nicht nur wegen des
   Urteils: `assets/manifest.yaml` fuehrt unter `bildsprache.nie` ausdruecklich «keine
   Zahlen-/Punktestand-Lastigkeit» (Esteban #534). Das Geraet widersprach der eigenen
   Bildsprache der Marke - gebaut, bevor diese Regel formuliert war, und nie nachgezogen.

   Jetzt: kein Panel, keine Polaritaets-Umkehr, kein Stadion. Die Zahl steht in Anton auf dem
   Kreide-Grund, und der Schiri STREICHT SIE AN - ein dicker Signalgelb-Marker liegt hinter der
   Zahl, genauso breit wie sie. Das ist derselbe Griff wie beim Link im Fliesstext (das Gelb
   traegt, es schreibt nicht) und bleibt im Zettel-Vokabular statt im Tafel-Vokabular. */
.post-layout .article__body .post-stat{
  display:block;                       /* das geteilte `grid: auto 1fr` setzt Zahl und Text
                                          nebeneinander; angestrichen wird untereinander */
  background:none; border:0; border-radius:0; box-shadow:none;
  padding:0; margin:38px 0;
}
.post-layout .article__body .post-stat__num{
  position:relative; display:inline-block; z-index:0;
  font-family:var(--font-head); font-weight:400;
  color:var(--ink); font-variant-numeric:tabular-nums;
  font-size:clamp(52px, 7.5vw, 76px); line-height:1;
  padding:0 6px; margin-bottom:12px;
}
/* Der Marker-Strich liegt HINTER der Zahl und deckt nur ihr unteres Drittel - so liest er als
   angestrichen, nicht als gelber Kasten mit Zahl drin. */
.post-layout .article__body .post-stat__num::before{
  content:""; position:absolute; z-index:-1;
  left:0; right:0; bottom:6px; height:0.34em;
  background:var(--accent);
}
.post-layout .article__body .post-stat__label{
  font-family:var(--font-mono); font-weight:700;
  color:var(--ink); text-transform:uppercase; letter-spacing:0.12em; font-size:12px;
  margin:0 0 5px;
}
.post-layout .article__body .post-stat__ctx{color:var(--body); font-size:15.5px; line-height:1.6}
.post-layout .article__body .post-stat__src{
  font-family:var(--font-mono);
  font-size:11px; letter-spacing:0.06em; color:var(--muted);
}

/* ---- Checkliste = der SPIELBERICHT ---------------------------------------------
   Ein Bogen mit Linien, kein Kasten: der Schiri hakt ab. Der Haken ist ein kleines
   gelbes Karten-Quadrat, leicht gekippt wie die Karten der Marke — das Gelb TRAEGT
   den Haken, es faerbt ihn nicht. */
.post-layout .article__body .post-checkliste{
  background:none; border:0; border-top:3px solid var(--ink); border-radius:0; padding:14px 0 0;
}
.post-layout .article__body .post-checkliste__titel{
  font-family:var(--font-head); font-weight:400; font-size:13px;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--ink); margin-bottom:12px;
}
.post-layout .article__body .post-checkliste__list li{
  border-top:1px solid var(--rule); padding:11px 0 11px 40px;
}
.post-layout .article__body .post-checkliste__list li::before{
  content:"✓"; left:0; top:9px;
  display:grid; place-items:center; width:23px; height:23px;
  background:var(--accent); color:var(--ink);
  border:2px solid var(--ink); border-radius:2px;
  transform:rotate(-6deg); font-size:13px; font-weight:900;
}

/* #566 (Esteban: «bei der Checkliste sollen die Marks auch beim Scrollen so abgehakt werden»)
   Dasselbe Verhalten wie bei seonar, aber in DIESER Marke erzaehlt: dort wandert eine Peilung
   die Messreihe hinunter, hier HAKT DER SCHIRI AB - die Karte liegt zuerst leer auf dem Zettel
   (Kreide-Grund, Haken unsichtbar) und wird beim Vorbeiscrollen gestempelt: Signalgelb faellt
   ein, der Haken erscheint, und die Karte kippt in ihre Endlage.

   Ohne JavaScript, ueber die scroll-getriebene Animation (`animation-timeline: view()`): jede
   Karte haengt an ihrer EIGENEN Sichtbarkeit, also wird eine nach der anderen abgehakt.
   Wo der Browser die Timeline nicht kennt (heute Safari/Firefox), passiert nichts - die Karten
   stehen dann fertig abgehakt da wie bisher. Kein Fallback noetig, kein Schaden.
   `prefers-reduced-motion` setzt sofort den Endzustand. */
.post-layout .article__body .post-checkliste__list li::before{
  animation:slf-abhaken linear both;
  animation-timeline:view();
  animation-range:entry 55% cover 62%;
}
@keyframes slf-abhaken{
  from{background:var(--paper); color:transparent; transform:rotate(-14deg) scale(0.86)}
  to  {background:var(--accent); color:var(--ink); transform:rotate(-6deg) scale(1)}
}
@media (prefers-reduced-motion:reduce){
  .post-layout .article__body .post-checkliste__list li::before{
    animation:none;
    background:var(--accent); color:var(--ink); transform:rotate(-6deg);
  }
}

/* ---- Nummerierte Liste = DIE KATEGORIEN-ZEILEN ---------------------------------
   NEU #566 (Esteban: «nummerierte Liste bitte bauen»). Sie trug bisher die geteilten
   Browser-Ziffern, also gar keine Handschrift.

   Das Geraet kommt vom Spielzettel («Kategorien-Zeilen: Stadt/Land/Fluss/Name/Tier»), und es
   wiederholt keines der Nachbarn: die Checkliste hat die gestempelte Karte mit Haken, die
   Merken-Box die grosse Urteils-Karte. Hier ist die Ziffer der ZEILEN-KOPF: eine kleine
   gekippte Kreide-Karte mit Ink-Rand, die Zahl in Anton, dahinter die Zeile.
   Nur `ol`: eine ungeordnete Liste hat keine Reihenfolge und behaelt ihre Bullets. */
.post-layout .article__body ol.post-list{
  list-style:none; counter-reset:slf-zeile;
  margin:0 0 28px; padding:0;
}
.post-layout .article__body ol.post-list li{
  counter-increment:slf-zeile;
  position:relative; padding-left:48px; margin-bottom:14px;
}
.post-layout .article__body ol.post-list li::before{
  content:counter(slf-zeile);
  position:absolute; left:0; top:0.15em;
  display:grid; place-items:center;
  width:28px; height:28px;
  background:var(--paper); color:var(--ink);
  border:2.5px solid var(--ink); border-radius:3px;
  box-shadow:3px 3px 0 var(--accent);   /* der Schatten traegt hier das Gelb, nicht die Flaeche */
  transform:rotate(-4deg);
  font-family:var(--font-head); font-weight:400; font-size:15px; line-height:1;
}

/* ---- Quellen = das REGELWERK, klein gedruckt -----------------------------------
   Der Verweis auf die Regel, nicht der Entscheid: eingerueckt an einer Ink-Kante,
   ohne Kasten, damit er sich vom Urteil sichtbar unterscheidet. */
.post-layout .article__body .post-sources{
  border-top:0; border-left:3px solid var(--ink); padding:2px 0 2px 16px;
  font-size:12.5px; line-height:1.55;
}

/* ---- CTA = die BAUCHBINDE (Lower Third) ----------------------------------------
   Broadcast statt Karte: ein breiter Ink-Balken mit dem Schiedsrichter-Streifen als
   gelber Kante oben. Hier hat der Streifen endlich die Flaeche, die er braucht — auf
   der Merken-Box wurde er in #557 nach drei Versuchen verworfen, weil er auf 19px
   Hoehe als Zackenreihe las. */
/* NEUBAU #566 (Esteban: «Call to Action abaendern»). Die Bauchbinde ist raus. Zwei Gruende:
   sie war ein dunkles Panel mit Anton-VERSALIEN ueber den ganzen Absatz - also schrie der
   Abschluss den Leser an, und ein Fliesstext in Versalien liest sich schlecht. Dazu war sie
   das zweite dunkle Panel im Artikel (neben der Score-Anzeige), die beide jetzt weg sind.

   Jetzt bleibt der Abschluss auf dem Kreide-Grund und traegt das Karten-Vokabular der Marke -
   dieselbe Familie wie die Merken-Box, aber ein eigenes Zeichen: dort ist der Offset-Schatten
   INK und das Etikett gelb, hier ist der Schatten SIGNALGELB und es gibt kein Etikett.
   Der Satz steht in der Lese-Schrift, der Link traegt den Marker-Strich wie im Fliesstext. */
.post-layout .post-cta{
  background:var(--paper); color:var(--ink);
  border:3px solid var(--ink); border-radius:4px;
  box-shadow:6px 6px 0 var(--accent);
  padding:26px 30px;
  font-family:var(--font-body); font-weight:500; font-size:18px;
  letter-spacing:0; text-transform:none; line-height:1.55;
}
.post-layout .post-cta__text, .post-layout .post-cta > p{color:var(--ink); margin:0}
.post-layout .post-cta a{
  color:var(--ink); font-weight:700; text-decoration:none;
  border-bottom:4px solid var(--accent); padding-bottom:1px;
  transition:background-color .15s;
}
.post-layout .post-cta a:hover{background:var(--accent-tint); border-bottom-color:var(--ink)}

/* Der Knopf (#566). Moeglich, seit der CTA einen eigenen Handlungs-Slot im Markup hat.
   Bei dieser Marke IST der Knopf die hochgehaltene Karte: Signalgelb-Flaeche mit Ink-Text
   (die Marken-Regel «Gelb traegt, es schreibt nie»), harte Ink-Kante, Offset-Schatten ohne
   Blur, leicht gekippt. Beim Druecken faehrt er in seinen Schatten hinein. */
/* `a.post-cta__knopf`: die Regel fuer den Link IM Satz ist spezifischer und wuerde dem Knopf
   sonst ihren Marker-Strich und ihre Farbe aufdruecken. */
.post-layout .post-cta a.post-cta__knopf{
  display:inline-block; margin-top:20px;
  background:var(--accent); color:var(--ink);
  font-family:var(--font-head); font-weight:400; font-size:17px;
  text-transform:uppercase; letter-spacing:0.03em; line-height:1.15;
  padding:13px 26px;
  border:3px solid var(--ink); border-radius:4px;
  box-shadow:5px 5px 0 var(--ink);
  transform:rotate(-1.5deg);
  text-decoration:none;
  transition:box-shadow .12s, transform .12s;
}
.post-layout .post-cta a.post-cta__knopf:hover{
  background:var(--accent);
  transform:rotate(-1.5deg) translate(2px, 2px); box-shadow:3px 3px 0 var(--ink);
}
.post-layout .post-cta a.post-cta__knopf:active{
  transform:rotate(-1.5deg) translate(5px, 5px); box-shadow:0 0 0 var(--ink);
}

/* ===================================================================
   #566 — DER KOPF DES ARTIKELS (Esteban: Meta-Zeile, Titel, Lead und
   Zwischenueberschriften «muss man aendern»). Alle vier trugen bis
   jetzt den geteilten Standard, hatten also gar keine Handschrift.
   =================================================================== */

/* ---- Meta-Zeile = DAS KATEGORIEN-TICKERBAND ------------------------------------
   Aus der Bildsprache: «das Kategorien-Ticker-Band». Die Zeile ueber dem Titel sagt, in
   welcher Kategorie gespielt wird - also bekommt die Kategorie den gestempelten Chip der
   Marke (Ink auf Signalgelb, harte Kante, leicht gekippt) und der Rest laeuft als ruhiges
   Laufband in Archivo Narrow versal daneben. */
/* GESTRICHEN #611: `display:flex` und `flex-wrap:wrap` standen hier WORTGLEICH wie in der
   geteilten Basis (blog.css:66) — reines Totgewicht. Die Trennlinie seit #557 ist klar: die
   Basis besitzt Struktur und Rhythmus, die Handschrift den Look. Der Baukasten der Zeile
   gehoert also der Basis; was hier bleibt, sind die Entscheide dieser Marke (Mono-Schrift,
   700er Gewicht, 11.5px, 0.14em Sperrung, Ink statt gedimmtem Ton, 9px statt 16px Abstand)
   plus die Ausrichtung, die der engere Abstand braucht. Haetten wir die zwei stehen lassen,
   wuerde die Marke einem kuenftigen Seitentyp ihren Blog-Baukasten aufzwingen, obwohl sie zu
   dem Punkt gar nichts zu sagen hat. */
.post-layout .article__meta{
  font-family:var(--font-mono); font-weight:700;
  font-size:11.5px; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--ink); align-items:center; gap:9px;
}
.post-layout .article__meta a:first-child,
.post-layout .article__meta .article__kicker,
.post-layout .article__meta > span:first-child{
  background:var(--accent); color:var(--ink);
  border:2px solid var(--ink); border-radius:3px;
  box-shadow:2px 2px 0 var(--ink);
  transform:rotate(-2deg);
  padding:3px 9px 2px; text-decoration:none;
}

/* ---- Titel = DER ANPFIFF -------------------------------------------------------
   Die Marke setzt ihren Titel versal (`titelbild.titel.versalien: true`, Anton, Zeilenhoehe
   0.98) - der Blog-Titel folgte dem nicht und stand gemischt. Jetzt gleicher Griff wie auf
   dem Titelbild, und darunter der breite Signalgelb-Marker als Anpfiff-Strich. */
/* Der Marker liegt als HINTERGRUND am Element, nicht als absolut gesetztes Pseudo-Element.
   Grund (#566, am Bild gemessen): als `::after` mit `bottom:0` erschien der Balken im Hero
   ueber statt unter dem Titel — der Kopf-Bereich bringt eigene Positionierung mit, und ein
   absolut gesetztes Kind haengt dann an der falschen Kante. Als `background-image` mit
   `background-position:left bottom` kann das nicht passieren: der Balken wird IM Element
   gezeichnet, unabhaengig von jedem Positionierungs-Kontext drumherum. */
.post-layout .article__title{
  font-family:var(--font-head); font-weight:400;
  text-transform:uppercase; letter-spacing:0.005em;
  line-height:0.98; color:var(--ink);
  padding-bottom:18px;
  background-image:linear-gradient(var(--accent), var(--accent));
  background-size:120px 9px;
  background-position:left bottom;
  background-repeat:no-repeat;
}

/* ---- Lead = DIE ANSAGE VOR DEM SPIEL -------------------------------------------
   Vorher ein umrandeter Kasten mit gelber Kante links - wieder eine Box, und dazu dieselbe
   linke Kante, die das Pull-Zitat traegt. Jetzt kastenlos: nur groesser, ruhiger und mit
   etwas Luft, damit der Absatz als Vorspann liest und nicht als Hinweisfeld. */
/* ZWEITE RUNDE #566 (Esteban: «dieser Text gleich unter dem grossen MUSTERBOGEN SLF, wie der
   formatiert ist, das gefaellt mir nicht, das muss ein bisschen mehr mit Design sein»).
   Die erste Fassung hat den Kasten nur ENTFERNT und den Text vergroessert - also nichts gebaut,
   nur weggenommen. Ein Vorspann ist bei dieser Marke die ANSAGE VOR DEM SPIEL, und die hat eine
   Form: der erste Satz steht gross und fett wie eine Durchsage, der Rest laeuft normal weiter,
   und links traegt ein Streifen-Band den Absatz - der Schiedsrichter-Streifen, das Kern-Pattern
   der Marke (konzept.md), das im Blog bisher nirgends vorkam.
   Warum er hier funktioniert und auf der Merken-Box nicht (#557, dort nach drei Versuchen
   verworfen): dort sollte er auf 19px Hoehe QUER liegen und las als Zackenreihe. Hier laeuft er
   SENKRECHT ueber die volle Absatzhoehe, hat also die Flaeche, die das Muster braucht. */
.post-layout .article__lead{
  background:none; border:0; border-radius:0;
  position:relative; padding:2px 0 2px 26px; max-width:62ch;
  font-family:var(--font-body); font-weight:500;
  font-size:19.5px; line-height:1.6; color:var(--ink);
}
.post-layout .article__lead::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:11px;
  background:repeating-linear-gradient(
    -22deg,
    var(--ink) 0 7px,
    transparent 7px 14px);
}
/* Der erste Satz als Durchsage. `::first-line` waere die falsche Achse (sie haengt an der
   Zeilenumbruch-Breite, nicht am Satz) - darum die erste ZEILE bewusst nicht, sondern ein
   groesserer, festerer Anfang ueber das erste Wort hinaus ist nur mit Markup moeglich.
   Was ohne Markup geht und trotzdem traegt: ein deutlich staerkerer Auftakt-Buchstabe. */
.post-layout .article__lead::first-letter{
  font-family:var(--font-head); font-weight:400;
  font-size:2.6em; line-height:0.82;
  float:left; margin:6px 10px 0 0; color:var(--ink);
}

/* ---- Zwischenueberschriften = DIE KATEGORIE-ZEILE ------------------------------
   h2 traegt Anton versal mit dem Marker-Strich darunter (kurz, nicht ueber die Breite) -
   dasselbe Zeichen wie der Titel, eine Stufe kleiner. h3 bleibt ohne Marker und bekommt
   stattdessen den kurzen Ink-Anstrich davor, damit die beiden Ebenen ohne Groessenraten
   unterscheidbar sind. */
.post-layout .article__body h2{
  font-family:var(--font-head); font-weight:400;
  text-transform:uppercase; letter-spacing:0.01em; line-height:1.05;
  color:var(--ink); padding-bottom:12px;
  background-image:linear-gradient(var(--accent), var(--accent));
  background-size:64px 6px;
  background-position:left bottom;
  background-repeat:no-repeat;
}
.post-layout .article__body h3{
  font-family:var(--font-head); font-weight:400;
  text-transform:uppercase; letter-spacing:0.02em; color:var(--ink);
  position:relative; padding-left:22px;
}
.post-layout .article__body h3::before{
  content:""; position:absolute; left:0; top:0.42em;
  width:13px; height:4px; background:var(--ink);
}
