/* ====================================================================
   LAZARUS — Shared Styles (Design-Tokens + Komponenten)
   Quelle der Tokens: tokens.css. Im Markup nur var(--lz-*).
   ==================================================================== */

/* --- Schriften, selbst gehostet ------------------------------------ *
 * Dateien liegen in assets/fonts/, Herkunft google-webfonts (SIL OFL).
 * Nur das latin-Subset — die Seite ist deutsch, alle Sonderzeichen der
 * Seite (✓ ⚠ ♜ …) liegen ohnehin ausserhalb aller Google-Subsets und
 * kommen wie bisher aus der System-Fallback-Schrift.
 * Archivo und JetBrains Mono sind VARIABLE Fonts: alle Schnitte einer
 * Familie teilen sich EINE Datei. Ein Schnitt weniger spart hier also
 * kein einziges Byte — nur eine Regel. Darum ist die Schnittliste exakt
 * dieselbe wie bei Google (Archivo 400/500/600/700, Mono 400/500/700):
 * jede Abweichung wuerde die Gewichtsauswahl verschieben. Messbar: ohne
 * Archivo 500 faellt font-weight:500 auf 400 zurueck und wird schmaler.
 * Die Schnitte sind einzeln festgenagelt, nicht als Range 400..700 —
 * so rutscht font-weight:600 bei JetBrains Mono weiterhin auf 700 hoch,
 * genau wie bisher.
 * unicode-range identisch zu Google (Subset "latin").
 * ------------------------------------------------------------------- */
@font-face{
  font-family:'Anton';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/anton-latin-400.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/archivo-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:500;font-display:swap;
  src:url(fonts/archivo-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:600;font-display:swap;
  src:url(fonts/archivo-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Archivo';font-style:normal;font-weight:700;font-display:swap;
  src:url(fonts/archivo-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';font-style:normal;font-weight:400;font-display:swap;
  src:url(fonts/jetbrains-mono-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';font-style:normal;font-weight:500;font-display:swap;
  src:url(fonts/jetbrains-mono-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';font-style:normal;font-weight:700;font-display:swap;
  src:url(fonts/jetbrains-mono-latin-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root{
  /* Grund und Flaeche.
     --lz-surface lag auf #161618 — das sind 3,8 Punkte L* ueber dem Grund
     #0C0C0D. Gemessen heisst das: eine Flaeche, die man nur sieht, wenn man
     sie sucht. Bloecke lasen sich deshalb nicht als Bloecke, sondern als
     Text mit Rahmen; die einzige Gliederung langer Seiten war Abstand.
     Referenz Hyrox: Grund #000, Blockflaeche #262626 — 15 Punkte L*.
     Neu: --lz-surface auf 7, --lz-surface-2 auf 12 Punkte ueber dem Grund.
     Das reicht, damit eine Flaeche ohne Rahmen als Flaeche liest, und
     bleibt unter dem Hyrox-Wert, weil Lazarus mehr Schwarz haelt.
     KEINE zweite Akzentfarbe — Struktur entsteht aus Flaeche, nicht Farbe. */
  --lz-ink:#0C0C0D; --lz-surface:#1C1C20; --lz-surface-2:#26262B; --lz-line:#34343B;
  /* --lz-line ist die DEKORATIVE Hairline (1,58:1 gegen den Grund) und
     bleibt genau so — sie trennt, sie bedient nicht.
     Wo eine Linie die einzige sichtbare Grenze eines BEDIENELEMENTS ist
     (Eingabefeld, Segment-Schalter, Geisterknopf), verlangt WCAG 1.4.11
     aber 3:1. Ein Nutzer muss sehen KOENNEN, wo das Feld aufhoert.
     #67676F haelt 3,49:1 gegen den Grund und 3,03:1 gegen --lz-surface —
     der kleinste Wert, der beides schafft, damit die Kante so leise wie
     moeglich bleibt. Nie fuer Trennlinien benutzen, sonst kippt der
     Hairline-Look in ein Raster aus grauen Strichen. */
  --lz-line-ui:#67676F;
  --lz-blood:#FF2E00; --lz-blood-deep:#D11F00; --lz-blood-glow:rgba(255,46,0,.30);
  /* --lz-ash lag auf #7A7A7E: 4,6:1 auf dem Grund, 4,3:1 auf --lz-surface.
     Labels, Captions und Meta-Zeilen stehen fast alle auf Flaeche.
     #8A8A90 war der erste Versuch und hielt 5,7:1 / 4,95:1 — reichte aber
     NICHT auf --lz-surface-2 (4,39:1), wo Badge-Beschreibungen, die
     Gruppenbeschreibung im Kartenkopf und die Einladungs-Meta stehen.
     Drei Befunde, ein Wert: #909097 haelt 5,9:1 auf dem Grund,
     5,15:1 auf --lz-surface und 4,71:1 auf --lz-surface-2. Alle drei
     Flaechen ueber AA — das ist der Punkt, an dem der Wert stehen bleibt. */
  --lz-bone:#F2F2F0; --lz-ash:#909097; --lz-white:#FFFFFF;
  /* --lz-ash-lift ist --lz-ash fuer Flaechen, die nicht auf reinem Ink
     liegen. --lz-ash traegt auf #0C0C0D 5,6:1 — auf dem Bildgrund der
     Kopfkarte (gemessen rgb(58,58,59)) nur noch 3,6:1 und faellt damit
     unter die Norm. Nicht den Grund aufhellen und nicht den Text gross
     machen: der Ton gehoert zum Grund, auf dem er liegt.
     Gemessen mit _tools/pruef-kontrast, 09/2026. */
  --lz-ash-lift:#B9B9C0;
  --lz-ok:#39D353; --lz-warn:#FFB000; --lz-warn-glow:rgba(255,176,0,.18);
  --lz-display:"Anton","Archivo Black",Impact,sans-serif;
  --lz-grotesk:"Archivo","Helvetica Neue",Arial,sans-serif;
  --lz-mono:"JetBrains Mono",Consolas,monospace;
  /* Die kleine Leiter. Drei Stufen, damit nicht jede Regel ihren eigenen
     rem-Wert erfindet (gezaehlt: .6 .64 .66 .7 .72 .74 .75 .76 .78 .8 —
     eine Skala aus Zufall):
       --lz-micro    Badge, Datum in der Rangspalte
       --lz-label    Mono-Labels, Eyebrows, Metazeilen
       --lz-caption  Hinweissaetze, Kartentitel, Fusslinks
     Auf dem Handy hat die Leiter einen Boden — siehe MOBIL-TYPOBODEN. */
  --lz-micro:.66rem; --lz-label:.72rem; --lz-caption:.78rem;
  /* Fingerziel. WCAG 2.5.5 (AAA) und 2.5.8 nennen 44x44 CSS-Pixel; hier
     steht die Zahl EINMAL, damit kein Knopf sie neu erfindet. */
  --lz-tap:44px;
  --lz-body:clamp(1rem,.95rem + .3vw,1.18rem);
  --lz-lead:clamp(1.3rem,1.1rem + 1vw,2rem);
  --lz-screamer:clamp(3rem,1.5rem + 9vw,11rem);
  /* Seitentitel: eine Stufe unter dem Screamer. Vorher stand auf jeder
     Unterseite ein eigener clamp() im style-Attribut (4.5/5/6/7rem) —
     das war eine Skala aus Zufall. Jetzt ein Wert: .screamer.title. */
  --lz-title:clamp(2.2rem,1rem + 6vw,5rem);
  --lz-mega:clamp(5rem,2rem + 22vw,22rem);
  --lz-track-label:.22em; --lz-track-tight:-.02em;
  --lz-gutter:clamp(1.25rem,1rem + 3vw,5rem);
  --lz-stack:clamp(4rem,3rem + 6vw,9rem);
  /* Die Schale: die Breite, in der Inhalt steht — mittig im Fenster.
     Vorher gab es sie nur als .wrap, und benutzt hat sie fast keine Seite.
     Ergebnis: auf 1440px klebte jede Unterseite am linken Gutter und rechts
     standen ~600px leer. --lz-measure ist die Textspalte INNERHALB der
     Schale (frueher .article{max-width:780px}); sie wandert im Rhythmus
     zwischen linker und rechter Kante. */
  --lz-shell:1200px;
  --lz-measure:780px;
  --lz-ease:cubic-bezier(.2,.7,.2,1); --lz-fast:.18s; --lz-slow:.5s;
  --lz-photo:grayscale(1) contrast(1.15) brightness(.85);
  /* Fuer Material, das schon behandelt IST: s/w mit dem einen Rot bereits
     im Bild. Hier darf kein grayscale(1) drueber — es wuerde genau die
     Spur wegnehmen, die den Look ausmacht. Unbehandeltes Rohmaterial
     bekommt weiterhin --lz-photo.
     brightness > 1, weil solches Material schon an der Quelle dunkel
     belichtet ist: mit dem Scrim des Foto-Bands darueber blieb sonst nur
     eine schwarze Flaeche uebrig. Gemessen an partner.jpg. */
  --lz-photo-treated:contrast(1.08) brightness(1.35);
  /* Hoehe der Top-Bar. Fallback fuer den ersten Frame und fuer den Fall,
     dass kein JS laeuft; renderHeader() misst die echte Hoehe und
     ueberschreibt den Wert am <html> (die Bar waechst, sobald das
     Profil-Dropdown eingeblendet wird). Der Hero rechnet damit. */
  /* Hoehe des Zeichens im Lockup. Kopf und Fuss teilen sich den Wert
     nicht: in der Bar sitzt es neben der Wortmarke, im Fuss darueber. */
  /* Scrim-Dichte fuer Text auf Foto. Kein Vollbild-Overlay: die Dichte
     sitzt nur dort, wo der Text steht. Aus --lz-ink abgeleitet, nicht aus
     reinem Schwarz — die Seite hat keinen Grund unter #0C0C0D.
     Gebraucht von der Scroll-Startseite (index.html). */
  --lz-scrim-1:rgba(12,12,13,.95);
  --lz-scrim-2:rgba(12,12,13,.82);
  --lz-scrim-3:rgba(12,12,13,.45);
  --lz-mark-bar:26px;
  --lz-barh:65px;
}

/* --- MOBIL-TYPOBODEN ------------------------------------------------ *
 * Auf dem Athletenprofil standen bei 390px 10,56px auf dem Schirm
 * (Status-Badge "THE FULL ✓", Datum in der Laufliste) und 38 Stellen auf
 * 11,52px. Das ist auf Armlaenge keine Schrift mehr, das ist Grafik.
 * Auf dem Desktop ist dieselbe Groesse in Ordnung: dort sitzt der Schirm
 * naeher an der Nase und ein Label darf leise sein.
 * Darum kein neuer Wert in dreissig Regeln, sondern ein Boden unter der
 * Leiter: ab hier faellt auf kleinen Schirmen nichts unter 13px.
 * 13px ist die Grenze, unter der iOS/Android-Nutzer messbar zoomen.     */
@media(max-width:600px){
  :root{ --lz-micro:.82rem; --lz-label:.82rem; --lz-caption:.86rem; }
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
/* Ein TOC-Klick animiert sonst quer ueber die ganze Regelseite. Laufschrift
   und Fortschrittsbalken sind laengst geschuetzt — der Sprung war es nicht. */
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{background:var(--lz-ink);color:var(--lz-bone);font-family:var(--lz-grotesk);
  font-size:var(--lz-body);line-height:1.5;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
a:focus-visible,input:focus-visible,button:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--lz-blood);outline-offset:3px}

/* --- Typo-Helfer --- */
.label{font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-ash)}
.eyebrow{font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-blood);margin-bottom:1.5rem;display:block}
.screamer{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:var(--lz-screamer);line-height:.9;letter-spacing:var(--lz-track-tight)}
.screamer.title{font-size:var(--lz-title)}
.mono{font-family:var(--lz-mono)}

/* --- Wortmarke (SVG, Anton in Pfade) -------------------------------- *
 * Eine Buchstabenform fuer Kopf und Fuss. Hoehe .85em = exakt die alte
 * Zeilenhoehe des Wort-Blocks im Footer: kein Layoutsprung. Farbe kommt
 * ueber currentColor, der Akzent "US" ueber das Token.                  */
.wordmark{display:block;width:auto;height:.85em}
.wordmark .wm-accent{fill:var(--lz-blood)}

/* --- Das Zeichen ---------------------------------------------------- *
 * Drei Teile, ein Dreieck. Farbe kommt ueber currentColor — das SVG
 * traegt keine Farbe, damit derselbe Pfad in Blood UND in Bone laufen
 * kann. Nie verzerren: width bleibt auto, nur die Hoehe wird gesetzt.   */
.mark{display:block;width:auto;flex:0 0 auto}

/* .lockup = Zeichen + Wortmarke als eine Einheit (Kopf, Fuss, OG-Karte).
   Darin markiert Blood GENAU EINEN Fokus: das Zeichen. Deshalb faellt der
   rote "US"-Akzent der Wortmarke hier auf die Textfarbe zurueck — zwei
   rote Elemente in einer Gruppe waeren Laerm. Die Wortmarke selbst bleibt
   unangetastet: allein stehend traegt sie ihren Akzent weiter.          */
.lockup .wordmark .wm-accent{fill:currentColor}

/* --- Skip-Link: erster fokussierbare Punkt jeder Seite --------------- */
.skiplink{position:absolute;left:var(--lz-gutter);top:-100px;z-index:100;
  background:var(--lz-blood);color:var(--lz-ink);font-family:var(--lz-mono);font-weight:700;
  font-size:var(--lz-label);text-transform:uppercase;letter-spacing:var(--lz-track-label);
  padding:.8rem 1.2rem;transition:top var(--lz-fast) var(--lz-ease)}
.skiplink:focus-visible{top:.6rem}
main:focus{outline:none}

/* --- Layout: die Schale -------------------------------------------- *
 * Jede Sektion ist ein Raster aus drei Spalten: Luft, Schale, Luft.
 * Direkte Kinder landen automatisch in der Schale — deshalb braucht KEINE
 * Seite dafuer einen zusaetzlichen Wrapper im Markup, und keine Seite kann
 * die Zentrierung vergessen. Genau das war der Fehler vorher: .wrap war
 * freiwillig, also stand der Inhalt mal mittig (Startseite) und mal links
 * (alle anderen).
 * Wer die volle Fensterbreite will, sagt .bleed — der negative Rand hebt
 * die Sektions-Polsterung auf, sonst reicht "full" nur bis an den Gutter.
 * .hero, .photoband und .soon setzen selbst display:flex und gewinnen ueber
 * die Klassenspezifitaet: sie bleiben randlos, wie sie waren.             */
section{padding:var(--lz-stack) var(--lz-gutter)}
/* Nur die oberste Ebene ist eine Schale. Wuerde die Regel auf JEDES
   <section> greifen, bekaeme auch ein verschachtelter Block (z.B. eine
   Badge-Gruppe) das Drei-Spalten-Raster und damit eine Schale in der
   Schale. Deshalb main > section — und nur dessen direkte Kinder.
   AUSGENOMMEN ist alles, was randlos SEIN SOLL: die Scroll-Schnitte der
   Startseite (.lzs-cut), Fotobaender, Hero, Platzhalter und die roten
   Flaechen (.slab).
   Die Liste muss vollstaendig sein — und das war sie erst im zweiten
   Anlauf. Ein blosses :not(.lzs-cut) hebt die Spezifitaet dieser Regel
   auf (0,1,2) und schlaegt damit .photoband (0,1,0): das Band war zwar
   1920px breit, sein Bild aber in der 1200px-Schalenspalte gefangen.
   Auf 1920px gemessen, im Screenshot als schwarze Raender sichtbar.
   Wer hier eine randlose Sektion ergaenzt, traegt sie in dieses :not()
   ein — sonst schnuert die Schale sie stillschweigend ein. */
main > section:not(.lzs-cut, .photoband, .hero, .soon, .slab, .rules-wrap){
  display:grid;
  grid-template-columns:
    [full-start] minmax(0,1fr)
    [shell-start] minmax(0,var(--lz-shell)) [shell-end]
    minmax(0,1fr) [full-end];
  align-content:start}
main > section:not(.lzs-cut, .photoband, .hero, .soon, .slab, .rules-wrap) > *{grid-column:shell;min-width:0}
main > section:not(.lzs-cut, .photoband, .hero, .soon, .slab, .rules-wrap) > .bleed{grid-column:full;margin-inline:calc(-1 * var(--lz-gutter))}
/* .wrap bleibt als Bauteil fuer Inhalt AUSSERHALB von <section> (Baender,
   Footer). Innerhalb einer Sektion ist es jetzt ueberfluessig. */
.wrap{max-width:var(--lz-shell);margin:0 auto}
.divider{border-top:1px solid var(--lz-line)}

/* --- Rhythmus: die Textspalte wandert -------------------------------- *
 * Drei Taktarten statt einer: Spalte links, Spalte rechts, Vollbreite.
 * Der Leerraum wechselt beim Scrollen die Seite — das ist der Unterschied
 * zwischen "gesetzt" und "abgeladen". .flip schiebt einen Block an die
 * rechte Kante der Schale, .midden zentriert ihn darin.                  */
/* .flip schiebt einen Block an die rechte Kante der Schale.
   width:100% ist der entscheidende Teil und war der Fehler: OHNE ihn
   schrumpft das Rasterelement mit margin-left:auto auf Inhaltsbreite
   (gemessen 725px und 763px statt 780px), und die linke Kante liegt bei
   jedem Block woanders. Ueber sechs Kapitel ergab das sieben verschiedene
   linke Kanten — und Scannen heisst, das Auge an EINER senkrechten Kante
   nach unten zu fuehren. Mit width:100% gibt es genau zwei Kanten. */
.flip{margin-left:auto;width:100%}
/* Auf schmalen Schirmen gibt es keinen Leerraum zu verteilen: der Versatz
   wuerde nur unruhig wirken, weil alle Bloecke ohnehin volle Breite haben. */
@media(max-width:900px){.flip{margin-left:0}}

/* === TOP BAR ======================================================= */
.bar{position:sticky;top:0;z-index:50;display:flex;align-items:center;
  justify-content:space-between;gap:1rem;padding:1.1rem var(--lz-gutter);
  border-bottom:1px solid var(--lz-line);background:rgba(12,12,13,.72);backdrop-filter:blur(8px)}
/* Kopf-Wortmarke: dieselbe SVG wie im Footer, nur klein. Vorher stand hier
   JetBrains Mono 700 — damit hatte die Marke zwei Buchstabenformen auf
   einem Bildschirm. em-Groesse haengt an font-size, .85em von 1rem = 13.6px. */
.bar .brandmark{display:inline-flex;align-items:center;color:var(--lz-bone);
  font-size:1rem;line-height:1;transition:color var(--lz-fast)}
.bar .brandmark:hover{color:var(--lz-white)}
/* Das Zeichen ist der eine Blood-Fokus der Marke — es faerbt sich beim
   Hover NICHT mit, sonst wandert der Fokus auf die ganze Zeile. */
.bar .brandmark .mark-bar{height:var(--lz-mark-bar);color:var(--lz-blood);margin-right:.7rem}
.bar .tag{color:var(--lz-ash);margin-left:.8rem}
.bar .bar-brand{display:flex;align-items:center}
.bar nav{display:flex;gap:1.4rem;align-items:center}
.bar nav a{font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-ash);transition:color var(--lz-fast)}
.bar nav a:hover,.bar nav a.active{color:var(--lz-bone)}
.bar nav a.active::before{content:"●";color:var(--lz-blood);margin-right:.5em;font-size:.7em;vertical-align:middle}
.bar nav a.cta{color:var(--lz-blood)}
.bar .who{color:var(--lz-ash)}
/* Hamburger (nur Mobile sichtbar) */
.navtoggle{display:none;flex-direction:column;gap:5px;background:transparent;border:0;cursor:pointer;padding:.45rem;z-index:60}
.navtoggle span{display:block;width:24px;height:2px;background:var(--lz-bone);transition:transform var(--lz-fast) var(--lz-ease),opacity var(--lz-fast)}
.navtoggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.navtoggle.open span:nth-child(2){opacity:0}
.navtoggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media(max-width:980px){
  .bar{flex-wrap:wrap}
  .bar .tag{display:none}
  .navtoggle{display:flex}
  .bar nav{position:absolute;top:100%;left:0;right:0;display:none;flex-direction:column;align-items:stretch;gap:0;
    background:var(--lz-ink);border-bottom:1px solid var(--lz-line);padding:.25rem 0}
  .bar nav.open{display:flex}
  .bar nav a,.bar nav .who{padding:1rem var(--lz-gutter);border-top:1px solid var(--lz-line);font-size:.82rem}
  .bar nav > a:first-child{border-top:0}
  .bar .who{display:block;color:var(--lz-bone)}
}

/* === BUTTONS / FORMS =============================================== */
.btn{font-family:var(--lz-mono);font-weight:700;text-transform:uppercase;letter-spacing:.14em;
  font-size:.78rem;background:var(--lz-blood);color:var(--lz-ink);border:0;padding:1rem 1.6rem;
  cursor:pointer;transition:background var(--lz-fast);display:inline-block;text-align:center}
.btn:hover{background:var(--lz-blood-deep)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.ghost{background:transparent;color:var(--lz-bone);border:1px solid var(--lz-line)}
.btn.ghost:hover{border-color:var(--lz-bone);background:transparent}
.btn.danger{background:transparent;color:var(--lz-blood);border:1px solid var(--lz-blood)}
.btn.danger:hover{background:var(--lz-blood);color:var(--lz-ink)}

.field{display:block;margin-bottom:1.1rem}
.field > label{display:block;font-family:var(--lz-mono);font-size:var(--lz-label);
  text-transform:uppercase;letter-spacing:.14em;color:var(--lz-ash);margin-bottom:.5rem}
/* 1rem ist hier eine Untergrenze, kein Geschmack: iOS Safari zoomt die ganze
   Seite hinein, sobald ein Feld kleiner als 16px gesetzt ist — und zoomt nicht
   wieder heraus. Auf .95rem (15,2px) sprang bei jedem Antippen die Seite auf
   ~115 %, das Passwortfeld lag danach halb ausserhalb. Gemessen 09/2026 an
   12 Feldern auf konto.html. 90 % der Eintragungen kommen ueber ein Telefon.
   Wer das hier kleiner setzen will, setzt stattdessen ein transform: scale()
   auf ein 16px-Feld — nie die font-size. */
.input,select.input,textarea.input{width:100%;background:var(--lz-surface);border:1px solid var(--lz-line);
  color:var(--lz-bone);font-family:var(--lz-mono);font-size:1rem;padding:.85rem 1rem;letter-spacing:.03em}
textarea.input{resize:vertical;min-height:80px;font-family:var(--lz-grotesk);letter-spacing:0}
.input::placeholder{color:var(--lz-ash)}

.seg{display:inline-flex;border:1px solid var(--lz-line);flex-wrap:wrap}
.seg button{font-family:var(--lz-mono);font-weight:700;text-transform:uppercase;letter-spacing:.12em;
  font-size:.74rem;background:transparent;color:var(--lz-ash);border:0;border-right:1px solid var(--lz-line);
  padding:.65rem 1.1rem;cursor:pointer;transition:color var(--lz-fast),background var(--lz-fast)}
.seg button:last-child{border-right:0}
/* Vier Knoepfe passen in der schmalen Einreichen-Spalte nicht in eine
   Zeile — ohne Zutun faellt der vierte allein in die zweite und sieht aus
   wie vergessen. Mit einer Mindestbreite brechen sie sauber auf 2x2 um
   und fuellen die Reihe. Die Trennlinie sitzt dann bei jedem Knopf, sonst
   fehlt sie mitten im Raster. */
.seg.seg-4{display:flex;width:100%}
.seg.seg-4 button{flex:1 1 8.5rem;border-right:1px solid var(--lz-line-ui)}
.seg.seg-4 button:last-child{border-right:0}
.seg button:hover{color:var(--lz-bone)}
.seg button[aria-pressed="true"]{background:var(--lz-blood);color:var(--lz-ink)}

/* === NOTICE / TOAST =============================================== */
.notice{font-family:var(--lz-mono);font-size:.8rem;letter-spacing:.04em;padding:.85rem 1rem;
  border:1px solid var(--lz-line);background:var(--lz-surface);margin:1rem 0;display:none}
.notice.show{display:block}
.notice.err{border-color:var(--lz-blood);color:var(--lz-blood)}
.notice.ok{border-color:var(--lz-ok);color:var(--lz-ok)}
.notice.info{border-color:var(--lz-line);color:var(--lz-ash)}

/* === HERO ========================================================= */
/* Hoehe: 100svh MINUS Top-Bar. Die Bar steht im Fluss ueber dem Hero —
   volle 100svh haben den Hero (und mit ihm die letzte H1-Zeile und die
   Scroll-Marke) um genau die Bar-Hoehe unter die Falz geschoben.
   Gemessen: 1440x900 lag die H1-Unterkante bei 964px, 390x844 bei 879px. */
.hero{position:relative;min-height:calc(100svh - var(--lz-barh));display:flex;align-items:flex-end;
  padding:0 var(--lz-gutter) clamp(2rem,4vw,4rem);overflow:hidden}
/* Hero-Foto. Liegt hier und nicht mehr als style-Attribut in index.html,
   weil nur von hier aus per Media Query umgeschaltet werden kann.
   hero.jpg ist 1920x1074 und wird per cover eingepasst. Auf hochkantem
   Handy zieht cover das Bild an der HOEHE auf und schneidet seitlich ab —
   sichtbar bleiben nur die mittleren ~25-31% der Breite, und zwar
   HOCHSKALIERT. Eine kleiner gerechnete Handy-Variante waere darum
   unschaerfer, nicht besser. hero-portrait.jpg ist deshalb kein Downscale,
   sondern der mittlere Ausschnitt 960x1074 in Originalaufloesung: gleiche
   Pixel auf dem Schirm, halbe Dateigroesse.
   Grenze 8/9: bis dahin deckt der 960er Ausschnitt den Container voll ab. */
.hero .photo{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center 30%;
  background-image:url(img/foto/hero.jpg);filter:var(--lz-photo)}
@media (max-aspect-ratio:8/9){
  .hero .photo{background-image:url(img/foto/hero-portrait.jpg)}
}
.hero .streak{position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(115deg,transparent 55%,rgba(255,46,0,.0) 60%,rgba(255,46,0,.45) 72%,transparent 73%),
             linear-gradient(115deg,transparent 62%,rgba(255,46,0,.30) 68%,transparent 69%)}
.hero .scrim{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(12,12,13,.55) 0%,rgba(12,12,13,0) 30%,rgba(12,12,13,.9) 100%)}
.hero .inner{position:relative;z-index:2;width:100%}
/* Die Wortmarke ist drei Zeilen hoch (3 x .82em) und steht ueber der
   Eyebrow-Zeile und dem Bodenabstand. --lz-mega kennt nur die Breite und
   lief deshalb auf flachen Fenstern (1440x900: 348.8px) unten heraus.
   Deckel: der Platz, der im Hero uebrig ist, geteilt durch die Zeilen.
   9rem = Eyebrow-Block (~2.3rem) + Bodenabstand (max 4rem) + Luft. */
.hero h1{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:min(var(--lz-mega), calc((100svh - var(--lz-barh) - 9rem) / 2.6));
  line-height:.82;letter-spacing:var(--lz-track-tight);color:var(--lz-bone)}
.hero h1 .run{color:var(--lz-blood);display:block}
.scrolltag{position:absolute;right:var(--lz-gutter);bottom:clamp(2rem,4vw,4rem);z-index:2;
  writing-mode:vertical-rl;text-orientation:mixed}
.scrolltag::after{content:"";display:block;width:1px;height:48px;background:var(--lz-ash);margin:.6rem auto 0}
@media(max-width:760px){.scrolltag{display:none}}

/* === PRINZIP (Foto-Cards Push/Pull/Run) =========================== */
.prinzip .head{display:flex;flex-wrap:wrap;align-items:baseline;gap:1rem 1.5rem;margin-bottom:clamp(2rem,4vw,3.5rem)}
.prinzip .head .lead{font-size:var(--lz-lead);color:var(--lz-blood);font-weight:600}
.pcards{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,2vw,1.5rem)}
.pcard{position:relative;aspect-ratio:4/5;border:1px solid var(--lz-line);overflow:hidden;display:flex;
  align-items:flex-end;padding:1.4rem}
.pcard .bg{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center;
  filter:var(--lz-photo);transition:transform var(--lz-slow) var(--lz-ease)}
.pcard:hover .bg{transform:scale(1.05)}
.pcard::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(12,12,13,.1) 0%,rgba(12,12,13,.85) 100%)}
.pcard .c{position:relative;z-index:2}
.pcard .ix{font-family:var(--lz-mono);color:var(--lz-blood);font-size:.8rem;letter-spacing:.1em}
.pcard h3{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:clamp(2rem,1rem + 4vw,3.4rem);line-height:.9;margin:.3rem 0 .4rem}
.pcard p{color:var(--lz-bone);font-size:.92rem;max-width:26ch}
.prinzip .foot{margin-top:clamp(2rem,4vw,3rem);color:var(--lz-bone)}
@media(max-width:760px){.pcards{grid-template-columns:1fr}.pcard{aspect-ratio:16/10}}

/* === DISZIPLINEN (Signature) ====================================== */
.disz-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1.2rem;margin-bottom:1rem}
.disz-note{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.12em;
  text-transform:uppercase;color:var(--lz-ash);min-height:1.1em;margin-bottom:1.5rem;display:block}
.disz-note b{color:var(--lz-blood);font-weight:700}
.tier{border-top:1px solid var(--lz-line);padding:clamp(2rem,4vw,3.5rem) 0;
  display:grid;grid-template-columns:minmax(120px,.5fr) 2.5fr;gap:1rem clamp(1.5rem,4vw,4rem);align-items:end}
.tier:last-of-type{border-bottom:1px solid var(--lz-line)}
.tier .meta .name{font-family:var(--lz-mono);font-weight:700;letter-spacing:.14em;text-transform:uppercase;font-size:1rem}
.tier .meta .sub{color:var(--lz-ash);font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:var(--lz-track-label);text-transform:uppercase;margin-top:.4rem}
.nums{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(1rem,3vw,3rem);align-items:end}
.num .big{font-family:var(--lz-display);font-weight:400;color:var(--lz-blood);
  font-size:clamp(3.2rem,1rem + 13vw,9rem);line-height:.8;letter-spacing:var(--lz-track-tight);transition:color var(--lz-fast)}
.num .big .km{font-size:.4em}
.num .cap{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:var(--lz-track-label);
  text-transform:uppercase;color:var(--lz-ash);margin-top:.7rem;display:block}
.tier:hover .num .big{color:var(--lz-white)}
@media(max-width:760px){.tier{grid-template-columns:1fr}.tier .meta{margin-bottom:.5rem}}

/* --- Volumenzaehler -------------------------------------------------
   Dasselbe Signature-Muster wie die Stufen-Stapel (.nums > .num), nur
   eine Groessenstufe kleiner: dort stehen vierstellige Pensen, hier
   summierte Zahlen, die fuenf- und sechsstellig werden ("11.000" sind
   sechs Zeichen). Kein neues Muster — nur eine andere Groesse. */
.vol-block{border-top:1px solid var(--lz-line);border-bottom:1px solid var(--lz-line);
  padding:clamp(1.4rem,4vw,2.4rem) 0;margin:clamp(1.4rem,4vw,2.2rem) 0}
.vol-block .block-head{margin-bottom:clamp(1.2rem,3vw,1.8rem)}
.nums-vol .big{font-size:clamp(2.6rem,1rem + 7vw,5.2rem);font-variant-numeric:tabular-nums}
.nums-vol .big .km{font-size:.32em}
/* Drei Riesenzahlen nebeneinander waeren auf 390px drei schmale Spalten
   mit Umbruch mitten in der Zahl. Untereinander bekommt jede die volle
   Breite — und bleibt damit das, was sie sein soll: gross. */
@media(max-width:600px){
  .nums-vol{grid-template-columns:1fr;gap:1.3rem}
}
.vol-fuss{font-family:var(--lz-mono);font-size:var(--lz-label);color:var(--lz-ash);
  margin-top:1.1rem;line-height:1.5}

/* Das einzeilige Laufband (.band) ist raus (09/2026). Es lief nur noch
   auf regeln.html und sagte dort in einer Endlosschleife, was die sieben
   Regelzeilen darunter ohnehin sagen. Die Startseite hat ihr eigenes
   Laufband (.lzs-marquee in index.html) — davon ist nichts betroffen.

   Falls es je zurueckkommt: git show pre-struktur-umbau:assets/styles.css */

/* === RANGLISTE (Leaderboard) ===================================== */
/* Ansage ueber der Tabelle: WELCHE Wertung hier steht. Ohne sie rangiert
   eine Liste Quarter gegen Full und Woman gegen Man — Zahlen, die nichts
   miteinander zu tun haben. */
.board-claim{display:block;margin:.6rem 0 1.4rem;color:var(--lz-ash)}
/* Direkt unter der Ueberschrift darf sie enger stehen. */
.board-head + .board-claim{margin-top:-1rem}
.board-claim b{color:var(--lz-bone);font-weight:400}
.board-claim .pensum{color:var(--lz-blood)}
.filters{display:flex;flex-wrap:wrap;gap:.8rem}
.lb{border-top:1px solid var(--lz-line)}
.row-entry{border-bottom:1px solid var(--lz-line);display:grid;
  grid-template-columns:54px 1fr auto auto;gap:1rem;align-items:center;padding:1.1rem 0}
.row-entry .rank{font-family:var(--lz-display);font-size:1.8rem;color:var(--lz-ash);line-height:1}
.row-entry.top .rank{color:var(--lz-blood)}
/* Gemischte Auswahl (mehrere Pensen in einer Liste): keine Platzziffer.
   Eine Zeit auf 250/25/5 ist keine Konkurrenz zu einer auf 2000/200/20. */
.row-entry .rank.norank{font-family:var(--lz-mono);font-size:1rem;color:var(--lz-line)}
/* Push.Pull.Run style: links steht kein Platz, sondern das VOLUMEN —
   die einzige Zahl, die ein freies Pensum hat. Sie braucht mehr Breite
   als eine Platzziffer und bricht am Slash um, statt die Zeile zu
   sprengen. Blood, weil sie hier die Hauptzahl ist (in der Rangliste
   ist sie die Nebenzahl in der Metazeile). */
#boardStyle .row-entry{grid-template-columns:7rem minmax(0,1fr) auto auto}
.row-entry .rank-vol{font-family:var(--lz-mono);font-weight:700;font-size:1rem;
  line-height:1.25;color:var(--lz-blood);letter-spacing:.02em;overflow-wrap:anywhere}
.row-entry .rank-vol .pensum{color:inherit}
@media(max-width:760px){
  #boardStyle .row-entry{grid-template-columns:5.4rem minmax(0,1fr) auto}
  .row-entry .rank-vol{font-size:.86rem}
}

/* Die Geschichte zum Lauf — bewusst Fliesstext in Bone, nicht Mono:
   sie ist das einzige Menschliche in einer Liste aus Zahlen. */
.entry-note{color:var(--lz-bone);font-size:.95rem;line-height:1.6;margin:.6rem 0 0;
  max-width:60ch;white-space:pre-line}
.entry-video{display:inline-block;margin-top:.6rem;font-family:var(--lz-mono);
  font-size:var(--lz-label);letter-spacing:.14em;text-transform:uppercase;
  color:var(--lz-blood);border-bottom:1px solid var(--lz-line);padding-bottom:.15rem;
  transition:color var(--lz-fast),border-color var(--lz-fast)}
.entry-video:hover{color:var(--lz-bone);border-color:var(--lz-bone)}

/* Derselbe Grund wie an .profile-id .name: der Name kommt vom Nutzer und
   kann 40 Zeichen ohne Leerzeichen sein. Ohne diese Zeile schob er
   rangliste.html auf 495px und gruppe.html auf 489px bei 360px Fenster. */
.row-entry .name{font-weight:600;overflow-wrap:break-word;min-width:0}
.row-entry .meta{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.1em;
  text-transform:uppercase;color:var(--lz-ash);margin-top:.2rem}
/* Eine gemeldete Rueckmeldung ist Fliesstext, kein Datenfeld: .meta waere
   Mono in Grossbuchstaben und ab zwei Saetzen nicht mehr lesbar. */
.row-entry .fb-body{font-size:.92rem;white-space:pre-wrap;margin:.35rem 0}
/* tabular-nums, weil eine Rangliste genau dafuer da ist: Zeiten untereinander
   vergleichen. Ohne sie ist 48:18 51px breit und 1:20:27 72px — die Spalte
   springt von Zeile zu Zeile, und das Auge findet die Ziffernstelle nicht. */
.row-entry .time{font-family:var(--lz-mono);font-weight:700;font-size:1.1rem;letter-spacing:.04em;
  font-variant-numeric:tabular-nums}
.row-entry .act{display:flex;gap:.5rem;align-items:center}
.iconbtn{background:transparent;border:1px solid var(--lz-line);color:var(--lz-ash);cursor:pointer;
  font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.1em;text-transform:uppercase;padding:.4rem .6rem}
.iconbtn:hover{color:var(--lz-bone);border-color:var(--lz-bone)}
.thumb{width:46px;height:46px;object-fit:cover;border:1px solid var(--lz-line);filter:var(--lz-photo);cursor:pointer}
.empty{color:var(--lz-ash);font-family:var(--lz-mono);font-size:.85rem;padding:2.5rem 0;text-align:center}

/* Kommentare (assets/social.js — gleiche Bausteine auf allen Seiten) */
.comments{grid-column:1/-1;margin:.6rem 0 .2rem}
.row-entry>.comments{padding-left:70px}
.comment{border-left:2px solid var(--lz-line);padding:.5rem 0 .5rem .9rem;margin-bottom:.5rem}
.comment .who{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.08em;text-transform:uppercase;color:var(--lz-ash)}
.comment .who b{color:var(--lz-bone);font-weight:700}
.comment .who a{color:inherit;text-decoration:none;border-bottom:1px solid transparent}
.comment .who a:hover{color:var(--lz-blood);border-color:var(--lz-blood)}
.comment .body{font-size:.92rem;margin-top:.15rem}
.cdel{background:none;border:0;padding:0;cursor:pointer;color:var(--lz-ash);
  font-family:var(--lz-mono);font-size:inherit;letter-spacing:inherit;text-transform:inherit}
.cdel:hover{color:var(--lz-blood)}
.cnote{color:var(--lz-ash);font-family:var(--lz-mono);font-size:var(--lz-caption);margin:.2rem 0 .6rem}
.cerr{color:var(--lz-blood);font-family:var(--lz-mono);font-size:var(--lz-caption);margin:.2rem 0 .6rem}
.cnum{color:var(--lz-blood);font-weight:700}
.cform{display:flex;gap:.5rem;margin:.4rem 0 1rem;max-width:640px}
/* Kompaktes Formular bleibt kompakt ueber den Innenabstand — die Schriftgroesse
   ist an die 16px-Untergrenze oben gebunden (iOS-Zoom). */
.cform .input{padding:.6rem .8rem;font-size:1rem}
.social{display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;margin-top:.55rem}

/* Leaderboard / Formulare auf kleinen Screens */
@media(max-width:600px){
  /* minmax(0,1fr), nicht 1fr: eine nackte fr-Spalte hat min-width:auto und
     schrumpft NIE unter ihren Inhalt. Ein Anzeigename mit 40 Zeichen ohne
     Leerzeichen (Migration 0001 erlaubt das) machte die Zeile deshalb
     481px breit und schob bei 360px das ganze Dokument auf 507px — der
     Bruch von Regel 1, kein waagerechtes Scrollen. Die vier anderen
     Rasterregeln hier benutzen minmax laengst; diese war die letzte nackte.
     Der Umbruch am Namen allein reicht nicht — er darf erst greifen, wenn
     die Spalte ueberhaupt schmaler werden darf. Gemessen 09/2026. */
  .row-entry{grid-template-columns:32px minmax(0,1fr) auto;gap:.5rem .7rem}
  .row-entry .rank{font-size:1.4rem}
  .row-entry .time{font-size:1rem}
  .row-entry .act{grid-column:1 / -1;justify-content:flex-start;flex-wrap:wrap;padding-left:32px}
  .row-entry>.comments{padding-left:32px}
  .cform{flex-direction:column}
  .board-head{gap:1rem}
  .seg{width:100%}
  .seg button{flex:1 1 auto;text-align:center}
}

/* === MODAL (Bild-Lightbox) ======================================= */
.modal{position:fixed;inset:0;z-index:100;background:rgba(7,7,8,.92);display:none;
  align-items:center;justify-content:center;padding:2rem}
.modal.show{display:flex}
.modal img{max-width:92vw;max-height:88vh;border:1px solid var(--lz-line)}
.modal .x{position:absolute;top:1.2rem;right:1.4rem;font-family:var(--lz-mono);color:var(--lz-bone);
  cursor:pointer;font-size:1.4rem}

/* === AUTH / SCHMALE SEITEN ======================================= */
.narrow{max-width:460px;margin:0 auto}
.page-top{padding-top:clamp(3rem,8vw,6rem)}
.card-panel{border:1px solid var(--lz-line);background:var(--lz-surface);padding:clamp(1.5rem,3vw,2.5rem)}

/* --- Kartengrund des Athletenkopfs ----------------------------------
   Der Monolith aus dem Markenbild (assets/img/foto/profil-grund.jpg,
   53 KB) liegt unter der Kopfkarte. Zwei Verlaeufe darueber:

   1. nach rechts — links steht der Text, dort muss der Grund satt sein.
      Nach rechts hin darf das Bild atmen, dort steht nichts.
   2. nach unten — die Karte endet im Seitengrund statt an einer Kante.
      Ohne diesen Verlauf haengt ein Foto in einem Kasten; mit ihm geht
      die Flaeche in die Seite ueber.

   Der Grund bleibt --lz-surface: laedt das Bild nicht, sieht die Karte
   aus wie jede andere, statt durchsichtig zu werden.

   "Fotos s/w, hart" bleibt gewahrt — das Bild IST schwarzweiss bis auf
   die eine rote Linie, und die ist der Akzent, kein zweiter Farbton. */
.profil-grund{
  position:relative;
  background:
    /* Die Werte sind gemessen, nicht geschaetzt: bei .28/.88 stand der Grund
       im Textbereich auf rgb(52,52,59), und die Metazeile in --lz-ash fiel
       damit von 5,6:1 auf 3,9:1 — unter die Norm von 4,5:1. Wer hier
       aufhellt, prueft mit _tools/pruef-kontrast nach, nicht mit dem Auge. */
    /* Der senkrechte Verlauf verdunkelt NUR die untere Haelfte — er hat eine
       Aufgabe: die Karte in den Seitengrund auslaufen lassen. Wuerde er auch
       oben abdunkeln, multiplizierte er sich mit dem waagerechten, und vom
       Bild bliebe nichts uebrig (gemessen: rgb(52,52,59) statt rgb(115,…)). */
    linear-gradient(180deg, transparent 0%, transparent 46%, rgba(12,12,13,.55) 78%, var(--lz-ink) 100%),
    linear-gradient(90deg,
      rgba(12,12,13,.97) 0%, rgba(12,12,13,.95) 52%,
      rgba(12,12,13,.62) 76%, rgba(12,12,13,.18) 100%),
    url("img/foto/profil-grund.jpg") right center / cover no-repeat,
    var(--lz-surface);
}

/* --- Badge-Symbolreihe im Profilkopf ---------------------------------
   Steht dort, wo vorher der Lazarus-Status als Wort stand. Ein Ziel fuer
   die ganze Reihe, mindestens 44px hoch. Die Hoehe ist fest reserviert,
   weil die Badges asynchron nachkommen — ohne Reservierung springt die
   halbe Seite, sobald sie da sind, und die Bestzeit rutscht kurz von
   Bildschirm 1. */
.statusline{min-height:44px;display:flex;align-items:center}
.badgerow{display:inline-flex;align-items:center;gap:.45rem;flex-wrap:wrap;
  min-height:44px;text-decoration:none;color:inherit}
.badgerow .bico{font-size:1.15rem;line-height:1;color:var(--lz-blood)}
.badgerow .bico.elite{color:var(--lz-warn)}
.badgerow .bcount{font-family:var(--lz-mono);font-size:var(--lz-caption);
  letter-spacing:.08em;color:var(--lz-ash-lift);margin-left:.15rem}
.badgerow .bcount b{color:var(--lz-bone)}
.badgerow.leer{font-family:var(--lz-mono);font-size:var(--lz-caption);
  letter-spacing:.06em;color:var(--lz-ash-lift)}
/* Hover nur, wo es einen Zeiger gibt — auf Touch bliebe der Zustand sonst
   nach dem Antippen kleben. */
@media (hover:hover){
  .badgerow:hover .bcount{color:var(--lz-bone)}
  .badgerow:hover .bico{filter:brightness(1.25)}
}

/* Alles Graue auf dieser Karte liegt auf dem Bild, nicht auf Ink — also
   eine Stufe heller. Betrifft Herkunftszeile und Metazeile. */
.profil-grund .regionline,
.profil-grund .metaline,
.profil-grund .muted{color:var(--lz-ash-lift)}

/* Der feuerrote Streifen. Er sitzt auf der Unterkante der Kopfkarte und
   laeuft nach rechts aus — dieselbe Geste wie die Linie im Bild, die aus
   dem Monolithen ins Feld laeuft.
   Das ist bewusst KEIN Puls-Streifen: er bewegt sich nicht, er wiederholt
   sich nicht, und es gibt genau einen pro Seite. Siehe docs/design/SKILL.md. */
.profil-grund::after{
  content:"";position:absolute;left:-1px;right:-1px;bottom:-1px;height:2px;
  background:linear-gradient(90deg,
    var(--lz-blood) 0%, var(--lz-blood) 34%, rgba(255,46,0,.35) 62%, transparent 100%);
  pointer-events:none;
}
.muted{color:var(--lz-ash);font-size:.9rem}
.linkline{font-family:var(--lz-mono);font-size:var(--lz-caption);letter-spacing:.06em;color:var(--lz-ash);margin-top:1.2rem}
.linkline a{color:var(--lz-blood)}

/* Upload Dropzone */
.drop{border:1px dashed var(--lz-line);background:var(--lz-surface);padding:2rem 1rem;text-align:center;
  cursor:pointer;transition:border-color var(--lz-fast)}
.drop:hover{border-color:var(--lz-ash)}
.drop.has{border-style:solid}
.preview{margin-top:1rem;border:1px solid var(--lz-line);filter:var(--lz-photo);width:100%}
/* --- Volumen-Eingabe: Push/Pull/Run als eine Zahl ------------------- *
 * Die Schreibweise des Pensums ist Gesetz (2000/200/20) — also sieht auch
 * die Eingabe so aus: drei Felder, zwei Slashes, kein Kasten drumherum.
 * Gesperrt (offizielle Stufe) steht sie da wie eine Anzeige; offen
 * ("Frei") bekommt sie die Linie, die ein Eingabefeld haben muss.      */
.pensum-input{display:flex;align-items:center;gap:.5rem}
.pensum-input .input{font-family:var(--lz-mono);font-weight:700;text-align:center;
  font-size:clamp(1.1rem,3.2vw,1.5rem);letter-spacing:.02em;padding:.55rem .3rem;
  min-width:0;flex:1 1 0}
.pensum-input .sep{font-family:var(--lz-mono);font-weight:700;color:var(--lz-ash);
  font-size:clamp(1.1rem,3.2vw,1.5rem);flex:none}
/* Gesperrt: keine Bedienspur, kein Spinner, nicht fokussierbar wirkend. */
.pensum-input .input.locked{background:transparent;border-color:var(--lz-line);
  color:var(--lz-ash);cursor:default}
.pensum-input.open .input{background:var(--lz-surface);border-color:var(--lz-line-ui);color:var(--lz-bone)}
.pensum-input.open .input:focus{border-color:var(--lz-blood);color:var(--lz-white)}
/* Die Zahlenpfeile von Chrome/Safari kosten hier nur Breite. */
.pensum-input .input::-webkit-outer-spin-button,
.pensum-input .input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.pensum-input .input[type=number]{-moz-appearance:textfield;appearance:textfield}

.aiout{font-family:var(--lz-mono);font-size:.85rem;border:1px solid var(--lz-line);padding:1rem;margin-top:1rem;background:var(--lz-ink)}
.aiout .big{font-family:var(--lz-display);color:var(--lz-blood);font-size:2.4rem;line-height:1}
.spin{display:inline-block;width:14px;height:14px;border:2px solid var(--lz-ash);border-top-color:var(--lz-blood);
  border-radius:50%;animation:sp .7s linear infinite;vertical-align:middle}
@keyframes sp{to{transform:rotate(360deg)}}

/* === FOOTER ====================================================== */
/* Ein Footer fuer alle Seiten — gebaut von renderFooter() in app.js.
   Die Wortmarke ist die SVG (siehe .wordmark), nicht mehr gesetzter Text:
   darum gibt es hier kein "footer .word b" mehr. */
footer{position:relative;padding:var(--lz-stack) var(--lz-gutter) 2.5rem;
  border-top:1px solid var(--lz-line);overflow:hidden}
/* Der Puls ist der eine Blood-Fokus des Fusses. Er sitzt in der oberen
   Polsterung, nicht ueber dem Inhalt: --lz-stack ist mindestens 4rem,
   der Streifen hoechstens 96px — sie kollidieren nie. */
footer .pulseband-foot{position:absolute;left:0;top:0;width:100%;
  height:clamp(52px,7vw,96px);pointer-events:none;opacity:.9}
footer .word{position:relative;display:block;font-size:var(--lz-screamer);line-height:.85;
  color:var(--lz-bone);transition:color var(--lz-fast)}
/* Zeichen ueber der Wortmarke — in Bone, weil Blood im Fuss schon an
   den Puls vergeben ist (Regel: ein Fokus pro Gruppe). */
footer .word .mark-foot{height:clamp(30px,4vw,56px);margin-bottom:clamp(.9rem,1.6vw,1.5rem)}
footer .word:hover{color:var(--lz-white)}
/* Der Fuss steht in der Schale wie alles andere — ohne das liefe er auf
   einem breiten Schirm bis an beide Raender auseinander, waehrend der
   Inhalt darueber bei 1200px endet. */
footer .foot-grid,footer .meta{max-width:var(--lz-shell);margin-inline:auto}

/* Zwei Bereiche: das Zeichen links, die Sitemap rechts daneben. Das
   Logo bleibt gross (es ist der Abbinder der Seite), die Links daneben
   sind bewusst klein — sie sollen auffindbar sein, nicht laut. */
footer .foot-grid{display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:clamp(2rem,5vw,5rem);align-items:start}
/* Drei gleich breite Spalten, nicht drei inhaltsbreite: sonst enden die
   Hairlines unter den Koepfen auf drei verschiedenen Laengen und das
   Raster sieht aus wie verrutscht. Die Breite richtet sich nach dem
   laengsten Eintrag ("Nutzungsbedingungen"), alle drei tragen sie mit. */
footer .foot-cols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(1.6rem,4vw,3.5rem);min-width:min(100%,34rem)}
/* Unter 900px passen Logo und drei Spalten nicht mehr nebeneinander:
   das Zeichen geht nach oben, die Spalten darunter. Unter 520px bleiben
   zwei Spalten — drei waeren dort je vier Zeichen breit. */
@media(max-width:900px){
  footer .foot-grid{grid-template-columns:minmax(0,1fr);gap:2.5rem}
}
@media(max-width:520px){
  footer .foot-cols{grid-template-columns:repeat(2,minmax(0,1fr));gap:1.8rem}
}
/* Unter 400px reicht auch fuer zwei Spalten die Breite nicht mehr:
   "Nutzungsbedingungen" muesste dann mitten im Wort brechen. Eine
   Spalte ist auf einem so schmalen Schirm ohnehin die ehrlichere Form. */
@media(max-width:400px){
  footer .foot-cols{grid-template-columns:minmax(0,1fr);gap:1.6rem}
}

/* Der Spaltenkopf traegt WAS, die Liste darunter WOHIN — derselbe Bau wie
   ein Blockkopf, nur leise. Echtes h2, kein span. */
footer .foot-h{font-family:var(--lz-mono);font-weight:700;font-size:var(--lz-label);
  letter-spacing:.18em;text-transform:uppercase;color:var(--lz-bone);
  margin:0 0 .9rem;padding-bottom:.7rem;border-bottom:1px solid var(--lz-line)}
footer .foot-col ul{list-style:none;margin:0;padding:0}
footer .foot-col li{margin-bottom:.5rem}
/* Kein white-space:nowrap: "Nutzungsbedingungen" ist 157px breit und
   sprengte damit auf einem 320px-Schirm die Spalte — die ganze Seite
   scrollte quer. Umbrechen darf es, notfalls im Wort. */
footer .foot-col a{font-family:var(--lz-mono);font-size:var(--lz-caption);letter-spacing:.08em;
  color:var(--lz-ash);transition:color var(--lz-fast);overflow-wrap:break-word}
footer .foot-col a:hover,footer .foot-col a:focus-visible{color:var(--lz-bone)}

footer .meta{display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;margin-top:2.5rem}
footer .meta span,footer .meta a{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:.16em;text-transform:uppercase;color:var(--lz-ash)}
footer .meta a{transition:color var(--lz-fast)}
footer .meta a:hover{color:var(--lz-bone)}

/* Die Schlusszeile steht UNTER der Sitemap und leiser als sie: eine
   Hairline trennt das Pflichtteil vom Angebot. Keine eigene Farbe — der
   Fuss traegt schon genug Grautoene, ein weiterer waere Laerm. */
footer .meta.legal{margin-top:clamp(2.5rem,5vw,4rem);padding-top:1.6rem;
  border-top:1px solid var(--lz-line);gap:1.6rem}
@media(max-width:640px){footer .meta.legal{justify-content:flex-start}}

/* Die Herkunft. Das Herz ist der einzige Farbton im Fuss — klein genug,
   dass es nicht mit der roten Flaeche der Seite konkurriert, gross genug,
   dass man es sieht. Es sitzt auf der Grundlinie der Mono-Schrift, nicht
   mittig: sonst schwimmt es ueber dem Text. */
footer .meta .origin{display:inline-flex;align-items:center;white-space:nowrap}
footer .meta .heart{width:11px;height:11px;flex:none;margin-right:.5em;
  color:var(--lz-blood);position:relative;top:-1px}

/* Die Kanaele: Quadrate, keine Kreise — Radius 0 gilt auch hier.
   Glyph in Ash wie jede Nebenschrift, erst beim Zeigen wird er hell.
   Blood bleibt aussen vor: der Fuss ist die leiseste Flaeche der Seite. */
footer .social{display:flex;gap:.6rem;margin-top:2.2rem;flex-wrap:wrap}
footer .social .sq{display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border:1px solid var(--lz-line);color:var(--lz-ash);
  transition:color var(--lz-fast),border-color var(--lz-fast),background var(--lz-fast)}
footer .social .sq svg{width:18px;height:18px;display:block}
footer .social .sq:hover{color:var(--lz-bone);border-color:var(--lz-line-ui);background:var(--lz-surface)}
footer .social .sq:focus-visible{color:var(--lz-bone);border-color:var(--lz-bone)}

/* Die Adresse ohne JavaScript: derselbe Ton wie der Link, den sie
   ersetzt — sonst faellt auf einer Seite ohne JS ein Loch auf. */
.mailto{font-family:var(--lz-mono)}
span.mailto{color:var(--lz-ash);cursor:text;-webkit-user-select:all;user-select:all}

/* --- Puls-Streifen als Sektionsmarke --------------------------------- *
 * Das Lazarus-Motiv: Flatline, dann ein Herzschlag. Wird von
 * assets/glut.js gezeichnet — ohne JS bleibt die Flaeche leer, nichts
 * verrutscht. Canvas ist ein replaced element: Breite/Hoehe stehen hier,
 * die Bitmap setzt glut() explizit nach (sonst rendert es winzig).       */
.pulseband{position:relative;height:clamp(64px,9vw,120px);overflow:hidden}
.pulseband canvas{display:block;width:100%;height:100%}
/* Als Trenner im Textfluss: die Flatline ersetzt die Hairline, die hier
   sonst staende. Volle Sektionsbreite, darum die negativen Raender. */
.pulseband-rule{margin:clamp(1.2rem,2.5vw,2rem) calc(-1 * var(--lz-gutter)) clamp(1.4rem,3vw,2.4rem);
  border-top:1px solid var(--lz-line);border-bottom:1px solid var(--lz-line)}

/* Am Fuss des Heros: sitzt auf der Kante, halb im Bild.
   z-index 1 = ueber Foto und Scrim, aber UNTER der Headline (.inner,
   z-index 2). "Text schlaegt Raster": auf schmalen Viewports reicht die
   Zeile "RUN" bis in das Band hinunter, und der Puls darf sie nicht
   ueberschreiben. pointer-events aus, damit der Scroll-Hinweis
   klickbar bleibt.                                                     */
.hero .pulseband{position:absolute;left:0;right:0;bottom:0;z-index:1;
  pointer-events:none;height:clamp(56px,7vw,96px)}

/* === EDITORIAL / CONTENT-SEITEN ================================== */
.article{max-width:780px}
.article .lead-blood{font-size:var(--lz-lead);color:var(--lz-blood);font-weight:600;margin:1rem 0 0}
.article h2{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:clamp(1.7rem,1rem + 3.5vw,3rem);line-height:.98;letter-spacing:var(--lz-track-tight);
  margin:clamp(2.6rem,5vw,4rem) 0 1rem}
.article p{color:var(--lz-bone);font-size:1.05rem;line-height:1.7;margin-bottom:1.1rem;max-width:68ch}
.article p.muted{color:var(--lz-ash)}

/* --- Rechtstexte (Impressum, Datenschutz, Nutzungsbedingungen) ------ *
 * Diese Seiten sind die Ausnahme von "Regelwerke sind Zeilen, keine
 * Kapitel": ein Datenschutzhinweis MUSS am Stueck lesbar sein, ohne dass
 * man 40 Zeilen aufklappt. Also echter Fliesstext — aber mit den Mitteln
 * des Hauses: Display nur fuer h2, Mono fuer die Ordnungsebene darunter,
 * Hairlines statt Kaesten, Radius 0.
 * h3 ist bewusst KEIN Display: sonst schreien auf einer Seite mit 30
 * Ueberschriften alle gleich laut und keine fuehrt mehr.               */
.article h3{font-family:var(--lz-mono);font-weight:700;text-transform:uppercase;
  letter-spacing:.14em;font-size:.85rem;color:var(--lz-bone);
  margin:2.2rem 0 .8rem}
.article h2 + h3{margin-top:1.4rem}
.article ul,.article ol{color:var(--lz-bone);font-size:1.05rem;line-height:1.7;
  max-width:68ch;margin:0 0 1.1rem;padding-left:1.4rem}
.article li{margin-bottom:.45rem}
.article li::marker{color:var(--lz-ash)}
.article a:not(.btn){color:var(--lz-blood);text-decoration:underline;
  text-underline-offset:.2em;text-decoration-thickness:1px}
.article a:not(.btn):hover{color:var(--lz-bone)}
.article dt{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.14em;
  text-transform:uppercase;color:var(--lz-ash);margin-top:1rem}
.article dd{color:var(--lz-bone);font-size:1.05rem;line-height:1.7;margin:.2rem 0 0}
/* Die Anschrift steht als Block, nicht als Absatz: sie wird gelesen wie
   ein Briefkopf, nicht wie ein Satz. */
.article address{font-style:normal;color:var(--lz-bone);font-size:1.05rem;line-height:1.7;
  margin-bottom:1.1rem}

/* Verarbeitungsuebersicht im Datenschutz. Eine echte Tabelle, weil es
   eine echte Tabelle IST — vier Spalten, die man quer vergleicht.
   Scrollt auf schmalen Schirmen in sich, statt die Seite zu sprengen. */
.legaltable{overflow-x:auto;margin:0 0 1.6rem;border:1px solid var(--lz-line)}
.legaltable table{border-collapse:collapse;width:100%;min-width:640px}
.legaltable th,.legaltable td{text-align:left;vertical-align:top;padding:.85rem 1rem;
  border-bottom:1px solid var(--lz-line);font-size:.92rem;line-height:1.55}
.legaltable th{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.14em;
  text-transform:uppercase;color:var(--lz-ash);background:var(--lz-surface);font-weight:700}
.legaltable td{color:var(--lz-bone)}
.legaltable tr:last-child td{border-bottom:0}
.legaltable td:first-child{font-family:var(--lz-mono);font-size:.82rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--lz-bone);white-space:nowrap}

/* Stand-Zeile am Kopf eines Rechtstexts. */
.article .stand{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.14em;
  text-transform:uppercase;color:var(--lz-ash);margin:1.4rem 0 0}
.pullquote{font-family:var(--lz-display);text-transform:uppercase;color:var(--lz-blood);
  font-size:clamp(1.7rem,1rem + 3.6vw,3.2rem);line-height:1.02;letter-spacing:var(--lz-track-tight);
  border-left:3px solid var(--lz-blood);padding-left:1.2rem;margin:clamp(1.8rem,3vw,2.6rem) 0}

/* Stufen-Liste */
.stufen{list-style:none;border-top:1px solid var(--lz-line);margin-top:1rem}
.stufen li{border-bottom:1px solid var(--lz-line);padding:1rem 0;display:flex;flex-wrap:wrap;gap:.3rem 1.2rem;align-items:baseline}
.stufen .nm{font-family:var(--lz-mono);font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--lz-bone);min-width:150px}
.stufen .vals{font-family:var(--lz-mono);color:var(--lz-ash);font-size:.92rem;letter-spacing:.03em}
.stufen .tag{color:var(--lz-blood);font-family:var(--lz-mono);font-size:.76rem;letter-spacing:.12em;text-transform:uppercase}

/* Regeln / Schritte */
.steps{list-style:none;counter-reset:s;margin-top:1rem}
.steps li{counter-increment:s;border-top:1px solid var(--lz-line);padding:1.1rem 0 1.1rem 3rem;position:relative;color:var(--lz-bone)}
.steps li::before{content:counter(s,decimal-leading-zero);position:absolute;left:0;top:1.1rem;
  font-family:var(--lz-mono);color:var(--lz-blood);font-weight:700;font-size:.9rem}
.steps li b{color:var(--lz-white);font-weight:600}

/* Foto-Band (Closing) */
.photoband{position:relative;min-height:60svh;display:flex;align-items:flex-end;padding:var(--lz-stack) var(--lz-gutter);overflow:hidden}
.photoband .bg{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center 35%;filter:var(--lz-photo)}
/* .treated am Band = das Bild bringt s/w und das eine Rot schon mit.
   Dann faellt nicht nur der grayscale weg, auch der Scrim wird leichter:
   der Standard-Scrim ist auf helleres Rohmaterial gerechnet und haette
   das ohnehin dunkle Motiv zugedeckt.                                  */
.photoband.treated .bg{filter:var(--lz-photo-treated)}
.photoband.treated::after{background:linear-gradient(180deg,rgba(12,12,13,.35),rgba(12,12,13,.8))}
.photoband::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(12,12,13,.6),rgba(12,12,13,.92))}
.photoband .c{position:relative;z-index:2;max-width:900px}
.cta-row{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.6rem}

/* Coming-soon Platzhalter */
.soon{min-height:62svh;display:flex;flex-direction:column;justify-content:center}
.soon .tagline{font-size:var(--lz-lead);color:var(--lz-bone);max-width:42ch;margin:1.2rem 0 2rem}
/* .chips/.chip standen unter .soon — und als die Partner-Seite ihren Kopf
   zur roten Flaeche machte, fiel die Klasse weg und die Chips wurden zu
   nacktem, zusammenlaufendem Text. Ein Bauteil, das nur in einem
   bestimmten Elternteil funktioniert, ist kein Bauteil. */
.chips{display:flex;flex-wrap:wrap;gap:.6rem}
.chip{font-family:var(--lz-mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--lz-ash);border:1px solid var(--lz-line-ui);padding:.5rem .8rem}

/* === Ebenen-Trenner (Wettkampf-Layer) =========================== */
.layer{border-top:1px solid var(--lz-line)}
.layer .eyebrow .n{color:var(--lz-bone)}
.layer .soon-tag{color:var(--lz-ash);font-family:var(--lz-display);text-transform:uppercase}

/* === Aufklapp-Infobox (Accordion) =============================== */
.acc{border:1px solid var(--lz-line);background:var(--lz-surface);margin-top:1.8rem;max-width:68ch}
.acc summary{list-style:none;cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:1rem;
  font-family:var(--lz-mono);font-weight:700;text-transform:uppercase;letter-spacing:.1em;font-size:.82rem;
  color:var(--lz-bone);padding:1.1rem 1.3rem;transition:color var(--lz-fast)}
.acc summary:hover{color:var(--lz-blood)}
.acc summary::-webkit-details-marker{display:none}
.acc summary .pm{color:var(--lz-blood);font-size:1.3rem;line-height:1;transition:transform var(--lz-fast) var(--lz-ease)}
.acc[open] summary .pm{transform:rotate(45deg)}
.acc .acc-body{padding:0 1.3rem 1.4rem;border-top:1px solid var(--lz-line)}
.acc .acc-body p{color:var(--lz-bone);font-size:1rem;line-height:1.7;margin:1.1rem 0}

/* === Wettkampf-Rangliste Teaser (gesperrt/abgedunkelt) ========== */
.comp-teaser{position:relative;border-top:1px solid var(--lz-line);padding-top:clamp(3rem,6vw,5rem)}
.comp-teaser .veil{opacity:.22;filter:grayscale(1);pointer-events:none;user-select:none;text-align:center;
  max-width:680px;margin:0 auto}
.comp-teaser .veil .screamer{font-size:clamp(2rem,1rem + 5vw,4.2rem);color:var(--lz-ash)}
.comp-teaser .veil p{color:var(--lz-ash);font-family:var(--lz-mono);font-size:.85rem;letter-spacing:.06em;margin-top:1rem}
.comp-teaser .veil .ghostrows{margin-top:2rem;border-top:1px solid var(--lz-line)}
.comp-teaser .veil .ghostrows span{display:block;height:46px;border-bottom:1px solid var(--lz-line)}
.comp-teaser .lockline{position:absolute;left:50%;top:54%;transform:translate(-50%,-50%);
  font-family:var(--lz-mono);font-size:.74rem;letter-spacing:.2em;text-transform:uppercase;color:var(--lz-ash);
  border:1px solid var(--lz-line);padding:.55rem .95rem;background:var(--lz-ink);white-space:nowrap}

/* === AVATAR / PROFIL-PANEL ====================================== */
.avatar{display:inline-flex;align-items:center;justify-content:center;width:46px;height:46px;
  border:1px solid var(--lz-line);background-size:cover;background-position:center;background-color:var(--lz-surface);
  filter:var(--lz-photo);overflow:hidden;flex:0 0 auto}
.avatar-ph{font-family:var(--lz-display);color:var(--lz-blood);font-size:1.05rem;letter-spacing:.04em;filter:none}
.avatar-lg{width:84px;height:84px}
.avatar-lg.avatar-ph{font-size:1.9rem}

.profile-head{display:flex;align-items:center;gap:1.2rem;margin-bottom:1.6rem}
/* .avatar-edit steht im Abschnitt MEDIA am Ende der Datei. */
/* Ein Anzeigename darf 40 Zeichen haben und muss kein Leerzeichen enthalten
   (Migration 0001, konto.html ohne Muster). 40 Buchstaben am Stueck sind
   die groesste nutzergesteuerte Schrift der Seite — ohne Umbruchfreigabe
   schiebt ein einziger solcher Name das Dokument bei 360px auf 643px und
   reisst damit die erste und haerteste Regel: kein waagerechtes Scrollen.
   Dieselbe Freigabe steht aus demselben Grund schon an .foot-col a und an
   .badge-name. Gemessen 09/2026. */
.profile-id .name{font-weight:700;overflow-wrap:break-word}

.badge-admin{font-family:var(--lz-mono);font-weight:700;font-size:.6rem;letter-spacing:.14em;
  color:var(--lz-blood);border:1px solid var(--lz-blood);padding:.12rem .4rem;margin-left:.5rem;vertical-align:middle}

.user-row{grid-template-columns:auto 1fr!important}

.hide{display:none!important}

/* ==== Lazarus-Status-Badge & Athleten-Links (0006) ================== */
/* Radius 0 gilt auch fuer den Status: die 2px, die hier standen, waren
   die einzige runde Ecke der ganzen Seite. */
.tierbadge{display:inline-block;padding:.32rem .6rem;
  font:600 var(--lz-micro)/1 var(--lz-mono);
  letter-spacing:.12em;border:1px solid;border-radius:0;text-transform:uppercase}
.tierbadge.t-full{color:var(--lz-blood);border-color:var(--lz-blood)}
/* Zweitfarben kommen aus den Tokens. Vorher standen hier eigene Hex-Werte
   (#e0a83a / #54c98a) neben --lz-warn / --lz-ok — vier Werte fuer zwei
   Farben, je nach Seite mal so, mal so. */
.tierbadge.t-half{color:var(--lz-warn);border-color:var(--lz-warn)}
.tierbadge.t-quarter{color:var(--lz-ok);border-color:var(--lz-ok)}
.tierbadge.none{color:var(--lz-ash);border-color:var(--lz-ash)}
.row-entry .name a.athlete-link{color:inherit;text-decoration:none;border-bottom:1px solid transparent;transition:color .15s,border-color .15s}
.row-entry .name a.athlete-link:hover{color:var(--lz-blood);border-color:var(--lz-blood)}

/* ==== Community-Ausbau (0007): Badges, Goals, Gruppen, Fotos ======== */
/* 8.75rem = 140px. minmax(9.5rem)=152px verfehlte bei 390px die zweite
   Spalte um 15px (verfuegbar 297,4px, gebraucht 312px) — 23 Karten
   standen dann untereinander. Icon, Titel und eine Zeile Text tragen
   140px problemlos. */
.badge-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,8.75rem),1fr));gap:.5rem}
.badge-card{border:1px solid var(--lz-line);background:var(--lz-surface-2);padding:.9rem .8rem;
  display:flex;flex-direction:column;gap:.3rem;transition:border-color var(--lz-fast) var(--lz-ease)}
.badge-card .badge-icon{font-size:1.4rem;line-height:1}
.badge-card .badge-name{font:700 var(--lz-label)/1.2 var(--lz-mono);letter-spacing:.06em;
  text-transform:uppercase;overflow-wrap:break-word}
.badge-card .badge-desc{font-size:var(--lz-label);color:var(--lz-ash);line-height:1.35}
.badge-card.earned{border-color:var(--lz-blood)}
.badge-card.earned .badge-icon{color:var(--lz-blood)}
.badge-card.earned.elite{border-color:var(--lz-warn);box-shadow:0 0 14px var(--lz-warn-glow)}
.badge-card.earned.elite .badge-icon{color:var(--lz-warn)}
/* Gesperrt: NICHT opacity:.35 — das drueckte den Text auf 1,67:1, also
   weit unter jede lesbare Grenze, und liess die Karte trotzdem stehen.
   Zuruecktreten heisst FEHLENDE Flaeche, nicht Nebel. */
.badge-card.locked{background:transparent;border-style:dashed;border-color:var(--lz-line)}
.badge-card.locked .badge-icon,.badge-card.locked .badge-name{color:var(--lz-ash)}
.badge-card:hover{border-color:var(--lz-ash)}

.goal-row{display:flex;align-items:center;gap:1rem;border:1px solid var(--lz-line);
  background:var(--lz-surface);padding:.8rem 1rem;margin-bottom:.6rem;flex-wrap:wrap}
.goal-row .tiername{font:700 var(--lz-label)/1 var(--lz-mono);letter-spacing:.08em;text-transform:uppercase;min-width:110px}
.goal-row .countdown{font:700 1.05rem/1 var(--lz-mono);color:var(--lz-blood)}
.goal-row .countdown.done{color:var(--lz-ok)}
.goal-row .countdown.over{color:var(--lz-warn)}
.goal-row .gmeta{font-size:var(--lz-label);color:var(--lz-ash)}
.goal-row .spacer{flex:1}

.group-card{border:1px solid var(--lz-line);background:var(--lz-surface);
  padding:0;margin-bottom:.8rem;overflow:hidden}
/* Die Mitgliederzeile der Crew-Seite. Stand vorher als
   style="grid-template-columns:auto 1fr auto" im Markup — zwei Fehler in
   einer Zeile: ein harter Wert im Markup (verboten), und ein nacktes 1fr,
   das die Regel in der Medienabfrage still ueberschrieb. Ein 40-Zeichen-
   Name schob den Stufen-Badge dadurch bis auf 479px hinaus, das Dokument
   mit ihm. minmax(0,1fr) laesst die Spalte schrumpfen, der Name bricht um. */
.row-member{grid-template-columns:auto minmax(0,1fr) auto}
/* Dieselbe Geschichte, zwei weitere Fundstellen: Kennzahlenzeile der
   Crew-Seite und Zeile im Crew-Verzeichnis. Beide standen als harter
   Wert im Markup mit nacktem 1fr. In admin.html stehen noch zwei —
   die Datei ist fremde offene Arbeit und bleibt unberuehrt. */
.row-stat{grid-template-columns:minmax(0,1fr) auto}
.row-crewlist{grid-template-columns:minmax(0,1fr) auto auto}

/* max-width + Umbruchfreigabe aus demselben Grund wie an .profile-id .name:
   ein Anzeigename darf 40 Zeichen ohne Leerzeichen haben. Ein inline-flex
   ohne Deckel waechst daran ueber die Schale hinaus — gemessen schob eine
   Mitgliederkachel gruppe.html bei 360px auf 479px. */
.member-chip{display:inline-flex;align-items:center;gap:.4rem;border:1px solid var(--lz-line);
  padding:.25rem .6rem;margin:.15rem .25rem .15rem 0;font-size:.75rem;font-family:var(--lz-mono);
  max-width:100%;overflow-wrap:anywhere}
.member-chip.invited{opacity:.5;border-style:dashed}
.soonbox{border:1px dashed var(--lz-line);color:var(--lz-ash);padding:.7rem 1rem;
  font:600 .7rem/1.4 var(--lz-mono);letter-spacing:.08em;text-transform:uppercase;margin-top:.8rem}

.respect-btn{display:inline-flex;align-items:center;gap:.35rem;border:1px solid var(--lz-line);
  background:none;color:var(--lz-bone);font:600 var(--lz-label)/1 var(--lz-mono);letter-spacing:.06em;
  padding:.4rem .65rem;cursor:pointer;transition:all var(--lz-fast) var(--lz-ease)}
.respect-btn:hover{border-color:var(--lz-blood)}
.respect-btn.mine{border-color:var(--lz-blood);color:var(--lz-blood)}
/* Eigener Eintrag: Zaehler statt Knopf — Selbst-Respect blockt Policy 0009. */
.respect-btn.static{cursor:default;color:var(--lz-ash)}
.respect-btn.static:hover{border-color:var(--lz-line)}
/* .runphotos: siehe Abschnitt MEDIA am Ende der Datei. */

.regionline{font-size:var(--lz-caption);color:var(--lz-ash);font-family:var(--lz-mono)}
.regionline b{color:var(--lz-bone)}

/* ==== User-Dropdown in der Nav ====================================== */
.usermenu{position:relative;display:inline-block}
.usertrigger{display:inline-flex;align-items:center;gap:.5rem;background:none;
  border:1px solid var(--lz-line);color:var(--lz-bone);cursor:pointer;
  padding:.5rem .85rem;transition:border-color var(--lz-fast) var(--lz-ease)}
.usertrigger:hover,.usertrigger[aria-expanded="true"]{border-color:var(--lz-blood)}
.usertrigger .who{color:var(--lz-bone)}
.usertrigger .caret{color:var(--lz-ash);font-size:.7rem;line-height:1}
.userdrop{position:absolute;right:0;top:calc(100% + 10px);min-width:200px;z-index:80;
  background:var(--lz-surface);border:1px solid var(--lz-line);display:none;flex-direction:column;
  box-shadow:0 14px 40px rgba(0,0,0,.55)}
.userdrop.open{display:flex}
.userdrop a{padding:.75rem 1.1rem;color:var(--lz-bone);text-decoration:none;
  font:600 .7rem/1 var(--lz-mono);letter-spacing:.1em;text-transform:uppercase;
  border-bottom:1px solid var(--lz-line);transition:background var(--lz-fast) var(--lz-ease),color var(--lz-fast) var(--lz-ease)}
.userdrop a:hover{background:var(--lz-surface-2);color:var(--lz-blood)}
.userdrop a.logoutline{color:var(--lz-blood);border-bottom:none;margin-top:.45rem;border-top:1px solid var(--lz-line)}
@media (max-width:760px){
  .userdrop{position:static;box-shadow:none;margin-top:.4rem;border-left:2px solid var(--lz-blood)}
}

/* ==== Gruppen-Seite: breites zweispaltiges Layout ==================== */
.groups-layout{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(300px,1fr);
  gap:clamp(1.5rem,1rem + 3vw,4rem);align-items:start;margin-top:1.6rem}
@media (max-width:900px){.groups-layout{grid-template-columns:1fr}}
/* Kopf, Abschnitte und Polsterung der Karte stehen weiter oben bei
   "GRUPPENKARTE" — hier bleiben nur die Teile, die dort nicht hingehoeren. */
.group-card .ghead{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.group-card .gactions{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center}
.group-card .cform{margin-top:.5rem;display:flex;gap:.6rem;flex-wrap:wrap}
.group-card .cform .input{flex:1;min-width:220px}
.sticky-side{position:sticky;top:calc(var(--lz-barh) + 1.4rem)}

/* ==== Athleten-Profil: breites zweispaltiges Layout ================== */
.profil-layout{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);
  gap:clamp(1.5rem,1rem + 3vw,4rem);align-items:start}
@media (max-width:900px){.profil-layout{grid-template-columns:1fr}}

/* === PASSWORT-FELDER (Anzeigen-Toggle + Live-Anforderungen) ========= */
.pwtoggle{position:absolute;right:0;top:0;height:100%;padding:0 .9rem;background:transparent;
  border:0;border-left:1px solid var(--lz-line);color:var(--lz-ash);cursor:pointer;
  font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);transition:color var(--lz-fast)}
.pwtoggle:hover{color:var(--lz-bone)}
.pwreqs{list-style:none;margin:-.4rem 0 1.2rem;padding:0;
  font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.06em;color:var(--lz-ash)}
.pwreqs li{padding:.28rem 0 .28rem 1.4rem;position:relative}
.pwreqs li::before{content:"–";position:absolute;left:0;color:var(--lz-ash)}
.pwreqs li.met{color:var(--lz-bone)}
.pwreqs li.met::before{content:"✓";color:var(--lz-ok)}

/* ==== RANGLISTE: Sortierung, Pensum, Verifizierung, Touch-Ziele =======
   Alles hier haengt an Tokens. Vorher standen im Markup der Rangliste
   zwei Gruen- und zwei Bernstein-Werte (#54c98a / #e0a83a) neben
   --lz-ok / --lz-warn und eine hartcodierte Schriftfamilie. */

/* Verifizierungs-Badge — eine Klasse fuer Zeit-Board und 24h-Liste. */
.vbadge{display:inline-block;margin-top:.3rem;font-family:var(--lz-mono);font-weight:600;
  font-size:var(--lz-micro);line-height:1;letter-spacing:.08em}
.vbadge.ok{color:var(--lz-ok)}
.vbadge.warn{color:var(--lz-warn);letter-spacing:.06em}

/* Das Pensum steht an jeder Stufe — die Zahlen sind das Logo, nicht
   der Stufenname. Drei Zahlen, Push/Pull/Run, ohne Leerzeichen. */
.row-entry .meta .pensum{color:var(--lz-blood)}
.board-pensum{display:block;font-family:var(--lz-display);color:var(--lz-blood);
  font-size:clamp(2.4rem,1rem + 7vw,5.5rem);line-height:.9;
  letter-spacing:var(--lz-track-tight);margin:.2rem 0 .4rem}
.board-pensum .unit{font-size:.32em;color:var(--lz-ash);letter-spacing:var(--lz-track-label);
  font-family:var(--lz-mono);vertical-align:.9em}

/* Das Zeit-Board hat eine Spalte mehr als die anderen Listen: das Datum
   ist sortierbar, also muss es auch sichtbar sein. Nur hier, deshalb an
   .board-time gehaengt — .row-entry bleibt fuer athlet/gruppe unveraendert. */
.board-time .lb-head,
.board-time .row-entry{grid-template-columns:54px minmax(0,1fr) 5.5rem 6rem minmax(0,15rem)}
.board-time .row-entry .date{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:.06em;color:var(--lz-ash);white-space:nowrap}
/* Feste Spalten fuer Datum, Zeit und Aktionen: nur so stehen Kopfzeile
   und Datenzeilen uebereinander — zwei getrennte Grids richten sich
   sonst jeweils an ihrem eigenen Inhalt aus. Die Aktionen duerfen dafuer
   umbrechen (eigene Zeile bekommen sie nur, wenn wirklich noetig). */
.board-time .row-entry .act{flex-wrap:wrap}
.board-time .row-entry .time{text-align:right}

/* Sortierbare Kopfzeile ueber dem Zeit-Board (role=table/row/columnheader). */
.lb-head{display:grid;gap:1rem;align-items:center;padding:.6rem 0;
  border-bottom:1px solid var(--lz-line)}
.lb-head .ch{font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-ash)}
.sortbtn{background:none;border:0;padding:.35rem .1rem;cursor:pointer;color:var(--lz-ash);
  font-family:var(--lz-mono);font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);display:inline-flex;align-items:center;gap:.4rem;
  min-height:32px;transition:color var(--lz-fast) var(--lz-ease)}
.sortbtn:hover{color:var(--lz-bone)}
.sortbtn .arrow{font-size:.9em;opacity:.35}
[aria-sort="ascending"] .sortbtn,[aria-sort="descending"] .sortbtn{color:var(--lz-blood)}
[aria-sort="ascending"] .sortbtn .arrow,[aria-sort="descending"] .sortbtn .arrow{opacity:1}
.lb-head .ch.num{text-align:right}
.board-pensum[hidden],.board-more[hidden],.lb[hidden],#moreBtn[hidden]{display:none}

/* Deckel mit Ansage: das Board laedt seitenweise nach, nie alles auf einmal. */
.board-more{display:flex;align-items:center;gap:1rem;flex-wrap:wrap;
  padding:1.1rem 0;border-bottom:1px solid var(--lz-line)}
.board-more .count{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:.08em;text-transform:uppercase;color:var(--lz-ash)}

/* Crew- und Bundesland-Wertung: rechts steht die Groesse, nach der
   sortiert wird. Eine Bestzeit rechts neben einer Sortierung nach
   Aktivitaet liest sich wie ein Sortierfehler. */
.row-entry .time .unit{font-family:var(--lz-mono);font-size:.62em;color:var(--lz-ash);
  letter-spacing:var(--lz-track-label)}

/* Respect-Faust und Sprechblase: monochrom, currentColor — die Seite kennt
   genau einen Akzent. Ein farbiges Emoji war das einzige bunte Element. */
.ico-fist,.ico-talk{width:1.05em;height:1.05em;flex:0 0 auto;display:block}

/* Zahlen stehen immer, auch die Null: gleiche Knopfbreite im Raster,
   und "noch keiner" ist von "kaputt" unterscheidbar. */
.rcount,.cnum{font-variant-numeric:tabular-nums;min-width:1.4ch;text-align:right;
  display:inline-block}
.rcount.zero,.cnum.zero{color:var(--lz-ash);font-weight:400}

/* Touch-Ziele: Maus 34px, Finger 44px. Das Raster bleibt, weil die
   Aktionsspalte auf Mobil ohnehin in eigener Zeile steht. */
.respect-btn,.iconbtn{min-height:34px;display:inline-flex;align-items:center;gap:.35rem}
@media (pointer:coarse){
  .respect-btn,.iconbtn{min-height:44px;padding-left:.9rem;padding-right:.9rem}
  .sortbtn{min-height:44px}
}
@media(max-width:600px){
  /* Die Aktionsspalte faellt ohnehin in eine eigene Zeile (Regel oben),
     Datum und Zeit bleiben nebeneinander stehen. */
  .board-time .lb-head,
  .board-time .row-entry{grid-template-columns:32px minmax(0,1fr) 4.4rem 4.6rem;gap:.5rem .7rem}
  .board-time .row-entry .date{font-size:.64rem}
}

/* ==== EINLADUNGSLINK ================================================
   Zwei Seiten desselben Vorgangs: der Owner erzeugt den Link auf
   gruppen.html, der Eingeladene landet mit ihm auf gruppe.html.
   Der Link IST der Beweis der Einladung, also wird er wie ein Passwort
   dargestellt: eigener rot umrandeter Block, nicht eine Zeile im
   Fliesstext — er ist genau einmal sichtbar (siehe Migration 0011). */
.invite-note{font-family:var(--lz-mono);font-size:.72rem;line-height:1.7;letter-spacing:.04em;
  color:var(--lz-ash);margin:.1rem 0 .8rem;max-width:64ch}
.invite-note b{color:var(--lz-bone);font-weight:700}
.invite-note.after{margin:.9rem 0 0}
.invite-out:empty{display:none}
.invite-state{font-family:var(--lz-mono);font-size:.74rem;letter-spacing:.06em;color:var(--lz-bone);
  border-left:2px solid var(--lz-line);padding-left:.75rem;margin:.2rem 0 .9rem}
.invite-state.none{color:var(--lz-ash)}
.invite-state b{color:var(--lz-blood)}

.invite-box{border:1px solid var(--lz-blood);background:var(--lz-surface-2);
  padding:1rem 1.1rem;margin-top:.9rem}
.invite-warn{font-family:var(--lz-mono);font-weight:700;font-size:.7rem;text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-blood);margin-bottom:.5rem}
.invite-url{display:flex;gap:.6rem;flex-wrap:wrap;margin:.7rem 0 .6rem}
.invite-url .input{flex:1;min-width:16rem;background:var(--lz-ink);border-color:var(--lz-blood);
  color:var(--lz-blood);font-weight:700}
.invite-meta{font-family:var(--lz-mono);font-size:.72rem;letter-spacing:.06em;color:var(--lz-ash)}
.invite-meta b{color:var(--lz-bone)}

/* Landeseite: die Einladung steht ueber der Crew-Seite. Man sieht, wo
   man hineingeht, bevor man drueckt. */
.joinland{border:1px solid var(--lz-blood);background:var(--lz-surface);
  padding:clamp(1.5rem,3vw,2.5rem);margin-bottom:clamp(2rem,5vw,3.5rem)}
.joinland.bad{border-color:var(--lz-line)}
.joinland .crew{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:var(--lz-title);line-height:.95;letter-spacing:var(--lz-track-tight);margin:.2rem 0 .7rem}
.joinland .jmeta{font-family:var(--lz-mono);font-size:.76rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--lz-ash)}
.joinland .jmeta b{color:var(--lz-bone)}
.joinland .jactions{display:flex;gap:.7rem;flex-wrap:wrap;align-items:center;margin-top:1.5rem}

/* ====================================================================
   STRUKTUR-BAUTEILE
   Alles hier loest EIN Problem: lange Seiten, auf denen Ueberschrift,
   Liste, Ueberschrift, Liste im selben Ton untereinander standen. Die
   einzige Gliederung war Abstand — und Abstand liest sich beim Scrollen
   nicht als Gliederung. Jetzt gibt es benannte Bloecke mit Flaeche.
   ==================================================================== */

/* --- BLOCK: der eine Baustein --------------------------------------- *
 * Flaeche im zweiten Ton, gefasst von einer Hairline. Kein Radius, kein
 * Schatten — das Designgesetz haelt. Was ihn sichtbar macht, ist der
 * angehobene --lz-surface-Wert oben, nicht eine neue Farbe.              */
.block{background:var(--lz-surface);border:1px solid var(--lz-line);
  padding:clamp(1.1rem,2.2vw,1.9rem)}
.block + .block{margin-top:clamp(.7rem,1.4vw,1.1rem)}

/* Kopfzeile eines Blocks: links WAS, rechts WIE VIEL. Die Zahl rechts ist
   der Grund, warum ein Block ein Block ist — ohne sie ist es eine
   Ueberschrift mit Kasten drumherum. */
.block-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:.5rem 1.5rem;flex-wrap:wrap}
.block-head .t{font-family:var(--lz-mono);font-weight:700;font-size:.82rem;
  text-transform:uppercase;letter-spacing:var(--lz-track-label);color:var(--lz-bone)}
.block-head .n{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:.1em;color:var(--lz-ash);font-variant-numeric:tabular-nums}
.block-head .n b{color:var(--lz-blood);font-weight:700}
.block-body{margin-top:1rem}

/* --- METER: 2px Fortschritt ----------------------------------------- *
 * Kantig, keine Rundung, Blood fuellt. Steht direkt unter der Kopfzeile
 * und beantwortet "wo stehe ich" ohne eine einzige Zahl zu lesen.        */
.meter{height:2px;background:var(--lz-line);margin:.7rem 0 0;overflow:hidden}
.meter > i{display:block;height:100%;background:var(--lz-blood);min-width:0}
.meter.done > i{background:var(--lz-ok)}
@media(prefers-reduced-motion:no-preference){
  .meter > i{transition:width var(--lz-slow) var(--lz-ease)}
}

/* --- SEITENKOPF ------------------------------------------------------ *
 * Jede Unterseite faengt gleich an: Eyebrow, Titel, ein Satz, der sagt
 * wofuer die Seite da ist. Vorher hatte jede Seite ihre eigene Mischung
 * aus .page-top, .board-head und inline-Stilen.                          */
.pagehead{display:grid;gap:1rem clamp(2rem,5vw,4rem);align-items:end;
  grid-template-columns:minmax(0,1fr) auto;
  padding-bottom:clamp(1.6rem,3vw,2.4rem);border-bottom:1px solid var(--lz-line)}
.pagehead .lede{grid-column:1/-1;color:var(--lz-ash);max-width:62ch;margin-top:.2rem}
.pagehead .lede a{color:var(--lz-blood)}
.pagehead .aside{justify-self:end;text-align:right}
@media(max-width:760px){
  .pagehead{grid-template-columns:1fr}
  .pagehead .aside{justify-self:start;text-align:left}
}

/* --- SPRUNGMARKEN "Auf einen Blick" ---------------------------------- *
 * Eine lange Regelseite muss zum Nachschlagen taugen, nicht nur zum
 * Lesen. Ohne diesen Block scrollt man blind.                            */
.toc{margin-top:clamp(1.6rem,3vw,2.4rem)}
/* Kacheln mit eigenem Rahmen statt 1px-Luecken auf einer Linienflaeche:
   bei 7 Eintraegen in 5 Spalten bleiben 3 Zellen leer, und eine leere
   Zelle auf Linienfarbe sieht aus wie ein grauer Klotz. So bleibt der
   Rest der Zeile einfach Blockflaeche. */
.toc .toc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr));
  gap:.5rem;margin-top:1rem}
/* Kachelflaeche ist der GRUND, nicht die hellere Flaeche: die rote "01"
   haelt auf --lz-surface-2 nur 4,05:1, auf --lz-ink dagegen 5,6:1. Sie ist
   Teil des Linknamens ("01 Das Pensum"), also echter Text — 4,5:1 ist
   Pflicht. Nebenwirkung ist erwuenscht: eingelassen statt aufgesetzt. */
.toc .toc-grid a{display:flex;flex-direction:column;gap:.35rem;
  background:var(--lz-ink);border:1px solid var(--lz-line);
  padding:.85rem 1rem;min-height:44px;
  transition:border-color var(--lz-fast) var(--lz-ease),background var(--lz-fast) var(--lz-ease)}
.toc .toc-grid a:hover{border-color:var(--lz-blood)}
.toc .toc-grid .no{font-family:var(--lz-mono);font-weight:700;font-size:var(--lz-label);
  letter-spacing:var(--lz-track-label);color:var(--lz-blood)}
.toc .toc-grid .nm{font-family:var(--lz-grotesk);font-weight:600;font-size:.92rem;color:var(--lz-bone)}

/* --- KAPITEL: die Marke klebt, der Text laeuft ----------------------- *
 * Auf einer 6-Kapitel-Seite verliert man nach zwei Bildschirmen den
 * Bezug, in welchem Kapitel man steht. Die Nummer bleibt deshalb stehen.
 * .flip dreht die Seite — so wandert der Leerraum von Kapitel zu Kapitel.
 * Unter 900px gibt es keinen Leerraum zu verteilen: die Marke legt sich
 * flach ueber den Text und klebt nicht mehr (sonst frisst sie auf dem
 * Handy den halben Schirm).                                              */
.chapter{display:grid;grid-template-columns:minmax(0,11rem) minmax(0,1fr);
  gap:clamp(1.2rem,3vw,3.5rem);align-items:start}
.chapter > .mark{position:sticky;top:calc(var(--lz-barh) + 1.4rem);align-self:start}
.chapter.flip{grid-template-columns:minmax(0,1fr) minmax(0,11rem)}
.chapter.flip > .mark{order:2}
.chapter .mark .no{display:block;font-family:var(--lz-display);font-weight:400;
  font-size:clamp(2.4rem,5vw,4rem);line-height:.8;color:var(--lz-blood);
  letter-spacing:var(--lz-track-tight)}
.chapter .mark .nm{display:block;margin-top:.5rem;font-family:var(--lz-mono);
  font-weight:700;font-size:.82rem;text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-bone)}
.chapter .body{min-width:0}
.chapter .body > .article{max-width:var(--lz-measure)}
@media(max-width:900px){
  .chapter,.chapter.flip{grid-template-columns:1fr;gap:1rem}
  .chapter > .mark,.chapter.flip > .mark{position:static;order:0;
    display:flex;align-items:baseline;gap:.8rem}
  .chapter .mark .no{font-size:2.2rem}
  .chapter .mark .nm{margin-top:0}
}

/* --- REGELKERN: die harte Aussage als Flaeche ------------------------ *
 * Was eine Regel WIRKLICH sagt, stand bisher als Satz im Fliesstext und
 * war von der Herleitung nicht zu unterscheiden. Der Kern steht jetzt
 * abgesetzt: Mono, Bone, links eine Blood-Kante.                         */
.core{border-left:3px solid var(--lz-blood);background:var(--lz-surface);
  padding:clamp(.9rem,2vw,1.3rem) clamp(1rem,2.2vw,1.5rem);
  margin:clamp(1.4rem,2.5vw,2rem) 0;max-width:var(--lz-measure)}
.core .k{display:block;font-family:var(--lz-mono);font-weight:700;font-size:var(--lz-label);
  text-transform:uppercase;letter-spacing:var(--lz-track-label);color:var(--lz-blood);
  margin-bottom:.5rem}
.core p{color:var(--lz-bone);font-size:1rem;line-height:1.6;margin:0;max-width:none}
.core p + p{margin-top:.6rem}

/* --- DATENBLOCK: Liste mit Kopf -------------------------------------- *
 * Rangliste, Crews, Bestzeiten, Mitglieder: ueberall dieselbe Figur —
 * eine benannte Ueberschrift und darunter Zeilen. Vorher war die
 * Ueberschrift eine .label-Zeile mit inline-Rand und die Zeilen liefen
 * direkt in die naechste Ueberschrift.                                   */
.dblock{margin-top:clamp(2rem,4vw,3rem)}
.dblock > .block-head{padding-bottom:.7rem;border-bottom:1px solid var(--lz-line)}
.dblock > .block-head .t{color:var(--lz-blood)}
.dblock .dnote{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.06em;
  color:var(--lz-ash);margin:.7rem 0 0}
.dblock .dbody{margin-top:.2rem}

/* Zwei Bloecke nebeneinander, wo Platz ist — sonst untereinander. */
.duo{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr));
  gap:clamp(1rem,2vw,1.6rem);align-items:start}

/* --- BADGE-WAND ------------------------------------------------------ *
 * Vorher: pro Gruppe eine graue Label-Zeile, darunter ein Grid, alles im
 * selben Ton — sechs Gruppen und knapp 30 Karten als eine einzige Flaeche.
 * Bei einem frischen Profil sind 28 davon gesperrt und stehen auf 35%
 * Deckkraft: die Seite las sich als grauer Teppich.
 * Jetzt ist jede Gruppe ein Block mit Zaehler und 2px-Fortschritt.
 * Erreichtes steht im Block vorn, Gesperrtes hinten — sortiert in
 * badges.js, nicht mit order:, damit die Reihenfolge in der Vorlesereihe
 * dieselbe ist wie im Bild.                                              */
.badge-wall{display:grid;gap:clamp(.7rem,1.4vw,1.1rem)}
.badge-block .badge-grid{margin-top:1.1rem}
/* Zusammenfassung ueber der Wand: eine Zahl, gross. */
.badge-sum{display:flex;align-items:baseline;gap:.8rem;flex-wrap:wrap;margin-bottom:.2rem}
.badge-sum .big{font-family:var(--lz-display);font-size:clamp(2.2rem,1rem+4vw,3.4rem);
  line-height:.85;color:var(--lz-blood);letter-spacing:var(--lz-track-tight)}
.badge-sum .of{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:var(--lz-track-label);text-transform:uppercase;color:var(--lz-ash)}

/* Im geflippten Kapitel haengt auch die Textspalte rechts — sonst stuende
   die Marke rechts und der Text bliebe trotzdem links kleben, und der
   Versatz waere nur halb da. */
/* Im geflippten Kapitel wird NICHT zusaetzlich der Text nach rechts
   geschoben. Gemessen war das Ergebnis 321px gegen 339px im normalen
   Kapitel — 18px, also kein Wechsel, sondern Zittern. Grund: rechts sitzt
   dort schon die Marke, die Textspalte kann die Schalenkante nie
   erreichen. Richtig gespiegelt ist es so: Marke links + Text eingerueckt
   (339) gegen Marke rechts + Text an der Schalenkante (120). Zwei klar
   verschiedene Kanten, und der rote Zaehler wechselt sichtbar die Seite. */
.chapter.flip .body > .article,
.chapter.flip .body > .core{width:100%}
@media(max-width:900px){
  .chapter.flip .body > .article,
  .chapter.flip .body > .core{margin-left:0}
}

/* Fliesstext INNERHALB eines Blocks: der Block traegt schon die Flaeche,
   der Absatz braucht nur Groesse und Zeilenhoehe. */
p.block-body,.block-body p{color:var(--lz-bone);font-size:.95rem;line-height:1.6;margin:1rem 0 0;max-width:none}
/* Nachsatz unter einer Liste im Block: das Kleingedruckte, nicht der Kern. */
.block .dnote{font-family:var(--lz-grotesk);font-size:.85rem;line-height:1.6;
  letter-spacing:0;color:var(--lz-ash);margin:1rem 0 0;max-width:70ch}

/* FAQ als eigene Wand statt als Kette von Aufklappern im Fliesstext. */
.faq-wall{display:grid;gap:.5rem;max-width:var(--lz-measure);margin-top:clamp(1.6rem,3vw,2.4rem)}
.faq-wall .acc{margin-top:0;max-width:none}

/* --- GRUPPENKARTE ---------------------------------------------------- *
 * Eine Karte enthaelt bis zu fuenf Abschnitte (Kopf, Mitglieder,
 * Einladungslink, Athlet einladen, Challenge-Hinweis). Die standen alle
 * im selben Ton untereinander und waren nur durch margin getrennt — auf
 * einer Karte mit Owner-Rechten war das eine Wand aus Text und Knoepfen.
 * Jetzt: der Kopf sitzt auf einer eigenen Flaeche, jeder Abschnitt
 * bekommt eine Hairline nach oben und sein Label steht in Blood.        */
.group-card .ghead{background:var(--lz-surface-2);border-bottom:1px solid var(--lz-line);
  padding:1.1rem 1.3rem;align-items:center}
.group-card .gname{font-size:1.15rem;font-weight:700}
.group-card .gdesc{font-size:.85rem;color:var(--lz-ash);margin:.25rem 0 0}
.group-card .gsection{margin:0;padding:1.1rem 1.3rem;border-top:1px solid var(--lz-line)}
.group-card .gsection:first-of-type{border-top:0}
.group-card .gsection > .label{display:block;color:var(--lz-blood);margin-bottom:.6rem}
.group-card .soonbox{margin:0;border:0;border-top:1px solid var(--lz-line);
  padding:.9rem 1.3rem;background:transparent}
@media(max-width:600px){
  .group-card .ghead,.group-card .gsection,.group-card .soonbox{padding-left:1rem;padding-right:1rem}
}

@media(max-width:900px){.sticky-side{position:static}}

/* .t traegt die Gestaltung, das Element traegt die Bedeutung: in einem
   Block-Kopf ist der Titel eine echte Ueberschrift (h2/h3), damit die
   Seite nach dem Umbau nicht aus einer h1 und lauter namenlosen Kaesten
   besteht. Der Browser-Standardstil muss dafuer weichen. */
.block-head h2.t,.block-head h3.t{margin:0;font-size:.82rem;font-weight:700}

/* Werkzeugleiste (Filter der Rangliste): Bloecke haben normalerweise
   Abstand nach unten, diese hier haengt an der Tabelle, die sie steuert. */
.filterbar{margin:1rem 0 1.4rem}
.filterbar .filters{margin:0}

/* --- ABSCHNITTSKOPF -------------------------------------------------- *
 * Auf athlet, gruppe und konto stand ueber jeder Liste
 * <h2 class="label" style="color:...;margin:2.4rem 0 .8rem"> — auf jeder
 * Seite mit einem anderen Rand, und ohne Linie darunter. Zwischen zwei
 * Listen lag damit nur Luft. Jetzt: ein Kopf, eine Linie, ein Abstand.  */
.secthead{font-family:var(--lz-mono);font-weight:700;font-size:.82rem;
  text-transform:uppercase;letter-spacing:var(--lz-track-label);color:var(--lz-blood);
  margin:clamp(2.2rem,4vw,3rem) 0 .9rem;padding-bottom:.7rem;
  border-bottom:1px solid var(--lz-line)}
.secthead:first-child{margin-top:0}
/* Der Hinweissatz gehoert zum Kopf, nicht zur Liste — er steht enger. */
.secthead + .linkline{margin-top:-.3rem;margin-bottom:1rem}

/* --- KAPITELMOTIV ---------------------------------------------------- *
 * Ein Bild im Kapitel, das ueber die Textspalte hinausgeht: die Regeln
 * waren die einzige lange Seite ohne ein einziges Bild und lasen sich
 * dadurch wie ein Formular. Steht als <figure> im Textfluss, nicht als
 * Hintergrund — die Bildunterschrift ist Teil der Regel.               */
.chapter-shot{margin:clamp(1.8rem,3vw,2.6rem) 0;border:1px solid var(--lz-line)}
.chapter-shot img{width:100%;height:auto;display:block;filter:var(--lz-photo-treated)}
.chapter-shot figcaption{font-family:var(--lz-mono);font-size:var(--lz-label);
  letter-spacing:.08em;text-transform:uppercase;color:var(--lz-ash);
  background:var(--lz-surface);padding:.7rem 1rem;border-top:1px solid var(--lz-line)}

/* Push/Pull/Run sind drei GLEICHRANGIGE Dinge und der eine Ort der Seite,
   an dem man drei Sachen nebeneinander vergleicht. .duo (auto-fit,
   minmax(20rem,1fr)) ergab in der Kapitelspalte zwei Spalten: Push und
   Pull nebeneinander, Run allein darunter neben einem Loch. Hier zaehlt
   die Dreiteilung mehr als die automatische Anpassung. */
.trio{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(.6rem,1.2vw,1rem);align-items:stretch}
.trio > .block{display:flex;flex-direction:column}
@media(max-width:860px){.trio{grid-template-columns:1fr}}

/* Ein Abschnittskopf, der ERSTES Kind seines Wrappers ist, bekommt oben
   keinen Rand — sonst stuenden die beiden Spalten eines Profils
   unterschiedlich hoch. Folgt der Wrapper aber selbst auf etwas, muss der
   Rand zurueck: sonst klebt "ZIELE" 12px unter der Crew darueber und nur
   40px ueber dem eigenen Inhalt — die Naehe sagt dann das Gegenteil der
   Bedeutung, und man liest den Kasten unter dem falschen Etikett. */
:where(div,section) + :where(div,section) > .secthead:first-child{
  margin-top:clamp(2.2rem,4vw,3rem)}

/* ====================================================================
   MOBIL- UND BEDIENKORREKTUREN (aus dem Gauntlet 09/2026)
   Alles hier ist gemessen, nicht geschaetzt — die Zahlen stehen dabei.
   ==================================================================== */

/* Anker-Sprung unter der klebenden Kopfleiste. Ohne scroll-margin landete
   ein Sprung aus dem Inhaltsverzeichnis 19px HINTER der 67px hohen Leiste
   — die Kapitelziffer war oben abgeschnitten. Gilt fuer alles, was ein
   Sprungziel sein kann. */
main > section,.layer,.page-top,[id]{scroll-margin-top:calc(var(--lz-barh) + 1.5rem)}

/* Datum in der Rangspalte ist kein Rang: 32px Spalte gegen 43px Inhalt —
   es lief ueber und klebte ohne Abstand am Nachbartext. */
.row-entry .rank.rank-date{font-family:var(--lz-mono);font-size:var(--lz-micro);
  line-height:1.25;color:var(--lz-ash);white-space:normal;word-break:keep-all}


/* Fingerziele. Die pointer:coarse-Regel weiter oben hatte die Segment-
   Filter und das Auswahlfeld nicht erfasst — ausgerechnet die
   meistgenutzten Bedienelemente der Rangliste (gemessen 37px und 41px). */
@media (pointer:coarse){
  .seg button,select.input{min-height:44px}
}
/* Der Hamburger war mit 38x30px das kleinste Ziel im Kopf — und auf Mobil
   der einzige Weg ins Menue. */
.navtoggle{min-width:44px;min-height:44px;align-items:center}
/* Fusszeilen-Links standen in einem 34px-Raster bei 17px Zielhoehe. Die
   Polsterung kostet keine Breite. */
footer .meta a{display:inline-block;padding:.65rem 0}

@media(max-width:600px){
  /* Profilkopf: der 84px-Avatar plus Abstand liess 181px fuer den Text —
     "1 Race · 1x 24h Challenge · dabei seit September 2026" brach auf drei
     Zeilen à 17 Zeichen um. Umbruch statt Quetschen. */
  .profile-head{flex-wrap:wrap}
  .profile-head .profile-id{flex:1 1 100%}

  /* Das Zeit-Board hatte bei 390px noch vier Spalten: fuer Name und Meta
     blieben 125px, das ergab sechs Zeilen à 12 Zeichen bei 227px
     Zeilenhoehe, und das Datum wurde auf 10px heruntergedreht.
     Jetzt: Platz, Name und Zeit in einer Zeile — das Datum rutscht unter
     den Namen, wo es die volle Breite hat. */
  .board-time .lb-head,
  .board-time .row-entry{grid-template-columns:32px minmax(0,1fr) auto}
  .board-time .lb-head .ch:nth-child(3){display:none}
  .board-time .row-entry .date{grid-column:2/-1;grid-row:2;
    font-size:.66rem;margin-top:.15rem}
  .board-time .row-entry .act{grid-row:3}
}

/* Bedienelemente tragen --lz-line-ui, nicht die dekorative Hairline:
   ein Eingabefeld, dessen Rand 1,58:1 haelt, hat fuer viele Augen gar
   keinen sichtbaren Rand (WCAG 1.4.11, 3:1 fuer Bedienelemente). */
.input,select.input,textarea.input,.seg,.btn.ghost,.iconbtn,
.usertrigger,.drop,.respect-btn{border-color:var(--lz-line-ui)}
.seg button{border-right-color:var(--lz-line-ui)}

/* ====================================================================
   RANDLOSE FLAECHEN — die zweite Lautstaerke
   Randlos heisst: ueber die ganze Fensterbreite, ohne Schale. Der Text
   darin startet aber NICHT am Fensterrand, sondern bei 28% — auf
   Mitte-links. Das ist der Unterschied zwischen "Bild mit Text drauf"
   und einem gesetzten Plakat: die Zeile beginnt dort, wo das Auge nach
   dem Sprung ueber die Flaeche ohnehin landet.
   ==================================================================== */
:root{ --lz-slab-start:28%; }

/* --- .slab: die grosse rote Flaeche ---------------------------------- *
 * Blood als FLAECHE, Ink als Schrift — die Umkehrung des ganzen Looks.
 * Genau deshalb wirkt sie: sie kommt selten und dann ganz.
 * Regel: hoechstens eine pro Seite, und nie zwei Sektionen hintereinander. */
.slab{position:relative;background:var(--lz-blood);color:var(--lz-ink);
  min-height:min(78svh,760px);display:flex;align-items:flex-end;
  padding:var(--lz-stack) var(--lz-gutter) clamp(2.5rem,6vw,5rem)}
.slab .c{width:100%;padding-left:max(0px, calc(var(--lz-slab-start) - var(--lz-gutter)))}
.slab .eyebrow{color:var(--lz-ink);opacity:.72}
.slab h2,.slab .screamer{color:var(--lz-ink)}
.slab p{color:var(--lz-ink);font-weight:600;max-width:34ch;margin-top:1.2rem}
/* Der Knopf dreht mit: schwarze Flaeche, rote Schrift. */
.slab .btn{background:var(--lz-ink);color:var(--lz-blood)}
.slab .btn:hover{background:#000}
.slab .btn.ghost{background:transparent;color:var(--lz-ink);border-color:rgba(12,12,13,.45)}
.slab .btn.ghost:hover{border-color:var(--lz-ink)}
.slab a:focus-visible,.slab .btn:focus-visible{outline-color:var(--lz-ink)}
@media(max-width:900px){
  .slab{min-height:auto;padding-top:clamp(3rem,10vw,5rem)}
  .slab .c{padding-left:0}
}

/* --- Fotoband: Bild randlos, Text auf Mitte-links -------------------- */
.photoband .c{max-width:none;width:100%;
  padding-left:max(0px, calc(var(--lz-slab-start) - var(--lz-gutter)))}
.photoband .c p,.photoband .c .lead{max-width:44ch}
@media(max-width:900px){.photoband .c{padding-left:0}}

/* --- Ausblenden statt Strecken --------------------------------------- *
 * Ein Motiv, das den Rahmen nicht fuellt, wurde bisher per cover
 * hochskaliert und dabei unscharf. Mit .fade-r / .fade-l steht es in
 * seiner echten Groesse an einer Kante und laeuft zur anderen hin ins
 * Schwarz aus — kein sichtbarer Rand, keine Unschaerfe.
 * Zwei Ebenen: die Maske nimmt dem Bild die Deckkraft, der Verlauf
 * darueber faengt ab, was der Browser ohne mask-image nicht kann.       */
.photoband.fade-r .bg,.photoband.fade-l .bg{background-size:auto 100%;background-repeat:no-repeat}
.photoband.fade-r .bg{background-position:left center;
  -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 55%,transparent 92%);
          mask-image:linear-gradient(90deg,#000 0%,#000 55%,transparent 92%)}
.photoband.fade-l .bg{background-position:right center;
  -webkit-mask-image:linear-gradient(270deg,#000 0%,#000 55%,transparent 92%);
          mask-image:linear-gradient(270deg,#000 0%,#000 55%,transparent 92%)}
/* Rueckfall ohne mask-image: derselbe Verlauf als Deckschicht. */
@supports not (mask-image: linear-gradient(#000,#000)){
  .photoband.fade-r::before,.photoband.fade-l::before{content:"";position:absolute;inset:0;z-index:1}
  .photoband.fade-r::before{background:linear-gradient(90deg,transparent 55%,var(--lz-ink) 92%)}
  .photoband.fade-l::before{background:linear-gradient(270deg,transparent 55%,var(--lz-ink) 92%)}
}

/* ====================================================================
   REGELREIHEN — Zahl, ein Satz, auf Klick der Rest
   Ersetzt das Sprungmarken-Menue UND die sechs Kapitel-Sektionen. Vorher
   musste man 9300px abscrollen, um zu wissen, was ueberhaupt drinsteht;
   das Menue darueber war eine Kachelreihe, die nichts sagte.
   Jetzt: sieben Zeilen, jede mit ihrer Regel in EINEM Satz. Die Seite
   ist ihr eigenes Inhaltsverzeichnis.
   Die geoeffnete Zeile dreht auf Blood mit Ink-Schrift — die Umkehrung
   des ganzen Looks als Zustandsanzeige, nicht als Dekor. Der INHALT
   bleibt dunkel: rot hinterlegter Fliesstext mit Listen und Panels waere
   unlesbar, und die Bloecke darin sind auf dunklen Grund gerechnet.
   ==================================================================== */
.rules{border-top:1px solid var(--lz-line)}
.rule{border-bottom:1px solid var(--lz-line);background:var(--lz-ink);
  transition:background var(--lz-fast) var(--lz-ease)}
/* Zeile und Inhalt teilen dieselbe Einrueckung: aussen randlos, innen
   auf der Schale — so steht die Riesenzahl auf einer Linie mit dem
   Seitentitel darueber. */
.rule > summary,.rule .rbody{
  padding-inline:max(var(--lz-gutter), calc((100% - var(--lz-shell)) / 2))}
.rule > summary{display:grid;
  grid-template-columns:minmax(0,9rem) minmax(0,1fr) auto;
  gap:clamp(1rem,3vw,3rem);align-items:center;
  padding-block:clamp(1.3rem,2.8vw,2.2rem);
  cursor:pointer;list-style:none}
.rule > summary::-webkit-details-marker{display:none}
.rule .no{display:block;font-family:var(--lz-display);font-weight:400;
  font-size:clamp(3.2rem,2rem + 6vw,7.5rem);line-height:.76;
  letter-spacing:var(--lz-track-tight);color:var(--lz-blood)}
.rule .nm{display:block;margin-top:.5rem;font-family:var(--lz-mono);font-weight:700;
  font-size:var(--lz-label);text-transform:uppercase;
  letter-spacing:var(--lz-track-label);color:var(--lz-bone)}
/* Der eine Satz. Display-Schrift, weil er die Ueberschrift IST. */
.rule .one{font-family:var(--lz-display);font-weight:400;text-transform:uppercase;
  font-size:clamp(1.3rem,1rem + 2.2vw,2.8rem);line-height:1;
  letter-spacing:var(--lz-track-tight);color:var(--lz-bone)}
.rule .pm{font-family:var(--lz-mono);font-size:1.8rem;line-height:1;color:var(--lz-blood);
  transition:transform var(--lz-fast) var(--lz-ease)}
.rule:hover{background:var(--lz-surface)}
.rule[open]{background:var(--lz-blood)}
.rule[open] .no,.rule[open] .nm,.rule[open] .one,.rule[open] .pm{color:var(--lz-ink)}
.rule[open] .pm{transform:rotate(45deg)}
.rule[open]:hover{background:var(--lz-blood)}
.rule > summary:focus-visible{outline:2px solid var(--lz-blood);outline-offset:-4px}
.rule[open] > summary:focus-visible{outline-color:var(--lz-ink)}
/* Der Inhalt holt sich den dunklen Grund zurueck und liegt in der
   Textspalte — nicht ueber die ganze Schale, sonst laufen die Zeilen zu
   lang. .flip schiebt ihn an die rechte Kante: der Takt bleibt. */
.rule .rbody{background:var(--lz-ink);padding-block:clamp(1.6rem,3vw,2.8rem) clamp(2.4rem,5vw,4rem)}
.rule .rbody > *{max-width:var(--lz-measure)}
.rule .rbody.flip > *{margin-left:auto}
.rule .rbody > .trio,.rule .rbody > .chapter-shot{max-width:none}
@media(max-width:760px){
  .rule > summary{grid-template-columns:minmax(0,1fr) auto;gap:.6rem 1rem}
  .rule .mark{grid-column:1/-1;display:flex;align-items:baseline;gap:.8rem}
  .rule .no{font-size:2.6rem}
  .rule .nm{margin-top:0}
  .rule .rbody.flip > *{margin-left:0}
}

/* Auf der roten Flaeche dreht ALLES mit, nicht nur die Ueberschrift.
   --lz-ash auf Blood ist 2,4:1 — jedes Kleingedruckte, jeder Chip und
   jede Mono-Zeile waere dort faktisch unlesbar. Ink mit Deckkraft statt
   eines eigenen Grautons: so bleibt es eine Farbe, wie das Gesetz sagt. */
.slab .chip{color:var(--lz-ink);border-color:rgba(12,12,13,.4)}
.slab .muted,.slab .mono,.slab .label,.slab .tagline{color:var(--lz-ink);opacity:.75}
.slab .tagline{opacity:1;font-weight:600}
.slab a:not(.btn){color:var(--lz-ink);text-decoration:underline;text-underline-offset:3px}
.slab .chips{margin-top:1.4rem}

/* Ein Motiv, das den Rahmen nicht fuellt, laeuft nach rechts ins Schwarz
   aus, statt hochskaliert und unscharf gestreckt zu werden. */
.chapter-shot.fade-r{border-right:0}
.chapter-shot.fade-r img{
  -webkit-mask-image:linear-gradient(90deg,#000 0%,#000 62%,transparent 100%);
          mask-image:linear-gradient(90deg,#000 0%,#000 62%,transparent 100%)}

/* --- Riesenzahl-Stufen im Regelkoerper -------------------------------- *
 * Das Signature-Modul ("Die Zahlen sind das Logo") darf NICHT auf die
 * Textspalte beschnitten werden — .rbody > * deckelt sonst auf 780px und
 * die Zahlen schrumpfen auf die Groesse, die sie vorher als Listenzeile
 * hatten. Hier gilt die volle Schale.                                    */
.rule .rbody > .tiers{max-width:none}
.tiers{margin:.4rem 0 0}
.tiers .eyebrow{margin-bottom:1rem}
.tiers-note{font-size:.85rem;line-height:1.6;color:var(--lz-ash);margin-top:1.4rem;max-width:70ch}
.tiers-note b{color:var(--lz-bone)}

/* ====================================================================
   MEDIA — Profilbild, Fotos zum Run, Lightbox (09/2026)
   Eine Bildsprache fuer alles, was Nutzer hochladen (assets/media.js).
   Avatare laufen ueberall s/w (--lz-photo) — wie jedes Foto der Seite;
   die Initialen als Platzhalter bleiben Blood auf Flaeche.
   Vorher gab es das Profilbild nur als 28px-Stift am Rand des Avatars
   und die Run-Fotos nur als "Foto+" in der eigenen Historie — beides
   hat keiner gefunden (Prod: 0 Run-Fotos bei 14 Eintraegen). Jetzt
   steht das Bild ueberall, wo der Name steht: Kopfleiste, Rangliste,
   Crew, Kommentare. Erst dann lohnt sich das Hochladen.
   ==================================================================== */
/* Groessen: -lg 84px (Profilkopf), Standard 46px, -sm 34px (Listen,
   Kommentare), -xs 24px (Kopfleiste). */
.avatar-sm{width:34px;height:34px}
.avatar-sm.avatar-ph{font-size:.85rem}
.avatar-xs{width:24px;height:24px;border-color:var(--lz-line-ui)}
.avatar-xs.avatar-ph{font-size:.62rem;letter-spacing:0}
.usertrigger .ava{display:inline-flex;line-height:0}
/* Mobil steht das Menue als Spalte; .who bringt dort den Gutter als
   Polsterung mit. Das Bild rueckt an den Gutter, der Name dicht dahinter. */
@media(max-width:980px){
  .bar nav .usertrigger .ava{margin-left:var(--lz-gutter)}
  .bar nav .usertrigger .who{padding-left:.6rem}
}

/* Athlet in einer Listenzeile: Bild links, Name und Meta rechts.
   Nicht ".who" — den Namen traegt schon die Autorzeile im Kommentar,
   und der Kommentarblock steht in derselben Zeile. */
.row-entry .ath{display:flex;align-items:flex-start;gap:.7rem;min-width:0}
.row-entry .ath > .avatar{margin-top:.05rem}
.row-entry .ath > .athtext{min-width:0;flex:1}

/* Profilbild aendern: der Avatar selbst ist der Knopf, der Hinweis
   erscheint bei Hover und Fokus. Daneben steht der Knopf mit Wort —
   ein Stift am Bildrand war fuer niemanden ein Upload. */
.avatar-edit{position:relative;flex:0 0 auto;display:inline-block;cursor:pointer;line-height:0}
.avatar-edit .avatar-hover{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:var(--lz-scrim-2);color:var(--lz-bone);font-family:var(--lz-mono);font-weight:700;
  font-size:.6rem;line-height:1;letter-spacing:.14em;text-transform:uppercase;opacity:0;
  transition:opacity var(--lz-fast) var(--lz-ease)}
/* Nur Hover: im Label steckt nichts Fokussierbares, der Tastaturweg ist
   der Knopf mit Wort daneben. */
.avatar-edit:hover .avatar-hover{opacity:1}
/* Ein Finger hovert nicht. Auf Fingergeraeten stand die Ueberblendung
   deshalb NIE — der Avatar war dort ein Knopf ohne jedes Zeichen, dass er
   einer ist. Sie steht dauerhaft und dafuer leiser (Ink mit Deckkraft,
   kein zweiter Grauton). Gilt fuer Profil und Konto gleichermassen. */
@media (hover:none){
  .avatar-edit .avatar-hover{opacity:1;background:var(--lz-scrim-3);
    align-items:flex-end;padding-bottom:.25rem}
}
.avatar-btns{display:flex;gap:.5rem;flex-wrap:wrap}
.avatar-btns .btn{padding:.7rem 1rem;font-size:.7rem}
/* MOBIL-TYPOBODEN, zweiter Teil: die kleine Leiter steht seit Runde 1 auf
   13px, aber drei Groessen stehen ausserhalb der Leiter im Klartext und
   fielen durch — 12,48px (.btn), 11,2px (.avatar-btns .btn) und 9,6px
   (die "Aendern"-Ueberblendung). Das Gesetz sagt: auf dem Handy steht
   nichts unter 13px. Also auch hier nicht. */
@media(max-width:600px){
  .btn{font-size:var(--lz-label)}
  .avatar-btns .btn{font-size:var(--lz-label);min-height:var(--lz-tap)}
  .avatar-edit .avatar-hover{font-size:var(--lz-micro);letter-spacing:.08em}
}
.avatar-field{margin-top:-.3rem}
.avatar-hint{font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.04em;line-height:1.6;
  color:var(--lz-ash);margin:.6rem 0 0}

/* Fotoleiste an einem Eintrag: Kacheln 72px, eigene mit Loeschen,
   eigene Eintraege mit einer Kachel zum Hinzufuegen (Zaehler n/5). */
/* Luecke .8rem: der Loeschknopf ragt ueber die Kachel hinaus und muss in
   der Luecke Platz haben, statt das Nachbarfoto zu ueberdecken. */
.runphotos{display:flex;gap:.8rem;flex-wrap:wrap;align-items:center;margin-top:.6rem}
.runphotos.busy{opacity:.55;pointer-events:none}
/* In der Laufliste ist die Leiste ein eigenes Rasterfeld der Zeile, kein
   Kind des Textblocks — nur so kann sie auf dem Handy NEBEN den Text
   rutschen statt darunter (siehe HANDFORMAT, Punkt 5). Am Desktop steht
   sie wie vorher darunter, eingerueckt auf die Textkante (70px = Rang-
   spalte 54px + Rasterluecke 16px, dieselbe Zahl wie bei .comments). */
.row-log > .runphotos{grid-column:1 / -1;padding-left:70px;margin-top:0}
.runphoto{position:relative;width:72px;height:72px;flex:0 0 auto}
.runphoto img{width:100%;height:100%;object-fit:cover;border:1px solid var(--lz-line);cursor:pointer;
  filter:var(--lz-photo);transition:filter var(--lz-fast) var(--lz-ease)}
.runphoto:hover img,.runphoto img:focus-visible{filter:none}
/* Ein img faellt aus der globalen Fokusregel (a, input, button …) heraus —
   der Ring steht deshalb hier, sonst gaebe es keinen. */
.runphoto img:focus-visible{outline:2px solid var(--lz-blood);outline-offset:2px}
.runphoto .del{position:absolute;top:-5px;right:-5px;width:28px;height:28px;padding:0;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  background:var(--lz-blood);color:var(--lz-ink);border:1px solid var(--lz-ink);
  font-family:var(--lz-mono);font-weight:700;font-size:.85rem;line-height:1}
.runphoto .del:hover{background:var(--lz-blood-deep)}
.photo-add{width:72px;height:72px;flex:0 0 auto;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:.15rem;cursor:pointer;text-align:center;padding:.2rem;
  border:1px dashed var(--lz-line-ui);color:var(--lz-ash);
  font-family:var(--lz-mono);font-weight:700;font-size:.56rem;line-height:1.2;letter-spacing:.1em;text-transform:uppercase;
  transition:border-color var(--lz-fast) var(--lz-ease),color var(--lz-fast) var(--lz-ease)}
.photo-add:hover,.photo-add:focus-within{border-color:var(--lz-bone);color:var(--lz-bone)}
.photo-add .plus{font-size:1.25rem;line-height:1;color:var(--lz-blood)}
.photo-add .cnt{color:var(--lz-ash);letter-spacing:.04em}
.photo-add.full{cursor:default;border-style:solid;border-color:var(--lz-line)}
.photo-add.full:hover{border-color:var(--lz-line);color:var(--lz-ash)}
/* Auswahl vor dem Upload (Einreichen): dieselben Kacheln, mit Entfernen. */
.pick-grid{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:.7rem}
.pick-grid:empty{display:none}
.pick-grid .runphoto img{cursor:default}

/* Kommentar mit dem Bild des Autors. */
.comment{display:flex;gap:.7rem;align-items:flex-start}
.comment > .avatar{margin-top:.1rem}
.comment .cbody{min-width:0;flex:1}

/* Lightbox: ein Bild gross, Pfeile, Zaehler. Ersetzt die .modal-Kopien
   in athlet und rangliste; admin haelt seine noch. */
.lightbox{position:fixed;inset:0;z-index:100;background:var(--lz-scrim-1);display:none;
  align-items:center;justify-content:center;padding:2rem}
.lightbox.show{display:flex}
.lightbox img{max-width:92vw;max-height:84vh;border:1px solid var(--lz-line)}
.lightbox button{position:absolute;background:transparent;border:0;color:var(--lz-bone);cursor:pointer;
  font-family:var(--lz-mono);min-width:44px;min-height:44px;transition:color var(--lz-fast)}
.lightbox button:hover{color:var(--lz-blood)}
.lightbox .lb-x{top:1rem;right:1.2rem;font-size:.8rem;letter-spacing:.12em;text-transform:uppercase;padding:.6rem .8rem}
.lightbox .lb-prev,.lightbox .lb-next{top:50%;transform:translateY(-50%);font-size:2.4rem;line-height:1;width:56px;height:88px}
.lightbox .lb-prev{left:.4rem}
.lightbox .lb-next{right:.4rem}
.lightbox .lb-count{position:absolute;bottom:1.2rem;left:50%;transform:translateX(-50%);
  font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:var(--lz-track-label);color:var(--lz-ash)}
.lightbox[data-n="1"] .lb-prev,.lightbox[data-n="1"] .lb-next,.lightbox[data-n="1"] .lb-count{display:none}
@media(max-width:600px){
  .lightbox{padding:0}
  .lightbox img{max-width:100vw;max-height:80vh;border:0}
}

/* ====================================================================
   ATHLETENPROFIL AUF DEM HANDY (Gauntlet 09/2026)
   Gemessen bei 390x844 und 360x800, echte Mobil-Emulation. Jede Zahl in
   den Kommentaren ist gemessen, nicht geschaetzt.
   Der Befund war: die erste Bestzeit stand bei 1071px, also erst auf
   Bildschirm 2 — zwischen Kopf und Bestzeiten lagen Crews und Ziele.
   Wer ein fremdes Profil oeffnet, fragt zuerst "wieviel" und "wie
   schnell". Beides gehoert auf den ersten Schirm, der Rest darunter.
   ==================================================================== */

/* --- 1) Fingerziele --------------------------------------------------
   20 Ziele lagen unter 44x44, das kleinste 25x16 ("FAQ" im Fuss).
   Gewachsen ist ausschliesslich die UNSICHTBARE Flaeche: Polsterung und
   min-height. Kein Rahmen, keine Flaeche, keine andere Schrift — die
   Kanten sehen aus wie vorher, sie sind nur greifbar geworden.
   Nur fuer grobe Zeiger: eine Maus trifft 17px, ein Daumen nicht.     */
@media (pointer:coarse){
  /* Der Kopf behaelt seine Hoehe: was die Marke an Polsterung bekommt,
     gibt die Bar an Innenabstand ab (65px vorher, 63px nachher). */
  .bar{padding-block:.6rem}
  .bar .brandmark{min-height:var(--lz-tap)}
  .skiplink{display:inline-flex;align-items:center;min-height:var(--lz-tap)}
  .crewchips a{min-height:var(--lz-tap)}
  /* Links in Hinweiszeilen ("Die Regeln", "Selbst eintragen"): als ein
     Kasten, damit sie nicht mitten im Wort umbrechen — bei 360px mass
     "Die Regeln" 305x36, weil der Link ueber zwei Zeilen lief. */
  .linkline a{display:inline-flex;align-items:center;
    min-height:var(--lz-tap);min-width:var(--lz-tap)}
  footer .foot-col a{display:inline-flex;align-items:center;
    min-height:var(--lz-tap);min-width:var(--lz-tap)}
  /* Der Zeilenabstand kommt jetzt aus der Polsterung — sonst stuenden
     zwischen zwei Zielen 8px Luft zu viel und der Fuss wuechse. */
  footer .foot-col li{margin-bottom:0}
  footer .meta a{display:inline-flex;align-items:center;min-height:var(--lz-tap)}
}

/* --- 2) Der Profilkopf ----------------------------------------------
   Er war 321px hoch: der 84px-Avatar stand per flex-wrap auf einer
   eigenen Zeile UEBER dem Namen, darunter vier weitere Zeilen. Neu:
   Avatar und Name nebeneinander (dafuer 64px statt 84px), Herkunft und
   Meta darunter ueber die volle Breite — dort brauchen sie zwei Zeilen
   statt vier. Das sind ~115px, die die Bestzeit nach oben ziehen.     */
@media(max-width:600px){
  /* Nur der Athletenkopf (.profile-athlete). Das Konto teilt sich
     .profile-head, hat aber andere Kinder — ein display:contents darauf
     wuerde dort die Zeilen durcheinanderwerfen. */
  .profile-athlete{display:grid;grid-template-columns:auto minmax(0,1fr);
    column-gap:.9rem;row-gap:.35rem;align-items:center;margin-bottom:1.1rem}
  /* display:contents — die vier Textzeilen werden Kinder des Rasters,
     ohne dass das Markup dafuer eine zweite Verpackung braucht. */
  .profile-athlete .profile-id{display:contents}
  .profile-athlete .avatar-slot{grid-area:1 / 1 / 3 / 2}
  .profile-athlete .name{grid-area:1 / 2 / 2 / 3}
  .profile-athlete .statusline{grid-area:2 / 2 / 3 / 3;margin:0}
  .profile-athlete .regionline,
  .profile-athlete .metaline{grid-column:1 / -1}
  /* NUR im Athletenkopf kleiner. Vorher stand hier .avatar-lg nackt und
     schrumpfte auch den Avatar im Konto von 84 auf 64px — samt der
     "Aendern"-Ueberblendung darauf. Der Kommentar behauptete, das Raster
     sei auf .profile-athlete verengt; fuer diese Zeile stimmte das nicht.
     (Gauntlet, Runde 2.) */
  .profile-athlete .avatar-lg{width:64px;height:64px}
  .profile-athlete .avatar-lg.avatar-ph{font-size:1.5rem}
  /* Der Knopf mit Wort faellt auf dem Handy weg: er stand als eigene
     Rasterzeile ueber die volle Breite und machte den Kopf 57px hoeher
     (143 -> 200px bei 390px) — bei 360px und langem Namen fiel die
     Bestzeit damit von Bildschirm 1. Dazu war er mit 200x38px und 11,2px
     Schrift der einzige Bruch beider Handregeln auf der Seite.
     Der Avatar selbst bleibt der Knopf; die Ueberblendung "Aendern"
     steht auf Fingergeraeten dauerhaft (Regel unten), also gibt es dort
     keinen unsichtbaren Weg. Das Datei-Feld darin ist ohnehin .hide und
     wird vom Label ausgeloest — display:none aendert daran nichts. */
  .profile-athlete .avatar-btns{display:none}
  /* Weniger Anlauf: 48px Luft ueber dem Eyebrow sind auf einem 800px
     hohen Schirm 6% der Seite, die nichts sagen. */
  .page-top{padding-top:clamp(2rem,6vw,3rem)}
  .eyebrow{margin-bottom:1rem}
}

/* --- 3) Der Volumenblock --------------------------------------------
   Gestapelt (Zahl, darunter das Mikrolabel) kostete er 237px. Neben-
   einander gestellt kostet er 155px und die Zahl bleibt exakt so gross.
   Das Label steht NEBEN der Zahl, auf ihrer Grundlinie — mit festem
   Abstand, nicht an der Kante.

   Korrektur 09/2026 (Gauntlet, Runde 2): mit justify-content:space-between
   klebte das Etikett am rechten Rand und zwischen Zahl und Etikett stand
   Leere — gemessen 125px (3.000 LIEGESTUETZE), 176px (300 KLIMMZUEGE),
   235px (30km LAUF) bei 390px Fensterbreite. Der Zeilenabstand im Block
   ist 54px: "LAUF" stand damit viermal weiter von seiner eigenen Zahl
   entfernt als vom Etikett der Zeile darueber. Naehe ist das staerkste
   Gruppierungssignal, das es gibt, und es arbeitete gegen die Gruppe.
   Fester Abstand heisst: das Paar bleibt ein Paar, egal wie lang die
   Zahl ist.                                                            */
@media(max-width:600px){
  .nums-vol{gap:.9rem}
  .nums-vol .num{display:flex;align-items:baseline;justify-content:flex-start;gap:.8rem}
  .nums-vol .num .cap{margin-top:0;text-align:left}
  /* "aus 2 bestaetigten Laeufen" ist bei 13px 219px breit — mit dem
     Titel daneben passt das auf 360px nicht mehr in eine Zeile. */
  .vol-block .block-head{flex-wrap:wrap;gap:.2rem .8rem}
}

/* --- 4) Die Reihenfolge ----------------------------------------------
   Steht im Markup (athlet.html), nicht hier. Eine Spalte per order: zu
   verschieben dreht das Bild und laesst die Tab-Reihenfolge stehen —
   ein Tastaturnutzer landete dann zuerst auf dem Crew-Link, der ganz
   unten steht. Wenn eine Reihenfolge falsch ist, ist die Reihenfolge
   falsch, nicht ihre Darstellung.                                      */

/* --- 5) Die Laufzeile ------------------------------------------------
   Sie war 134px hoch (390px) und 203px (360px): Datum in einer 32px-
   Spalte, Metazeile zweizeilig, Aktionen in einer dritten Zeile.
   Neu, drei Zeilen statt sechs:
     Was / Zeit  ·  Pensum / Datum  ·  Aktionen
   Die Bestaetigung steht als Zeichen an der Zeit (wie in der Rangliste),
   nicht mehr als "· ✓ BESTAETIGT" in der Metazeile — dort sprengte sie
   auf 360px die Zeile.                                                 */
.vmark{font-family:var(--lz-mono);font-weight:700;font-size:var(--lz-micro);
  margin-left:.4em}
.vmark.ok{color:var(--lz-ok)}
.vmark.warn{color:var(--lz-warn)}
.row-log .rowfoot{margin-top:.2rem}
@media(max-width:600px){
  .row-log{grid-template-columns:minmax(0,1fr) auto;gap:.1rem .8rem;padding:.6rem 0}
  .row-log .row-main{grid-area:1 / 1 / 4 / 2;min-width:0}
  .row-log .time{grid-area:1 / 2 / 2 / 3;text-align:right;white-space:nowrap}
  .row-log .rank-date{grid-area:2 / 2 / 3 / 3;text-align:right;align-self:start}
  /* Pensum und Aktionen teilen sich ein Band: passt beides nebeneinander,
     steht es nebeneinander; sonst bricht es um. Kein zweites Raster. */
  .row-log .rowfoot{display:flex;align-items:center;justify-content:space-between;
    flex-wrap:wrap;gap:0 .8rem;margin-top:0}
  .row-log .rowfoot .meta{margin-top:.15rem}
  .row-log .rowfoot .social{margin-top:.15rem}
  /* Die Sperrung ist Luxus breiter Spalten. Bei 226px Spaltenbreite
     kostet .1em genau den Umbruch, den die Zeile nicht hat. */
  .row-log .meta{letter-spacing:.04em}
  /* Die Aktionen muessen NEBENEINANDER passen: bei 360px bleiben der
     Spalte 208px, Faust (62px) und Kommentarknopf (139px) brauchten mit
     der Fingerpolsterung 209px — zwei Pixel, die die Zeile von 116 auf
     165px trieben. Schmalere Polsterung, gleiche 44px Hoehe. */
  /* NICHT auf .row-log verengt, und das ist Absicht: die Verbreiterung des
     Knopfes (--lz-label statt .7rem, dazu das TALK-Zeichen in social.js)
     ging an ALLE Seiten, die Reparatur hing nur am Profil. Folge, gemessen:
     auf gruppe.html brach .social bei 360px auf zwei Zeilen um (44 -> 96px),
     die Zeilen wuchsen von 151 auf 228px, die Seite um 394px.
     Regel daraus: wer ein geteiltes Bauteil breiter macht, repariert es
     dort, wo er es breiter gemacht hat — nicht auf einer Seite. */
  .social{gap:.4rem}
  .respect-btn,.iconbtn{padding-inline:.55rem}
  /* Das Wort "Kommentare" kostet 139px von 208px Spaltenbreite und sagt
     neben einer Sprechblase nichts, was das Zeichen nicht sagt. Es bleibt
     im Baum (Screenreader, Tastatur) und verschwindet nur aus dem Bild —
     display:none nimmt dem Knopf seinen Namen. */
  .row-log .iconbtn{position:relative}
  .row-log .iconbtn .lbl{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}

  /* --- Die Fotoleiste in der Zeile ---------------------------------
     Sie war die vierte Textzeile und kostete 51px: 113 -> 164px (390px)
     bzw. 113 -> 163px (360px). Auf dem EIGENEN Profil traf das jede Zeile,
     auch die ohne ein einziges Foto — media.js gibt dort immer die Kachel
     zum Hinzufuegen aus.
     Jetzt sitzt sie im rechten Rasterfeld unter dem Datum. Dort standen
     ohnehin 44px Flaeche leer, weil die linke Spalte (Name, Pensum,
     Aktionen) hoeher ist als Zeit plus Datum. Die Zeile waechst dadurch
     um NULL Pixel.
     Und es steht nur noch die erste Kachel da, mit der Anzahl darauf:
     44px sind auf Armlaenge kein Bild, sondern ein Fleck. Gross wird ein
     Foto erst in der Lightbox, und die oeffnet derselbe Tipp wie vorher —
     mit Pfeilen durch alle. Am Desktop bleibt die volle Leiste. */
  .row-log > .runphotos{grid-area:3 / 2 / 4 / 3;justify-self:end;align-self:end;
    position:relative;padding-left:0;margin-top:0;gap:.5rem;flex-wrap:nowrap}
  .row-log .runphoto,.row-log .photo-add{width:var(--lz-tap);height:var(--lz-tap)}
  .row-log .runphoto:not(:first-child){display:none}
  /* Die Zahl steht auf der Kachel, nicht daneben: daneben waere sie eine
     zweite Spalte und die Zeile wieder breiter. Ab zwei Fotos — "1" auf
     einem Bild ist keine Information. */
  .row-log > .runphotos[data-n]:not([data-n="0"]):not([data-n="1"])::after{
    content:attr(data-n);position:absolute;left:0;bottom:0;
    width:var(--lz-tap);text-align:center;
    background:var(--lz-ink);color:var(--lz-bone);
    font:700 var(--lz-micro)/1 var(--lz-mono);padding:.22rem 0}
  /* Loeschen braucht den Blick auf das Bild. Auf 44px sieht man nicht,
     WAS man loescht — und 28x28 waere ohnehin kein Fingerziel. Bleibt am
     Desktop; in der Auswahl vor dem Upload (.pick-grid) unberuehrt. */
  .row-log .runphoto .del{display:none}
  /* Die Kachel zum Hinzufuegen behaelt das Plus und den Zaehler; das Wort
     "Foto" stand bei 8,96px auf dem Schirm und ist der einzige Text, der
     auf 44px nicht in Fingergroesse passt. Der Name des Knopfes steht im
     title und am Datei-Feld. */
  .row-log .photo-add{padding:0;font-size:var(--lz-micro);gap:.1rem}
  .row-log .photo-add .lbl{display:none}
  /* Badge-Namen: "DREIFALTIGKEIT" ist bei 13px und .06em Sperrung 121px
     breit, die Karte bietet bei 360px 123px. Zu knapp fuer eine Regel,
     die stehen soll. */
  .badge-card .badge-name{letter-spacing:.02em}
}

/* --- 5b) Luft, die nichts sagt ---------------------------------------
   Bei 360px stand die erste Bestzeit nach dem Umbau auf 797px — drei
   Pixel ueber der Falte, das ist kein Bestehen, das ist Glueck. Die
   fehlende Reserve liegt in den Abstaenden: um den Volumenblock lagen
   90px Luft (Rand + Polsterung, zweimal), ueber jedem Abschnittskopf
   35px. Auf einem 800px hohen Schirm ist das ein Achtel der Seite fuer
   nichts. Die Hairline trennt bereits — der Abstand muss es nicht
   nochmal tun.                                                         */
@media(max-width:600px){
  .card-panel{padding:1.2rem}
  .vol-block{padding:1rem 0;margin:1rem 0}
  .vol-block .block-head{margin-bottom:.8rem}
  .secthead{margin-top:1.6rem}
  :where(div,section) + :where(div,section) > .secthead:first-child{margin-top:1.6rem}
}

/* --- 6) Kleinkram, der bisher im Markup stand ------------------------
   Auf athlet.html standen Groessen und Raender als style="" im HTML.
   Branding lebt in den Tokens, nicht im Markup — hier ist ihr Platz. */
.profile-id .name{font-size:clamp(1.5rem,1.1rem + 1.8vw,1.9rem);line-height:1.15;margin:0}
.statusline{margin:.5rem 0 .3rem}
.regionline{margin:.2rem 0}
.metaline{font-size:var(--lz-caption);color:var(--lz-ash)}
/* Nur im Athletenkopf. Ungescoped landete der Abstand auch im Konto,
   wo .avatar-field ihn bereits mit -.3rem austariert hat. */
.profile-athlete .avatar-btns{margin-top:.8rem}
.empty a{color:var(--lz-blood)}
/* Abschnittskopf und Liste trugen beide eine Hairline — zwei Striche
   mit 14px Luft dazwischen lesen sich als Fehler, nicht als Raster. */
.secthead + .lb{border-top:0}

/* Crew-Zugehoerigkeit als kantige Hairline-Chips (vorher im <style> von
   athlet.html). Ein Chip ist ein Ziel: die Hoehe steht in der
   Fingerregel oben. */
.crewchips{display:flex;flex-wrap:wrap;gap:.5rem}
.crewchips a{display:inline-flex;align-items:center;gap:.5rem;
  border:1px solid var(--lz-line);padding:.45rem .75rem;
  font-family:var(--lz-mono);font-size:var(--lz-label);letter-spacing:.06em;
  color:var(--lz-bone);
  transition:color var(--lz-fast) var(--lz-ease),border-color var(--lz-fast) var(--lz-ease)}
.crewchips a:hover{color:var(--lz-blood);border-color:var(--lz-blood)}
.crewchips .role{color:var(--lz-ash)}
/* Verstrichener Termin auf einem OEFFENTLICHEN Profil: neutral in Asche,
   nicht in Warnfarbe. Kein Pranger; das Ziel steht weiter. */
.goal-row .countdown.open{color:var(--lz-ash)}
