/* ==========================================================================
   Burnell MMA & BJJ — style.css
   Tokens og regler: se DESIGN.md v1.3 (§3 farver, §4 typografi, §5 grid, §6 bevægelse)
   ========================================================================== */

/* ---- Skrifter (self-hosted, §11) ---- */
@font-face {
  font-family: "Breaking";
  src: url("../fonts/breaking.woff2") format("woff2");
  font-weight: 100 900;   /* én fysisk vægt — undgår syntetisk fed ved 700 */
  font-display: swap;
}
@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}
@font-face {
  font-family: "Khand";
  src: url("../fonts/khand-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("../fonts/satoshi-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("../fonts/satoshi-500.woff2") format("woff2");
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: "Satoshi";
  src: url("../fonts/satoshi-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

/* ---- Tokens (§3, §4, §5) ---- */
:root {
  /* Brandkerne */
  --volt:      #1FBEDA;
  --tide:      #3D70A8;
  --plum-500:  #582C7E;

  /* Lilla-rampe.
     De tre flade-toner er skruet ned i mætning: fra 38% til 22%, og hue
     er trukket fra 270 mod 253, altså fra rødlig mod blålig. Det lilla er
     der stadig, men det ligger som grafit i stedet for at lægge et slør
     over hver flade. De mættede mellemtoner (700-500) er urørt — de
     bruges kun til glød og forløb, ikke til flader. */
  --plum-900:  #121019;
  --plum-950:  #0B0A11;   /* nyhedsetikettens flade: næsten sort med et strejf lilla, aldrig ren sort */
  --plum-800:  #1B1825;
  --plum-700:  #342145;
  --plum-600:  #4A2569;

  /* Lys + neutraler */
  --bone:      #EDEAF0;
  --mist:      #9991A1;
  --graphite:  #403847;
  --ash:       #CCC7D1;
  --white:     #FFFFFF;
  --volt-deep: #17A0B9;

  /* Linjeværk: hvidt, men dæmpet så en 1px streg ikke fylder mere end en
     divider skal. --rule til rene dividere, --rule-strong til kanter der
     skal læses som et klikbart element. */
  --rule:        color-mix(in srgb, var(--white) 16%, transparent);
  --rule-strong: color-mix(in srgb, var(--white) 30%, transparent);

  /* Typografi */
  /* Breaking er display-skriften. Den rummer kun ASCII-tegnsætning — ingen
     tankestreg, halvlang streg, typografiske anførselstegn eller midterprik
     — så display-sat tekst er skrevet med de tegn den HAR. Khand er
     reserven, hvis der alligevel slipper et tegn igennem.
     Lodret er de to skrifter identiske, målt: upm 1000, ascender 750,
     descender -250, versalhøjde 680 og ingen underlængde. De optiske
     justeringer længere nede holder derfor uændret. */
  --font-display: "Breaking", "Khand", system-ui, sans-serif;
  --font-body:    "Satoshi", "Archivo", -apple-system, "Segoe UI", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, monospace;

  --fs-display:  clamp(7.22rem, 4.54rem + 13.41vw, 15.47rem);
  /* Endepunkterne er 87px ved 375 og 150px ved 1440, og hældningen regnet
     derudfra: (150 − 87) / (1440 − 375) = 5,92vw med skæringen 4,05rem.
     Loftet på 9,375rem svarer til 150px og holder graden i ro over 1440 —
     uden det ville en 1920-skærm ende på 178.
     Gulvet er sat ned til 5,1rem: med det gamle på 5,68rem (90,9px) ville
     minimum vinde over de 87px og mobilgraden slet ikke ændre sig. */
  --fs-h1:       clamp(5.1rem, 4.05rem + 5.92vw, 9.375rem);
  --fs-h2:       clamp(4.13rem, 3.09rem + 5.16vw, 7.22rem);
  --fs-h3:       clamp(3.09rem, 2.68rem + 2.07vw, 4.13rem);
  /* Disciplinnavnenes grad. Menupunkterne bag burgeren kører på den samme,
     så de to læses som én stemme (Alberts valg 2026-09-12). Loftet er
     lavere op til 1600px — se medieforespørgslen lige efter :root. */
  --fs-disc:     clamp(1.95rem, 1.35rem + 2.9vw, 3.75rem);
  --fs-lead:     clamp(1.0625rem, 1rem + 0.30vw, 1.25rem);
  --fs-body:     1rem;
  --fs-small:    0.875rem;
  --fs-meta:     0.75rem;

  /* Grid og mål */
  --page-max:    90rem;
  --page-gutter: clamp(1.25rem, 4vw, 4rem);
  --grid-gap:    1.5rem;
  --section-sm:  clamp(3.5rem, 2.80rem + 3.00vw,  5.50rem);
  --section-md:  clamp(5.0rem, 3.80rem + 5.00vw,  9.00rem);
  --section-lg:  clamp(7.0rem, 5.40rem + 6.80vw, 13.50rem);

  /* Eventstribens højde. Ét sted, fordi headeren placerer sig lige under
     den — skrider den ene, skrider den anden.

     32 og ikke 45: de 45 var headerens sammenklappede kassehøjde, og den
     var god SÅ LÆNGE den var lilla og læstes som en del af headeren. Som
     selvstændig hvid stribe er den samme højde for tung. Teksten fylder
     19px, så 32 giver 6,5px luft over og under. */
  /* Event-stribens højde. 0 mens der ingen stribe er (den ligger pakket i
     _gemt/event-striben.html) — sæt 32px igen når den kommer på. Headeren
     og skemaets filtre måler sig ud fra tallet. */
  --stribe-h: 0px;
  /* Luften om heroens videoflade (2026-09-14): ca. 8px på en telefon, 20px
     ved 1440. Headeren rykkes lige så meget ned, så den står i samme afstand
     til fladens overkant som før fladen fik luft. */
  --hero-luft: clamp(0.5rem, 0.2rem + 1.2vw, 1.25rem);
  /* LOFTET på de brede elementer (2026-09-14): header, heroens overskrift og
     quiz-kort, collagen og Næste prøvetime-kortet bliver højst så brede og
     står centreret. Bredere end sidens indhold (--page-max): 1920px, så
     almindelige store skærme fyldes ud (var 1600px til 2026-09-14). Selve
     hero-videoen har ikke loftet — den fylder skærmen. */
  --flade-max: 120rem;

  --radius-media:   14px;
  --radius-control: 999px;
  --radius-input:   6px;

  /* Hero-vandmærkets størrelse — bruges af BÅDE .hero__mark og
     .disciplines__mark (fortsættelsen), så flugten aldrig kan skride */
  /* 13% mindre end før: 40,8 → 35,5vw og loftet 624 → 543px. Gulvet på
     336px er urørt, og det er dét der gælder på telefon — vw-leddet giver
     kun 153px ved 375, så mærket har samme størrelse på mobil som før.
     Bruges også af B'et i CTA-sektionen, se .s-final__mark. */
  --mark-w: clamp(336px, 35.5vw, 543px);
  /* Hero-B'ets afstand til højre kant. Fortsættelsen i disciplin-sektionen
     bruger SAMME token: skrider den ene, skrider flugten over
     sektionsgrænsen. 0 holder mærket inden for skærmen; -3% lod det stikke
     53px ud på en 1763px skærm. */
  --mark-right: 0px;

  /* Afstand fra viewport-bunden til nextbaren — quizzen bruger samme tal,
     så de to kort flugter forneden i hero. Luften om heroens videoflade
     lægges til, så begge står 1,25rem inde fra fladens nederste kant, som
     de stod fra heroens kant før fladen fik luft. */
  --nextbar-offset: calc(1.25rem + var(--hero-luft));

  /* Hero-videoens afmætning. Difference-inversionen (B'et og ordet ELITEN)
     vender farvekanaler enkeltvis — på en blå baggrund giver det gul. Med
     gråtonet kilde bliver inversionen ren metal/chrome. 1 = helt grå. */
  --hero-desat: 0;

  /* Bevægelse (§6) */
  --ease-out:  cubic-bezier(0.22, 1, 0.36, 1);
  --ease-ui:   cubic-bezier(0.4, 0, 0.2, 1);
  --dur-reveal: 0.8s;
  --dur-ui:     0.3s;
}

/* ---- Reset og grund ---- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  /* Mobilbrowsere forstørrer selv tekst i blokke der er bredere end skærmen.
     Rulletekstens bånd er flere tusind pixels bredt og blev derfor blæst op,
     mens "Event" ved siden af beholdt sin størrelse. */
  -webkit-text-size-adjust: 100%;
          text-size-adjust: 100%;
}
body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  letter-spacing: -0.005em;
  color: var(--bone);
  background: var(--plum-900);
  -webkit-font-smoothing: antialiased;
}
img, video { max-width: 100%; display: block; }
a { color: inherit; }
button { font: inherit; cursor: pointer; border: none; background: none; color: inherit; }
:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }
.s-light :focus-visible { outline-color: var(--plum-900); }

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---- Typografi-klasser (§4) ---- */
h1, h2, h3, .display {
  font-synthesis-weight: none;  /* aldrig algoritmisk fed på display-fonten */
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
h1 { font-size: var(--fs-h1); line-height: 0.86; } /* midt mellem de øvrige overskrifters 0.74 og normal 1.0 */
h2 { font-size: var(--fs-h2); line-height: 0.74; }
h3 { font-size: var(--fs-h3); line-height: 0.80; }
.display { font-size: var(--fs-display); line-height: 0.72; }

p { max-width: 68ch; }
.lead { font-size: var(--fs-lead); line-height: 1.5; max-width: 46ch; }
/* Hero-manchetten: brødtekstfonten, men sat som tracket-out versaler —
   samme greb som eyebrows og mono-labels. Graden skal NED når teksten bliver
   versal, fordi versaler fylder optisk mere end minuskler ved samme grad. */
.hero__headline .lead {
  font-family: var(--font-body); font-weight: 500;
  text-transform: uppercase;
  font-size: clamp(0.875rem, 0.79rem + 0.33vw, 1.0625rem);
  line-height: 1.75;
  letter-spacing: 0.16em;
  max-width: 44ch;
}

.mono {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 400;
}

/* En 15-tommer bærbar er 1366–1536px bred og ramte loftet på 4,4rem (70px)
   lige så hårdt som en stor skærm — for stort dér, sagde Albert
   (2026-09-12). Op til 1600px er loftet derfor 3,5rem (56px); de store
   skærme derover beholder de 70px. Gulvet og hældningen er de samme, så
   graden er identisk på telefon og tablet. Gælder både disciplinnavnene
   og menupunkterne bag burgeren. */
@media (max-width: 1599.98px) {
  :root { --fs-disc: clamp(1.95rem, 1.35rem + 2.9vw, 3rem); }
}

/* ---- Layout ---- */
.wrap {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}
.split, .split--alt { display: grid; gap: var(--grid-gap); align-items: center; }
.split { grid-template-columns: 6fr 4fr; }
.split--alt { grid-template-columns: 4fr 6fr; }
@media (max-width: 991.98px) {
  .split, .split--alt { grid-template-columns: 1fr; }
}

/* Sektionstilstande (§1.1: mørk = fortælling, lys = beslutning) */
.s-dark { background: var(--plum-900); color: var(--bone); }
.s-light { background: var(--bone); color: var(--graphite); }
.s-light h1, .s-light h2, .s-light h3, .s-light .display { color: var(--plum-900); }
.s-volt-panel { background: var(--plum-900); color: var(--bone); }

/* ---- Komponenter (§7) ---- */

/* Eyebrow */
.eyebrow {
  /* baseline: mærket hænger på tekstens grundlinje. Det rammer versalernes
     optiske midte og virker også når labelen ombrydes — center ville dér
     placere mærket i mellemrummet MELLEM linjerne. */
  display: inline-flex; align-items: baseline; gap: 0.4em;
  /* Display-skriften har ÉN fysisk vægt: uden font-synthesis-weight ville browseren
     tegne en falsk fed og mærket ville ikke matche resten af displaytypen. */
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  font-size: 1.499rem;                 /* 5% under 1.578rem */
  line-height: 1.4;
  text-transform: uppercase; letter-spacing: 0.06em;
  /* Samme farve som overskriften den står over — eyebrow og h2 læses som
     ét hoved. Reglerne spejler h2'ernes: --bone som grundtone på mørk
     bund, plum-900 på lys, og ren hvid på volt-panelet, hvor h2 også er
     hævet dertil. Ren hvid som grundtone gjorde eyebrowen lysere end
     overskriften under den. */
  color: var(--bone);
  margin-bottom: 1.25rem;
  /* Mærkets feltstørrelse, sat i em så det følger skriften. Logofilen er
     tæt beskåret: motivet fylder 99,6% af feltet med 0,21% luft under —
     begge tal er målt på filen og bruges nedenfor til flugtningen.
     Feltet står i em, så em-værdien skal justeres modsat skriftgraden hvis
     mærket skal beholde sin faktiske størrelse. 0.608em = cirka 15,4px. */
  --eb-maerke: 0.589em;
  /* Hvor højt mærket løftes over skriftlinjen. Se den vigtige note ved
     .eyebrow::before om HVORFOR det er en transform og ikke en margen.
     0.0354em stiller mærkets midte præcis på versalernes midte. Målt ved
     at rendere "LEDELSEN" — rene versaler uden accenter — og mærket ved
     løft 0, og tage forskellen på de to blækmidter. Accenterne (Å, É når
     0,83em) er bevidst holdt UDE af referencen: de findes kun i én af de
     otte labels, og øjet læser versalbåndet, ikke de spredte accenter.
     Større tal = højere. Ét tal at skrue på. */
  --eb-loft: 0.0343em;
}
/* B-mærket i stedet for en prik. Logoet bruges som MASKE og ikke som
   baggrundsbillede: så er mærket farvet af background og følger paletten,
   i stedet for at være låst til filens egne farver. */
/* Det officielle logo i sine egne farver: turkis-til-lilla forløb med det
   hvide B indeni. Derfor et BAGGRUNDSBILLEDE og ikke en maske — en maske
   kan kun bære én farve, og så ville forløbet gå tabt. */
.eyebrow::before {
  content: ""; flex: none;
  width: var(--eb-maerke); height: var(--eb-maerke);
  background: url("../img/eyebrow-logo.svg") center / contain no-repeat;
  /* VIGTIGT: margin-bottom kan IKKE flytte mærket lodret her. Et flex-element
     uden egen tekst får sin grundlinje syntetiseret fra BORDERBOKSEN, ikke
     fra margenboksen, så align-items: baseline låser feltets underkant til
     skriftlinjen uanset hvad margenen er. Målt: margenen kan gå fra 0,97px
     til 6,02px uden at mærket rykker sig én pixel.
     Derfor en transform — den flytter det tegnede uden at røre layoutet. */
  /* Rulningen lægges OVEN PÅ løftet. --eb-rul-* sættes af main.js på
     forælderen og står på 0 alle andre steder end i "Mere end et gym".
     Rækkefølgen betyder noget: rotate til sidst, så mærket drejer om sin
     egen midte og ikke om et punkt forskudt af flytningen. */
  transform: translateY(calc(-1 * var(--eb-loft)))
             translateX(var(--eb-rul-x, 0px))
             rotate(var(--eb-rul-r, 0deg));
}
.s-light .eyebrow { color: var(--plum-900); }   /* som .s-light h2 */
/* Store skærme: 10% større. Mærket og løftet er i em, så de følger med
   uden at flugtningen skal måles om. Brudpunktet er det samme som
   disciplingitterets tredje spalte (1101px). */
@media (min-width: 1101px) { .eyebrow { font-size: 1.649rem; } }

/* GLIMTET BAG B'ET
   Samme opskrift som disciplinkortenes lys — næsten hvid kerne der
   stråler ud i plum-500 — men lagt som to drop-shadows i stedet for en
   gradient. På et mærke der kun er 14px ville en gradient blive en
   firkantet plet bag et rundt bogstav; drop-shadow følger blækkets egen
   form, så skæret sidder i B'et og ikke i dets kasse.

   Der er INTET lys i hvile. Mærket står som før, og lyset findes kun i
   det korte glimt når det kommer i syne.

   Yderpunkterne er gennemsigtige drop-shadows og ikke "none": skyggerne
   skal have samme form hele vejen igennem, ellers kan browseren ikke
   regne mellemtrinene ud og glimtet ville springe frem i stedet for at
   tone. */
@keyframes eb-glimt {
  0% {
    filter: drop-shadow(0 0 1.5px transparent) drop-shadow(0 0 5px transparent);
  }
  22% {
    filter:
      drop-shadow(0 0 3px  color-mix(in srgb, var(--white) 55%, transparent))
      drop-shadow(0 0 11px color-mix(in srgb, var(--plum-500) 58%, transparent));
  }
  100% {
    filter: drop-shadow(0 0 1.5px transparent) drop-shadow(0 0 5px transparent);
  }
}
.eyebrow.glimter::before { animation: eb-glimt 1.5s var(--ease-out); }
@media (prefers-reduced-motion: reduce) {
  .eyebrow.glimter::before { animation: none; }
}

/* Knapper */
.btn {
  display: inline-block;
  padding: 14px 28px;
  border-radius: var(--radius-control);
  font-family: var(--font-body); font-weight: 600; font-size: 0.875rem;
  /* Almindelig sætningsform. text-transform er arvet, så det er ikke nok
     at fjerne versalerne — de skal slås aktivt fra, ellers siver de ned
     fra en forfader. Sporingen ned fra 0,04em: den var sat til versaler,
     hvor bogstaverne har brug for luft imellem sig, og virker løs på små
     bogstaver. */
  text-transform: none;
  letter-spacing: 0.01em;
  text-decoration: none; text-align: center;
  transition: background-color var(--dur-ui) var(--ease-ui),
              color var(--dur-ui) var(--ease-ui),
              border-color var(--dur-ui) var(--ease-ui),
              transform var(--dur-ui) var(--ease-ui);
}
.btn:active { transform: scale(0.98); }

/* Prøvetime-knappen: kun kontur og tekst i accentfarven, resten gennemsigtig.
   Den står tre steder, alle på plum-900, hvor cyan tekst giver 8,52:1.
   Ved hover fyldes den, som .btn--outline og .btn--ghost gør det. */
.btn--linje {
  /* Én variabel styrer hele knappen: fylde, tekst, kant, lys og
     monogrammets skær. En farvevariant behøver derfor kun sætte --linje. */
  --linje: var(--volt);
  background: color-mix(in srgb, var(--linje) 10%, transparent);
  color: var(--linje);
  border: 1px solid var(--linje);
  /* isolation frem for en position: knappen får sin egen stakkontekst, så
     lyset på ::before kan ligge på z-index -1: bag teksten, men foran
     knappens egen fylde. Uden den ville et negativt lag falde helt bagud
     og forsvinde bag sektionens baggrund. */
  position: relative; isolation: isolate; overflow: hidden;
}
/* Lyset der følger musen. Faldet følger 1/(1+d·a) frem for at ligge
   jævnt — det er dét der giver lyskilde frem for flade. Ingen hvid kerne
   her, kun knappens egen cyan hele vejen ind,
   med et strejf plum-500 yderst så det hører til samme familie.
   --mx/--my sættes af main.js; uden JS står lyset midt i knappen. */
.btn--linje::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(7rem 7rem at var(--mx, 50%) var(--my, 50%),
    /* Kun knappens egen farve — intet lilla. Faldkurven er den samme;
       det er alene styrken der er skruet ned. */
    color-mix(in srgb, var(--linje) 13%, transparent) 0%,
    color-mix(in srgb, var(--linje) 11%, transparent) 8%,
    color-mix(in srgb, var(--linje)  7%, transparent) 18%,
    color-mix(in srgb, var(--linje)  4%, transparent) 36%,
    color-mix(in srgb, var(--linje)  2%, transparent) 60%,
    transparent 88%);
  opacity: 0; pointer-events: none;
  transition: opacity 0.3s var(--ease-ui);
}
/* Monogrammet. Et tæt felt af Burnell-B'er ligger permanent i knappen,
   men usynligt: masken er den SAMME radial som lyset, så mærkerne kun
   træder frem dér hvor man lyser på dem. Filen er allerede hvid i tre
   paths, så den kan flisebelægges direkte uden at skulle farves.
   Maskens toppunkt er 0.3 og ikke 1 — den styrer både hvor og HVOR
   kraftigt mærkerne træder frem, så feltet forbliver et vandmærke.
   ::after males efter ::before, så monogrammet ligger oven på lyset. */
.btn--linje::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  /* To lag forskudt en halv flise: det giver den diagonale gitterstilling
     et monogramfelt har, frem for et lige skakbræt. Flisefilen har luft
     omkring mærket — motivet fylder 29% af sin viewBox — så de to lag kan
     gribe ind i hinanden uden at overlappe, og mellemrummet styres alene
     med flisestørrelsen her. */
  background:
    url("../img/eyebrow-mark-flise.svg")   0   0 / 46px 46px repeat,
    url("../img/eyebrow-mark-flise.svg") 23px 23px / 46px 46px repeat;
  opacity: 0; pointer-events: none;
  -webkit-mask-image: radial-gradient(5rem 5rem at var(--mx, 50%) var(--my, 50%),
    rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.2) 16%, rgba(0,0,0,0.08) 40%, transparent 72%);
          mask-image: radial-gradient(5rem 5rem at var(--mx, 50%) var(--my, 50%),
    rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.2) 16%, rgba(0,0,0,0.08) 40%, transparent 72%);
  transition: opacity 0.3s var(--ease-ui);
}
@media (hover: hover) and (pointer: fine) {
  /* Bag hover-forespørgslen, så lyset ikke bliver hængende efter et tryk
     på en berøringsskærm, hvor :hover kan klæbe. */
  .btn--linje:hover::before,
  .btn--linje:hover::after { opacity: 1; }
  .btn--linje:hover { border-color: color-mix(in srgb, var(--linje) 70%, var(--white)); }
}
/* Hvid variant: samme knap, kun grundfarven skiftet. Lys, monogram og
   fylde følger med af sig selv. */
.btn--linje-hvid { --linje: var(--white); }
.btn--linje:focus-visible::before,
.btn--linje:focus-visible::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .btn--linje::before, .btn--linje::after { transition: none; }
}
/* Primær på lyse sektioner: mørk lilla. Den lyse lilla er udgået. */
.btn--plum { background: var(--plum-900); color: var(--bone); }
/* Sekundær DÉR HVOR to mørklilla knapper står sammen: kun kontur, så de to
   ikke vejer lige meget. */
.btn--outline {
  background: transparent; color: var(--plum-900);
  border: 1px solid var(--plum-900);
}

.btn--ghost { border: 1px solid var(--bone); color: var(--bone); }

/* Statistik */

/* Linjeværk (§3.5) */

/* Placeholder (§9.4) */
.ph {
  display: flex; align-items: center; justify-content: center;
  background: var(--plum-700);
  border: 1px solid color-mix(in srgb, var(--plum-700) 90%, white);
  border-radius: var(--radius-media);
  font-family: var(--font-mono); font-size: var(--fs-meta);
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--mist); text-align: center;
}
.s-light .ph { background: var(--ash); border-color: color-mix(in srgb, var(--ash) 80%, black); color: var(--graphite); }

/* ==========================================================================
   HEADER / NAV
   ========================================================================== */
.site-header {
  /* Ligger UNDER eventstriben, som nu er sin egen faste stribe øverst.
     --stribe-h er stribens højde ét sted, så de to ikke kan glide fra
     hinanden. */
  position: fixed; inset: calc(var(--stribe-h) + var(--hero-luft)) 0 auto 0; z-index: 40;
  padding-block: 0.75rem;
  transition: padding 0.45s var(--ease-out);
}
/* Toppens skygge. Øverst på siden har headeren ingen egen flade, og hvid
   tekst kan lande oven på et lyst sted i covervideoen. Et blødt fald fra
   toppen giver teksten noget at stå på uden at lægge en synlig kant.
   Den rækker halvanden headerhøjde ned, så faldet er langt nok til ikke
   at kunne ses som en kant, og forsvinder når pillerne tænder deres egne
   flader og menuen er klappet væk. */
.site-header::after {
  /* Skyggen begynder helt oppe ved skærmkanten og ikke ved headerens top:
     headeren står --hero-luft nede, og uden dette gled videoens lyse top
     uskygget gennem striben over headeren, når man begyndte at scrolle. */
  content: ""; position: absolute; inset: calc(-1 * var(--hero-luft)) 0 auto 0; z-index: -1;
  height: calc(320% + var(--hero-luft));
  /* plum-900 og ikke ren sort — DESIGN.md §0.6. Sort ville trække et koldt
     hul i den lilla grund; plum-900 er den samme farve som resten af
     sidens bund og lægger sig derfor i familien. */
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--plum-900) 62%, transparent) 0%,
    color-mix(in srgb, var(--plum-900) 44%, transparent) 22%,
    color-mix(in srgb, var(--plum-900) 26%, transparent) 44%,
    color-mix(in srgb, var(--plum-900) 12%, transparent) 66%,
    color-mix(in srgb, var(--plum-900)  4%, transparent) 84%,
    transparent 100%);
  pointer-events: none;
  transition: opacity var(--dur-ui) var(--ease-ui);
}
.site-header.scrolled::after { opacity: 0; }
/* På forsiden ligger mørket i hero-videoens scrim i stedet, så det scroller
   med videoen (se .hero__scrim). En fast skygge kom ud af takt på iPhone og
   lod en lys stribe af videoen komme frem. Browsere uden :has() beholder
   skyggen som før. */
body:has(.hero) .site-header::after { display: none; }

/* Fuld bredde, ikke .wrap: headeren skal nå helt ud i siderne, og logoet
   skal stå midt på SKÆRMEN. Tre felter med auto i midten gør midterfeltet
   uafhængigt af hvor bredt der er indhold i de to sider — med 1fr til
   hver side bliver logoet centreret uanset om menuen er foldet ud eller
   sammen. */
.header-rad {
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 1rem;
  padding-inline: var(--page-gutter);
  /* Loftet: rækken centreres, og heroens overskrift og quiz-kort flugter
     med dens kanter (.hero__inner har samme loft og samme luft) */
  max-width: var(--flade-max); margin-inline: auto;
}
/* Rækken SKAL med. Logoet står først i koden men i midterste kolonne, og
   uden en fast række sender den automatiske placering det næste element
   — der vil tilbage i en tidligere kolonne — ned på en ny række. */
.brand { grid-row: 1; grid-column: 2; justify-self: center; }
/* Menu og pille står sammen ude i højre side. Første kolonne er tom og
   holder blot balancen, så logoet bliver liggende midt på skærmen. */
.header-hoejre {
  grid-row: 1; grid-column: 3; justify-self: end;
  display: flex; align-items: center; gap: 0;
}

/* PILLERNE. Samme stil som Næste prøvetime-kortet, men først når man har
   scrollet: øverst på siden står logo og knap frit oven på videoen, med
   topskyggen som eneste hjælp. Kanten og fladen ligger i variabler der
   skifter, så begge piller kan animere med én regel. */
.brand, .header-pille {
  display: flex; align-items: center;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: transparent;
  transition: background-color var(--dur-ui) var(--ease-ui),
              border-color var(--dur-ui) var(--ease-ui);
}
.site-header.scrolled .header-pille {
  background: var(--plum-900);
  border-color: var(--rule);
}
/* Logoet får IKKE en pille. Ved scroll folder navnetrækket sig sammen, så
   kun mærket bliver tilbage og følger med ned ad siden — og det får en
   skygge i stedet for en flade, så det løfter sig fra indholdet bagved.
   max-width og ikke display: none, så mærket glider på plads i midten i
   stedet for at hoppe dertil. Den negative margen æder mellemrummet op
   til navnetrækket, som ellers stod tilbage som et hul. */
.brand span {
  display: block; overflow: hidden;
  max-width: 12rem; opacity: 1;
  transition: max-width 0.42s var(--ease-out),
              opacity 0.24s var(--ease-ui),
              margin-left 0.42s var(--ease-out);
}
.site-header.scrolled .brand span {
  max-width: 0; opacity: 0; margin-left: -0.75rem;
}
/* Polstringen er skæv, fordi navnetrækket skal have mere luft til højre
   end mærket til venstre. Når navnet er væk, skal de to sider være ens —
   ellers står mærket et par pixels ved siden af midten. */
.site-header.scrolled .brand { padding-right: 0.8rem; }
.brand { transition: padding-right 0.42s var(--ease-out); }
.brand img { transition: filter var(--dur-ui) var(--ease-ui); }
.site-header.scrolled .brand img {
  filter: drop-shadow(0 2px 5px color-mix(in srgb, #000 60%, transparent))
          drop-shadow(0 10px 22px color-mix(in srgb, #000 45%, transparent));
}
/* Polstringen står fast, også når fladen er slukket: ellers hoppede
   logoet og knappen et par pixels i det øjeblik man begyndte at scrolle.
   Venstre polstring er sat efter geometrien og ikke efter øjemål: pillen
   har helrund ende, og et kvadratisk mærke inde i den skal holde sine
   hjørner fri af buen. Med 44px mærke og 0,45rem luft over og under er
   buens indhug ud for hjørnerne 10px — derfor mindst det til venstre. */
.brand {
  gap: 0.75rem; text-decoration: none;
  padding: 0.45rem 1.2rem 0.45rem 0.8rem;
}
.brand img { width: 44px; height: 44px; }
.brand b {
  font-weight: 700; font-size: 1rem; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--bone); line-height: 1.1;
}
.brand small {
  display: block; font-family: var(--font-mono); font-size: 0.625rem;
  letter-spacing: 0.14em; color: var(--white); font-weight: 400;
  white-space: nowrap;
}
.brand b { white-space: nowrap; }
.header-pille { gap: 0.35rem; padding: 0.35rem; }

/* MENUEN BOR ALTID BAG BURGEREN — også på brede skærme og øverst på
   siden (Alberts valg 2026-09-12; før foldede punkterne ind ved scroll).
   Wrapperen står derfor foldet fra start. Den er stadig et gitter med
   0fr og ikke display: none: et display: none-element tegner heller ikke
   sine fixed børn, og så kunne menufeltet slet ikke åbnes.
   min-width: 0 er nødvendig: uden den nægter gitterelementet at blive
   smallere end sit indhold, og 0fr ville intet udrette. */
.header-menu {
  display: grid; grid-template-columns: 0fr;
  overflow: hidden; opacity: 0; visibility: hidden;
}
.site-nav {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 2rem; min-width: 0;
}
.site-nav a {
  /* Samme grad OG vægt som teksten i Tilmelding-knappen. */
  text-decoration: none; font-size: 0.875rem; font-weight: 600;
  color: var(--bone); white-space: nowrap;
}
/* .site-nav a farvede før ALLE links bone og vandt over knapklassen på
   specificitet. Knappen ligger nu uden for nav'en, så den beholder sin
   egen farve af sig selv. */
.nav-cta {
  color: var(--linje);
  /* Ved scroll er pillen kun burgeren: Tilmelding flytter ind i menufeltet,
     så knappen kun ses øverst på siden eller når menuen er åben (Alberts
     valg 2026-09-12). Den FOLDER ind som navnetrækket i logoet — max-width
     og opacity, ikke display — så pillen glider sammen i stedet for at
     hoppe. Knappens eget lys ligger inde i den (inset: 0, overflow:
     hidden på .btn--linje), så der klippes intet af undervejs. Samme
     kurve og tempo som logoet: ease-out på bredden, ease-ui på lyset. */
  white-space: nowrap; max-width: 12rem;
  transition: max-width 0.45s var(--ease-out), opacity 0.28s var(--ease-ui),
              padding 0.45s var(--ease-out), margin-left 0.45s var(--ease-out),
              border-color 0.28s var(--ease-ui), visibility 0s;
}
.site-header.scrolled .nav-cta {
  max-width: 0; opacity: 0; padding-inline: 0;
  margin-left: -0.35rem;              /* æder pillens gap, så burgeren står alene */
  border-color: transparent;
  visibility: hidden;                 /* ude af tastaturets rækkefølge når den er væk */
  transition: max-width 0.45s var(--ease-out), opacity 0.28s var(--ease-ui),
              padding 0.45s var(--ease-out), margin-left 0.45s var(--ease-out),
              border-color 0.28s var(--ease-ui), visibility 0s 0.45s;
}

/* BURGEREN bor i pillen sammen med Tilmelding og står altid fremme med
   ordet MENU ved siden af ikonet. */
.nav-toggle {
  position: relative; z-index: 60;
  display: flex; align-items: center; gap: 0.1rem;
  height: 44px; white-space: nowrap;
  padding: 0 0.7rem 0 0;
}
/* Målene og stregerne står HER og ikke inde i mobilmediet: burgeren
   bruges nu også på brede skærme, når menuen er foldet ind. Lå de stadig
   i mediet, var knappen uden noget at se på udenfor mobil. */
.nav-toggle__ikon { position: relative; flex: none; width: 44px; height: 44px; }
.nav-toggle__ikon i {
  position: absolute; left: 11px; width: 22px; height: 2px;
  background: var(--bone);
  transition: transform var(--dur-ui) var(--ease-ui), top var(--dur-ui) var(--ease-ui);
}
.nav-toggle__ikon i:nth-child(1) { top: 18px; }
.nav-toggle__ikon i:nth-child(2) { top: 25px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__ikon i:nth-child(1) { top: 21px; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__ikon i:nth-child(2) { top: 21px; transform: rotate(-45deg); }
/* Ordet i displayskriften, samme grad som menupunkterne i båndet, så
   burger og menu læses som samme ting. */
.nav-toggle__ord {
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  /* Ordet skal fylde pillens højde, ikke stå som en lille etiket ved
     siden af ikonet. Breaking er smal, så 1.85rem holder sig inden for
     de 44px uden at ordet bliver bredere end ikonet er højt gange to. */
  font-size: 1.85rem; letter-spacing: 0.03em; text-transform: uppercase;
  line-height: 1; color: var(--bone);
  /* Breakings versaler sidder højt i deres linje: blækket ligger 0.085em
     over midten af linjeboksen (målt). Skubbes ned præcis så meget, så
     der er lige meget luft over og under bogstaverne — ikke boksen. */
  position: relative; top: 0.085em;
}
/* MENUEN BAG BURGEREN er et lille felt oppe i hjørnet, ikke en hel skærm:
   der er fire punkter, og en fuldskærm til fire punkter er for meget.
   position: fixed tager den ud af den wrapper der folder ind, så den kan
   stå frit uanset at wrapperen er lukket i. Gælder både den foldede
   desktop og smalle skærme. */
.site-nav.open {
  position: fixed; z-index: 50;
  top: calc(var(--stribe-h) + var(--hero-luft) + 6rem); right: var(--page-gutter);
  /* Bredden følger punkterne: "Hold & tider" er det længste, og feltet
     skal kunne rumme det på én linje i disciplingraden (op til 4,4rem). */
  width: min(30rem, calc(100vw - 2 * var(--page-gutter)));
  visibility: visible; opacity: 1;
  flex-direction: column; align-items: stretch; gap: 0.15rem;
  /* Rigelig luft til kanterne: feltet er ikke en liste i en kasse, det er
     et kort med fem store ord (Alberts valg 2026-09-12). */
  padding: 1.6rem 1.5rem;
  background: var(--plum-950);
  border: 1px solid var(--rule);
  border-radius: var(--radius-media);
  box-shadow: 0 18px 40px color-mix(in srgb, #000 55%, transparent);
  animation: nav-ind 0.22s var(--ease-out);
}
@keyframes nav-ind { from { opacity: 0; transform: translateY(-8px); } }
@media (prefers-reduced-motion: reduce) { .site-nav.open { animation: none; } }
.site-nav.open a {
  /* Samme grad som disciplinnavnene — ét token, så de aldrig glider fra
     hinanden (--fs-disc). */
  font-family: var(--font-display); font-size: var(--fs-disc);
  text-transform: uppercase;
  line-height: 0.95;
  padding: 0.25rem 0;
}
/* Ingen hover i feltet: 64px type larmer mere end den vejleder. */
/* Wrapperen er foldet og dæmpet; den åbne menu skal ud af den. En
   opacity på forælderen slår igennem på hele indholdet, også et fixed
   barn, så den skal med her. */
.header-menu:has(.site-nav.open) { overflow: visible; opacity: 1; visibility: visible; }

/* MINI-FIGHTCARDET. Klubbens næste kamp i venstre felt: to runde portrætter
   med navnene stablet imellem sig og "vs" mellem navnene, i samme pille som
   Tilmelding-pillen. Øverst på siden står den frit på videoen og får sin
   flade ved scroll — samme regel som pillen til højre. Det er ét link, som
   fører til billetsalget. Markup: build.mjs (fra data/minifightcard.json)
   og main.js (fra /api/minifightcard). */
/* Feltet strækkes til rækkens højde, og pillen fylder feltet: så er
   fightcardet ALTID lige så højt som menupillen til højre, som sætter
   rækkens højde — både med Tilmelding på desktop og med burgeren alene
   på mobil. Portrætterne følger med (se --avatar nedenfor). */
.header-venstre {
  grid-row: 1; grid-column: 1; align-self: stretch;
  display: flex; min-width: 0;
  /* Feltet er en container, så fightcardet kan måle sin egen plads (se
     @container nedenfor). Containment gør feltets EGEN bredde 0, så det
     skal strækkes ud i hele gitterfeltet (justify-self: stretch, som er
     standard — IKKE start, for så måler containeren 0 og kortet folder
     altid sammen). Kortet ligger som flex-barn i venstre kant. */
  container-type: inline-size;
}
/* Pillens højde står ét sted: Tilmelding-knappen (14px + 24,8px + 14px) i
   0,35rem polstring og 1px kant er 66px; på mobil, hvor knappen er væk og
   burgeren alene sætter højden, 57px. Begge piller får tallet, så de er
   ens uanset hvad der står i dem, og portrættet måler sig efter det. */
.site-header { --pille-h: 66px; }
.header-pille { min-height: var(--pille-h); }
.fightcard {
  position: relative;               /* holdepunkt for "vs"-mærket */
  height: var(--pille-h);
  /* Portrættets mål: pillens indre højde, altså højden minus polstring og
     kant. Sat EKSPLICIT og ikke med aspect-ratio ud fra en strakt højde —
     Safari på iPhone regner ikke bredden ud af en højde, der kommer fra
     align-self: stretch. Kortet blev dermed målt, som om portrætterne var
     nul brede: pillen klappede sammen, portrætterne flød ud over den, og
     "vs" landede ude i venstre kant, fordi left: 50% var af et kort på
     nogle få pixels. To faste tal kan ingen browser regne forkert. */
  --avatar: calc(var(--pille-h) - 0.7rem - 2px);
  display: flex; align-items: center; gap: 0.6rem;
  /* Samme polstring som menupillen, så portrætterne får samme luft til
     kanten som burgeren og knappen. */
  padding: 0.35rem;
  padding-right: 0.9rem;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  background: transparent;
  text-decoration: none; color: var(--bone);
  /* gap og padding er med i overgangen, fordi foldningen ved scroll (se
     nedenfor) lukker mellemrummene sammen med midten. */
  transition: background-color var(--dur-ui) var(--ease-ui),
              border-color var(--dur-ui) var(--ease-ui),
              gap 0.45s var(--ease-out), padding 0.45s var(--ease-out);
}
/* hidden må ikke tabe til display: flex — kortet skal kunne gemmes helt,
   når der ikke er nogen kamp */
.fightcard[hidden] { display: none; }
.site-header.scrolled .fightcard { background: var(--plum-900); border-color: var(--rule); }
.fightcard__avatar {
  position: relative; flex: none; align-self: center;
  width: var(--avatar); height: var(--avatar);
  border-radius: 50%; overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--plum-800);
  /* Det andet portræt glider ind over det første, når kortet folder */
  transition: margin-left 0.45s var(--ease-out), box-shadow 0.28s var(--ease-ui);
}
/* Initialerne ligger under billedet og ses kun, når portrættet mangler */
.fightcard__avatar b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  font-size: 1.25rem; letter-spacing: 0.04em; color: var(--mist);
}
.fightcard__avatar img {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center top;
}
.fightcard__avatar img[hidden] { display: none; }
.fightcard__midt {
  display: grid; justify-items: center; text-align: center; gap: 0.1rem;
}
/* Midten og infokolonnen kan FOLDES: samme greb som navnetrækket i logoet
   (max-width + opacity, overflow: hidden), så de glider ind og ud i stedet
   for at hoppe. Loftet på 14rem er rigeligt over deres naturlige bredde. */
.fightcard__midt, .fightcard__info {
  max-width: 14rem; overflow: hidden;
  transition: max-width 0.45s var(--ease-out), opacity 0.28s var(--ease-ui),
              margin 0.45s var(--ease-out);
}
/* VED SCROLL folder kortet sig sammen til de to portrætter — glidende — og
   hover eller tastaturfokus på feltet folder det ud igen samme vej. Kun
   det ØVERSTE af siden viser kortet fuldt. På smalle skærme er kortet i
   forvejen kompakt gennem container-forespørgslen (display: none), så
   disse regler ændrer intet dér. */
.site-header.scrolled .header-venstre:not(:hover):not(:focus-within) .fightcard { gap: 0; padding-right: 0.35rem; }
.site-header.scrolled .header-venstre:not(:hover):not(:focus-within) .fightcard__midt,
.site-header.scrolled .header-venstre:not(:hover):not(:focus-within) .fightcard__info { max-width: 0; opacity: 0; margin: 0; }
.site-header.scrolled .header-venstre:not(:hover):not(:focus-within) .fightcard__midt + .fightcard__avatar {
  margin-left: -0.75rem; box-shadow: 0 0 0 2px var(--plum-900);
}
/* "vs"-mærket toner frem, når portrætterne er lagt sammen — lidt efter, så
   det ikke står oven på navnene mens de er på vej væk */
.site-header.scrolled .header-venstre:not(:hover):not(:focus-within) .fightcard__vs-kompakt {
  opacity: 1; visibility: visible;
  transition: opacity 0.28s var(--ease-ui) 0.2s, visibility 0s;
}
/* Tre linjer til højre for portrætterne: etiket i accentfarven som "Næste
   prøvetime:", datoen i bone, stævnet i mist. Stedet står IKKE her — det
   ligger i linkets aria-label og i titlen på hover. */
.fightcard__info {
  display: grid; gap: 0.2rem; align-content: center;
  font-size: 0.5625rem; letter-spacing: 0.14em; line-height: 1;
  color: var(--mist); white-space: nowrap;
}
.fightcard__mrk { color: var(--volt); }
.fightcard__info time { color: var(--bone); }
/* Under etiketten: dato og stævne stablet, og arrangørens mærke ved siden
   af, præcis så højt som de to linjer (to linjer + mellemrum). */
.fightcard__event { display: flex; align-items: center; gap: 0.45rem; }
.fightcard__linjer { display: grid; gap: 0.2rem; }
.fightcard__maerke { display: block; height: calc(2 * 0.5625rem + 0.2rem); width: auto; border-radius: 2px; }
.fightcard__maerke[hidden] { display: none; }
.fightcard__navn {
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  /* Navn + vs + navn skal holde sig inden for portrættets højde */
  font-size: 1.25rem; line-height: 1; letter-spacing: 0.03em;
  text-transform: uppercase; white-space: nowrap;
  /* Breaking sidder højt i sin linje, som MENU-ordet: samme forskydning */
  position: relative; top: 0.085em;
}
/* "vs" mellem navnene med en kort streg til hver side */
.fightcard__vs {
  display: flex; align-items: center; gap: 0.4rem;
  font-style: normal; font-size: 0.5rem; letter-spacing: 0.2em; line-height: 1;
  color: var(--mist);
}
.fightcard__vs::before, .fightcard__vs::after {
  content: ""; width: 1.25rem; height: 1px; background: var(--rule-strong);
}
/* "vs"-mærket hen over midten af bunden, hvor de to portrætter mødes. Det
   er der altid, men usynligt; den kompakte form (container-forespørgslen)
   og foldningen ved scroll toner det frem. */
.fightcard__vs-kompakt {
  position: absolute; left: 50%; bottom: 0.15rem;
  transform: translateX(-50%);
  font-style: normal; font-size: 0.5rem; letter-spacing: 0.12em; line-height: 1;
  padding: 2px 5px; border-radius: var(--radius-control);
  color: var(--bone); background: var(--plum-900); border: 1px solid var(--rule);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.28s var(--ease-ui), visibility 0s 0.28s;
}
/* Tilmelding inde i menufeltet vises KUN når pillens egen knap er væk:
   ved scroll, og på smalle skærme hvor den aldrig er i pillen. Så står
   den aldrig to steder på én gang. Den er den ALMINDELIGE knap (btn
   btn--linje btn--linje-hvid) med samme flade, lys og hover som i
   headerens pille — kun graden skal tages tilbage, fordi .site-nav.open a
   sætter disciplingraden på alle links. */
.site-nav__cta { display: none; }
.site-header.scrolled .site-nav.open .site-nav__cta { display: inline-block; margin-top: 1.5rem; }
/* Menupunkternes skrift, versaler og polstring skal TAGES TILBAGE her:
   .site-nav.open a rammer også CTA'en og vinder over .btn på specificitet.
   Værdierne er .btn's egne, så knappen står præcis som i headerens pille. */
.site-nav.open .site-nav__cta {
  font-family: var(--font-body); font-weight: 600; font-size: 0.875rem;
  line-height: 1.2; letter-spacing: 0.01em; text-transform: none;
  padding: 14px 28px;
  /* .site-nav a farver alle links bone; knappen skal have sin egen --linje */
  color: var(--linje);
}

/* HEADEREN PÅ SMALLE SKÆRME: kun mærket i midten, mini-fightcardet som to
   portrætter i venstre hjørne og burgeren i højre. Sidekolonnerne er 1fr,
   og et 1fr kan ikke blive smallere end sit indhold — derfor skal begge
   sider være smalle, ellers skubbes mærket ud af midten. Tilmelding går
   fra pillen ind i menufeltet. */
@media (max-width: 640px) {
  /* Mærket alene er nok: det står i midten og fører hjem, og navnet står
     i footeren. */
  .brand span { display: none; }
  /* Ens luft hele vejen rundt om mærket, så det ikke rører den runde ende */
  .brand { padding: 0.45rem 0.8rem; }
  .nav-cta { display: none; }
  /* MENUEN FYLDER SKÆRMEN på mobil: punkterne midt på fladen med
     Tilmelding under (Alberts valg 2026-09-12). Ikke et hjørnekort som
     på de brede skærme — på en telefon er der ikke andet at se på.
     Burgeren bliver liggende ovenpå (z-index 60) og er krydset ud. */
  .site-nav.open {
    inset: 0; width: auto; max-width: none; height: 100dvh;
    border: 0; border-radius: 0; box-shadow: none;
    justify-content: center; align-items: center;
    gap: 0.35rem;
    /* SAMME polstring foroven og forneden: ellers lander punkterne under
       skærmens midte. De 5,5rem holder dem fri af burgeren, hvis listen
       en dag bliver så lang at den fylder skærmen. */
    padding: 5.5rem var(--page-gutter);
    overflow-y: auto;
    /* Ren indtoning: et helskærmsfelt skal ikke glide 8px ned som
       hjørnekortet på de brede skærme. */
    animation-name: nav-ind-mobil;
  }
  @keyframes nav-ind-mobil { from { opacity: 0; } }
  .site-nav.open a { text-align: center; padding: 0.3rem 0; }
  .site-nav.open .site-nav__cta { display: inline-block; margin-top: 1.5rem; }
  /* Pillen har aldrig Tilmelding her, så feltets knap skal frem uanset scroll */
  /* Siden bagved må ikke rulle med, mens menuen dækker den */
  html.menu-aaben, html.menu-aaben body { overflow: hidden; }
  /* Pillen uden Tilmelding er lavere; fightcardet følger med (--pille-h) */
  .site-header { --pille-h: 57px; }
}
/* KOMPAKT FIGHTCARD: kun de to portrætter, det andet lagt halvt ind over
   det første, med en ring i pillens farve imellem, og "vs" hen over
   midten af bunden. Styres af FELTETS bredde og ikke af skærmens: fejlen,
   kunden så på en MacBook, var et vindue på omkring 1000px, hvor
   menupunkterne til højre åd venstre felt, kortet blev klemt, og
   portrættet lagde sig ind over navnene. Fuldt kort er ca. 20rem bredt;
   under 22rem folder det sammen — det rammer alle telefoner og ethvert
   smalt vindue. Et tryk åbner kamp-dialogen (main.js), som på desktop. */
@container (max-width: 22rem) {
  .fightcard { gap: 0; padding: 0.35rem; }
  .fightcard__midt, .fightcard__info { display: none; }
  .fightcard__avatar + .fightcard__avatar,
  .fightcard__midt + .fightcard__avatar { margin-left: -0.75rem; }
  /* Ringen mellem de to portrætter hører til kortets EGEN flade. Øverst på
     siden har kortet ingen flade (den kommer ved scroll), og ringen stod
     dér som en løs cirkel oven på videoen. */
  .site-header.scrolled .fightcard__avatar + .fightcard__avatar,
  .site-header.scrolled .fightcard__midt + .fightcard__avatar { box-shadow: 0 0 0 2px var(--plum-900); }
  .fightcard__avatar b { font-size: 1rem; }
  .fightcard__vs-kompakt { opacity: 1; visibility: visible; transition: none; }
}
/* På mobil står burgeren uden ordet MENU — ikonet er nok, og der er
   bedre plads til de tre ting ved siden af hinanden. */
@media (max-width: 640px) {
  .nav-toggle__ord { display: none; }
  .nav-toggle { padding-right: 0; }
}
/* Øverst på siden står burger og fightcard frit på videoen, også på
   mobil (Alberts valg 2026-09-12 — før havde de altid flade dér). Fladen
   kommer ved scroll, som på desktop, via .site-header.scrolled. */

/* ==========================================================================
   1. HERO (§5.2 hjørneforankring, §9.1 video)
   ========================================================================== */
.hero {
  position: relative;
  /* Blandingsgruppen for B'et og ordet ELITEN. Uden den afgøres gruppen
     længere oppe, og en afspillende video løftes på mobil til sit eget
     kompositlag — så kan difference ikke aflæse dens pixels, og ordet står
     bare hvidt. Symptomet var at inverteringen virkede mens POSTEREN var
     synlig og forsvandt i det øjeblik videoen startede. */
  isolation: isolate;
  /* max-height hører sammen med min-height. Uden loftet voksede heroen
     bare, når quiz-kortet blev højt: på en 667px skærm blev den 807px, og
     kortet — der sidder i bunden — havnede 144px under skærmkanten. Med
     loftet er gitteret indeni højdebegrænset, og minmax(0, 1fr) på
     overskriftsrækken kan gøre sit arbejde. */
  min-height: 100svh; max-height: 100svh;
  display: flex; flex-direction: column;
  /* klipper helt: gradient-B'et stopper ved sektionsgrænsen —
     fortsættelsen tegnes som outline af .disciplines__mark nedenunder */
  overflow: hidden;
  /* ...men grænsen mellem gradient-B'et og omridset er videofladens nederste
     kant, ikke heroens: disciplinerne trækkes op over heroens bundluft med
     denne negative margin, så deres top står præcis ved fladens bund, og
     deres mørke bund dækker gradient-B'et i luften. (Før klippede heroen med
     en clip-path og disciplinerne tegnede omridset op med en negativ
     clip-path — Safari på iPhone klippede ved sektionens egen top, så der
     stod et mellemrum mellem B og omrids.) */
  margin-bottom: calc(-1 * var(--hero-luft));
}
/* Luften i hele pixels, hvor browseren kan runde: en brøkdel af en pixel
   gav halve pixels i kanterne omkring videofladen. I en @supports, fordi en
   custom property ikke falder tilbage — en ukendt round() ville ellers
   ødelægge alle de steder, der bruger variablen. */
@supports (width: round(nearest, 1.5px, 1px)) {
  :root { --hero-luft: round(nearest, clamp(0.5rem, 0.2rem + 1.2vw, 1.25rem), 1px); }
}
/* VIDEOFLADEN er et kort med luft hele vejen rundt og runde hjørner;
   sektionens mørke bund ses i luften. Video og scrim deler geometrien.
   Sat med top/left/width/height og ikke inset: en absolut <video>
   strækkes ikke af inset alene (den tager sin egen bredde).
   --stribe-h: står eventstriben der, begynder fladen under den. Heroen
   klipper stadig ved sin egen underkant, så B'et krydser luften i bunden
   og fortsætter i disciplinerne som før. */
.hero__video,
.hero__scrim {
  top: calc(var(--stribe-h) + var(--hero-luft));
  left: var(--hero-luft);
  width: calc(100% - 2 * var(--hero-luft));
  height: calc(100% - var(--stribe-h) - 2 * var(--hero-luft));
  border-radius: var(--radius-media);
}
.hero__video {
  position: absolute;
  object-fit: cover;
  background: var(--plum-900);
  /* INTET filter her. Der stod filter: grayscale(var(--hero-desat)) med
     --hero-desat: 0 — visuelt en nul-operation, men et filter er et filter:
     hver eneste videoframe blev sendt gennem et ekstra render-pass, og
     videoen blev holdt ude af browserens hurtige overlay-sti. Skal
     afmætningen tilbage, sæt filteret på igen SAMMEN med en værdi > 0. */
  /* Hold videoen i den normale kompositsti frem for et hardware-overlay,
     så laget ovenover kan blande med den. */
  transform: translateZ(0);
  backface-visibility: hidden;
}
.hero__scrim {
  position: absolute;   /* pladsen deles med videoen — se ovenfor */
  /* Klipper sin bundscrim (::after) til de runde hjørner — ellers stak dens
     firkantede hjørner ud forneden og lagde en mørk kant over lyset */
  overflow: hidden;
  /* Øverste lag: mørket i toppen, som headerens skygge gav før
     (2026-09-14). Det ligger HER, i scrimen, der scroller med videoen —
     headerens skygge sidder på en fast header, og på iPhone flyttes faste
     lag med forsinkelse under scroll, så videoens lyse top kom frem i en
     stribe over den. Samme trin som skyggen; 18rem ≈ 320 % af headeren.
     Headerens egen skygge er slået fra på forsiden (se .site-header::after). */
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--plum-900) 62%, transparent) 0%,
      color-mix(in srgb, var(--plum-900) 44%, transparent) 22%,
      color-mix(in srgb, var(--plum-900) 26%, transparent) 44%,
      color-mix(in srgb, var(--plum-900) 12%, transparent) 66%,
      color-mix(in srgb, var(--plum-900)  4%, transparent) 84%,
      transparent 100%) top / 100% 18rem no-repeat,
    linear-gradient(
      100deg,
      color-mix(in srgb, var(--plum-900) 62%, transparent) 0%,
      color-mix(in srgb, var(--plum-900) 30%, transparent) 45%,
      color-mix(in srgb, var(--plum-900) 6%, transparent) 100%
    );
}
/* ekstra bundscrim så bundbjælken altid står klart */
.hero__scrim::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 30%;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--plum-900) 55%, transparent));
}
/* KANTLAGET OM VIDEOFLADEN — .hero-lys lige før heroen i HTML'en, et tomt
   lag med fladens geometri, der bærer den udvendige kant herunder. (Lyset
   bag fladen lå også her; det er fjernet igen 2026-09-14 og ligger i
   git-historikken.) z-index: 1 løfter laget over heroen OG disciplinerne,
   som overlapper heroens bundluft med deres mørke bund — ellers blev
   kantens bundlinje dækket. Højden er 100svh som heroen, så de følges på
   iPhone (laget har ingen positioneret forælder). */
.hero-lys {
  position: absolute; z-index: 1; pointer-events: none;
  top: calc(var(--stribe-h) + var(--hero-luft));
  left: var(--hero-luft);
  width: calc(100% - 2 * var(--hero-luft));
  height: calc(100svh - var(--stribe-h) - 2 * var(--hero-luft));
  border-radius: var(--radius-media);
}
/* KANTEN om videofladen (2026-09-14) — samme streg som quiz-kortet (1px i
   --rule, hvid 16 %), men UDVENDIG: stregen ligger lige uden for fladens
   kant i stedet for oven på dens yderste pixel. Rundingen er 1px større,
   så stregens inderkant følger fladens hjørner.
   Den sidder på .hero-lys (uden for heroen og over disciplinerne), fordi
   disciplinerne dækker luften under fladen — en udvendig streg i heroen
   ville miste bundlinjen. Laget ligger på z-index 1, så stregen er hel hele
   vejen rundt, også over B'et, der stikker ud i luften. */
.hero-lys::after {
  content: ""; position: absolute; z-index: 1; pointer-events: none;
  inset: -1px;
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius-media) + 1px);
}
.hero__inner {
  /* BEVIDST uden z-index: et z-index her ville danne en stakkontekst og
     afskære .w--blend fra at difference-blande med hero-videoen. DOM-orden
     holder den stadig over .hero__mark. */
  position: relative;
  flex: 1;
  width: 100%; /* .wrap's margin-inline:auto må ikke udløse shrink-to-fit i flex-kolonnen */
  /* Headerens loft i stedet for indholdets (.wrap): overskrift og quiz-kort
     flugter med headerens kanter på alle bredder */
  max-width: var(--flade-max);
  display: grid;
  grid-template-rows: 1fr auto;
  padding-top: clamp(7.5rem, 14vh, 10rem); /* fri af sticky header + versal-overhæng */
  padding-bottom: var(--nextbar-offset); /* flugter med nextbaren */
}
.hero__headline { align-self: center; }
/* NÅR QUIZ-KORTET BLIVER FOR HØJT
   Kortet vokser opad og skubber overskriften op. Med grid-template-rows:
   1fr auto har den første række et AUTO-minimum, altså overskriftens egen
   højde — så når kortet er højere end resten af pladsen, kan rækken ikke
   give mere, og kortet bliver i stedet skubbet ud under skærmkanten.
   Det sker allerede ved "Kamphold — kræver godkendelse", der fylder 426px.

   minmax(0, 1fr) lader rækken skrumpe helt væk, så kortet altid bliver
   inden for bunden. Alene ville det dog sende overskriften op under
   headeren, fordi center-justering lader den flyde over i BEGGE retninger.

   safe center løser præcis det: centrér, men fald tilbage til start hvis
   indholdet ikke kan være der. Overskriften bliver altså centreret så
   længe der er plads — nøjagtig som før — og når der ikke er, står den
   øverst og lader kortet lægge sig hen over sig.

   @supports fordi de to hører sammen: uden safe-understøttelse skal
   rækken heller ikke kunne skrumpe. */
@supports (align-self: safe center) {
  .hero__inner {
    /* min-height: 0 skal med. .hero__inner er et flex-element, og et
       flex-element har min-height: auto — det kan altså ikke blive mindre
       end sit eget indhold, uanset hvad flex: 1 tildeler det. Uden dette
       voksede gitteret bare videre, og minmax(0, 1fr) fik aldrig noget at
       skrumpe. */
    min-height: 0;
    grid-template-rows: minmax(0, 1fr) auto;
  }
  .hero__headline { align-self: safe center; }
}
/* Forsidens H1 kører på --fs-h2, samme grad som sektionernes H2 og
   undersidernes H1 (Alberts valg 2026-09-12). */
.hero__headline h1 { font-size: var(--fs-h2); max-width: 16ch; color: var(--bone); }
.hero__headline .lead { margin-top: 1.5rem; color: var(--bone); }
.hero__headline .mono { display: block; margin-top: 1.75rem; color: var(--mist); }

/* Vandmærke — monogram der bløder ud af højre kant (§5.2) */
/* På mobil ligger B'et lidt højere end på desktop: -7% mod -12%, altså
   40px længere oppe på en 812px høj hero. Fortsættelsen i disciplin-
   sektionen følger automatisk med — main.js læser mærkets faktiske
   bottom-værdi og regner ikke med et fast tal. */
@media (max-width: 767.98px) {
  /* -4 % og ikke -7 % (2026-09-14): quiz-kortet dækker heroens nederste
     tredjedel på mobil, og ved -7 % stod kun ~26px af B'et over kortet.
     -1 % løftede det for højt; -4 % er halvvejs. B'et stikker stadig ud
     under heroen, så fortsættelsen i disciplin-sektionen (.disciplines__mark)
     har noget at flugte med — JS'en læser værdien, så den følger selv med. */
  .hero__mark { --mark-bottom: -4%; }
}
.hero__mark {
  position: absolute;   /* z-index fjernet — se .hero__inner */
  right: var(--mark-right);
  /* JS læser denne værdi for at placere outline-fortsættelsen — ændres den
     her, følger fortsættelsen automatisk med. */
  bottom: var(--mark-bottom, -12%);
  width: var(--mark-w);
  pointer-events: none;
}

/* Quiz-kort — nederst til venstre, overlapper hero-bunden */
.quiz {
  position: relative; z-index: 3;
  width: min(400px, 100%);
  /* Bunden og blurren her bliver overskrevet af ".quiz, .nextbar" langt
     nede i filen, som gør kortet helt uigennemsigtigt. Farven holdes ens
     begge steder, så den bliver rigtig hvis den regel en dag fjernes. */
  background: color-mix(in srgb, var(--plum-950) 92%, transparent);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid var(--rule);
  border-radius: var(--radius-media);
  padding: 1.5rem;
}
/* Sponsorlogoet er procesbjælken: Monster-logoet får mere fyld for hvert
   trin. Tre udgaver oven på hinanden, data-trin vælger den tændte. */
/* Mærkerne i venstre hjørne, tælleren i højre. Ordet "Trin:" er væk —
   tallet siger det samme og fylder mindre. .quiz__status er sr-only og
   dermed position: absolute, så den falder ud af flowet og forstyrrer
   ikke space-between. */
.quiz__trin {
  /* flex-start og ikke center: tælleren skal flugte med mærkernes overkant
     og ikke stå midt for dem. Mærkegruppen er den højeste og bliver stående
     hvor den er — det er kun tallet der flytter op. */
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 0.75rem;
  margin-block: 0.55rem 1.75rem;
}
/* end og ikke center: "Sponsoreret af" står over logoet, og plus og dåse
   skal flugte med selve logoet, ikke med midten af blokken. Marginerne
   under plus og dåse er halvdelen af højdeforskellen til logoets 3,6rem. */
.quiz__maerker { display: flex; align-items: end; gap: 0.55rem; }
.quiz__taeller { color: var(--mist); }
.quiz__sponsor { display: grid; justify-items: start; }
/* Logoet er 1120×443. Inde i filerne er kløerne skaleret til 90 % og
   ordmærket til 120 % af originalen (Alberts ønske), så viewBox'en er
   bredere end de 1000 der kom fra Figma. Alle tre udgaver deler viewBox
   og er venstrestillet, så kløerne ikke flytter sig ved skiftet.
   Udgaverne ligger absolut oven på hinanden og tones over. */
.quiz__logo {
  position: relative; display: block;
  height: 3.6rem; aspect-ratio: 1120 / 443;
}
.quiz__logo img {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  opacity: 0;
  transition: opacity 0.4s var(--ease-out);
}
.quiz__logo[data-trin="1"] img:nth-child(1),
.quiz__logo[data-trin="2"] img:nth-child(2),
.quiz__logo[data-trin="3"] img:nth-child(3) { opacity: 1; }
.quiz__maerker .daase { margin-bottom: 7.8px; }  /* (57,6 − 42) / 2 */
/* Quiz-spørgsmålet i display-fonten. Den er smal, så graden skal OP for
   at bære samme vægt som før. font-synthesis-weight slås fra: fonten har kun
   én fysisk vægt, og browseren ville ellers tegne en syntetisk fed. */
.quiz__q {
  font-family: var(--font-display);
  font-synthesis-weight: none;
  font-weight: 700;
  font-size: clamp(1.6875rem, 1.45rem + 0.7vw, 2.25rem);
  line-height: 0.74; letter-spacing: 0.01em; /* som de øvrige overskrifter —
     underlængderne er flade, så blækket fylder 0.714em også i
     sætningscase, og linjerne kolliderer derfor ikke */
  margin-bottom: 1rem; color: var(--bone);
}
.quiz__opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }
/* Dobbelttryk-zoom slås fra på alt der kan trykkes på — og på hele
   quizkortet, så et hurtigt andet tryk der rammer mellemrummet mellem to
   svar heller ikke zoomer. Første tryk skifter spørgsmålet, og andet tryk
   landede før på en ny knap og zoomede ind. På iOS kunne zoomet ud igen
   efterlade monster-logoets overtonede lag delvist utegnet.
   manipulation beholder panorering og knibe-zoom, så siden stadig kan
   forstørres med to fingre. */
button, a, [role="button"], .quiz { touch-action: manipulation; }
.quiz__opts button {
  padding: 9px 16px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-control);
  font-size: 0.875rem; font-weight: 500; color: var(--bone);
  transition: border-color var(--dur-ui) var(--ease-ui), background-color var(--dur-ui) var(--ease-ui), color var(--dur-ui) var(--ease-ui);
}
.quiz__result { display: none; }
.quiz.done .quiz__result { display: block; }
/* Mærkerne bliver stående på svarsiden — alle tre tændt viser at man er
   igennem. Kun spørgsmålet og svarknapperne forsvinder. */
.quiz.done .quiz__q, .quiz.done .quiz__opts { display: none; }
.quiz__result .mono { color: var(--volt); display: block; margin-bottom: 0.5rem; }
.quiz__result p { font-size: 0.9375rem; margin-bottom: 1rem; color: var(--bone); }
.quiz__result .btn { width: 100%; }
.quiz__result .btn + .btn { margin-top: 0.5rem; }
.quiz__alt[hidden] { display: none; }
.quiz__reset {
  margin-top: 0.75rem; width: 100%;
  font-family: var(--font-mono); font-size: 0.6875rem;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--mist);
}

/* ==========================================================================
   MONSTER-DÅSEN — en RIGTIG cylinder i CSS 3D, ikke et billede der drejer.
   24 lodrette skiver stilles op i en ring (rotateY + translateZ), og hver
   skive viser sit eget udsnit af den flade etiket. Derfor er silhuetten
   ægte: dåsen er lige så bred hele vejen rundt, og etiketten forsvinder om
   bag kanten i stedet for at blive mast sammen.

   De tre billeder laves af udrul-daase.py ud af ét frontalfoto:
     daase-etiket.webp   den udrullede etiket, 360°, forsiden i midten
     daase-skulder.webp  skulderen udrullet, til keglen over kroppen
     daase-fod.webp      foden udrullet, til keglen under kroppen
   Låg og bund er rene runde flader. Alle mål herunder er brøkdele af
   dåsens diameter og kommer fra fotoets rækker — scriptet udskriver dem.

   Skiverne skrives af main.js og ikke i HTML: de er ren pynt, og markuppen
   skal ikke bære 24 tomme spans i to filer.
   ========================================================================== */
.daase {
  /* Det eneste mål man normalt rører: alt andet regnes ud herfra.
     17 px giver en dåse på 42 px — samme højde som mærkerne ved siden af. */
  --d: 17px;                              /* dåsens diameter */

  --skiver: 24;
  --w: calc(var(--d) * 0.131652);         /* d · tan(180°/24) = én skives bredde */
  --wrap: calc(var(--d) * 3.1596);        /* 24 skiver = hele omkredsen */
  /* Fotoets inddeling i dåse-diametre (udrul-daase.py udskriver dem):
     kroppen er det lige stykke, skulder og fod de koniske ender. */
  --krop-y:  calc(var(--d) * 0.2553);     /* kroppens overkant */
  --h:       calc(var(--d) * 2.0177);     /* kroppens højde */
  --sk-h:    calc(var(--d) * 0.2128);     /* skulderens højde over kroppen */
  --sk-slant: calc(var(--d) * 0.2260);    /* skulderskivens længde langs keglen */
  --laag-r:  calc(var(--d) * 0.4238);     /* lågets radius */
  --fod-h:   calc(var(--d) * 0.1667);     /* fodens højde under kroppen */
  --fod-slant: calc(var(--d) * 0.2975);
  --fod-r:   calc(var(--d) * 0.2535);     /* bundskivens radius */
  --spin: 7s;
  --haeld: 12deg;                         /* dåsen står ikke stift lodret */
  --vip: 4.5s;                            /* én runde af aksens kegle */

  position: relative; flex: none;
  display: block;
  width: var(--d);
  height: calc(var(--d) * 2.4823);
  /* Slukket indtil quizzen er kørt igennem — dåsen er præmien, ikke pynt.
     opacity/filter flader 3D-rummet ud HER — og kun her — så de rammer det
     færdige billede af dåsen og ikke de enkelte skiver. */
  opacity: 0.5;
  filter: saturate(0.35) brightness(0.75);
  transition: opacity 0.6s var(--ease-out), filter 0.6s var(--ease-out);
}
/* PRØVET OG FORKASTET (2026-09-12): filteret flyttet ned på de enkelte
   flader, så det kunne tegnes én gang og genbruges under omdrejningen.
   Et filter gør fladen til sin egen gruppe og tager den UD af dåsens
   3D-rum — cylinderen faldt sammen til en flad plade. Filteret skal
   ramme det samlede billede og bliver derfor på .daase. */
/* PRÆCESSION — dåsen drejer ikke bare, dens akse tegner en kegle om
   midtpunktet, som en snurretop der er ved at lægge sig. Tre lag oven i
   hinanden, alle i samme 3D-rum:
     scene  drejer hældningens RETNING rundt (rotateY φ)
     haeld  lægger den faste hældning på (rotateZ 12°)
     mod    drejer φ tilbage igen
   Uden mod-laget ville låg og bund — som er flade billeder — blive
   foreshortnet til en streg hver gang φ passerer 90°. For en rund dåse
   er moddrejningen usynlig; for de flade lag er den det hele. Netto får
   alt en ren hældning på 12° i en retning der kører rundt: toppen kører
   i én cirkel, bunden i den modsatte, midten står stille.
   De to rotationer var før én registreret egenskab (--phi), som blev
   animeret og arvet ned til mod-laget. Det så rigtigt ud, men en
   custom-property-animation kan browseren IKKE lægge på GPU'en: hver
   frame blev stilen for hele dåse-træet regnet om på hovedtråden, og
   24 skiver fik nye transforms — hele tiden, mens heroen er på skærmen.
   Nu er det to almindelige transform-keyframes med samme varighed og
   samme lineære forløb; de starter i samme frame (elementerne bygges
   sammen af main.js) og kan derfor ikke komme ud af takt. Resultatet er
   pixel for pixel det samme, men kører helt på compositoren. */
.daase__scene, .daase__haeld, .daase__mod {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
}
/* Keglen kører i sit eget tempo (4,5 s mod omdrejningens 7 s), så
   bevægelsen aldrig gentager sig synligt. Begge kører ALTID — også mens
   dåsen er dæmpet i quizzen; det er kun lyset der venter på svarene. */
.daase__scene {
  transform: perspective(300px) rotateY(0deg);
  animation: daase-vip-scene var(--vip) linear infinite;
}
.daase__haeld { transform: rotateZ(var(--haeld)); }
.daase__mod {
  transform: rotateY(0deg);
  animation: daase-vip-mod var(--vip) linear infinite;
}
@keyframes daase-vip-scene { to { transform: perspective(300px) rotateY(360deg); } }
@keyframes daase-vip-mod { to { transform: rotateY(-360deg); } }
/* ENDERNE ER RIGTIG 3D. Før var låg og bund flade fotos i dåsens
   midterplan. Det holdt så længe dåsen kun hældede til siden; vippede den
   mod eller fra os, var fotoets bagte perspektiv uenigt med kroppens ægte,
   og man så enten ind i cylinderen (mørk halvmåne) eller en kantskive der
   sad skævt i forhold til fotoet. Nu er skulder og fod kegler af 24
   skiver ligesom kroppen, med hver sit udrullede stykke af fotoet, og låg
   og bund er runde flader lagt vandret. Alt sidder i samme rum, deler
   samme perspektiv og drejer sammen — så kan ingen del være uenig med en
   anden, uanset hvilken vej dåsen vipper.

   Keglen: hver skive står i ringen som kroppens (rotateY + translateZ),
   men drejer om sin egen fod (transform-origin bund) og læner sig ind mod
   aksen med rotateX. clip-path gør rektanglet til et trapez, så
   nabo-skiverne mødes foroven hvor omkredsen er mindre. */
.daase__skulder, .daase__fod {
  position: absolute; left: 0; right: 0;
  transform-style: preserve-3d;
}
.daase__skulder { top: calc(-1 * var(--sk-h)); height: var(--sk-h); }
.daase__fod     { top: var(--h); height: var(--fod-h); }
.daase__skulderskive, .daase__fodskive {
  position: absolute; left: 50%;
  width: calc(var(--w) + 0.6px);
  margin-left: calc(var(--w) / -2);
  backface-visibility: hidden;
  background-size: var(--wrap) 100%;
  background-repeat: repeat-x;   /* som kroppens skiver: sømmen på sidste skive */
  background-position-x: calc(-1 * var(--i) * var(--w));
}
.daase__skulderskive {
  bottom: 0; height: var(--sk-slant);
  transform-origin: 50% 100%;
  transform: rotateY(calc(var(--i) * 15deg - 180deg)) translateZ(calc(var(--d) / 2)) rotateX(19.7deg);
  clip-path: polygon(0 100%, 100% 100%, 92.4% 0, 7.6% 0);   /* 0.848 bred foroven */
  background-image: url("../img/daase-skulder.webp");
}
.daase__fodskive {
  top: 0; height: var(--fod-slant);
  transform-origin: 50% 0;
  transform: rotateY(calc(var(--i) * 15deg - 180deg)) translateZ(calc(var(--d) / 2)) rotateX(-55.9deg);
  clip-path: polygon(0 0, 100% 0, 75.3% 100%, 24.7% 100%);   /* 0.507 bred forneden */
  background-image: url("../img/daase-fod.webp");
}
/* Låg og bund: runde flader lagt vandret oven på og under keglerne
   (rotateX ±90°). Forsiden vender ud af dåsen og bagsiden er usynlig, så
   låget ses kun oppefra og bunden kun nedefra. Ingen fotos: set oppefra er
   et låg bare aluminium. 1.03: keglens hjørner stikker en anelse ud over
   den runde radius. */
.daase__laag, .daase__bundskive {
  position: absolute; left: 50%;
  border-radius: 50%;
  backface-visibility: hidden;
  pointer-events: none;
}
.daase__laag {
  width: calc(var(--laag-r) * 2.06); height: calc(var(--laag-r) * 2.06);
  margin-left: calc(var(--laag-r) * -1.03);
  top: calc(-1 * var(--sk-h) - var(--laag-r) * 1.03);
  transform: rotateX(90deg);
  background: radial-gradient(circle at 50% 50%,
    #d9d5e0 0%, #c8c2d1 30%, #ebe8f0 62%, #a29cad 100%);
}
.daase__bundskive {
  width: calc(var(--fod-r) * 2.06); height: calc(var(--fod-r) * 2.06);
  margin-left: calc(var(--fod-r) * -1.03);
  top: calc(var(--h) + var(--fod-h) - var(--fod-r) * 1.03);
  transform: rotateX(-90deg);
  background: radial-gradient(circle at 50% 50%, #3a3542 0%, #22202a 70%, #15131b 100%);
}
.daase__krop {
  position: absolute; left: 0; right: 0;
  top: var(--krop-y);
  height: var(--h);
  /* Perspektivet ligger på .daase__scene, så krop, låg og bund deler
     samme kamera — kroppen må ikke flade ud for sig selv her */
  transform-style: preserve-3d;
}
.daase__spin {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  animation: daase-drej var(--spin) linear infinite;
}
@keyframes daase-drej { to { transform: rotateY(-360deg); } }
/* +0.6px bredde lukker hårfine sømme mellem skiverne uden at flytte
   baggrunden — background-position regner stadig med den rene bredde. */
.daase__skive {
  position: absolute; top: 0; left: 50%;
  width: calc(var(--w) + 0.6px); height: 100%;
  margin-left: calc(var(--w) / -2);
  /* -180° flytter etikettens midte om foran: kloen sidder midt på den
     flade etiket, og uden forskydningen ville dåsen stå med bagsiden mod
     os, når animationen holder stille. */
  transform: rotateY(calc(var(--i) * 15deg - 180deg)) translateZ(calc(var(--d) / 2));
  backface-visibility: hidden;
  /* Etiketten skaleres til omkredsen; hver skive trækker den sin egen
     bredde til venstre og viser dermed sit udsnit. repeat-x og IKKE
     no-repeat: skiven er 0,6 px bredere end sin plads, og på den sidste
     skive rager de 0,6 px ud over billedets kant. Med no-repeat viste de
     ingenting — en mørk streg lige ned gennem bagsidens klo, som ligger
     præcis på billedets kant. Med repeat-x viser de billedets første
     0,6 px, som er fortsættelsen, fordi etiketten er sømløs. */
  background: url("../img/daase-etiket.webp") calc(-1 * var(--i) * var(--w)) 0 / var(--wrap) 100% repeat-x;
}
/* Lyset ligger stille mens dåsen drejer — det er rummet der belyser den,
   ikke etiketten der bærer sin egen skygge rundt. Blødere end på en sort
   dåse: hvid aluminium trækker mindre skygge ind fra kanterne. */
.daase__lys {
  position: absolute; left: 0; right: 0;
  /* KUN kroppen. Laget er en flad firkant med mørke kanter i siderne;
     kroppen er fuld bredde, så dér har det altid dåse bag sig. Strakt ud
     over skulder og fod, hvor dåsen er smallere, hang de mørke sidebånd
     ude i luften ved siden af halsen og foden som en skygge. */
  top: var(--krop-y);
  height: var(--h);
  pointer-events: none;
  /* Lyset skal ligge FORAN kroppen i rummet — ellers står det midt inde i
     cylinderen og dækkes af de forreste skiver */
  transform: translateZ(calc(var(--d) / 2 + 0.5px));
  background: linear-gradient(90deg,
    rgba(6, 4, 10, 0.62) 0%,
    rgba(6, 4, 10, 0.26) 14%,
    rgba(6, 4, 10, 0) 32%,
    rgba(255, 255, 255, 0.28) 43%,
    rgba(255, 255, 255, 0.05) 56%,
    rgba(6, 4, 10, 0.2) 74%,
    rgba(6, 4, 10, 0.58) 100%);
}
/* Uden for skærmen står alt stille. Dåsens omdrejning og kegle er
   custom-property-animationer, som browseren IKKE kan lægge på GPU'en:
   hver frame regnes forfra på hovedtråden og 24 skiver skal sættes om.
   Det er spild, når kortet er scrollet forbi. main.js sætter klassen. */
.i-ro, .i-ro *,
.i-ro::before, .i-ro::after,
.i-ro *::before, .i-ro *::after { animation-play-state: paused !important; }

/* TÆNDT: i quizzen når alle tre trin er nået, og altid i prøvetime-
   dialogen — der er dåsen ikke en præmie man skal spille om. */
.quiz.done .daase,
.ptime .daase { opacity: 1; filter: none; }
/* LYSET BAG DÅSEN er disciplinkortenes lys (se "LYSET UNDER STREGEN"):
   samme to lag, samme farvestop, samme åndedræt — bare rundt om et punkt
   i stedet for langs en streg. ::before er bloomet, ::after kernen.
   z-index -1 lægger dem bag dåsen inde i dens egen stacking context. */
.daase::before, .daase::after {
  content: ""; position: absolute; z-index: -1;
  border-radius: 50%;
  opacity: 0; pointer-events: none;
  transition: opacity 0.5s var(--ease-ui);
}
.daase::before {
  inset: -40% -130%;
  background:
    radial-gradient(closest-side,
      color-mix(in srgb, var(--volt) 13%, transparent) 0%,
      color-mix(in srgb, var(--volt) 4%, transparent) 30%,
      transparent 66%),
    radial-gradient(closest-side,
      color-mix(in srgb, var(--plum-500) 46%, transparent) 0%,
      color-mix(in srgb, var(--plum-500) 26%, transparent) 8%,
      color-mix(in srgb, var(--plum-500) 17%, transparent) 18%,
      color-mix(in srgb, var(--plum-500) 10%, transparent) 34%,
      color-mix(in srgb, var(--plum-500)  5%, transparent) 60%,
      transparent 88%);
}
.daase::after {
  inset: 15% -45%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--white) 74%, transparent) 0%,
    color-mix(in srgb, var(--white) 34%, transparent) 9%,
    color-mix(in srgb, var(--plum-500) 44%, transparent) 26%,
    color-mix(in srgb, var(--plum-500) 14%, transparent) 52%,
    transparent 82%);
}
.quiz.done .daase::before, .quiz.done .daase::after,
.ptime .daase::before, .ptime .daase::after { opacity: 1; }
.quiz.done .daase::before, .ptime .daase::before { animation: disc-bloom 5.1s ease-in-out infinite; }
.quiz.done .daase::after,  .ptime .daase::after { animation: disc-kerne 3.4s ease-in-out infinite; }
/* Plusset foran dåsen er bare et plus — samme dæmpede tone som tælleren,
   og det skifter ikke med svarene */
.quiz__plus {
  font-family: var(--font-mono); font-size: 1.125rem; line-height: 1;
  color: var(--mist);
  margin-bottom: 19.8px; /* (57,6 − 18) / 2: midt for logoet */
}
@media (prefers-reduced-motion: reduce) {
  /* Dåsen bliver stående i en kvartdrejning — man skal stadig kunne se
     at den er rund, den skal bare ikke køre rundt af sig selv. */
  .daase__spin { animation: none; transform: rotateY(-14deg); }
  .daase__scene, .daase__mod { animation: none; }
  .daase::before, .daase::after { animation: none; }
}

/* ==========================================================================
   BUNDBJÆLKE (day1-mønster, §8.1)
   ========================================================================== */
.nextbar {
  position: fixed; z-index: 45;
  /* Flugter med headerens højre kant, også når headeren har nået loftet
     (--flade-max) og står centreret. 100% er skærmens bredde uden
     scrollbaren — samme bredde som headeren centreres i. */
  right: max(var(--page-gutter), calc((100% - var(--flade-max)) / 2 + var(--page-gutter)));
  bottom: var(--nextbar-offset);
  display: flex; align-items: center; gap: 1.25rem;
  /* Overskrives af ".quiz, .nextbar" langt nede i filen — samme farve dér */
  background: color-mix(in srgb, var(--plum-950) 92%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--rule);
  border-radius: var(--radius-control);
  padding: 0.5rem 0.5rem 0.5rem 1.4rem;
  transform: translateY(0);
  transition: transform 0.4s var(--ease-out), opacity 0.4s var(--ease-out);
}
.nextbar[hidden] { display: none; }
.nextbar__label { color: var(--volt); }
.nextbar__what { font-weight: 600; font-size: 0.9375rem; color: var(--bone); white-space: nowrap; }
.nextbar__when { font-family: var(--font-mono); font-size: var(--fs-meta); letter-spacing: 0.06em; text-transform: uppercase; color: var(--mist); white-space: nowrap; }
@media (max-width: 640px) {
  .nextbar {
    right: 0.75rem; left: 0.75rem; bottom: 0.75rem;
    justify-content: space-between; padding-left: 1.1rem;
  }
  .nextbar__label { display: none; }
  /* Knappen må ALDRIG ombrydes til to linjer */
  .nextbar .btn { white-space: nowrap; font-size: 0.75rem; padding: 12px 18px; }
}

/* ==========================================================================
   2. DISCIPLINER — typografiske kort, ingen clip-art
   ========================================================================== */
.disciplines { padding-block: var(--section-md); }
/* Tre spalter: de seks discipliner står i de to første (tre i hver), og
   nyhederne (.disc-nyt) har den tredje for sig selv. main.js
   bygger spalterne; uden JS falder gitteret tilbage på tre kolonner med
   kortene i DOM-rækkefølge. Alle kort vejer lige — hierarkiet ligger i
   overskriften, så kortene ikke skal konkurrere. */
.disciplines__grid {
  margin-top: 2.5rem;
  display: grid; grid-template-columns: repeat(3, 1fr);
  /* Rækkeafstanden er den samme som kortets egen luft over navnet
     (padding-top), så bunden af et kort matcher toppen af det næste. */
  column-gap: var(--grid-gap); row-gap: 1.75rem;
}
/* Med JS: to disciplinspalter + nyhedskortet som tredje flex-barn.
   Spalterne er uafhængige, så højden i den ene aldrig påvirker den
   anden. stretch, så nyhedskortet kan fylde hele spaltehøjden; wrap, så
   det kan lægge sig under spalterne på smallere skærme. */
.disciplines__grid.har-spalter {
  display: flex; flex-wrap: wrap; align-items: stretch;
  gap: var(--grid-gap);
  /* Etiketten (.disc-nyt) ligger absolut oven på gitteret, og gitteret er
     en container, så cqw kan regne tredjedelen ud — også inde i
     transform, hvor % ellers ville pege på etikettens egen bredde. */
  position: relative; container-type: inline-size;
}
/* flex-basis 20% og ikke 0: med basis 0 lægges nyhedskortets polstring
   oven i dets andel, og det blev 50px bredere end spalterne. Med samme
   basis over polstringen vokser alle tre lige meget og ender lige brede.
   3 × 20 % er under 100 %, så intet ombrydes på brede skærme. */
.disc-spalte {
  flex: 1 1 20%; min-width: 0;
  display: grid; align-content: start; row-gap: 1.75rem;
}
/* Disciplinerne fylder altid højst to tredjedele: hver spalte er præcis
   en tredjedel af gitteret, og den sidste tredjedel står tom til
   nyhedsetiketten, som flyver oven på den. Under 1101px er der to spalter
   der deler bredden, og etiketten ryger ned som sin egen sektion. */
@media (min-width: 1101px) {
  .disc-spalte { flex: 0 0 calc((100% - 2 * var(--grid-gap)) / 3); }
}
@media (max-width: 1100px) { .disciplines__grid { grid-template-columns: repeat(2, 1fr); } }
/* LYSET UNDER STREGEN
   Opstod som hover-lys under disciplinkortenes streg; kortene har ingen
   hover længere, men dåsen, holdtiderne, filterpillerne og trænerringen
   bygger stadig på keyframes'ene og tankegangen her.
   Bygget som en lyskilde, ikke som en flade. En rigtig punktlyskilde
   falder af med 1/(1 + d·a): styrken styrtdykker lige omkring kernen og
   får så en lang, svag hale. Det er præcis dét der giver klinge-udtrykket
   — kernen brænder ud i hvidt, og farven dukker først op i halen, hvor
   lyset er svagt nok til at være farvet.

   Farvestoppene følger den kurve i stedet for at ligge jævnt: over
   halvdelen af styrken er væk efter 8% af vejen, tre fjerdedele efter en
   tredjedel. Jævnt fordelte stop ville give en flad vask i stedet.

   To lag: ::after er selve kernen — kort, smal, næsten hvid. ::before er
   bloomet omkring den, i plum-500 med et strejf brand-cyan yderst, hvor
   det lilla ellers ville dø fladt ud. Begge ligger under kortets indhold;
   det klares af z-index på barnereglen længere nede. */
/* Levende: de to lag ånder i hver sin takt, 3,4 og 5,1 sekunder. Tallene
   går ikke op i hinanden, så mønstret gentager sig først efter godt et
   halvt minut og lyset aldrig står stille.
   Kun transform animeres — opacity er reserveret til ind- og udtoningen,
   og en keyframe der også satte opacity ville tage magten fra den og få
   lyset til at springe frem i stedet for at tone ind. */
@keyframes disc-kerne {
  0%, 100% { transform: scale(1, 1); }
  50%      { transform: scale(0.93, 1.12); }
}
@keyframes disc-bloom {
  0%, 100% { transform: scale(1, 1); }
  50%      { transform: scale(1.03, 1.14); }
}
/* Ikke et kort med ramme: én streg i toppen. Ingen flade, ingen hjørner
   og ingen hover — kortet er sektionens egen bund og fører ingen steder
   hen, så det skal heller ikke reagere på markøren. */
.disc-card {
  border-top: 1px solid var(--rule-strong);
  padding-top: 1.75rem;
  display: grid; align-content: start; gap: 0.75rem;
}
/* Loftet er sat efter "Kickboksning", det længste navn: det skal kunne stå
   på én linje i sin spalte, ellers falder rækken fra hinanden */
.disc-card h3 {
  color: var(--bone);
  font-size: var(--fs-disc);
}
/* Fakta hentes fra skemaet — tomme felter må ikke reservere plads hvis JS
   udebliver, derfor :empty-reglerne */
.disc-card__naeste {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem;
  margin-top: 0.35rem;
}
.disc-card__naeste b,
.disc-card__uge { font-weight: 400; font-size: var(--fs-meta); font-style: normal; }
.disc-card__tid { color: var(--volt); }
/* Mærkatet bliver stående i accentfarven, mens selve tiden er hvid: øjet
   skal lande på svaret, ikke på etiketten der gentager sig i alle fem kort. */
.disc-card__mrk { color: var(--volt); }
.disc-card__vaerdi { color: var(--white); }
/* Kolonet trækker vejret i takt med prikken i eventstriben — samme
   keyframe, ikke en kopi, så de to aldrig kan glide fra hinanden. */
.disc-card__mrk i,
.nextbar__label i {
  font-style: normal;
  animation: news-blink 1.6s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .disc-card__mrk i, .nextbar__label i { animation: none; }
}
/* Antal hold står på række med overskriften og flugter med dens bundlinje.
   Er der ikke plads på én linje (Muay Thais "Kombineret med kickboksning"),
   bliver teksten stående ved siden af navnet og ombryder i sig selv til to
   linjer — og det er den NEDERSTE linje der flugter med overskriften:
   last baseline, ikke first. Navnet må aldrig krympe, teksten tager resten. */
.disc-card__top {
  display: flex; align-items: last baseline;
  column-gap: 1rem;
}
.disc-card__top > h3 { flex: none; }
.disc-card__uge { color: var(--mist); flex: 1 1 0; min-width: 0; }
.disc-card__tid:empty, .disc-card__uge:empty, .disc-card__niveau:empty { display: none; }
/* Niveaumærket står kun der når næste hold faktisk kræver godkendelse */
.disc-card__niveau {
  font-style: normal; font-size: 0.625rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--mist);
  border: 1px solid var(--rule); border-radius: var(--radius-control);
  padding: 2px 8px;
}
/* "Se alle hold": samme stille knap som svarmulighederne i quizkortet —
   svag streg, ingen fylde, ingen hover. Den skal ikke konkurrere med
   Tilmelding og Gratis prøvetime, som er de eneste knapper med hover. */
.disc-card__skema {
  justify-self: start;
  display: inline-block; margin-top: 0.25rem;
  padding: 9px 16px;
  border: 1px solid var(--rule-strong); border-radius: var(--radius-control);
  color: var(--bone); text-decoration: none;
  font-family: var(--font-body); font-weight: 500; font-size: 0.875rem;
  letter-spacing: 0.01em; line-height: 1.2; text-transform: none;
}

/* ---- NYHEDSETIKETTEN — flyver oven på gitterets tredje tredjedel ----
   Disciplinerne fylder altid højst to tredjedele (se .disc-spalte); den
   sidste tredjedel står tom, og etiketten ligger absolut oven på den,
   klistret til skærmens højre kant og lige så høj som spalterne (top og
   bund er gitterets). Sektionen klipper (overflow: hidden), så intet
   giver vandret scroll.
   I hvile hænger striben med de tre andre artikler uden for skærmkanten,
   så man kun ser den fremhævede. Hover, fokus eller et tryk trækker
   etiketten ind, så striben kommer til syne — om nødvendigt ind over
   disciplinerne.
   Indeni: "Nyheder", kilde og dato, det valgte foto stort, og til højre
   en lodret stribe med de TRE andre artikler (den valgte tages ud af
   striben, main.js), hver med sin overskrift i to linjer under.
   Fladen er --plum-950: næsten sort, aldrig ren sort (§0.6). */
.disc-nyt {
  --nyt-luft: var(--page-gutter);
  --nyt-overskud: max(0px, (100vw - var(--page-max)) / 2);
  --nyt-kloft: 0.75rem;
  --nyt-pad: 1.5rem;
  /* UD er den plads der faktisk er uden for indholdsbredden: sidens luft
     plus det der er tilovers uden for --page-max. */
  --nyt-ud: calc(var(--nyt-luft) + var(--nyt-overskud));
  /* Striben tager den plads der er derude. Gulvet er den bredde den havde
     som fast tal; loftet er sat efter HØJDEN: bredere miniaturer er også
     højere, og over 13rem bliver de FIRE tilsammen højere end det
     fremhævede foto og trækker hele etiketten længere ned. */
  --nyt-stribe: clamp(6.9rem, calc(var(--nyt-ud) - var(--nyt-kloft) - var(--nyt-pad)), 13rem);
  /* BEHOV er den plads striben skal bruge uden for indholdskanten. */
  --nyt-behov: calc(var(--nyt-kloft) + var(--nyt-stribe) + var(--nyt-pad));
  /* Er der mere plads end striben skal bruge (brede skærme), forlænges
     fladen med resten, så den stadig når skærmkanten. Er der mindre
     (omkring 1101-1500px), hænger striben ud over kanten og trækkes ind
     ved hover. Kun ét af de to tal er nogensinde større end nul. */
  --nyt-ekstra: max(0px, calc(var(--nyt-ud) - var(--nyt-behov)));
  --nyt-mangler: max(0px, calc(var(--nyt-behov) - var(--nyt-ud)));
  /* Højden følger indholdet, fordi fotoet er 4:5. Derfor ingen bottom:
     etiketten hænger i toppen af gitteret og slutter hvor den slutter. */
  position: absolute; top: 0; z-index: 2;
  /* Bredden er tredje spalte PLUS det striben skal bruge udenfor, og højre
     kant sidder --nyt-behov uden for indholdskanten. Tilsammen lander
     etikettens venstre kant præcis på tredje spaltes venstre kant, og
     fotoet slutter præcis på indholdskanten — kun striben er udenfor.
     right animeres ved hover og må derfor ikke indeholde cqw: Chrome
     interpolerer ikke længder med container-enheder. */
  right: calc(-1 * var(--nyt-behov));
  width: calc((100cqw - 2 * var(--grid-gap)) / 3 + var(--nyt-behov));
  display: grid; grid-template-rows: auto auto; row-gap: 0.85rem;
  padding: var(--nyt-pad);
  /* Bevægelsen ligger på translate og IKKE på right: at flytte en kant er
     en LAYOUT-ændring, og browseren måtte regne siden om for hvert billede
     i de 0,45 sekunder, udfoldningen varer — med fem fotos indeni. translate
     flytter kun det færdige billede og koster ingen layout.
     (Lag-gennemgangen 2026-09-12.) */
  transition: translate 0.45s var(--ease-out);
}
/* Fladen tegnes af en ::before og ikke af kassen selv, fordi den skal
   kunne fortsætte forbi etikettens højre kant og helt ud til skærmen på
   brede skærme. z-index: -1 lægger den bag indholdet, men stadig foran
   disciplinerne — etiketten har sin egen stakkontekst. */
.disc-nyt::before {
  content: ""; position: absolute; z-index: -1;
  inset: 0 calc(-1 * var(--nyt-ekstra)) 0 0;
  background: var(--plum-950);
  /* Samme streg som prøvetime-bjælken. Højre side ligger uden for
     skærmen, så det er top, bund og venstre kant man ser. */
  border: 1px solid var(--rule);
  border-radius: var(--radius-media) 0 0 var(--radius-media);
}
.disc-nyt:hover, .disc-nyt:focus-within, .disc-nyt.er-ude {
  translate: calc(-1 * var(--nyt-mangler));
}
.nyt__mrk {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem;
}
.nyt__scene {
  display: grid; min-height: 0;
  grid-template-columns: minmax(0, 1fr) var(--nyt-stribe);
  grid-template-rows: auto auto;
  /* Overskrifterne ligger inde i billederne. Bundrækken er prikkernes
     alene, og den holder sig i fotoets spalte, så de står midt under
     billedet og ikke midt under foto + stribe. */
  grid-template-areas: "foto stribe" "prikker .";
  gap: 0.85rem var(--nyt-kloft);
}
/* display: contents: linket har ingen egen boks, så foto, overskrift og
   "Læs artiklen" kan stå i scenens gitter side om side med striben, som
   ikke er en del af linket (knapper må ikke stå inde i et link). Fokus
   tegnes derfor på fotoet, ikke på linket selv. */
.nyt__valgt { display: contents; color: inherit; text-decoration: none; }
.nyt__foto {
  grid-area: foto; position: relative; overflow: hidden; min-height: 0;
  /* Portræt som sidens øvrige store fotos (Ledelsen, trænerne) */
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-media);
  border: 1px solid var(--rule);      /* som sidens øvrige medier */
  background: var(--plum-800);
}
.nyt__foto img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 30%;
  transition: transform 0.7s var(--ease-out);
}
/* Striben: de tre andre artikler stablet fra toppen, hver med foto i 16:9
   og overskrift under. Den valgte er [hidden] og tæller ikke med. */
/* Striben står altid fremme. Er der ikke plads nok uden for indholdet til
   den, hænger den ud over skærmkanten, og hover folder etiketten ud — se
   --nyt-mangler ovenfor. */
.nyt__stribe {
  grid-area: stribe; min-height: 0;
  display: grid; grid-auto-rows: auto; align-content: start; gap: 0.6rem;
}
.nyt__mini {
  display: block; min-height: 0; padding: 0; background: none; border: 0;
  color: inherit; text-align: left; cursor: pointer;
}
.nyt__mini[hidden] { display: none; }
.nyt__mini-foto {
  position: relative; min-height: 0; overflow: hidden;
  aspect-ratio: 16 / 9;
  /* Nødvendigt: som inline-span ville aspect-ratio slet ikke gælde */
  display: block;
  border-radius: 8px; border: 1px solid var(--rule);
  background: var(--plum-800);
}
.nyt__mini-foto img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.5s var(--ease-out);
}
/* Samme greb i miniatureformat: to linjer nederst i billedet */
.nyt__mini-tekst {
  font-size: 0.6875rem; line-height: 1.2; color: var(--white);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.nyt__mini:focus-visible { outline: none; }
.nyt__mini:focus-visible .nyt__mini-foto { outline: 2px solid var(--volt); outline-offset: 2px; }
/* Overskrifterne ligger nederst INDE i billederne. Bunden bag dem er både
   farvet og blurret, så teksten kan læses uanset hvad der er på fotoet.
   Masken toner både farven og blurren ud opad — uden den ville blurren
   stoppe i en lige, synlig kant midt på billedet.
   Scrimen er et lag for sig og ikke bare teksten med baggrund på: både
   absolut positionering OG det at være flex-barn blokificerer
   display:-webkit-box, og så holder -webkit-line-clamp op med at klippe.
   Her er scrimen den absolutte, og teksten indeni er et almindeligt
   blokelement, der frit kan være en -webkit-box. */
.nyt__scrim {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  padding: 3.5rem 1rem 0.9rem;
}
/* Farven, blurren og masken ligger på et lag BAG teksten og ikke på
   scrimen selv: masken gælder hele elementets tegning, så med den på
   scrimen blev toppen af bogstaverne tonet halvt væk sammen med
   baggrunden. z-index: -1 holder laget bag teksten, inde i scrimens egen
   stakkontekst. */
.nyt__scrim::before {
  /* 1–2px ud over kanterne (2026-09-14): højderne er brøkdele af en pixel,
     og blurren blegner ud lige ved sin kant, så på mobil stod en tynd, lys
     kant af fotoet under laget. Fotoboksen klipper det overskydende væk. */
  content: ""; position: absolute; inset: 0 -1px -2px; z-index: -1;
  background: linear-gradient(to top,
    color-mix(in srgb, var(--plum-950) 88%, transparent) 0%,
    color-mix(in srgb, var(--plum-950) 66%, transparent) 45%,
    transparent 100%);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  -webkit-mask-image: linear-gradient(to top, #000 55%, transparent 100%);
          mask-image: linear-gradient(to top, #000 55%, transparent 100%);
}
.nyt__scrim--mini { padding: 1.25rem 0.5rem 0.4rem; }
.nyt__scrim--mini::before {
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
}
/* KILDEMÆRKET — fighting.dk's eget logo øverst i højre hjørne, så det er
   tydeligt hvem artiklen kommer fra. Logofilen er ensfarvet, så den
   bruges som MASKE og males hvid; sådan følger den paletten i stedet for
   at være låst til filens egen farve. Samme greb som B-mærket i
   eyebrowen. Attributten styrer det, så en artikel fra en anden kilde
   (Instagram senere) bare lader være med at have den. */
.nyt__foto[data-maerke="fighting"]::after,
.nyt__mini-foto[data-maerke="fighting"]::after {
  content: ""; position: absolute; z-index: 1;
  top: 0.7rem; right: 0.7rem;
  width: 5.5rem; aspect-ratio: 1722 / 309;
  background: var(--white);
  opacity: 0.85;
  -webkit-mask: url("../img/fighting-dk-logo.svg?v=1") center / contain no-repeat;
          mask: url("../img/fighting-dk-logo.svg?v=1") center / contain no-repeat;
  pointer-events: none;
}
.nyt__mini-foto[data-maerke="fighting"]::after {
  top: 0.4rem; right: 0.4rem; width: 3.1rem;
}
.nyt__overskrift {
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  text-transform: uppercase; letter-spacing: 0.01em;
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2.4rem); line-height: 1.02;
  color: var(--white);
  /* Højst tre linjer, så prikker: en lang overskrift må ikke fylde hele
     billedet. Hele overskriften står stadig i data-titel og på artiklen. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
  transition: color var(--dur-ui) var(--ease-ui);
}
/* Prikkerne siger hvor mange artikler der er, og hvilken man ser. Rækken
   under fotoet er deres alene, og den holder sig i fotoets spalte, så
   "midt i rækken" er midt under billedet. Bygget af main.js: uden JS kan
   de ikke bruges, og så skal de heller ikke stå der. */
.nyt__prikker {
  grid-area: prikker; justify-self: center; align-self: center;
  display: flex; gap: 0.55rem;
  padding-top: 0.9rem;
}
.nyt__prik {
  position: relative;
  width: 6px; height: 6px; border-radius: 50%;
  padding: 0; border: 0; cursor: pointer;
  background: color-mix(in srgb, var(--white) 26%, transparent);
  transition: background var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-ui);
}
/* Prikken er 6px, men fingeren rammer 20px: en usynlig kasse udenom.
   Den ligger i ::after, så selve prikken beholder sin størrelse. */
.nyt__prik::after { content: ""; position: absolute; inset: -7px; }
/* Den valgte blinker i takt med kolonet i "Næste hold:" og prikken i
   eventstriben — samme keyframe, ikke en kopi, så de aldrig glider fra
   hinanden. */
.nyt__prik[aria-current="true"] {
  background: var(--volt); transform: scale(1.3);
  animation: news-blink 1.6s ease-in-out infinite;
}
.nyt__prik:focus-visible { outline: 2px solid var(--volt); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .nyt__prik { transition: none; }
  .nyt__prik[aria-current="true"] { animation: none; }
}
@media (hover: hover) and (pointer: fine) {
  .nyt__valgt:hover .nyt__foto img { transform: scale(1.035); }
  .nyt__valgt:hover .nyt__overskrift { color: var(--white); }
}
.nyt__valgt:focus-visible .nyt__foto { outline: 2px solid var(--volt); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .disc-nyt, .nyt__foto img, .nyt__mini-foto img { transition: none; }
}
/* Tablet og mobil: ingen tredje tredjedel, så etiketten holder op med at
   flyve og bliver sin egen sektion i fuld bredde under disciplinerne —
   fladen fra kant til kant, indholdet inden for sidens luft. Fotoet i
   16:10 (artikelbillederne er liggende), de tre andre artikler som en
   vandret række under det. */
@media (max-width: 1100px) {
  /* Nyhederne er sidste element i sektionen og skal slutte præcis hvor
     den lyse sektion begynder. Sektionens egen bundluft fjernes derfor og
     lægges ind i nyhedsblokken i stedet — ellers stod der en stribe af
     sektionens lilla under den mørke flade. */
  .disciplines { padding-bottom: 0; }
  .disc-nyt {
    position: static; z-index: auto; width: auto; right: auto;
    flex: 0 0 calc(100% + 2 * var(--nyt-ud));
    margin-inline: calc(-1 * var(--nyt-ud));
    margin-top: 1.5rem;
    padding: 2.75rem var(--nyt-ud);
    /* Her er etiketten en almindelig sektion i fuld bredde, så fladen kan
       ligge på kassen selv — og ingen streg: en sektion tegnes ikke op
       som et kort. */
    background: var(--plum-950);
    border: 0;
    grid-template-rows: auto auto;
  }
  .disc-nyt::before { display: none; }
  .disc-nyt:hover, .disc-nyt:focus-within, .disc-nyt.er-ude { right: auto; translate: none; }
  .nyt__scene {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    /* Prikkerne nederst her — mellem fotoet og striben delte de de to op
       og lignede en afslutning midt i kortet. */
    grid-template-areas: "foto" "stribe" "prikker";
  }
  .nyt__foto { aspect-ratio: 16 / 10; }
  /* Striben bliver en vandret ruller: to og en halv miniature ad gangen.
     Den halve er pointen — den viser at der er mere at swipe til. flex frem
     for gitter, fordi antallet af synlige skal styres af bredden og ikke af
     et fast kolonnetal. */
  .nyt__stribe {
    display: flex; gap: 0.75rem;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    /* Kant til kant (2026-09-14): striben går ud i nyhedsblokkens luft på
       begge sider, så miniaturerne ikke skæres ved indholdsbredden, men kan
       swipes helt ud til skærmkanten. Luften lægges ind som polstring, så
       den første miniature stadig starter ved indholdet, og snap-punkterne
       holder samme afstand. Miniaturernes procentbredde regnes af
       indholdsboksen (uden polstring), så der stadig står to og en halv fremme. */
    margin-inline: calc(-1 * var(--nyt-ud));
    padding-inline: var(--nyt-ud);
    scroll-padding-inline: var(--nyt-ud);
  }
  .nyt__stribe::-webkit-scrollbar { display: none; }
  /* To mellemrum står fremme (mellem 1-2 og 2-3), derfor 2 × 0.75rem */
  .nyt__mini { flex: 0 0 calc((100% - 1.5rem) / 2.5); scroll-snap-align: start; }
}
@media (max-width: 767.98px) {
  .disc-nyt { padding-block: 2.5rem; }
  /* Miniaturerne er kun omkring 70px høje her. To linjer tekst med den
     normale scrim dækkede næsten hele billedet, så teksten skæres til én
     linje og scrimen holdes lav. */
  .nyt__scrim--mini { padding: 0.7rem 0.4rem 0.3rem; }
  .nyt__mini-tekst { -webkit-line-clamp: 1; }
  /* Miniaturerne er kun omkring 125px brede her, og kildemærket fyldte
     halvdelen af dem */
  .nyt__mini-foto[data-maerke="fighting"]::after { width: 2rem; top: 0.3rem; right: 0.3rem; }
  .nyt__foto[data-maerke="fighting"]::after { width: 4.5rem; }
}

@media (max-width: 767.98px) {
  .disciplines__grid { grid-template-columns: 1fr; row-gap: 1.75rem; }
  .disc-spalte { row-gap: 1.75rem; }
}

/* ==========================================================================
   3. PLADS TIL ALLE (lys)
   ========================================================================== */
.s-pladstilalle { padding-block: var(--section-lg); text-align: center; }
.s-pladstilalle .eyebrow { justify-content: center; }
.s-pladstilalle h2 { max-width: 16ch; margin-inline: auto; }
.s-pladstilalle p { margin: 2rem auto 0; }
.s-pladstilalle .actions { margin-top: 2.5rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }

/* ==========================================================================
   4+5. SPLITS (mørk)
   ========================================================================== */
.s-split {
  padding-block: var(--section-md);
  /* Lyset bag medierne (figure::before) stikker 42 % af mediets bredde ud
     til hver side. Uden dette lagde det 143 px til sidens bredde, og hele
     siden kunne skubbes vandret — værst på mobil, hvor man skøjtede rundt.
     clip og IKKE hidden: hidden ville tvinge overflow-y til auto og gøre
     sektionen til sin egen scroll-container. Lyset klippes kun dér hvor
     det alligevel er ude af skærmen. */
  overflow-x: clip;
}
.s-split .split, .s-split .split--alt { align-items: center; }
.s-split figure { position: relative; isolation: isolate; }
/* LYS BAG MEDIET — disciplinkortenes lys (se "LYSET UNDER STREGEN") lagt
   bag billedet: samme to lag, samme farvestop, samme åndedræt. ::before
   er bloomet, bredt ud omkring billedet; ::after kernen, som kun stikker
   lige ud over kanten. Begge på z-index -1 i figurens egen stacking
   context, så de ligger bag mediet og over sektionens bund.
   (En firkantet udgave med blur blev prøvet og forkastet — ellipsen
   var bedre.) Ved hover vokser begge lag udad — inset animeres, ikke
   transform, som åndedrættet allerede bruger. */
.s-split figure::before, .s-split figure::after {
  content: ""; position: absolute; z-index: -1;
  border-radius: 50%; pointer-events: none;
  transition: inset 0.7s var(--ease-out);
}
/* Kraftigere end på kortene: bag et foto ses kun dét der stikker ud
   over kanten, så både styrke og udstrækning er sat op (~1,6×), ellers
   drukner det i plum-900.
   Strammet en smule (2026-09-14): udstrækningen er ca. 15 % mindre, og
   kurven falder hurtigere mod kanten, så lyset står skarpere om mediet —
   styrken i midten er den samme. Var inset -36% -42% / -10% -13%, hover
   -44% -50% / -14% -17%, og ud-tonet ved 88 % / 82 %. */
.s-split figure::before {
  inset: -30% -35%;
  background:
    radial-gradient(closest-side,
      color-mix(in srgb, var(--volt) 22%, transparent) 0%,
      color-mix(in srgb, var(--volt) 8%, transparent) 26%,
      transparent 56%),
    radial-gradient(closest-side,
      color-mix(in srgb, var(--plum-500) 72%, transparent) 0%,
      color-mix(in srgb, var(--plum-500) 44%, transparent) 7%,
      color-mix(in srgb, var(--plum-500) 30%, transparent) 15%,
      color-mix(in srgb, var(--plum-500) 18%, transparent) 29%,
      color-mix(in srgb, var(--plum-500)  9%, transparent) 51%,
      transparent 75%);
  animation: disc-bloom 5.1s ease-in-out infinite;
}
.s-split figure::after {
  inset: -8.5% -11%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--white) 90%, transparent) 0%,
    color-mix(in srgb, var(--white) 50%, transparent) 8%,
    color-mix(in srgb, var(--plum-500) 62%, transparent) 22%,
    color-mix(in srgb, var(--plum-500) 24%, transparent) 44%,
    transparent 70%);
  animation: disc-kerne 3.4s ease-in-out infinite;
}
.s-split figure:hover::before { inset: -37% -42.5%; }
.s-split figure:hover::after { inset: -12% -14.5%; }
/* Wipe-reveal'et klipper til figurens egen kasse, også når det er
   færdigt — og lyset ligger UDEN for kassen. Så slutter klippet her et
   godt stykke uden for i stedet: samme wipe nedefra, men lyset kommer med
   når kanten passerer. */
.s-split figure.reveal-clip.in { clip-path: inset(-45% -45% -45% -45%); }
@media (prefers-reduced-motion: reduce) {
  .s-split figure::before, .s-split figure::after { animation: none; }
}
.s-split .ph { aspect-ratio: 4 / 5; width: 100%; }
.s-split .ph--reel { aspect-ratio: 9 / 16; max-width: 340px; margin-inline: auto; }
.s-split .content h2 { max-width: 14ch; margin-bottom: 1.5rem; }
.s-split .content p { color: var(--mist); margin-bottom: 1rem; }
.s-split .content .credentials { list-style: none; margin: 1.5rem 0 2rem; display: grid; gap: 0.6rem; }
.s-split .content .credentials li {
  display: flex; gap: 0.75rem; align-items: baseline;
  font-size: var(--fs-small); color: var(--bone);
}
.s-split .content .credentials li::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--volt); flex: none; transform: translateY(-2px);
}
.quote-mark { font-size: clamp(2.75rem, 1.9rem + 4.2vw, 5.5rem); /* som marqueen */ line-height: 1.1; font-family: var(--font-display); text-transform: uppercase; color: var(--bone); max-width: 18ch; }

@media (max-width: 991.98px) {
  .s-split .split > figure, .s-split .split--alt > figure { order: -1; }
  .s-split .ph { aspect-ratio: 16 / 10; }
  .s-split .ph--reel { aspect-ratio: 9 / 16; }
}

/* ==========================================================================
   LEDELSEN + ANBEFALINGEN — ét mørkt lærred med B-omrids og striber (§3.5)
   De to splits deler baggrunden, så grafikken kan krydse grænsen mellem
   dem. B'et har heroens størrelse og højre kant (--mark-w/--mark-right) og
   står centreret på grænsen (--graense sættes af main.js; uden JS midt i
   lærredet). Striberne ligger i B'ets egne koordinater i forlængelse af dets
   skrå kanter, så de altid er parallelle med det — overflow: visible lader
   dem løbe ud over monogrammet, og lærredet klipper dem.
   Samme styrke som disciplinerne: B 12 %, striber 10 %.
   ========================================================================== */
.b-flade {
  position: relative;
  background: var(--plum-900);
  overflow: hidden;
  overflow: clip;   /* clip hvor det findes: gør ikke lærredet til en rulleboks */
}
.b-flade > section { position: relative; z-index: 1; background: transparent; }
.b-flade__mark,
.b-flade__striber {
  position: absolute; z-index: 0;
  right: var(--mark-right);
  top: calc(var(--graense, 50%) - var(--mark-w) / 2);
  width: var(--mark-w); height: var(--mark-w);
  overflow: visible;
  pointer-events: none;
  will-change: transform;
}
.b-flade__mark { opacity: 0.12; }
.b-flade__mark path { stroke-width: 1.6; }
.b-flade__striber { opacity: 0.10; }
.b-flade__striber path { stroke-width: 1.2; }
/* Optegningen: kun når main.js styrer den og bevægelse er tilladt. Uden JS
   og ved reduceret bevægelse står grafikken færdigtegnet. */
.b-flade.tegner .b-flade__mark path { stroke-dasharray: 1; stroke-dashoffset: var(--tegn-b, 1); }
.b-flade.tegner .b-flade__striber path { stroke-dasharray: 1; stroke-dashoffset: var(--tegn-s, 1); }

/* ==========================================================================
   6. MARQUEE (§7)
   ========================================================================== */
.marquee {
  overflow: hidden; white-space: nowrap;
  /* Symmetrisk padding virker kun fordi blækket centreres i em-boksen
     nedenfor — ellers ville luften være skæv trods ens tal her */
  padding-block: 0.9rem;
  border-bottom: 1px solid var(--volt);
  /* Samme grad som .disc-card h3 — striben og disciplinnavnene
     læses som samme stemme. */
  --marquee-fs: clamp(2.75rem, 1.9rem + 4.2vw, 5.5rem);
}
.marquee__track {
  display: flex; width: max-content;
  /* Ingen CSS-animation: main.js driver positionen, fordi farten og
     retningen følger scrollet og derfor ikke kan stå i en keyframe.
     Uden JS står striben stille — den er ren pynt (aria-hidden). */
  will-change: transform;
}
.marquee__unit {
  display: inline-flex; align-items: center; flex: none;
  font-family: var(--font-display); font-size: var(--marquee-fs);
  text-transform: uppercase; letter-spacing: 0.01em;
  color: var(--bone); line-height: 1;
}
/* Display-versalerne fylder 0.685em over baseline og intet under, så blækket
   sidder 0.065em fra em-boksens top og 0.25em fra bunden. Uden dette skub
   står teksten højt i stribens luft — og logoet, der centreres på em-boksen,
   ville flugte med boksen i stedet for med bogstaverne. Målt, ikke gættet. */
.marquee__unit i {
  font-style: normal;
  transform: translateY(0.0925em);
}
/* aspect-ratio giver bredden FØR svg'en er hentet — ellers er hver divider
   0px bred indtil load, og sporet hopper i bredden midt i loopet */
.marquee__unit img {
  height: 0.46em; width: auto; aspect-ratio: 1;
  flex: none; margin-inline: 0.4em;
}

/* ==========================================================================
   7. KÆMPERNES HISTORIER — det lilla panel (§9.2)
   ========================================================================== */
.stories { padding-block: var(--section-md); position: relative; overflow: hidden; }
.stories h2 { max-width: 16ch; }   /* arver bone som de øvrige mørke sektioner */
.stories__intro { color: color-mix(in srgb, var(--white) 82%, transparent); margin-top: 1.25rem; max-width: 52ch; }
.stories__rail {
  display: grid; grid-auto-flow: column;
  --kort-b: min(240px, 62vw);
  grid-auto-columns: var(--kort-b);
  gap: var(--grid-gap);
  overflow-x: auto;
  /* overflow-x:auto tvinger overflow-y til auto — selv 1px for højt indhold
     gør railen lodret slæbbar med gummibånd. Forbyd det eksplicit. */
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  /* Plads til hover-lyset: railen klipper alt uden for sin kasse, så den
     får luft hele vejen rundt — og trækkes tilsvarende ud med negative
     margener, så kortene står præcis hvor de stod. scroll-padding holder
     snap-punkterne på indholdskanten og ikke på railens nye yderkant. */
  padding-block: 6rem;
  margin-block: -3.5rem -5.5rem;
  /* 6rem er mere end sidens gutter på smalle skærme; railen stikker så
     ud over .wrap i begge sider, men .stories klipper i skærmkanten, og
     kortene står stadig på indholdskanten. */
  /* Vandret: railen er skærmbred (vinduet ligger uden for .wrap), og
     polstringen er afstanden fra skærmkanten til indholdskanten — samme
     formel som .wrap bruger: gutteren, og over sidens maksimum halvdelen
     af det overskydende oveni. Så står første kort præcis på
     indholdskanten, og kort på vej ud løber gennem gutteren og forsvinder
     først i skærmkanten. */
  --kant: max(var(--page-gutter), calc((100% - var(--page-max)) / 2 + var(--page-gutter)));
  padding-inline: var(--kant);
  scroll-padding-inline: var(--kant);
  scrollbar-width: none;
  /* Kan trækkes med musen (main.js) */
  cursor: grab;
}
/* Vinduet holder railen og er skærmbredt (det ligger uden for .wrap), så
   kortene kan løbe gennem gutteren og først forsvinde i skærmkanten.
   Her sad før et lys i begge kanter, der viste at der var mere at rulle
   til; det er erstattet af prikkerne nedenfor (Alberts valg 2026-09-12).
   Gradienterne ligger i git-historikken. */
.stories__vindue { position: relative; }

/* PRIKKERNE under railen — samme kontrol som i nyhedskortet: én prik pr.
   kort, den man står på i volt, og man kan klikke sig hen til et kort.
   Bygget af main.js: uden JS kan de ikke bruges, og en død kontrol er
   værre end ingen. */
.stories__prikker {
  display: flex; justify-content: center; gap: 0.55rem;
  /* Railen har negativ bundmargen (den har polstring til hover-lyset), så
     prikkerne ligger tæt på kortene af sig selv — 8px. Luften her gør
     afstanden til kortene til en bevidst afstand og ikke et tilfælde. */
  margin-top: 1rem;
}
.stories__prik {
  position: relative;
  width: 6px; height: 6px; border-radius: 50%;
  padding: 0; border: 0; cursor: pointer;
  background: color-mix(in srgb, var(--white) 26%, transparent);
  transition: background var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-ui);
}
/* Prikken er 6px, men fingeren rammer 20px: en usynlig kasse udenom.
   Den ligger i ::after, så selve prikken beholder sin størrelse. */
.stories__prik::after { content: ""; position: absolute; inset: -7px; }
.stories__prik[aria-current="true"] { background: var(--volt); transform: scale(1.3); }
.stories__prik:focus-visible { outline: 2px solid var(--volt); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .stories__prik { transition: none; } }
/* Store skærme: ingen prikker. Her rulles railen med mus og træk, og flere
   kort står fremme på én gang (Alberts valg 2026-09-13). */
@media (min-width: 1101px) { .stories__prikker { display: none; } }
/* På mobil ses ét kort ad gangen, og så skal det stå MIDT på skærmen når
   det falder i hak — men kun når der ER kort på begge sider af det.
   Første kort bliver liggende i indholdskanten som resten af siden, og
   sidste kort slutter i den modsatte kant; ville man centrere dem, skulle
   railen have en halv skærm luft i hver ende, og så flugtede første kort
   ikke længere med overskriften.
   Polstringen er derfor uændret (indholdskanten), og det er alene
   scroll-snap-align der flytter sig: start, center … center, end. Fordi
   scroll-padding er ens i begge sider, falder snapportens midte sammen
   med skærmens, og "center" betyder dermed midt på skærmen. */
@media (max-width: 767.98px) {
  .stories__rail .story-card { scroll-snap-align: center; }
  .stories__rail .story-card:first-child { scroll-snap-align: start; }
  .stories__rail .story-card:last-child { scroll-snap-align: end; }
}
.stories__rail.traekker { cursor: grabbing; scroll-behavior: auto; }
.stories__rail.traekker .story-card { cursor: grabbing; }
.stories__rail::-webkit-scrollbar { display: none; }
.story-card {
  scroll-snap-align: start;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-media);
  /* Samme streg som prøvetime-bjælken (.nextbar), som de øvrige medier.
     Bunden er mørk som .reel-thumb: den lyse pladsholder-grå der lå her
     før, skinnede igennem den halvgennemsigtige streg og gjorde kanten
     tydeligere end på billederne. */
  border: 1px solid var(--rule);
  background: var(--plum-800);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 1.1rem;
  color: var(--white);
}
.story-card .mono { color: color-mix(in srgb, var(--white) 70%, transparent); }
.story-card b { font-weight: 600; font-size: 0.9375rem; }

/* ==========================================================================
   8. STATISTIK + 9. MOSAIK (lys)
   ========================================================================== */

/* ==========================================================================
   10. PRAKTISK (lys)
   ========================================================================== */

/* ==========================================================================
   11. SIDSTE CTA (mørk)
   ========================================================================== */
.s-final { padding-block: var(--section-lg); text-align: center; position: relative; overflow: hidden; }
/* Samme grad som heroens H1: siden åbner og lukker med samme stemme. */
.s-final h2 { font-size: var(--fs-h1); max-width: 12ch; margin-inline: auto; }
.s-final .lead { margin: 1.75rem auto 0; color: var(--mist); }
.s-final .actions { margin-top: 2.5rem; display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
.s-final .openmat { margin-top: 1.5rem; }
.s-final .openmat .mono { color: var(--volt); }
.s-final__mark {
  /* -5% og ikke -10%: B'et blødte 135px ud over venstre kant ved 1440 og
     blev hugget af sektionens overflow. Halvdelen af overhænget er trukket
     ind, så mere af monogrammet står på siden. */
  position: absolute; left: -5%; top: 50%; transform: translateY(-50%);
  /* Samme token som heroens B frem for en kopi af tallene. De to stod med
     hver sin identiske clamp, og de skal følges ad. */
  width: var(--mark-w); opacity: 0.08; pointer-events: none;
}

/* ==========================================================================
   COLLAGEN (Mere end et gym)
   Ligger INDE i sektionen, under teksten, og erstatter billedbåndet fra
   hallen (2026-09-14 — båndet ligger i git-historikken). Kortenes plads,
   størrelse og bevægelse sættes af main.js; her står rammen.

   Desktop: sporet er --laengde skærme højt (plus det, gitteret er højere
   end skærmen), og scenen står fast imens. Tablet og mobil (data-fast="0"):
   ingen fastlåsning — scenen er præcis så høj som gitteret og ruller forbi
   som alt andet. Uden JS vises collagen ikke: den er pynt, og kortene har
   ingen plads uden main.js.
   ========================================================================== */
.collage {
  position: relative;
  height: calc(var(--laengde, 2) * 100vh + var(--ekstra, 0px));
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
}
.collage:not(.er-klar) { display: none; }
.collage__scene {
  position: sticky; top: 0; z-index: 1;
  width: 100%; height: 100vh;
  overflow: hidden;
}
.collage[data-fast="0"] { height: auto; }
.collage[data-fast="0"] .collage__scene { position: relative; height: var(--scenehoejde, 60vh); }
.collage__kort { position: absolute; inset: 0; z-index: 10; }
.collage__kort figure {
  position: absolute; left: 50%; top: 50%;
  margin: 0; overflow: hidden;
  /* Mørk bund: mangler et foto et øjeblik, ses et mørkt kort — ikke
     bunken igennem et tomt kort. */
  background: var(--plum-900);
  border-radius: var(--radius-media);
  will-change: transform;
}
.collage__kort figure[hidden] { display: none; }
.collage__kort figure > img:first-child,
.collage__kort video {
  display: block; width: 100%; height: 100%;
  object-fit: cover; pointer-events: none; -webkit-user-drag: none;
}
/* Sort/hvid lægges på her og ikke i filen: videoerne på Bunny bruges som de
   er (CLAUDE.md). Filteret rammer også poster-billedet før afspilning. */
.collage__kort video { filter: grayscale(1); }
/* B'et som vandmærke i Dias' højre hjørne — hvidt og let gennemsigtigt */
.collage__b {
  position: absolute; right: 5%; bottom: 7%;
  width: 13%; height: auto; opacity: 0.8;
  pointer-events: none;
}
.collage__hint {
  position: absolute; inset-inline: 0; bottom: 3vh; z-index: 20;
  display: grid; justify-items: center; gap: 0.5vh;
  color: var(--plum-900);
  font: 600 0.8rem/1 system-ui, sans-serif;
  text-transform: uppercase; letter-spacing: 0.2em;
  pointer-events: none;
}
.collage__hint svg { animation: collage-duk 1.8s ease-in-out infinite; }
.collage[data-fast="0"] .collage__hint { display: none; }
@keyframes collage-duk { 0%, 100% { transform: none; } 50% { transform: translateY(25%); } }
@media (prefers-reduced-motion: reduce) {
  .collage__hint { display: none; }
}

/* ==========================================================================
   KONTAKT (underside)
   ========================================================================== */
/* Samme top som trænersiden: undersider begynder under den faste header,
   og de to skal have samme stemme i toppen. */
.kontakt { padding-block: 10.5rem var(--section-md); }
.kontakt h1 { font-size: var(--fs-h2); max-width: 16ch; color: var(--bone); }
.kontakt .lead { max-width: 46ch; margin-top: 1.25rem; }

.kontakt__net {
  margin-top: 3.5rem;
  display: grid; gap: var(--grid-gap);
  /* Samme kolonneluft som medlemskabssektionen på info & priser */
  column-gap: clamp(var(--grid-gap), 8vw, 8rem);
}
@media (min-width: 900px) {
  .kontakt__net { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Kolonnerne byttet: Find os venstre, Skriv til os højre. Byttet her og
     ikke i DOM, så mobilrækkefølgen (skriv, find, tider) står urort —
     tider ligger sidst i DOM og dermed altid sidst på mobil. */
  .kontakt__skriv { grid-column: 2; grid-row: 1; }
  .kontaktkort--find { grid-column: 1; grid-row: 1; }
  .kontakt__tider { grid-column: 1; grid-row: 2; }
}

/* Skriv til os står DIREKTE på sektionen — kortrammen er væk. */
.kontakt__skriv { display: grid; align-content: start; gap: 1rem; }
.kontakt__skriv > p { color: var(--mist); max-width: 44ch; }
.kontakt__ilink { color: var(--bone); }
.kontakt__some { display: flex; gap: 1rem; margin-top: 0.25rem; }
.kontakt__some a {
  display: grid; place-items: center;
  width: 44px; height: 44px;             /* rimeligt trykmål */
  border-radius: 50%;
  /* Hvid fyldt cirkel med mærket i plum-900 — 18,97:1, ingen kant nødvendig */
  background: var(--white);
  color: var(--plum-900);
}
.kontakt__some svg { width: 20px; height: 20px; }

.kontaktkort {
  --kp: clamp(1.5rem, 3vw, 2.25rem);   /* kortets polstring — bruges af kortbilledets udfald */
  position: relative; overflow: hidden;
  display: grid; align-content: start; gap: 1rem;
  padding: var(--kp);
  border-radius: var(--radius-media);
}
/* Etiketterne er H2'er, og .mono slår h2-elementreglen på specificitet,
   så grad og skrift er etikettens egne. Hvid på den mørke sektion. */
.kontaktkort__eyebrow { color: var(--volt); text-transform: uppercase; letter-spacing: 0.06em; }

/* Mailen som knap: ghost-stilen — hvid kontur og tekst, intet fyld.
   Adressen kan blive lang på en smal skærm; knappen må aldrig sprænge. */
.kontakt__mailknap { justify-self: start; max-width: 100%; overflow-wrap: anywhere; }

/* Lokationsblokken: HVIDT kort — samme hvide som de lyse sektioners bund —
   med en konturtegning af kvarteret bag indholdet. Tekstfarverne er de
   lyse sektioners: overskrift plum-900, brød graphite. */
.kontaktkort--find {
  padding-bottom: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--bone);
}
.kontaktkort--find > p { color: var(--graphite); max-width: 40ch; }
/* Også volt på det hvide kort — 2,23:1 er for lavt til brødtekst, men
   etiketten er stor mono-versal og bærer ikke information alene; adressen
   under den er dataen. Bevidst valg efter ønske. */
.kontaktkort--find .kontaktkort__eyebrow { color: var(--volt); }
/* Billedet ligger bag indholdet i fuld flade på ALLE skærme. B-mærket
   sidder ved 51%/48% af kilden, og object-position er regnet så det står
   i kortets højre side: cover beskærer vandret, og en LAV X-procent
   skubber udsnittet mod kildens venstre kant — så peger den synlige del
   længere til højre, og B'et med den.
   Læseligheden bor i sløret, ikke i billedet. ::after ligger EFTER
   billedet i dokumentordenen og maler derfor over det, men under
   indholdet, som er løftet til z-index 1. */
.kontaktkort__kort {
  /* Kortet er BREDERE end billedets format, så cover beskærer lodret og
     object-position kan ikke flytte mærket vandret — der er intet vandret
     overskud at flytte i. Boksen forlænges derfor 45% ud over højre kant
     (kortets overflow klipper), så billedet skubbes mod højre og mærket
     lander centreret i kortets højre side. Målt: 74% vandret, 49% lodret
     ved 1440. */
  position: absolute; inset: 0 auto 0 0; z-index: 0;
  width: 145%; height: 100%; max-width: none;
  object-fit: cover; object-position: 50% 72%;
  pointer-events: none;
}
.kontaktkort--find::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  /* Fuldt dækkende bone langt ind i kortet, så etiketten og adressen står
     på ren lys bund — kortbilledet får kun den højre tredjedel. */
  background: linear-gradient(100deg,
    var(--bone) 34%,
    color-mix(in srgb, var(--bone) 92%, transparent) 52%,
    color-mix(in srgb, var(--bone) 40%, transparent) 72%,
    transparent 90%);
  pointer-events: none;
}
.kontaktkort--find > *:not(.kontaktkort__kort) { position: relative; z-index: 1; }
@media (max-width: 899.98px) {
  /* Mobil: kortet er LAVERE end billedets format, så cover viser hele
     billedhøjden og B-mærket ville stå fast i midten — object-position
     kan ikke flytte det op, når der intet lodret overskud er at flytte i.
     Boksen forlænges derfor opad: 138% højde med toppen løftet, så den
     nederste del beskæres og mærket lander i øverste tredjedel. 43%
     vandret stiller det i højre del. Sløret løber fra nederste venstre
     hjørne — teksten bor dér, og mærket står frit øverst til højre. */
  .kontaktkort__kort {
    inset: auto; left: 0; right: 0; top: -58%; width: 100%; height: 158%;
    object-position: 43% 50%;
  }
  .kontaktkort--find::after {
    background: linear-gradient(to top right,
      var(--bone) 42%,
      color-mix(in srgb, var(--bone) 92%, transparent) 60%,
      color-mix(in srgb, var(--bone) 40%, transparent) 78%,
      transparent 94%);
  }
}
.kontaktkort__adresse {
  font-style: normal;   /* address-elementet er kursivt som standard */
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.25rem);
  line-height: 0.9; text-transform: uppercase; color: var(--plum-900);
}
/* Sammensat vælger, ikke kun klassen: .kontaktkort--find > p farver alle
   afsnit graphite og slår en enkelt klasse på specificitet — adressen
   skal op i plum-900 som de lyse sektioners overskrifter. */
.kontaktkort--find > .kontaktkort__adresse { color: var(--plum-900); }
.kontaktkort--find .btn { justify-self: start; margin-top: 0.5rem; }

.kontakt__tider { margin-top: 0; align-self: start; color: var(--mist); }
.kontakt__tider a { color: var(--bone); }

/* ==========================================================================
   INFO & PRISER (underside) — mørk som de øvrige undersider; kun FAQ lys
   ========================================================================== */
.infopriser-top { padding-block: 10.5rem 0; }
/* Ingen ch-klemme: "Information og priser" er 21 tegn og skal stå på én
   linje når skærmen tillader det — på smalle skærme ombrydes den af sig selv. */
.infopriser-top h1 { font-size: var(--fs-h2); color: var(--bone); }
.infopriser-top .lead { max-width: 46ch; margin-top: 1.25rem; }

/* Medlemskab og praktisk i ÉN sektion: prisen til venstre, begge lister
   stablet til højre — halv højde i forhold til to fulde sektioner. */
/* Topluften er 3.5rem som kontaktsidens afstand fra brødtekst til nettet —
   de to sider skal have samme rytme fra H1-blokken ned til kortene. */
.infopriser-pris { padding-block: 3.5rem var(--section-lg); }   /* sidste sektion på siden nu */
/* Mere luft mellem kortet og praktisk-kolonnen end grid-gap'en giver.
   Lige store kolonner — symmetrisk med kontaktsidens net, ikke .split's
   6fr/4fr. Kun relevant over 991px; derunder stabler .split alligevel. */
.infopriser-pris .split {
  column-gap: clamp(var(--grid-gap), 8vw, 8rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 991.98px) {
  .infopriser-pris .split { grid-template-columns: 1fr; }
  /* Mobil: CTA'erne op under medlemskortet, FØR praktisk-listen. Kolonnen
     opløses med display: contents, så dens børn bliver grid-børn i .split
     og kan ordnes frit — DOM'en er urort af hensyn til desktop. */
  .infopriser-kol { display: contents; }
  .medlemskort-scene { order: 0; }
  .infopriser-kol .actions { order: 1; margin-top: 0; }
  .infopriser-kol .infopriser-etiket { order: 2; margin-top: 1rem; }
  .infopriser-kol ul { order: 3; margin-top: 0; }
}
.infopriser-pris .price {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(3rem, 2.2rem + 2.5vw, 4.75rem); line-height: 0.9;
  color: var(--bone);
}
.infopriser-pris .price small {
  /* På linje med prisen, ikke under den — hængt på grundlinjen */
  font-family: var(--font-mono);
  font-size: var(--fs-meta); letter-spacing: 0.06em; color: var(--mist);
  margin-left: 0.5rem;
}

/* Medlemskortet: sidens glassprog (som quizkortet), med en volt-hårlinje
   øverst som det ene accentgreb og konturmærket som vandmærke. */
/* Scenen bærer perspektivet, kortet hælder inde i den. Perspektivet SKAL
   sidde på forælderen — på elementet selv ville rotationen blive flad. */
.medlemskort-scene { position: relative; perspective: 1100px; align-self: start; }
.medlemskort__skygge {
  position: absolute; bottom: -26px; left: 8%; right: 8%; height: 2.75rem;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%,
    color-mix(in srgb, var(--plum-900) 65%, transparent), transparent 70%);
  opacity: 0.75; pointer-events: none; will-change: transform;
}
.medlemskort__hint {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}
.medlemskort:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }
.medlemskort {
  --hx: 0.5; --hy: 0.5;      /* lyspunkt, 0–1, sættes af main.js */
  --hue: 0;                  /* forlæggets hue-signal — lagt på kilernes drejning */
  --glans-o: 0.35;           /* glansen tager til med hældningen */
  touch-action: pan-y;       /* forlægget siger none; på en rigtig side skal lodret scroll overleve */
  position: relative; overflow: hidden;
  display: grid; align-content: start; gap: 1.5rem;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  /* Kortbunden som mørkt "materiale" — langs brandrampen */
  background: linear-gradient(145deg,
    color-mix(in srgb, var(--plum-800) 92%, transparent),
    color-mix(in srgb, var(--plum-900) 88%, transparent) 55%,
    color-mix(in srgb, var(--plum-800) 92%, transparent));
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-radius: var(--radius-media);
  will-change: transform;
}
.medlemskort__etiket { color: var(--volt); }
/* Grid-gap'en på 1.5rem er luft nok — den generelle ul-margin nulstilles.
   Sektionsklassen med i selektoren: .infopriser-pris ul står SENERE i
   filen og ville ellers vinde på ens specificitet. */
.infopriser-pris .medlemskort > ul { margin-top: 0; padding-top: 0; }
.medlemskort .infopriser-vilkaar { margin-top: 0; }
/* B'et er nu forsidens CTA-mærke: de udfyldte flader, hvide. Det bløder ud
   over kortets højre og nederste kant og klippes af overflow: hidden. */
.medlemskort__maerke {
  position: absolute; right: -5%; bottom: -14%;   /* rykket ind, men bløder stadig lidt over højre kant */
  width: clamp(150px, 48%, 250px);
  opacity: 0.09; pointer-events: none;
}

/* Holo-foliet: ÉN farve — volt. Iriseringen kommer af lysstyrke, ikke af
   kulør: volt veksler med rent hvidt og med kortets egne mørke plum-toner.
   Ingen hue-rotate: den ville per definition dreje volt væk fra #1FBEDA. */
.medlemskort__folie,
.medlemskort__glans,
.medlemskort__kant {
  position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none;
}
.medlemskort__folie {
  background:
    repeating-linear-gradient(115deg,
      color-mix(in srgb, var(--white) 6%, transparent) 0 1px, transparent 1px 5px),
    /* Forlæggets spectral-løb én til én — ACCENT→plum-500, CYAN→volt,
       mint = volt 52% hvid, deep = plum-500 78% sort: samme opskrift, kun
       de tilladte kulører. --hue er forlæggets hue-signal, men drejer
       kilerne i stedet for at hue-rotere — hue-rotate ville per definition
       skabe andre blå end #1FBEDA. */
    conic-gradient(from calc(210deg + var(--hue, 0) * 1deg)
      at calc(var(--hx) * 100%) calc(var(--hy) * 100%),
      var(--plum-500) 0deg,
      var(--volt) 90deg,
      color-mix(in srgb, var(--volt) 52%, var(--white)) 160deg,
      var(--plum-500) 230deg,
      color-mix(in srgb, var(--plum-500) 78%, #000000) 300deg,
      var(--plum-500) 360deg);
  /* screen, IKKE forlæggets color-dodge: dodge dividerer bunden med
     (1 − kilde) og fabrikerer marineblå af volt over plum. */
  mix-blend-mode: screen;
  opacity: 0.32;
}
.medlemskort__glans {
  background: radial-gradient(200px circle
    at calc(var(--hx) * 100%) calc(var(--hy) * 100%),
    color-mix(in srgb, var(--white) 50%, transparent), transparent 65%);
  mix-blend-mode: screen;
  opacity: var(--glans-o, 0.35);
}
/* Kanten følger lyset. En border-farve kan ikke tage en gradient, så ringen
   er et 1px-lag, hvor midten maskeres væk: to masker lagt over hinanden,
   den ene begrænset til content-box, og xor efterlader netop rammen.
   Grundtonen er --rule hele vejen rundt, så kanten aldrig forsvinder. */
.medlemskort__kant {
  padding: 1px;
  background:
    radial-gradient(140% 120% at calc(var(--hx) * 100%) calc(var(--hy) * 100%),
      color-mix(in srgb, var(--volt) 62%, transparent) 0%,
      color-mix(in srgb, var(--white) 22%, transparent) 26%,
      transparent 62%),
    var(--rule);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
/* Indholdet skal ligge over foliet men under glans og kant. Mærket undtages —
   det skal blive i sit absolutte hjørne og ikke trækkes ind i grid-flowet. */
.medlemskort > *:not(.medlemskort__folie):not(.medlemskort__glans):not(.medlemskort__kant):not(.medlemskort__maerke) { position: relative; }
@media (forced-colors: active) {
  .medlemskort__folie, .medlemskort__glans, .medlemskort__kant, .medlemskort__skygge { display: none; }
}

.infopriser-vilkaar { font-size: var(--fs-small); position: relative; }
.infopriser-vilkaar a { color: var(--mist); }

.infopriser-kol { align-content: start; }
.infopriser-etiket { color: var(--volt); }
.infopriser-kol .actions { margin-top: 2rem; display: flex; gap: 1rem; flex-wrap: wrap; }
.infopriser-pris ul { list-style: none; display: grid; gap: 0.6rem; margin-top: 1.5rem; }
.infopriser-pris ul li {
  display: flex; gap: 0.75rem; align-items: baseline;
  font-size: var(--fs-small); color: var(--bone); line-height: 1.6;
}
.infopriser-pris ul li::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--volt); flex: none; transform: translateY(-2px);
}
.infopriser-pris ul a { color: var(--white); }

/* FAQ: native details/summary — ingen JS at fejle på. Markøren er vores
   egen (+/−), browserens trekant slås fra begge steder den kan optræde. */

.faq { margin-top: 2.5rem; display: grid; border-top: 1px solid var(--ash); }
.faq__punkt { border-bottom: 1px solid var(--ash); }
.faq__punkt summary {
  list-style: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem;
  padding: 1.15rem 0;
  font-weight: 600; color: var(--plum-900);
}
.faq__punkt summary::-webkit-details-marker { display: none; }
.faq__punkt summary::after {
  content: "+";
  font-family: var(--font-mono); font-size: 1.1rem; line-height: 1;
  color: var(--plum-900); flex: none;
}
.faq__punkt[open] summary::after { content: "−"; }
.faq__punkt > p {
  padding: 0 0 1.25rem; max-width: 60ch;
  color: var(--graphite); font-size: var(--fs-small); line-height: 1.7;
}
.faq__punkt > p a { color: var(--plum-900); }

/* ==========================================================================
   HOLDOVERSIGT & TIDER (underside)
   Forsidens skema-struktur på mørk bund, i disciplinkortenes sprog:
   border-top-linjer, display-dagnavne, og dagens kolonne får disciplin-
   lysets bloom/kerne (samme keyframes, disc-bloom/disc-kerne).
   ========================================================================== */
.holdtider-top { padding-block: 10.5rem 0; }
.holdtider-top h1 { font-size: var(--fs-h2); color: var(--bone); }
.holdtider-top .lead { max-width: 46ch; margin-top: 1.25rem; }

.holdtider { padding-block: 3.5rem var(--section-md); }

/* Filtrene: sticky lige under eventstriben, så de er ved hånden når man
   ruller i skemaet. Glasbund så skemaet kan ses glide under dem. */
.holdtider-filtre {
  position: sticky; top: calc(var(--stribe-h) + 0.75rem); z-index: 5;
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin-bottom: 2.5rem;
}
.filterpille {
  font-family: var(--font-mono); font-size: 0.6875rem;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--mist);
  background: color-mix(in srgb, var(--plum-900) 72%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--rule); border-radius: 999px;
  padding: 0.5rem 0.9rem; cursor: pointer;
  transition: color var(--dur-ui) var(--ease-ui), border-color var(--dur-ui) var(--ease-ui);
}
/* Valgt-tilstanden er trænervælgerens lys, ikke en farveskift: hvid rand
   tæt på pillen og plum-bloom med et strejf volt udenom, der ånder i de
   samme to takter som miniaturerne (3,4 og 5,1 s). Teksten løftes blot
   til bone. Lyset ligger i box-shadow på to pseudolag — pillen er en
   afrundet rekt, så ringens cirkulære gradienter kan ikke genbruges
   direkte, men farvestakken er den samme. */
.filterpille { position: relative; }
.filterpille.is-valgt { color: var(--bone); border-color: var(--rule-strong); }
.filterpille::before,
.filterpille::after {
  content: ""; position: absolute; inset: 0; border-radius: 999px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.5s var(--ease-ui);
}
.filterpille::before {
  box-shadow:
    0 0 14px color-mix(in srgb, var(--plum-500) 55%, transparent),
    0 0 34px color-mix(in srgb, var(--plum-500) 30%, transparent),
    0 0 60px color-mix(in srgb, var(--volt) 16%, transparent);
}
.filterpille::after {
  box-shadow:
    0 0 0 1.5px color-mix(in srgb, var(--white) 74%, transparent),
    0 0 10px color-mix(in srgb, var(--plum-500) 44%, transparent);
}
/* 0.41 = 0.68 dæmpet 40 % (Alberts valg 2026-09-12) — styrken sidder på
   laget, så gradientens kurve er uændret. */
.filterpille.is-valgt::before { opacity: 0.41; animation: pille-bloom 5.1s ease-in-out infinite; }
.filterpille.is-valgt::after { opacity: 0.41; animation: pille-kerne 3.4s ease-in-out infinite; }
@keyframes pille-bloom { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes pille-kerne { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.02); } }
@media (prefers-reduced-motion: reduce) {
  .filterpille::before, .filterpille::after { animation: none !important; }
}
.filterpille:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }

/* Kolonnerne: disciplinkortets anatomi i stedet for det lyse hairline-net */
.holdtider .schedule__grid { border-block: 0; column-gap: 1.25rem; }
.holdtider .schedule__day {
  position: relative;
  border-left: 0; border-top: 1px solid var(--rule-strong);
  padding: 1.75rem 0 1rem;
}
.holdtider .schedule__day:last-child { border-right: 0; }
.holdtider .schedule__day.is-today { background: transparent; }
.holdtider .schedule__dayname {
  font-family: var(--font-display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.4rem, 1rem + 1.1vw, 2rem); letter-spacing: 0;
  color: var(--bone); margin-bottom: 1rem;
}
/* Dagens navn er som de andres — ordet "I dag" ER markeringen.
   Grundskemaets .is-today-regel (volt-deep, til lys bund) står senere i
   filen og skal slås eksplicit, og prikken er overflødig ved siden af
   ordet. */
.holdtider .is-today .schedule__dayname { color: var(--bone); }
.holdtider .is-today .schedule__dayname::before { display: none; }
.holdtider .schedule__idag { color: var(--volt); }

/* Dagens kolonne har INGEN lyseffekt (Alberts valg 2026-09-12): dagen
   siges med ordet "I dag" i volt ved siden af dagsnavnet i stedet. Lyset
   var de samme to lag som disciplinkortene — bloom i plum-500 og en
   næsten hvid kerne — begge med evige keyframes; de ligger i
   git-historikken, hvis udtrykket skal tilbage. */

/* Holdene på mørk bund */
.holdtider .schedule__item { border-top-color: var(--rule); }
.holdtider .schedule__item .mono { color: var(--mist); opacity: 1; }
.holdtider .schedule__item b { color: var(--bone); }
.holdtider .tag { border-color: var(--rule); color: var(--mist); }
/* Intro-pillen på mørk bund: samme stille sprog som Øvede/Invite only —
   forsidens fyldte plum-udgave ville drukne i sektionens egen bund. */
.holdtider .tag--intro { background: transparent; border-color: var(--rule); color: var(--mist); }
.holdtider .schedule__item.er-skjult { display: none; }
.schedule__tom {
  display: none; padding-block: 0.65rem;
  border-top: 1px solid var(--rule);
  color: var(--mist); font-size: var(--fs-small);
}
.holdtider .uden-hold .schedule__tom { display: block; }

/* Swipe-fade og hint på mørk bund */
.holdtider .schedule__scroll::after { background: linear-gradient(90deg, transparent, var(--plum-900)); }

.holdtider-note { margin-top: 2rem; color: var(--mist); font-size: var(--fs-small); max-width: 60ch; }

/* FAQ'en på lys bund — genbruger .faq-mekanikken fra info & priser-tiden */
.holdtider-faq, .forside-faq { padding-block: var(--section-md); }

/* ==========================================================================
   FOOTER
   ========================================================================== */
.site-footer {
  /* Samme mørke lilla som nyhedsetiketten — mørkere end .s-dark, som
     footeren ellers ville arve sin bund fra. Reglen står efter .s-dark og
     vinder derfor på rækkefølgen. */
  background: var(--plum-950);
  padding-block: var(--section-sm) 7rem; /* plads til nextbar */
  /* Bone frem for mist: 15,9:1 mod 6,25:1. Samme grad som før. */
  font-size: var(--fs-small); color: var(--bone);
}
.site-footer .cols {
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--grid-gap);
}
@media (max-width: 860px) { .site-footer .cols { grid-template-columns: 1fr 1fr; row-gap: 2.5rem; } }
/* Samme grad og skrift som disciplin-kortenes overskrifter */
.site-footer h4 {
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  font-size: clamp(1.75rem, 1.4rem + 1.75vw, 3rem);
  line-height: 0.9; letter-spacing: 0.01em;
  text-transform: uppercase; color: var(--bone);
  margin-bottom: 1rem;
}
/* Ingen hover på footerens links: de skal ikke skifte farve */
.site-footer a { color: var(--bone); text-decoration: none; }
.site-footer ul { list-style: none; display: grid; gap: 0.6rem; }
/* Logoet i footeren deler klasse med headerens, og headerens regler
   (polstring til pillen, gitterfelt, foldning på små skærme) gælder derfor
   også her — det var derfor mærket stod forskudt fra teksten under det.
   Alt det nulstilles, så det flugter med kolonnens venstre kant. */
.site-footer .brand {
  padding: 0; margin-bottom: 1rem;
  grid-row: auto; grid-column: auto; justify-self: start;
}
.site-footer .brand span { display: block; max-width: none; opacity: 1; margin-left: 0; }
/* Bureauets mærke: lige over stregen, i venstre side. Ordmærket i mono som
   den juridiske linje, logoet i samme farve som teksten. */
.site-footer .lavet-af {
  display: inline-flex; align-items: center; gap: 0.6rem;
  margin-top: 3rem; margin-bottom: 1rem;
  color: var(--bone);
}
.site-footer .lavet-af .mono { font-size: 0.6875rem; letter-spacing: 0.06em; }
/* Svane + ordmærke er 1000×335, altså tre gange så bredt som højt.
   Logoet står sort på en hvid pille, som på zivo.dk: footerens bund er
   næsten sort, så svanen forsvandt uden en lys flade bag sig. Inline SVG
   med svane og ordmærke i hver sin gruppe, begge i logoets egen sorte.
   Ingen hover på hele linket. */
.site-footer .zivo-logo {
  display: block; box-sizing: content-box;
  width: 3.1rem; height: 1.04rem;
  padding: 0.3rem 0.6rem;
  background: var(--white);
  border-radius: var(--radius-control);
}
.site-footer .zivo-logo__svane,
.site-footer .zivo-logo__ord { fill: #0F0D0E; }
.site-footer .legal { margin-top: 0; padding-top: 1.5rem; border-top: 1px solid var(--rule); font-family: var(--font-mono); font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase; }

/* ==========================================================================
   TRÆNERE (/traenere/)
   Uden JS er det en almindelig liste: alle elleve står under hinanden,
   læsbare og indekserbare. main.js sætter .er-vaelger og gør den til en
   vælger hvor én vises ad gangen.

   De inaktive fjernes IKKE fra dokumentet — de stables i samme gittercelle
   og skjules med opacity og visibility. Teksten bliver dermed stående i
   siden, hvilket både er ærligt over for søgemaskiner og gør at højden
   ikke hopper. Højden bæres af portrættet, ikke af teksten: 4:5 er højere
   end selv den længste biografi i sin spalte.
   ========================================================================== */
/* Undersider begynder i toppen af dokumentet, hvor den FASTE header
   ligger oven på. Forsiden har ikke problemet: heroen fylder skærmen og
   headeren svæver gennemsigtigt hen over den.

   Toppen er sat DIREKTE og ikke som --section-md plus et tillæg. Den
   sektionsværdi vokser fra 80 til 133px, mens headeren kun vokser fra
   104 til 115 — lagde man et voksende tillæg oveni, blev luften dobbelt
   så stor på desktop som på mobil. Et fast tal holder de to ender tæt
   sammen: 53px luft under headeren ved 1440 og 64px ved 375. Målt begge
   steder med headeren udfoldet og scroll i nul. */
/* overflow-x: clip fordi lyset bag den yderste avatar rækker ~51px ud fra
   cirklen og dermed forbi sidens kant — det gav 26px vandret rullebredde på
   mobil. clip og ikke hidden: hidden ville tvinge den anden akse til at
   blive en rulleboks, og så ville lyset også blive skåret opad og nedad.
   Ved kanten er gløden nede omkring 5%, så snittet kan ikke ses. */
.traenere { padding-block: 10.5rem var(--section-md); overflow-x: clip; }
/* Samme grad som forsidens H1, der også kører på --fs-h2 og ikke --fs-h1:
   de to sider skal have samme stemme i toppen. */
.traenere h1 { font-size: var(--fs-h2); max-width: 16ch; color: var(--bone); }
.traenere .lead { max-width: 46ch; margin-top: 1.25rem; }
.traenere__vaelger { margin-top: 3.5rem; }
.traenere__liste { list-style: none; display: grid; gap: var(--section-sm); }

/* align-content: start er ikke pynt. Kortene ligger stablet i samme
   gittercelle (se .er-vaelger nedenfor), så kortet bliver lige så højt som
   det HØJESTE kort. Med normal/stretch fordeles overskuddet ud i de auto-
   høje rækker — på mobil lagde det 166px tom plads mellem billedet og
   brødteksten. */
.traener { display: grid; gap: var(--grid-gap); align-content: start; }
@media (min-width: 768px) {
  .traener { grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); align-items: start; }
}
.traener__foto { position: relative; }
/* Blinket når en træner vælges: miniaturernes lys — hvid rand, plum-bloom
   og et strejf volt yderst — oversat til fotoets rektangel og spillet én
   gang. Lyset ligger i box-shadow på et pseudolag, så selve billedet ikke
   røres, og laget er der kun mens .blinker står på. */
.traener__foto::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  border-radius: var(--radius-media);
  opacity: 0; pointer-events: none;
  box-shadow:
    0 0 0 1.5px color-mix(in srgb, var(--white) 74%, transparent),
    0 0 18px color-mix(in srgb, var(--plum-500) 60%, transparent),
    0 0 44px color-mix(in srgb, var(--plum-500) 35%, transparent),
    0 0 84px color-mix(in srgb, var(--volt) 18%, transparent);
}
.traener__foto.blinker::after { animation: traener-blink 0.65s var(--ease-ui); }
@keyframes traener-blink {
  0%   { opacity: 0; }
  22%  { opacity: 1; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .traener__foto.blinker::after { animation: none; }
}
/* Afspilningsknappen dækker hele fotoet; selve play-mærket genbruges fra
   reel-miniaturerne. Knappen er usynlig i sig selv — fotoet ER knappen. */
.traener__spil {
  position: absolute; inset: 0; width: 100%;
  background: none; border: 0; cursor: pointer;
  border-radius: inherit;
}
.traener__spil:focus-visible { outline: 2px solid var(--volt); outline-offset: 2px; }
/* SoMe under navnet: samme hvide cirkler som på kontaktsiden, bare mindre */
.traener__some { display: flex; gap: 0.6rem; }
.traener__some a {
  display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--white); color: var(--plum-900);
}
.traener__some svg { width: 17px; height: 17px; }
/* Spil-mærket på miniaturerne: lille udgave af reel-play-mærket, i
   ringens nederste højre hjørne — udenfor selve cirklens beskaering. */
.traenere__ring { position: relative; }
.traenere__spilmaerke {
  position: absolute; right: -2px; bottom: -2px; z-index: 1;
  width: 20px; height: 20px; border-radius: 50%;
  background: color-mix(in srgb, var(--plum-900) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--white) 35%, transparent);
}
.traenere__spilmaerke::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 0; height: 0; transform: translateX(1px);
  border-style: solid; border-width: 4px 0 4px 7px;
  border-color: transparent transparent transparent var(--white);
}
.traener__foto img, .traener__foto .ph {
  /* height: auto skal med: billedets height-attribut låser ellers den
     anden akse, og så bliver aspect-ratio ignoreret. */
  width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: var(--radius-media); display: block;
  /* Samme streg som prøvetime-bjælken (.nextbar) og sidens øvrige medier */
  border: 1px solid var(--rule);
}
.traener__foto .ph {
  background: color-mix(in srgb, var(--white) 6%, transparent);
}
.traener__info { display: grid; align-content: start; gap: 0.75rem; }
.traener__felt { color: var(--volt); }
.traener__navn {
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  font-size: clamp(2.25rem, 1.6rem + 3.2vw, 4rem);
  line-height: 0.9; text-transform: uppercase; color: var(--bone);
}
.traener__bio { color: var(--mist); max-width: 46ch; }

/* ---- Med JS: vælger ---- */
/* Større afstand NEDAD end til siden: på mobil står vælgeren og portrættet
   over hinanden, og med kun 24px imellem løb miniaturegitteret og det store
   billede sammen til én blok. Sidelæns (fra 900px) er 24px det rigtige. */
.traenere__vaelger.er-vaelger {
  display: grid; row-gap: 2.5rem; column-gap: var(--grid-gap);
}
@media (min-width: 900px) {
  /* Skinnen er smallere igen, efter at miniaturerne blev små runde. Med en
     tredjedel af bredden stod seks 61px cirkler spredt ud over 429px med
     182px tomt under sig, mens portrættet var klemt. En fjerdedel giver
     fire cirkler i bredden, en tættere blok — og et større portræt. */
  .traenere__vaelger.er-vaelger {
    grid-template-columns: minmax(0, 3fr) minmax(0, 9fr);
  }
}
.er-vaelger .traenere__liste { display: grid; gap: 0; }
.er-vaelger .traenere__liste { position: relative; }
/* De skjulte kort tages UD af flowet. Blev de stående, ville listen have
   det højeste korts højde, og et kort med kort biografi ville slæbe et par
   hundrede pixels tom plads efter sig. Det viste kort bliver i flowet og
   bestemmer alene højden; de øvrige lægger sig oven på det, hvilket er
   præcis hvad overblændingen skal bruge. */
.er-vaelger .traener {
  position: absolute; top: 0; left: 0; width: 100%;
  opacity: 0; visibility: hidden;
  transition: opacity 0.45s var(--ease-out), visibility 0s linear 0.45s;
}
.er-vaelger .traener.er-fremme {
  position: relative;
  opacity: 1; visibility: visible;
  transition: opacity 0.45s var(--ease-out), visibility 0s;
}

/* PRIKKERNE under det fremhævede portræt (mobil): én pr. træner, den viste
   i volt. Samme udtryk som prikkerne under reels. Der er kun ét sæt, og
   main.js flytter det ind under portrættet på den træner der vises. Fra
   900px står miniaturerne ved siden af portrættet, og der er de overflødige. */
.traenere__prikker {
  display: flex; justify-content: center; flex-wrap: wrap; gap: 0.55rem;
  margin-top: -0.5rem;
}
@media (min-width: 900px) { .traenere__prikker { display: none; } }
.traenere__prik, .schedule__prik {
  position: relative;
  width: 6px; height: 6px; border-radius: 50%;
  padding: 0; border: 0; cursor: pointer;
  background: color-mix(in srgb, var(--white) 26%, transparent);
  transition: background var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-ui);
}
.traenere__prik::after, .schedule__prik::after { content: ""; position: absolute; inset: -7px; }
.traenere__prik[aria-current="true"],
.schedule__prik[aria-current="true"] { background: var(--volt); transform: scale(1.3); }
.schedule__prik:focus-visible { outline: 2px solid var(--volt); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) { .traenere__prik, .schedule__prik { transition: none; } }

/* Ugeskemaets prikker: én pr. dag, kun hvor skemaet er en swipe-rail */
.schedule__prikker { display: flex; justify-content: center; gap: 0.55rem; margin-top: 1rem; }
@media (min-width: 1201px) { .schedule__prikker { display: none; } }

/* Skinnen: tæller, miniaturer og de to knapper */
/* Skinnen står først — også på mobil. Der er det miniaturerne man vælger
   i, og så ruller man ned og læser om den valgte. Lå de under portrættet,
   skulle man forbi hele biografien for at finde vælgeren. */
.traenere__skinne { display: grid; align-content: start; gap: 1.5rem; }
/* Miniaturerne er runde og små: de skal kunne overskues på ét blik, ikke
   konkurrere med portrættet. Navnet står UNDER cirklen frem for hen over
   ansigtet — der er ikke plads til et fald på en 64px cirkel.
   auto-fit frem for et fast spalteantal: så lægger de sig af sig selv med
   fire i bredden på mobil og seks i skinnen på desktop. */
.traenere__mini {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(3.75rem, 1fr));
  gap: 1.5rem 0.75rem;
}
/* Fire i bredden hele vejen op til to-spaltet layout. auto-fit alene gav
   fem spalter på de bredere telefoner og helt op til ti på tablet — og
   dermed en efterladt række med én. Loftet på bredden holder cirklerne
   samlet, når der er mere plads end fire kolonner kræver; gitteret bliver
   stående til venstre som resten af sektionens tekst. */
@media (max-width: 899.98px) {
  .traenere__mini {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    max-width: 26rem;
  }
}
.traenere__mini button {
  display: grid; justify-items: center; gap: 0.5rem;
  padding: 0; border: 0; background: none; cursor: pointer;
  position: relative;
  /* align-content: start, ellers strækkes cirklen. Knapperne i en række er
     lige høje efter den med det længste navn, og standardværdien stretch
     fordeler den ekstra højde ud i begge rækker — så blev en 61px cirkel
     67px høj og dermed oval. Samme fælde som på selve trænerkortet. */
  align-content: start;
}
/* Den valgte løftes op i stakken, så dens lys lægger sig OVEN på naboerne
   i stedet for at blive skåret af dem. Det er sådan lysspild opfører sig. */
.traenere__mini button[aria-current="true"] { z-index: 1; }

.traenere__ring {
  position: relative; display: block;
  width: 100%; max-width: 4rem;
}
.traenere__ring img,
.traenere__ring.er-tom {
  display: block; width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: 50%; border: 1px solid var(--rule);
  position: relative; z-index: 1;             /* over lyset i ::before/::after */
  opacity: 0.5;
  transition: opacity var(--dur-ui) var(--ease-ui), border-color var(--dur-ui) var(--ease-ui);
}
.traenere__ring.er-tom { background: color-mix(in srgb, var(--white) 6%, transparent); }

/* LYSET BAG DEN VALGTE
   Samme lyskilde som disciplinkortene, bare lagt om en cirkel i stedet for
   en streg. Faldet er det samme — 1/(1 + d·a) — så over halvdelen af
   styrken er væk kort efter kanten og resten er en lang, svag hale.

   Forskellen er hvor man ser den. På disciplinkortet ligger den hvide
   kerne frit; her er den dækket af portrættet, så det synlige er halen
   uden om cirklen. Derfor er stoppene skudt ud, så de begynder præcis
   ved kanten: kernelaget er 150% af cirklen, hvilket sætter kanten på 67%
   af lagets radius, og bloomet er 260%, hvilket sætter den på 38%. */
.traenere__ring::before,
.traenere__ring::after {
  content: ""; position: absolute; z-index: 0;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  border-radius: 50%; opacity: 0; pointer-events: none;
  transition: opacity 0.5s var(--ease-ui);
}
.traenere__ring::before {
  width: 260%; height: 260%;
  background:
    radial-gradient(closest-side,
      transparent 36%,
      color-mix(in srgb, var(--volt) 13%, transparent) 40%,
      color-mix(in srgb, var(--volt)  4%, transparent) 58%,
      transparent 80%),
    radial-gradient(closest-side,
      transparent 36%,
      color-mix(in srgb, var(--plum-500) 46%, transparent) 39%,
      color-mix(in srgb, var(--plum-500) 26%, transparent) 44%,
      color-mix(in srgb, var(--plum-500) 17%, transparent) 51%,
      color-mix(in srgb, var(--plum-500) 10%, transparent) 61%,
      color-mix(in srgb, var(--plum-500)  5%, transparent) 76%,
      transparent 93%);
}
.traenere__ring::after {
  width: 150%; height: 150%;
  background: radial-gradient(closest-side,
    transparent 64%,
    color-mix(in srgb, var(--white) 74%, transparent) 67%,
    color-mix(in srgb, var(--white) 34%, transparent) 71%,
    color-mix(in srgb, var(--plum-500) 44%, transparent) 79%,
    color-mix(in srgb, var(--plum-500) 14%, transparent) 88%,
    transparent 99%);
}
/* Samme to takter som disciplinkortene, 3,4 og 5,1 sekunder, der ikke går
   op i hinanden. translate skal med i hver keyframe — ellers tager
   animationen centreringen med sig. */
@keyframes traener-bloom {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.09); }
}
@keyframes traener-kerne {
  0%, 100% { transform: translate(-50%, -50%) scale(1); }
  50%      { transform: translate(-50%, -50%) scale(1.05); }
}
/* Styrken skrues ned på selve laget frem for i farvestoppene, så kurven i
   gradienten bliver præcis som disciplinkortenes — kun dæmpet. Det er
   samme greb som opacity på et lysdæmp.
   0.34 = halvdelen af de oprindelige 0.68: 50 % mindre tydeligt
   (Alberts valg 2026-09-12). */
.traenere__mini button[aria-current="true"] .traenere__ring::before,
.traenere__mini button[aria-current="true"] .traenere__ring::after { opacity: 0.34; }
.traenere__mini button[aria-current="true"] .traenere__ring::before {
  animation: traener-bloom 5.1s ease-in-out infinite;
}
.traenere__mini button[aria-current="true"] .traenere__ring::after {
  animation: traener-kerne 3.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .traenere__ring::before, .traenere__ring::after { animation: none !important; }
}

/* Navnet dæmpes IKKE sammen med billedet. Det er hele pointen med at flytte
   det ned under cirklen, at man kan læse hvem der er hvem uden at vælge. */
.traenere__mini b {
  font-family: var(--font-mono); font-weight: 400;
  font-size: 0.625rem; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--mist); text-align: center; line-height: 1.2;
  position: relative; z-index: 1;
}
/* Ingen cyan kant på den valgte. Lyset bag cirklen siger allerede hvem der
   er valgt, og to markeringer om det samme trækker i hver sin retning. */
.traenere__mini button[aria-current="true"] .traenere__ring img,
.traenere__mini button[aria-current="true"] .traenere__ring.er-tom {
  opacity: 1;
}
.traenere__mini button[aria-current="true"] b { color: var(--white); }

/* ==========================================================================
   REVEALS (§6.1) — IntersectionObserver sætter .in
   ========================================================================== */
.reveal {
  opacity: 0; transform: translateY(24px);
  transition: opacity var(--dur-reveal) var(--ease-out), transform var(--dur-reveal) var(--ease-out);
  transition-delay: calc(var(--stagger, 0) * 0.08s);
}
.reveal.in { opacity: 1; transform: none; }

/* ==========================================================================
   REDUCERET BEVÆGELSE (§6.3) — ikke valgfrit
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   POLISH — filmkorn, linjeværk, micro-interactions
   ========================================================================== */

/* Selection og scrollbar hører til paletten */
::selection { background: var(--volt); color: var(--plum-900); }
.s-light ::selection { background: var(--plum-900); color: var(--white); }
/* Rulleskinnen: browserens egen — ingen farve-overstyring. Den gamle
   plum-regel er bevidst fjernet, så skinnen følger platformens standard. */

/* Asfalt-tekstur (Higgsfield) — sidens gennemgående råhed.
   screen-blend lægger kun stenenes lysglimt på fladen og mørkner aldrig,
   så den virker ens over video, plum og volt. */

/* Linjeværk (§3.5): logoets foldekanter som dekorativt baggrundselement */
.linework {
  position: absolute; inset: 0; pointer-events: none;
  opacity: 0.16; overflow: hidden;
}
.linework line { stroke-width: 1.5; }

/* Story-cards: lys bagved ved hover. Kortet klipper sit indhold
   (overflow: hidden, for videoens hjørner), så lyset kan ikke være et
   barn af det — men en box-shadow klippes ikke af elementets eget
   overflow. Samme toner som "LYSET UNDER STREGEN": en tynd hvid kant,
   plum-500 tæt på, en bred plum-hale og et strejf volt yderst. */
.story-card {
  transition: transform var(--dur-ui) var(--ease-ui), border-color var(--dur-ui) var(--ease-ui);
  cursor: pointer;
}
/* Lyset ved hover er fjernet (2026-09-14): reels-kortene får kun previewet.
   Det var fire box-shadow-lag i plum og volt — ligger i git-historikken. */
/* :active bliver: det er ikke en hover, men kvitteringen for et tryk, og
   den gælder også berøringsskærme. */
.story-card:active { transform: translateY(-2px); }

/* Disciplin-kort: nummer glider mod volt, pil viser sig */
/* Pilen og hover-farven på disciplinkortene er fjernet: de stammer fra
   dengang kortene var links til tilmeldingen. Kortene fører ingen steder
   hen længere, og på mobil lå pilen oven i harmonikaens vinkel. Når
   undersiderne pr. kampsport findes, hører de hjemme her igen. */

/* Hero-mark parallax får transition slået fra — styres af rAF */
.hero__mark { will-change: transform; }

/* Lightbox til reels (§9.2) — skelet, aktiveres når videofilerne kommer */
.lightbox {
  margin: auto; /* reset nulstiller dialogens UA-centrering — gendan den */
  border: none; padding: 0; background: transparent;
  /* Bredden må aldrig give en 9:16-video der er højere end skærmen. Det
     tredje led er den bredde hvor videoen præcis fylder 92% af højden
     minus luften over den (--lb-luft, kun mobil) — på en lav telefon
     (375×667) gav 92vw alene en video på 613px, der stak 27px ud under
     kanten. dvh følger mobilens adresselinje; vh-linjerne er reserve for
     browsere uden dvh. */
  --lb-luft: 0px;
  max-width: min(420px, 92vw, calc((92vh - var(--lb-luft)) * 9 / 16));
  max-width: min(420px, 92vw, calc((92dvh - var(--lb-luft)) * 9 / 16));
  max-height: 92vh; max-height: 92dvh;
}
.lightbox::backdrop {
  background: color-mix(in srgb, var(--plum-900) 88%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.lightbox video, .lightbox .ph {
  width: 100%; aspect-ratio: 9 / 16;
  border-radius: var(--radius-media);
}
.lightbox__close {
  position: absolute; top: 0.75rem; right: 0.75rem; z-index: 2;
  width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--plum-900) 70%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--white); font-size: 1.15rem; line-height: 1;
}
@media (max-width: 767.98px) {
  /* Knappen skal stå OVER videoen, ikke oven på den: dialogen får luft i
     toppen, og knappen bor i det luftrum — stadig i højre hjørne. */
  .lightbox { padding-top: 54px; --lb-luft: 54px; }
  /* Mindre ring på mobil: 34px er stadig et rimeligt tapmål, og knappen
     står alene i sit luftrum uden noget at blive forvekslet med. */
  .lightbox__close { top: 0; right: 0; width: 34px; height: 34px; font-size: 1rem; }
}
/* Swipe-luk på mobil: videoen følger fingeren og glider tilbage ved slip */
.lightbox video { touch-action: none; }
.lightbox.snapback video { transition: transform 0.25s var(--ease-out); }

/* Higgsfield-tekstur (§9.6: abstrakt flade, ingen personer) */

/* (Mobil-hero havde en teksturbaggrund som fallback. Videoen indlæses nu på
   alle bredder, og teksturfilen er fjernet — reglen er derfor væk.) */

/* ==========================================================================
   MOTION II — premium-lag (inden for §6: maks 4 scrub-grupper, ingen pinning)
   ========================================================================== */

/* Ord-for-ord headline-reveal (The Grind / SplitText-mønster, uden lib).
   JS pakker hvert ord i .w > i; containeren beholder .reveal som IO-trigger,
   men dens egen fade/rise neutraliseres — ordene bærer animationen. */
.split-words.reveal { opacity: 1; transform: none; transition: none; }
.split-words .w {
  display: inline-block; overflow: hidden;
  vertical-align: bottom;
  padding-bottom: 0.06em; margin-bottom: -0.06em;
  padding-top: 0.30em;   margin-top: -0.30em;   /* plads til versal- og Å-overhæng ved stram linjeafstand */
}
.split-words .w i {
  display: inline-block; font-style: normal;
  transform: translateY(115%);
  transition: transform 0.9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 0.07s);
}
.split-words.in .w i { transform: none; }

/* Clip-reveal på medier: fladen tørres frem nedefra */
.reveal-clip {
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1s var(--ease-out);
  transition-delay: calc(var(--stagger, 0) * 0.08s);
}
.reveal-clip.in { clip-path: inset(0 0 0 0); }
/* Fade-only reveal (til mosaik, hvor transform er optaget af parallax) */
.reveal-fade {
  opacity: 0;
  transition: opacity 0.9s var(--ease-out);
  transition-delay: calc(var(--stagger, 0) * 0.08s);
}
.reveal-fade.in { opacity: 1; }

/* Scrub-parallax (§6: gruppe 2+3 af 4 — hero-mark er gruppe 1) */

.s-final__mark { will-change: transform; }

/* Figurvarianter af linjeværket */
.linework--sparse line { stroke-width: 1; }

/* Sektionen overlapper heroens bundluft (heroen har negativ margin), så dens
   top — og dermed hvor omridset af hero-B'et begynder — står præcis ved
   hero-videoens nederste kant, og dens mørke bund dækker gradient-B'et i
   luften. Almindelig overflow: hidden og ingen negativ clip-path: den gav et
   mellemrum mellem B og omrids på iPhone. Toppolstringen får luften lagt
   til, så indholdet står, hvor det stod. main.js lægger overlappet til
   omridsets placering. */
.disciplines {
  position: relative;
  overflow: hidden;
  padding-top: calc(var(--section-md) + var(--hero-luft));
}
.disciplines .linework { opacity: 0.10; }
/* Fortsættelsen af hero-B'et som ren streg (§3.5) — placeret så det
   flugter 1:1 med gradient-B'et over sektionsgrænsen */
.disciplines__mark {
  position: absolute;
  right: var(--mark-right);
  width: var(--mark-w);
  /* Fallback uden JS (antager hero = 100svh). JS måler og overskriver,
     så flugten også holder på mobil hvor heroen kan være højere. */
  top: calc(8svh - var(--mark-w));
  opacity: 0.12;
  pointer-events: none;
  will-change: transform;
}
.disciplines__mark path { stroke-width: 1.6; }
/* Vises nu på alle bredder — JS-justeringen gør flugten robust på mobil */

/* Hero-indgangssekvens: lead + mono + quiz følger efter H1-ordene */
.hero__headline .lead.reveal { transition-delay: 0.45s; }
.hero__headline .mono.reveal { transition-delay: 0.6s; }
.hero .quiz.reveal { transition-delay: 0.75s; }
/* Kortet holder sit eget kompositlag PERMANENT. Reveal-overgangen
   løfter det til et lag og smider laget væk igen når den slutter
   (transform: none) — netop dét øjeblik, midt i at dåsens 24 skiver
   drejer og hero-videoen spiller, er dér halvfærdige kort er set på
   desktop: kortets område rasteriseres om, og når GPU'en ikke når det,
   står de fliser tomme. Med laget beholdt sker der ingen om-rasterisering.
   Ingen synlig forskel: kortet er uigennemsigtigt, så tekstens
   kantudjævning er den samme. */
.hero .quiz { will-change: transform; }

/* Count-up-tal må ikke hoppe i bredden */

@media (prefers-reduced-motion: reduce) {
  .split-words .w i { transform: none; transition: none; }
  .reveal-clip { clip-path: none; transition: none; }
  .reveal-fade { opacity: 1; }
}

/* ==========================================================================
   REELS — thumbnails, hover-preview, play-affordance
   ========================================================================== */
.reel-thumb {
  position: relative; display: block; width: 100%;
  aspect-ratio: 9 / 16; max-width: 340px; margin-inline: auto;
  border-radius: var(--radius-media); overflow: hidden;
  background: var(--plum-800); padding: 0;
}
.reel-thumb video, .story-card video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
}
.reel-thumb__play {
  position: absolute; inset: 0; margin: auto;
  width: 56px; height: 56px; border-radius: 50%;
  background: color-mix(in srgb, var(--plum-900) 55%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid color-mix(in srgb, var(--white) 35%, transparent);
  transition: transform var(--dur-ui) var(--ease-ui), background-color var(--dur-ui) var(--ease-ui);
  pointer-events: none;
}
.reel-thumb__play::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 0; height: 0; transform: translateX(2px);
  border-style: solid; border-width: 9px 0 9px 15px;
  border-color: transparent transparent transparent var(--white);
}

/* Story-cards bliver video-kort */
.story-card { position: relative; overflow: hidden; padding: 0; }
.story-card__meta {
  position: absolute; inset: auto 0 0 0; z-index: 2;
  display: flex; flex-direction: column; gap: 2px;
  padding: 2.25rem 1.1rem 1.1rem;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--plum-900) 78%, transparent));
}
.story-card__meta .mono { color: color-mix(in srgb, var(--white) 75%, transparent); }
/* Navnet står øverst i display-fonten; titlen under beholder mono.
   IG-kortet er undtaget — dets <b> er en handling, ikke et navn. */
.story-card__meta b { font-weight: 600; font-size: 0.9375rem; color: var(--white); }
.story-card:not(.story-card--ig) .story-card__meta b {
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  font-size: clamp(1.75rem, 1.4rem + 1.75vw, 3rem); /* som "Følg med i vores resultater" */
  line-height: 0.92; letter-spacing: 0.01em;
  text-transform: uppercase;
}
/* Samme mærke som på Chris Curtis-videoen, bare skaleret til det mindre
   kort. Det står permanent — det er det eneste der viser at kortet er en
   video, nu hvor der ikke er nogen hover til at afsløre det. */
.story-card .reel-thumb__play { width: 46px; height: 46px; }
/* Ved hover kører previewet, og reelsene har indbrændte undertekster
   nederst — navn, gradient og play-mærke fader væk, så de kan læses.
   Kun med mus: på touch er der intet preview, og teksten skal blive. */
.story-card__meta { transition: opacity var(--dur-ui) var(--ease-ui); }
.story-card .reel-thumb__play {
  transition: opacity var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-ui),
              background-color var(--dur-ui) var(--ease-ui);
}
@media (hover: hover) and (pointer: fine) {
  .story-card:not(.story-card--ig):hover .story-card__meta,
  .story-card:not(.story-card--ig):hover .reel-thumb__play { opacity: 0; }
}

/* IG-kortet: broen til Instagram i stedet for et live-feed */
.story-card--ig {
  display: flex; align-items: flex-end;
  background: var(--plum-900);
  /* Samme kant som nextbar-kortet ("Næste prøvetime"): 1px i --rule.
     Kortet har ingen video at stå på, så kanten er dét der giver det form */
  border: 1px solid var(--rule);
  text-decoration: none;
}
.story-card--ig .story-card__meta { position: static; background: none; padding: 1.1rem; z-index: 1; }
/* B'et som på medlemskortet (info & priser): nede til højre, så stort at
   det bløder over højre kant og bunden — kortets overflow: hidden klipper
   det. Samme svage styrke som dér. */
.story-card__maerke {
  position: absolute; right: -14%; bottom: -12%;
  width: 90%;
  opacity: 0.09; pointer-events: none;
}

/* ==========================================================================
   UGESKEMA — hairline-grid i sidens sprog (§8.2-light på forsiden)
   ========================================================================== */
.schedule { padding-block: var(--section-sm) var(--section-md); }

.schedule__grid {
  display: grid; grid-template-columns: repeat(7, 1fr);
  border-block: 1px solid var(--ash);
}
.schedule__day {
  padding: 1.1rem 0.9rem 1.4rem;
  border-left: 1px solid var(--ash);
  min-width: 0;
}
.schedule__day:last-child { border-right: 1px solid var(--ash); }
.schedule__day.is-today { background: var(--white); }
.schedule__dayname { color: var(--graphite); margin-bottom: 0.6rem; }
.is-today .schedule__dayname { color: var(--volt-deep); }
/* Ordet står oprejst og en anelse mindre end dagsnavnet. Farven arves her
   paa forsiden; holdoversigten sætter sin egen (volt paa mørk bund). */
.schedule__idag { font-style: normal; font-size: 0.9em; }
.is-today .schedule__dayname::before {
  content: ""; display: inline-block; width: 7px; height: 7px;
  border-radius: 50%; background: var(--volt); margin-right: 6px;
  vertical-align: 1px;
}
.schedule__item {
  display: grid; gap: 2px;
  padding-block: 0.65rem;
  border-top: 1px solid var(--ash);
}
.schedule__item .mono { font-size: 0.6875rem; color: var(--graphite); opacity: 0.7; }
.schedule__item b { font-size: 0.875rem; font-weight: 600; color: var(--plum-900); line-height: 1.25; }
.tag {
  justify-self: start; margin-top: 4px;
  font-family: var(--font-mono); font-style: normal;
  font-size: 0.625rem; letter-spacing: 0.06em; text-transform: uppercase;
  border: 1px solid var(--ash); border-radius: var(--radius-control);
  padding: 2px 8px; color: var(--graphite);
}
.tag--intro { background: var(--plum-900); border-color: var(--plum-900); color: var(--white); }

/* Smalle skærme: vandret rail med snap — dagens kolonne scrolles ind */
@media (max-width: 1200px) {
  .schedule__grid {
    display: flex; overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
  }
  .schedule__grid::-webkit-scrollbar { display: none; }
  .schedule__day { flex: 0 0 236px; scroll-snap-align: start; }
}

/* Rigtige fotos i split-figurer: 4:5, sidens hjørneradius, og hele
   spaltens bredde. Spalten er min(38%, 478px) i begge mørke splits (se
   SPLIT-RYTME), så medierne bliver lige store af sig selv — og fordi de
   fylder spalten, går de helt ud til indholdets yderkant: venstre kant i
   Ledelsen, højre i Anbefalingen. Det er dét der bærer skiftet mellem
   de to sektioner. */
.s-split figure img {
  width: 100%;
  /* height: auto skal med: uden den vinder billedets height-attribut, og
     aspect-ratio bliver ignoreret fordi begge akser så er låst. */
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center;
  border-radius: var(--radius-media);
  /* Samme streg som prøvetime-bjælken (.nextbar) — alle sidens medier
     har den, så de læses som én familie. */
  border: 1px solid var(--rule);
}

/* Skema-scroller: udtoningen i kanten viser at der kan swipes (kun smalle
   skærme). Teksten "Swipe for flere dage" er afløst af prikkerne under
   dagene (Alberts valg 2026-09-13). */
.schedule__scroll { position: relative; }
@media (max-width: 1200px) {
  .schedule__scroll::after {
    content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 64px;
    background: linear-gradient(90deg, transparent, var(--bone));
    pointer-events: none;
    transition: opacity var(--dur-ui) var(--ease-ui);
  }
  .schedule__scroll.at-end::after { opacity: 0; }
}

.stories > .wrap { position: relative; z-index: 2; }

/* Hero: grovere filmkorn end resten af siden — kompenserer for lysere scrim */
.hero
/* B'et inverterer videoen bag sig (The Grind-greb): hvid fill + difference
   = negativet af optagelsen inde i bogstavformerne.
   NB: difference inverterer hver farvekanal for sig — på blå baggrund giver
   det gult. Det er en bevidst accept, ikke en fejl. */
.hero__mark { mix-blend-mode: difference; }

/* ==========================================================================
   TRÆNINGSVIDEOER — 3 kort i loop (Grind-forlæg), efter "Plads til alle"
   ========================================================================== */
.training { padding-block: var(--section-sm) var(--section-md); }
.training h2 { text-align: center; max-width: 18ch; margin-inline: auto; }
.training .eyebrow { display: flex; justify-content: center; }
.training__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gap);
  max-width: 62rem; margin: 3.5rem auto 0;
}
.train-card {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius-media);
  overflow: hidden;
  background: var(--plum-800);
  transform: translateY(var(--off, 0));
}
.train-card video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
}
.train-card__label {
  position: absolute; left: 1rem; bottom: 0.75rem; z-index: 2;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
  line-height: 0.95; text-transform: uppercase;
  color: var(--white);
}

@media (min-width: 768px) {
  .training__grid > *:nth-child(2) { --off: 2.25rem; }
  .training__grid > *:nth-child(3) { --off: 4.5rem; }
  .training { padding-bottom: calc(var(--section-md) + 4.5rem); }
}
@media (max-width: 767.98px) {
  .training__grid {
    display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; margin-inline: calc(-1 * var(--page-gutter));
    padding-inline: var(--page-gutter);
  }
  .training__grid::-webkit-scrollbar { display: none; }
  .train-card { flex: 0 0 72vw; scroll-snap-align: center; }
}

/* ==========================================================================
   FØLG BURNELL — community-plakat på volt (Grind-forlæg)
   Kæmpe mørkt ord kant til kant, spredte fotokort, grov tekstur over alt
   ========================================================================== */
.follow {
  position: relative; overflow: hidden;
  background: var(--volt);
  min-height: 100vh;
  display: grid; place-items: center;
  align-content: center; /* rækkerne må ikke strækkes ud i sektionshøjden */
  /* ekstra luft forneden så some-knapperne får plads under ordet */
  padding-block: var(--section-md) clamp(7rem, 16vh, 11rem);
}
.follow__word {
  /* Loft over hvor bredt ordet må blive. Under dette flugter det med
     skærmens sider; over det holder det størrelsen og centreres i stedet
     for at vokse i det uendelige på 4K- og ultrawide-skærme.
     Ét tal at skrue på — main.js læser det. */
  --follow-max: 1920px;
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase;
  --fw-lh: 0.8;          /* bruges også af .fw-foto nedenfor */
  line-height: var(--fw-lh);
  font-size: 35.5vw;
  /* -0.045em var tunet til Khand, som har brede sidebærere. Display-skriften
     er allerede ultrasmal — samme værdi lukkede mellemrummene helt, så
     bogstaverne smeltede sammen til én blækmasse. Let positiv i stedet,
     så hvert bogstav læses som sit eget billedvindue. */
  letter-spacing: 0.01em;
  white-space: nowrap;
  user-select: none;
  z-index: 1;
  justify-self: start; /* JS-fit flugter blækket fra venstre kant */
  /* scaleY blev lagt på for at give Khand højde. Display-skriften er i forvejen
     ultrasmal, så fittingen skalerer den op til ~900px for at fylde bredden —
     ekstra strækning ville få ordet til at sprænge sektionen. */
  transform: scaleY(1);
  transform-origin: center;
  margin-bottom: 3vh;
}
/* Hver bogstavgruppe er et vindue: to lag med samme tekst — det bageste (fw-a)
   viser nuværende foto, det forreste (fw-foto--b) fader næste ind — se "FOTOVINDUERNE". */
.fw-group { position: relative; display: inline-block; }
.fw-group i {
  font-style: normal;
  background-color: var(--plum-900);      /* fallback hvis billedet fejler */
  background-size: cover; background-position: center;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent; /* iOS respekterer ikke color alene */
  /* background-clip:text maler KUN inden for boksen — negativ letter-spacing
     gør boksen smallere end blækket, så glyf-overhæng (L-fod, J-hale) blev
     usynligt. Padding udvider boksen; negativ margin ophæver layoutskiftet. */
  padding: 0 0.18em 0 0.06em;
  margin: 0 -0.18em 0 -0.06em;
}
/* FOTOVINDUERNE (2026-09-08) — bogstaverne som MASKE, fotoet som lag der
   flyttes med transform.

   Før lå fotoet som background-image på selve teksten (background-clip:
   text), og glidet var en animation af background-position. Den slags kan
   browseren ikke lægge på grafikkortet: hver frame blev hele bogstavboksen
   malet om — tre bokse i skærmbredde på desktop, seks på mobil — så længe
   sektionen var på skærmen. Det var forsidens tungeste tegneopgave.

   Nu: .fw-a står stadig i flowet og bestemmer bredden, men er usynlig.
   Oven på ligger .fw-foto (samme boks som fw-a's inline-boks, se noten om
   IKKE inset:0 nedenfor) med bogstaverne som mask-image — en SVG med
   præcis samme skrift, grad, spatiering og skriftlinje, bygget af main.js
   med skriften indlejret. Inde i vinduet ligger .fw-foto__bg i fotoets
   fulde størrelse (sat af JS som --fw-iw/--fw-ih, samme 1,75×-regning som
   før) og glider med transform. Masken rasteriseres én gang; glidet er
   rent compositor-arbejde. Samme billede, samme bane (38 %→62 %), samme
   takt og forskydning. .fw-tex ligger uændret ovenpå. */
.fw-group.er-foto .fw-a {
  background: none;
  color: transparent; -webkit-text-fill-color: transparent;
}
.fw-group .fw-foto {
  /* IKKE inset:0. Gruppens boks er kun line-height høj (0.8em), mens
     bogstavets egen inline-boks er ~1em (ascender + descender). Med inset:0
     blev vinduet lavere end teksten, og den øverste stribe af bogstavet
     faldt udenfor. Her matches fw-a's boks præcist — inkl. fw-a's padding
     og negative margin, som arves fra .fw-group i via samme regel. */
  position: absolute;
  left: 0; right: 0;
  top: calc((var(--fw-lh) * 1em - 1em) / 2);
  height: 1em;
  line-height: 1;
  overflow: hidden;
  padding: 0 0.18em 0 0.06em;
  margin: 0 -0.18em 0 -0.06em;
  pointer-events: none;
  /* Masken sættes inline af main.js (data-URI SVG). Uden maske males der
     INTET — så et vindue kan aldrig stå som en rå firkant. */
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  /* Skal give en compositing-flade: transform-animationen indeni kører så
     på GPU'en, og masken lægges på dér. KUN mens vinduerne faktisk skifter
     (.follow.koerer, sat af main.js): 18 permanente lag med hver sin maske
     bliver liggende i telefonens grafikhukommelse resten af besøget, også
     længe efter man er scrollet forbi. */
  transform: translateZ(0);
}
.follow.koerer .fw-group .fw-foto { will-change: transform; }
.fw-group .fw-foto--b {
  opacity: 0;
  transition: opacity 1.1s var(--ease-ui);
}
.fw-group .fw-foto--b.show { opacity: 1; }
.fw-group .fw-foto__bg {
  position: absolute;
  top: 0; left: 50%;
  width: var(--fw-iw, 0px); height: var(--fw-ih, 0px);
  margin-left: calc(var(--fw-iw, 0px) / -2);   /* vandret centreret = background-position 50% */
  background-color: var(--plum-900);
  background-size: 100% 100%; background-repeat: no-repeat;
  /* Lodret: samme tal som background-position Y% gav: (boks − foto) · p.
     Boksen er 1em høj — det er præcis fw-foto's højde. */
  --fw-p0: 0.38; --fw-p1: 0.62;
  transform: translate3d(0, calc((1em - var(--fw-ih, 0px)) * 0.5), 0);
  animation: fw-glid 26s ease-in-out infinite alternate;
}
/* De tre bogstavvinduer må ikke glide i takt. Negativ forsinkelse starter
   dem forskudt uden ventetid, og begge lag i en gruppe deler den, så
   overblændingen ikke afslører et spring i motivet. */
.fw-group:nth-child(2) .fw-foto__bg { animation-delay: -8.7s; }
.fw-group:nth-child(3) .fw-foto__bg { animation-delay: -17.3s; }
@keyframes fw-glid {
  from { transform: translate3d(0, calc((1em - var(--fw-ih, 0px)) * var(--fw-p0)), 0); }
  to   { transform: translate3d(0, calc((1em - var(--fw-ih, 0px)) * var(--fw-p1)), 0); }
}
@media (max-width: 767.98px) {
  /* Mobil viser BEGGE linjer. Længere tur og mindre udsving, som før. */
  .fw-group .fw-foto__bg { animation-duration: 40s; --fw-p0: 0.43; --fw-p1: 0.57; }
}
@media (prefers-reduced-motion: reduce) {
  .fw-group .fw-foto__bg { animation: none; }
}

.follow__cta {
  position: absolute; bottom: clamp(3rem, 8vh, 5rem); /* tæt på ordet uden at røre det */
  left: 0; right: 0;                 /* kant til kant — ingen transform-matematik */
  padding-inline: var(--page-gutter);
  z-index: 2;
  display: grid; justify-items: center; gap: 0.6rem;
  text-align: center;
}
.follow__label {
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(1.75rem, 1.4rem + 1.75vw, 3rem); /* som disciplin-kortene */
  line-height: 0.95; text-align: center; justify-self: center;
  /* Hvid på volt gav kun 2,2:1 og faldt igennem. Plum-900 giver 8,5:1. */
  color: var(--plum-900);
}
.follow__sub {
  color: var(--graphite);   /* som brødtekst på lys bund */
  margin-top: -0.1rem;
}
.follow__links {
  display: flex; gap: 0.75rem; margin-top: 0.4rem;
  justify-self: center; justify-content: center;
}
.follow__links a {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--plum-900); color: var(--white);   /* 19:1 */
  transition: transform var(--dur-ui) var(--ease-ui), background-color var(--dur-ui) var(--ease-ui);
}
.follow__links svg { width: 20px; height: 20px; }

/* reveal-clip på volt-fladen skal ikke arve .ph-stil — kun wipe-effekten */
/* Anden linje findes kun på mobil */
.follow__word--narrow, .follow__word--sub { display: none; }
/* Kun desktop-linjen strammes; mobilens to linjer er urørt. */
.follow__word--wide { letter-spacing: -0.018em; }

@media (max-width: 767.98px) {
  /* Fuld skærmhøjde også på mobil — svh undgår browserbjælke-hoppet */
  .follow { min-height: 100svh; padding-block: var(--section-sm) clamp(6rem, 18vh, 9rem); }
  .follow__word { font-size: 35vw; margin-bottom: 0; }
  .follow__word--wide { display: none; }
  .follow__word--narrow { display: block; }
  .follow__word--sub { display: block; margin-top: 0; margin-bottom: 7vh; }
  /* CTA centreret vandret OG med ens luft under */
  .follow__cta { bottom: clamp(5.5rem, 19vh, 9rem); } /* luft ned fra MMA&BJJ */
}

/* ==========================================================================
   SIDETEKSTUR — ÉT fast lag over hele siden. Fixed, så den ikke følger med
   scroll: indholdet glider forbi under en stillestående flade, præcis som
   korn på film. overlay lysner på mørk bund og mørkner på lys, så samme lag
   virker på alle sektionsfarver.
   Turkis får ET EKSTRA lag oveni — se .follow::before.
   ========================================================================== */
.page-texture {
  position: fixed; inset: 0; z-index: 90;
  pointer-events: none;
  /* INGEN mix-blend-mode længere (2026-09-08). Laget blev før blandet med
     screen, og et fast lag over hele skærmen med blanding tvinger
     browseren til at tegne HELE siden ind i en ekstra buffer i hver
     frame — den mest sandsynlige årsag til tomme pletter på Windows med
     integreret grafikkort. Kornet bæres nu i flisens ALFA (hvidt korn
     med gennemsigtighed), og almindelig komposition af hvidt med alfa er
     matematisk det samme som screen af gråt: pixel for pixel samme
     resultat på mørkt, lyst og video. Se noise-tile-alfa.svg. */
  background-image: url("../img/noise-tile-alfa.svg?v=1");
  background-size: 400px 400px;
  background-repeat: repeat;
  opacity: 0.07;
}
/* DIALOGERNE ligger i browserens top layer, som tegnes over ALT — også
   over .page-texture, uanset z-index. Så de får deres eget kornlag: samme
   flise, samme blanding, samme styrke, som ::after på selve dialogen.
   position: fixed dækker hele skærmen (en fixed efterkommer klippes ikke
   af dialogens overflow, da den ikke har transform/filter), så kornet
   ligger over både boksen og backdroppen bag den. pointer-events: none,
   så klik på backdroppen stadig lukker. */
.ptime::after, .lightbox::after {
  content: ""; position: fixed; inset: 0; z-index: 3;
  pointer-events: none;
  /* Samme alfa-flise som .page-texture — ingen blanding, samme pixels */
  background-image: url("../img/noise-tile-alfa.svg?v=1");
  background-size: 400px 400px;
  background-repeat: repeat;
  opacity: 0.07;
}

/* .s-light og .follow beholder position: relative — deres indhold ligger
   på z-index 1 ovenpå. */
.follow, .s-light { position: relative; }
/* KORN PÅ LYSE FLADER. Sidens faste kornlag blandes med screen og
   forsvinder mod hvidt — på .s-light var det derfor væk. Her får de lyse
   sektioner deres eget lag: en lys udgave af samme flise (hvidt papir
   med mørke prikker) blandet med multiply, som gør det modsatte af
   screen og bider netop på hvidt. background-attachment: fixed holder
   kornet stille mens indholdet glider forbi, som på resten af siden
   (iOS ignorerer det og lader kornet følge med — det er acceptabelt).
   Laget ligger OVER indholdet (z 2, .wrap er 1) præcis som sidens faste
   korn gør — multiply med en næsten hvid flise rører ikke mørk tekst
   nævneværdigt. isolation holder blandingen inde i sektionen. */
.s-light { isolation: isolate; }
.s-light::before {
  content: ""; position: absolute; inset: 0; z-index: 2;
  pointer-events: none;
  /* Sort korn med alfa i stedet for lys flise + multiply: matematisk
     samme resultat (se noise-tile-lys-alfa.svg), men uden blanding, så
     sektionen ikke skal tegnes i en ekstra buffer. */
  background: url("../img/noise-tile-lys-alfa.svg?v=1") 0 0 / 400px 400px repeat;
  /* INGEN background-attachment: fixed. Den tvinger browseren til at male
     laget om ved hver eneste scroll-frame — det var mærkbart lag på
     almindelige maskiner. Kornet følger nu sektionen; på et stillestående
     mønster kan man ikke se forskel. */
  /* Lavt: kornet skal anes som papir, ikke ses som støj. 0.5 var alt for
     meget, 0.09 for lidt. */
  opacity: 0.11;
}
/* Turkis-sektionen får sit eget kornlag oveni sidens: kornet én gang til i
   en anden skala, så de to ikke flugter. overlay på turkis giver både
   lysere og mørkere pletter, hvor sidens screen-lag kun kan lysne.
   isolation gør .follow til sin egen stacking context, så laget kan ligge
   på z-index -1: over sektionens egen turkis, under alt indhold — uden at
   røre ordets background-clip. */
.follow { isolation: isolate; }
.follow::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  pointer-events: none;
  background-image: url("../img/noise-tile.svg?v=fin3");
  background-size: 260px 260px;
  background-repeat: repeat;
  mix-blend-mode: overlay;
  opacity: 0.22;
}
/* BETONMUREN: revnet beton over HELE sektionen — også bogstaverne og
   knapperne, så det hele står som ét stykke malet mur. Laget er sort korn
   med gennemsigtighed: samme resultat som multiply, men uden blanding, så
   bogstavernes glidende fotos ikke tvinger laget til at blive regnet om.
   Sort gør turkisen mørkere i samme nuance — der opstår ingen ny blå. */
.follow::after {
  content: ""; position: absolute; inset: 0; z-index: 50;
  pointer-events: none;
  background: url("../img/beton-revner.webp") center / cover no-repeat;
  opacity: 0.3;
}
/* BETONSLID: malingen hæfter ikke i murens revner og porer. Masken er lavet
   af SAMME murbillede, og main.js lægger den præcis oven i muren — så en
   revne der løber gennem betonen også æder sig gennem bogstavet netop dér.

   Masken sidder INDE i hvert fotovindue, på .fw-foto__maling: et fast lag
   rundt om det glidende foto (fotoet flytter sig indeni, masken bliver
   stående mod muren). Vinduet selv får revnefarven som bund, så et hul i
   malingen viser en mørk revne — formet af præcis samme bogstavmaske som
   fotoet. Intet kan derfor tegne uden for bogstaverne, og der er ingen
   bløde kanter fra to lag, som muren kunne skinne igennem.
   Polaroidlaget (.fw-tex) får samme maske, så ridserne også er væk i hullet.
   Slås først til når main.js har placeret masken (.har-slid), og farven
   først når bogstavmasken findes (.er-foto) — ellers stod vinduet som en
   rå firkant. Farven er volt gjort mørkere mod sort: samme nuance som
   turkisen, ingen lilla. */
.fw-group .fw-foto__maling { position: absolute; inset: 0; display: block; }
.follow.har-slid .fw-group .fw-foto__maling,
.follow.har-slid .fw-group .fw-tex {
  -webkit-mask-image: url("../img/beton-slid-let.webp"); mask-image: url("../img/beton-slid-let.webp");
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: var(--mw) var(--mh); mask-size: var(--mw) var(--mh);
  -webkit-mask-position: var(--mx) var(--my); mask-position: var(--mx) var(--my);
}
.follow.har-slid .fw-group.er-foto .fw-foto {
  background-color: color-mix(in srgb, var(--volt) 38%, #000);
}
/* Indholdet skal ligge over kornlaget */
.s-light > .wrap { position: relative; z-index: 1; }

/* Anbefalingens video i 4:5 og hele spaltens bredde, som fotoet i
   Ledelsen. Videoen er 9:16 med mest luft i toppen — cover + bottom
   beskærer oppefra og zoomer naturligt ind på personen. */
.reel-thumb--lg {
  aspect-ratio: 4 / 5;
  max-width: none;
  width: 100%;
  /* Samme streg som prøvetime-bjælken (.nextbar), som de øvrige medier */
  border: 1px solid var(--rule);
}
.reel-thumb--lg video { object-position: bottom; }
/* Chris Curtis-videoen kører af sig selv (data-autoplay, 2026-09-14), så
   play-mærket står ikke fast oven på den. Det dukker op ved hover — og ved
   tastaturfokus — som tegn på, at et klik afspiller den med lyd. */
.reel-thumb--lg .reel-thumb__play {
  opacity: 0;
  transition: opacity var(--dur-ui) var(--ease-ui), transform var(--dur-ui) var(--ease-ui),
              background-color var(--dur-ui) var(--ease-ui);
}
.reel-thumb--lg:focus-visible .reel-thumb__play { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .reel-thumb--lg:hover .reel-thumb__play { opacity: 1; }
}

/* ==========================================================================
   SPLIT-RYTME (Grind-forlæg): medie og tekst CENTRERET om samme vandrette
   midte — de to spalters midtpunkter flugter, uanset hvilken der er
   højest — og luftig linjeafstand i brødteksten. Ingen top-forskydning
   af hverken tekst eller medie: den ville flytte midten.
   ========================================================================== */
.s-split .split,
.s-split .split--alt {
  align-items: center;
}
.s-split .content p {
  line-height: 1.95;
  max-width: 46ch;
}
.s-split .content .credentials li {
  line-height: 1.7;
}
/* SPEJLET split (billede til venstre, tekst til højre — Ledelsen).
   De mørke splits skifter side, men afstanden mellem medie og tekst skal
   være den samme begge veje. I den utvungne udgave (tekst venstre) opstår
   afstanden af sig selv: teksten begynder i sidens venstre kant og stopper
   ved 46ch, og mediet står centreret i sin 4fr-spalte. Spejlet gør det
   samme, bare spejlvendt: samme spalter i omvendt orden, mediet centreret
   som før, og TEKSTBLOKKEN gjort 46ch bred og skubbet helt ud i højre kant
   (margin-left: auto). Så ender teksten i sidens højre kant præcis som den
   anden begynder i venstre, og afstanden ind til mediet er den samme —
   ikke en indrykning nogen har tunet, men den samme geometri spejlet.
   Spalten er mindst 478px, så mediet ikke loftes af 4fr på smal desktop. */
@media (min-width: 992px) {
  /* Forlægget (thegrind.nl, "1 op 1 coaching" → "de app"): mediet er
     38 % af indholdsbredden og rører yderkanten, tekstblokken rører den
     modsatte kant, og midten står tom. Spalten er den samme i begge
     retninger, og 478px-loftet holder mediet på den størrelse det altid
     har haft på brede skærme — det skal ikke vokse med sektionen. */
  .s-split .split { grid-template-columns: 1fr min(38%, 478px); }
  .s-split .split--alt { grid-template-columns: min(38%, 478px) 1fr; }
  .s-split .split--alt .content { max-width: 46ch; margin-left: auto; }
}

/* Polaroid-teksturen som SIT EGET lag oven på fotoet — ikke som et ekstra
   baggrundslag med background-blend-mode. Den kombination falder ud sammen
   med background-clip:text på mobile browsere: klipningen fejler, og da
   teksten er gennemsigtig forsvandt billederne helt.
   Teksturfilen bærer selv sin alfa (mellemtoner er gennemsigtige, kun ridser
   og pletter er dækkende), så laget kan komponeres helt normalt. */
.fw-group .fw-tex {
  position: absolute;
  left: 0; right: 0;
  top: calc((var(--fw-lh) * 1em - 1em) / 2);
  height: 1em;
  line-height: 1;
  background-image: url("../img/texture-polaroid.webp");
  background-size: cover; background-position: center;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  opacity: 0.2;
  pointer-events: none;
}

/* Anbefalingen: navnet er nu overskrift, rollen har overtaget den volt-farvede
   linje, og citatet står lige under. */
.quote-role {
  display: block; color: var(--volt);
  margin-top: 1.5rem;
}
/* Arver sektionens brødtekst-behandling (grad, linjeafstand og målebredde)
   — kun afstanden op til rollelinjen er sin egen. */
.s-split .content p.quote-bio { margin-top: 0.9rem; }
/* .s-split .content p farver ALLE afsnit mist og vinder over .quote-mark
   på specificitet — citatet skal blive ved med at stå lyst. */
:is(.s-split, .seminar) .content h2:has(+ .quote-mark) { margin-bottom: 0; }
.s-split .content p.quote-mark {
  color: var(--bone);
  /* Samme stramme sats som h2 — citatet skal læses som en fortsættelse af
     navnet ovenover, ikke som et selvstændigt afsnit. */
  line-height: 0.74;
  margin-top: 0;
}

/* Ord markeret med data-blend inverterer baggrunden bag sig — samme greb som
   B'et i hero. Difference mod hvid giver ren invertering. */
.w--blend { mix-blend-mode: difference; }
.w--blend i { color: #fff; }
/* Reveal-animationen slutter med transform:none, hvilket dropper ordets
   kompositlag — og dér holdt blandingen op med at kunne aflæse videoen bag.
   Symptomet var at inverteringen virkede i præcis animationens varighed
   (0.9s + 0.21s forsinkelse) og derefter stod ordet hvidt.
   translateZ(0) er identisk i 2D, men holder laget i live. */
.split-words.in .w--blend i { transform: translateZ(0); }
@media (prefers-reduced-motion: reduce) {
  .split-words .w--blend i { transform: translateZ(0); }
}

/* Quiz- og næste-hold-kortet: helt uigennemsigtige, ingen blur.
   Samme mørke lilla som nyhedsetiketten, headeren og footeren.
   DET ER HER farven sættes — reglerne længere oppe når aldrig at gælde. */
.quiz, .nextbar {
  background: var(--plum-950);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}

/* Nextbaren ligger fast over skiftende sektioner. Over MØRK bund vendes den
   til et hvidt kort; klassen sættes fra main.js ud fra sektionens luminans. */
.nextbar {
  transition: transform 0.4s var(--ease-out), opacity 0.4s var(--ease-out),
              background-color 0.45s var(--ease-ui);
}
.nextbar__label, .nextbar__what, .nextbar__when {
  transition: color 0.45s var(--ease-ui);
}
/* Farveskiftet er droppet: kortet har nu en afdæmpet hvid kant, som
   holder det adskilt fra baggrunden uden at skulle vende om undervejs. */

/* Nextbaren dukker først op når man har scrollet forbi hero på mobil:
   ellers ligger den oven i quiz-kortet. Klassen sættes fra main.js. */
/* Glimtet ligger kun på mobil. Kassen er den samme som barens, så den
   radiale midte falder sammen med kortets midte; højden kommer fra
   --nextbar-h, som main.js måler på baren frem for at gætte den. */
.nextbar__glimt { display: none; }

@media (max-width: 767.98px) {
  .nextbar {
    transform: scale3d(0.03, 0.05, 1);
    opacity: 0;
    pointer-events: none;
    /* Kun baggrundsfarven må tone. Transform og opacity styres af
       animationerne herunder, og en overgang oveni ville trække i samme
       egenskaber og udjævne glimtet til en almindelig indtoning. */
    transition: background-color 0.45s var(--ease-ui);
  }
  .nextbar--vis {
    transform: scale3d(1, 1, 1);
    opacity: 1;
    pointer-events: auto;
  }

  .nextbar__glimt {
    display: block;
    position: fixed; z-index: 44;      /* lige under baren: kortet ligger oven på sit eget lys */
    left: 0.75rem; right: 0.75rem; bottom: 0.75rem;
    height: var(--nextbar-h, 4.3rem);
    border-radius: var(--radius-control);
    pointer-events: none; opacity: 0;

    /* KANTFRIT LYS
       En baggrund males aldrig uden for sin egen kasse. Den tidligere
       gradient havde en lodret radius på 128% af kassehøjden, så farven
       var stadig stærk når den ramte over- og underkanten — og dér blev
       den hugget lige af. Det var de kanter der tegnede kortets boks.

       ellipse closest-side lægger 100%-stoppet PRÆCIS på kanten, og når
       det stop er transparent, er der intet at hugge. Kernen står derfor
       blødt inde i kassen.

       Spildet uden for kortet kommer fra box-shadow, som males uden for
       kassen og aldrig klippes af den. Tre lag følger samme rampe som
       disciplinkortene: plum tæt på, plum svagere længere ude, volt
       yderst. Skyggen følger border-radius, så lyset har kortets form. */
    background: radial-gradient(ellipse closest-side at 50% 50%,
      color-mix(in srgb, var(--white) 72%, transparent) 0%,
      color-mix(in srgb, var(--white) 34%, transparent) 10%,
      color-mix(in srgb, var(--plum-500) 50%, transparent) 26%,
      color-mix(in srgb, var(--plum-500) 24%, transparent) 52%,
      color-mix(in srgb, var(--plum-500) 10%, transparent) 74%,
      transparent 100%);
    box-shadow:
      0 0  34px  4px color-mix(in srgb, var(--white)    22%, transparent),
      0 0  78px 16px color-mix(in srgb, var(--plum-500) 42%, transparent),
      0 0 140px 46px color-mix(in srgb, var(--plum-500) 20%, transparent),
      0 0 210px 80px color-mix(in srgb, var(--volt)     10%, transparent);
  }

  /* HYPERRUMSSPRINGET
     Kortet har KUN to keyframes og én kurve over dem. Det er så glat som
     bevægelsen kan blive: hvert ekstra stop er en ny acceleration og
     dermed et hak. Opaciteten behøver ikke sit eget stop — kurven er så
     forrest-tung at den er oppe på 0,87 efter en tredjedel af tiden.

     Skaleringen er ensartet: siderne kommer ind samtidig med top og bund.

     Ud af skærmen er kortet væk efter 200ms mens lyset kører i 320 —
     120ms hvor lyset står alene og slukker.

     Ind i skærmen er kortet 70ms forsinket, så lyset tændes først. To
     ting holder glimtet i kort snor dér: det topper ved 0,5 i skala —
     samme lille, sammentrukne lys som på vej ud — og det når aldrig over
     1,0, altså kortets egen kasse. Vokser det derudover, står der en
     glorie omkring et kort i fuld størrelse, og med en box-shadow der
     spilder op til 290px ud, læses den som en udtværing. */
  @keyframes nextbar-ind {
    from { opacity: 0; transform: scale3d(0.10, 0.10, 1); }
    to   { opacity: 1; transform: scale3d(1, 1, 1); }
  }
  @keyframes nextbar-glimt-ind {
    0%   { opacity: 0;    transform: scale3d(0.25, 0.34, 1); }
    22%  { opacity: 1;    transform: scale3d(0.50, 0.60, 1); }
    55%  { opacity: 0.06; transform: scale3d(0.80, 0.85, 1); }
    100% { opacity: 0;    transform: scale3d(1.00, 1.00, 1); }
  }
  @keyframes nextbar-ud {
    from { opacity: 1; transform: scale3d(1, 1, 1); }
    to   { opacity: 0; transform: scale3d(0.08, 0.08, 1); }
  }
  @keyframes nextbar-glimt-ud {
    0%   { opacity: 0;    transform: scale3d(1.3, 1.25, 1); }
    60%  { opacity: 1;    transform: scale3d(0.50, 0.60, 1); }   /* her er kortet væk */
    100% { opacity: 0;    transform: scale3d(0.20, 0.34, 1); }
  }

  /* --spring sættes af main.js ved HVERT skift og fjernes et øjeblik før,
     så animationen kan køre forfra. Retningen læses af --vis, der sidder
     på begge elementer. */
  .nextbar.nextbar--spring.nextbar--vis {
    animation: nextbar-ind 340ms 70ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  .nextbar.nextbar--spring:not(.nextbar--vis) {
    animation: nextbar-ud 200ms cubic-bezier(0.5, 0, 0.75, 0) both;
  }
  .nextbar__glimt.nextbar--spring.nextbar--vis {
    animation: nextbar-glimt-ind 180ms cubic-bezier(0.16, 1, 0.3, 1) both;
  }
  .nextbar__glimt.nextbar--spring:not(.nextbar--vis) {
    animation: nextbar-glimt-ud 320ms cubic-bezier(0.33, 0, 0.67, 1) both;
  }
  .nextbar.nextbar--spring, .nextbar__glimt.nextbar--spring { will-change: transform, opacity; }
}

/* Uden bevægelse: kortet toner ind og ud, og glimtet udgår helt. */
@media (prefers-reduced-motion: reduce) {
  .nextbar__glimt { display: none !important; }
  .nextbar.nextbar--spring { animation: none !important; }
  @media (max-width: 767.98px) {
    .nextbar {
      transform: none;
      transition: opacity 0.3s var(--ease-out), background-color 0.45s var(--ease-ui);
    }
    .nextbar--vis { transform: none; }
  }
}

/* ==========================================================================
   B-KONTUR GENNEM QUIZ-KORTET (mobil)
   Kortet lægger sig hen over hero-B'et. I stedet for at dække det helt,
   tegnes B'ets konturer oven på kortet og klippes til dets kant — samme greb
   som fortsættelsen ned i disciplin-sektionen.
   Placeringen sættes fra main.js, fordi B'et er positioneret i forhold til
   heroen og desuden flyttes af parallaksen; en fast CSS-offset ville skride.
   ========================================================================== */
.quiz__mark { display: none; }
@media (max-width: 767.98px) {
  .quiz { overflow: hidden; }
  /* Inline SVG frem for baggrundsbillede: kun sådan kan stregtykkelsen styres
     fra CSS, så stilen bliver identisk med .disciplines__mark nedenunder. */
  .quiz__mark {
    display: block;
    position: absolute;
    left: var(--b-x, 0); top: var(--b-y, 0);
    width: var(--mark-w); height: auto;
    opacity: 0.12;   /* samme som fortsættelsen — kortet har samme
                        baggrundsfarve som sektionen, så det ser ens ud */
    pointer-events: none;
  }
  .quiz__mark path { stroke-width: 1.6; }
}

/* ==========================================================================
   EVENT-STRIBE — ligger inde i headeren og følger dens fixed-position samt
   skjul/vis ved scroll. Ren tekst: blinkende prik + "Event" i turkis til
   venstre, pil til højre, rullende tekst imellem.
   På store skærme flugter striben med menupunkterne; --news-x sættes fra
   main.js ud fra navigationens faktiske venstrekant.
   ========================================================================== */

.site-news {
  /* SIN EGEN faste stribe øverst — ikke længere en række i headeren.
     z-index over headeren, så den bliver liggende når menuen klapper væk.

     Højden er den headeren havde i sammenklappet tilstand: 12px top,
     19px tekst, 14px bund = 45. Den var god, og nu er den stribens egen
     frem for et resultat af headerens polstring. */
  position: fixed; inset: 0 0 auto 0; z-index: 41;
  height: var(--stribe-h);
  display: flex; align-items: center;
  /* Gennemsigtig hvid. Striben lå før på headerens lilla bagflade og
     skiftede udseende med den; nu har den sin egen, som er den samme
     uanset hvor på siden man er. */
  background: color-mix(in srgb, var(--white) 88%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);

  /* Sporet fylder HELE bredden, og mærket lægger sig oven på i venstre
     side. Var de to flex-søskende, ville teksten først begynde efter
     mærket; nu ruller den ind under det og videre ud i fuld bredde. */
  --news-luft: 0.9rem;
  /* Hvor sidens indhold begynder. Striben selv er fuld skærmbredde, men
     mærket skal stå præcis dér hvor brandet og alt andet indhold starter.
     Under sidens maksimumbredde er det bare margenen; over den lægges
     halvdelen af det overskydende til. 100% er stribens egen bredde, som
     er skærmens — derfor rammer den samme kant som .wrap gør. */
  --news-kant: max(var(--page-gutter),
                   calc((100% - var(--page-max)) / 2 + var(--page-gutter)));
  text-decoration: none;
  font-family: var(--font-mono); font-size: var(--fs-meta);
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--white);
}
.site-news-mrk {
  position: absolute; left: var(--news-kant); top: 0; bottom: 0; z-index: 1;
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--volt); white-space: nowrap;
}
.site-news-mrk::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--volt); flex: none;
  animation: news-blink 1.6s ease-in-out infinite;
}
@keyframes news-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }

.site-news-spor {
  /* display: block skal med. Sporet er et <span>, og uden flex-forælderen
     er det inline — dér bider overflow: hidden ikke, og sporet voksede til
     hele båndets bredde i stedet for at klippe det. */
  display: block; overflow: hidden; width: 100%;
  /* Hullet UNDER mærket — et hul midt i båndet, så teksten er synlig på
     begge sider og kun forsvinder dér hvor mærket står.
     En maske frem for en baggrund bag mærket:
     headeren er gennemsigtig øverst på siden og får først sin bagflade
     ved scroll, så en farvet plade ville kun passe det ene sted. Masken
     virker begge steder, fordi den fjerner teksten i stedet for at dække
     den. Rampen på 2,5rem får teksten til at glide ind under mærket i
     stedet for at blive hugget af på en kant.
     --news-maerke måles af main.js; tallet her er kun reserve. */
  --hul-fra: calc(var(--news-kant) - var(--news-luft));
  --hul-til: calc(var(--news-kant) + var(--news-maerke, 5rem) + var(--news-luft));
  -webkit-mask-image: linear-gradient(to right,
    #000 0, #000 calc(var(--hul-fra) - 1.2rem),
    transparent var(--hul-fra), transparent var(--hul-til),
    #000 calc(var(--hul-til) + 1.2rem), #000 100%);
          mask-image: linear-gradient(to right,
    #000 0, #000 calc(var(--hul-fra) - 1.2rem),
    transparent var(--hul-fra), transparent var(--hul-til),
    #000 calc(var(--hul-til) + 1.2rem), #000 100%);
}
.site-news-track {
  display: inline-flex;   /* INGEN gap — -50%-loopet kræver at én kopi er
                             præcis halvdelen af sporets bredde */
  white-space: nowrap;
  animation: news-roll 38s linear infinite;
}
/* Kun RULLETEKSTEN skifter farve — samme som overskrifter på lys bund.
   18,97:1 mod hvid, hvor den hvide tekst ville forsvinde helt. Mærket og
   prikken til venstre bliver i volt. */
.site-news-track > span { color: var(--plum-900); font-size: inherit; }
.site-news-track i { font-style: normal; color: var(--volt); padding-inline: 1.1rem; }
@keyframes news-roll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .site-news-track { animation: none; }
  .site-news-mrk::before { animation: none; }
}
@media (max-width: 767.98px) {
  .site-news { --news-luft: 0.6rem; }
}

/* CTA-B'et rager ned under sektionen; footeren viser fortsættelsen som streg */
.s-final__mark {
  top: auto; bottom: -11.5%; transform: none; /* hvor langt B'et rager ned i footeren */
}
.site-footer { position: relative; overflow: hidden; }
.site-footer > .wrap { position: relative; z-index: 1; }
.footer__mark {
  position: absolute;
  width: clamp(336px, 40.8vw, 624px);
  opacity: 0.12;
  pointer-events: none;
  z-index: 0;
}
.footer__mark path { stroke-width: 1.6; }

/* ==========================================================================
   PRØVETIME-DIALOG — samme mørke kort som quizzen, så den føles som en
   forlængelse af samtalen og ikke som en systembesked.
   ========================================================================== */
.ptime {
  width: min(420px, calc(100vw - 2rem));
  padding: 1.75rem;
  border: none; border-radius: var(--radius-media);
  background: var(--plum-800);
  color: var(--bone);
  /* Centrering: browseren giver dialog:modal position: fixed + inset: 0
     + margin: auto — men vores globale reset (* { margin: 0 }) slår
     margin: auto ihjel, så inset: 0 klistrer kortet op i venstre hjørne.
     Derfor sættes margin: auto eksplicit her.
     Og INGEN position: relative — den ville tage kortet ud af den faste
     positionering og lægge det tilbage i dokumentflowet. Den faste
     position er i forvejen holdepunkt for .ptime__luk. */
  margin: auto;
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
}
.ptime::backdrop {
  background: color-mix(in srgb, var(--plum-900) 72%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.ptime__luk {
  position: absolute; top: 0.75rem; right: 0.75rem;
  width: 32px; height: 32px; line-height: 1;
  border-radius: 50%; color: var(--mist);
  font-size: 0.875rem;
}
.ptime__eyebrow { display: block; color: var(--volt); margin-bottom: 0.5rem; }
.ptime__titel {
  font-family: var(--font-display); font-weight: 700;
  font-synthesis-weight: none;
  text-transform: uppercase; line-height: 0.8;
  font-size: clamp(1.75rem, 1.4rem + 1.75vw, 3rem);
  margin-bottom: 0.85rem;
}
/* Holdnavn og tidspunkt over hinanden — tidspunktet er det man scanner efter.
   Dåsen står i samme boks ude til højre: den hører til DET hold, ikke til
   dialogen som helhed. Teksten har sin egen wrapper, fordi main.js tømmer
   den ved hver åbning — uden wrapperen ville dåsen ryge med.
   Dåsen og linjen om drikken vises KUN når dialogen er åbnet fra quiz-
   kortets CTA (.ptime--fra-quiz, sat af main.js) — så kan man se på
   hvor mange der får den, hvor mange der bruger quizzen. */
.ptime__hold {
  display: grid; grid-template-columns: 1fr;
  align-items: center; column-gap: 1rem;
  padding: 0.85rem 1rem; margin-bottom: 0.85rem;
  border: 1px solid var(--rule); border-radius: var(--radius-media);
}
.ptime--fra-quiz .ptime__hold { grid-template-columns: 1fr auto; }
.ptime__praemie, .ptime__drink { display: none; }
.ptime--fra-quiz .ptime__praemie { display: flex; align-items: center; gap: 0.6rem; }
.ptime--fra-quiz .ptime__drink { display: block; }
.ptime__praemie > i { font-style: normal; color: var(--bone); font-size: 0.75rem; white-space: nowrap; }
.ptime__holdtekst { display: grid; gap: 2px; }
.ptime__holdtekst > b { font-size: 1.0625rem; font-weight: 600; }
.ptime__holdtekst > span {
  font-family: var(--font-mono); font-size: 0.6875rem;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--volt);
}
.ptime__hold .daase { --d: 18px; }
/* Drikken er et tillæg, ikke et argument: kort og i mist, lige under
   holdboksen så den hører til dét hold. */
.ptime__drink {
  font-size: 0.875rem; line-height: 1.5;
  color: var(--mist); margin-bottom: 0.85rem;
}
/* Det praktiske står lysere og lidt større end forbeholdet under —
   det er beskeden man skal handle på */
.ptime__praktisk {
  font-size: 0.9375rem; line-height: 1.5;
  color: var(--bone); margin-bottom: 0.6rem;
}
.ptime__praktisk b { font-weight: 600; color: var(--volt); }
.ptime__note {
  font-size: 0.875rem; line-height: 1.55;
  color: var(--mist); margin-bottom: 1.25rem;
}
.ptime__note b { color: var(--bone); font-weight: 600; }
.ptime__actions { display: grid; gap: 0.5rem; }
.ptime__actions .btn { width: 100%; }

/* ==========================================================================
   KAMP-DIALOGEN — bag mini-fightcardet i headeren. Samme kort som
   prøvetime-dialogen (.ptime: flade, kant, lukkeknap, slør), bare bredere:
   to portrætter side om side og rækker under kræver plads. min() holder
   den inden for skærmen med 1rem luft; indholdet ruller, hvis det bliver
   højere end skærmen (.ptime har max-height + overflow). Reglerne står
   EFTER .ptime og vinder på rækkefølgen.
   Ét afsnit pr. event: navn, dato og sted, første events første kamp
   stort (kæmper – vs – kæmper), de øvrige kampe som rækker, og eventets
   knapper to og to.
   ========================================================================== */
/* SÆT ALDRIG display på <dialog> her: en egenskab fra os slår browserens
   egen "dialog:not([open]) { display: none }" ihjel, og så stod kortet
   åbent nederst på forsiden. Kortet ruller som ét hele (.ptime har
   max-height + overflow-y), og hvert event beholder sine egne knapper —
   billet- og streamlink er forskellige fra event til event.
   Rullepanelet males i kortets egen flade med footerens mørkeste tone som
   indikator, så det ikke står som en lys stribe i et mørkt kort. */
.kamp {
  width: min(34rem, calc(100vw - 2rem));
  scrollbar-width: thin;
  scrollbar-color: var(--plum-950) var(--plum-800);
}
.kamp::-webkit-scrollbar { width: 10px; }
.kamp::-webkit-scrollbar-track { background: var(--plum-800); }
.kamp::-webkit-scrollbar-thumb {
  background: var(--plum-950); border-radius: 999px;
  border: 2px solid var(--plum-800);
}
/* minmax(0, 1fr): en lang ubrydelig tekst (et domæne i fightcard-linket)
   må ikke kunne gøre kortet bredere end skærmen */
.kamp__events { display: grid; grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
.kamp__event { min-width: 0; }
.kamp__event + .kamp__event { padding-top: 1.5rem; border-top: 1px solid var(--rule); }
/* Arrangørens ordmærke som overskrift — ellers navnet, på én linje når
   det kan (ingen kunstig maksbredde; det ombryder kun i nød). */
/* Logoet står stort og midt i kortet; linjerne under følger med i midten */
.kamp__logo { display: block; height: 3.6rem; width: auto; max-width: 100%; margin: 0.25rem auto 0.9rem; }
.kamp__logo ~ .kamp__meta, .kamp__logo ~ .kamp__fightcard { text-align: center; }
.kamp__logo ~ .kamp__fightcard { display: block; width: fit-content; max-width: 100%; margin-inline: auto; }
.kamp__titel {
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  text-transform: uppercase; line-height: 0.85;
  font-size: clamp(1.75rem, 1.4rem + 1.75vw, 3rem);
  margin-bottom: 0.6rem;
}
.kamp__meta {
  color: var(--mist); font-size: 0.6875rem; letter-spacing: 0.08em;
  line-height: 1.6; margin-bottom: 0.35rem;
}
/* Linktekst til fight cardet, under eventets overskrift */
.kamp__fightcard {
  display: inline-block; margin-bottom: 1.25rem;
  font-size: 0.6875rem; letter-spacing: 0.08em; color: var(--bone);
  text-decoration: none; border-bottom: 1px solid var(--rule-strong); padding-bottom: 1px;
}
/* Duellen: kæmper – midte – kæmper. Portrættet øverst, navnet under, og
   land og rekord i mono nederst. Midten: titelkamp (cyan) over "vs",
   vægtklasse under (mist), og en lille artikelknap nederst. */
.kamp__duel {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: start; gap: 0.75rem;
  margin-bottom: 1.25rem;
}
.kamp__duel + .kamp__duel { padding-top: 1.25rem; border-top: 1px solid var(--rule); }
.kamp__kaemper { display: grid; justify-items: center; text-align: center; gap: 0.5rem; min-width: 0; }
/* Portræt: rund beskæring i .kamp__foto, og klubbens B som mærke uden for
   beskæringen, nederst til højre (kun på klubkæmpere, sat af main.js) */
.kamp__portraet { position: relative; display: block; width: 5.5rem; }
.kamp__foto {
  position: relative; display: block; width: 100%; aspect-ratio: 1;
  border-radius: 50%; overflow: hidden;
  border: 1px solid var(--rule); background: var(--plum-900);
}
/* Initialer bag billedet — og "?" når modstanderen er TBA */
.kamp__foto b {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  font-size: 2rem; letter-spacing: 0.04em; color: var(--mist);
}
.kamp__foto img {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center top;
}
.kamp__klub {
  position: absolute; right: -4%; bottom: -2%; width: 30%; height: auto;
  filter: drop-shadow(0 2px 4px color-mix(in srgb, #000 60%, transparent));
}
.kamp__navn {
  font-family: var(--font-display); font-weight: 700; font-synthesis-weight: none;
  font-size: 1.35rem; line-height: 1; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--bone);
}
.kamp__sub { font-size: 0.625rem; letter-spacing: 0.1em; color: var(--mist); }
.kamp__midt {
  display: grid; justify-items: center; gap: 0.4rem; text-align: center;
  /* Smal nok til at vægtklassen ombryder, så to portrætter og midten kan
     stå ved siden af hinanden på 320px */
  max-width: 7rem; min-width: 0;
  padding-top: calc(2.75rem - 1.4em); /* "vs" omkring portrættets midte (5,5rem højt) */
}
.kamp__titelkamp { font-size: 0.5625rem; letter-spacing: 0.14em; line-height: 1; color: var(--volt); }
.kamp__vs { font-style: normal; font-size: 0.625rem; letter-spacing: 0.2em; line-height: 1; color: var(--mist); }
.kamp__vaegt { font-size: 0.5625rem; letter-spacing: 0.12em; line-height: 1.4; color: var(--mist); }
/* Den lille artikelknap: samme stille stil som "Se alle hold", bare mindre */
.kamp__artikel {
  display: inline-block; margin-top: 0.15rem;
  padding: 6px 11px; border: 1px solid var(--rule-strong); border-radius: var(--radius-control);
  font-family: var(--font-body); font-weight: 500; font-size: 0.6875rem; line-height: 1.2;
  color: var(--bone); text-decoration: none; white-space: nowrap;
}
/* De ikke-fremhævede kampe: samme opsætning, mindre portræt og navn */
.kamp__duel--lille .kamp__portraet { width: 3.5rem; }
.kamp__duel--lille .kamp__foto b { font-size: 1.25rem; }
.kamp__duel--lille .kamp__navn { font-size: 1.05rem; }
.kamp__duel--lille .kamp__midt { padding-top: calc(1.75rem - 1.4em); }
/* Aflyst kamp (data: "aflyst": true): kæmperne tonet ned i gråt og en
   streg henover portrætbåndet med AFLYST i midten. Højden følger
   portrættets, så stregen altid ligger midt på ansigterne. Artiklen, der
   forklarer aflysningen, står uændret og klikbar ovenpå. */
.kamp__duel--aflyst { --portraet: 5.5rem; position: relative; }
.kamp__duel--aflyst .kamp__kaemper,
.kamp__duel--aflyst .kamp__vaegt { opacity: 0.4; filter: grayscale(1); }
/* "vs" giver ingen mening i en aflyst kamp, og artikelknappen rykker ned
   under stregen, ud for navnene, så den ikke støder op i AFLYST */
.kamp__duel--aflyst .kamp__vs { display: none; }
/* Dobbelt klasse: mobilreglen for .kamp__duel--lille .kamp__midt står senere */
.kamp__duel.kamp__duel--aflyst .kamp__midt { padding-top: calc(var(--portraet) + 0.5rem); }
.kamp__duel--aflyst .kamp__artikel { position: relative; z-index: 2; margin-top: 0; }
.kamp__aflyst {
  position: absolute; left: 0; right: 0; top: 0; z-index: 1;
  height: var(--portraet);
  display: flex; align-items: center; gap: 0.75rem;
  font-size: 0.6875rem; letter-spacing: 0.2em; line-height: 1; text-transform: uppercase;
  color: var(--bone); pointer-events: none;
}
.kamp__aflyst::before,
.kamp__aflyst::after { content: ""; flex: 1; border-top: 1px solid var(--bone); }
.kamp__duel--aflyst.kamp__duel--lille { --portraet: 3.5rem; }
/* Kampe under en anden kamp har polstring foroven (skillelinjen) */
.kamp__duel + .kamp__duel .kamp__aflyst { top: 1.25rem; }
@media (max-width: 480px) {
  .kamp__duel--aflyst { --portraet: 4.25rem; }
  .kamp__duel--aflyst.kamp__duel--lille { --portraet: 3rem; }
}
/* Knapperne: to ved siden af hinanden, mindre end sidens store knapper.
   Farverne følger deres slægtninge: billet som Gratis prøvetime, stream
   som Tilmelding. */
.kamp__knapper { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.kamp__knapper .btn { padding: 10px 12px; font-size: 0.8125rem; white-space: nowrap; }
/* Små skærme: mindre polstring og portrætter, så to kæmpere og midten kan
   stå ved siden af hinanden på 320px */
@media (max-width: 480px) {
  .kamp { padding: 1.25rem; }
  .kamp__logo { height: 2.8rem; }
  .kamp__portraet { width: 4.25rem; }
  .kamp__foto b { font-size: 1.5rem; }
  .kamp__navn { font-size: 1.15rem; }
  .kamp__midt { padding-top: calc(2.125rem - 1.4em); max-width: 6rem; }
  .kamp__duel--lille .kamp__portraet { width: 3rem; }
  .kamp__duel--lille .kamp__midt { padding-top: calc(1.5rem - 1.4em); }
  .kamp__knapper .btn { padding: 10px 8px; font-size: 0.75rem; }
}
