/* ceeme-beweging.css — HOE DE SITE ZICH GEDRAAGT.
   ================================================================================================
   Njusja wees me op visual.be en op de eerste pagina van mistral.ai, en zei erbij dat het haar niet
   om één animatie ging maar om hoe een echte, mooie website WERKT. Dat klopt: het verschil tussen
   die twee sites en de onze zit niet in een effect dat je ergens inplakt. Het zit erin dat de site
   voortdurend antwoordt op wat je doet. Je scrollt en de kop reageert. Je beweegt de muis en er
   beweegt iets mee. Je gaat naar de volgende pagina en die schuift er niet in, hij lost op.

   Dit bestand is die laag, één keer, voor de hele site. Zeven gedragingen, meer niet:

     1. de leesbalk        hoever je bent, als één amberlijn bovenaan
     2. de kop             hij verdwijnt als je naar beneden leest en komt terug als je omhoog gaat
     3. de aankomst        secties komen omhoog en scherp binnen, één keer, met een korte trap
     4. de cursor          een amberstip die met vertraging volgt en groeit boven wat klikbaar is
     5. de aanraking       links, kaarten en tabelrijen antwoorden op de muis
     6. de overgang        van pagina naar pagina lost op in plaats van te knipperen
     7. de rust            met beweging uitgezet blijft er niets van over, en dat is geen verlies

   ── Waarom dit bij ons anders moet dan bij een bureau ─────────────────────────────────────────
   visual.be mag alles verbergen tot je scrollt; hun bezoekers zijn mensen met JavaScript aan. Onze
   bezoekers zijn óók crawlers, en die zijn het halve product. Dus geldt hier één harde regel:

       ZONDER JAVASCRIPT VERANDERT ER NIETS AAN WAT ER STAAT.

   Alles hieronder hangt aan `html.beweegt`, en die klasse zet ceeme-beweging.js pas als het draait.
   Geen JS, geen render, beweging uitgezet: dan staat elke sectie er gewoon, zichtbaar, op zijn
   plaats. Een site die adviseert om leesbaar te zijn voor machines en zelf zijn tekst achter een
   opacity van 0 legt, is geen goede reclame voor zichzelf.

   Eén accent: amber #C6892B. Geen tweede kleur, ook niet hier. */

/* ── 1. De leesbalk ─────────────────────────────────────────────────────────────────────────────
   Eén lijn van 2px bovenaan, die meegroeit met hoever je gelezen hebt. Geen percentage, geen
   cijfer — je hóéft hem niet te lezen, je ziet hem in je ooghoek. Dit is het goedkoopste signaal
   dat een pagina lang is en dat je vordert, en op onze gidsen van 1200 woorden telt dat.
   scaleX in plaats van width: dat draait op de compositor en kost geen layout. */
.bw-lees {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 60;
  background: #C6892B; transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform; pointer-events: none;
}

/* ── 2. De kop die reageert ─────────────────────────────────────────────────────────────────────
   Twee dingen tegelijk, en ze horen bij elkaar:

   Bovenaan de pagina is de kop gewoon de kop. Zodra je voorbij de eerste schermhoogte bent, krijgt
   hij een fijne amberlijn onderaan — een klein teken dat je niet meer in de hero zit.

   En hij verbergt zich als je naar beneden leest. Dat is geen truc: een plakkende kop van 64px op
   een telefoon eet een zesde van je scherm op terwijl je aan het lezen bent. Ga je omhoog, dan is
   dat vrijwel altijd omdat je iets zoekt — en dan staat hij er meteen weer. Mistral doet hetzelfde,
   en de reden dat je het daar niet merkt is precies dat het goed werkt. */
html.beweegt header {
  transition: transform 320ms cubic-bezier(.4, 0, .2, 1), box-shadow 320ms ease;
}
html.beweegt.bw-diep header { box-shadow: 0 1px 0 rgba(198, 137, 43, .45) }
html.beweegt.bw-weg header { transform: translateY(-100%) }
/* Een uitklapmenu openhouden en dan wegscrollen zou het menu meenemen. Hover binnen de kop zet de
   verberging uit. */
html.beweegt header:hover, html.beweegt header:focus-within { transform: none !important }

/* ── 3. De aankomst ─────────────────────────────────────────────────────────────────────────────
   Elke sectie komt 14px omhoog en van doorzichtig naar vol, in 620ms. Dat is traag genoeg om te
   zien en snel genoeg om niet in de weg te zitten.

   Drie keuzes die het verschil maken tussen "professioneel" en "een template":
     · 14px, niet 40. Grote sprongen lezen als een presentatie, kleine als papier dat gaat liggen.
     · Eén keer. Terugscrollen en het opnieuw zien afspelen is het moment waarop een bezoeker door
       heeft dat het een effect is. Zodra hij dat weet, is het weg.
     · Wat al in beeld staat bij het laden, beweegt niet. Een hero die binnenfadet terwijl je hem
       al aan het lezen bent, is alleen maar vertraging. ceeme-beweging.js slaat die over.

   `.bw-in` staat op het element vóór het in beeld komt; de observer haalt hem eraf. */
html.beweegt .bw-in {
  opacity: 0; transform: translateY(14px);
  transition: opacity 620ms cubic-bezier(.16, 1, .3, 1), transform 620ms cubic-bezier(.16, 1, .3, 1);
}
html.beweegt .bw-in.bw-nu { opacity: 1; transform: none }
/* De trap. Kinderen van een blok komen na elkaar binnen, 60ms uit elkaar. Vier stappen is de grens:
   daarna wacht je op het laatste item en dat voelt traag. */
html.beweegt .bw-na-1 { transition-delay: 60ms }
html.beweegt .bw-na-2 { transition-delay: 120ms }
html.beweegt .bw-na-3 { transition-delay: 180ms }
html.beweegt .bw-na-4 { transition-delay: 240ms }

/* ── 4. De cursor ───────────────────────────────────────────────────────────────────────────────
   Op visual.be is de muisaanwijzer een oranje stip die met vertraging achter je pointer aan komt.
   Njusja: "zelfs de muis is geanimeerd". Het is het detail waaraan je ziet dat iemand aan de site
   gewerkt heeft in plaats van hem opgeleverd.

   Wij doen het net anders, en met opzet: de echte cursor blijft staan. Bij hen is hij verborgen,
   en dat is het moment waarop zo'n effect gaat irriteren — je verliest je aanwijzer in een formulier
   of boven een tabel. Onze stip is een tweede laag die eromheen leeft. Hij is klein (10px), hij
   loopt achter, en boven iets klikbaars groeit hij naar een ring van 34px met de link erin.

   Alleen op een muis. `pointer: fine` sluit telefoon en tablet uit, waar een zwevende stip niets
   betekent en alleen batterij kost. */
.bw-stip {
  position: fixed; top: 0; left: 0; width: 10px; height: 10px; border-radius: 999px;
  background: #C6892B; z-index: 70; pointer-events: none; opacity: 0;
  transform: translate3d(-50%, -50%, 0);
  transition: width 220ms cubic-bezier(.16, 1, .3, 1), height 220ms cubic-bezier(.16, 1, .3, 1),
              background-color 220ms ease, border-color 220ms ease, opacity 260ms ease;
  border: 0 solid #C6892B; will-change: transform;
}
html.beweegt.bw-muis .bw-stip { opacity: .9 }
/* Boven een link of knop: van gevulde stip naar open ring. De ring omvat het doel in plaats van het
   te bedekken, dus je blijft zien waar je op klikt. */
html.beweegt .bw-stip.bw-raak {
  width: 34px; height: 34px; background: transparent; border-width: 1.5px; opacity: 1;
}
/* Ingedrukt: hij krimpt. Dat is de terugkoppeling die een aanraakscherm wel geeft en een muis niet. */
html.beweegt .bw-stip.bw-druk { width: 22px; height: 22px }
@media (hover: none), (pointer: coarse) { .bw-stip { display: none } }

/* ── 5. De aanraking ────────────────────────────────────────────────────────────────────────────
   Wat onder de muis komt, geeft antwoord. Drie plekken, en verder nergens — een site waar alles
   beweegt voelt goedkoop.

   De onderstreping die van links groeit: een link in lopende tekst mag rustig zijn tot je hem
   nadert. background-size op een gradient in plaats van een ::after, want dan blijft hij netjes
   breken over twee regels. */
html.beweegt .hw-sec p a:not(.hw-link):not(.hw-btn),
html.beweegt .hw-faq p a {
  text-decoration: none; color: #A8721F;
  background-image: linear-gradient(#C6892B, #C6892B);
  background-repeat: no-repeat; background-position: 0 100%; background-size: 0% 1.5px;
  transition: background-size 300ms cubic-bezier(.16, 1, .3, 1);
}
html.beweegt .hw-sec p a:hover, html.beweegt .hw-faq p a:hover { background-size: 100% 1.5px }

/* De kaart die opkijkt. 2px omhoog en de rand ontsteekt in amber — geen schaduw die opzwelt, want
   dat is het effect dat elke bootstrap-site heeft. */
html.beweegt .hw-link { transition: border-color 200ms ease, transform 240ms cubic-bezier(.16, 1, .3, 1) }
html.beweegt .hw-link:hover { transform: translateY(-2px) }

/* De tabelrij die zich aanwijst. Op een oordeeltabel van veertien rijen breed is je oog de rij kwijt
   halverwege; dit is de goedkoopste oplossing en hij werkt beter dan zebrastrepen. */
html.beweegt .hw-table tbody tr { transition: background-color 140ms ease }
html.beweegt .hw-table tbody tr:hover { background: rgba(198, 137, 43, .05) }

/* ── 5b. De knop die zich vult vanaf je muis ────────────────────────────────────────────────────
   Njusja wees op de knoppen van visual.be: kom je met de muis binnen, dan groeit er een oranje
   cirkel die de knop vult. Het aardige eraan is niet de kleur maar het VERTREKPUNT — de cirkel
   begint precies waar jouw muis de rand raakte. Kom je van links, dan komt hij van links. Daarom
   voelt het alsof de knop op jou reageert en niet op een klasse.

   ── Hoe dit werkt zonder één regel HTML te veranderen ─────────────────────────────────────────
   Er staan al honderden knoppen op de site en die willen we niet allemaal aanpassen. Dus:

     ::after  is de gewone achtergrond van de knop        (z-index -2)
     ::before is de amber cirkel die groeit               (z-index -1)
     de tekst zelf staat in het element                   (schildert boven allebei)

   Waarom die omweg: tekst die direct in een element staat, wordt geschilderd vóór positioned
   kinderen met z-index 0 of hoger. Een cirkel met z-index 0 zou dus over het opschrift heen liggen.
   Met -1 ligt hij eronder, maar dan ook onder de achtergrond van de knop — en dus onzichtbaar.
   Vandaar dat de achtergrond naar ::after verhuist. Drie lagen, geen extra markup.

   --bx en --by zet ceeme-beweging.js op het punt waar je binnenkwam; --bd is de doorsnee die groot
   genoeg is om vanuit elke hoek de hele knop te dekken. Verlaat je de knop, dan schuift het punt mee
   naar waar je vertrok en krimpt de cirkel daarheen terug. */
html.beweegt .hw-btn, html.beweegt .hw-btn2,
html.beweegt .btn-ink, html.beweegt .btn-ghost {
  position: relative; overflow: hidden; background-color: transparent; isolation: isolate;
  transition: color 260ms ease, border-color 260ms ease;
}
html.beweegt .hw-btn::after, html.beweegt .hw-btn2::after,
html.beweegt .btn-ink::after, html.beweegt .btn-ghost::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -2;
}
html.beweegt .hw-btn::after, html.beweegt .btn-ink::after { background: #221E18 }
/* De open knoppen hebben geen vlak, alleen hun rand — die blijft op het element zelf staan. */
html.beweegt .hw-btn2::after, html.beweegt .btn-ghost::after { background: transparent }

html.beweegt .hw-btn::before, html.beweegt .hw-btn2::before,
html.beweegt .btn-ink::before, html.beweegt .btn-ghost::before {
  content: ""; position: absolute; z-index: -1; border-radius: 999px; background: #C6892B;
  left: var(--bx, 50%); top: var(--by, 50%);
  width: var(--bd, 220px); height: var(--bd, 220px);
  transform: translate(-50%, -50%) scale(0);
  /* 520ms met een uitloop: snel op gang, zacht tot stilstand. Bij 300ms is het een flits, bij 800ms
     wacht je erop. Dit is dezelfde curve als de aankomst van de secties, zodat de hele site
     hetzelfde ritme heeft — dat is wat "één site" van "losse effecten" onderscheidt. */
  transition: transform 520ms cubic-bezier(.16, 1, .3, 1);
  pointer-events: none;
}
html.beweegt .hw-btn:hover::before, html.beweegt .hw-btn2:hover::before,
html.beweegt .btn-ink:hover::before, html.beweegt .btn-ghost:hover::before,
html.beweegt .hw-btn:focus-visible::before, html.beweegt .hw-btn2:focus-visible::before,
html.beweegt .btn-ink:focus-visible::before, html.beweegt .btn-ghost:focus-visible::before {
  transform: translate(-50%, -50%) scale(1);
}
/* Amber vlak, donkere tekst. Op #C6892B is #17170F het enige dat comfortabel leest. */
html.beweegt .hw-btn:hover, html.beweegt .hw-btn2:hover,
html.beweegt .btn-ink:hover, html.beweegt .btn-ghost:hover { color: #17170F }
html.beweegt .hw-btn2:hover, html.beweegt .btn-ghost:hover { border-color: #C6892B }

/* De variant waarin de cirkel over de rand loopt, zoals bij hen. Losser en vrolijker, maar op een
   crèmekleurige achtergrond ook luider. Zet de klasse op <html> om hem aan te zetten; het voorbeeld
   toont ze naast elkaar zodat de keuze op wat je ziet berust en niet op mijn smaak. */
html.beweegt.bw-vlek-uit .hw-btn, html.beweegt.bw-vlek-uit .hw-btn2,
html.beweegt.bw-vlek-uit .btn-ink, html.beweegt.bw-vlek-uit .btn-ghost { overflow: visible }
html.beweegt.bw-vlek-uit .hw-btn:hover::before, html.beweegt.bw-vlek-uit .hw-btn2:hover::before,
html.beweegt.bw-vlek-uit .btn-ink:hover::before, html.beweegt.bw-vlek-uit .btn-ghost:hover::before {
  transform: translate(-50%, -50%) scale(1.18);
}

/* ── 6. De overgang tussen pagina's ─────────────────────────────────────────────────────────────
   Dit is de grootste van de zeven en de minst zichtbare. Een klik op een link geeft nu een witte
   flits: de oude pagina verdwijnt, de browser tekent leeg, de nieuwe komt. Op een site met een
   crèmekleurige achtergrond is die flits wit en dus lelijk.

   Met de View Transition API lost de ene pagina op in de andere. Twee regels, geen JavaScript,
   geen router, geen framework. Browsers die het niet kennen negeren het blok en krijgen wat ze nu
   ook krijgen — dit is de zeldzame verbetering die niets kost.

   De kop doet niet mee aan de vervaging: die staat op elke pagina op dezelfde plek, dus die hoort
   te blijven staan terwijl de inhoud wisselt. Dat is precies waarom een sitewissel bij Mistral
   aanvoelt als één ding in plaats van als vier losse bestanden. */
@view-transition { navigation: auto }
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: bw-uit 180ms cubic-bezier(.4, 0, 1, 1) both }
  ::view-transition-new(root) { animation: bw-aan 260ms cubic-bezier(0, 0, .2, 1) both }
}
@keyframes bw-uit { to { opacity: 0 } }
@keyframes bw-aan { from { opacity: 0; transform: translateY(6px) } }
header { view-transition-name: bw-kop }

/* ── 7. De rust ─────────────────────────────────────────────────────────────────────────────────
   Wie in zijn systeem heeft gezet dat hij geen beweging wil, heeft daar een reden voor die ons niet
   aangaat. Dan gaat alles uit: geen aankomst, geen cursor, geen verbergende kop, geen overgang.
   Niet afgezwakt — uit. Wat overblijft is de site zoals hij zonder dit bestand ook was, en dat is
   het bewijs dat deze laag nergens inhoud draagt.

   Let op de volgorde: dit blok staat als laatste, dus het wint van alles hierboven. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto }
  html.beweegt .bw-in { opacity: 1 !important; transform: none !important; transition: none !important }
  html.beweegt.bw-weg header { transform: none }
  html.beweegt header { transition: none }
  .bw-stip { display: none !important }
  .bw-lees { transition: none }
  html.beweegt .hw-link:hover { transform: none }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none }
  /* De knop houdt zijn kleurwissel — dat is informatie, geen beweging — maar de cirkel groeit niet.
     Hij staat er meteen, over de hele knop. */
  html.beweegt .hw-btn::before, html.beweegt .hw-btn2::before,
  html.beweegt .btn-ink::before, html.beweegt .btn-ghost::before {
    transition: none; left: 50%; top: 50%;
  }
}

/* ══ 8. DE CAMERA — J182, 1 september 2026 ══════════════════════════════════════════════════════
   Njusja, tweemaal achter elkaar, over twee verschillende versies:
   *"ik zie niets wat ik nog nooit op een andere website zag"* en *"nope, nog steeds niet speciaal"*.
   En daarna: *"denk zoals een wereldbefaamde motion ux bouwer"*.

   Ze heeft in beide gevallen gelijk gehad, en de fout zat niet in de sterkte maar in de SOORT.
   Ik bouwde twee keer een EFFECT: iets dat je op elk element plakt en dat overal hetzelfde doet.
   Dat is precies wat elk sjabloon doet, en daarom herkende ze het meteen.

   ── Wat een motion designer anders doet ──────────────────────────────────────────────────────
   Drie dingen, en geen ervan is een effect:

   1. HET BEELDVLAK IS EEN CAMERA, NIET EEN VENSTER. Op een gewone site staat alles in hetzelfde
      platte vlak en fade-t het aan. Hier ligt elke sectie als een PLAAT in de ruimte: ze komt van
      onder-achter aan, kantelt recht als ze op ooghoogte staat, en kantelt weg als ze vertrekt.
      Aankomst → scherpstelling → vertrek. Dat is een camerabeweging en geen overgang, en het is
      het verschil tussen "er komt iets binnen" en "ik beweeg ergens doorheen".

   2. SCHERPTEDIEPTE MAAKT DE DIEPTE ECHT. Kantelen alleen leest het oog als een truc; kantelen mét
      onscherpte op afstand leest het als ruimte, omdat het is wat een lens doet. Dit is de goedkope
      helft van het idee en de helft die het verkoopt.

   3. NIETS BEWEEGT ALS ÉÉN BLOK. De plaat beweegt, en wat erin staat loopt ACHTER. Bij de vakmensen
      heet dat overlapping action, en het is de reden dat iets "gemaakt" voelt in plaats van
      "toegepast": in de natuur komt een massa nooit exact gelijk tot stilstand met zijn onderdelen.

   ── En waarom dit hier past en niet zomaar mooi is ───────────────────────────────────────────
   Wij verkopen dat een machine door jouw pagina beweegt en kiest. Een site waar de bezoeker zelf
   door de inhoud beweegt in plaats van hem voorbij te zien komen, is dat verhaal in vorm.

   ── DE GRENS, die hier hard is ───────────────────────────────────────────────────────────────
   · Alles staat in `@supports (animation-timeline: view())` + `prefers-reduced-motion`. Geen
     ondersteuning of beweging uit: er verandert niets en de pagina staat er gewoon.
   · Geen JavaScript. Dit hangt NIET aan `html.beweegt` — het kan niet halverwege stukgaan.
   · De opacity zakt tot 0,42 en niet lager, en de onscherpte is 3,5px op het uiterste punt: op de
     verste stand is elke letter nog te lezen. `scripts/test-zonderjs.mjs` mag hier nooit op afgaan
     en dat is geen toeval maar de ontwerpeis.
   · `perspective()` staat IN de transform van het element zelf en niet op een ouder — een ouder met
     perspective wordt een containing block en zou de leesbalk en het menu uit hun `fixed` trekken. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* De plaat. 0% = ze komt aan van onder-achter · 50% = recht en scherp op ooghoogte ·
       100% = ze vertrekt naar boven-achter. Symmetrisch, want een camera doet niet iets anders
       bij het weggaan dan bij het komen. */
    @keyframes ceeme-plaat {
      /* ⚠ HET SCHERPE VENSTER IS BREED, en dat is na Njusja's *"nog voor ik kon lezen was het al
         weg"* de belangrijkste maat van het hele bestand. Een sectie staat van 28% tot 72% van
         haar doorloop VOLLEDIG stil, scherp en op volle sterkte — dat is meer dan de helft van de
         tijd dat ze in beeld is. De camera beweegt alleen aan de uiteinden, waar je toch niet
         leest. Beweging mag nooit tussen de lezer en de zin gaan staan. */
      0%   { opacity: .6; transform: perspective(1600px) translate3d(0, 6vh, -200px) rotateX(8deg) }
      28%  { opacity: 1;  transform: perspective(1600px) translate3d(0, 0, 0) rotateX(0) }
      72%  { opacity: 1;  transform: perspective(1600px) translate3d(0, 0, 0) rotateX(0) }
      100% { opacity: .6; transform: perspective(1600px) translate3d(0, -6vh, -200px) rotateX(-8deg) }
    }
    /* Wat erin staat loopt achter: kleinere uitslag, maar over hetzelfde bereik, zodat het de plaat
       nooit inhaalt en pas ná haar tot rust komt. */
    @keyframes ceeme-nasleep {
      /* Alleen naar BENEDEN uit rust, nooit omhoog: een blok dat omhoog schuift kruipt tegen de
         kop erboven, en dat is exact wat Njusja *"slechte uitlijning tegen titel geplakt"* noemde. */
      0%   { transform: translate3d(0, 30px, 0) }
      30%, 100% { transform: none }
    }

    .band, .sb, .pv, .finalcta {
      transform-origin: 50% 50%;
      animation: ceeme-plaat linear both;
      animation-timeline: view();
      animation-range: cover 0% cover 100%;
    }
    /* De hero blijft er buiten: daar staat het WebGL-doek, en dat heeft zijn eigen beweging. */
    .cmp-zij { animation: none }

    .band > .wrap > *, .sb > .wrap > *, .pv > .wrap > * {
      animation: ceeme-nasleep linear both;
      animation-timeline: view();
      animation-range: cover 6% cover 94%;
    }
    /* De trap. Drie stappen, meer niet — bij vier gaat het tellen en dat mag je nooit zien. */
    .band > .wrap > :nth-child(2) { animation-range: cover 10% cover 94% }
    .band > .wrap > :nth-child(3) { animation-range: cover 14% cover 94% }
  }
}

/* ══ 9. WOORD VOOR WOORD SCHERP — J183, 1 september 2026 ════════════════════════════════════════
   Njusja, na drie afgekeurde versies: *"denk nu eens echt als bekende UX developer met tekst motion
   etc. zoek desnoods online naar top effecten"*. Eén woord uit dat onderzoek verklaarde alle drie
   de mislukkingen: SPLIT-TEXT. Bekroond werk animeert per WOORD; ik bewoog steeds hele blokken. Een
   blok dat aankomt is een overgang. Woorden die één voor één scherp worden is typografie die zich
   gedraagt — een andere discipline, en de reden dat het onmiskenbaar is.

   ── Het effect ───────────────────────────────────────────────────────────────────────────────
   Elk woord komt van 10px onder de regel, onscherp en half aanwezig, en zet zich neer. Niet
   aanfaden maar SCHERPSTELLEN: een woord dat aanfade-t leest als "er verschijnt iets", een woord
   dat scherpstelt leest als een lens die het pakt. Dat kan alleen als de tekst per woord opgeknipt
   is, en dat is precies waarom je het bijna nergens ziet.

   ⛔ GEEN `animation-timeline` MEER, en dat is de belangrijkste regel van dit blok.
   Versie vier hing aan scroll-gedreven animatie. Njusja werkt in Safari, de bronnen geven vier
   verschillende Safari-versies op voor die functie en spreken elkaar tegen, en haar oordeel was:
   *"ik zie niks?"*. Volkomen terecht — er gebeurde niets. Ik had beweging gebouwd op een functie
   waarvan ik de ondersteuning in de enige browser die telde niet kon meten.

   Dit werkt nu met een waarnemer en een gewone overgang: oud, saai, overal. En het is voor dít
   effect ook beter. Met een klok kies je een cadans; met een scrollpositie erf je die van de muis
   van de bezoeker. Een woord dat scherpstelt hoort dat in zijn eigen tempo te doen.

   ── DE GRENZEN ───────────────────────────────────────────────────────────────────────────────
   · De beginstand hangt aan `.bw-kop`, en die klasse zet het script pas NADAT het knippen gelukt
     is. Geen JavaScript → geen spans, geen klasse, geen regel die aanslaat → de kop staat er
     gewoon. De uitgeleverde HTML bevat geen enkele span; een crawler leest een normale kop.
   · Ondergrens 0,32 en niet 0. Ook halverwege is elk woord leesbaar. Na de leeskop van gisteren —
     die tekst onzichtbaar maakte omdat ik de veiligheid beredeneerde in plaats van bekeek — is dat
     hier de eerste eis en geen detail.
   · Het script heeft daarbovenop een wekker van 1,5 s die alles alsnog aanzet als de waarnemer
     nooit langskomt. Er bestaat geen toestand waarin een kop op zijn beginwaarde blijft hangen.
   · De klasse heet `bw-w` en niet `w`: home.html draagt al een `<em class="w">gekozen</em>` in het
     productbeeld, en dat woord zou zijn meegegaan zonder dat iemand het verband legde. */
/* ⛔ §9 IS TERUGGEDRAAID — 1 september 2026, 01u05. HIER STOND DE WOORD-VOOR-WOORD-BEWEGING.
   ================================================================================================
   Het idee was goed en het onderzoek klopte: split-text is waar bekroond werk op draait. De
   uitvoering is vijf keer op rij stukgegaan, en altijd op dezelfde manier — tekst die verdween.

     1. de leeskop            een verloop met `background-clip: text`; buiten het verloopvlak kreeg
                              de letter geen verf en was hij niet bleek maar onzichtbaar
     2. de scroll-tijdlijn    Safari zette de beginstand wél en liet de tijdlijn nooit lopen
     3. de wekker             zette na 1,5 s álles aan, ook twintig schermen lager — het effect weg
     4. het masker            `overflow: hidden` met het woord eronder: geen bodem, dus wég
     5. de heroïsche koppen   `.cmp-zij` en `.ph` hebben hun eigen onthulling; de mijne botste

   ── WAAROM IK HET ERUIT HAAL EN NIET NOG EEN KEER REPAREER ───────────────────────────────────
   Niet omdat het onmogelijk is. Omdat ik het niet kan ZIEN. Mijn browservenster rendert niet — nul
   frames — dus elke controle die ik deed was een meting in de HTML en het CSS, nooit een blik op
   het scherm. Njusja was de hele avond mijn enige paar ogen, en elke ronde kostte haar een
   schermafdruk van haar eigen live site met een gat waar een titel hoorde.

   Daar komt bij dat deze pagina's al DRIE eigen bewegingssystemen hebben: `.rv` met zijn eigen
   onthulling, de horizontale panelenschuiver in de hero, en de aankomstlaag van ceeme-beweging.js.
   Een vierde laag daarbovenop botst met alle drie op een andere manier, en dat is niet blind uit
   te meten om één uur 's nachts op een productiesite.

   ⛔ DE VOORWAARDE OM DIT TERUG TE ZETTEN: eerst een manier waarop de bouw zelf een schermafdruk
   maakt en toont dat elke kop nog leesbaar is. Pas daarna de beweging. De volgorde van deze avond
   was omgekeerd, en dat is de hele verklaring.

   Het script `public/js/ceeme-woorden.js` blijft staan, met zijn volledige verslag erin. Het wordt
   nergens meer geladen. Wat hieronder volgt (§10, de richting) verbergt niets en blijft wél staan. */

/* ══ 10. DE RICHTING VOLGT DE PLAATS — J184, 1 september 2026 ═══════════════════════════════════
   Njusja: *"moest een blok af en toe eens van opzij komen ipv boven naar beneden zou dat ook een
   speciaal effect zijn, toch?"*. Ja, en het antwoord op "af en toe" staat in ceeme-beweging.js §3c:
   niet af en toe en niet willekeurig, maar volgend uit waar het blok ligt. Links in de kolom → van
   links. Rechts → van rechts. Volle breedte → van onderen, zoals altijd.

   Het verschil met een willekeurige richting is groot en het is precies het verschil tussen
   "gemaakt" en "toegepast": bij willekeur voel je de dobbelsteen, bij deze regel lijkt het of de
   pagina zich in elkaar schuift.

   ⚠ WAAROM `overflow-x: clip` OP MAIN EN NIET `hidden`. Een blok dat van 44px buiten zijn plaats
   komt kan het venster breder maken, en dan krijgt de pagina een horizontale schuifbalk die er
   even is en weer weg gaat — het lelijkste dat beweging je kan opleveren. `clip` snijdt dat af
   zonder een scroll-container te maken; `hidden` zou dat wél doen en daarmee elke `position:
   sticky` op de pagina slopen. Dat is een bekende val en de reden dat het hier uitgeschreven staat. */
body { overflow-x: clip }

/* ⚠ DE SELECTOR BEGINT MET `html.beweegt` EN DAT IS GEEN OPSMUK. De basisregel in ceeme-2026.css
   luidt `html.beweegt .rv { transform: translateY(30px) }` en heeft specificiteit (0,2,1). Een
   regel `.rv[data-uit="links"]` haalt (0,2,0) en verliest dus — de richting zou nooit hebben
   aangeslagen, hoe correct de rest ook was. Gevonden door de specificiteit uit te rekenen vóór het
   live ging, niet door achteraf te kijken waarom er niets gebeurde.

   De 14px omlaag blijft staan naast de zijwaartse verplaatsing: een blok dat puur horizontaal
   binnenschuift ziet eruit alsof het over een rail loopt. Met een klein beetje val eronder valt het
   op zijn plaats, en dat is wat je wil zien. */
@media (prefers-reduced-motion: no-preference) {
  html.beweegt .rv[data-uit="links"]  { transform: translate3d(-56px, 14px, 0) }
  html.beweegt .rv[data-uit="rechts"] { transform: translate3d(56px, 14px, 0) }
  html.beweegt .rv[data-uit].in       { transform: none }
}

/* ══ 11. DE CURSOR VAN DE TYPEMACHINE — J185, 1 september 2026 ══════════════════════════════════
   Njusja: *"of zorg bij de koppen alsof ze getypt worden"*. De H1 van elke pagina wordt letter voor
   letter gezet door ceeme-woorden.js; dit is alleen het streepje dat er tijdens het typen achter
   knippert. Amber, want dat is het enige accent op deze site.

   ⚠ DIT VERBERGT NIETS EN KAN NIETS VERBERGEN. Het is een `::after` op een klasse die alleen
   bestaat terwijl er getypt wordt, en die het script zelf weer weghaalt — met een tijdslot van twee
   seconden als harde eindstreep. Alle vijf de mislukte versies van vanavond hadden een beginstand
   in de CSS die op iets moest wachten. Deze regel wacht nergens op. */
.bw-typt::after {
  content: "";
  display: inline-block;
  width: .06em;
  height: .82em;
  margin-left: .06em;
  background: #C6892B;
  vertical-align: -.06em;
  animation: bw-knipper .62s steps(1) infinite;
}
@keyframes bw-knipper { 0%, 50% { opacity: 1 } 50.01%, 100% { opacity: 0 } }
@media (prefers-reduced-motion: reduce) { .bw-typt::after { display: none } }
