/*
  Salzburg Knights — shared site CSS
  DESIGN_SYSTEM.md v3 "Cold Steel Club" (ROADMAP Task 0.6, Lukas 2026-09-20: DS folder
  design-system/salzburg-knights-design-system/ is the source of truth). Token block
  below mirrors that source (also copied standalone to assets/css/tokens.css) and keeps
  the OLD (v2) token names as aliases so the ~200 existing var(--…) call sites in this
  file and every page keep working — DESIGN_SYSTEM.md §2 has the full alias table.
  Custom-property system, base resets, and component patterns (.btn, .card, .action,
  .info-card, header/nav, hero, sections, footer) live here so pages can share one
  stylesheet instead of duplicating this block per page.
*/

:root{
  /* v3 tokens (DESIGN_SYSTEM §2/§3/§4) — hex values mirrored here, not just referenced
     from assets/css/tokens.css, so this file still renders correctly on pages that
     don't load tokens.css yet (impressum/**, tabu, LOOP.md).
     ponytail: two copies of the same hex values; drop this local copy once every page
     loads tokens.css and impressum migrates off the old chrome. */
  --surface-100:   #141210;
  --surface-200:   #1e1b18;
  --border:        #332f2a;
  --ink-dim:       #a8a29c;
  --ink-on-accent: #1a1210;
  --orange:        #e64900;
  --white:         #ffffff;
  --radius-md:     4px;
  --radius-sm:     2px;   /* name unchanged from v2, value shrinks 10px → 2px */
  --font-display:  'Alfa Slab One', Georgia, serif;
  --font-body:     'Barlow', system-ui, sans-serif;

  /* v2 names kept as aliases onto v3 (DESIGN_SYSTEM.md §2 alias table) */
  --ink-2:    var(--surface-200);
  --ink-3:    var(--surface-200);  /* v3 collapses the 3rd surface step, DESIGN_SYSTEM §2 */
  --paper:    var(--white);        /* v2 text → DS's "--ink (=white)"; points straight at
                                       --white because --ink itself is not mirrored in this
                                       local fallback block (only in assets/css/tokens.css) */
  --silver:   var(--ink-dim);      /* v2's dual role (text + hairline) collapses to one
                                       var; the handful of border-color:var(--silver)
                                       call sites (btn-ghost, quick-prev/next, train-chip)
                                       keep using it, now a hair lighter than --border */
  --silver-2: var(--ink-dim);      /* v3 has no separate muted tier, DESIGN_SYSTEM §2 */
  --line:     var(--border);
  --accent:   var(--orange);       /* still Probetraining-CTA only */
  --chrome:   linear-gradient(180deg,#ffffff 0%,#c7c9cd 55%,#8e9096 100%);
              /* retired in v3 (no gradient token, DESIGN_SYSTEM §2/§5) — kept as the old
                 literal value for its one remaining usage (.stat-band .stat .num);
                 solidifying the stat numbers to --ink is a visual change, not a token
                 rename, out of scope for this task */

  /* geometry */
  --container:   1200px;
  --radius:      var(--radius-md);   /* 20px → 4px, DESIGN_SYSTEM §2/§4 */
  --radius-in:   var(--radius-md);   /* 14px → 4px, same target as --radius */
  --nav-h:       72px;   /* .nav bar itself, DESIGN_SYSTEM §8 "height ≤72px, one line" */
  --header-h:    var(--nav-h); /* full fixed header block == nav height (nav bar only, no
                    band below it); downstream (scroll-padding, hero/page-head padding,
                    mobile menu top) stays correct with no other edits */

  /* type scale (DESIGN_SYSTEM §3) */
  --wordmark: clamp(2.2rem, 7vw, 3.5rem);   /* v3 headline-1, 56px ceiling (DS §3) */
  --h2:       clamp(1.5rem, 4vw, 2rem);      /* v3 headline-2, 32px ceiling (DS §3) */
  --h3:       clamp(1.22rem, 2vw, 1.6rem);
  --stat:     clamp(3.2rem, 10vw, 6rem);     /* v3 jersey-number, 96px ceiling (DS §3) */
  --newsdate: clamp(1.6rem, 3vw, 2.4rem);
  --lead:     clamp(1.05rem, 2.2vw, 1.35rem);
  --body:     1rem;
  --meta:     .82rem;
  --eyebrow:  .78rem;
  --label:    .74rem;

  /* motion (DESIGN_SYSTEM §5) — one easing curve, one entrance duration */
  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast:   220ms;
  --dur-base:   320ms;
  --dur-media:  500ms;
  --dur-reveal: 560ms;
  --dur-press:  100ms;  /* press-in feedback only (DS §5 Fluid-interface rules, 24.2) */
  --dur-enter:  900ms;
  --dur-count:  1600ms;

  /* spacing (DESIGN_SYSTEM §4) */
  --section-pad:       clamp(80px, 10vw, 160px);
  --section-pad-tight: clamp(56px, 8vw, 104px);
  --head-gap:  clamp(46px, 6vw, 72px);
  --gutter:    24px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-padding-top:calc(var(--header-h) + 24px)}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{font-family:var(--font-body);color:var(--paper);background:var(--surface-100);line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{display:block;max-width:100%;height:auto} /* height:auto: HTML width/height attrs only hint the aspect ratio (Task 4.2) */
picture{display:contents} /* Task 8.1: <picture> wrapper generates no box, layout stays as with a bare <img> */
a{color:inherit;text-decoration:none}
.container{width:100%;max-width:var(--container);margin:0 auto;padding:0 22px}
h1,h2,h3,.display{font-family:var(--font-display);font-weight:400;line-height:1.02;letter-spacing:.01em;text-transform:uppercase;color:var(--paper);overflow-wrap:break-word;text-wrap:balance}
/* tracking (DS §3, 2026-10-03): negative only >= 24px display; small labels keep theirs */
h1{letter-spacing:-.02em}
h2{letter-spacing:-.01em}
h3{letter-spacing:0}
.display{letter-spacing:-.01em}
p,li{text-wrap:pretty}

/* Double-Bezel — the material of the site (DESIGN_SYSTEM §8). Outer shell + inner
   core, concentric radii (20 - 6 padding = 14). Used by Pass B components. */
.bezel{background:var(--ink-2);border:1px solid var(--line);padding:6px;border-radius:var(--radius)}
.bezel > .bezel-core{background:var(--surface-100);border-radius:var(--radius-in);box-shadow:inset 0 1px 0 rgba(255,255,255,.08);overflow:hidden}

/* type = the "label" token, DESIGN_SYSTEM.md §8 (2026-09-24): 13px/+0.04em, .btn-sm below is padding-only */
.btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.04em;font-size:.8125rem;padding:.85rem 1.5rem;border-radius:var(--radius-sm);border:2px solid transparent;cursor:pointer;transition:transform var(--dur-fast) var(--ease-spring), box-shadow var(--dur-fast) var(--ease-spring), background var(--dur-fast) var(--ease-spring), color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring);white-space:nowrap}
/* author display beats UA [hidden]; buttons hidden until confirmed (e.g. #trialWhatsApp) */
.btn[hidden]{display:none}
@media (hover:hover) and (pointer:fine){.btn:hover{transform:translateY(-2px)}}
.btn-primary{background:var(--accent);color:var(--ink-on-accent);padding-right:.6rem}
.btn-primary .btn-arrow{width:28px;height:28px;border-radius:50%;background:rgba(20,18,16,.14);display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;transition:transform var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
.btn-primary .btn-arrow svg{width:15px;height:15px}
@media (hover:hover) and (pointer:fine){.btn-primary:hover .btn-arrow{transform:translate(2px,-1px) scale(1.05)}}
/* Ball-Bounce (Task 14.4.6, Block 63): kurzer Squash/Stretch bei Klick/Tap auf die
   Probetraining-CTA (.btn-primary ist per Design-System exklusiv der Probetraining-Button,
   §2/§8). Klasse wird von nav.js gesetzt/entfernt, verzoegert nie die Navigation selbst. */
/* interruptible (DS §5 Fluid-interface): the base `scale` transition of .btn retargets from the
   current value, so a repeated tap never snaps; nav.js only sets/clears the class (~120ms) */
.btn-primary.is-bouncing{scale:.94}
@media (prefers-reduced-motion:reduce){.btn-primary.is-bouncing{scale:none}}
/* .btn-dark: v1 holdover, still used by not-yet-rebuilt sections (about/joinband).
   DESIGN_SYSTEM §8 marks it deleted once those sections move to .btn-ghost/.btn-outline. */
.btn-dark{background:var(--ink-3);color:var(--paper)}
@media (hover:hover) and (pointer:fine){.btn-dark:hover{background:var(--ink-2)}}
.btn-dark:focus-visible{background:var(--ink-2)}
.btn-ghost{background:transparent;border-color:var(--silver);color:var(--paper)}
@media (hover:hover) and (pointer:fine){.btn-ghost:hover{background:var(--paper);color:var(--surface-100);border-color:var(--paper)}}
.btn-ghost:focus-visible{background:var(--paper);color:var(--surface-100);border-color:var(--paper)}
.btn-outline{background:transparent;border-color:var(--line);color:var(--paper)}
@media (hover:hover) and (pointer:fine){.btn-outline:hover{border-color:var(--silver)}}
.btn-outline:focus-visible{border-color:var(--silver)}
.btn-sm{padding:.6rem 1.05rem}
.nav-cta{display:none}
@media(min-width:1000px){.nav-cta{display:inline-flex}}
@media(min-width:821px) and (max-width:1099px){.nav-right .social-mini{display:none}}
@media(min-width:1200px){header.site .brand span{white-space:nowrap}}
.menu-cta{display:none}
@media(max-width:820px){.menu-cta{display:block;margin-top:.5rem}}
/* /probetraining/ (Lukas 2026-09-23): the nav CTA would point at the page itself; the form submit
   carries the one orange there instead. */
body:has(#trialForm) .nav-cta,body:has(#trialForm) .menu-cta{display:none}

.eyebrow{font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.28em;font-size:var(--eyebrow);color:var(--orange);display:inline-flex;align-items:center;gap:.5rem;margin-bottom:.7rem}
.eyebrow::before{content:'';width:14px;height:2px;background:var(--orange);flex:none}
/* Sektionsnummern 01/02/03 (Task 14.4.2, Block 63): reines CSS-Counter, kein Markup, dekorativ
   (Pseudo-Element-Inhalt wird von Screenreadern nicht vorgelesen). Nur Homepage: subpages
   tragen body.subpage (scripts/chrome.js), .eyebrow taucht dort in echten Sektionsnummern-
   fremden Kontexten auf (News, FAQ, Teams ...). */
body:not(.subpage){counter-reset:section-num}
body:not(.subpage) .eyebrow{counter-increment:section-num}
body:not(.subpage) .eyebrow::after{content:counter(section-num,decimal-leading-zero);color:var(--ink-dim);margin-left:.5rem}
.section{padding:var(--section-pad) 0}
.section-tight{padding:var(--section-pad-tight) 0}
.section-head{max-width:720px;margin-bottom:var(--head-gap)}
.section-head h2{font-size:var(--h2)}
.section-head p{color:var(--silver-2);font-size:1.05rem;margin-top:.7rem}

/* small layout utilities — replace one-off inline style="" attributes */
.mt-lg{margin-top:34px}
.mt-md{margin-top:18px}
.mt-sm{margin-top:.7rem}
.cta-row{display:flex;gap:.9rem;flex-wrap:wrap}
.cta-row.centered{justify-content:center}
.about-lead{color:var(--silver-2);font-size:1.05rem;margin-top:.8rem}
.about-cta{margin-top:1.8rem}

/* skip link (Task 4.4): off-screen until keyboard focus; z-index above header.site (1000),
   which is later in the DOM and would otherwise cover it */
.skip-link{position:absolute;left:-999px;top:8px;z-index:1100;background:var(--surface-200);color:var(--paper);border:1px solid var(--border);padding:.6rem 1rem;border-radius:var(--radius-sm);font-family:var(--font-body);font-weight:600}
.skip-link:focus-visible{left:8px}
/* #main = skip-link target (<main tabindex="-1"> or impressum's empty span): programmatic
   focus only, not interactive, so no focus ring */
#main[tabindex="-1"]:focus{outline:none}

/* header — floating glass pill (desktop) / full bar (mobile), DESIGN_SYSTEM §8. */
header.site{position:fixed;top:0;left:0;right:0;z-index:1000;display:flex;align-items:center}
/* Glass lives on .nav::before, never on .nav itself: a filter on .nav would make it a backdrop root
   and the nested .menu/.dropdown could not blur the page (DS §8 Materials, 2026-10-03) */
.nav{position:relative;isolation:isolate;display:flex;align-items:center;justify-content:space-between;width:calc(100% - 32px);max-width:var(--container);margin:16px auto 0;padding:0 22px;height:var(--nav-h);border:1px solid var(--line);border-radius:var(--radius-md)}
.nav::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;background:rgba(30,27,24,.70);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);transition:background var(--dur-base) var(--ease-spring)}
header.site.scrolled .nav::before{background:rgba(30,27,24,.80)}

.brand{display:flex;align-items:center;gap:.7rem;font-family:var(--font-display);font-weight:400;text-transform:uppercase;letter-spacing:.04em;font-size:1.18rem;color:var(--paper)}
.brand img{width:42px;height:42px;object-fit:contain}

.menu{display:flex;align-items:center;gap:.25rem;list-style:none}
.menu > li{position:relative}
.menu > li > a, .menu > li > button{display:flex;align-items:center;gap:.3rem;background:none;border:0;cursor:pointer;font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:.84rem;color:var(--silver);padding:.6rem .6rem;border-radius:var(--radius-sm);transition:color var(--dur-fast) var(--ease-spring), background var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring);position:relative}
@media (hover:hover) and (pointer:fine){.menu > li > a:hover,.menu > li > button:hover{color:var(--paper)}}
.menu > li > a:focus-visible,.menu > li > button:focus-visible{color:var(--paper)}
.caret{width:9px;height:9px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform var(--dur-base) var(--ease-spring)}
/* desktop dropdown: scale .96 -> 1 + opacity from the trigger corner, same path in and out
   (DS §5 Disclosure motion); glass .86 (DS §8 Materials) */
.dropdown{position:absolute;top:calc(100% + 6px);left:0;min-width:220px;background:rgba(30,27,24,.86);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);border:1px solid var(--line);border-radius:var(--radius-sm);padding:8px;opacity:0;visibility:hidden;transform:scale(.96);transform-origin:top left;transition:opacity var(--dur-base) var(--ease-spring), transform var(--dur-base) var(--ease-spring), visibility var(--dur-base)}
.menu > li:focus-within .dropdown{opacity:1;visibility:visible;transform:scale(1)}
@media (hover:hover) and (pointer:fine){.menu > li:hover .dropdown{opacity:1;visibility:visible;transform:scale(1)}}
/* JS-driven overrides on top of the :hover/:focus-within default (nav.js): '.dropdown-forced'
   opens on click/tap for non-hover pointers, '.dropdown-suppressed' closes on Escape even
   while the trigger still holds focus. Same specificity as the rule above -- source order
   after it is what makes these win. */
.menu > li.dropdown-forced .dropdown{opacity:1;visibility:visible;transform:scale(1)}
.menu > li.dropdown-suppressed .dropdown{opacity:0;visibility:hidden;transform:scale(.96)}
.dropdown a{display:block;font-family:var(--font-body);text-transform:none;letter-spacing:0;font-weight:500;font-size:.92rem;color:var(--silver);padding:.6rem .8rem;border-radius:var(--radius-sm)}
@media (hover:hover) and (pointer:fine){.dropdown a:hover{background:var(--ink-3);color:var(--paper)}}
.dropdown a:focus-visible{background:var(--ink-3);color:var(--paper)}

.nav-right{display:flex;align-items:center;gap:.7rem}
/* no overflow:hidden: it would clip the 44px ::after hit area (24.2); the active fill gets the inner radius instead */
.langtoggle{display:flex;border:1.5px solid var(--line);border-radius:var(--radius-sm)}
.langtoggle a:first-child{border-radius:.5px 0 0 .5px}
.langtoggle a:last-child{border-radius:0 .5px .5px 0}
.langtoggle a{display:inline-block;background:none;border:0;cursor:pointer;font-family:var(--font-body);font-weight:600;font-size:.74rem;letter-spacing:.05em;color:var(--silver);padding:.32rem .6rem;position:relative;transition:background var(--dur-fast) var(--ease-spring), color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
.langtoggle a.active{background:var(--paper);color:var(--surface-100)}
.social-mini{display:flex;gap:.4rem}
.social-mini a{width:34px;height:34px;display:grid;place-items:center;border-radius:50%;background:var(--ink-3);color:var(--paper);position:relative;transition:background var(--dur-fast) var(--ease-spring), color var(--dur-fast) var(--ease-spring), transform var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.social-mini a:hover{transform:translateY(-2px);background:var(--paper);color:var(--surface-100)}}
.social-mini a:focus-visible{background:var(--paper);color:var(--surface-100)}
.social-mini svg{width:17px;height:17px}
.burger{position:relative;display:none;flex-direction:column;gap:5px;background:none;border:0;cursor:pointer;padding:8px;transition:scale var(--dur-fast) var(--ease-spring)}
.burger span{width:26px;height:2.5px;background:var(--paper);border-radius:2px;transform-origin:center;transition:transform var(--dur-base) var(--ease-spring), opacity var(--dur-base) var(--ease-spring)}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0;transform:scaleX(.2)}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7.5px) rotate(-45deg)}
@media (prefers-reduced-motion:reduce){
  .dropdown,.caret,.burger span{transition:none}
}

/* hero — big centered crest (intro video end frame) over live-site team photo (duotone + scrim,
   §9), text below (Lukas 2026-09-23, hero-photo reinstated per web-art-director) */
.hero{position:relative;min-height:100vh;min-height:100dvh;display:flex;align-items:center;justify-content:center;color:var(--paper);padding-top:calc(var(--header-h) + 24px);isolation:isolate;text-align:center}
.hero-media{position:absolute;inset:0;z-index:-1;overflow:hidden}
/* 50% (Phase 18.7, 2026-09-28, gemessen): heads 233px below top at 1440x900, header 88px */
.hero-media img{width:100%;height:100%;object-fit:cover;object-position:50% 50%;filter:grayscale(1) contrast(1.08) brightness(.82)}
/* Spielfeldlinien + Hallenboden-Noise (Task 14.5.1/2, Block 64): zwei zusaetzliche
   Background-Layer ueber dem bestehenden Scrim, Deckkraft direkt in den SVGs gebacken (4-6%
   Linien, ~4% Noise), rein dekorativ, senkt den gemessenen Hero-Text-Kontrast nicht spuerbar. */
.hero-media::after{content:'';position:absolute;inset:0;
  background-image:
    linear-gradient(180deg,rgba(20,18,16,.60) 0%,rgba(20,18,16,.78) 60%,rgba(20,18,16,1) 100%),
    linear-gradient(0deg,rgba(168,162,156,.10),rgba(168,162,156,.10)),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.04'/%3E%3C/svg%3E"),
    url("../img/court-lines.svg");
  background-repeat:no-repeat,no-repeat,repeat,no-repeat;
  background-size:100% 100%,100% 100%,140px 140px,cover;
  background-position:0 0,0 0,0 0,center}
.hero-inner{padding-block:40px;display:flex;flex-direction:column;align-items:center}
.hero-crest{width:clamp(260px,min(52vh,80vw),620px);height:auto;aspect-ratio:1;margin:0 auto 8px;display:block;background:#000;mix-blend-mode:lighten}
/* #000 box, not surface-100: with lighten it vanishes on the black intro stage and over the hero
   photo alike — the #141210 box read as a lighter square after the gate (Lukas 2026-09-26) */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.hero h1{font-size:var(--wordmark);line-height:1.02}
.hero .lead{font-family:var(--font-body);font-size:var(--lead);max-width:46ch;margin:1.1rem auto 0;color:var(--silver);font-weight:400;text-transform:none;letter-spacing:0}
.hero-cta{display:flex;flex-wrap:wrap;justify-content:center;gap:.9rem;margin-top:2rem}

/* stat-band — the hero region's single gradient-fill moment (numbers only) */
.stat-band{background:var(--ink-2);position:relative;isolation:isolate}
/* Spielfeldlinien (Task 14.5.1, Block 64): selbe SVG wie Hero, Deckkraft im SVG gebacken (5.5%).
   ::before liegt vor .stat-grid im DOM -> malt darunter, keine z-index-Kniffe noetig. */
.stat-band::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:url("../img/court-lines.svg");background-repeat:no-repeat;
  background-position:center;background-size:cover}
.stat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:2.6rem 0}
.stat-band .stat{padding:0 2rem}
.stat-band .stat + .stat{border-left:1px solid var(--line)}
.stat-band .stat:first-child{padding-left:0}
.stat-band .stat .num{font-family:var(--font-display);font-weight:400;font-size:var(--stat);line-height:1;color:var(--orange)} /* orange text accent, DS §2 (23.22): >=24px on surface-200 */
.stat-band .stat .lbl{font-size:var(--label);text-transform:uppercase;letter-spacing:.12em;color:var(--silver-2);margin-top:.4rem}
/* Stat-Unterstrich (Task 14.4.3, Block 63): scaleX 0->1, gesetzt vom selben rAF-Tick wie der
   Zaehler in nav.js (kein zweiter Timer). Reduced motion: nav.js setzt scaleX(1) sofort. */
.stat-band .stat .num-bar{height:3px;width:2.4rem;max-width:100%;background:var(--orange);margin-top:.5rem;transform-origin:left;transform:scaleX(0)}

/* news */
.news-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:26px}
.news-grid.single{grid-template-columns:1fr;max-width:460px}
.card{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column;transition:transform var(--dur-base) var(--ease-spring), border-color var(--dur-base) var(--ease-spring), scale var(--dur-base) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.card:hover{transform:translateY(-6px);border-color:rgba(255,255,255,.18)}}
.card:focus-visible{border-color:rgba(255,255,255,.18)}
.card .thumb{aspect-ratio:16/10;overflow:hidden}
.card .thumb img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.card:hover .thumb img{transform:scale(1.06)}}
.card .body{padding:22px 22px 26px;display:flex;flex-direction:column;flex:1}
.tag{align-self:flex-start;font-family:var(--font-body);text-transform:uppercase;letter-spacing:.1em;font-size:.7rem;font-weight:500;color:var(--silver-2);background:var(--ink-3);padding:.3rem .7rem;border-radius:var(--radius-sm);margin-bottom:.8rem}
.card h3{font-size:var(--h3);line-height:1.12;margin-bottom:.5rem}
.card .meta{font-size:var(--meta);color:var(--silver-2);margin-top:auto;padding-top:1rem}
.card .more{color:var(--silver);font-weight:600;font-size:.9rem;margin-top:.9rem;display:inline-flex;align-items:center;gap:.4rem}
.card .more svg{width:15px;height:15px;transition:transform var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.card:hover .more svg{transform:translateX(4px)}}

/* quick actions */
.actions{background:var(--surface-100);color:var(--paper)}
.actions .section-head h2{color:var(--paper)}
.actions .section-head p{color:var(--silver-2)}
.action-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}

/* about — Phase 17.7 (Home-Verein.dc.html): align-items stretch statt center + bezel/img
   height:100% + object-fit:cover, damit Bild- und Textspalte gleich hoch werden (Audit
   2026-09-26 Punkt 9: Text war 704px, Bild nur 427px zentriert mit Leerraum drumherum). */
.about-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:54px;align-items:stretch}
.about-media{position:relative;height:100%}
.about-media .bezel,.about-media .bezel-core{height:100%}
.about-media img{width:100%;height:100%;object-fit:cover;border-radius:var(--radius)}
.about h2{font-size:clamp(2rem,4.4vw,3rem)}
.values{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:1.8rem}
.value{background:var(--ink-3);border-radius:var(--radius-in);padding:18px}
.value b{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.04em;display:flex;align-items:center;gap:.5rem}
.value b .dot{width:9px;height:9px;border-radius:50%;background:var(--silver);flex:0 0 auto}
.value p{font-size:.9rem;color:var(--silver-2);margin-top:.3rem}

/* meet the team */
.team-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:18px}
.team-card{text-align:center}
.team-card .photo{aspect-ratio:3/4;border-radius:var(--radius-in);overflow:hidden;background:var(--ink-3);position:relative;isolation:isolate}
.team-card .photo img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.team-card:hover .photo img{transform:scale(1.06)}}
.team-card .num{position:absolute;top:10px;left:10px;background:var(--surface-100);color:var(--paper);font-family:var(--font-display);font-weight:400;font-size:.78rem;padding:.2rem .55rem;border-radius:var(--radius-sm);z-index:1}
.team-card .name{font-family:var(--font-display);font-weight:400;text-transform:uppercase;letter-spacing:.02em;font-size:.86rem;margin-top:.7rem;line-height:1.2}

/* instagram — monochrome follow control, glyph stays (DESIGN_SYSTEM §2) */
.ig{background:var(--surface-100)}
.ig-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:24px;margin-bottom:40px}
.ig-handle{display:flex;align-items:center;gap:16px}
.ig-badge{width:64px;height:64px;border-radius:var(--radius-in);background:var(--ink-3);display:grid;place-items:center;color:var(--paper)}
.ig-badge svg{width:32px;height:32px}
.ig-handle h2{font-size:clamp(1.7rem,3.6vw,2.5rem)}
.ig-handle a.tag-handle{color:var(--silver-2);font-weight:600}
.ig-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:14px}
.ig-tile{position:relative;aspect-ratio:1;border-radius:var(--radius-in);overflow:hidden;display:block;isolation:isolate}
.ig-tile img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.ig-tile:hover img{transform:scale(1.1)}}
.ig-tile .ov{position:absolute;inset:0;background:linear-gradient(180deg,rgba(20,18,16,0),rgba(20,18,16,.55));opacity:0;transition:opacity var(--dur-fast) var(--ease-spring);display:grid;place-items:center;color:var(--paper)}
@media (hover:hover) and (pointer:fine){.ig-tile:hover .ov{opacity:1}}
.ig-tile .ov svg{width:30px;height:30px}
.ig-live :where(div){max-width:100%}
.ig-note{margin-top:22px;font-size:.82rem;color:var(--silver-2);text-align:center}
.ig-follow{display:inline-flex;align-items:center;gap:.6rem;background:var(--ink-3);border:1px solid var(--line);color:var(--paper);font-family:var(--font-body);text-transform:uppercase;letter-spacing:.06em;font-weight:600;padding:.85rem 1.6rem;border-radius:var(--radius-sm);transition:transform var(--dur-fast) var(--ease-spring), background var(--dur-fast) var(--ease-spring), color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.ig-follow:hover{transform:translateY(-2px);background:var(--paper);color:var(--surface-100)}}
.ig-follow:focus-visible{background:var(--paper);color:var(--surface-100)}
.ig-follow svg{width:20px;height:20px}

/* contact */
.contact{background:var(--surface-100);color:var(--paper)}
.contact .section-head h2{color:var(--paper)}
.contact .section-head p{color:var(--silver-2)}
.contact-grid{display:grid;grid-template-columns:1fr 1.1fr;gap:34px;align-items:start}
.contact-grid.single{grid-template-columns:1fr;max-width:640px}
.info-cards{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.info-card{background:var(--surface-300);border:1px solid var(--border-strong);border-left:3px solid var(--orange);border-radius:var(--radius-in);padding:18px}
.info-card .ic-ico{width:38px;height:38px;border-radius:var(--radius-sm);background:var(--ink-3);display:grid;place-items:center;margin-bottom:.7rem}
.info-card .ic-ico svg{width:19px;height:19px;color:var(--orange)}
/* class-based, not tag-based (heading-order fix, 2026-09-24): these titles are h2 or h3
   depending on the page's own hierarchy (kontakt/probetraining have no h2 above them, team
   pages nest under "Auf einen Blick" h2) — same visual size either way */
.info-card .ic-label{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:.8rem;color:var(--silver-2);margin-bottom:.25rem}
.info-card p, .info-card a{font-size:.96rem;color:var(--paper);word-break:break-word}
.info-card a{text-decoration:underline;text-decoration-color:var(--orange);text-underline-offset:3px}
@media (hover:hover) and (pointer:fine){.info-card a:hover{color:var(--silver)}}
.info-card a:focus-visible{color:var(--silver)}
.info-card.wide{grid-column:1 / -1}
.train-edit{font-size:.78rem;color:var(--silver-2);margin-top:.7rem}
.legal-line{grid-column:1/-1;font-size:.8rem;color:var(--silver-2);margin-top:.4rem}

/* sponsors */
.sponsors-head{text-align:center;max-width:680px;margin:0 auto var(--head-gap)}
.sponsors-head h2{font-size:clamp(1.8rem,4vw,2.6rem)}
.sponsors-head p{color:var(--silver-2);margin-top:.6rem}
.logo-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.logo-cell{background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius-in);height:120px;display:grid;place-items:center;padding:22px;transition:transform var(--dur-base) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.logo-cell:hover{transform:translateY(-4px)}}
.logo-cell img{width:auto;max-height:100%;max-width:100%;object-fit:contain}
.media-partner{text-align:center;margin-top:40px}
.media-partner span{font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.2em;font-size:.78rem;color:var(--silver-2);display:block;margin-bottom:14px}
.media-partner a{display:inline-block}
.media-partner img{height:46px;width:auto}

/* Foto-Baender (Task 14.5.3, Block 64): 1-2 Vollbreite-Fotos zwischen Homepage-Sektionen.
   Duotone: Foto-Filter wie ueberall (§9), Orange-Ton per mix-blend-mode:overlay statt Flaeche
   (Grenze 4 -- kein zweiter orange Fill). Parallax faehrt das <img> ueber die Zeit (nav.js,
   IO-gated), darum 40px Ueberschuss oben/unten + overflow:hidden auf dem Container, damit nie
   eine Kante sichtbar wird. Keine Transition auf transform (Seam-Regel: kein Lag/Throb),
   reduced-motion laesst nav.js das <img> einfach bei translateY(0). */
.photoband{position:relative;overflow:hidden;height:clamp(220px,32vw,420px)}
.photoband img{position:absolute;top:-40px;left:0;width:100%;height:calc(100% + 80px);
  object-fit:cover;display:block}
.photoband::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(20,18,16,.45) 0%,rgba(20,18,16,0) 25%,
    rgba(20,18,16,0) 75%,rgba(20,18,16,.45) 100%)}

/* join */
.joinband{background:var(--ink-2);color:var(--paper)}
.joinband h2{font-size:clamp(2rem,5vw,3.4rem)}
.joinband p{max-width:48ch;margin:1rem 0 1.8rem;color:var(--silver);font-size:1.08rem}
.joinband .btn-ghost{border-color:var(--silver)}

/* footer */
footer.site{background:var(--surface-100);color:var(--silver-2);padding:64px 0 30px}
.foot-grid{display:grid;grid-template-columns:1.4fr repeat(4,1fr);gap:34px}
.foot-brand .brand{color:var(--paper);margin-bottom:1rem}
.foot-brand p{font-size:.92rem;max-width:34ch}
footer.site .foot-h{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--paper);font-size:1rem;margin-bottom:1.1rem}
footer.site ul{list-style:none;display:flex;flex-direction:column;gap:var(--space-1)}
/* tap targets >=24px (WCAG 2.5.8, DESIGN_SYSTEM.md §8 Footer tap targets 2026-09-25): padding
   replaces most of the old .6rem list gap, so the column rhythm stays ~the same */
footer.site ul a,.foot-nap a,.foot-bottom a{display:inline-block;padding:var(--space-1) 0}
footer.site ul a,.foot-nap a{font-size:.92rem;transition:color var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){footer.site ul a:hover,.foot-nap a:hover{color:var(--paper)}}
footer.site ul a:focus-visible,.foot-nap a:focus-visible{color:var(--paper)}
.foot-nap{font-style:normal;line-height:1.6;font-size:.92rem}
.foot-nap + .foot-nap{margin-top:.6rem}
.foot-social{display:flex;gap:.6rem;margin-top:1.2rem}
.foot-social a{width:40px;height:40px;border-radius:50%;background:var(--ink-3);display:grid;place-items:center;color:var(--paper);transition:background var(--dur-base) var(--ease-spring), color var(--dur-base) var(--ease-spring), transform var(--dur-base) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.foot-social a:hover{background:var(--paper);color:var(--surface-100);transform:translateY(-3px)}}
.foot-social a:focus-visible{background:var(--paper);color:var(--surface-100)}
.foot-social svg{width:18px;height:18px}
.foot-bottom{border-top:1px solid var(--line);margin-top:46px;padding-top:24px;display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px;font-size:.82rem;color:var(--silver-2)}
@media (hover:hover) and (pointer:fine){.foot-bottom a:hover{color:var(--paper)}}
.foot-bottom a:focus-visible{color:var(--paper)}

.reveal{opacity:0;transform:translateY(26px);transition:opacity var(--dur-reveal) var(--ease-spring), transform var(--dur-reveal) var(--ease-spring)}
.reveal.in{opacity:1;transform:none}

@media (max-width:820px){
  .reveal{transform:translateY(16px)}
}

@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
}

/* Intro (homepage only, DESIGN_SYSTEM §5, Lukas 2026-09-23/25) — black stage on every load
   (Lukas: "komplett schwarzes Bild", also on reload): page, hero photo and body colour hidden,
   the knight plays big (html.intro-big) and lands in its hero slot. Inline script next to the
   video sets html.intro (no reduced motion); nav.js swaps it to html.intro-out when the video
   ends or is skipped. Failsafe: if nav.js never runs, the page shows itself 9s after the gate is
   gone (not while the gate is still up, see ANNAHMEN Block 94). */
html.intro body{background:#000}
html.intro header.site,html.intro .hero-media,html.intro .hero ~ *,html.intro footer.site{opacity:0;pointer-events:none}
html.intro:not(.has-gate) header.site,html.intro:not(.has-gate) .hero-media,html.intro:not(.has-gate) .hero ~ *,html.intro:not(.has-gate) footer.site{animation:intro-failsafe 0s 9s forwards}
/* hero text is gated by .in (nav.js); same 9s failsafe if nav.js never runs */
html.intro:not(.has-gate) .hero-inner h1,html.intro:not(.has-gate) .hero-inner .lead,html.intro:not(.has-gate) .hero-inner .hero-cta{animation:intro-failsafe-in 0s 9s forwards}
html.intro:not(.has-gate) body{animation:intro-failsafe-bg 0s 9s forwards}
/* gate.js never loaded (has-gate stays, gate-is-live never set): show the page after 12s, past
   the gate's own 10s failsafe — otherwise the homepage would stay black (code-pruefer Phase 16) */
html.intro.has-gate:not(.gate-is-live) header.site,html.intro.has-gate:not(.gate-is-live) .hero-media,html.intro.has-gate:not(.gate-is-live) .hero ~ *,html.intro.has-gate:not(.gate-is-live) footer.site{animation:intro-failsafe 0s 12s forwards}
html.intro.has-gate:not(.gate-is-live) .hero-inner h1,html.intro.has-gate:not(.gate-is-live) .hero-inner .lead,html.intro.has-gate:not(.gate-is-live) .hero-inner .hero-cta{animation:intro-failsafe-in 0s 12s forwards}
html.intro.has-gate:not(.gate-is-live) body{animation:intro-failsafe-bg 0s 12s forwards}
@keyframes intro-failsafe-bg{to{background:var(--surface-100)}}
/* reduced motion: the inline script never sets html.intro, so none of the above applies; the
   failsafe keyframes are 0s state switches, not motion. Belt and braces if a class lingers: */
@media (prefers-reduced-motion:reduce){
  html.intro body{background:var(--surface-100)}
  html.intro header.site,html.intro .hero-media,html.intro .hero ~ *,html.intro footer.site{opacity:1;pointer-events:auto;animation:none}
}
@keyframes intro-failsafe-in{to{opacity:1;transform:none}}
html.intro-out header.site,html.intro-out .hero-media,html.intro-out .hero ~ *,html.intro-out footer.site{transition:opacity var(--dur-enter) var(--ease-spring)}
html.intro-out body{transition:background-color var(--dur-enter) var(--ease-spring)}
@keyframes intro-failsafe{to{opacity:1;pointer-events:auto}}

/* Castle gate (Task 15.6, Lukas 2026-09-25) — two photo leaves over the hero, swung open by
   assets/js/gate.js (scroll/swipe/keys). Inline script sets html.has-gate once per session, never with
   reduced motion; html.gate-can-skip shows the skip button (2nd visit on this device) — otherwise it
   only appears on keyboard focus. Failsafe: without gate.js (html.gate-is-live) it fades after 10s. */
.gate{display:none}
html.has-gate .gate{display:block;position:fixed;inset:0;z-index:1200;perspective:1400px;overflow:hidden;
  touch-action:none;transition:opacity 500ms var(--ease-spring)}
html.has-gate:not(.gate-is-live) .gate{animation:gate-failsafe 0s 10s forwards}
@keyframes gate-failsafe{to{opacity:0;visibility:hidden}}
html.gate-is-out .gate{opacity:0;pointer-events:none}
.gate-stage{position:absolute;inset:0;transform-style:preserve-3d;will-change:transform}
.gate-leaf{position:absolute;top:0;bottom:0;width:50%;overflow:hidden;will-change:transform;
  backface-visibility:hidden;box-shadow:0 0 60px rgba(0,0,0,.6)}
.gate-leaf-l{left:0;transform-origin:left center}
.gate-leaf-r{right:0;transform-origin:right center}
/* natural wood colour, no duotone (Lukas 2026-09-25: "Tueren in Holzfarbe", ANNAHMEN Block 92) */
.gate-leaf img{width:100%;height:100%;object-fit:cover;filter:contrast(1.05) brightness(.62)}
.gate-leaf-l img{object-position:right center}
.gate-leaf-r img{object-position:left center}
.gate-leaf::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 50%,transparent 40%,rgba(0,0,0,.55) 100%),rgba(0,0,0,.2)}
.gate-title{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1.2rem;padding:0 6%;text-align:center;pointer-events:none;
  will-change:transform,filter,opacity}
.gate-kicker{font-family:var(--font-display);text-transform:uppercase;color:var(--paper);
  font-size:clamp(2rem,7vw,5.5rem);line-height:1}
.gate-hint{display:flex;flex-direction:column;align-items:center;gap:.6rem;font-weight:600;
  font-size:.8rem;letter-spacing:.3em;text-transform:uppercase;color:rgba(255,255,255,.8);
  transition:opacity 400ms var(--ease-spring)}
.gate-hint svg{width:14px;height:18px;animation:gate-bounce 1.6s ease-in-out infinite}
@keyframes gate-bounce{0%,100%{transform:translateY(0);opacity:.5}50%{transform:translateY(5px);opacity:1}}
.gate-progress{position:absolute;left:0;right:0;bottom:0;height:2px;background:rgba(255,255,255,.12)}
.gate-progress-fill{height:100%;background:var(--orange);transform:scaleX(0);transform-origin:left center}
.gate-skip{position:absolute;right:clamp(16px,3vw,32px);bottom:clamp(20px,4vh,40px);
  font:600 .8125rem/1 var(--font-body);letter-spacing:.04em;text-transform:uppercase;color:var(--paper);
  background:var(--surface-200);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:.8rem 1.1rem;cursor:pointer;
  opacity:0;pointer-events:none}
html.gate-can-skip .gate-skip,.gate-skip:focus-visible{opacity:1;pointer-events:auto}
.gate-skip:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.gate-credit{position:absolute;left:clamp(16px,3vw,32px);bottom:clamp(12px,2vh,20px);
  font-size:.6875rem;color:rgba(255,255,255,.5)}
.gate-credit a{color:inherit}

/* Knight big phase (after the gate): crest plays centred and large, then nav.js FLIPs it into
   its hero slot. mix-blend lighten keeps the video's black background invisible. */
/* no page scroll while the knight plays big (leftover wheel/swipe momentum from the gate) */
html.intro-big,html.intro-big body{overflow:hidden}
html.intro-big .hero-crest{position:fixed;left:50%;top:50%;z-index:1100;margin:0;
  width:min(105vh,100vw);transform:translate(-50%,-50%)}
@media (prefers-reduced-motion:reduce){
  .gate,html.has-gate .gate{display:none}
  .gate-hint svg{animation:none}
}

/* Hero entrance — crest/wordmark/subtext/CTAs fade up staggered, gated by nav.js to
   start only after the intro video ends/is skipped (or immediately on repeat visit/reduced-motion).
   .hero-inner keeps its "reveal" class as the JS hook only; its own base .reveal fade is
   neutralized here so it never double-fades on top of its children (seam rule). */
.hero-inner.reveal{opacity:1;transform:none;transition:none}
.hero-inner h1,.hero-inner .lead,.hero-inner .hero-cta{
  opacity:0;transform:translateY(20px);
  transition:opacity var(--dur-enter) var(--ease-spring), transform var(--dur-enter) var(--ease-spring);
}
.hero-inner.in h1{transition-delay:80ms}
.hero-inner.in .lead{transition-delay:160ms}
.hero-inner.in .hero-cta{transition-delay:240ms}
.hero-inner.in h1,.hero-inner.in .lead,.hero-inner.in .hero-cta{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .hero-inner h1,.hero-inner .lead,.hero-inner .hero-cta{opacity:1;transform:none;transition:none}
}

@media (max-width:1023px){
  .foot-grid{grid-template-columns:1fr 1fr;gap:30px}
}
@media (max-width:599px){
  .foot-grid{grid-template-columns:1fr}
}
@media (max-width:1040px){
  .menu > li > a, .menu > li > button{font-size:.8rem;padding:.6rem .45rem}
}
@media (max-width:980px){
  .news-grid,.action-grid,.logo-grid{grid-template-columns:1fr 1fr}
  .about-grid,.contact-grid{grid-template-columns:1fr;gap:34px}
  .ig-grid{grid-template-columns:repeat(3,1fr)}
  .team-grid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:820px){
  .nav{width:100%;max-width:none;margin:0;border-radius:0;border:0}
  /* scroll-edge fade replaces the hard bottom line, only when scrolled (DS §8 Materials) */
  .nav::after{content:"";position:absolute;left:0;right:0;top:100%;height:24px;pointer-events:none;background:linear-gradient(180deg,rgba(20,18,16,.55),rgba(20,18,16,0));opacity:0;transition:opacity var(--dur-base) var(--ease-spring)}
  header.site.scrolled .nav::after{opacity:1}
  .nav-right .social-mini{display:none}
  .burger{display:flex}
  .menu{position:fixed;top:var(--header-h);left:auto;right:0;width:min(88vw,420px);background:rgba(30,27,24,.86);-webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);flex-direction:column;align-items:stretch;justify-content:flex-start;gap:0;padding:14px 18px 26px;
    /* right-aligned side sheet (DS §8, 2026-10-03): explicit height from the viewport. Since 24.8 the glass sits on
       .nav::before, so header.site is no longer the containing block (was: backdrop-filter, design audit 2026-09-26) */
    height:calc(100vh - var(--header-h));height:calc(100dvh - var(--header-h));box-sizing:border-box;overflow-y:auto;transform:translateX(110%);transition:transform var(--dur-base) var(--ease-spring)}
  .menu.open{transform:translateX(0)}
  .menu > li > a, .menu > li > button{color:var(--paper);width:100%;justify-content:space-between;font-size:1rem;padding:.85rem .4rem;border-bottom:1px solid var(--line)}
  .menu > li.menu-cta > a{background:var(--accent);color:var(--ink-on-accent);font-family:var(--font-body);font-weight:600;border:2px solid transparent;border-radius:var(--radius-sm);justify-content:center;padding:.6rem 1.05rem;font-size:.8rem}
  /* submenu: grid 0fr -> 1fr (DS §5), reversible mid-flight. High specificity on purpose: it must
     beat the desktop :focus-within/:hover/.dropdown-forced open rules. visibility keeps the
     collapsed links out of the tab order and flips at the end of the close */
  header.site .menu > li > .dropdown{position:static;display:grid;grid-template-rows:0fr;opacity:1;visibility:hidden;transform:none;background:none;-webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;border:0;border-radius:0;padding:0;min-width:0;transition:grid-template-rows var(--dur-base) var(--ease-spring), visibility var(--dur-base)}
  header.site .menu > li > .dropdown.open{grid-template-rows:1fr;visibility:visible}
  .dropdown-in{min-height:0;overflow:hidden;padding-left:12px}
  .dropdown-in > a:last-child{margin-bottom:8px}
  .caret.open{transform:rotate(225deg)}
}
/* mobile menu scrim: dim layer behind the side sheet; opacity only, tap closes (nav.js).
   Sits before .nav in the header so the sheet paints above it; starts below the bar */
.menu-scrim{display:none}
@media (max-width:820px){
  .menu-scrim{display:block;position:fixed;inset:var(--header-h) 0 0 0;background:rgba(20,18,16,.6);opacity:0;pointer-events:none;transition:opacity var(--dur-base) var(--ease-spring)}
  .menu-scrim.open{opacity:1;pointer-events:auto}
}
@media (prefers-reduced-motion:reduce){
  .menu{transition:none}
  header.site .menu > li > .dropdown{transition:none}
}
@media (max-width:560px){
  .news-grid,.action-grid,.logo-grid,.info-cards{grid-template-columns:1fr}
  .ig-grid,.team-grid{grid-template-columns:repeat(2,1fr)}
  .values{grid-template-columns:1fr}
  .stat-grid{grid-template-columns:repeat(2,1fr);gap:1.6rem 0}
  .stat-band .stat{padding:0 1rem}
  .stat-band .stat:nth-child(3){border-left:0;padding-left:0}
}

/* ============================================================
   SPIELBETRIEB PAGES (Milestone 2) — Spieltermine / Spielergebnisse /
   Trainingszeiten. Additive only: reuses existing tokens/components
   (--ink, --accent, --line, .section-head, .train-table, .btn-outline);
   nothing above this block is changed.
   ============================================================ */

.page-head{padding-top:calc(var(--header-h) + var(--section-pad-tight))}
.page-head .section-head{margin-bottom:0}
/* sub-page body section right after the head: no second top pad (form/cards above the fold) */
.page-head + .section-tight{padding-top:0}
.page-head h1{font-size:var(--h2)}
/* breadcrumbs (Task 4.4) — meta style DS §3; separator via CSS, wraps at 390px */
.crumbs{margin-bottom:var(--space-2)}
/* meta style, DESIGN_SYSTEM.md §8 (2026-09-24): structural crumbs only — the final
   [aria-current] crumb below is exempt (long dynamic news titles shouldn't be uppercased) */
.crumbs ol{display:flex;flex-wrap:wrap;gap:0 .5rem;list-style:none;margin:0;padding:0;font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.06em;font-size:.75rem;color:var(--ink-dim);overflow-wrap:anywhere}
.crumbs li + li::before{content:"/";margin-right:.5rem}
.crumbs a{display:inline-block;padding:var(--space-2) 0;color:var(--ink-dim);transition:color var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.crumbs a:hover{color:var(--paper)}}
.crumbs a:focus-visible{color:var(--paper)}
.crumbs [aria-current]{padding:var(--space-2) 0;color:var(--paper);text-transform:none;letter-spacing:normal}

/* fixtures / results lists */
.fixture-team-group{margin-top:var(--head-gap)}
.fixture-team-group:first-child{margin-top:2.4rem}
.fixture-team-group h3{font-size:1.05rem;margin-bottom:1rem;color:var(--paper)}
.fixture-list{display:flex;flex-direction:column;gap:12px}
.fixture-row,.result-row{display:grid;gap:18px;align-items:center;background:var(--ink-2);border:1px solid var(--line);border-radius:var(--radius-in);padding:16px 20px;transition:transform var(--dur-base) var(--ease-spring)}
.fixture-row{grid-template-columns:120px 1fr 1.4fr auto}
.result-row{grid-template-columns:120px 1fr auto}
@media (hover:hover) and (pointer:fine){.fixture-row:hover,.result-row:hover{transform:translateY(-4px)}}
.fixture-date{font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.04em;font-size:.84rem;color:var(--silver-2)}
.fixture-opp{font-family:var(--font-display);font-weight:400;font-size:.98rem;text-transform:uppercase;letter-spacing:.01em}
.fixture-venue{font-size:.86rem;color:var(--silver-2)}
.fixture-time{font-family:var(--font-body);font-weight:600;font-size:.9rem;color:var(--paper);text-align:right}
/* Scoreboard-Optik (Task 14.8.1): big tabular-nums score + W/L badge, DS tokens only.
   Orange badge fill = a small "Live-Score-Anzeige" (tokens.json §color, orange usage note),
   not a second CTA-style fill. Grey badge fill uses --surface-100 text, not grey-as-text-on-
   surface (contrast ~5.35:1, passes AA) — grey stays off surface-100/200 as TEXT, per DS §2.
   DS-Nachtrag logged in OPEN_ITEMS for web-art-director to fold this pattern into the DS docs. */
.result-score{display:flex;align-items:center;gap:.6rem;font-family:var(--font-display);font-weight:400;font-size:clamp(1.5rem,4vw,2.1rem);font-variant-numeric:tabular-nums;color:var(--ink);white-space:nowrap}
/* flat, no win/loss color-coding (DESIGN_SYSTEM.md §8, 2026-09-24) — label text carries meaning */
.result-score em{font-style:normal;display:inline-flex;align-items:center;padding:.28rem .6rem;border-radius:var(--radius-sm);font-family:var(--font-body);font-weight:600;font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;background:var(--border);color:var(--ink-dim)}

/* Empty state (Phase 17.7, Spielbetrieb-leer.dc.html): boxed card instead of a bare
   centred paragraph (Audit 2026-09-26 Punkt 4 — page reads >80% empty). Info cards below
   are plain bordered boxes, NOT the design's border-left accent treatment (anti-slop per
   task brief) — link text stays white/paper, only the arrow glyph is orange (DESIGN_SYSTEM
   §2: orange never as text, only underline/icon). */
.empty-state{text-align:left;max-width:none;margin:2.4rem 0 0;padding:32px;background:var(--surface-200);border:1px solid var(--border);border-radius:var(--radius-md);display:flex;align-items:center;justify-content:space-between;gap:24px}
.empty-state .section-head{margin-bottom:0}
.empty-state p{color:var(--silver-2);margin-bottom:0}
.empty-state .btn{flex-shrink:0}
@media(max-width:700px){.empty-state{flex-direction:column;align-items:stretch}}

.empty-info-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5);margin-top:var(--space-5)}
.empty-info-card{background:var(--surface-200);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-2)}
.empty-info-card .head{display:flex;align-items:center;gap:10px}
.empty-info-card .head svg{flex:none}
.empty-info-card .head span{font-weight:700;color:var(--paper);font-size:1rem}
.empty-info-card p{color:var(--ink-dim);font-size:.875rem;line-height:1.4;margin:0}
.empty-info-card a{display:inline-flex;align-items:center;gap:.4rem;font-weight:600;font-size:.8rem;text-transform:uppercase;letter-spacing:.04em;color:var(--paper);margin-top:.25rem}
.empty-info-card a .arrow{color:var(--orange)}
@media(max-width:700px){.empty-info-grid{grid-template-columns:1fr}}

/* trainingszeiten */
.train-band{background:var(--ink-2);color:var(--paper)}

@media (max-width:560px){
  .fixture-row,.result-row{grid-template-columns:1fr;gap:6px;text-align:left}
  .fixture-time{text-align:left}
}

/* ================================================================
   CLUB SUBPAGES (Milestone 3) — Verein / Vorstand / Trainer / Herren-1 /
   Mitgliedschaft / Trainingsvideos / Kontakt / Datenschutz / Impressum.
   Additive only: reuses existing tokens/components (--ink, --accent, --line,
   --radius, .section-head, .card, .btn, .team-card, .contact, .info-card,
   .map-consent); nothing above this block is changed.
   ================================================================ */

/* subtle tint for a second same-page content band that needs to read as a deliberate break
   rather than a stacked duplicate of the preceding section (DESIGN_SYSTEM §4 rhythm) */
.tint{background:var(--ink-2)}

/* people grid — Vorstand / Trainer: photo, name, role */
.people-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:26px}
.people-card{text-align:center}
.people-card .photo{aspect-ratio:1;border-radius:var(--radius);overflow:hidden;background:var(--ink-3);isolation:isolate}
/* Portraits in colour (Lukas 2026-09-28: "alle Personenfotos in Farbe"; was duotone since
   Audit 2026-09-26 Punkt 6). Roster cards were never filtered. */
.people-card .photo img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
/* portraits are 3:4 / tall, the box is square: centre each face (measured 2026-09-26, Lukas "Gesichter in
   die Mitte"); y% = (face_y*H - W/2) / (H - W), clamped at 0 */
/* 2026-09-28 (Phase 18.5, Lukas "Haaransätze angleichen"): head top measured via subject mask,
   aligned to Raphael/Dominik at ~12% of the box; y% = (head_top*W_box/W - 0.12*W_box) / overflow */
.people-card .photo img[src*="vorstand-adrian-mitchell"]{object-position:50% 43%}
.people-card .photo img[src*="vorstand-lukas-blank"]{object-position:50% 60%}
.people-card .photo img[src*="vorstand-dominik-klocker"],.people-card .photo img[src*="vorstand-raphael-miksch"]{object-position:50% 0}
@media (hover:hover) and (pointer:fine){.people-card:hover .photo img{transform:scale(1.06)}}
.people-card .photo.noph{display:grid;place-items:center}
.people-card .initials{font-family:var(--font-display);font-weight:400;font-size:2.4rem;color:var(--silver-2)}
.people-card .name{font-family:var(--font-display);font-weight:400;text-transform:uppercase;letter-spacing:.02em;font-size:1rem;margin-top:.9rem}
.people-card .role{font-size:.86rem;color:var(--silver-2);margin-top:.2rem}

/* Vorstand (Phase 17.7, Vorstand.dc.html): bio directly in the card, no second heading
   block underneath (Audit 2026-09-26 Punkt 8 — jeder Name doppelt). Modifier only, Trainer
   keeps the plain centred .people-card caption (object-position rules above still match,
   same .photo/.photo img structure). */
.people-card.bio-card{text-align:left;background:var(--surface-200);border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;display:flex;flex-direction:column}
.people-card.bio-card .photo{border-radius:0}
.people-card.bio-card .info{padding:var(--space-4)}
.people-card.bio-card .name{margin-top:0;font-family:var(--font-body);font-weight:700;text-transform:none;letter-spacing:normal;font-size:1.05rem}
.people-card.bio-card .role{color:var(--ink-dim);text-transform:uppercase;letter-spacing:.06em;font-size:.72rem;font-weight:500;margin:.3rem 0 .75rem}
.people-card.bio-card .bio{font-size:.8rem;line-height:1.4;color:var(--ink-dim);margin:0}

/* roster template — Herren-1 (and future U14/U19 teams: copy this block wholesale,
   swap the data source, keep the coach-highlight + player-grid shape) */
.roster-coach{display:flex;gap:26px;align-items:center;background:var(--ink-2);border-radius:var(--radius);padding:26px;margin-bottom:var(--head-gap)}
.roster-coach .photo{width:120px;height:120px;border-radius:50%;overflow:hidden;flex:0 0 auto;background:var(--ink-3)}
.roster-coach .photo img{width:100%;height:100%;object-fit:cover}
.roster-coach .role{font-family:var(--font-body);font-weight:500;color:var(--silver-2);text-transform:uppercase;letter-spacing:.1em;font-size:.76rem;margin-bottom:.3rem}
.roster-coach h3{font-size:1.3rem}
.roster-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:22px}
.roster-card{text-align:center}
.roster-card .photo{aspect-ratio:3/4;border-radius:var(--radius-in);overflow:hidden;background:var(--ink-3);position:relative;isolation:isolate}
.roster-card .photo img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.roster-card:hover .photo img{transform:scale(1.06)}}
.roster-card .num{position:absolute;top:10px;left:10px;background:var(--orange);color:var(--ink-on-accent);font-family:var(--font-display);font-weight:400;font-size:.78rem;padding:.2rem .55rem;border-radius:var(--radius-sm);z-index:1}
/* no-photo fallback: used instead of showing a wrong/mismatched player photo */
.roster-card .photo.noph{display:grid;place-items:center}
.roster-card .initials{font-family:var(--font-display);font-weight:400;font-size:2.1rem;color:var(--silver-2)}
.roster-card .name{font-family:var(--font-display);font-weight:400;text-transform:uppercase;letter-spacing:.02em;font-size:.9rem;margin-top:.7rem;line-height:1.2}

/* legal prose — Impressum / Datenschutz */
.legal-body{max-width:760px}
.legal-body h2{font-size:1.4rem;margin-top:2.2rem;margin-bottom:.7rem}
.legal-body h2:first-child{margin-top:0}
.legal-body p{color:var(--silver-2);margin-bottom:.9rem}
/* Barlow ships 400/500/600 only — un-set strong/b synthesize a fake bold 700 in the browser */
.legal-body strong,.legal-body b{font-weight:600}
/* inline prose link, DESIGN_SYSTEM.md §8 (2026-09-24): color:inherit + orange underline everywhere,
   one rule for legal/form-note/train-chip/train-dropin prose links, see the other declarations below */
.legal-body a{color:inherit;text-decoration:underline;text-decoration-color:var(--orange);text-underline-offset:.2em}
/* .todo is not scoped to .legal-body — used wherever an unsourced-fact placeholder needs the
   established placeholder-italic treatment (mirrors .train-table td.tba) */
.todo{color:var(--silver-2);font-style:italic}

/* membership pricing — Mitgliedschaft */
/* Phase 17.7 (Mitgliedschaft.dc.html): 5 cards, 5 columns on desktop like the design —
   no grid hole (Audit 2026-09-26 Punkt 3, was repeat(3,1fr) with 5 cards). */
/* Phase 18.6 (Lukas 2026-09-27): 4 cards as 2x2, U14 + Herren merged (same fee); thin orange
   frame = DS orange DETAIL (§Farben "thin orange details"), not a fill. */
.pricing-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}
.price-card{background:var(--ink-2);border:1px solid var(--border);border-radius:var(--radius);padding:20px;text-align:center;transition:transform var(--dur-base) var(--ease-spring), border-color var(--dur-base) var(--ease-spring)}
/* 2026-09-28 Lukas: neutral border, orange only on hover/focus (DS §2, gatekeeper REVISE 18.8) */
@media (hover:hover) and (pointer:fine){.price-card:hover{transform:translateY(-6px);border-color:var(--orange)}}
.price-card:focus-within{border-color:var(--orange)}
.price-card h3{font-size:.94rem;hyphens:auto;overflow-wrap:break-word}
.price-card .price{font-family:var(--font-display);font-weight:400;font-size:2.2rem;color:var(--paper);margin:.6rem 0}
.price-card .price.todo{color:var(--silver-2)}
.price-card .price span{font-size:.9rem;color:var(--silver-2);font-weight:500;text-transform:none;display:block}
.price-card .price.todo span{color:var(--silver-2)}
.price-card p{color:var(--silver-2);font-size:.9rem;margin-bottom:1.2rem}

/* training videos — Trainingsvideos */
/* Trainingsvideos (Phase 17.7): numbered drill cards grouped by category, filled play
   icon + "[Video folgt]" placeholder until real clips exist (no autoplay/embed yet, so
   no iframe path — .video-frame/.video-grid retired in favour of .drill-*). */
/* 2026-10-05: .drill-* rules removed with /trainingsvideos/ (Phase 25); comments kept as history. */

/* redirect stub — Kopie-von-Trainer-1 */
.redirect-stub{min-height:70vh;display:flex;align-items:center;justify-content:center;text-align:center;padding:var(--section-pad) 0}
.redirect-stub p{color:var(--silver-2);margin-top:.8rem}

/* fanshop — product grid rendered by assets/js/fanshop.js into #shopRoot (gap closed:
   these classes shipped in the JS with no CSS backing anywhere in the file) */
.shop-notice{color:var(--silver-2);font-size:.92rem;margin-top:1rem}
.shop-notice strong{color:var(--paper)}
.shop-group{margin-top:var(--head-gap)}
.shop-group:first-child{margin-top:2.4rem}
.shop-group-title{font-size:1.3rem;margin-bottom:1.2rem}
.shop-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:26px}
.shop-price{color:var(--silver-2);font-size:.95rem;margin:.3rem 0 1rem}
/* disabled CTA pattern, DESIGN_SYSTEM §8 — never a faded .btn-primary */

/* Home merch teaser (Task 14.7.2) — surface-200 band between #kontakt and #sponsoren (both
   default surface-100): keeps the DS rule of no two identical surface bands side by side.
   Reuses .shop-grid/.card.shop-card/.shop-price from the fanshop page itself, no new grid CSS. */
.merch-teaser{background:var(--surface-200)}
.merch-cta{text-align:center;margin-top:var(--space-6)}

@media (max-width:980px){
  .people-grid{grid-template-columns:repeat(2,1fr)}
  .roster-grid{grid-template-columns:repeat(3,1fr)}
  .shop-grid{grid-template-columns:1fr 1fr}
}
@media (max-width:560px){
  .people-grid{grid-template-columns:1fr}
  .roster-grid{grid-template-columns:repeat(2,1fr)}
  .pricing-grid{grid-template-columns:1fr}
  .roster-coach{flex-direction:column;text-align:center}
  .shop-grid{grid-template-columns:1fr}
}

/* ================================================================
   NEWS (Milestone 4) — generated listing (news/index.html) and
   generated post pages (news/<slug>/index.html), built by
   scripts/build-news.js. Reuses .card / .news-grid / .section-head /
   .legal-body from the existing component system — only the pieces
   those patterns don't already cover live here.
   ================================================================ */

/* article meta line under the post h1 — overrides the default
   .section-head p treatment (lighter, smaller, no lead-paragraph size) */
.section-head .meta{color:var(--silver-2);font-size:.85rem;margin-top:.6rem}

/* empty-state for the listing page when no posts exist yet — mirrors the
   Spieltermine/Spielergebnisse empty-state pattern (DESIGN_SYSTEM.md §8) */
.news-empty{border:1px solid var(--line);border-radius:var(--radius);padding:48px 32px;text-align:center}
.news-empty p{color:var(--silver-2)}

/* post hero image, full-bleed under the article head */
.article-cover{border-radius:var(--radius);overflow:hidden;margin-bottom:var(--head-gap)}
.article-cover img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block}

/* listing thumbnails + post cover are stimmungsbilder (game/event photos), not portraits
   or product shots — silver duotone applies like every other photo on the site (§9).
   Scoped to .news-grid so the Fanshop's .card-based product grid (color, not duotone,
   per the same rule) is unaffected. */
/* two-photo cover (news frontmatter cover2): halves side by side, same frame as a single cover */
.cover-pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-1,4px);width:100%;height:100%}
.cover-pair source{display:none} /* source would take a grid cell inside display:contents <picture> */
.cover-pair img{width:100%;height:100%;object-fit:cover;object-position:center 20%;display:block}
.article-cover .cover-pair img{aspect-ratio:4/3;height:auto}
.news-grid .thumb img,.article-cover img{transition:transform var(--dur-media) var(--ease-spring)}

/* listing: year groups + team filter (assets/js/news.js toggles [hidden]; .card and
   .train-filter set display, so [hidden] needs an explicit rule) */
.news-year+.news-year{margin-top:2.6rem}
.news-year>h2{font-size:var(--h2);margin-bottom:1.2rem}
.news-filter{margin-top:var(--space-5)}
.news-year[hidden],.news-year .card[hidden],.news-filter[hidden]{display:none}

/* article prose — extends .legal-body with the markdown-generated elements
   (h3 subheads, inline images, lists) the Impressum/Datenschutz prose never needed */
.article-body h3{font-size:1.15rem;margin-top:1.8rem;margin-bottom:.6rem;color:var(--paper)}
.article-body img{width:100%;border-radius:var(--radius);margin:1.4rem 0;display:block}
.article-body ul{color:var(--silver-2);margin:0 0 .9rem 1.2rem;padding:0}
.article-body li{margin-bottom:.4rem}
.article-body strong{color:var(--paper);font-weight:600}
.article-body em{font-style:italic}

/* ================================================================
   HOMEPAGE PASS B (2026-09-11) — News feature grid, Schnellzugang
   slider, Verein values list, Kontakt chips, Sponsor marquee, IG bento.
   Additive only: reuses .bezel/.bezel-core, .tag, .contact-grid,
   tokens; nothing above this block is changed. index.html only —
   index.en.html keeps the old markup until its own mirror pass.
   ================================================================ */

/* fly-in entrance — extends the existing .reveal observer (DESIGN_SYSTEM §5).
   Elements carry both classes; the shared IntersectionObserver in nav.js adds
   .in to any .reveal target, which also resolves these rules. */
.reveal-fly-l,.reveal-fly-b,.reveal-fly-r{filter:blur(6px);transition:opacity var(--dur-reveal) var(--ease-spring), transform var(--dur-reveal) var(--ease-spring), filter var(--dur-reveal) var(--ease-spring)}
.reveal-fly-l{transform:translate(-80px,40px) rotate(-2deg)}
.reveal-fly-b{transform:translate(0,40px) rotate(0)}
.reveal-fly-r{transform:translate(80px,40px) rotate(2deg)}
.reveal-fly-l.in,.reveal-fly-b.in,.reveal-fly-r.in{transform:none;filter:none}
.news-feature-grid .news-card:nth-child(1){transition-delay:0ms}
.news-feature-grid .news-card:nth-child(2){transition-delay:120ms}
.news-feature-grid .news-card:nth-child(3){transition-delay:240ms}
@media (max-width:820px){
  .reveal-fly-l,.reveal-fly-b,.reveal-fly-r{transform:translateY(16px) rotate(0)}
}
@media (prefers-reduced-motion:reduce){
  .reveal-fly-l,.reveal-fly-b,.reveal-fly-r{transform:none;filter:none;transition:none}
}

/* news — asymmetric feature grid, the page's only card grid (DESIGN_SYSTEM §10 #5) */
.news-feature-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:26px}
.news-feature-grid .news-card.feature{grid-column:1 / 3;grid-row:1 / 3}
.news-feature-grid .news-card:nth-child(2){grid-column:3 / 4;grid-row:1 / 2}
.news-feature-grid .news-card:nth-child(3){grid-column:3 / 4;grid-row:2 / 3}
.news-feature-grid .bezel{height:100%}
.news-feature-grid .bezel-core{display:flex;flex-direction:column;height:100%}
.news-media{position:relative;display:block;aspect-ratio:16/10;overflow:hidden;isolation:isolate}
.news-feature-grid .feature .news-media{aspect-ratio:16/12}
.news-media img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.news-card:hover .news-media img{transform:scale(1.06)}}
.news-body{padding:22px 24px 26px;display:flex;flex-direction:column;flex:1}
.news-date{display:flex;align-items:baseline;gap:.4rem;margin-bottom:.6rem}
.news-date .nd-day{font-family:var(--font-display);font-weight:400;font-size:var(--newsdate);line-height:1;color:var(--silver)}
.news-date .nd-mon{font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.08em;font-size:.72rem;color:var(--silver-2)}
.news-card h3{font-size:var(--h3);line-height:1.12;margin-bottom:.5rem}
.news-card h3 a{color:inherit}
.news-card .more{color:var(--silver);font-weight:600;font-size:.9rem;margin-top:auto;padding-top:1rem;display:inline-flex;align-items:center;gap:.4rem}
.news-card .more svg{width:15px;height:15px;transition:transform var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.news-card:hover .more svg{transform:translateX(4px)}}
@media (max-width:820px){
  .news-feature-grid{grid-template-columns:1fr}
  .news-feature-grid .news-card.feature,.news-feature-grid .news-card:nth-child(2),.news-feature-grid .news-card:nth-child(3){grid-column:auto;grid-row:auto}
  .news-feature-grid .feature .news-media{aspect-ratio:16/10}
}

/* Schnellzugang slider — horizontal scroll-snap carousel (DESIGN_SYSTEM §5, §8) */
.quick{background:var(--surface-100)}
.quick-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:24px;margin-bottom:var(--head-gap)}
.quick-head-text{max-width:640px}
.quick-head-text h2{font-size:var(--h2);color:var(--paper)}
.quick-head-text p{color:var(--silver-2);font-size:1.05rem;margin-top:.7rem}
.quick-controls{display:flex;gap:.6rem}
.quick-prev,.quick-next{width:46px;height:46px;border-radius:50%;background:var(--ink-2);border:1px solid var(--line);color:var(--paper);display:grid;place-items:center;cursor:pointer;transition:transform var(--dur-fast) var(--ease-spring), border-color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.quick-prev:hover,.quick-next:hover{border-color:var(--silver);transform:translateY(-2px)}}
.quick-prev:focus-visible,.quick-next:focus-visible{border-color:var(--silver)}
.quick-prev:disabled,.quick-next:disabled{opacity:.35;pointer-events:none}
.quick-prev svg,.quick-next svg{width:18px;height:18px}
.quick-track-wrap{overflow-x:hidden}
.quick-track{display:flex;gap:26px;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding:8px calc(50% - 42.5vw) 28px}
.quick-track:focus-visible{outline:2px solid var(--orange);outline-offset:-4px}
.quick-track::-webkit-scrollbar{display:none}
.quick-slide{flex:0 0 auto;width:85vw;max-width:520px;scroll-snap-align:center;opacity:.6;transform:scale(.92);transition:transform var(--dur-base) var(--ease-spring), opacity var(--dur-base) var(--ease-spring)}
.quick-slide.is-active{opacity:1;transform:scale(1)}
.quick-media{position:relative;isolation:isolate;aspect-ratio:4/3;overflow:hidden}
.quick-media img{width:100%;height:100%;object-fit:cover}
.quick-media-top img{object-position:50% 20%}
.quick-body{padding:22px 24px 26px}
.quick-body h3{font-size:var(--h3);margin-bottom:.5rem}
.quick-body p{color:var(--silver-2);font-size:.92rem;margin-bottom:1.1rem}
.quick-progress{height:2px;background:var(--line);border-radius:var(--radius-sm);overflow:hidden;max-width:200px;margin:28px auto 0}
.quick-progress-fill{display:block;height:100%;width:100%;background:var(--silver);transform-origin:0 50%;transform:scaleX(.25);transition:transform var(--dur-base) var(--ease-spring)}
@media (min-width:612px){
  .quick-track{padding-left:calc(50% - 260px);padding-right:calc(50% - 260px)}
}
@media (prefers-reduced-motion:reduce){
  .quick-slide{opacity:1;transform:none;transition:none}
}
@media (max-width:820px){
  .quick-prev,.quick-next{display:none}
}
/* Desktop (Lukas 2026-09-25, Task 15.3): one card across the full container width, no peeking
   neighbours, arrows/drag move exactly one card (nav.js scrollByOne = slide width + GAP). */
@media (min-width:1024px){
  .quick-track-wrap{max-width:var(--container);margin:0 auto;padding:0 22px}
  .quick-track{padding:8px 0 28px}
  .quick-slide{width:100%;max-width:none;scroll-snap-align:start;opacity:1;transform:none}
  .quick-slide .bezel-core{display:grid;grid-template-columns:3fr 2fr;align-items:stretch}
  .quick-media{aspect-ratio:auto;min-height:420px}
  .quick-body{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;padding:40px 44px}
}

/* Verein — team photo stays duotone at all times, no hover-to-color exception
   (that's news cards only, DESIGN_SYSTEM §9) */
.about-media .bezel-core{position:relative;isolation:isolate}

/* Verein — vertical hairline list, never a 3-up (DESIGN_SYSTEM §6, §10 #7) */
.values-list{margin-top:1.8rem;border-top:1px solid var(--line)}
.value-row{padding:20px 0;border-bottom:1px solid var(--line)}
.value-row h3{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.04em;font-size:1.02rem}
.value-row p{font-size:.92rem;color:var(--silver-2);margin-top:.35rem}

/* Verein (Phase 17.7, Verein.dc.html): static fact band (no count-up JS, unlike the
   home .stat-band — this is a simple boxed card, not a full-bleed hero moment) + the
   "Wege zum Verein" link cards (Vorstand/Trainer/Mitgliedschaft). */
.fact-band{background:var(--surface-200);border:1px solid var(--border);border-radius:var(--radius-md);display:grid;grid-template-columns:repeat(4,1fr)}
.fact{padding:var(--space-6) var(--space-5);border-right:1px solid var(--border)}
.fact:last-child{border-right:0}
.fact .num{font-family:var(--font-display);font-weight:400;font-size:2.6rem;line-height:1.04;color:var(--paper)}
.fact .lbl{font-size:.78rem;font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-dim);margin-top:.5rem}
.path-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-5);margin-top:1rem}
.path-card{display:flex;align-items:center;justify-content:space-between;gap:12px;background:var(--surface-200);border:1px solid var(--border);border-radius:var(--radius-md);padding:20px 24px;font-weight:600;color:var(--paper)}
.path-card:focus-visible{color:var(--paper);border-color:var(--border-strong)}
@media (hover:hover) and (pointer:fine){.path-card:hover{color:var(--paper);border-color:var(--border-strong)}}
.path-card .arrow{color:var(--orange);font-size:1.1rem}
@media(max-width:980px){.fact-band{grid-template-columns:repeat(2,1fr)}.fact:nth-child(2){border-right:0}.fact:nth-child(3),.fact:nth-child(4){border-top:1px solid var(--border)}.path-grid{grid-template-columns:1fr}}
@media(max-width:560px){.fact-band{grid-template-columns:1fr}.fact{border-right:0!important;border-top:1px solid var(--border)}.fact:first-child{border-top:0}}

/* Kontakt — two data columns: contact rows + training-time chips (DESIGN_SYSTEM §8, §10 #9) */
.contact-list{border-top:1px solid var(--line)}
.contact-row{display:flex;flex-wrap:wrap;justify-content:space-between;gap:12px 16px;padding:18px 0;border-bottom:1px solid var(--line)}
.contact-row .cl-label{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.08em;font-size:.78rem;color:var(--silver-2)}
.contact-row a{font-size:1rem;color:var(--paper)}
@media (hover:hover) and (pointer:fine){.contact-row a:hover{color:var(--silver)}}
.contact-row a:focus-visible{color:var(--silver)}
.train-note{font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.08em;font-size:.78rem;color:var(--silver-2);margin-bottom:1rem}
.train-chips{display:flex;flex-direction:column;gap:var(--space-3)}
.train-chip{background:var(--ink-3);border:1px solid var(--line);border-radius:var(--radius-sm);padding:0 var(--space-4);transition:border-color var(--dur-fast) var(--ease-spring)}
.train-chip[open]{border-color:var(--silver)}
/* sentence case: full FAQ questions, uppercase is a label-token rule (DESIGN_SYSTEM.md §8, 2026-09-24) */
.train-chip summary{transition:scale var(--dur-fast) var(--ease-spring);list-style:none;cursor:pointer;padding:var(--space-4) 0;font-family:var(--font-body);font-weight:600;text-transform:none;letter-spacing:normal;font-size:.92rem;color:var(--ink-dim);display:flex;justify-content:space-between;align-items:center}
.train-chip[open] summary{color:var(--paper)}
.train-chip summary::-webkit-details-marker{display:none}
/* +/- Icon (Task 14.4.5, Block 63): zwei ueberlagernde Balken, der vertikale dreht 90deg auf
   den horizontalen -> reines CSS-rotate, kein Content-Swap. Markup: scripts/build-faq.js +
   probetraining/index.html (gleiche .train-chip-Klasse, Kommentar am Skriptkopf). */
.faq-ic{position:relative;width:14px;height:14px;flex:0 0 auto}
.faq-ic::before,.faq-ic::after{content:'';position:absolute;top:50%;left:50%;width:14px;height:2px;background:var(--orange);transform:translate(-50%,-50%);transition:transform var(--dur-base) var(--ease-spring)}
.faq-ic::after{transform:translate(-50%,-50%) rotate(90deg)}
.train-chip[open] .faq-ic::after{transform:translate(-50%,-50%) rotate(0deg)}
/* FAQ open/close (DS §5 Disclosure motion): block-size 0 <-> auto via ::details-content +
   interpolate-size; content-visibility allow-discrete keeps the closing content painted until the
   end. Without ::details-content support the panel stays instant. */
@supports (selector(::details-content)){
  .train-chip{interpolate-size:allow-keywords}
  .train-chip::details-content{block-size:0;overflow:clip;transition:block-size var(--dur-base) var(--ease-spring), content-visibility var(--dur-base) allow-discrete}
  .train-chip[open]::details-content{block-size:auto}
  /* the global reduce net (*::before/::after) does not reach ::details-content */
  @media (prefers-reduced-motion:reduce){.train-chip::details-content{transition:none}}
}
@media (prefers-reduced-motion:reduce){.faq-ic::before,.faq-ic::after{transition:none}}
.train-slot{display:flex;flex-wrap:wrap;justify-content:space-between;gap:6px 12px;padding:12px 0;border-top:1px solid var(--line);font-size:.88rem;color:var(--silver-2)}
.train-slot:last-of-type{padding-bottom:16px}
.train-slot .ts-day{font-family:var(--font-body);font-weight:600;color:var(--paper);min-width:28px}

/* Sponsors — single marquee, the only one on the site (DESIGN_SYSTEM §5, §9). Manual
   pause/play button added Task 14.8.3: native <button aria-pressed>, .is-paused class toggles
   animation-play-state alongside the existing :hover/:focus-within pause. .marquee-viewport
   carries the mask/overflow so the button itself sits outside the clipped/animated track. */
.marquee{display:flex;align-items:stretch;gap:8px}
.marquee-viewport{flex:1;min-width:0;overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.marquee-track{display:flex;align-items:center;gap:56px;width:max-content;animation:marquee 40s linear infinite}
.marquee:focus-within .marquee-track,.marquee.is-paused .marquee-track{animation-play-state:paused}
@media (hover:hover) and (pointer:fine){.marquee:hover .marquee-track{animation-play-state:paused}}
.marquee-logo{flex:0 0 auto;height:44px;display:flex;align-items:center}
.marquee-logo:focus-visible{outline-offset:-2px}
.marquee-logo img{height:100%;width:auto;object-fit:contain}
.marquee-toggle{position:relative;flex:0 0 auto;width:34px;display:grid;place-items:center;background:none;border:0;border-left:1px solid var(--border);color:var(--ink-dim);cursor:pointer;transition:color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
/* rendered box is already 34x44 (stretched to .marquee-logo's height), flush against the
   viewport's right edge — ::before widens the hit area left only (no right-side room, no
   vertical pad needed; touch-target fix). */
.marquee-toggle::before{content:'';position:absolute;inset:0 0 0 -10px}
.marquee-toggle:focus-visible{color:var(--ink)}
@media (hover:hover) and (pointer:fine){.marquee-toggle:hover{color:var(--ink)}}
.marquee-toggle:focus-visible{outline-offset:-2px}
.marquee-toggle .marquee-ic-play{display:none}
.marquee.is-paused .marquee-toggle .marquee-ic-pause{display:none}
.marquee.is-paused .marquee-toggle .marquee-ic-play{display:block}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .marquee-toggle{display:none}
  .marquee-viewport{overflow:visible;-webkit-mask-image:none;mask-image:none}
  .marquee-track{animation:none;flex-wrap:wrap;justify-content:center;width:auto}
}

/* Instagram bento — overrides the base .ig-grid (repeat(6,1fr)) that
   index.en.html's unmirrored fallback grid still relies on; index.html's
   5-tile bento wins here via source order (DESIGN_SYSTEM §10 #8). */
#igLive[hidden]{display:none}
/* 2-click Instagram (Task 8.3): reuses .map-consent, assets/js/ig-consent.js */
.ig-consent{aspect-ratio:auto;margin-top:22px}
.ig-consent[hidden]{display:none}
/* REVISE fix (web-gatekeeper, this pass): .ig-tile img had no duotone filter,
   letting full-color photos (incl. an orange basketball) act as a second
   accent (DESIGN_SYSTEM §9). Static duotone only, no hover-to-color here
   (that move is reserved for news cards). */
.ig-grid{grid-template-columns:repeat(4,1fr);grid-template-areas:"a a b c" "a a d e"}
.ig-grid .ig-tile:nth-child(1){grid-area:a}
.ig-grid .ig-tile:nth-child(2){grid-area:b}
.ig-grid .ig-tile:nth-child(3){grid-area:c}
.ig-grid .ig-tile:nth-child(4){grid-area:d}
.ig-grid .ig-tile:nth-child(5){grid-area:e}
@media (max-width:980px){
  .ig-grid{grid-template-columns:repeat(4,1fr)}
}
@media (max-width:560px){
  .ig-grid{grid-template-columns:repeat(2,1fr);grid-template-areas:"a a" "b c" "d e"}
}

/* Footer mini-crest, exact size per DESIGN_SYSTEM §8 (nav .brand img is 42px) */
.foot-brand .brand img{width:40px;height:40px}

/* keyboard focus ring for every interactive element (DESIGN_SYSTEM §Nav/§Buttons) */
:focus-visible{outline:2px solid var(--orange);outline-offset:2px}

/* hover colour changes ease like every other interactive state (DESIGN_SYSTEM §5) */
.dropdown a,.info-card a,.contact-row a,.foot-bottom a{transition:color var(--dur-fast) var(--ease-spring), background var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
@media (prefers-reduced-motion:reduce){
  .dropdown a,.info-card a,.contact-row a,.foot-bottom a{transition:none}
}

/* surface-300 cards: sections stacking these get a surface-200 band so 100→200→300 layers
   (Lukas 2026-09-23, more grey steps); border brightens to orange on hover/focus */
section:not(.section-light):has(.info-cards),section:not(.section-light):has(.train-group),section:not(.section-light):has(.hall-card){background:var(--surface-200)}
/* seam (Phase 25.1): a grey band right after a page head keeps its top pad (the generic
   `.page-head + .section-tight` rule zeroes it, so the heading would stick to the dark→grey edge) */
.page-head + .section-tight:not(.section-light):is(:has(.info-cards),:has(.train-group),:has(.hall-card)){padding-top:var(--section-pad-tight)}
/* DS §4: never two surface-200 bands adjacent — a band directly after a band falls back to surface-100 */
:is(section:has(.info-cards),section:has(.train-group),section:has(.hall-card)) + :is(section:not(.section-light):has(.info-cards),section:not(.section-light):has(.train-group),section:not(.section-light):has(.hall-card)){background:var(--surface-100)}
.info-card{transition:border-color var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.info-card:hover,.train-group:hover,.hall-card:hover{border-color:var(--orange)}}
.info-card:focus-within,.train-group:focus-within,.hall-card:focus-within{border-color:var(--orange)}
@media (prefers-reduced-motion:reduce){
  .info-card,.train-group,.hall-card{transition:none}
}

/* viewport-scoped orange (DESIGN_SYSTEM Dated decision 2026-09-21): from 1000px the sticky .nav-cta
   carries the page's one orange, so the hero Probetraining CTA switches to outline there */
@media(min-width:1000px){
  .hero-cta-swap{background:transparent;border-color:var(--line);color:var(--paper)}
  @media (hover:hover) and (pointer:fine){.hero-cta-swap:hover{background:var(--paper);color:var(--surface-100);border-color:var(--paper)}}
  .hero-cta-swap:focus-visible{background:var(--paper);color:var(--surface-100);border-color:var(--paper)}
  .hero-cta-swap .btn-arrow{background:rgba(255,255,255,.14)}
}
@media (prefers-reduced-motion:reduce){
  .hero-cta-swap{transition:none}
}

/* Probetraining — form, steps, bring list, trust row (Roadmap 2.1). Tokens only. */
.form-grid{display:grid;grid-template-columns:1fr;gap:16px;max-width:760px}
.field label{display:block;font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:.8rem;color:var(--silver-2);margin-bottom:.4rem}
.field input,.field select,.field textarea{width:100%;font-family:var(--font-body);font-size:1rem;background:var(--surface-200);border:1px solid var(--ink-dim);color:var(--paper);border-radius:var(--radius-sm);padding:.85rem 1rem}
.field textarea{min-height:7rem;resize:vertical}
/* error state (DESIGN_SYSTEM.md §8 Forms, 2026-09-24): never orange — orange stays CTA/detail-only */
.field input:user-invalid,.field select:user-invalid,.field textarea:user-invalid,
.field input[aria-invalid="true"],.field select[aria-invalid="true"],.field textarea[aria-invalid="true"]{border:2px solid var(--paper);padding:calc(.85rem - 1px) calc(1rem - 1px)}
.field-hint{font-size:.8rem;margin-top:.4rem}
.field-error{color:var(--paper);font-size:.8rem;font-weight:500;margin-top:.4rem}
.form-actions{display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.4rem}
.form-note{max-width:760px;margin-top:1rem;font-size:.85rem;color:var(--silver-2)}
@media (min-width:720px){
  .form-grid{grid-template-columns:1fr 1fr}
  .form-grid .field.full{grid-column:1 / -1}
}
.steps{list-style:none;counter-reset:step;display:grid;grid-template-columns:1fr;gap:14px}
.steps li{counter-increment:step;background:var(--surface-200);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.steps li::before{content:counter(step);display:block;font-family:var(--font-display);font-size:1.4rem;color:var(--silver-2);margin-bottom:.5rem}
.steps h3{font-size:1.05rem;margin-bottom:.3rem;display:flex;align-items:center;gap:.4rem}
.steps h3 .ic-inline{color:var(--orange)}
.steps p{color:var(--silver-2);font-size:.96rem}
@media (min-width:720px){.steps{grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}}
.bring-list{list-style:disc;padding-left:1.2rem;color:var(--silver-2)}
.train-chip p{padding-bottom:14px;color:var(--silver-2)}
.trust-band{padding:var(--space-7) 0;background:var(--surface-100);border-top:1px solid var(--border)}
.trust-band-list{list-style:none;display:grid;grid-template-columns:1fr;gap:var(--space-6)}
.trust-item{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2)}
.trust-logo{display:block;background:var(--white);border-radius:var(--radius-sm);padding:var(--space-2) var(--space-3)}
.trust-logo img{display:block;height:44px;width:auto}
.trust-ico{width:32px;height:32px;color:var(--orange);flex-shrink:0}
.trust-title{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:.85rem;color:var(--paper)}
.trust-text{color:var(--silver-2);font-size:.95rem;max-width:32ch}
.trust-link{color:var(--silver);font-weight:600;font-size:.95rem;text-decoration:underline;text-underline-offset:3px}
@media (hover:hover) and (pointer:fine){.trust-link:hover{color:var(--paper)}}
.trust-link:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
@media (min-width:760px){.trust-band-list{grid-template-columns:repeat(3,1fr);gap:var(--space-7)}}

/* inline prose link, DESIGN_SYSTEM.md §8 (2026-09-24): one rule, replaces the two competing
   patterns (plain --ink underline vs --ink-dim + orange underline) — color:inherit so it matches
   its surrounding paragraph, orange stays the one allowed underline accent */
.form-note a,.train-chip p a,.train-dropin a{color:inherit;text-decoration:underline;text-decoration-color:var(--orange);text-underline-offset:.2em}

/* Task 3.1: filterable training table + hall cards (tokens only, no accent) */
.train-filter{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:1rem}
.train-filter button{font-family:var(--font-body);font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:.78rem;min-height:44px;padding:.55rem 1rem;background:transparent;border:1px solid var(--line);border-radius:var(--radius-sm);color:var(--paper);cursor:pointer;transition:border-color var(--dur-fast) var(--ease-spring), background var(--dur-fast) var(--ease-spring), color var(--dur-fast) var(--ease-spring), scale var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.train-filter button:hover{border-color:var(--silver)}}
.train-filter button:focus-visible{border-color:var(--silver)}
.train-filter button[aria-pressed="true"]{background:var(--paper);color:var(--surface-100);border-color:var(--paper)}
.hall-list + .train-dropin{margin-top:1.2rem}
.train-dropin{max-width:60ch;margin:0 0 1.2rem;font-size:1rem;color:var(--paper)}
.train-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr));gap:16px;margin-top:1.2rem}
.train-group{background:var(--surface-300);border:1px solid var(--border-strong);border-left:3px solid var(--orange);border-radius:var(--radius);padding:20px;transition:border-color var(--dur-fast) var(--ease-spring)}
.train-group[hidden],.hall-card[hidden]{display:none}
.train-group h3{font-size:1.4rem;margin-bottom:.3rem}
.tg-meta{color:var(--silver-2);font-size:.875rem;margin-bottom:.9rem}
.tg-slots{list-style:none;margin:0;padding:0}
.tg-slots li{display:grid;grid-template-columns:8.5rem 1fr;gap:.3rem 1rem;padding:.9rem 0;border-top:1px solid var(--line)}
.tg-when{font-family:var(--font-body);font-weight:600;font-size:1.05rem;color:var(--paper);font-variant-numeric:tabular-nums}
.tg-when strong{display:block;text-transform:uppercase;letter-spacing:.06em;font-size:.82rem;font-weight:600;color:var(--paper)}
.tg-where{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.tg-where>a{color:var(--paper);font-weight:600;text-decoration:underline;text-underline-offset:.2em}
/* Trainings-Icons (Task 14.4.1, Block 63): 1em inline SVG, Pfade aus lucide (kein Paket),
   currentColor + orange-Wrapper. Ersetzt die alten reinen Orange-Punkte vor .tg-when/h3/h4 durch
   eine gleich kleine, aber inhaltliche Markierung (Uhr/Pin/Person/Ball) an derselben Stelle. */
.ic-inline{width:1em;height:1em;vertical-align:-.15em;flex-shrink:0}
.tg-when .ic-inline,.train-group>h3 .ic-inline,.hall-card>h3 .ic-inline,.tg-meta .ic-inline,.tg-where>a .ic-inline,.em-name .ic-inline,.em-slot-line .ic-inline{color:var(--orange);margin-right:.35em}
.tg-addr,.tg-route{color:var(--silver-2);font-size:.875rem}
.tg-route a{color:var(--paper);text-decoration:underline;text-underline-offset:.2em}
.tg-next{margin-top:.6rem;padding-top:.8rem;border-top:1px solid var(--line);color:var(--paper);font-size:.92rem}
.tg-next::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--orange);margin-right:.5em;margin-bottom:1px}
.tg-slots a:focus-visible,.train-dropin a:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.train-groups + .train-note{margin-top:1rem;margin-bottom:0}
.hall-groups{margin-top:.6rem;color:var(--paper);font-size:.875rem}
@media (max-width:520px){.tg-slots li{grid-template-columns:1fr}.tg-when strong{display:inline;margin-right:.4rem}.tg-route{display:flex;flex-wrap:wrap;gap:0 .6rem}.tg-route a{display:inline-flex;align-items:center;min-height:44px}}
.hall-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:26px}
.hall-card{background:var(--surface-300);border:1px solid var(--border-strong);border-left:3px solid var(--orange);border-radius:var(--radius);padding:var(--space-4);transition:border-color var(--dur-fast) var(--ease-spring)}
.hall-card h3{font-size:var(--body);margin-bottom:.5rem}
.hall-card address{font-style:normal;color:var(--silver-2)}
.hall-notes{margin-top:.6rem;color:var(--silver-2);font-size:.92rem}
.hall-links{display:flex;flex-direction:column;gap:.35rem;margin-top:.9rem;font-size:.92rem}
.hall-links a{color:var(--paper);text-decoration:underline;text-underline-offset:.2em}
@media (prefers-reduced-motion:reduce){
  .train-filter button{transition:none}
}

/* small thumbnail slot inside a .hall-card (team card on /teams/, hall card on
   /trainingszeiten/ — ROADMAP Task 14.6). Base filter only here; hover-to-color/zoom is added
   below, scoped to .teams-grid only (DESIGN_SYSTEM.md: the team INTRO photo stays duotone
   always — this hover treatment is the cards-only exception Lukas decided 2026-09-23). */
.card-photo{aspect-ratio:16/10;border-radius:var(--radius-in);overflow:hidden;margin-bottom:14px}
/* about-team.jpeg is portrait 450x600 (heads at ~39-50%, feet ~73% of height): 66% starts the
   16:10 crop at ~35% so the heads sit inside, not cut off at the top (measured Phase 25.1c) */
.card-photo img[src*="about-team"]{object-position:50% 66%}
.card-photo img{width:100%;height:100%;object-fit:cover;transition:transform var(--dur-media) var(--ease-spring)}
.teams-grid .hall-card:focus-within .card-photo img{transform:scale(1.04)}
@media (hover:hover) and (pointer:fine){.teams-grid .hall-card:hover .card-photo img{transform:scale(1.04)}}
@media (prefers-reduced-motion:reduce){
  .card-photo img{transition:filter var(--dur-media) var(--ease-spring)}
  .teams-grid .hall-card:focus-within .card-photo img{transform:none}
@media (hover:hover) and (pointer:fine){.teams-grid .hall-card:hover .card-photo img{transform:none}}
}

/* round coach photo (Phase 25.2): /teams/ cards + youth team page "Trainer" info-card */
.coach-line{display:flex;align-items:center;gap:.7rem;margin:.4rem 0 0}
.coach-avatar{width:56px;height:56px;flex:none;border-radius:50%;object-fit:cover;border:2px solid var(--border-strong);background:var(--surface-100)}
.section-light .coach-avatar{border-color:var(--light-border);background:var(--light-bg)}
/* trainer cards (Phase 25.3): team line + button under the name, centred like the card */
.people-card .finder-actions{justify-content:center;margin-top:.9rem}

/* team page intro photo (ROADMAP Task 14.6.2) — duotone always, no hover (see .card-photo
   comment above); hidden slot renders nothing when no photo is on file yet. */
.team-photo{aspect-ratio:16/9;border-radius:var(--radius);overflow:hidden;margin-top:var(--space-6)}
.team-photo img{width:100%;height:100%;object-fit:cover;object-position:50% 62%}
/* 16:9 + 62%: crop = ~35%-77% of the portrait, heads (39-50%) and feet (73%) both inside */
@media (max-width:640px){.team-photo{aspect-ratio:4/3}}

/* Altersfinder on /trainingszeiten/ (Task 14.3.3). Tokens only, native input+button. */
.agefinder-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:1rem}
.agefinder-form .field{max-width:12rem}
.agefinder-out{margin-top:1rem;color:var(--silver-2);font-size:.95rem;display:flex;flex-wrap:wrap;align-items:center;gap:.5rem}

/* Wochenplan Mo-Fr (Task 14.3.4), static, no JS. Grid on wide screens, a vertical list per
   day (source order Mo..Fr) once columns no longer fit — readable at 390px. */
.week-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
.week-day{background:var(--surface-300);border:1px solid var(--border-strong);border-radius:var(--radius);padding:16px}
.week-day h3{font-size:.95rem;text-transform:uppercase;letter-spacing:.06em;margin-bottom:.7rem;color:var(--silver-2)}
.week-list{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.week-list li{display:flex;flex-direction:column;gap:.1rem;padding-top:.6rem;border-top:1px solid var(--line)}
.week-list li:first-child{padding-top:0;border-top:0}
.week-time{font-family:var(--font-body);font-weight:600;font-variant-numeric:tabular-nums;color:var(--paper)}
.week-group{color:var(--paper);font-size:.9rem}
.week-hall{color:var(--silver-2);font-size:.85rem}
@media (max-width:820px){.week-grid{grid-template-columns:1fr}}

/* 2-click map (Task 3.3): box holds text + button + plain link, iframe is added by
   assets/js/map-consent.js only after a click. Rendered by scripts/build-training.js. */
.map-consent{aspect-ratio:4/3;margin-top:.9rem;background:var(--surface-300);border:1px solid var(--border-strong);border-left:3px solid var(--orange);border-radius:var(--radius-sm);display:grid;place-items:center;align-content:center;gap:.7rem;text-align:center;padding:1.5rem;overflow:hidden}
.map-consent p{color:var(--silver);font-size:.9rem}
.map-alt{color:inherit;font-size:.9rem;text-decoration:underline;text-decoration-color:var(--orange);text-underline-offset:.2em}
.map-consent.is-loaded{padding:0;border-style:solid}
.map-consent iframe{width:100%;height:100%;border:0;display:block}
.hall-list{list-style:none;margin:.5rem 0 0;padding:0;display:grid;gap:.35rem}
.hall-list li{position:relative;padding-left:.9rem}
.hall-list li::before{content:'';position:absolute;left:0;top:.55em;width:6px;height:6px;border-radius:50%;background:var(--orange)}

/* Expand-Map (Phase 14) — React/framer-motion island (ROADMAP Task 14.1/14.2, Block 60/61).
   .em-slot is the server-rendered host (data-expand-map/data-em, static fallback text as its
   children); `display:contents` makes it invisible to layout so the fallback sits exactly where
   the old markup did (grid cell in .tg-slots li, flow child in .hall-card/.hall-list li). Once
   src/islands/expand-map.tsx mounts, it renders a single `.em-card` in its place — `grid-column`
   makes that card always take the full row/width no matter which ancestor layout it lands in. */
.em-slot{display:contents}
.em-card{position:relative;width:100%;grid-column:1/-1;background:var(--surface-300);
  border:1px solid var(--border-strong);border-radius:var(--radius-md);overflow:visible}
.em-card::before{content:'';position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.03;
  background-image:linear-gradient(var(--ink) 1px,transparent 1px),
    linear-gradient(90deg,var(--ink) 1px,transparent 1px);background-size:14px 14px}
.em-trigger{position:relative;z-index:1;width:100%;display:flex;flex-direction:column;
  background:none;border:0;border-radius:var(--radius-md);cursor:pointer;text-align:left;
  padding:0;font-family:var(--font-body);color:var(--ink);overflow:hidden}
.em-trigger:focus-visible{outline:2px solid var(--orange);outline-offset:-2px}
.em-row{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-4)}
/* street-map preview (Task 16.4, Lukas 2026-09-25: "die Karten sollen echte Strassen anzeigen")
   — real OSM photo visible on the collapsed card, no click needed; same pin as .em-pin below. */
.em-preview{position:relative;display:block;width:100%;height:220px;background:var(--surface-100)}
.em-preview-img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.em-preview-pin{position:absolute;left:50%;top:50%;width:26px;height:26px;transform:translate(-50%,-100%)}
.em-preview-pin svg{display:block;width:100%;height:100%}
@media (max-width:640px){.em-preview{height:190px}}
.em-icon{width:18px;height:18px;flex:0 0 auto;color:var(--ink-dim)}
.em-info{position:relative;flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.em-name{font-weight:600;color:var(--ink)}
.em-slot-line{font-size:.85rem;color:var(--ink-dim)}
.em-underline{display:block;height:2px;width:2.4rem;max-width:100%;background:var(--orange);
  transform-origin:left;transform:scaleX(0);margin-top:2px;
  transition:transform var(--dur-fast) var(--ease-spring)}
.em-card:focus-within .em-underline,.em-card.is-open .em-underline{transform:scaleX(1)}
@media (hover:hover) and (pointer:fine){.em-card:hover .em-underline{transform:scaleX(1)}}
.em-toggle{flex:0 0 auto;font-size:.78rem;font-weight:600;text-transform:uppercase;
  letter-spacing:.04em;color:var(--ink-dim);white-space:nowrap}
.em-panel{position:relative;z-index:1;overflow:hidden;border-top:1px solid var(--border)}
/* .em-map: only for halls without coords (no mapImg, see components/ui/expand-map.tsx) —
   the drawn placeholder grid + pin; halls with a real map show it in .em-preview instead. */
.em-map{position:relative;height:240px;background:var(--surface-100)}
.em-map-grid{position:absolute;inset:0;opacity:.06;
  background-image:linear-gradient(var(--border-strong) 1px,transparent 1px),
    linear-gradient(90deg,var(--border-strong) 1px,transparent 1px);background-size:10% 10%}
.em-pin{position:absolute;left:50%;top:50%;width:32px;height:32px;transform:translate(-50%,-100%)}
.em-pin-svg{display:block;width:100%;height:100%}
.em-map-fade{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,var(--surface-100),transparent 22%)}
.em-details{padding:var(--space-4)}
.em-address{margin:0 0 var(--space-2);color:var(--ink-dim);font-size:.85rem}
.em-routes{display:flex;flex-wrap:wrap;gap:var(--space-4)}
.em-routes a{display:inline-flex;align-items:center;min-height:44px;color:var(--ink-dim);
  font-size:.85rem;font-weight:600;text-decoration:underline;
  text-decoration-color:var(--orange);text-underline-offset:2px}
.em-routes a:focus-visible{color:var(--ink)}
@media (hover:hover) and (pointer:fine){.em-routes a:hover{color:var(--ink)}}

/* Home team finder (Roadmap 3.4). Tokens only. Without JS only the heading and .finder-fallback
   buttons show; assets/js/training.js sets .js on <html>, which reveals .finder-ui. */
.finder{background:var(--surface-100)}
.finder h2{font-size:var(--h2);margin-bottom:1.2rem}
.finder-grid{display:grid;grid-template-columns:1fr;gap:2rem}
.finder-ui{display:none}
.js .finder-ui{display:block}
.js .finder-fallback{display:none}
.finder-fallback,.finder-actions{display:flex;flex-wrap:wrap;gap:.8rem}
.finder-actions{margin-top:1.4rem}
/* /teams/ cards (build-training.js teams-grid): button row bottom-aligned across a grid row,
   buttons never wider than the card */
.teams-grid .hall-card{display:flex;flex-direction:column}
.teams-grid .finder-actions{margin-top:auto;padding-top:1.4rem}
.teams-grid .finder-actions .btn{max-width:100%;padding-inline:1rem;font-size:.85rem;white-space:normal}
.train-halls{margin-top:1rem;color:var(--silver-2);font-size:.9rem}
.train-halls a{color:var(--paper);text-decoration:underline;text-underline-offset:.2em}
@media (min-width:900px){
  .finder-grid{grid-template-columns:1fr 1fr;gap:4rem;align-items:start}
}

/* Home countdown strip (Roadmap 8.2). Tokens only; stays [hidden] until assets/js/countdown.js
   finds a next game or training. Live-Punkt (Task 14.4.4, Block 63): .live-dot sitzt als
   Geschwister von #countdownTitle, nicht darin -- countdown.js ueberschreibt #countdownTitle
   per textContent und wuerde ein Kind-Element sonst loeschen. Sichtbar nur, weil #countdown
   selbst bis dahin [hidden] bleibt (kein extra JS fuer die Sichtbarkeitsregel noetig). Dauer aus
   Token (--dur-count, 1600ms) -- DESIGN_SYSTEM §5 kennt keinen Puls-Wert, siehe ANNAHMEN Block 63. */
.countdown{background:var(--surface-100);border-block:1px solid var(--border);padding:1.6rem 0}
.countdown-label{display:inline-flex;align-items:center;gap:.5em;font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.06em;font-size:.75rem;color:var(--ink-dim);margin-bottom:.3rem}
.live-dot{width:8px;height:8px;border-radius:50%;background:var(--orange);flex:0 0 auto;animation:live-pulse var(--dur-count) var(--ease-spring) infinite}
@keyframes live-pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(1.4)}}
@media (prefers-reduced-motion:reduce){.live-dot{animation:none}}
.countdown-when{font-family:var(--font-display);font-size:var(--h3);line-height:1.2}
.countdown-time{font-family:var(--font-body);font-size:1rem;color:var(--ink-dim);margin-left:.4rem}
.countdown-what{margin-top:.3rem}
.countdown-note{margin-top:.8rem;color:var(--ink-dim);font-size:.9rem}
.countdown-note a{color:var(--ink);text-decoration:underline;text-underline-offset:.2em}
.countdown-actions{margin-top:1rem}

/* Home-game banner (Task 14.8.2) — same [hidden]-until-JS pattern as .countdown above, reuses
   its label/dot/when/time look (own class names since it's a second, independent section, not
   a variant of #countdown). Stays hidden: no markup reflow when assets/js/countdown.js finds
   no future home game (data/schedule.json today has no "home":true entries). */
.home-game-banner{background:var(--surface-200);border-block:1px solid var(--border);padding:1.6rem 0}
.hgb-label{display:inline-flex;align-items:center;gap:.5em;font-family:var(--font-body);font-weight:500;text-transform:uppercase;letter-spacing:.06em;font-size:.75rem;color:var(--ink-dim);margin-bottom:.3rem}
.hgb-match{font-family:var(--font-display);font-size:var(--h3);line-height:1.2}
.hgb-time{font-family:var(--font-body);font-size:1rem;color:var(--ink-dim)}
.hgb-venue{margin-top:.3rem;color:var(--ink-dim);font-size:.9rem}
.hgb-actions{margin-top:1rem}

/* FAQ list / pricing grid sit in the page-head container (its .section-head has margin-bottom:0): give them the head gap */
.page-head .section-head + .train-chips,.page-head .section-head + .pricing-grid{margin-top:var(--head-gap)}
/* federation logo tile, DESIGN_SYSTEM.md §9 (2026-09-24): same opaque light-background JPG as the
   sponsor marquee — invert would paint a white box, reuse .marquee-logo's grayscale/opacity instead.
   Class sits on the <a> (like .marquee-logo) so :hover/:focus-visible target the actual control. */
.federation-logo{display:inline-block;height:56px}
.federation-logo img{height:100%;width:auto;object-fit:contain}
@media (prefers-reduced-motion:reduce){.crumbs a{transition:none}}

/* Scroll-Fortschritt auf News-Artikeln (Task 14.4.7, Block 63). Markup: scripts/build-news.js
   (renderPostPage, direkt in <main>). .header.site ist eine schwebende Pille mit 16px
   Aussenabstand (--header-h beginnt erst danach) -- top:0 liegt also im transparenten Rand
   darueber, keine Kollision. JS (nav.js, passive scroll listener) setzt scaleX(); reduced
   motion: keine eigene Transition definiert, Update bleibt ein hartes Springen (Vorgabe ok). */
.read-progress{position:fixed;top:0;left:0;width:100%;height:3px;background:var(--orange);transform-origin:left;transform:scaleX(0);z-index:1001;pointer-events:none}

/* 404 page (Task 14.9). Ball's static cx/cy in 404.html already sit at the "missed" rest
   position next to the ring -- that IS the reduced-motion fallback, no separate markup.
   Motion-safe only: keyframes fly the ball in from off-canvas, it hits the ring and bounces
   back to that same rest transform (0,0). Duration derived from --dur-enter (900ms * 4/3 =
   1200ms, "~1.2s" per roadmap), easing var(--ease-spring) -- no new motion tokens. */
.error-404{min-height:70vh;min-height:70dvh;display:flex;align-items:center;text-align:center;padding-top:calc(var(--header-h) + 24px)}
.error-404 .container{display:flex;flex-direction:column;align-items:center}
.error-ball-scene{margin-bottom:8px}
.error-ring{stroke:var(--orange)}
.error-ball{fill:var(--orange)}
.error-404 h1{font-size:var(--wordmark);line-height:1.02;margin-bottom:12px}
.error-404 .lead{margin:0 auto}
.error-404 .error-en{font-family:var(--font-body);color:var(--ink-dim);font-size:.92rem;margin:.4rem auto 0}
.error-actions{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-top:32px}
@media (prefers-reduced-motion:no-preference){
  .error-ball{transform-box:fill-box;transform-origin:center;animation:airball-bounce calc(var(--dur-enter) * 4 / 3) var(--ease-spring) both}
}
@keyframes airball-bounce{
  0%{transform:translate(-120px,60px) scale(.5)}
  45%{transform:translate(20px,-14px) scale(1.05)}
  55%{transform:translate(38px,-22px) scale(.9)}
  70%{transform:translate(4px,10px) scale(1.06)}
  85%{transform:translate(-6px,-4px) scale(.98)}
  100%{transform:translate(0,0) scale(1)}
}

/* === Freunde werben (Phase 19) ===
   /freunde-werben/ (QR landing, mobile first 360-430px). Reuses .page-head, .section-head,
   .tint, .legal-body, .btn-primary and the tokens above; nothing outside this block changes.
   Orange: only the final .btn-primary (DESIGN_SYSTEM §2, Lukas 2026-10-02) + thin DETAILS.
   The header CTA would link to itself here, so it is hidden (same pattern as /probetraining/). */
body.fw-page .nav-cta,body.fw-page .menu-cta{display:none}
/* hidden header entry after promoUntil (countdown.js) must beat the .menu li display rules */
[data-promo-only][hidden]{display:none}
/* decorative court lines behind the headline, opacity is baked into the SVG (like .stat-band) */
body.fw-page .page-head{position:relative;isolation:isolate}
body.fw-page .page-head::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("../img/court-lines.svg") center/cover no-repeat}
.fw-ended{margin-top:1.2rem;padding:.8rem 1rem;border:1px solid var(--border-strong,var(--line));
  border-left:3px solid var(--orange);background:var(--surface-200);color:var(--paper);
  font-size:1rem;max-width:46ch}
.fw-ended[hidden]{display:none}
.fw-ended strong{font-weight:700}

/* 3 steps: big Alfa Slab number, one column on phones */
.fw-steps{list-style:none;counter-reset:fw;display:grid;grid-template-columns:1fr;gap:14px}
.fw-steps li{counter-increment:fw;display:grid;grid-template-columns:auto 1fr;column-gap:1rem;
  align-items:start;background:var(--surface-200);border:1px solid var(--line);
  border-radius:var(--radius);padding:18px}
.fw-steps li::before{content:counter(fw);grid-row:1 / span 2;font-family:var(--font-display);
  font-size:var(--stat);line-height:.9;color:var(--paper);min-width:.8em;text-align:center}
.fw-steps h3{font-size:var(--h3);margin-bottom:.3rem}
.fw-steps p{color:var(--ink-dim);font-size:1rem}
@media (min-width:720px){
  .fw-steps{grid-template-columns:repeat(3,minmax(0,1fr))}
  .fw-steps li{grid-template-columns:1fr;row-gap:.6rem}
  .fw-steps li::before{grid-row:auto;text-align:left}
}

/* reward table: stacked cards below 720px (labels from data-label), real table above */
.fw-table{width:100%;border-collapse:collapse}
.fw-table th,.fw-table td{text-align:left;vertical-align:top}
.fw-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.fw-table tr{display:block;background:var(--surface-200);border:1px solid var(--line);
  border-radius:var(--radius);padding:16px 18px;margin-bottom:14px}
.fw-table th[scope="row"]{display:block;font-family:var(--font-display);font-weight:400;
  font-size:1.2rem;text-transform:uppercase;color:var(--paper);margin-bottom:.6rem}
.fw-table td{display:block;color:var(--ink-dim);overflow-wrap:break-word;hyphens:auto}
.fw-table td + td{margin-top:.4rem}
.fw-table td::before{content:attr(data-label);display:block;font-weight:500;
  text-transform:uppercase;letter-spacing:.06em;font-size:.75rem;color:var(--ink-dim)}
.fw-table td:first-of-type{color:var(--paper);font-weight:600;font-size:1.1rem}
@media (min-width:720px){
  .fw-table thead{position:static;width:auto;height:auto;overflow:visible;clip:auto}
  .fw-table thead tr{background:none;border:0;padding:0;margin:0}
  .fw-table tr{display:table-row;background:none;border:0;padding:0;margin:0}
  .fw-table th,.fw-table td{display:table-cell;padding:16px 18px;border-bottom:1px solid var(--line)}
  .fw-table thead th{font-weight:500;text-transform:uppercase;letter-spacing:.06em;
    font-size:.75rem;color:var(--ink-dim)}
  .fw-table th[scope="row"]{font-size:1.1rem;margin:0;width:26%}
  .fw-table td + td{margin:0}
  .fw-table td::before{display:none}
  .fw-table td:first-of-type{width:18%}
}
.fw-foot{margin-top:1rem;color:var(--ink-dim);font-size:.9rem}

/* guarantee: orange DETAIL (left bar), no fill */
.fw-guarantee{background:var(--surface-200);border:1px solid var(--line);
  border-left:3px solid var(--orange);border-radius:var(--radius);padding:22px 20px;max-width:760px}
.fw-guarantee h2{font-size:var(--h2);margin-bottom:.6rem}
.fw-guarantee p{font-size:var(--lead);color:var(--paper)}

.fw-terms{list-style:none;display:grid;gap:.6rem;padding:0}
.fw-terms li{position:relative;padding-left:1.2rem;color:var(--ink-dim)}
.fw-terms li::before{content:'';position:absolute;left:0;top:.7em;width:6px;height:6px;
  background:var(--orange)}
.fw-terms li[hidden]{display:none}

.fw-cta{margin-top:1.6rem}
.fw-cta .btn{justify-content:center;width:100%}
@media (min-width:600px){.fw-cta .btn{width:auto}}
.fw-cta .btn:focus-visible{outline:2px solid var(--orange);outline-offset:3px}

/* === Buddy + Kodex (Phase 19.6) ===
   /buddy/ and /kodex/ (body.bk-page). Reuses .page-head, .section-head, .tint, .legal-body,
   .fw-terms and .btn-primary; nothing outside this block changes. Orange: only the primary button
   on /buddy/ (DESIGN_SYSTEM §2). Angular cut corners via clip-path, no children photos.
   .kodex-num is the hook for a later web-motion task; no motion here. */
body.bk-page .page-head{position:relative;isolation:isolate}
body.bk-page .page-head::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:url("../img/court-lines.svg") center/cover no-repeat}
.bk-cta{margin-top:1.6rem}
.bk-cta .btn{justify-content:center;width:100%}
@media (min-width:600px){.bk-cta .btn{width:auto}}
.bk-cta .btn:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.legal-body a:focus-visible,.kodex-note a:focus-visible{outline:2px solid var(--paper);
  outline-offset:3px}

/* 4 rule cards: big Alfa Slab number, one column on phones */
.kodex-rules{list-style:none;display:grid;grid-template-columns:1fr;gap:14px;padding:0}
.kodex-card{display:grid;grid-template-columns:auto 1fr;column-gap:1rem;align-content:start;
  background:var(--surface-200);padding:20px 18px;
  clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,22px 100%,0 calc(100% - 22px))}
.kodex-num{grid-row:1 / span 2;font-family:var(--font-display);font-size:var(--stat);
  line-height:.9;color:var(--orange);min-width:.8em;text-align:center}
.kodex-card h3{font-size:var(--h3);margin-bottom:.4rem}
.kodex-card p{grid-column:2;color:var(--ink-dim);font-size:1rem;overflow-wrap:break-word;
  hyphens:auto}
@media (min-width:720px){
  .kodex-rules{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
  .kodex-card{grid-template-columns:1fr;row-gap:.5rem;padding:24px 22px}
  .kodex-num{grid-row:auto;text-align:left}
  .kodex-card p{grid-column:auto}
}

/* consequences table: stacked cards below 720px (labels from data-label), real table above */
.kodex-table{width:100%;border-collapse:collapse}
.kodex-table th,.kodex-table td{text-align:left;vertical-align:top}
.kodex-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.kodex-table tr{display:block;background:var(--surface-200);border:1px solid var(--line);
  border-radius:var(--radius);padding:16px 18px;margin-bottom:14px}
.kodex-table th[scope="row"]{display:block;font-weight:400;color:var(--paper);
  overflow-wrap:break-word;hyphens:auto}
.kodex-table td{display:block;margin-top:.6rem;color:var(--paper);font-weight:600;
  overflow-wrap:break-word;hyphens:auto}
.kodex-table th[scope="row"]::before,.kodex-table td::before{content:attr(data-label);
  display:block;font-family:var(--font-body);font-weight:500;text-transform:uppercase;
  letter-spacing:.06em;font-size:.75rem;color:var(--ink-dim)}
@media (min-width:720px){
  .kodex-table thead{position:static;width:auto;height:auto;overflow:visible;clip:auto}
  .kodex-table thead tr{background:none;border:0;padding:0;margin:0}
  .kodex-table tr{display:table-row;background:none;border:0;padding:0;margin:0}
  .kodex-table th,.kodex-table td{display:table-cell;padding:16px 18px;
    border-bottom:1px solid var(--line)}
  .kodex-table td{margin:0}
  .kodex-table th::before,.kodex-table td::before{display:none}
  .kodex-table thead th{font-weight:500;text-transform:uppercase;letter-spacing:.06em;
    font-size:.75rem;color:var(--ink-dim)}
  .kodex-table th[scope="row"]{width:60%}
}
.kodex-note{margin-top:1.4rem;max-width:62ch;color:var(--ink-dim)}
.kodex-note strong{color:var(--paper)}

/* reduced motion: static stack, nothing here animates (hook kept for the motion task) */
@media (prefers-reduced-motion:reduce){
  .kodex-num,.kodex-card{transition:none;animation:none;transform:none}
}

/* === Home-Bänder, Hero-Split, Einwilligung (Phase 19.3/19.4) === */
.hero-split{display:inline-block}
.home-band{text-align:center}
.home-band p{font-size:1rem;color:var(--paper);margin:0}
.home-band h2{font-size:var(--h2);margin:0 0 var(--space-4)}
.home-band .home-band-lead{font-size:1.125rem;max-width:44ch;margin:0 auto var(--space-4)}
.home-band p + p{margin-top:var(--space-3)}
.home-band .home-band-badge{display:inline-flex;align-items:center;gap:var(--space-2);margin-top:var(--space-5);
  padding:var(--space-1) var(--space-4);border-radius:999px;font-size:.8rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;background:var(--light-ink);color:var(--white)}
.home-band .home-band-badge::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--orange)}
.home-band a{text-decoration:underline;text-decoration-color:var(--orange);text-underline-offset:3px}
.home-band a:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
/* Light section (DS §10): scoped token remap so existing --paper/--silver rules flip to dark ink */
.section-light{background:var(--light-bg);color:var(--light-ink);--paper:var(--light-ink);
  --silver:var(--light-ink-dim);--silver-2:var(--light-ink-dim);--line:var(--light-border)}
.section-light h1,.section-light h2,.section-light h3{color:var(--light-ink)}
.section-light a{color:var(--light-ink);text-decoration-line:underline;text-decoration-color:var(--orange);
  text-decoration-thickness:2px;text-underline-offset:.2em}
@media (hover:hover) and (pointer:fine){.section-light a:hover{text-decoration-thickness:3px}}
.section-light a:focus-visible{text-decoration-thickness:3px}
.section-light a:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.section-light .home-band-lead{color:var(--light-ink-dim)}
.section-light .court-lines,.section-light .court-lines *{stroke:var(--light-border)}
.field-consent{display:grid;grid-template-columns:auto 1fr;gap:.7rem;align-items:start}
.field-consent label{text-transform:none;letter-spacing:0;font-size:.95rem;margin:0;color:var(--paper)}
.field-consent input{margin-top:.25rem;width:1.2rem;height:1.2rem}
.field-consent input:focus-visible{outline:2px solid var(--orange);outline-offset:2px}
.field-consent .field-error{grid-column:1 / -1}

/* === Gate 19.8 Fixes === */
/* Kampagne bringt den Extra-Eintrag Probetraining → Logo darf nicht schrumpfen; „Home" ab Desktop
   weg, das Logo führt schon zur Startseite (web-gatekeeper 2026-10-02, DS §8) */
@media (min-width:821px){header.site .brand{flex-shrink:0}}
/* mobil darf die Wortmarke zweizeilig umbrechen, sonst schiebt sie den Burger aus dem Viewport
   (gemessen 2026-10-03: Burger bei 390 px auf x 388–430, seit Gate 19.8) */
/* solange der Kampagnen-Eintrag Probetraining sichtbar ist, passt die Wortmarke nicht daneben
   (gemessen 2026-10-02: +84 px Überlauf DE bis 1600 px) → nur Wappen; ab 2027 automatisch zurück */
@media (min-width:821px){header.site:has(li[data-promo-only]:not([hidden])) .brand span{display:none}}
/* auch ohne Kampagne zu eng zwischen Burger-Grenze und 1200 px (gemessen: bis +69 px DE) */
@media (min-width:821px) and (max-width:1199px){header.site .brand span{display:none}}
@media (min-width:821px){.menu > li:first-child{display:none}}
/* drei Team-Karten: große Altersklasse als Unterscheider statt drei gleicher Karten (DS §6) */
#teams .card h3{font-family:var(--font-display);font-weight:400;font-size:clamp(2.4rem,4.5vw,3.4rem);line-height:1;margin-bottom:.4rem}

/* === Motion Phase 20 (20.1/20.2/20.4) ===
   Spec: docs/seo/MOTION_SPEC_phase20.md. One curve (--ease-spring), every effect has a
   prefers-reduced-motion path (static end state), mobile travel <= 24px. */

/* 20.1 cross-document page transition (Chromium 126+/Safari 18.2+; others: hard switch as before).
   No per-card morphs (size-jump risk, DS §5). The header has no view-transition-name any more:
   a named element becomes a backdrop root and kills the .nav::before glass blur (Gate 24.9,
   2026-10-03); the header is identical on every page, so its crossfade is invisible. */
@media (prefers-reduced-motion:no-preference){
  @view-transition{navigation:auto}
  ::view-transition-old(root){animation:vt-out var(--dur-fast) var(--ease-spring) both}
  ::view-transition-new(root){animation:vt-in var(--dur-base) var(--ease-spring) both}
  /* homepage logo intro (html.intro) brings its own choreography: no double animation */
  html.intro::view-transition-old(root),html.intro::view-transition-new(root){animation:none}
}
@keyframes vt-out{from{opacity:1}to{opacity:0}}
@keyframes vt-in{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* 20.2 court lines: one inline SVG (aria-hidden), drawn on scroll where animation-timeline
   exists, otherwise (and for reduced motion) simply fully drawn. Never orange. */
.court-lines{position:absolute;inset:0;width:100%;height:100%;z-index:-1;pointer-events:none;
  fill:none;stroke:var(--border);stroke-width:2;stroke-linecap:round}
.court-lines *{fill:none;stroke:var(--border)}
body.fw-page .page-head::before,body.bk-page .page-head::before{content:none}
/* overflow:clip, not hidden: hidden would make the band the view() scroller of its lines */
.home-band-promo{position:relative;isolation:isolate;overflow:clip}
/* the view() timeline needs a CSS box as subject (SVG shapes have none), so the <svg> animates a
   registered property and the shapes read it as their dash offset */
@property --court-draw{syntax:'<number>';inherits:true;initial-value:0}
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    .court-lines{--court-draw:1;animation:court-draw linear both;animation-timeline:view();
      animation-range:entry 0% cover 40%}
    .court-lines *{stroke-dasharray:1;stroke-dashoffset:var(--court-draw)}
  }
}
@keyframes court-draw{to{--court-draw:0}}

/* 20.4a hero headline: the two halves slide together after the intro handoff (hooked on the
   existing .hero-inner.in stagger, so no own timers; same 900ms hero-handoff exception) */
.hero-inner .hero-split,.home-band .reveal .hero-split{opacity:0;transform:translateX(-24px);
  transition:opacity var(--dur-enter) var(--ease-spring), transform var(--dur-enter) var(--ease-spring)}
.hero-inner .hero-split + .hero-split,.home-band .reveal .hero-split + .hero-split{transform:translateX(24px)}
.hero-inner.in .hero-split,.home-band .reveal.in .hero-split{opacity:1;transform:none;transition-delay:80ms}
@media (max-width:719px){
  .hero-inner .hero-split,.home-band .reveal .hero-split{transform:translateX(-16px)}
  .hero-inner .hero-split + .hero-split,.home-band .reveal .hero-split + .hero-split{transform:translateX(16px)}
  .hero-inner.in .hero-split,.home-band .reveal.in .hero-split{transform:none}
}
html.intro:not(.has-gate) .hero-inner .hero-split{animation:intro-failsafe-in 0s 9s forwards}
html.intro.has-gate:not(.gate-is-live) .hero-inner .hero-split{animation:intro-failsafe-in 0s 12s forwards}

/* 20.4b Kodex numbers settle 1.15 -> 1 when their card gets .in (nav.js reveal observer) */
.kodex-num{opacity:0;transform:scale(1.15);transform-origin:left center;
  transition:opacity var(--dur-reveal) var(--ease-spring), transform var(--dur-reveal) var(--ease-spring)}
.kodex-card.in .kodex-num{opacity:1;transform:none}

/* 20.4c CTA sheen: sweep lives on the base ::after (transition never inside :hover);
   overflow:clip clips it to the button box */
.btn-primary{position:relative;overflow:clip;isolation:isolate}
.btn-primary::after{content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 0,rgba(255,255,255,.18) 50%,transparent 100%);
  transform:translateX(-120%);transition:transform var(--dur-reveal) var(--ease-spring)}
.btn-primary:focus-visible::after{transform:translateX(120%)}
@media (hover:hover) and (pointer:fine){.btn-primary:hover::after{transform:translateX(120%)}}

@media (prefers-reduced-motion:reduce){
  .hero-inner .hero-split,.home-band .reveal .hero-split{opacity:1;transform:none;transition:none;animation:none}
  .kodex-num{opacity:1;transform:none;transition:none}
  .btn-primary::after{display:none}
  .court-lines{animation:none;--court-draw:0}
  .court-lines *{stroke-dasharray:none;stroke-dashoffset:0}
}

/* Freunde-werben story island (ROADMAP 20.3, src/islands/referral-story.tsx). The static
   steps/table stay the source of truth; the island adds a decorative .rs-layer and, only after
   it set html.js-rs itself, hides not-yet-revealed reward rows until framer animates them in.
   No JS / reduced motion: the class is never set, everything is plain static markup. */
.fw-steps-wrap{position:relative}
.rs-layer{position:absolute;inset:0;pointer-events:none;overflow:visible}
.rs-layer svg{position:absolute;left:0;top:0;overflow:visible}
.js-rs .fw-steps li::before{transform:scale(var(--rs-s,1));transform-origin:left center}
.js-rs .fw-table tbody tr:not([data-rs-in]){opacity:0}

/* Sponsors on light (ROADMAP 23.2): logos sit on white tiles so opaque-white JPG backgrounds
   merge with the tile and dark-on-transparent art (Vicona) stays readable. */
.section-light .marquee-track{gap:16px}
.section-light .marquee-logo{height:76px;padding:12px 22px;background:var(--light-card);
  border:1px solid var(--light-border);border-radius:var(--radius-in);text-decoration:none}
.section-light .marquee-logo:focus-visible{outline:2px solid var(--orange);outline-offset:-2px}
.section-light .marquee-toggle{color:var(--light-ink-dim);border-left-color:var(--light-border)}
.section-light .marquee-toggle:focus-visible{color:var(--light-ink)}
@media (hover:hover) and (pointer:fine){.section-light .marquee-toggle:hover{color:var(--light-ink)}}
.section-light .marquee-toggle:focus-visible{outline:2px solid var(--orange);outline-offset:-2px}

/* === Phase 23 Block B: light component variants (DS §10 "Light variants of components"),
   form/accordion/table light (23.17 to 23.20). Scoped under .section-light, existing --light-*
   tokens only. .section-light already remaps --paper/--silver/--silver-2/--line; these three more
   flip the remaining dark text/hairline tokens, fixed surfaces (--ink-2/-3, --surface-*) are
   re-skinned per component below. No transition lives inside a :hover block. === */
.section-light{--ink:var(--light-ink);--ink-dim:var(--light-ink-dim);--border:var(--light-border)}
/* eyebrow text: orange only on --surface-100 (DS §2, 23.22); 200-surface bands stay dim, light bands dim */
:is(.stat-band,.tint,.train-band,.joinband,.merch-teaser,.home-game-banner,
  section:not(.section-light):has(.info-cards,.train-group,.hall-card)) .eyebrow{color:var(--silver-2)}
.section-light .eyebrow{color:var(--light-ink-dim)}

/* buttons on light: .section-light a would otherwise recolour/underline them */
.section-light .btn{text-decoration:none}
.section-light .btn-primary{color:var(--ink-on-accent)}
.section-light .btn-ghost{border-color:var(--light-ink);color:var(--light-ink)}
.section-light .btn-ghost:focus-visible{background:var(--light-ink);color:var(--light-bg);border-color:var(--light-ink)}
@media (hover:hover) and (pointer:fine){.section-light .btn-ghost:hover{background:var(--light-ink);color:var(--light-bg);border-color:var(--light-ink)}}
.section-light .btn-outline{border-color:var(--light-border-strong);color:var(--light-ink)}
.section-light .btn-outline:focus-visible{border-color:var(--light-ink)}
@media (hover:hover) and (pointer:fine){.section-light .btn-outline:hover{border-color:var(--light-ink)}}

/* seam: a light band right after a page head keeps its top pad (the generic rule zeroes it) */
.page-head + .section-tight.section-light{padding-top:var(--section-pad-tight)}

/* cards, news, tags */
.section-light .bezel{background:var(--light-card);border-color:var(--light-border)}
.section-light .bezel > .bezel-core{background:var(--light-card);box-shadow:none}
.section-light .card{background:var(--light-card);border-color:var(--light-border)}
@media (hover:hover) and (pointer:fine){.section-light .card:hover{border-color:var(--light-border-strong)}}
.section-light .card:focus-visible{border-color:var(--light-border-strong)}
.section-light .news-card .bezel{transition:border-color var(--dur-base) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.section-light .news-card:hover .bezel{border-color:var(--light-border-strong)}}
.section-light .news-card:focus-within .bezel{border-color:var(--light-border-strong)}
.section-light :is(.news-card,.card) a:not(.btn){text-decoration:none}
.section-light .tag{background:var(--light-bg);color:var(--light-ink-dim)}

/* info / training / hall / map cards: 3px orange bar stays (graphic) */
.section-light :is(.info-card,.train-group,.hall-card,.map-consent){background:var(--light-card);
  border-color:var(--light-border);border-left-color:var(--orange)}
@media (hover:hover) and (pointer:fine){.section-light :is(.info-card,.train-group,.hall-card):hover{border-color:var(--orange)}}
.section-light .info-card .ic-ico{background:var(--light-bg)}
.section-light .info-card .ic-ico svg{color:var(--light-ink)}
.section-light .week-day{background:var(--light-card);border-color:var(--light-border)}
.section-light .em-card{background:var(--light-card);border-color:var(--light-border)}
.section-light :is(.em-preview,.em-map){background:var(--light-bg)}
.section-light .em-map-fade{background:linear-gradient(to top,var(--light-bg),transparent 22%)}

/* people, roster */
.section-light :is(.people-card,.roster-card) .photo{background:var(--light-bg)}
.section-light .people-card.bio-card{background:var(--light-card);border-color:var(--light-border)}
.section-light .people-card.bio-card .bio{color:var(--light-ink)}
.section-light .roster-card .num{background:var(--light-ink);color:var(--white)}
.section-light .roster-coach{background:var(--light-card);border:1px solid var(--light-border)}
.section-light .roster-coach .photo{background:var(--light-bg)}

/* drills */

/* shop: the white product plate loses its frame, supplier white = card (fanshop.css plate rule is
   out-specified here, no edit there) */
.section-light .shop-card .thumb{background:transparent;border:0;padding:var(--space-5)}
.section-light .shop-card .body{border-top:1px solid var(--light-border)}
.section-light .shop-notice{background:var(--light-card);border-color:var(--light-border)}
/* gate fix: --light-border was 1.28:1 here; disabled-on-light takes the strong border (3.19:1)
   with the dim ink, so it still reads as a control (assumption, DS gap) */
.section-light .btn-primary.is-disabled{background:var(--light-bg);color:var(--light-ink-dim);
  border:1px solid var(--light-border-strong)}

/* logo tiles (colour logos on white tiles) */
.section-light .logo-cell{background:var(--light-card);border-color:var(--light-border);
  transition:transform var(--dur-base) var(--ease-spring), border-color var(--dur-base) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.section-light .logo-cell:hover{border-color:var(--light-border-strong)}}
.section-light :is(.media-partner a,.federation-logo){padding:var(--space-3) var(--space-4);
  background:var(--light-card);border:1px solid var(--light-border);border-radius:var(--radius-in);
  text-decoration:none}
.section-light .federation-logo{height:auto}

/* steps: numerals and rules in ink, never orange */
.section-light .steps li{background:transparent;border:0;border-top:2px solid var(--light-ink);
  border-radius:0;padding:var(--space-4) 0 0}
.section-light .steps li::before{color:var(--light-ink)}
.section-light .steps p{color:var(--light-ink)}
.section-light :is(.fw-steps li,.fw-guarantee,.fw-ended,.kodex-card){background:var(--light-card)}
.section-light .kodex-num{color:var(--light-ink)}

/* long reading text */
.section-light .legal-body{max-width:68ch}
.section-light .legal-body :is(p,li),.section-light .article-body ul{color:var(--light-ink)}
.section-light .legal-body hr{border:0;border-top:1px solid var(--light-border)}
.section-light .legal-body :is(th,td){border-color:var(--light-border)}

/* fixture / result rows, empty states */
.section-light :is(.fixture-row,.result-row,.empty-info-card,.empty-state){background:var(--light-card);
  border-color:var(--light-border)}
.section-light .result-score em{background:var(--light-bg);color:var(--light-ink-dim)}
.section-light .empty-info-card a .arrow{color:var(--light-ink)}

/* forms (23.18) */
.section-light .field label{color:var(--light-ink)}
.section-light .field :is(input,select,textarea){background:var(--light-card);color:var(--light-ink);
  border:1px solid var(--light-border-strong);
  transition:border-color var(--dur-fast) var(--ease-spring)}
@media (hover:hover) and (pointer:fine){.section-light .field :is(input,select,textarea):hover{border-color:var(--light-ink-dim)}}
.section-light .field :is(input,select,textarea):focus-visible{border-color:var(--light-ink)}
.section-light .field ::placeholder{color:var(--light-ink-dim);opacity:1}
/* error: 2px ink border, never orange; message below carries the text */
.section-light .field :is(input,select,textarea)[aria-invalid="true"]{border:2px solid var(--light-ink);
  padding:calc(.85rem - 1px) calc(1rem - 1px)}
.section-light .field :is(input,select,textarea):user-invalid{border:2px solid var(--light-ink);
  padding:calc(.85rem - 1px) calc(1rem - 1px)}
.section-light .field-consent label{color:var(--light-ink-dim)}
.section-light .field-consent input{accent-color:var(--light-ink)}

/* accordion + filter (23.19) */
.section-light .train-chip{background:var(--light-card);border-color:var(--light-border)}
.section-light .train-chip[open]{border-color:var(--light-border-strong)}
.section-light .train-chip summary{color:var(--light-ink)}
.section-light .train-chip p{color:var(--light-ink)}
.section-light .faq-ic::before,.section-light .faq-ic::after{background:var(--light-ink)}
.section-light .train-filter button{border-color:var(--light-border-strong);color:var(--light-ink-dim)}
.section-light .train-filter button[aria-pressed="true"]{background:var(--light-ink);
  color:var(--light-bg);border-color:var(--light-ink)}

/* tables (23.20): rows as cards on phones, card-coloured cells on the real table */
.section-light .fw-table td{color:var(--light-ink)}
@media (max-width:719px){
  .section-light :is(.fw-table,.kodex-table) tr{background:var(--light-card)}
}
@media (min-width:720px){
  .section-light :is(.fw-table,.kodex-table) tbody :is(th,td){background:var(--light-card)}
}
@media (prefers-reduced-motion:reduce){
  .section-light .logo-cell,.section-light .news-card .bezel,
  .section-light .field :is(input,select,textarea){transition:none}
}

/* promo band (23.23): the nav CTA carries the page's one orange from 1000px, so there the band
   gets a light ghost button as its closing action and the inline text link steps aside */
.home-band .home-band-btn{display:none;margin-top:var(--space-5)}
@media (min-width:1000px){
  .home-band .home-band-btn{display:block}
  .home-band a.home-band-link{display:none}
}

/* === Phase 24 (DS §5 "Fluid-interface rules", §8 Wayfinding, 2026-10-03) ===
   Press feedback: independent `scale` property composes with hover lifts and .reveal transforms.
   Base transitions of these selectors list `scale` (release = their own --dur-fast/-base);
   the duration-only transition in :active is the one sanctioned exception to "no transition in
   state blocks". `a.card` instead of `.card` and no `.news-card` (an <article> holding links):
   the container itself must not press when an inner link is pressed. */
:is(.btn, a.card, .quick-prev, .quick-next, .burger, .menu > li > a, .menu > li > button,
    .dropdown a, .langtoggle a, .social-mini a, .marquee-toggle, .train-chip summary,
    .train-filter button, .chip, .ig-follow):active{
  scale:.97;transition-duration:var(--dur-press)}

/* touch: no 300ms delay, no grey tap flash */
a,button,summary,label,[role=button]{touch-action:manipulation;-webkit-tap-highlight-color:transparent}

/* >= 44px tap targets: transparent hit area, visuals unchanged. Langtoggle segments stay at
   100% width so adjacent hit areas never overlap (height only). */
.social-mini a::after,.marquee-toggle::after,.burger::after,.langtoggle a::after{
  content:"";position:absolute;left:50%;top:50%;
  width:max(100%,44px);height:max(100%,44px);transform:translate(-50%,-50%)}
.langtoggle a::after{width:100%}

/* current page in the main nav: --paper text + 2px --paper bar, not orange (orange = the CTA) */
.menu > li > a[aria-current],.menu > li > button[aria-current="true"]{color:var(--paper)}
.menu > li > a[aria-current]::after,.menu > li > button[aria-current="true"]::after{
  content:"";position:absolute;left:.6rem;right:.6rem;bottom:.2rem;height:2px;background:var(--paper)}
.dropdown a[aria-current="page"]{color:var(--paper)}
@media (max-width:820px){
  .menu > li > a[aria-current]::after,.menu > li > button[aria-current="true"]::after{
    left:.4rem;right:auto;width:2rem;bottom:.45rem}
}

/* reduced motion: the global floor. Component blocks above stay; this guarantees nothing
   slips through. Opacity crossfades (.xfade) are the one allowed exception. The sponsor
   marquee is static here, so its aria-hidden duplicate set is hidden (no doubled logos). */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-delay:0s!important;
    animation-iteration-count:1!important;
    transition-duration:.01ms!important;transition-delay:0s!important}
  .xfade,.xfade::before,.xfade::after{
    transition-property:opacity!important;transition-duration:var(--dur-fast)!important}
  .marquee-track > [aria-hidden="true"]{display:none}
}

/* === Phase 24.8 system modes (DS §8 Materials, 2026-10-03) ===
   Opaque instead of translucent: no backdrop-filter, solid surfaces, scrolled mobile bar gets a
   1px line instead of the scroll-edge fade. */
@media (prefers-reduced-transparency:reduce){
  .nav::before,header.site.scrolled .nav::before{background:var(--surface-200);-webkit-backdrop-filter:none;backdrop-filter:none}
  .dropdown{background:var(--surface-200);-webkit-backdrop-filter:none;backdrop-filter:none}
  @media (max-width:820px){
    .menu{background:var(--surface-100);-webkit-backdrop-filter:none;backdrop-filter:none}
    header.site .menu > li > .dropdown{background:none}
    .nav::after{display:none}
    header.site.scrolled .nav{box-shadow:0 1px 0 var(--border)}
  }
}
/* More contrast: near-opaque fills, 1px contrasting outlines, no dimmed text */
@media (prefers-contrast:more){
  :root{--ink-dim:#d0cac3;--border:#d0cac3;--light-ink-dim:var(--light-ink)}
  .nav::before,header.site.scrolled .nav::before,.dropdown,.menu{background:rgba(30,27,24,.96)}
  .nav,.dropdown{border:1px solid var(--paper)}
  .dropdown{border-color:var(--paper)}
  @media (max-width:820px){
    .nav{border:0;border-bottom:1px solid var(--paper)}
    .menu{border-left:1px solid var(--paper)}
    header.site .menu > li > .dropdown{background:none;border:0}
  }
  .section-light{--border:var(--light-ink)}
  .quick-slide{opacity:1}
}
