/* SumoVolley.io — homepage.
 *
 * ⚠️ STAAT BEWUST LOS VAN style.css EN themes.css. Die twee dragen de acht
 * spelkleuren, de laddersystematiek en honderd componenten die hier niet
 * voorkomen; ze meeladen zou de eerste verf van een marketingpagina laten wachten
 * op de opmaak van een heel spel. Deze pagina heeft ÉÉN ontwerp in twee standen.
 *
 * ⚠️ ALLES HANGT AAN `[data-mode]`, nooit aan een themanaam. Het pre-paint-script
 * in de <head> zet dat attribuut vóór de eerste verf — uit een opgeslagen keuze,
 * anders uit de voorkeur van het toestel.
 */

/* ⚠️ DE LICHTE STAND IS HET `day`-THEMA VAN HET SPEL, LETTERLIJK OVERGENOMEN.
   `themes.css` bouwt zijn lichte ladder uit twee getallen — `--th-h: 214` en
   `--th-s: 40%` voor `day` — en daaruit volgen alle vlakken. Die uitkomsten staan
   hieronder uitgerekend, zodat de homepage dezelfde blauwtint draagt als de arena
   zonder dat hij `themes.css` hoeft te laden (dat bestand draagt acht kleuren en
   honderd componenten die hier niet voorkomen).

   ⚠️ VERANDERT `day` OOIT VAN TINT, DAN LOOPT DIT UIT DE PAS. Dat is de prijs van
   niet-meeladen, en hij is bewust genomen. Bij een wijziging: neem `--th-h` en
   `--th-s` uit `themes.css` en reken deze zes opnieuw uit met dezelfde
   lichtheden — die staan er per regel bij.

   ⚠️ `--dim` IS BEWUST DONKERDER DAN `--text-dim` UIT HET SPEL (54%). In het spel
   staat die tekst op een paneel van 85-90%; hier staat hij op de PAGINA van 78%,
   en dan haalt 54% de leesbaarheidsdrempel van 4,5:1 niet. Op 30% wel. */
:root {
    --bg:       hsl(214, 40%, 78%);   /* = --bg-page        (de paginakleur) */
    --surface:  hsl(214, 40%, 90%);   /* = --panel-surface  (kop, kaarten, voet) */
    --alt:      hsl(214, 40%, 85%);   /* = --bg-panel       (de om-en-om banden) */
    --ink:      hsl(214, 30%, 13%);   /* = --text-primary */
    --dim:      hsl(214, 20%, 30%);   /* donkerder dan --text-dim — zie noot */
    --line:     hsl(214, 40%, 76%);   /* = --border-row */
    --accent:   #1e6fd9;
    --gold:     #f5c518;
    --gold-ink: #2a2202;
    --glass:    hsla(214, 40%, 93%, .8);
    --shadow:   0 1px 2px hsla(214, 30%, 13%, .07), 0 8px 24px hsla(214, 30%, 13%, .09);
    --m1: #c23a52;
    --m2: #245fa8;
    --m3: #6a44b0;
    /* De scrollbalk — zie de noot bij `::-webkit-scrollbar`. */
    --scroll-goot:    hsl(214, 40%, 88%);
    --scroll-duim:    hsl(214, 26%, 62%);
    --scroll-duim-op: hsl(214, 28%, 48%);
}

:root[data-mode="dark"] {
    --bg:       #0f1a2b;
    --surface:  #16233a;
    --alt:      #132032;
    --ink:      #eef3fa;
    --dim:      #9cb0c9;
    --line:     #24344d;
    --accent:   #6ab0ff;
    --gold:     #f5c518;
    --gold-ink: #2a2202;
    --glass:    rgba(20, 32, 54, .74);
    --shadow:   0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .35);
    --m1: #ef6b83;
    --m2: #63a8e8;
    --m3: #a487e0;
    --scroll-goot:    #16233a;
    --scroll-duim:    #3d5170;
    --scroll-duim-op: #56719b;
}

/* ── Het raster en de fijne lijnen, net als op het inlogscherm ──────────────
   ⚠️ TWEE VERSCHILLENDE LAGEN, en ze doen iets anders:

     `body::after`   het RASTER van 40x40 — ACHTER alles (z-index -1), zoals
                     `.grid-bg` op login, privacy en de 404. Geeft de pagina diepte
                     zonder ergens overheen te liggen.
     `body::before`  de fijne HORIZONTALE lijnen — een vaste laag OVER de hele
                     pagina (z-index 150), precies als op login: boven de kop en de
                     secties, onder de menu's (200) en de vensters.

   ⚠️ EN DE KOP DRAAGT ER EEN EIGEN KOPIE VAN (`.top::before`). Die moet namelijk
   BOVEN de schermafdrukken liggen, en die liggen zelf boven de lijnen — dus de kop
   komt boven de laag uit en zou hem anders missen. Zie de noot bij de z-index van
   `.top`. De laag over de pagina heeft een tijdje ALLEEN in de kop gezeten en dat
   was te weinig: zonder de rest blijft van het raster een patroon van grote
   vierkanten over. De schermafdrukken zijn apart opgetild (`.shot img`) — dáár was
   de redenering wél juist, want een foto van het spel hoort geen lijnen te dragen.

   ⚠️ De waarden zijn overgenomen uit login.html, met `day` (h=214) ingevuld — de
   homepage heeft één ontwerp in twee standen en dus geen `--th-h`. Verandert die
   tint daar ooit, dan loopt dit uit de pas; zie de noot bovenin dit bestand, waar
   dat al voor zes andere kleuren geldt. */
:root {
    --grid-line: hsla(214, 50%, 30%, .06);
    --scanline:  hsla(214, 40%, 20%, .04);
}
:root[data-mode="dark"] {
    --grid-line: rgba(255, 255, 255, .05);
    --scanline:  rgba(0, 0, 0, .08);
}
/* ⚠️ `z-index: -1` EN NIET 0. Een geplaatst element met z-index 0 tekent BOVEN de
   gewone inhoud van de pagina — dan ligt het raster over de tekst in plaats van
   erachter. Negatief zet het achter de inhoud maar nog vóór de achtergrond van
   `body`, en dat is precies de laag die we willen. */
body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 40px 40px;
}
/* ⚠️ OVER DE HELE PAGINA, PRECIES ZOALS OP LOGIN. Deze laag heeft eerst alleen in
   de kop gezeten, met als redenering dat lijnen over veertien schermafdrukken en
   de illustratie iets anders zijn dan lijnen over een egaal inlogkaartje. Dat is
   op 2026-09-02 teruggedraaid: zonder die lijnen blijft van het raster alleen een
   patroon van grote vierkanten over, en dan lijkt de pagina niet meer op de
   voordeur ernaast. De secties onderaan dragen bovendien hetzelfde vlak als de kop
   en zagen er dan anders uit dan die kop.

   ⚠️ z-index 150, hetzelfde getal als op login, en om dezelfde reden: boven de kop
   (20) en de secties, onder de twee menu's die daar net voor opgetild zijn. Een
   open menu hoort schoon te zijn. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 150;
    pointer-events: none;
    background: repeating-linear-gradient(
        to bottom,
        transparent 0px, transparent 3px,
        var(--scanline) 3px, var(--scanline) 4px);
}

* { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    /* ⚠️ SAMEN MET DE SCROLLBALK HIERONDER HOUDT DIT HET LOGO OP DEZELFDE PLEK ALS
       OP HET INLOGSCHERM. Deze pagina is lang en heeft altijd een balk, die pagina
       past meestal op één scherm en heeft er geen — en de kop centreert met
       `margin: auto` binnen de beschikbare breedte, die daardoor ~10px verschilde.
       Het gevolg was niet te zien op één pagina, wél bij het wisselen van tabblad:
       dan trilde het merk (gemeld 2026-09-02). `stable` reserveert de ruimte altijd,
       dus beide pagina's rekenen met hetzelfde. De volledige redenering staat in
       `login.html` bij de `html`-regel. */
    scrollbar-gutter: stable;
}
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* ⚠️ EXACT DEZELFDE MATEN ALS OP HET INLOGSCHERM, en de BREEDTE is wat telt: de
   gereserveerde ruimte hierboven is zo breed als de balk zelf, dus met 10px daar en
   de systeembreedte (~15px) hier zouden de twee koppen alsnog een paar pixels uit
   elkaar liggen. De kleuren komen wél uit de thema-tokens — het inlogscherm heeft
   vaste wit-alpha's die op deze lichte pagina onzichtbaar zouden zijn.

   Bijvangst: de schuifrij met schermafdrukken krijgt dezelfde balk. Die had al
   `scrollbar-width: thin` voor Firefox; dat blijft, want die eigenschap raakt de
   webkit-regels niet. */
/* ⚠️ DE DUIM STOND OP `--line`, EN DAT IS DE KLEUR VAN EEN RANDJE. Op de lichte
   stand (76% lichtheid) tegen een goot van 85% is dat vrijwel niet te zien; een
   scrollbalk moet juist opvallen tegen zijn achtergrond. Nu een eigen token per
   stand, ongeveer halverwege tussen de rand en de tekstkleur. */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--scroll-goot); }
::-webkit-scrollbar-thumb {
    background: var(--scroll-duim);
    border-radius: 5px;
    min-height: 40px;
}
::-webkit-scrollbar-thumb:hover { background: var(--scroll-duim-op); }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: 'Cascadia Code', ui-monospace, 'Courier New', monospace;
    font-size: 15px;
    line-height: 1.65;
    -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.2; margin: 0; }
p { margin: 0; }
img { max-width: 100%; height: auto; }

a { color: var(--accent); }

/* ⚠️ DE AANRAAK-FLITS VAN DE BROWSER IS ALTIJD EEN RECHTHOEK, ook om een knop die
   volledig rond is. Op een telefoon zag je bij een tik op het maantje, de wereldbol
   of de naamknop een blauw VIERKANT achter een ronde pil verschijnen (gemeld met
   een foto, 2026-09-02). Hij is niet te vormen — alleen uit te zetten.

   ⚠️ EN DAN MOET ER IETS VOOR IN DE PLAATS KOMEN. Zonder terugkoppeling weet je op
   een aanraakscherm niet of je tik geregistreerd is; `:hover` bestaat daar niet.
   Vandaar de `:active`-stand hieronder: hij volgt de eigen vorm van de knop, dus
   rond blijft rond. Zet die twee dus altijd samen. */
a, button, .btn, .icon-btn { -webkit-tap-highlight-color: transparent; }
.btn:active, .icon-btn:active { transform: scale(0.96); }
.btn, .icon-btn { transition: transform .08s ease; }
@media (prefers-reduced-motion: reduce) {
    .btn, .icon-btn { transition: none; }
    /* Geen schaal, maar wél terugkoppeling — anders is er bij uitgezette beweging
       helemaal niets meer te zien van een tik. */
    .btn:active, .icon-btn:active { transform: none; filter: brightness(0.93); }
}

/* Zichtbare focus, overal. Een marketingpagina is vaak het eerste wat iemand met
   een toetsenbord tegenkomt. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

.skip {
    position: absolute;
    left: -9999px;
}
.skip:focus {
    left: 12px; top: 12px; z-index: 50;
    background: var(--surface); color: var(--ink);
    padding: 10px 16px; border-radius: 8px; border: 1px solid var(--line);
}

/* ── Knoppen ───────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;              /* raakbaar met een duim */
    padding: 0 20px;
    border: 1px solid var(--line);
    border-radius: 999px;   /* volledig rond, net als de icoonknoppen */
    background: transparent;
    color: var(--ink);
    font: inherit;
    font-size: .88em;
    letter-spacing: .5px;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}
.btn-primary {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--gold-ink);
    font-weight: bold;
}
.btn-ghost   { background: var(--surface); }
.btn-lg      { min-height: 52px; padding: 0 26px; font-size: .95em; }

.icon-btn {
    position: relative;                /* draagt het onzichtbare raakvlak hieronder */
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--surface); color: var(--ink);
    font: inherit; font-size: .74em; letter-spacing: .5px; cursor: pointer;
    flex: none;                        /* nooit samenpersen — zie `.brand-mark` */
}
/* De huisknop is een LINK en geen knop: het is navigatie, dus middenklik, "openen
   in nieuw tabblad" en de statusbalk horen te werken. Daardoor heeft hij twee
   dingen nodig die een `<button>` niet heeft. */
#home-btn { text-decoration: none; }
#home-btn img { width: 17px; height: 17px; }

/* ⚠️ DE TAALKNOP IS EEN PIL EN GEEN ROND KNOPJE, en dat is een bewuste
   gelijktrekking met het inlogscherm (Burak, 2026-09-02). Daar stond al een pil
   met een wereldbol en de taalcode erin; hier stonden alleen twee letters in een
   cirkel van 34px. Dezelfde functie op twee pagina's die je direct na elkaar ziet
   hoorde er niet anders uit te zien — en de bol zegt "taal" zonder dat je die
   twee letters hoeft te lezen.

   ⚠️ HET RONDE KNOPJE BLIJFT VOOR HET THEMA, en dat is geen inconsistentie die
   nog opgeruimd moet worden: die knop toont hier een maantje (twee standen) en op
   het inlogscherm een palet (acht kleuren). Verschillende dingen mogen er
   verschillend uitzien; dezelfde dingen niet.

   `width: auto` moet expliciet, want `.icon-btn` legt 34px vast. */
.icon-btn.lang-btn {
    width: auto;
    gap: 5px;
    padding: 0 11px;
    letter-spacing: .5px;
}
.icon-btn.lang-btn .emoji { width: 15px; height: 15px; }

/* ⚠️ HET RAAKVLAK IS GROTER DAN DE KNOP, en dat is hoe je klein én bruikbaar
   combineert. Eerst stonden deze knoppen op een aanraakscherm gewoon op 44px,
   maar dan vullen twee ervan naast Play Now de hele kopregel — precies wat er
   gemeld is. Nu blijven ze visueel 34px en steekt een onzichtbaar vlak eromheen
   uit tot 44: een duim raakt hetzelfde oppervlak, het oog ziet een kleine knop.
   Zelfde patroon als `.m-rail .m-toggle::before` in het spel.
   `pointer: coarse` en niet schermbreedte: een aanraaktablet van 1200px heeft
   dezelfde duim als een telefoon. */
@media (pointer: coarse) {
    .icon-btn::before {
        content: ''; position: absolute;
        top: 50%; left: 50%; transform: translate(-50%, -50%);
        width: 44px; height: 44px;
    }
    .top .btn { min-height: 40px; }
}

/* De knoppen IN de kop zijn compacter dan die in de hero: daar zijn ze het
   onderwerp, hier begeleiden ze alleen. */
.top .btn { min-height: 36px; padding: 0 15px; font-size: .82em; }

/* Eén knop, twee iconen: laat zien waar je NAARTOE gaat. */
:root[data-mode="light"] .ico-light,
:root:not([data-mode="dark"]) .ico-light { display: none; }
:root[data-mode="dark"] .ico-dark { display: none; }

/* ── Kop ───────────────────────────────────────────────────────────────── */

/* ⚠️ ÉÉN KOP, TWEE VORMEN. Bovenaan een gewone balk over de volle breedte; op een
   smal scherm krimpt hij voorbij de hero tot een zwevende pil met alleen de
   knoppen erin. Dat gebeurt volledig hier — `home.js` zet één klasse.

   De alternatieve opzet (kop laten wegscrollen en er een apart compact balkje
   onder schuiven) zou dezelfde twee knoppen een tweede keer in de HTML zetten,
   met dezelfde teksten uit dezelfde sleutels. Dat is de valkuil waar dit project
   herhaaldelijk op is stukgelopen; vandaar één element dat van vorm verandert.

   ⚠️⚠️ MAAR DE HOOGTE VAN DIE KOP MAG NOOIT VERANDEREN. Hier zat een bug die het
   hele scherm liet flikkeren en de pagina terugduwde bij het scrollen, en de
   oorzaak is de moeite waard om te onthouden:

     1. de kop is `sticky`, dus hij houdt zijn plek in de STROOM
     2. de compacte stand veranderde zijn hoogte (andere padding, geen onderrand)
     3. daardoor schoof ALLES eronder een paar pixels — inclusief het blokje
        waaraan de waarnemer meet
     4. dat blokje kwam weer over de grens, de klasse ging eraf, de kop groeide,
        het blokje schoof terug… en dat honderd keer per seconde

   Een lus die zichzelf voedt: de meting bepaalt de hoogte, en de hoogte bepaalt
   de meting. Twee sloten ertegen — hieronder verandert alleen nog wat GEEN hoogte
   kost (achtergrond, randkleur, schaduw en breedte), en het
   meetblokje staat buiten de stroom (zie `#top-sentinel`). Verander je hier iets
   aan `padding-top/bottom`, `height` of `border-*-width`, dan is de flikkering
   terug. */
/* ⚠️ EXACT ZO HOOG ALS DE SPELHEADER: 56px, de waarde van `--header-h` in
   style.css, met dezelfde `padding: 0 16px`. Zo lopen de twee schermen in elkaar
   over als je van de homepage naar de arena gaat.

   Dat de hoogte nu EXPLICIET is in plaats van uit padding volgt, is meteen een
   sterker slot op de waarschuwing hierboven: met `box-sizing: border-box` zitten
   padding én rand in die 56px, dus er is geen instelling meer die de hoogte per
   ongeluk kan verschuiven. */
/* ⚠️ 160 EN NIET 20, EN DAT IS EEN STAPELINGS-BESLISSING MET TWEE GEVOLGEN.
   De schermafdrukken liggen op 151 om boven de lijnen-laag (150) uit te komen; met
   de kop op 20 schoven ze bij het scrollen dus over de drie knoppen heen (gemeld
   2026-09-02). En omdat `.top` met een z-index een eigen stacking-context maakt,
   waren de twee menu's erin (200) in werkelijkheid óók opgesloten onder die
   lijnen-laag — die 200 telde alleen bínnen de kop.

   Boven de lijnen komen betekent wel dat de kop ze niet meer krijgt. Vandaar het
   `::before` hieronder: de kop draagt zijn eigen kopie. Dat is dezelfde opzet als
   waar deze pagina uit vertrokken is, alleen nu naast de laag over de pagina in
   plaats van in plaats daarvan. */
.top {
    position: sticky; top: 0; z-index: 160;
    display: flex; align-items: center;
    height: 56px;
    padding: 0 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    transition: background .28s ease, border-color .28s ease;
}
/* De eigen kopie van de fijne lijnen — zie de noot bij de z-index hierboven.
   Alleen zinvol zolang de kop een VLAK is: is hij doorzichtig (de compacte pil, en
   op een telefoon altijd), dan zouden deze lijnen los over de pagina hangen naast
   de laag die er toch al ligt. Die twee uitzonderingen staan bij hun eigen blok. */
.top::before {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: repeating-linear-gradient(
        to bottom,
        transparent 0px, transparent 3px,
        var(--scanline) 3px, var(--scanline) 4px);
}
/* ⚠️⚠️ EN ER ANIMEERT GEEN ENKELE BREEDTE MEE. Dat is de tweede bug van deze kop,
   en hij is een andere dan de flikkering hierboven.
   Bij het omschakelen veranderden DRIE breedtes tegelijk: het woordmerk kromp naar
   nul, de bal groeide van nul naar 28, en de pil zelf trok samen naar
   `max-content` en hercentreerde zich. Drie animaties die om dezelfde ruimte
   vechten, dus je zag de bal naar links reizen, het logo vervagen, en aan het eind
   alles nog een keer terugschuiven naar het midden.

   De oplossing is niet ze op elkaar afstemmen — dat is precies het soort
   afstelwerk dat bij de eerstvolgende tekstlengte weer scheef staat. De
   OMSCHAKELING IS NU INSTANT, en alleen wat GEEN layout raakt animeert:
   achtergrond, randkleur en schaduw. Eén frame verandert de vorm, daarna komt het
   glas er in 0,28s overheen.

   ⚠️ Zet `max-width`, `padding`, `width`, `gap` of `opacity` van de merktekens
   NOOIT terug in een `transition`. Alles wat in deze balk van breedte verandert,
   verandert de plek van alles ernaast. */
.top-inner {
    display: flex;
    align-items: center;
    gap: 20px;
    flex: 1;                       /* de kop is nu zelf een flex-rij */
    min-height: 36px;
    max-width: 1160px;
    margin: 0 auto;
    padding: 0 10px;               /* in BEIDE standen gelijk */
    border: 1px solid transparent; /* óók in de volle stand, anders springt de hoogte */
    border-radius: 999px;
    transition: background .28s ease, border-color .28s ease, box-shadow .28s ease;
}

/* ⚠️ DE PIL ALLEEN OP SMALLE SCHERMEN. Op een bureaublad is er ruimte zat en is
   een gewone balk rustiger; daar voegt het krimpen niets toe. De klasse wordt
   door `home.js` altijd gezet — dat scheelt een tweede plek die over breedte
   moet beslissen — maar hij DOET alleen iets binnen deze media-query. Zo volgt
   een venster dat je breder sleept vanzelf, zonder dat er JavaScript aan te pas
   komt. */
/* ⚠️ HIER ZAT EEN ZAK-ANIMATIE VOOR DE COMPACTE PIL (`pil-zakt`, 0,26s), en die
   is er samen met de intree van het inlogscherm uit (Burak, 2026-09-03): geen
   animaties op de publieke pagina's. De vorm wisselt nu in één beeld, precies zoals
   het woordmerk en de nav dat al deden — die stonden hier bewust al zonder overgang,
   omdat drie breedtes die tegelijk animeren langs elkaar heen schuiven.
   Het glas eromheen verschijnt nog wel zacht: dat is een `transition` op
   achtergrond, rand en schaduw, en die raken de layout niet. */

@media (min-width: 721px) and (max-width: 900px) {
    html.top-pil .top { background: transparent; border-bottom-color: transparent; }
    html.top-pil .top::before { display: none; }   /* geen vlak = geen eigen lijnen */
    html.top-pil .top-inner {
        /* ⚠️ DE PIL HOORT OM ZIJN INHOUD TE SLUITEN, MET HET SCHERM ALS DAK.
           Zonder dak is hij precies zo breed als zijn inhoud — en sinds de knop
           "Verder als <naam>" kan zeggen is dat op een telefoon breder dan het
           scherm. Hij is gecentreerd (`margin: 0 auto`), dus hij steekt dan aan
           BEIDE kanten uit, en alles erin wordt door flex samengeperst: de bal
           werd een ovaal en het taalmenu opende ergens links buiten de knop.

           ⚠️ HIER STOND `max-width: min(max-content, calc(100vw - 24px))`, EN DAT
           IS ONGELDIGE CSS. Intrinsieke sleutelwoorden als `max-content` mogen niet
           IN een rekenfunctie staan — `min()` rekent met lengtes. De hele regel
           werd dus weggegooid, en dan blijft `max-width: 1160px` met `flex: 1`
           staan: de pil liep over de volle breedte. Zichtbaar als een brede strook
           achter de knopjes zodra je scrollde (gemeld 2026-09-02). Het verraderlijke
           is dat het probleem dat de regel moest oplossen — een pil die het scherm
           uit stak — er óók door verdween: volle breedte steekt nergens uit. De fix
           leek dus te werken en deed niets.

           Nu in twee eigenschappen die allebei geldig zijn: `width: max-content`
           laat hem om zijn inhoud sluiten, `max-width` is het dak. En `flex` moet
           mee terug naar `0 1 auto` — met `flex: 1` groeit hij alsnog tot het dak,
           ongeacht zijn breedte. */
        flex: 0 1 auto;
        width: max-content;
        max-width: calc(100vw - 24px);
        gap: 14px;
        background: var(--glass);
        /* -webkit- voor Safari; zonder blur valt hij terug op de halfdoorzichtige
           vlakkleur hierboven, en dat is nog steeds leesbaar. */
        -webkit-backdrop-filter: blur(14px) saturate(1.6);
        backdrop-filter: blur(14px) saturate(1.6);
        border-color: var(--line);
        box-shadow: var(--shadow);
    }
    /* Het WOORDMERK verdwijnt door z'n breedte, niet door `display: none` — dat
       laatste springt, dit schuift mee. De bal blijft: een kop zonder enig
       merkteken zag er kaal uit, en dan is er niets meer dat zegt waar je bent. */
    /* ⚠️ IN DE PIL VERVALT DE TAALCODE EN BLIJFT DE BOL (Burak, 2026-09-02). De
       pil is de compacte stand; twee letters die je toch al aan de bol afleidt
       kosten daar breedte die de speelknop nodig heeft. De knop wordt dan weer
       rond, dus dezelfde vorm als de themaknop ernaast. */

    html.top-pil .brand-word { max-width: 0; opacity: 0; }
    html.top-pil .brand-mark { max-width: 28px; opacity: 1; }
    html.top-pil .nav        { max-width: 0; opacity: 0; overflow: hidden; margin: 0; gap: 0; }
}

/* ⚠️ BUITEN DE STROOM, EN DAT IS DE HELFT VAN DE REPARATIE. Stond dit blokje in
   de stroom onder de kop, dan verschuift het zodra de kop van hoogte verandert —
   precies de lus die hierboven beschreven staat. Absoluut geplaatst hangt het aan
   de documentoorsprong en kan geen enkele layout-wijziging het verplaatsen.
   90px: de pil komt pas als je echt aan het scrollen bent, niet bij een tikje. */
#top-sentinel {
    position: absolute; top: 0; left: 0;
    width: 1px; height: 90px;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .top, .top-inner, .nav { transition: none; }
}

/* ── DE SPEELKNOP STAAT ALTIJD IN DE KOP ───────────────────────────────────
 *
 * Er staan drie gouden knoppen op deze pagina: in de kop, in de hero en onderaan
 * na de argumenten. Dat is met opzet — je hoort er nooit naar te hoeven zoeken.
 *
 * ⚠️ HIJ IS ÉÉN VERSIE LANG VERBORGEN GEWEEST TOT JE GESCROLD HAD, en dat is op
 * 2026-09-02 teruggedraaid (Burak). De redenering was dat de kop en de hero
 * dezelfde knop herhalen zolang je bovenaan staat; dat klopt, maar een knop die
 * verschijnt en verdwijnt is duurder dan die herhaling. Bouw dat dus niet terug.
 *
 * ⚠️ DAARMEE IS HET LOGO WEER DE PARTIJ DIE MOET WIJKEN, en dat kan hier niet met
 * een vast breekpunt: sinds de knop "Verder als <naam>" kan zeggen is hij niet
 * meer van vaste breedte. Zie `html.cta-verder` verderop — het pre-paint-script zet die
 * klasse zodra hij het lange opschrift neerzet, en dán maakt het woordmerk plaats
 * voor de bal. Dat is een STAND en geen meting, dus er kan geen lus ontstaan.
 */

/* ⚠️ IN DE VOLLE BALK WORDT DE KNOP NOOIT AFGEKAPT. Hier stond een beletselteken
 * als vangnet, en dat sloeg te vroeg aan: op een gewoon bureaubladscherm las je
 * "Continue as Sculpt…", en een afgekapte knop in de kop laat de hele pagina
 * lezen alsof hij niet past (gemeld 2026-09-02). De knop is waar deze pagina voor
 * bestaat; hij hoort dus niet de partij te zijn die inlevert.
 *
 * Wat er wél inlevert staat hieronder: de drie nav-links verdwijnen zodra de knop
 * een naam draagt en het scherm smaller is dan 1100px. Dat is precies te bepalen,
 * want `html.cta-verder` zegt of dat lange opschrift er staat. */
.top-right [data-play] { flex: none; }
.top-right [data-play] .btn-lbl { white-space: nowrap; }

/* ⚠️ IN DE PIL MAG HIJ WÉL INKORTEN. Daar is de breedte begrensd op het scherm
 * (`width: max-content` met `max-width: 100vw - 24px`), dus met `flex: none` zou een lange naam er
 * dwars doorheen breken. Dit is het enige punt waar een beletselteken beter is
 * dan overloop. */
html.top-pil .top-right [data-play] { flex: 1 1 auto; min-width: 0; }
html.top-pil .top-right [data-play] .btn-lbl { overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 1100px) {
    html.cta-verder .nav { display: none; }
}

/* ⚠️ EN DAN MOET DE OVERLOOP ERGENS HEEN. Nu er niets in de kop meer kan krimpen,
   loopt de rij op een smal scherm met een lange naam gewoon het beeld uit. Op een
   telefoon is een afgekorte naam de goedkoopste van de twee fouten — daar is het
   woordmerk toch al een bal en telt elke pixel. Op een bureaublad blijft de knop
   onaangetast; dáár las een beletselteken als een pagina die niet past. */
@media (max-width: 640px) {
    /* ⚠️ `min-width: 0` MOET OOK OP `.top-right` ZELF, en dat was de fout. De knop
       mocht al krimpen, maar zijn OUDER niet: een flex-item staat standaard op
       `min-width: auto` en weigert dus onder zijn inhoud te zakken. De hele rechter
       groep bleef daardoor zo breed als de knop, en die liep het scherm uit met een
       lange naam (gemeld 2026-09-02). Zelfde soort fout als bij `.lang`, alleen een
       niveau hoger — zie valkuilen §71. */
    .top-right { min-width: 0; }
    .top-right [data-play] { flex: 1 1 auto; min-width: 0; }
    .top-right [data-play] .btn-lbl { overflow: hidden; text-overflow: ellipsis; }

    /* ⚠️ HIER VERDWEEN DE TAALCODE, EN DAT IS TERUGGEDRAAID (Burak, 2026-09-02).
       Hij viel weg zodra er een naam in de kop stond, om ruimte te maken toen het
       woordmerk daar ook nog stond. Sinds het merk op een telefoon in de PAGINA
       staat is die ruimte er, en dan is wegvallen alleen nog een verschil met het
       inlogscherm — daar staat hij wél. Dezelfde knop op twee schermen die je direct
       na elkaar ziet hoort er hetzelfde uit te zien. Hetzelfde gold in de compacte
       pil; die regel is om dezelfde reden weg. */
}

/* ⚠️ `min-width: 0` IS HIER GEEN OPSMUK. Een flex-item staat standaard op
   `min-width: auto`, en dat betekent "krimp nooit onder je eigen inhoud". Het logo
   hield daardoor zijn volle breedte en duwde Play Now buiten het scherm in plaats
   van zelf een stap terug te doen. Met deze regel schaalt het logo mee en blijft
   de knop staan — en dát is de juiste volgorde: de knop is waar de pagina voor
   bestaat, het logo is decoratie. */
.brand { display: flex; align-items: center; line-height: 0; min-width: 0; }
/* ⚠️ GEEN `transition` HIER. Deze twee wisselen elkaar af, en allebei nemen ze
   BREEDTE in — een overgang laat ze dus langs elkaar heen schuiven terwijl de
   knoppen ernaast meebewegen. Dat was zichtbaar als een bal die naar links reisde.
   Instant wisselen is hier het rustigst; het glas eromheen doet de zachtheid. */
.brand-word, .brand-mark { overflow: hidden; }
.brand-word { width: 180px; max-width: 100%; height: auto; }
/* In de volle balk is de bal er niet; hij komt pas in de pil. `max-width: 0`
   i.p.v. `display: none`: dat eerste laat hem geen ruimte innemen zonder dat de
   flex-rij van item-aantal verandert.

   ⚠️ `flex: none` IS WAT HEM ROND HOUDT. Een flex-item mag standaard krimpen, en
   de hoogte staat hier vast op 28px — dus zodra de rij te vol werd, werd de bal
   een ovaal. Hij is nagemeten en wel degelijk een perfecte cirkel (78,0% dekking
   tegen 78,5% theoretisch); de vervorming ontstond bij het tonen.
   `object-fit: contain` is het vangnet als hij tóch ooit een niet-vierkant vak
   krijgt: dan wordt hij kleiner in plaats van uitgerekt. */
.brand-mark {
    width: 28px; height: 28px; max-width: 0; opacity: 0;
    flex: none;
    object-fit: contain;
}

/* ⚠️ OOK HIER GEEN OVERGANG. De nav kromp mee naar nul, en dat was de VIERDE
   breedte die tegelijk bewoog. Zie de noot bij `.top-inner`. */
.nav {
    display: flex; gap: 22px; margin-left: 14px;
}
/* ⚠️ 13px EN NIET `.88em`. Deze rij staat óók op het inlogscherm, en daar is de
   basis-lettergrootte een andere (hier 15px, daar de browserstandaard, en op een
   smal scherm zelfs 18px). Dezelfde `em` levert dan drie verschillende maten op
   terwijl het twee koppen zijn die je direct na elkaar ziet. Was 13,2px; het
   verschil is onzichtbaar en de gelijkheid is dat niet. */
.nav a {
    color: var(--dim); text-decoration: none; font-size: 13px; letter-spacing: .5px;
    padding: 6px 0; border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--ink); border-bottom-color: var(--accent); }

.top-right { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* ⚠️ `flex: none` IS HIER DE HELE BUGFIX, EN HET GAAT NIET OVER BREEDTE MAAR OVER
   POSITIE. `.lang` was het enige item in `.top-right` dat nog mocht krimpen — de
   twee ronde knoppen en de speelknop staan allemaal op `flex: none`. Werd de rij
   te vol (een lange naam in de knop, bijvoorbeeld het Turkse "yoyo olarak devam
   et"), dan perste flex dít blokje naar bijna nul. De pil erin bleef zichtbaar
   staan, want die staat zelf op `flex: none` en steekt gewoon uit — maar het MENU
   hangt met `right: 0` aan de rechterrand van dit blokje, en die lag dan honderd
   pixels links van de knop die je aantikte. Zo opende het menu ergens links in
   beeld (gemeld 2026-09-02 op /tr).

   Het menu was dus nooit "te breed" of "verkeerd uitgelijnd": het hing correct aan
   een element dat op de verkeerde plek stond. */
.lang { position: relative; flex: none; }
/* ⚠️ EEN VLAG ALS `<img>` EN NIET ALS EMOJI-TEKEN — zie de noot bij `HOME_VLAG` in
   server.js: op Windows bestaat er geen vlag-glyph en tekent de browser er "GB" of
   "NL" van. `flex: none` omdat een vlag anders samengeperst wordt zodra een
   taalnaam de rij breed maakt; "Nederlands" en "Français" zijn de langste. */
.lang-flag { flex: none; width: 18px; height: 18px; border-radius: 2px; }

.lang-menu {
    position: absolute; right: 0; top: calc(100% + 8px);
    margin: 0; padding: 6px; list-style: none;
    min-width: 170px;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 10px;
    box-shadow: var(--shadow);
    z-index: 200;   /* boven de lijnenlaag (150) — een open menu hoort schoon */
}
/* ⚠️ DEZE REGEL STOND HIER AL, EN EEN TWEEDE `.lang-menu a` ERBOVEN DEED NIETS.
   De vlaggen kwamen erbij met een eigen regeltje (`display: flex; gap: 9px`) een
   paar regels hoger — en dit blok, met dezelfde specificiteit maar LATER in het
   bestand, zette `display: block` er gewoon overheen. Gevolg: de vlag plakte tegen
   de taalnaam aan (gemeld 2026-09-02). Bij gelijke specificiteit wint de volgorde;
   zie `docs/valkuilen.md` §4. Alles staat daarom nu in één regel.

   ⚠️ 13px EN NIET `em`/`rem`. Ditzelfde menu staat op het inlogscherm, en dat zet
   op een smal scherm `html { font-size: 18px }` — met een relatieve maat zijn de
   twee menu's daar dus verschillend groot terwijl ze hetzelfde moeten zijn. De
   maten hieronder zijn letterlijk die van `#lang-menu button` in login.html. */
.lang-menu a {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 14px; border-radius: 7px;
    color: var(--ink); text-decoration: none;
    font-size: 13px; letter-spacing: .5px;
}
.lang-menu a:hover { background: var(--alt); }
.lang-menu a[aria-current] { color: var(--accent); font-weight: bold; }

/* ── Het keuzemenu onder de speelknop in de kop ───────────────────
   Zelfde opzet als `.lang-menu`: absoluut onder zijn eigen knop, in een anker dat
   `position: relative` draagt. Dat anker staat als `.menu-anchor` in de HTML en
   moet net als `.lang` op `flex: none` — zie de noot daar; een anker dat door flex
   krimpt zet zijn menu op de verkeerde plek. */
.menu-anchor { position: relative; flex: none; }
.cta-menu {
    position: absolute; right: 0; top: calc(100% + 8px);
    min-width: 232px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: 12px;
    box-shadow: var(--shadow);
    z-index: 200;   /* boven de lijnenlaag (150) — een open menu hoort schoon */
}
.cta-menu-kop {
    margin: 4px 10px 8px;
    color: var(--dim);
    font-size: .74em; letter-spacing: .5px;
    /* Een gebruikersnaam kan lang zijn; hier afkorten in plaats van het menu
       breder laten worden dan het scherm. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cta-menu-rij {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px; border-radius: 8px;
    color: var(--ink); text-decoration: none;
}
.cta-menu-rij:hover { background: var(--alt); }
.cmr-ic { flex: none; width: 20px; text-align: center; font-size: 1em; }
.cmr-tekst { display: flex; flex-direction: column; min-width: 0; }
.cmr-tekst b { font-size: .88em; font-weight: bold; }
.cmr-tekst small { color: var(--dim); font-size: .76em; }

/* Het pijltje achter de naam zegt dat er iets OPENGAAT en niet dat je meteen
   vertrekt. Alleen op de knop in de kop — die in de hero blijft een directe link
   en houdt daarom zijn ›.

   ⚠️ HET TEKEN STAAT ER LETTERLIJK EN NIET ALS ESCAPE. Hier stond een
   CSS-escape voor U+25BE, en die is onderweg door een patch-script gesneuveld:
   in het bestand belandde een STUURTEKEN (0x15) gevolgd door "be", en op het
   scherm stond letterlijk "be" achter de naam (gemeld 2026-09-02). Een escape
   overleeft twee lagen quoting niet en faalt onzichtbaar — valkuilen §57.

   ⚠️ ▼ EN ▲ (U+25BC/U+25B2) EN NIET ▾/▴. Alleen die twee staan in CLAUDE.md
   als veilige richtingpijltjes: ze zitten in elk systeemfont, zijn geen emoji en
   hebben dus geen SVG nodig. De kleinere varianten ontbreken op sommige Androids.

   ⚠️ OP DE KNOP EN NIET OP HET LABEL. `.btn-lbl` staat op een smal scherm op
   `overflow: hidden` met een beletselteken; een pijl daarbinnen wordt dus
   meegeknipt en komt midden in de naam te staan. Buiten dat label blijft hij
   rechts staan, wat er ook voor naam in past.

   ⚠️ HIJ HANGT AAN `cta-verder` EN NIET AAN `aria-haspopup`, EN DAT IS EEN
   CORRECTIE. Hier stond het omgekeerd, met als redenering "alleen als er echt een
   menu is — een selector op `.cta-verder` zou de pijl ook bij Play Now tonen".
   Dat klopt niet: die klasse wordt gezet door dezelfde beslissing die de NAAM
   neerzet (`zetSpeelLabel`, `!!(tekst && zin)`), dus met "Play Now" staat hij uit.

   Wat er wél misging is het MOMENT. `cta-verder` komt van het pre-paint-script en
   staat er dus vóór de eerste verf; `aria-haspopup` wordt pas gezet als het menu
   gebouwd wordt, en dat gebeurt na het antwoord van `/auth/session`. Bij elke
   verversing verscheen het pijltje daardoor een fractie later dan de naam — het
   enige wat op deze pagina nog knipperde (gemeld 2026-09-02). Nu komen naam en
   pijl in hetzelfde frame.

   De OPEN-stand blijft aan `aria-expanded` hangen: die verandert alleen door een
   klik, en daar valt niets te flikkeren. */
html.cta-verder #cta-anchor a[data-play]::after {
    content: '▼';
    margin-left: 6px;
    font-size: .7em;
    line-height: 1;
    flex: none;
}
html.cta-verder #cta-anchor a[aria-expanded="true"]::after { content: '▲'; }

/* ── Hero ──────────────────────────────────────────────────────────────── */

/* ⚠️ DE ARENA BEPAALT DE HOOGTE VAN DEZE RIJ, en daar kwam een leeg gat boven de
   kop uit. De illustratie is vierkant en vulde de hele kolom (~530px), terwijl het
   tekstblok maar ~380px hoog is — met `align-items: center` zweeft die tekst dan
   in het midden van een veel te hoge rij. Een `max-width` op de arena lost beide
   klachten in één keer op: de rij wordt lager én het beeld kleiner.
   Verhoog je die waarde, dan komt het gat terug. */
.hero {
    display: grid;
    grid-template-columns: 1fr 1fr;
    /* ⚠️ NAMEN EN GEEN VOLGORDE. De geruststelling onderaan ("gratis, geen
       download") stond ín het tekstblok, en dan kan hij op een smal scherm niet
       ná het beeld komen te staan — precies waar hij hoort, want daar beantwoordt
       hij de vraag die het beeld oproept. Nu is hij een eigen rasterveld en
       bepaalt de media-query verderop de stapeling. */
    grid-template-areas: "tekst kunst" "noot kunst";
    column-gap: 48px;
    row-gap: 16px;
    align-items: center;
    max-width: 1160px;
    margin: 0 auto;
    padding: 52px 28px 62px;
}
.hero-text { grid-area: tekst; }
.hero .hero-art { grid-area: kunst; }
.hero .note { grid-area: noot; margin-top: 0; }
.hero h1 { font-size: 2.9em; letter-spacing: -1px; }
.hero h1 em { color: var(--accent); font-style: normal; }
.lede { margin-top: 20px; color: var(--dim); font-size: 1.02em; max-width: 34ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.note { margin-top: 16px; color: var(--dim); font-size: .78em; }

/* ⚠️ ECHTE SPELKUNST, OP DE ECHTE MATEN. De achtergrond is de arena-plaat die het
   spel op een telefoon gebruikt, de figuren zijn de sprites uit de wedstrijd. Er
   staat hier dus niets wat je na Play Now niet terugziet.

   Elke waarde hieronder is UITGEREKEND uit het spel (canvas 600×600), niet
   geschat — dat scheelde de eerste versie drie zichtbare fouten:

     sumo    Sumo.js: radius 40 → drawHeight = radius*2 = 80  → 80/600  = 13,333%
             breedte volgt uit de beeldverhouding, dus `width: auto`
             MatchScene.js: startX 20% en 80% (dat is het MIDDEN van de sumo)
             voeten op groundY = 550                          → 550/600 = 91,667%
     paal    Constants.js: netWidth 9                         → 9/600   = 1,5%
             netHeight 180, dus poleTopY = 550-180 = 370      → 370/600 = 61,667%
     bal     Ball.js: radius 22 → 44 breed                    → 44/600  = 7,333%

   ⚠️ EN ER WORDT NIETS GESPIEGELD. `Sumo.draw()` doet een kale `drawImage`, zonder
   één `scale(-1)` in het hele bestand — de sprites staan al goed. Hier stond een
   `transform: scaleX(-1)` op de rechter sumo, en díé draaide hem juist de
   verkeerde kant op. Wil je weten hoe iets in de arena hoort te staan: lees de
   scene, niet het scherm. */
.hero-art {
    position: relative;
    aspect-ratio: 1 / 1;
    width: 100%;
    max-width: 430px;
    margin-left: auto;          /* blijft tegen de rechterrand van zijn kolom */
    border-radius: 16px;
    overflow: hidden;
    background: url('/assets/img/m-background.svg') center/cover no-repeat;
    border: 1px solid var(--line);
    box-shadow: var(--shadow);
}
.hero-art .ground {
    position: absolute; left: 0; right: 0; top: 91.667%; bottom: 0;
    background: rgba(20, 30, 46, .18);
}
/* ⚠️ DE PAAL IS VIER LAGEN, NIET ÉÉN VERLOOP — nagebouwd uit `drawPole` in
   MatchScene.js. Er stond alleen het eiken-verloop, en dan lees je een geel
   streepje in plaats van bamboe. Wat ontbrak zijn juist de twee lagen die hem
   herkenbaar maken:

     1. cilinder-shading  — de horizontale licht/donker-band die hem ROND maakt
     2. knoopringen       — vier banden op 0/25/50/75% van de hoogte, elk een
                            donkere streep met een lichte glans eronder. Dát is
                            wat je als bamboe leest.
     3. het eiken-verloop (de vier stops uit `drawPole`)

   De volgorde staat vast: in CSS ligt de EERSTE achtergrond bovenop, dus de
   shading dekt de ringen af en de ringen liggen op het hout. Draai je ze om, dan
   verdwijnt de rondheid onder de ringen.

   De bovenste ring is in het spel dikker (5px tegen 2,5px) "zodat de top niet
   leeg/gat-achtig oogt" — dat is het dopje dat je ziet. Die staat apart als
   `::before`, want een repeating-gradient kan niet één band anders maken. */
.hero-art .pole {
    position: absolute;
    left: 50%; width: 1.5%; margin-left: -.75%;
    top: 61.667%; bottom: 8.333%;
    background:
        linear-gradient(90deg,
            rgba(0,0,0,.48) 0%, rgba(0,0,0,.16) 16%, rgba(255,255,255,.50) 32%,
            rgba(255,255,255,.10) 46%, rgba(0,0,0,.22) 78%, rgba(0,0,0,.52) 100%),
        repeating-linear-gradient(180deg,
            rgba(80,55,15,.40)    0,      rgba(80,55,15,.40)    1.39%,
            rgba(255,240,200,.25) 1.39%,  rgba(255,240,200,.25) 2.06%,
            transparent           2.06%,  transparent           25%),
        linear-gradient(90deg, #7a571f 0%, #c79a4f 45%, #d4a85d 58%, #6a4a18 100%);
}
/* Het dikkere kopstuk: 5px van de 180 hoge paal = 2,78%, met de glans eronder. */
.hero-art .pole::before {
    content: ''; position: absolute;
    left: -6%; right: -6%; top: 0; height: 2.78%;
    background: rgba(80, 55, 15, .55);
    box-shadow: 0 .67% 0 rgba(255, 240, 200, .3);
}
/* De schaduw-ellips aan de voet, ook uit drawPole (rx = netWidth × 1,6). */
.hero-art .pole::after {
    content: ''; position: absolute;
    left: 50%; bottom: -.4%; width: 480%; height: 1.2%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, .3); border-radius: 50%;
}
.hero-art .sumo {
    position: absolute; bottom: 8.333%;
    height: 13.333%; width: auto;
    transform: translateX(-50%);   /* `left` is het MIDDEN, net als startX in de scene */
}
/* ⚠️ DE LINKER SUMO STAAT, DE RECHTER SPRINGT. Twee figuren stil op de grond is
   de stand vóór de aftrap — precies niet waar het spel om draait. De rechter staat
   nu bij de paal in de lucht met de bal ernaast: het moment van de smash.
   `left` is bij allebei het MIDDEN (zie `translateX(-50%)` hierboven), net als
   `startX` in de scene; alleen de rechter is naar de paal geschoven en opgetild.
   Zijn kruin komt daarmee boven de paaltop (61,667%) uit, en dat is wat een sprong
   in dit spel doet. */
/* De witte sumo hangt boven de bal: hij slaat 'm naar beneden. */
.hero-art .sumo-l { left: 50%; bottom: 57%; }
.hero-art .sumo-r { left: 63%; bottom: 33%; }
/* ⚠️ DE BAL MOET ONDER DE VOET VAN DE SUMO BLIJVEN, anders verdwijnt die erachter.
   Je vroeg om ~5px; op een illustratie van ~430px is dat 1,2%, en dat was net te
   weinig: de voeten staan op 57% van onderen en de bal reikte tot 60%. Op 42% van
   boven eindigt hij op 58% van onderen, en dan is de voet vrij. Zakt hij verder,
   dan raakt hij de bal niet meer aan en verdwijnt de smash. */
.hero-art .ball   { position: absolute; left: 53%; top: 42%; width: 7.333%; height: auto; }

/* ── De balk boven de arena: twee profielkaarten met de stand ertussen ──────
   Zelfde opbouw als in het spel. De maten schalen mee met de illustratie
   (`cqw` van de vierkante `.hero-art`), zodat hij op elke breedte klopt. */
/* ⚠️ `container-type` MAG HIER WÉL, en dat is niet in tegenspraak met de
   waarschuwing in mobile.css. Die gaat over `.canvas-container/-frame/-wrap` in
   het SPEL: daar maakt hij een stacking-context, en dan valt de meldingenstrook
   onder het rechterpaneel. Binnen `.hero-art` hoeft niets naar buiten te steken —
   alle kinderen zitten er absoluut in — dus een eigen stacking-context is hier
   zonder gevolgen. Zonder deze regel kunnen de maten hieronder niet meeschalen
   met de illustratie. */
.hero-art { container-type: inline-size; }
.ha-bar {
    /* ⚠️ 9% EN NIET 4%. Op 4% stonden de twee kaarten vrijwel tegen de muur, en
       de naampil (die met zijn buitenrand op de avatar ligt) raakte hem dan ook.
       Naar binnen schuiven lost allebei op: de kaarten ademen, en de pil heeft
       ruimte voordat hij de rand haalt. */
    position: absolute; inset: 4% 9% auto 9%;
    display: flex; align-items: flex-start; justify-content: space-between;
    z-index: 2;
}
/* ⚠️ DE NAAM MAG DE KAART NIET BREDER MAKEN, en dat is sinds die naam van de
   BEZOEKER komt geen theoretisch geval meer. `.ha-bar` staat op `space-between`
   met de stand ertussen: wordt het rechterblokje breder, dan schuift de stand mee
   naar links EN verschuift de avatar binnen zijn eigen blokje, want die staat
   gecentreerd. Met "THE_KING_IS_BO" was dat goed zichtbaar (gemeld 2026-09-02).

   Daarom is `.ha-p` precies zo breed als de avatar en hangt de naam er ABSOLUUT
   onder, gecentreerd op diezelfde avatar. Een lange naam groeit dan naar twee
   kanten uit zonder iets te verplaatsen. */
.ha-p { position: relative; width: 17cqw; }
.ha-p img {
    width: 17cqw; height: 17cqw;
    border-radius: 14%;
    border: 1px solid rgba(255, 255, 255, .55);
    box-shadow: 0 2px 8px rgba(10, 24, 44, .28);
    background: rgba(255, 255, 255, .35);
}
.ha-p span {
    position: absolute;
    /* Dichter op de avatar: hij hoort bij die kaart en niet bij de grond eronder. */
    top: calc(100% + 1.6cqw);
    padding: .7cqw 2cqw;
    border-radius: 999px;
    background: rgba(255, 255, 255, .82);
    color: #16202e;
    font-size: 2.9cqw;
    letter-spacing: .3px;
    /* ⚠️ NAAR BINNEN GROEIEN, NIET NAAR TWEE KANTEN. Gecentreerd op de avatar
       loopt een lange naam de illustratie uit en wordt hij door de `overflow:
       hidden` van `.hero-art` vlak tegen de muur afgeknipt (gemeld 2026-09-02).
       Elke pil ligt nu met zijn BUITENrand op die van zijn eigen avatar en groeit
       richting het midden; daar is ruimte, en het knipt nooit tegen de rand.
       Het dak van 34cqw houdt hem uit de buurt van de stand. */
    /* Met de kaart op 9% van de rand en een kleinere letter past er meer voordat
       er iets afgeknipt wordt: de pil begint op 9cqw en reikt tot 43 — de stand
       staat op 50. */
    max-width: 32cqw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* ⚠️ WEER GECENTREERD ONDER DE AVATAR (Burak, 2026-09-02). Hij heeft even met zijn
   buitenrand op de avatar gelegen omdat een lange naam anders tegen de muur werd
   afgeknipt — maar dat was een oplossing voor een probleem dat inmiddels weg is:
   de kaarten staan nu op 9% van de rand in plaats van 4%.

   Nagerekend: de avatar is 17cqw breed, dus zijn MIDDEN ligt op 9 + 8,5 = 17,5cqw.
   Een gecentreerde pil van 32cqw reikt tot 17,5 - 16 = 1,5cqw van de rand, en aan
   de andere kant tot 33,5 — ruim voor de stand op 50. Vandaar dat dak van 32; ga je
   daarboven, dan raakt hij de muur weer. */
.ha-p span { left: 50%; transform: translateX(-50%); }
/* De stand staat in het spel op de canvas geschreven, met een donkere omlijning
   zodat hij op elke achtergrond leesbaar blijft. `paint-order` zet die lijn ACHTER
   de letter; zonder dat vreet een dikke streek de vorm van de cijfers op. */
/* ⚠️ EEN OMLIJNING IN TWEE LAGEN, EN NIET `paint-order`. Chrome ondersteunt
   `paint-order` op HTML-tekst pas vanaf versie 111; daarvóór wordt de lijn ÓVER
   de vulling getekend en eet hij de helft van zijn dikte uit de letter. Bij een
   dikte van 9% van de lettergrootte is dat zoveel dat de cijfers dichtslibben —
   gemeld op een laptop met Chrome 109 (2026-09-02).

   `@supports (paint-order: stroke)` helpt niet: `paint-order` is een geldige
   SVG-eigenschap, dus die vraag antwoordt "ja" in browsers waar HTML-tekst er
   niets mee doet.

   Vandaar twee lagen: het pseudo-element draagt ALLEEN de lijn en ligt met
   `z-index: -1` achter de echte tekst. Dat werkt in elke browser en geeft precies
   hetzelfde beeld als `paint-order: stroke fill`.

   ⚠️ DE TWEEDE LAAG LEEST EEN `data-`ATTRIBUUT en niet de tekst zelf — CSS kan
   geen `textContent` kopiëren. Wie de tekst zet, moet dus BEIDE zetten; zie
   `updateCanvasScore` in main.js. Loopt dat uiteen, dan staat de omlijning van de
   vorige stand achter de nieuwe.

   ⚠️ EN `z-index: 0` OP HET ELEMENT ZELF IS NODIG: dat maakt er een eigen
   stapelcontext van, zodat de -1 binnen deze tekst blijft en niet achter iets
   anders op de pagina belandt. */
.ha-score {
    /* ⚠️ ABSOLUUT GECENTREERD, want met `space-between` bepaalt de breedte van de
       twee kaarten waar het midden ligt — en die van rechts hangt sinds vandaag af
       van de naam van de bezoeker. Zo staat de stand altijd op dezelfde plek. */
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    z-index: 0;
    top: 2.5cqw;
    font-size: 8cqw; font-weight: bold; letter-spacing: 1px;
    color: #fff;
}
.ha-score::before {
    content: attr(data-score);
    position: absolute; left: 0; top: 0;
    -webkit-text-stroke: .55cqw rgba(0, 0, 0, .85);
    color: transparent;
    z-index: -1;
}
:root[data-mode="dark"] .hero-art::after {
    content: ''; position: absolute; inset: 0;
    background: rgba(8, 14, 26, .32); pointer-events: none;
}

/* ⚠️ DEZELFDE DEMPING OP DE SCHERMAFDRUKKEN, EN DIT IS EEN TUSSENSTAP. De zestien
   afdrukken tonen het spel in de DAGSTAND; schakel je de pagina naar donker, dan
   staan er zestien lichtbakken op een donkere pagina — en ze beloven bovendien iets
   dat niet klopt. De echte oplossing is een tweede set afdrukken in de nachtstand
   (D44 in docs/next-session-ideas-new.md); zodra die er is, mag deze regel weg.

   ⚠️ EEN FILTER EN GEEN SLUIER, en dat is een afwijking van de arena hierboven. Die
   krijgt een `::after` over zich heen; dat kan hier niet, want een `<img>` is een
   vervangen element en heeft geen pseudo-elementen. Het op de `<figure>` zetten zou
   ook het onderschrift dimmen, en dat is gewone paginatekst.

   `brightness(.7)` is het rekenkundige equivalent van die sluier: 1 − 0.32 = 0.68.
   Het verschil is dat de sluier ook een spoortje blauw meegeeft en dit puur dooft —
   op een foto van een spel is dat verschil niet te zien.

   ⚠️ GEEN `invert()`. Dat is de klassieke donkere-modus-truc en hij is voor
   TEKSTSCHERMEN: witte achtergrond, donkere letters. Dit zijn foto's met
   geschilderde avatars en een strand — inverteren maakt de zwarte sumo wit en het
   zand paars. Zie D44. */
:root[data-mode="dark"] .shot img {
    filter: brightness(.7);
}

/* ── Banden ────────────────────────────────────────────────────────────── */

.band { padding: 62px 28px; }
.band.alt { background: var(--alt); }
.band > h2, .cta > h2 {
    max-width: 1160px; margin: 0 auto 34px;
    font-size: 1.5em; letter-spacing: -.4px; text-align: center;
}

.steps {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px;
    max-width: 1160px; margin: 0 auto; padding: 0; list-style: none;
    counter-reset: none;
}
.steps li {
    background: var(--surface); border: 1px solid var(--line);
    border-radius: 14px; padding: 24px;
}
.step-n {
    display: inline-flex; align-items: center; justify-content: center;
    width: 30px; height: 30px; margin-bottom: 12px;
    border-radius: 50%; background: var(--accent); color: #fff;
    font-size: .82em; font-weight: bold;
}
.steps h3, .grid4 h3 { font-size: 1em; margin-bottom: 8px; }
.steps p, .grid4 p, .cards p { color: var(--dim); font-size: .88em; }

/* ── Schermafdrukken ───────────────────────────────────────────────────── */

/* ⚠️ DE TELEFOON-AFDRUK IS STAAND EN DE ANDERE TWEE LIGGEND, dus een gewoon
   raster van drie gelijke kolommen zou de eerste twee tot postzegels maken naast
   een torenhoge derde. Vandaar `align-items: start` plus een eigen, smallere
   kolom voor de telefoon: elk beeld houdt zijn eigen verhouding en niets wordt
   opgerekt. */
.shots {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 26px;
    max-width: 1160px;
    margin: 0 auto;
    align-items: start;
}
.shot { margin: 0; }
/* ⚠️ DE AFDRUKKEN LIGGEN BOVEN DE LIJNEN-LAAG (150), en dat is geen opmaak maar
   een BEWERING. Dit is een foto van het spel; lopen er fijne lijnen overheen, dan
   lijkt het alsof het spel er zélf zo uitziet — en dat is precies het misverstand
   dat een schermafdruk moet wegnemen (gemeld 2026-09-02, met drie voorbeelden).

   Alleen de AFBEELDING, niet het onderschrift: dat is tekst van de pagina en hoort
   er net zo bij als de rest. `position: relative` is nodig omdat `z-index` op een
   niet-geplaatst element niets doet. Het werkt omdat geen enkele voorouder een
   eigen stacking-context maakt — `.shots-rij-wrap` staat op `relative` ZONDER
   z-index, en `overflow` alleen maakt er geen. Zet daar dus geen z-index bij.

   ⚠️ DE HERO-ILLUSTRATIE HOUDT DE LIJNEN WEL. Die is getekend en niet
   gefotografeerd: hij belooft niets over hoe het spel er precies uitziet, en hij is
   juist het beeld waar het raster van de pagina omheen sluit. */
.shot img {
    display: block; width: 100%; height: auto;
    position: relative;
    z-index: 151;
    border-radius: 12px;
    border: 1px solid var(--line);
    box-shadow: var(--shadow);
    background: var(--surface);   /* zolang hij laadt geen gat in de pagina */
}
.shot figcaption {
    margin-top: 12px;
    color: var(--dim);
    font-size: .84em;
    line-height: 1.55;
}
.shot--phone img { border-radius: 16px; }

/* ⚠️ DE BUREAUBLAD-AFDRUKKEN DRAGEN HET LABEL "VOORBEELD" (2026-09-15). Daarop zijn de
   spelers, namen, chat en cijfers verzonnen (de nepvulling); zonder label lees je ze
   als de echte stand van het spel, en een naam erop als een bestaande speler. De
   telefoon- en tabletafdrukken tonen het echte spel van eerder en hebben geen label.
   Klein en gecentreerd ONDER de afbeelding, boven het onderschrift: op het beeld
   zelf (linksboven) dekte het de bovenkant van de afdruk af.

   ⚠️ DE VERZONNEN NAMEN STAAN EXACT (`=naam`) OP BLOCKED NAMES IN PRODUCTIE,
   zodat niemand ze registreert en een echte speler niet in een voorbeeld staat.
   Nieuwe afdrukken met andere namen: die namen daar ook bijzetten.

   Een zacht pilletje in de kleur van het thema (`--surface`), zodat het bij de
   pagina hoort en niet als een sticker leest. Het ligt naast het onderschrift
   gewoon onder de lijnen-laag, net als die tekst: het is pagina en geen foto. */
.shot-voorbeeld {
    display: block;
    width: fit-content;
    max-width: 100%;
    margin: 10px auto 0;
    padding: 2px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--surface) 60%, transparent);
    border: 1px solid var(--line);
    color: var(--dim);
    font-size: 9px;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: .02em;
}
.shot-voorbeeld + figcaption { margin-top: 8px; }
@media (max-width: 520px) {
    .shot-voorbeeld {
        margin-top: 8px;
        padding: 1px 6px;
        font-size: 8px;
        letter-spacing: 0;
    }
}

/* ── De kopjes boven de drie groepen ─────────────────────────────────────── */
.shots-kop {
    max-width: 1160px;
    margin: 34px auto 14px;
    font-size: .82em;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--dim);
    font-weight: normal;
}
.shots-kop:first-of-type { margin-top: 0; }

/* ── DE TELEFOON-AFDRUKKEN SCHUIVEN HORIZONTAAL ──────────────────────────────
   ⚠️ EEN RIJ EN GEEN RASTER, en dat is een maatkwestie. Er zijn er negen en ze
   zijn bijna twee keer zo hoog als breed: naast elkaar in een raster wordt elke
   telefoon een postzegel, onder elkaar wordt het een pagina van drie schermen
   lang. Schuivend passen er op een bureaublad vier in beeld en op een telefoon
   twee, en de rest is één veeg weg.

   ⚠️ VOLLEDIG IN CSS, ZONDER JAVASCRIPT. `overflow-x` met `scroll-snap` geeft
   een veeg, een muiswiel én de tabtoets in één keer; een eigen carrousel zou
   knoppen, een stand en een teller vragen die alle drie kunnen verouderen. Dat
   past bij de rest van deze pagina: JavaScript is hier comfort, nooit een
   voorwaarde.

   ⚠️ `scroll-padding-inline` HOORT ERBIJ. Zonder dat klikt de eerste afdruk bij
   het terugscrollen tegen de rand van het venster in plaats van tegen de marge
   van de pagina — dan lijkt de rij scheef te staan. */
/* ── De omhulling draagt de twee pijlen ──────────────────────────────────
   `position: relative` is het enige wat hij hoeft te doen; de knoppen worden door
   `home.js` aangemaakt en hangen eraan. */
.shots-rij-wrap { position: relative; }

/* ⚠️ VERTICAAL OP DE AFBEELDING EN NIET IN HET MIDDEN VAN DE RIJ. Onder elke
   afdruk staat een onderschrift van één of twee regels, dus het midden van de rij
   ligt lager dan het midden van het BEELD. Op 40% staat de pijl op de afbeelding,
   ongeacht hoe lang een onderschrift wordt. */
.shots-pijl {
    position: absolute;
    top: 40%;
    transform: translateY(-50%);
    z-index: 152;   /* boven de afdrukken (151) — anders schuiven die eroverheen */
    width: 38px; height: 38px;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font: inherit; font-size: 1em; line-height: 1;
    cursor: pointer;
    box-shadow: var(--shadow);
}
.shots-pijl:hover { background: var(--alt); }
.shots-pijl--links  { left: -10px; }
.shots-pijl--rechts { right: -10px; }
/* Op een aanraakscherm schuift de rij al met een veeg; twee knoppen die daar
   overheen liggen kosten dan alleen maar ruimte op het beeld. */
@media (pointer: coarse) {
    .shots-pijl { display: none; }
}

.shots--rij {
    display: flex;
    gap: 18px;
    max-width: 1160px;
    margin: 0 auto;
    padding-bottom: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;   /* geen terug-navigatie bij het doorvegen */
    scroll-snap-type: x proximity;
    scroll-padding-inline: 0;
    /* ⚠️ `scrollbar-width` ZET DE `::-webkit-scrollbar`-REGELS VAN DEZE PAGINA UIT.
       Sinds Chrome de standaard-eigenschappen ondersteunt geldt: staat er
       `scrollbar-width` of `scrollbar-color` op een scroller, dan negeert de browser
       de pseudo-elementen voor díé scroller. De balk bovenaan dit bestand (10px, met
       tokens) raakte deze rij dus niet, en wat je zag was de standaardbalk van de
       browser — in de donkere stand een lichte streep onder zestien gedempte
       afdrukken (gemeld 03-09).

       De uitweg is niet die regels terugvechten maar de standaard-eigenschap
       gebruiken: `scrollbar-color` volgt het thema en werkt sámen met `thin`.
       Een doorzichtige goot met alleen een duim erin — smaller en rustiger dan de
       10px van de paginabalk, en dat mag hier: dit is een balk ín de inhoud en niet
       de rand van het scherm.

       ⚠️ `scrollbar-width` ERFT NIET — zie de noot in style.css. */
    scrollbar-width: thin;
    scrollbar-color: var(--scroll-duim) transparent;
}
.shots--rij .shot {
    flex: 0 0 230px;
    scroll-snap-align: start;
}
/* ⚠️ ALLEEN TIJDENS HET SLEPEN. `user-select` houdt de onderschriften ongemoeid
   bij een gewone klik en voorkomt alleen dat een sleep een tekstselectie wordt.
   `scroll-snap-type: none` erbij omdat het kleven anders tegen de muis in trekt;
   bij het loslaten komt het terug en klikt de rij netjes op zijn plek. */
/* ⚠️ `ew-resize` EN NIET `grab`. Die laatste is de vanzelfsprekende keuze voor een
   sleepbare rij en ziet er op macOS ook goed uit — maar op Windows tekent het
   systeem er een grofgeblokte hand bij die uit een ander tijdperk komt (gemeld met
   een foto, 2026-09-02). `ew-resize` is daar wél een strakke, geschaalde dubbele
   pijl, en hij zegt bovendien preciezer wat er kan: zijwaarts schuiven.

   ⚠️ BEWUST GEEN EIGEN CURSOR-AFBEELDING. Dat kan (`cursor: url(data:...)`, en de
   CSP laat `data:` toe), maar een eigen plaatje negeert de cursorgrootte die de
   gebruiker in zijn systeem heeft ingesteld — en dat is voor wie een grote cursor
   nodig heeft geen detail. Een systeemcursor schaalt mee. */
.shots--rij { cursor: ew-resize; }
.shots--rij.sleept {
    user-select: none;
    scroll-snap-type: none;
}
.shots--rij.sleept img { pointer-events: none; }
/* De onderschriften mogen niet zo lang worden dat de rij scheef oogt: elke kaart
   is even breed, dus een regel meer bij één afdruk duwt alleen die kaart omlaag —
   niet de rij. Vandaar een vaste hoogte voor de tekst. */
.shots--rij figcaption {
    font-size: .78em;
    margin-top: 10px;
}
@media (max-width: 520px) {
    /* Op een telefoon twee tegelijk in beeld: 2x44% plus de tussenruimte laat de
       derde net zichtbaar aansnijden, en dát is wat laat zien dát er meer is. */
    .shots--rij .shot { flex-basis: 44%; }
}

/* ── De bureaublad-afdrukken in dezelfde schuifrij (2026-09-15) ─────────────────
   Liggende beelden, dus bredere kaarten dan de telefoons: twee in beeld en de derde
   net zichtbaar aan de rand, zodat je ziet dat er meer is. Op een smal scherm één
   met de volgende aangesneden. Staat ná de telefoonregel hierboven: zelfde gewicht,
   dus de volgorde beslist. */
.shots--rij-breed .shot { flex-basis: 44%; }
.shots--rij-breed figcaption { font-size: .84em; }
@media (max-width: 760px) {
    .shots--rij-breed .shot { flex-basis: 84%; }
}

.devices {
    max-width: 1160px;
    margin: 30px auto 0;
    text-align: center;
    color: var(--dim);
    font-size: .86em;
}

.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; max-width: 1160px; margin: 0 auto; }
.card {
    background: var(--surface); border: 1px solid var(--line);
    border-top: 3px solid var(--c, var(--accent));
    border-radius: 14px; padding: 24px;
}
.card.m1 { --c: var(--m1); }
.card.m2 { --c: var(--m2); }
.card.m3 { --c: var(--m3); }
.card h3 { display: inline; font-size: 1.05em; color: var(--c); }
.tag {
    display: inline-block; margin-left: 10px; padding: 2px 9px;
    border-radius: 20px; background: var(--alt); color: var(--dim);
    font-size: .68em; letter-spacing: 1px; text-transform: uppercase;
    vertical-align: middle;
}
.card p { margin-top: 12px; }

.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; max-width: 1160px; margin: 0 auto; }

/* ── Slotoproep ────────────────────────────────────────────────────────── */

.cta { padding: 66px 28px 74px; background: var(--alt); text-align: center; }
.cta p { color: var(--dim); margin-bottom: 26px; }
.cta .note { margin-top: 14px; }

/* ── Voettekst ─────────────────────────────────────────────────────────── */

/* ⚠️ DE VOET STAAT IN `css/foot.css` EN NIET HIER. Vier publieke pagina's delen
   hem; ze hadden er elk een eigen, en dat liep zichtbaar uit de pas. Hier staat
   alleen nog de vertaling van de tokens van DEZE pagina naar de vijf namen die dat
   bestand leest. Zet nieuwe voet-opmaak daar neer, niet hier. */
.foot {
    --foot-bg:     var(--surface);
    --foot-line:   var(--line);
    --foot-ink:    var(--ink);
    --foot-dim:    var(--dim);
    --foot-accent: var(--accent);
}

/* ── Smallere schermen ─────────────────────────────────────────────────── */

@media (max-width: 900px) {
    /* ⚠️ HET BEELD STOND HIER BOVENAAN (`order: -1`) EN DAT IS TERUGGEDRAAID
       (Burak, 2026-09-02). Een nieuwe bezoeker kreeg dan eerst een spelbeeld
       zonder één woord uitleg, en moest zelf raden waar hij was beland. De
       volgorde is nu: titel, uitleg, speelknop, beeld, en pas daarna de
       geruststelling ("gratis, geen download"). Dat laatste hoort ná het beeld:
       het beantwoordt de vraag die het beeld oproept. */
    .hero {
        grid-template-columns: 1fr;
        grid-template-areas: "tekst" "kunst" "noot";
        row-gap: 34px;
        padding: 44px 22px 54px;
    }
    .hero h1 { font-size: 2.2em; }
    .lede { max-width: none; }
    .hero-art { margin: 0 auto; }   /* één kolom → gecentreerd */
    .steps, .cards { grid-template-columns: 1fr; }
    .shots { grid-template-columns: 1fr; }
    .grid4 { grid-template-columns: 1fr 1fr; }
}

/* ── DE KOP OP EEN TELEFOON: DRIE ZWEVENDE KNOPPEN, GEEN BALK ───────────────
 *
 * Onder 720px is de kop geen balk meer maar drie knoppen die boven de pagina
 * zweven: thema en taal links, je naam rechts. Geen achtergrond, geen rand, geen
 * logo — het merk staat in de PAGINA, boven de hero-titel (`.hero-brand`), en
 * scrolt dus gewoon mee.
 *
 * ⚠️ WAT HIER WEGGING EN WAAROM. Er is een hele reeks pogingen geweest om logo,
 * taal, thema én een knop met "Verder als <naam>" in één balk van 360px te
 * passen: het woordmerk krimpen, de taalcode verbergen, het merk vervangen door
 * de bal, een ondergrens voor het merk. Elke ronde loste één naamlengte op en
 * brak bij de volgende. De uitweg was niet nóg een rekensom maar één partij
 * eruit halen — en dat is het logo, want dat hoeft niet vast te staan.
 *
 * ⚠️ DAARMEE VERVALT OOK DE COMPACTE PIL OP EEN TELEFOON (zie de media-query
 * hierboven, die begint nu bij 721). Er valt niets samen te trekken: de kop
 * neemt hier al geen ruimte in. De bal-als-favicon bij het scrollen hoorde bij
 * die pil en is daarmee ook weg.
 *
 * ⚠️ 720 EN NIET 500. De grens is niet "is dit een telefoon" maar "past er nog
 * een navigatie naast" — en dat is precies waar `.nav` verdwijnt. Boven die
 * grens is de kop een echte balk met een woordmerk erin en verandert er niets.
 */
@media (max-width: 720px) {
    .nav { display: none; }
    .top { padding: 0 12px; }   /* hoogte blijft 56px, net als in het spel */
    .top-inner { gap: 12px; }
    .top-right { gap: 8px; }

    /* De balk zelf verdwijnt volledig; de pagina scrolt eronderdoor. De knoppen
       dragen hun eigen vlak (`--surface` + `--line`) en blijven dus leesbaar. */
    .top { background: transparent; border-bottom-color: transparent; }
    .top::before { display: none; }   /* geen vlak = geen eigen lijnen */
    .top-inner {
        background: transparent;
        border-color: transparent;
        box-shadow: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        animation: none;
    }

    /* Het merk staat in de pagina, niet meer hier. */
    .brand { display: none; }

    /* ⚠️ DE SPLITSING GEBEURT MET ÉÉN AUTO-MARGE EN NIET MET EEN EXTRA HTML-LAAG.
       `.top-right` bevat thema, taal en de naamknop als drie broertjes; met
       `flex: 1` en een auto-marge vóór de naamknop schuift die naar rechts en
       blijven de twee icoontjes links staan. Zo hoeft de opbouw van de kop niet te
       veranderen — en dus ook niets aan de menu-ankers die eraan hangen. */
    /* ⚠️ MINDER LUCHT BOVEN HET MERK. De kop neemt hier geen vlak meer in maar
       nog wel 56px in de stroom; met de 44px insprong van de hero erbovenop
       stond het merk 100px onder de rand en las de bovenkant als leeg. */
    .hero { padding-top: 16px; }

    .top-right { flex: 1; min-width: 0; margin-left: 0; }
    #cta-anchor { margin-left: auto; }

    /* ⚠️ HET TAALMENU HANGT MEE NAAR DE KANT WAAR ZIJN KNOP STAAT. Het is
       `right: 0` — uitgemeten voor een knop rechts in de balk — en sinds de
       twee icoontjes hier links staan liep het dus links het scherm uit; de
       helft van de talen was onleesbaar (gemeld 2026-09-02). Er is nergens
       een correctie die een menu binnen beeld trekt, dus dat moet per kant. */
    .lang-menu { right: auto; left: 0; }

    /* ⚠️ En de pil-regel die BUITEN die media-query staat moet hier terug. Met
       `flex: 1 1 auto` zou de naamknop bij het scrollen de hele breedte pakken,
       want er is nu niets meer dat hem tegenhoudt. Het afkorten blijft. */
    html.top-pil .top-right [data-play] { flex: 0 1 auto; }
}

/* ⚠️ HET MERK BOVEN DE HERO-TITEL — ALLEEN ONDER 720px. Daarboven staat het in de
   kop en zou dit een tweede logo op één scherm zijn. */
.hero-brand { display: none; }
@media (max-width: 720px) {
    .hero-brand {
        display: block;
        width: 180px;
        max-width: 62%;      /* op ~280px (opgevouwen telefoon) nog steeds heel */
        height: auto;
        margin: 0 0 18px;    /* links uitgelijnd met de titel eronder */
    }
}

/* ⚠️ HET WOORDMERK BLIJFT OP EEN TELEFOON STAAN — de bal hoort alleen in de pil.
   Deze grens stond even op 430px, en toen verdween het logo dus óók bovenaan de
   pagina waar er ruimte zat is. Dat was een noodgreep tegen een afgeknipte
   Play Now-knop; de echte oplossing was de knoppen kleiner maken.

   ⚠️ DE OUDE REKENSOM HIER TELDE DE SPEELKNOP MEE, EN DIE STAAT ER NIET MEER.
   Sinds die knop pas in de compacte pil verschijnt (zie de noot hierboven) deelt
   het logo de volle balk alleen nog met het maantje en de taal:
     24 (padding) + logo + 12 + 34 + 8 + 34 = 112 + logo.
   Op 360px is er dus ruimte voor 248px logo. Het stond op 130 — uitgerekend voor
   een kop die toen wel een knop droeg — en dat was klein genoeg om onleesbaar te
   worden zodra het woordmerk fijner werd getekend (gemeld 2026-09-02). Nu 150,
   met ruim honderd pixels marge.

   ⚠️ EN DIE KNOP IS NIET MEER VAN VASTE BREEDTE. Hij kan "Verder als <naam>"
   zeggen, en een naam is niet te voorspellen — elke rekensom met een vast getal
   zou dus voor de één kloppen en voor de ander niet. Vandaar dat het antwoord in
   de WISSEL zit en niet in een breekpunt: waar die knop staat, staat het logo als
   bal.

   ⚠️ DEZE HELE REKENSOM GAAT ALLEEN NOG OVER 721px EN HOGER. Onder die grens
   bestaat het woordmerk in de kop niet meer — het staat daar boven de hero-titel,
   in de pagina (zie `.hero-brand`). Er stonden hier drie krimpstappen (160 / 150 /
   120 bij 720 / 430 / 350) en die zijn weggehaald toen ze dode code werden; laat
   ze weg zolang de kop op een telefoon geen logo draagt. */

/* ⚠️ MET "VERDER ALS <NAAM>" IN DE KOP WORDT HET WOORDMERK DE BAL.
 *
 * Het pre-paint-script zet `cta-verder` op <html> zodra er een onthouden naam
 * is, en `home.js` corrigeert 'm zodra de server geantwoord heeft. Alleen
 * dán geldt deze regel — met het korte "Play Now" is er ruimte zat en blijft het
 * woordmerk gewoon staan.
 *
 * Nagerekend op 640px, met de langste redelijke naam:
 *   24 (padding) + 12 + 34 (maantje) + 8 + 34 (taal) + 8 = 120 vast,
 *   + ~250 (de knop) + 28 (de bal) = 398.
 * Dat past ruim; met het woordmerk (160) erbij zou het 530 zijn en dan knelt het
 * al vanaf ~520px. Vandaar 640 en niet krapper: een naam is niet te voorspellen,
 * en een logo dat tot een onleesbare veeg geperst wordt is erger dan een bal
 * (gemeld 2026-09-02).
 *
 * De ellips op de knop hieronder blijft het laatste vangnet: bij een extreem
 * lange naam op een heel smal toestel kort de naam af in plaats van de kop uit
 * te duwen.
 *
 * ⚠️ DIE WISSEL GELDT ALLEEN NOG BOVEN 720px. Op een telefoon staat er helemaal
 * geen logo meer in de kop — het staat boven de hero-titel — dus daar valt er ook
 * niets te wisselen. De vorige ronde probeerde het nog wél te laten passen (het
 * merk krimpen tot een vloer van 96px, de naam laten afkorten); dat werkte op
 * papier en bleef een verdeling van te weinig ruimte over te veel partijen.
 *
 * En boven 720px is de wissel niet meer nódig in de VOLLE balk: op 721px staan het
 * woordmerk (180), de twee icoontjes (~76) en een naamknop (~150) samen op ruim
 * 400px, en dat past ruim. De enige plek waar het merk nog een bal wordt is de
 * compacte pil, en die regel staat hierboven bij `html.top-pil`. Er is dus geen
 * `html.cta-verder`-regel meer nodig; hij stond hier en is weggehaald. */

/* ⚠️ ZODRA ER EEN NAAM OP STAAT, IS HET GEEN ACTIEKNOP MEER MAAR EEN GEBRUIKERSMENU
 * — en dan wordt hij neutraal in plaats van geel (2026-09-02).
 *
 * Het is één en hetzelfde element: uitgelogd staat er "Play Now" en dat is de
 * primaire actie van deze pagina, dus die blijft geel. Ingelogd staat er je naam
 * met een pijltje eronder, en dat is navigatie — hetzelfde ding als de pil in de
 * kop van de arena, die daar altijd al een neutraal, thema-volgend vlak was.
 * Ze stonden op twee kleuren op dezelfde plek in dezelfde kop; nu op dezelfde.
 *
 * ⚠️ HET VOLGT HET THEMA EN IS GEEN VASTE KLEUR. Er is een ronde geweest waarin de
 * arena en het inlogscherm juist NAAR het geel toe getrokken werden ("geel = de
 * primaire actie"); dat is op verzoek teruggedraaid, want de kleurwissel per thema
 * is precies wat deze knoppen leuk maakt. Zet hier dus geen hex neer.
 *
 * `--surface` + `--line` is exact wat de twee icoonknoppen ernaast dragen — op de
 * lichte stand wit-achtig ("standaard wit"), op de donkere vanzelf donker.
 * Specificiteit: `html.cta-verder .top` verslaat `.btn-primary` ruim, dus er is
 * geen `!important` nodig. */
html.cta-verder .top .btn-primary {
    background: var(--surface);
    border-color: var(--line);
    color: var(--ink);
    font-weight: normal;
}
html.cta-verder .top .btn-primary:hover { background: var(--alt); }

@media (max-width: 520px) {
    body { font-size: 14px; }
    .hero h1 { font-size: 1.85em; }
    .band, .cta { padding-left: 18px; padding-right: 18px; }
    .grid4 { grid-template-columns: 1fr; }
    .hero-actions .btn { flex: 1 1 100%; }
}
