/* ── tokens ─────────────────────────────────────────────────────────────── */
:root{
  --ink:#0f1012; --ink2:#1d1e20; --mut:#6b6d72;
  --paper:#ffffff; --paper2:#f2f2f4; --paper3:#e9e9ec;
  --line:rgba(15,16,18,.13); --line-d:rgba(255,255,255,.15);
  /* Accent wordt door de labbalk gezet; standaard = de huisstijl (HUISSTIJL.md,
     01-09-2026). Terracotta is de TEKSTkleur op papier (5,46:1 op wit, 4,51:1 op
     --paper3); koraal is op wit maar 2,57:1 en dus uitsluitend een vlak, een balk
     of een lijn — én de tekstkleur op een donkere ondergrond (6,92:1 op #16181c). */
  --ac:#b84226; --ac-lt:#ff7a59;
  --ink3:#3a3c41;                   /* zachtere lopende tekst */
  /* Switzer, zelf gehost. Besluit 16-08-2026: augen.pro's typografie overnemen.
     ⚠️ Hun font is PP Neue Montreal en dat is betaald (Pangram Pangram).
     Switzer (Indian Type Foundry, gratis voor commercieel gebruik) komt uit
     dezelfde neo-grotesk-familie en is in onze eigen referentie al aangewezen
     als de eerlijke tegenhanger. Kopen kan later; dan is het deze ene regel.
     Gemeten bij augen: gewicht 350, letterafstand −0,02em, regelhoogte 1,2.
     350 bestaat niet in Switzer (geen variabele versie op Fontshare), dus
     400 voor tekst en 300 voor groot type — dezelfde opbouw als zij. */
  /* 21-08: Switzer -> Geist. Lenny wil augens letter, en dat is PP Neue
     Montreal Book 350 (Pangram Pangram, vanaf $40). Van vijf gratis
     kandidaten naast augens eigen tekst gezet, komt Geist het dichtst: even
     smal, rechte afsluitingen, dezelfde compacte B/a/y. Switzer is breder en
     ronder. Geist is variabel 100-900 in één bestand van 29 kB.
     Terug of naar iets anders: de labbalk heeft alle vijf. */
  --sans:'Geist','Switzer',-apple-system,BlinkMacSystemFont,'Helvetica Neue',
         system-ui,sans-serif;
  --gut:5.13vw;
  --maxw:1560px;
  /* ── typografische schaal ────────────────────────────────────────────────
     Zeven stappen, en verder niets. Er stonden er 19, waarvan zes binnen 4 px
     van elkaar — dat leest niet als hiërarchie maar als ruis. Wie een achtste
     maat nodig heeft, heeft waarschijnlijk een bestaande rol nodig.
     16 px blijft bestaan voor invoervelden: daaronder zoomt iOS bij elke tik. */
  --fs-display:clamp(40px,6vw,84px);
  --fs-h2:clamp(30px,3.2vw,46px);
  --fs-h3:clamp(22px,2vw,26px);
  --fs-lead:clamp(18px,1.6vw,20px);
  --fs-basis:17px;
  --fs-ui:15px;
  --fs-micro:12px;
  /* ── ritme ───────────────────────────────────────────────────────────────
     Drie afstanden in plaats van één. Elke sectie evenveel lucht geven maakt
     alles even belangrijk, en dus niets. */
  --ruimte-groot:clamp(96px,10vw,148px);
  --ruimte-midden:clamp(56px,5.5vw,88px);
  --ruimte-klein:clamp(28px,2.6vw,40px);
}
/* Alle vijf de standen hebben een eigen regel, ook de standaard — anders
   maakt de knop van de vorige standaard het attribuut leeg en val je terug
   op :root in plaats van op die letter. (21-08, na de wissel naar Geist.) */
html[data-font="switzer"]{--sans:'Switzer','Helvetica Neue',Arial,sans-serif}
html[data-font="systeem"]{--sans:-apple-system,BlinkMacSystemFont,'SF Pro Text',
  'SF Pro Display',system-ui,sans-serif}
html[data-font="general"]{--sans:'General Sans','Helvetica Neue',Arial,sans-serif}
/* 21-08: kandidaten om Switzer te vervangen. Lenny wil augens letter, en dat
   is PP Neue Montreal (Book 350 + Light 300, Pangram Pangram, vanaf $40).
   Deze drie zijn gratis en komen uit dezelfde neo-grotesk-hoek. */
html[data-font="geist"]{--sans:'Geist','Helvetica Neue',Arial,sans-serif}
html[data-font="instrument"]{--sans:'Instrument Sans','Helvetica Neue',Arial,sans-serif}
html[data-font="inter"]{--sans:'Inter','Helvetica Neue',Arial,sans-serif}
/* 25-08: Clash Grotesk, aangewezen door Lenny na sensiq.co. Twee teststanden,
   want dat zijn twee verschillende vragen:
     data-font="clash"  = Clash Grotesk OVERAL, ook de lopende tekst
     data-kop="clash"   = alleen de KOPPEN, tekst blijft staan — dat is hoe sensiq
                          het doet (Clash Grotesk kop + Inter Display tekst)
   Clash Grotesk heeft geen gewicht 350, dus de displaykoppen gaan naar 400/500;
   op 350 zou de browser zelf gaan interpoleren en dat oogt slap. */
html[data-font="clash"]{--sans:'Clash Grotesk','Helvetica Neue',Arial,sans-serif}
html[data-kop="clash"]{--disp:'Clash Grotesk','Helvetica Neue',Arial,sans-serif}
html[data-kop="clash"] .display{font-weight:500;letter-spacing:-.025em}
html[data-kop="clash"] .h2{font-weight:500;letter-spacing:-.024em}
html[data-font="clash"] .display,html[data-font="clash"] .h2{font-weight:500}

/* ══ ÉÉN THEMA: WIT ═════════════════════════════════════════════════════════
   Hier stond een compleet tweede (donker) thema dat de systeemvoorkeur
   volgde. Eruit op 16-08-2026: de site is wit. Op een Mac die op donker
   staat kreeg je anders een zwarte site, en dat was precies wat weg moest.
   De volledige oude versie staat in _backup-wit-0816/ — daar komt hij
   vandaan als het ooit terug moet. Bijkomend voordeel: de token-val van
   een omgekeerde band (--ink dat de achtergrond ís) bestaat niet meer. */

/* ── basis ──────────────────────────────────────────────────────────────── */
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;background:var(--paper);color:var(--ink);
  /* −0,02em is augen.pro's waarde, en zij zetten hem op ALLES — ook op lopende
     tekst van 16 px, waar wij `normal` hadden staan. Gemeten: 16px→−0,32px,
     27px→−0,54px, 12px→−0,24px, alle drie exact −0,02em.
     ⚠️ Hun regelhoogte van 1,2 is bewust NIET overgenomen. Augen zet er korte
     statements en labels in; onze antwoorden zijn alinea's van drie zinnen in
     het Nederlands, en 1,2 maakt die slecht leesbaar. Koppen staan wel strak. */
  font-family:var(--sans);font-size:var(--fs-basis);font-weight:400;
  letter-spacing:-.02em;
  line-height:1.55;letter-spacing:-.011em;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,p,ul,figure{margin:0}
ul{padding:0;list-style:none}
a{color:inherit;text-decoration:none}
::selection{background:var(--ac);color:#fff}

/* ── layout ─────────────────────────────────────────────────────────────── */
.wrap{max-width:var(--maxw);margin:0 auto;padding-left:var(--gut);padding-right:var(--gut)}
.block{padding:var(--ruimte-groot) 0}
/* Het cijferblok mag landen, de afsluiter juist niet: daar wil je een
   besluit, geen adempauze. */
.block.ruim{padding:calc(var(--ruimte-groot) * 1.3) 0}
.block.ctaband{padding:var(--ruimte-midden) 0}
section[id]{scroll-margin-top:64px}
.b-paper{background:var(--paper)}
.b-paper2{background:var(--paper2)}
/* ⚠️ `.b-ink` WAS de zwarte band tussen witte blokken. De site is sinds
   16-08 helemaal wit, dus hij is nu een gewoon wit vlak met een haarlijn
   erboven — anders zie je niet meer waar de ene sectie ophoudt.
   De naam blijft staan omdat hij op elf plekken in bouw.py gebruikt wordt;
   hernoemen is een aparte ronde. */
.b-ink{background:var(--paper);color:var(--ink);
  border-top:1px solid var(--line)}
.b-ink .lbl b{color:var(--ink)}

/* twee kolommen: labelpaar links, inhoud rechts */
.cols{display:grid;grid-template-columns:minmax(150px,1.5fr) 6fr;gap:clamp(24px,4vw,72px)}
.lbl{font-size:var(--fs-ui);line-height:1.25;letter-spacing:-.02em;color:var(--mut);font-weight:400}
.lbl b{display:block;color:var(--ink);font-weight:400}

.rule{height:1px;background:var(--line);border:0;margin:0}

/* ── type ───────────────────────────────────────────────────────────────── */
.display{font-weight:300;letter-spacing:-.028em;line-height:1.08;
  font-size:var(--fs-display)}
.h2{font-weight:300;letter-spacing:-.024em;line-height:1.14;
  font-size:var(--fs-h2)}
.h3{font-weight:400;letter-spacing:-.018em;line-height:1.22;font-size:var(--fs-h3)}
.lead{font-size:var(--fs-lead);line-height:1.48;letter-spacing:-.012em;max-width:34em}
.mut{color:var(--mut)}
.ac{color:var(--ac)}
.small{font-size:var(--fs-ui);line-height:1.45;letter-spacing:-.01em}

/* ── nav ────────────────────────────────────────────────────────────────── */
/* De pil is 335 px breed en staat midden boven de tekstkolom: bij scrollen
   liepen 26 tekstregels eronder door. Hij schuift nu weg zodra je naar
   beneden leest en komt terug zodra je omhoog gaat. */
header{transition:transform .28s cubic-bezier(.4,0,.2,1)}
body.nav-weg header{transform:translateY(-140%)}
@media(prefers-reduced-motion:reduce){body.nav-weg header{transform:none}}
header{position:fixed;inset:14px 0 auto 0;z-index:60;display:flex;justify-content:center;
  pointer-events:none}
.navbar{pointer-events:auto;display:flex;align-items:center;gap:8px;max-width:calc(100% - 24px)}
/* ⚠️ 02-09-2026: hier zat een zwarte CIRKEL van 44 px om het beeldmerk, met het
   logo omgekeerd naar wit erin. Lenny: *"in de hero is er een zwart bolletje om
   ons logo, haal dat weg."* De cirkel bestond omdat één bestand twee ondergronden
   moet dienen: de hero is donker, de rest van de site wit. Opgelost met de stand
   in plaats van met een vorm — `body.op-donker` (site.js zet hem zolang de kopbalk
   over de hero staat) keert het logo om. Geen cirkel meer, op geen van beide. */
.mark{flex:none;display:grid;place-items:center;padding:0 2px;
  transition:opacity .25s ease}
.mark:hover{opacity:.62}
/* Het beeldmerk gaat vóór de naam (HUISSTIJL.md §3, instructie 01-09-2026).
   merk.webp is zwart lijnwerk op transparant; de cirkel is --ink, dus omkeren.
   ⚠️ width:auto is verplicht — een <img> met alleen height wordt in deze
   grid-cel uitgerekt. Dat is in voorstel/ddc al eens 6,7× te breed geworden. */
.mark img{height:30px;width:auto;display:block;filter:none;
  transition:filter .25s ease}
/* over de hero (en op nacht) is de ondergrond donker: het zwarte lijnwerk omkeren */
body.op-donker .mark img, html[data-thema="nacht"] .mark img, /* over de hero (en op nacht) is de ondergrond donker: het zwarte lijnwerk omkeren */
body.op-donker .mark img, html[data-grond="antraciet"] .mark img{filter:invert(1)}
.pill{display:flex;align-items:center;gap:2px;background:rgba(233,233,236,.94);
  border-radius:999px;padding:5px}
.pill a{padding:9px 17px;border-radius:999px;font-size:var(--fs-ui);letter-spacing:-.015em;color:var(--ink3);
  transition:background .22s ease,color .22s ease;white-space:nowrap}
.pill a:hover{background:#fff;color:var(--ink)}
.pill a.cta{background:var(--ink);color:#fff}
.pill a.cta:hover{background:var(--ac);color:#fff}
.burger{display:none;width:44px;height:44px;border-radius:999px;background:rgba(233,233,236,.94);
  border:0;cursor:pointer;padding:0}

/* ── thema-knop ─────────────────────────────────────────────────────────────
   Zon en maan liggen over elkaar; alleen de opacity en een kleine draai
   wisselen, dus de browser hoeft niets te herberekenen.                     */

/* ── dock-navigatie ─────────────────────────────────────────────────────────
   Het vergrootglas-effect van macOS, maar op WOORDEN in plaats van iconen —
   kale iconen zonder tekst zijn precies wat we in de DCSS-audit afkeurden.
   Het item onder de muis groeit, de buren iets minder, en dat loopt uit met
   de afstand. Alleen `transform` en `font-variation-settings` bewegen mee.

   Geen `backdrop-filter`: dat is hier de bekende oorzaak van stroef scrollen.
   Echt matglas zit achter `?blur=1`.                                        */
.pill.dock a{transform-origin:center bottom;
  transition:background .22s ease,color .22s ease}
.pill.dock a span{display:inline-block;
  transform:scale(var(--s,1));
  transition:transform .18s cubic-bezier(.2,.9,.3,1.25)}
@media(hover:none){.pill.dock a span{transform:none!important}}
html.glas-echt .pill{background:rgba(233,233,236,.62);
  -webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}
html.glas-echt[data-thema="donker"] .pill{background:rgba(20,20,24,.62)}
.burger span{display:block;width:16px;height:1.5px;background:var(--ink);margin:8px auto;
  transition:transform .25s ease,opacity .2s ease}
.nav-open .burger span:nth-child(1){transform:translateY(5px) rotate(45deg)}
.nav-open .burger span:nth-child(2){opacity:0}
.nav-open .burger span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}

/* ── hero ───────────────────────────────────────────────────────────────── */
/* 240 px boven de kop was 27% van een scherm van 900 px, en daarin stond
   niets. De menubalk is 66 px hoog, dus 170 px is ruim. */
.hero{padding-top:clamp(112px,11vw,170px);padding-bottom:clamp(70px,8vw,120px);
  background:var(--paper2)}
.hero .display{max-width:16ch}
.hero .lead{margin-top:clamp(24px,3vw,40px)}
.btns{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(24px,3.4vw,40px)}
.btn{display:inline-flex;align-items:center;gap:10px;padding:14px 24px;border-radius:999px;
  font-size:var(--fs-ui);letter-spacing:-.015em;min-height:48px;
  transition:transform .22s ease,background .22s ease,color .22s ease,border-color .22s ease}
.btn-p{background:var(--ink);color:#fff}
.btn-p:hover{background:var(--ac);transform:translateY(-1px)}
.btn-s{border:1px solid var(--line);color:var(--ink)}
.btn-s:hover{border-color:var(--ink);transform:translateY(-1px)}
.btn i{font-style:normal;transition:transform .25s ease}
.btn:hover i{transform:translateX(3px)}
.facts{margin-top:clamp(40px,5vw,64px);display:flex;flex-wrap:wrap;gap:8px 26px;
  font-size:var(--fs-ui);color:var(--mut);letter-spacing:-.01em}
.facts span::before{content:"";display:inline-block;width:4px;height:4px;border-radius:50%;
  background:var(--ac);margin-right:9px;vertical-align:2px}

/* ── diensten ───────────────────────────────────────────────────────────── */
.svc{border-top:1px solid var(--line);padding:clamp(34px,4vw,58px) 0}
.svc:last-of-type{border-bottom:1px solid var(--line)}
.svc-n{font-size:var(--fs-ui);color:var(--mut);letter-spacing:-.01em}
.svc-n b{display:block;color:var(--ink);font-weight:400;font-size:var(--fs-ui)}
.svc-body{max-width:74ch}
.svc-body .h3{margin-bottom:16px}
.svc-body p{color:var(--ink3);max-width:38em}
.pts{margin-top:24px;display:grid;gap:9px;max-width:36em}
.pts li{position:relative;padding-left:22px;font-size:var(--fs-basis);color:var(--ink3);letter-spacing:-.011em}
.pts li::before{content:"";position:absolute;left:0;top:.62em;width:9px;height:1px;background:var(--ac)}
.pts li strong{font-weight:400;color:var(--ink)}
.note{margin-top:24px;padding-left:16px;border-left:2px solid var(--ac);
  font-size:var(--fs-ui);color:var(--ink3);max-width:34em}
.note b{font-weight:400;color:var(--ink)}
/* (De omkering voor de zwarte band is er op 16-08 uit: die band is wit.) */

/* processtrook 01-05 */
.flow{margin-top:24px;display:grid;grid-template-columns:repeat(5,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:8px;overflow:hidden}
.flow div{background:var(--paper);padding:14px 15px}
.b-paper2 .flow div{background:var(--paper2)}
.flow span{display:block;font-size:var(--fs-micro);color:var(--ac);letter-spacing:.02em;margin-bottom:8px}
.flow em{font-style:normal;font-size:var(--fs-ui);letter-spacing:-.015em}

/* ── cijferblok ─────────────────────────────────────────────────────────── */
.nums{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(28px,4vw,60px);
  margin-top:clamp(40px,4vw,64px)}
.num b{display:block;font-weight:300;letter-spacing:-.035em;line-height:.94;
  font-size:clamp(52px,7.6vw,116px);color:var(--ac)}
.num span{display:block;margin-top:16px;font-size:var(--fs-ui);color:var(--mut);letter-spacing:-.01em;
  max-width:22ch}

/* ── werk ───────────────────────────────────────────────────────────────── */
.job{display:grid;grid-template-columns:52px 1.35fr 2.2fr auto;gap:clamp(14px,2.4vw,40px);
  align-items:start;padding:clamp(22px,2.6vw,34px) 0;border-top:1px solid var(--line)}
.job:last-of-type{border-bottom:1px solid var(--line)}
.job .n{font-size:var(--fs-ui);color:var(--mut)}
.job .t{font-size:var(--fs-lead);letter-spacing:-.018em;line-height:1.28}
.job .d{font-size:var(--fs-ui);color:var(--ink3);line-height:1.5}
.job .s{font-size:var(--fs-micro);color:var(--mut);white-space:nowrap;padding-top:3px}
.job .s::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--ac);margin-right:8px;vertical-align:1px}

/* ── het werk met beeld ─────────────────────────────────────────────────────
   De projectenlijst was een tabel zonder één beeld, op de pagina die
   uitgerekend "Het werk" heet. Nu staat de opname ernaast: tekst links,
   schermafdruk rechts. Vier van de vijf hebben er een; het vijfde project
   loopt nog en krijgt een eerlijk leeg vlak in plaats van een plaatje. */
.job{grid-template-columns:46px minmax(0,1fr) minmax(0,42%);
  align-items:center}
.job-tekst{display:grid;gap:clamp(8px,.9vw,12px);align-content:center}
.job .s{margin-top:8px}
.job-beeld,.job-leeg{margin:0}
.job-beeld .hb-vlak{border-radius:calc(var(--r) - 8px)}
.job-leeg{display:grid;place-items:center;aspect-ratio:16/10;
  border:1px dashed var(--line);border-radius:calc(var(--r) - 8px);
  background:var(--paper2)}
.job-leeg span{font-size:var(--fs-micro);color:var(--mut);letter-spacing:.06em}
@media (max-width:860px){
  .job{grid-template-columns:40px minmax(0,1fr);align-items:start}
  .job-beeld,.job-leeg{grid-column:1/-1;margin-top:16px}
}

/* ── aanpak ─────────────────────────────────────────────────────────────── */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:8px;overflow:hidden;margin-top:clamp(24px,3.4vw,40px)}
.steps > div{background:var(--paper2);padding:clamp(20px,2.2vw,30px)}
.steps span{font-size:var(--fs-micro);color:var(--ac);letter-spacing:.02em}
.steps h3{margin:8px 0 8px;font-weight:400;font-size:var(--fs-lead);letter-spacing:-.02em}
.steps p{font-size:var(--fs-ui);color:var(--ink3);line-height:1.5}

/* ── waarom ─────────────────────────────────────────────────────────────── */
.why{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:8px;overflow:hidden;margin-top:clamp(24px,3.4vw,40px)}
.why > div{background:var(--paper);padding:clamp(24px,2.6vw,38px)}
.why h3{font-weight:400;font-size:var(--fs-h3);letter-spacing:-.02em;margin-bottom:8px}
.why p{font-size:var(--fs-basis);color:var(--ink3);line-height:1.55}

/* ── waarom bij ons: de cijferwand (variant J, gekozen 15-08) ────────────────
   Het getal eerst, de reden eronder. De linkerkolom draagt hier de kop en de
   knop en blijft plakken; daarom mag hij breder dan de standaard 1.5fr.    */
.rdn-sec .cols{grid-template-columns:minmax(240px,2.4fr) 5fr}
.rdn-sec .lbl .h2{margin-top:16px;color:var(--ink)}
.rdn-lead{margin-top:16px;font-size:var(--fs-basis);color:var(--ink3);
  line-height:1.55;max-width:30ch}
.rdn-sec .btns{margin-top:24px}
.rdn{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:8px;overflow:hidden}
.rdn-c{background:var(--paper);padding:clamp(24px,2.6vw,40px)}
/* Vaste hoogte met de cijfers onderaan uitgelijnd: "8,3 → 3,3" staat op een
   kleiner korps dan "4" en zou zonder deze box 22 px uit de rij zakken.    */
.rdn-n{display:flex;align-items:flex-end;height:clamp(54px,6.4vw,96px);
  font-weight:300;letter-spacing:-.045em;line-height:.9;
  font-size:clamp(54px,6.4vw,96px);color:var(--ink);
  font-variant-numeric:lining-nums tabular-nums}
.rdn-n.lang{font-size:clamp(30px,3.2vw,48px);letter-spacing:-.035em;line-height:1.1}
.rdn-b{display:block;margin-top:8px;font-size:var(--fs-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--ac)}
/* in het donker is #b84226 maar 3,63:1 — de site zet .ac daarom op --ac-lt */
.rdn-c h3{margin:24px 0 8px;font-weight:400;font-size:var(--fs-h3);
  letter-spacing:-.02em;padding-top:20px;position:relative}
/* De lijn liep vol via `width`, en dat is layout. Een schaal langs de x-as
   doet de compositor en ziet er identiek uit. */
.rdn-c h3::before{content:"";position:absolute;top:0;left:0;height:1px;width:100%;
  background:var(--line);transform:scaleX(var(--groei,0));transform-origin:left center;
  transition:transform .7s cubic-bezier(.2,.7,.3,1)}
.rdn-c.in h3::before{--groei:1}
.rdn-c p{font-size:var(--fs-basis);color:var(--ink3);line-height:1.55}
@media(prefers-reduced-motion:reduce){.rdn-c h3::before{--groei:1;transition:none}}

/* ── zo werkt het: tijdlijn (variant F, gekozen 15-08) ───────────────────────
   ⚠️ Deze band WAS zwart. Sinds 16-08 is de site wit, dus alle wit-transparante
   waarden zijn donker-transparant geworden. De omgekeerde inkt-tokens die hier
   stonden (--tl-tekst / --tl-vlak / de override op --ink) zijn daarmee overbodig:
   er draait niets meer om, en daarmee vervalt ook de token-val die ons vier keer
   een onzichtbaar label heeft opgeleverd.

   ⚠️ En: geen enkele animatie hier raakt nog de layout. `grid-template-rows`
   (uitklap) en `width` (accentbalk) worden per frame opnieuw doorgerekend én
   duwden alles eronder omlaag — dat is wat er stroef aan voelde. De uitleg
   staat nu gewoon open, precies zoals hij op een aanraakscherm altijd al deed. */
.tlband{position:relative;overflow:hidden}
.tlband > .wrap{--kaart:var(--paper2);position:relative;z-index:1}
.tlband::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(34% 30% at 10% 6%,color-mix(in srgb,var(--ac) 7%,transparent),transparent 70%),
    radial-gradient(30% 26% at 90% 46%,color-mix(in srgb,var(--ac) 5%,transparent),transparent 72%)}
.tl{list-style:none;margin:0;padding:0;position:relative}
.tl::before{content:"";position:absolute;left:23px;top:0;bottom:0;width:2px;
  background:linear-gradient(to bottom,transparent,var(--ac) 8%,var(--ac) 92%,transparent);
  opacity:.3}
.tl-r{position:relative;padding-left:76px;margin-bottom:24px}
.tl-knoop{position:absolute;left:0;top:14px;width:48px;height:48px;border-radius:999px;
  display:grid;place-items:center;background:var(--ac);color:#fff;z-index:2;
  border:4px solid var(--paper);transform:scale(.82);opacity:0;
  transition:transform .3s cubic-bezier(.2,.7,.3,1),opacity .26s ease}
.tl-knoop svg{width:20px;height:20px}
.tl-k{position:relative;overflow:hidden;border-radius:22px;background:var(--kaart);
  border:1px solid var(--line);
  transition:border-color .3s ease}
.tl-k:hover,.tl-k:focus-visible{border-color:color-mix(in srgb,var(--ac) 45%,transparent);
  outline:none}
/* Zonder foto is een band van 150 px vooral leegte. Nu een kopstrip die de
   chip draagt; wordt er ooit eigen beeld toegevoegd, dan mag hij weer hoger. */
.tl-b{display:block;position:relative;height:clamp(62px,7vw,86px);overflow:hidden}
/* Geen foto: hetzelfde technische vlak als de dienstkaarten. De oude
   dienstfoto's hoorden bij de zeven diensten en zijn afgekeurd. */
.tl-vlak{position:absolute;inset:0;background:
  radial-gradient(38% 46% at var(--gx,30%) var(--gy,34%),
    color-mix(in srgb,var(--ac) 14%,transparent),transparent 70%),
  linear-gradient(180deg,rgba(15,16,18,.03),rgba(15,16,18,0)),
  repeating-linear-gradient(0deg,rgba(15,16,18,.045) 0 1px,transparent 1px 26px),
  repeating-linear-gradient(90deg,rgba(15,16,18,.045) 0 1px,transparent 1px 26px)}
.tl-b::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,var(--kaart),transparent 62%)}
.tl-chip{position:absolute;top:14px;right:14px;z-index:1;font-size:var(--fs-micro);
  letter-spacing:.1em;text-transform:uppercase;padding:6px 12px;border-radius:999px;
  background:var(--ac);color:#fff}
.tl-body{display:block;padding:18px 22px 22px}
.tl-nr{display:block;font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ac);font-variant-numeric:tabular-nums}
.tl-t{margin:8px 0 0;font-size:clamp(21px,2vw,26px);font-weight:350;letter-spacing:-.02em;
  color:var(--ink)}
/* ⚠️ Stond op `grid-template-rows:0fr → 1fr` bij hover. Dat is een
   layout-animatie: de browser rekent per frame de hele kaart én alles eronder
   opnieuw door, en de kaarten daaronder schuiven weg onder je muis vandaan.
   De uitleg is nu gewoon zichtbaar — hetzelfde als op een aanraakscherm. */
.tl-uit{display:block}
.tl-in p{margin:8px 0 0;font-size:var(--fs-ui);line-height:1.55;color:var(--ink3)}
/* ⚠️ Ook `width` is layout. Een schaal langs de x-as doet de compositor. */
.tl-balk{position:absolute;left:0;bottom:0;height:3px;width:100%;background:var(--ac);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .38s cubic-bezier(.2,.7,.3,1)}
.tl-k:hover .tl-balk,.tl-k:focus-visible .tl-balk{transform:scaleX(1)}
/* De kaarten komen vanaf hun eigen kant in beeld; `in` zet site.js al.
   Ritme gelijk aan de rest van de site: klein en kort (12 px / .42 s), niet
   38 px in .65 s — dat las als traag, niet als rustig. */
.tl-r.rv{opacity:1;transform:none}
.tl-r .tl-k{opacity:0;transform:translate3d(-14px,10px,0)}
.tl-r.rechts .tl-k{transform:translate3d(14px,10px,0)}
.tl-r.in .tl-k{opacity:1;transform:none;
  transition:opacity .38s ease,transform .42s cubic-bezier(.2,.7,.3,1),border-color .3s ease}
.tl-r.in .tl-knoop{transform:scale(1);opacity:1;transition-delay:.06s}
@media(min-width:900px){
  .tl::before{left:50%;transform:translateX(-50%)}
  .tl-r{width:50%;padding-left:0;margin-bottom:40px}
  .tl-r.links{padding-right:56px}
  .tl-r.rechts{margin-left:50%;padding-left:56px}
  .tl-knoop{left:auto;right:-24px}
  .tl-r.rechts .tl-knoop{left:-24px;right:auto}
  .tl-r.links .tl-chip{right:auto;left:14px}
  .tl-r.links .tl-body{text-align:right}
  .tl-r.links .tl-balk{transform-origin:right center}
}
@media(prefers-reduced-motion:reduce){
  .tl-r .tl-k,.tl-r.rechts .tl-k{opacity:1;transform:none}
  .tl-knoop{opacity:1;transform:none}
  .tl-k,.tl-balk{transition:none}
}

/* ── het bewijs (variant Q, gekozen 15-08) ────────────────────────────────── */
.bw-lead{margin-top:16px;font-size:var(--fs-lead);color:var(--ink3);line-height:1.5;
  max-width:52ch}
.bw-r{display:grid;grid-template-columns:52px minmax(0,1fr) auto;
  gap:clamp(14px,2.4vw,36px);align-items:start;padding:clamp(18px,2vw,28px) 0;
  border-top:1px solid var(--line)}
.bw-r:last-child{border-bottom:1px solid var(--line)}
.bw-n{font-size:var(--fs-ui);color:var(--mut);padding-top:5px}
.bw-r h3{font-weight:400;font-size:var(--fs-lead);letter-spacing:-.018em;line-height:1.3;
  margin-bottom:8px}
.bw-r p{font-size:var(--fs-ui);color:var(--ink3);line-height:1.5;max-width:60ch}
.bw-s{font-size:var(--fs-micro);color:var(--mut);white-space:nowrap;padding-top:7px}
.bw-s::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--ac);margin-right:8px;vertical-align:1px}
.bw-t{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(16px,2vw,30px);
  margin-top:clamp(24px,3.4vw,40px)}
.bw-t b{display:block;font-weight:300;letter-spacing:-.045em;line-height:.9;
  font-size:clamp(34px,3.6vw,56px);color:var(--ink);
  font-variant-numeric:lining-nums tabular-nums}
.bw-t span{display:block;margin-top:8px;font-size:var(--fs-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--mut)}

/* ── de vier opnames onder het bewijs ───────────────────────────────────────
   Vijf regels tekst laten niet zien wát er gebouwd is. Deze strip wel, en elke
   opname linkt door naar de volledige projectpagina. */
.bw-strip{display:grid;grid-template-columns:repeat(4,1fr);
  gap:clamp(10px,1.2vw,18px);margin-top:clamp(24px,3.2vw,40px)}
.bws-i{display:block;text-decoration:none;color:inherit}
.bws-i .hb-vlak{border-radius:calc(var(--r) - 8px)}
.bws-i img{display:block;width:100%;height:auto;
  transition:transform .8s cubic-bezier(.2,.7,.2,1)}
.bws-i:hover img{transform:scale(1.04)}
.bws-t{display:block;margin-top:8px;font-size:var(--fs-micro);
  color:var(--mut);letter-spacing:.08em}
.bws-i:hover .bws-t{color:var(--ac)}
@media (max-width:860px){ .bw-strip{grid-template-columns:repeat(2,1fr)} }
.bw-q{margin:clamp(24px,3vw,40px) 0 0;padding:clamp(20px,2.2vw,28px);
  border-left:2px solid var(--ac)}
.bw-q blockquote{margin:0;font-size:var(--fs-lead);letter-spacing:-.015em;line-height:1.45}
.bw-q figcaption{margin-top:8px;font-size:var(--fs-ui);color:var(--mut)}
@media(max-width:820px){
  .bw-r{grid-template-columns:38px 1fr;gap:8px 14px}
  .bw-s{grid-column:2;padding-top:0}
  .bw-t{grid-template-columns:repeat(2,1fr)}
}

/* ── contact ────────────────────────────────────────────────────────────── */
.form{display:grid;gap:14px;max-width:560px;margin-top:clamp(24px,3vw,40px)}
.f2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.form label{display:block;font-size:var(--fs-micro);color:var(--ink3);margin-bottom:8px;letter-spacing:-.01em}
.form input,.form textarea{width:100%;background:var(--paper);border:1px solid var(--line);
  border-radius:8px;padding:13px 15px;color:var(--ink);font:inherit;font-size:var(--fs-ui);min-height:50px;
  transition:border-color .2s ease,box-shadow .2s ease}
.form textarea{min-height:120px;resize:vertical}
.form input:focus,.form textarea:focus{outline:0;border-color:var(--ac);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--ac) 22%,transparent)}
.form button{justify-self:start;border:0;cursor:pointer;font:inherit}
.ok{display:none;padding:16px 18px;border:1px solid var(--ac);border-radius:8px;
  color:var(--ac);font-size:var(--fs-ui)}
.ok.on{display:block}
.cways{display:flex;flex-wrap:wrap;gap:10px;margin-top:24px}
.cway{display:inline-flex;align-items:center;gap:9px;padding:11px 17px;border-radius:999px;
  border:1px solid var(--line);font-size:var(--fs-ui);letter-spacing:-.012em;
  transition:border-color .22s ease,color .22s ease}
.cway:hover{border-color:var(--ac);color:var(--ac)}

footer{background:var(--paper);color:var(--mut);padding:34px 0 44px;
  font-size:var(--fs-ui);border-top:1px solid var(--line)}
.fr{display:flex;flex-wrap:wrap;gap:10px 26px;justify-content:space-between;align-items:center;
  border-top:1px solid var(--line);padding-top:26px}
.todo{color:var(--ac)}

/* ── reveal (alleen transform/opacity) ──────────────────────────────────── */
/* 0,9 s over 18 px leest als traagheid, niet als rust. Vuistregel: hoe
   kleiner de verplaatsing, hoe korter de duur. */
/* Nagemeten op augen.pro, 16-08-2026: hun blokken komen op met ALLEEN opacity.
   36 elementen onder de vouw stonden op opacity 0 met `transform: none` — er
   beweegt niets, het verschijnt. Dat is rustiger dan onze 12 px omhoog, en het
   is bovendien goedkoper: geen enkele eigenschap die layout aanraakt. */
.rv{opacity:0;transition:opacity .5s cubic-bezier(.22,1,.36,1)}
.rv.in{opacity:1}

/* Woord voor woord opkomen — augen.pro, gemeten en niet gegokt.
   Zij splitsen een kop in losse woorden en animeren per woord `filter: blur()`
   samen met `opacity`, gestaffeld. Geen masker en geen verschuiving: de
   woorden komen SCHERP in beeld in plaats van omhoog te schuiven.

   ⚠️ blur staat op onze jank-lijst en dat blijft terecht. Daarom drie remmen:
   het staat alleen op de H1 en de eerste kop eronder, het duurt een halve
   seconde, en site.js zet de laag daarna helemaal uit (`.sp.klaar`) zodat er
   geen permanent gepromoveerde filterlaag blijft staan tijdens het scrollen. */
.spw{display:inline-block;vertical-align:bottom}
.spi{display:inline-block;opacity:0;filter:blur(7px);
  transition:opacity .5s cubic-bezier(.22,1,.36,1),
             filter .5s cubic-bezier(.22,1,.36,1)}
.sp.in .spi{opacity:1;filter:blur(0)}
.sp.klaar .spi{filter:none;transition:none}

@media(prefers-reduced-motion:reduce){.rv{opacity:1;transition:none}
  .spi{opacity:1;filter:none;transition:none}
  *{animation:none!important}}

/* ══ STIJL ═══════════════════════════════════════════════════════════════════
   De iPhone-skin is er op 14-08-2026 uit gehaald (besluit Lenny: de zware,
   samengeknepen iOS-koppen — gewicht 600 — zijn lelijk). De site staat vast op
   Redactie: de lichte snit met haarlijnen. Verder verandert er niets, want de
   iPhone-regels golden alleen als de skin aan stond.

   Wat WEL uit die richting komt en bewust in de basis staat, niet in een
   schakelaar: de kaarten (afgeronde panelen met zachte schaduw). Zie het blok
   KAARTEN verderop. Terughalen kan uit git of uit _backup-stijl-0814/.        */

/* ══ DIENSTEN ALS TABBLADEN ══════════════════════════════════════════════════
   Naar het aangeleverde component: links de titels met een voortgangsbalk die
   volloopt, rechts het paneel dat verticaal inschuift. Verschil met het
   origineel: dat toont 3 diensten met een FOTO per stuk. Wij hebben er zeven
   en geen beeld dat we mogen tonen, dus het rechterpaneel draagt de inhoud
   zelf. Komt er later beeld, dan schuift dat er gewoon boven in.

   Op smalle schermen valt het uit elkaar: een rail van zeven plus een paneel
   past niet op 390 px. Daar staat alles gewoon onder elkaar, zoals eerst.    */

.tabs{display:grid;grid-template-columns:minmax(230px,1fr) 2.1fr;
  gap:clamp(24px,3.4vw,64px);align-items:start}
.tabrail{display:flex;flex-direction:column;position:sticky;top:96px}
/* De panelen zijn 403 tot 609 px hoog; zonder ondergrens verspringt alles
   eronder tot 206 px zodra je van tabblad wisselt. */
@media(min-width:901px){.tabpanelen{min-height:620px}}
.tab{position:relative;display:grid;grid-template-columns:14px 26px 1fr;
  align-items:start;gap:0 12px;padding:15px 0;background:0;border:0;cursor:pointer;
  font:inherit;text-align:left;color:var(--mut);
  border-top:1px solid var(--line);transition:color .4s ease}
.tab:first-child{border-top:0}
.tab[aria-selected="true"]{color:var(--ink)}
.tab:hover{color:var(--ink)}
.tabbalk{grid-row:1/3;width:2px;height:100%;background:var(--line);border-radius:8px;
  overflow:hidden}
.tabbalk i{display:block;width:100%;height:100%;background:var(--ac);border-radius:8px;
  transform:scaleY(0);transform-origin:top center}
/* Was een klok die 6 s volliep tot het volgende tabblad. Het automatisch
   doorwisselen is eruit (het kostte de lezer zijn regel en verschoof de
   pagina tot 206 px), dus dit is nu puur een aanwijzer bij het gekozen
   tabblad. */
.tab[aria-selected="true"] .tabbalk i{transform:scaleY(1);transition:transform .22s ease-out}
.tabn{font-size:var(--fs-micro);font-variant-numeric:tabular-nums;opacity:.5;padding-top:5px}
.tabt{font-size:var(--fs-lead);letter-spacing:-.02em;line-height:1.25}

.tabpanelen{position:relative}
.tabpanelen .svc{margin-bottom:0;grid-template-columns:1fr}
.tabpanelen .svc .svc-n{display:none}
.tabpanelen .svc[hidden]{display:none}
.tabpanelen .svc.komt{animation:tabin .5s cubic-bezier(.16,.84,.32,1)}
@keyframes tabin{from{opacity:0;transform:translateY(var(--vanaf,18px))}
  to{opacity:1;transform:none}}

@media(max-width:900px){
  .tabs{grid-template-columns:1fr;gap:0}
  .tabrail{display:none}
  .tabpanelen .svc{margin-bottom:8px;animation:none!important}
  .tabpanelen .svc[hidden]{display:grid!important}
  .tabpanelen .svc .svc-n{display:block}
}
@media(prefers-reduced-motion:reduce){
  .tab[aria-selected="true"] .tabbalk i{transition:none}
  .tabpanelen .svc.komt{animation:none}
}

/* ══ VOETTEKST ═══════════════════════════════════════════════════════════════
   Naar het aangeleverde ontwerp: gecentreerd, merkteken in een cirkel, nav,
   ronde kanaalknoppen, invoerveld met knop. Twee dingen bewust anders:

   1. Alleen de kanalen die we ÉCHT hebben (LinkedIn en mail). Vier iconen
      waarvan er drie nergens heen gaan is een lege belofte.
   2. Het veld heet geen "Subscribe" en doet ook niet alsof. Er is geen
      nieuwsbrief; het opent een bericht met het adres er al in. Een veld dat
      "u staat op de lijst" zegt en niets verstuurt was letterlijk een
      auditbevinding bij DCSS.                                                */
footer{--voetmut:var(--mut)}
footer .wrap{display:flex;flex-direction:column;align-items:center;text-align:center;
  gap:clamp(22px,2.6vw,34px)}
.fmerk{width:88px;height:88px;border-radius:999px;background:var(--paper2);
  display:grid;place-items:center;font-size:var(--fs-lead);letter-spacing:-.03em;color:var(--ink)}
.fnav{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 30px}
.fnav a{font-size:var(--fs-basis);letter-spacing:-.015em;color:var(--ink);padding:4px 0;
  border-bottom:1px solid transparent;transition:border-color .22s ease,color .22s ease}
.fnav a:hover{border-bottom-color:var(--ac);color:var(--ink)}
.fsoc{display:flex;gap:12px}
.fsoc a{width:46px;height:46px;border-radius:999px;border:1px solid var(--line);
  display:grid;place-items:center;color:var(--ink3);
  transition:border-color .22s ease,color .22s ease,transform .22s ease}
.fsoc a:hover{border-color:var(--ac);color:var(--ac);transform:translateY(-2px)}
.fsoc svg{width:19px;height:19px;fill:currentColor}
.fsoc svg[fill="none"]{fill:none;stroke:currentColor}
footer .fr{justify-content:center;gap:10px 26px;width:100%}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ══ CTA-KNOP MET GLOED ══════════════════════════════════════════════════════
   Naar de aangeleverde knop, maar in het gekozen accent in plaats van paars —
   die kleur staat nog open, en AI-paars is een anti-patroon dat `ui-ux-pro-max`
   zelf markeert. De diepte komt van gestapelde verlopen en inset-schaduwen;
   de gloed is een ::after waarvan alleen de OPACITY beweegt. Geen `filter`,
   geen verloop dat per frame hertekend wordt.                                */
.btn-p{position:relative;isolation:isolate;
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--ac) 78%,#fff) 0%,
    var(--ac) 46%,
    color-mix(in srgb,var(--ac) 84%,#000) 100%);
  color:#fff;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.42),
    inset 0 -1px 0 rgba(0,0,0,.22),
    0 1px 2px rgba(0,0,0,.18),
    0 10px 22px -12px color-mix(in srgb,var(--ac) 70%,transparent);
  /* alleen transform beweegt; de gloed zit in ::after en doet opacity */
  transition:transform .22s cubic-bezier(.2,.8,.3,1)}
.btn-p::after{content:"";position:absolute;inset:-14px;z-index:-1;border-radius:inherit;
  background:radial-gradient(60% 60% at 50% 60%,
    color-mix(in srgb,var(--ac) 55%,transparent) 0%,transparent 72%);
  opacity:.5;transition:opacity .28s ease}
.btn-p:hover{background:linear-gradient(180deg,
    color-mix(in srgb,var(--ac) 88%,#fff) 0%,
    color-mix(in srgb,var(--ac) 96%,#fff) 46%,
    var(--ac) 100%);
  transform:translateY(-2px)}
.btn-p:hover::after{opacity:1}
.btn-p:active{transform:translateY(0)}
@media(prefers-reduced-motion:reduce){.btn-p{transition:none}}

/* ── uitklapmenu onder Diensten ──────────────────────────────────────────────
   Drie items in de balk; alles wat we doen hangt onder Diensten. Klikken op een
   regel springt naar de sectie én zet dat tabblad open, dus je landt op de
   dienst die je koos in plaats van bovenaan de lijst.

   Geen `backdrop-filter` (jank), en het paneel is dekkend — doorschijnend
   zonder vervaging laat de tekst eronder als spookletters doorschemeren.     */
.heeftmenu{position:relative;display:flex}
.menuknop i{display:inline-block;width:7px;height:7px;margin-left:7px;
  border-right:1.4px solid currentColor;border-bottom:1.4px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .26s ease}
.heeftmenu.open .menuknop i{transform:rotate(-135deg) translate(-3px,-3px)}
.submenu{position:absolute;top:calc(100% + 12px);left:50%;transform:translateX(-50%) translateY(-6px);
  min-width:290px;background:var(--paper);border:1px solid var(--line);border-radius:22px;
  padding:8px;display:flex;flex-direction:column;gap:1px;
  box-shadow:0 18px 44px -18px rgba(0,0,0,.4);
  opacity:0;visibility:hidden;transition:opacity .2s ease,transform .24s cubic-bezier(.16,.84,.32,1),visibility .24s}
.submenu[hidden]{display:flex}
.heeftmenu.open .submenu{opacity:1;visibility:visible;transform:translateX(-50%)}
.submenu a{display:flex;align-items:baseline;gap:9px;padding:9px 13px;border-radius:8px;
  font-size:var(--fs-ui);letter-spacing:-.015em;color:var(--ink);white-space:nowrap;
  transition:background .18s ease}
.submenu a b{font-weight:400;font-size:var(--fs-micro);color:var(--mut);font-variant-numeric:tabular-nums}
.submenu a:hover,.submenu a:focus-visible{background:var(--paper3)}
.submenu .sublos{margin-top:8px;border-top:1px solid var(--line);border-radius:0 0 8px 8px;
  padding-top:13px}
/* pijltje ZIT in de span, anders schaalt het woord eroverheen */
.pill.dock .menuknop span{display:inline-flex;align-items:center}

@media(max-width:900px){
  .heeftmenu{flex-direction:column;width:100%}
  .submenu{position:static;transform:none;min-width:0;opacity:1;visibility:visible;
    box-shadow:none;border:0;border-radius:0;padding:2px 0 8px 14px;background:0}
  .submenu[hidden]{display:none}
  .heeftmenu.open .submenu{transform:none}
  .submenu a{white-space:normal;font-size:var(--fs-ui)}
}

/* ══ CHAT ════════════════════════════════════════════════════════════════════
   Naar het aangeleverde ontwerp: bubbels rechts voor de bezoeker, links voor
   ons, met een typ-animatie ertussen. Bewust ZONDER model erachter — een bot
   die over onze prijzen praat terwijl die nog niet vaststaan is een risico,
   geen functie. Elke route eindigt in een gesprek.                           */
.chatknop{position:fixed;right:16px;bottom:16px;z-index:75;width:54px;height:54px;
  border-radius:999px;border:0;cursor:pointer;display:grid;place-items:center;
  background:var(--ink);color:var(--paper);
  box-shadow:0 10px 26px -10px rgba(0,0,0,.5);
  transition:transform .22s cubic-bezier(.2,.8,.3,1),background .22s ease}
.chatknop:hover{transform:translateY(-2px)}
.chatknop svg{width:22px;height:22px}
.chatstip{position:absolute;top:11px;right:11px;width:8px;height:8px;border-radius:999px;
  background:var(--ac);box-shadow:0 0 0 2px var(--paper)}
body.chat-open .chatknop{transform:scale(.9);opacity:.6}

.chat{position:fixed;right:16px;bottom:80px;z-index:76;width:min(380px,calc(100vw - 32px));
  max-height:min(560px,calc(100vh - 120px));display:flex;flex-direction:column;
  background:var(--paper);color:var(--ink);border:1px solid var(--line);
  border-radius:22px;overflow:hidden;box-shadow:0 24px 60px -20px rgba(0,0,0,.45)}
.chat[hidden]{display:none}
.chat.komt{animation:chatin .34s cubic-bezier(.16,.84,.32,1)}
@keyframes chatin{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.chatkop{display:flex;align-items:flex-start;gap:12px;padding:16px 16px 12px;
  border-bottom:1px solid var(--line)}
.chatkop b{display:block;font-weight:400;font-size:var(--fs-basis);letter-spacing:-.015em}
.chatkop span{display:block;font-size:var(--fs-micro);color:var(--mut);margin-top:8px;line-height:1.4}
.chatdicht{margin-left:auto;background:0;border:0;cursor:pointer;font-size:var(--fs-lead);line-height:1;
  color:var(--mut);padding:0 2px}
.chatdicht:hover{color:var(--ink)}
.chatlog{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px}
.bel{max-width:84%;padding:11px 14px;border-radius:22px;font-size:var(--fs-ui);line-height:1.45;
  animation:belin .3s cubic-bezier(.16,.84,.32,1)}
@keyframes belin{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.bel.ik{align-self:flex-end;background:var(--ink);color:var(--paper);border-bottom-right-radius:6px}
.bel.wij{align-self:flex-start;background:var(--paper3);border-bottom-left-radius:6px}
.bel a{color:var(--ac);text-decoration:underline;text-underline-offset:3px}
.tikt{align-self:flex-start;display:flex;gap:4px;padding:13px 14px;background:var(--paper3);
  border-radius:22px;border-bottom-left-radius:6px}
.tikt i{width:6px;height:6px;border-radius:999px;background:var(--mut);
  animation:tik 1.2s infinite ease-in-out}
.tikt i:nth-child(2){animation-delay:.16s}
.tikt i:nth-child(3){animation-delay:.32s}
@keyframes tik{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
.chatvragen{display:flex;flex-wrap:wrap;gap:7px;padding:12px 16px 16px;
  border-top:1px solid var(--line)}
.chatvragen button{background:0;border:1px solid var(--line);border-radius:999px;
  padding:8px 13px;font:inherit;font-size:var(--fs-ui);cursor:pointer;color:var(--ink);
  transition:border-color .2s ease,background .2s ease}
.chatvragen button:hover{border-color:var(--ac);background:color-mix(in srgb,var(--ac) 8%,transparent)}
@media(max-width:900px){
  .chat{right:8px;left:8px;width:auto;bottom:76px}
}
@media(prefers-reduced-motion:reduce){
  .chat.komt,.bel{animation:none}.tikt i{animation:none;opacity:.55}}

/* ══ KAARTEN ═════════════════════════════════════════════════════════════════
   Uit de iPhone-richting gehaald en in de basis gezet, want dit is het deel dat
   Lenny wilde. Het redactionele origineel scheidt met HAARLIJNEN op een vlak
   vel; hier scheiden losse kaarten met een zachte schaduw. Werkt in beide
   thema's omdat alles op tokens draait.                                       */
:root{--r:22px;
  --schaduw:0 1px 1px rgba(0,0,0,.03),0 10px 26px -14px rgba(0,0,0,.22)}

.flow,.why,.steps{border:0;background:transparent;border-radius:0;overflow:visible;gap:12px}
.flow div,.why > div,.steps > div{border-radius:var(--r);box-shadow:var(--schaduw)}
.flow div,.b-paper2 .flow div,.why > div{background:var(--paper)}
/* ⚠ De stapkaarten staan BINNEN de donkere sectie. Papier maakt ze licht en dan
   valt de witte tekst erin weg — het moet een opgetild DONKER vlak zijn. */
.steps > div{background:var(--paper2);box-shadow:none;border-radius:var(--r)}
.heroshot img{border-radius:var(--r)}
.ok{border-radius:22px}
.note{border-left:0;padding:14px 16px;border-radius:22px;
  background:color-mix(in srgb,var(--ac) 7%,var(--paper))}
.b-ink .note{background:var(--paper2)}

.svc,.svc:last-of-type{border:0;background:var(--paper);border-radius:var(--r);
  box-shadow:var(--schaduw);padding:clamp(24px,2.8vw,40px);margin-bottom:8px}
.job,.job:last-of-type{border:0;background:var(--paper);border-radius:var(--r);
  box-shadow:var(--schaduw);padding:clamp(18px,2.2vw,28px);margin-bottom:8px}
.b-ink .job{background:var(--paper3);box-shadow:none}
/* de dienstensectie staat op papier2, dus de kaarten moeten daar wit oplichten */
.b-paper .svc{background:var(--paper2)}

/* ── hero-beeld ─────────────────────────────────────────────────────────── */
.heroshot{margin:clamp(40px,6vw,64px) 0 0;padding:0}
.heroshot img{display:block;width:100%;height:auto;border-radius:8px}

/* Lenis — vereiste opmaak, letterlijk zoals de bibliotheek 'm nodig heeft */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto!important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}
.lenis.lenis-smooth iframe{pointer-events:none}

/* ── labbalk ────────────────────────────────────────────────────────────── */
#lab{position:fixed;right:14px;bottom:14px;z-index:80;background:rgba(15,16,18,.95);
  color:#fff;border-radius:999px;padding:8px 10px;display:flex;align-items:center;gap:9px;
  font-size:var(--fs-micro);letter-spacing:-.01em;box-shadow:0 6px 24px rgba(0,0,0,.22)}
#lab b{font-weight:400;color:#8a8c92;padding:0 3px}
#lab .sw{width:20px;height:20px;border-radius:999px;border:1.5px solid transparent;cursor:pointer;
  padding:0;transition:transform .18s ease}
#lab .sw:hover{transform:scale(1.14)}
#lab .sw[aria-pressed="true"]{border-color:#fff}
#lab .ft,#lab .sc,#lab .st{background:transparent;border:1px solid rgba(255,255,255,.28);color:#fff;
  border-radius:999px;padding:5px 11px;cursor:pointer;font:inherit;font-size:var(--fs-micro)}
#lab .ft[aria-pressed="true"],#lab .sc[aria-pressed="true"],
#lab .st[aria-pressed="true"]{background:#fff;color:#0f1012}
#lab .cn{background:transparent;border:1px solid rgba(255,255,255,.28);color:#fff;border-radius:999px;padding:5px 11px;cursor:pointer;font:inherit;font-size:var(--fs-micro)}
#lab .cn[aria-current="true"]{background:var(--ac);color:#fff;border-color:transparent}
#lab .x{background:transparent;border:0;color:#8a8c92;cursor:pointer;font:inherit;padding:0 4px}

/* ── mobiel ─────────────────────────────────────────────────────────────── */
@media(max-width:900px){
  :root{--gut:22px}
  body{font-size:var(--fs-ui)}
  .cols{grid-template-columns:1fr;gap:16px}
  .flow{grid-template-columns:repeat(2,1fr)}
  .nums{grid-template-columns:1fr;gap:30px}
  .job{grid-template-columns:38px 1fr;gap:10px 14px}
  .job .d{grid-column:2}
  .job .s{grid-column:2;white-space:normal}
  .steps,.why{grid-template-columns:1fr}
  /* .rdn-sec .cols is specifieker dan .cols hierboven, dus expliciet terug */
  .rdn-sec .cols{grid-template-columns:1fr}
  .rdn{grid-template-columns:1fr}
  .rdn-n{font-size:clamp(46px,13vw,64px);height:clamp(46px,13vw,64px)}
  .f2{grid-template-columns:1fr}
  .hero .display{max-width:none}
  header{inset:10px 0 auto 0}
  .burger{display:block}
  .navbar{width:100%;padding:0 14px;justify-content:space-between;gap:10px}
  .pill{position:absolute;top:56px;left:14px;right:14px;flex-direction:column;
    align-items:stretch;padding:8px;border-radius:22px;background:#fff;
    box-shadow:0 12px 34px rgba(0,0,0,.14);visibility:hidden;opacity:0;
    transform:translateY(-6px);transition:opacity .22s ease,transform .22s ease,visibility .22s}
  .nav-open .pill{visibility:visible;opacity:1;transform:none}
  .pill a{padding:13px 16px;font-size:var(--fs-ui);text-align:left}
  #lab{left:14px;right:14px;justify-content:center;flex-wrap:wrap;border-radius:8px}
}
@media(max-width:420px){.flow{grid-template-columns:1fr}}
/* De labbalk moet opzij voor de chatknop. Bewust HELEMAAL ONDERAAN: het
   labbalk-blok staat verderop in dit bestand, dus een regel hierboven verliest
   op volgorde ondanks dezelfde specificiteit. */
#lab{right:84px;bottom:18px}
@media(max-width:900px){#lab{left:14px;right:14px;bottom:84px}}

/* Nu het meerdere pagina's zijn: een korte overvloeier tussen twee pagina's,
   zodat het één ding blijft in plaats van vijf losse documenten. Puur CSS,
   en browsers die het niet kennen slaan het over. */
@view-transition{navigation:auto}
::view-transition-old(root),::view-transition-new(root){animation-duration:.22s}
@media(prefers-reduced-motion:reduce){
  ::view-transition-old(root),::view-transition-new(root){animation:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   TOEVOEGING 12-08 (avond) — meerdere pagina's, dienstenkaarten, beweging
   ══════════════════════════════════════════════════════════════════════════ */

/* ── voortgangsbalk ───────────────────────────────────────────────────────
   Alleen `transform` beweegt, dus geen herberekening van de layout.        */
.pbar{position:fixed;top:0;left:0;right:0;height:2px;z-index:70;pointer-events:none}
.pbar i{display:block;height:100%;background:var(--ac);
  transform:scaleX(0);transform-origin:0 50%;will-change:transform}

/* ── paginakop op de binnenpagina's (lager dan de hero op de startpagina) ── */
.kop{padding-top:clamp(122px,13vw,182px);padding-bottom:clamp(28px,3.6vw,52px);
  background:var(--paper2);border-bottom:1px solid var(--line)}
.kop .display{max-width:20ch}
.kop .lead{margin-top:clamp(16px,2.2vw,24px)}

/* het sectielabel blijft staan zolang je door de sectie scrollt (augen-manier) */
@media(min-width:901px){ .cols > .lbl{position:sticky;top:104px;align-self:start} }

/* ── merk met slogan ──────────────────────────────────────────────────────── */
.lockup{display:block}
.lockup .lm{display:block;font-size:clamp(26px,2.5vw,34px);letter-spacing:-.045em;
  line-height:1;color:var(--ink)}
.lockup .ls{display:block;margin-top:8px;font-size:var(--fs-ui);line-height:1.35;
  letter-spacing:-.012em;color:var(--mut);max-width:20ch}
/* Was #9a9ca2 toen de voettekst zwart was; op wit is dat 2,74:1. */
.fslogan{margin-top:16px;font-size:var(--fs-ui);color:var(--mut);letter-spacing:-.012em}

/* actieve pagina in het menu */
.pill a{position:relative}
/* :not(.cta) — anders krijgt de donkere knop donkere tekst (1,00:1). */
.pill a[aria-current="page"]:not(.cta){color:var(--ink)}
.pill a[aria-current="page"]:not(.cta)::after{content:"";position:absolute;
  left:17px;right:17px;bottom:5px;height:1px;background:currentColor;opacity:.32}

/* ── dienstenkaarten ──────────────────────────────────────────────────────
   Een rij die doorloopt buiten het beeld: dat is zelf de uitnodiging om te
   schuiven. Snappen doet de browser, de pijlen zijn er voor wie ze zoekt.  */

/* de rij loopt tot buiten de marge door, zodat de laatste kaart afgesneden is */
/* De rij zelf. Stond tot 23-08 op .carr; los getrokken zodat de gepinde etappe
   hem horizontaal kan verschuiven zonder de scrollcontainer te kapen. */

/* ── de vijf diensten als raster ────────────────────────────────────────────
   Drie boven, twee onder. In de schuifrij die hier stond vielen kaart 04 en 05
   permanent half buiten beeld; je moest schuiven om te zien dat ze bestonden. */
.dienstraster{display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(12px,1.4vw,22px)}
.dienstraster .ck > a{aspect-ratio:auto}
/* de foto bovenin de kaart, tekst eronder */
.ck-foto{display:block;position:relative;aspect-ratio:16/10;overflow:hidden;
  background:var(--paper2);border-bottom:1px solid var(--line)}
.ck-foto img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .9s cubic-bezier(.2,.7,.2,1)}
.ck > a:hover .ck-foto img{transform:scale(1.045)}
.dienstraster .ck-onder{position:static;padding:clamp(14px,1.5vw,20px)}
.dienstraster .ck-boven{position:absolute;top:0;left:0;right:0;
  padding:clamp(12px,1.2vw,16px);z-index:2}
/* ⚠️ Geen verloop over de foto om het nummer leesbaar te maken: bij een lichte
   opname (het productraster, het offerteformulier) blijft wit-op-wit staan.
   Gemeten 23-08. Nummer en pictogram krijgen daarom hun eigen ondergrond, en
   die werkt ongeacht wat eronder ligt. */
.dienstraster .ck-waas{display:none}
.dienstraster .ck-icoon,.dienstraster .ck-tel{
  background:rgba(12,14,16,.82);color:#fff;border:0;
  -webkit-backdrop-filter:none;backdrop-filter:none}
.dienstraster .ck-tel{padding:5px 10px;border-radius:999px;letter-spacing:.06em}
.dienstraster .ck-icoon{border-radius:999px}
.dienstraster .ck-icoon svg{stroke:#fff}
.dienstraster .ck-pijl{bottom:clamp(14px,1.5vw,20px);right:clamp(14px,1.5vw,20px)}
@media (max-width:1080px){ .dienstraster{grid-template-columns:repeat(2,1fr)} }
@media (max-width:640px){ .dienstraster{grid-template-columns:1fr} }
.ck{scroll-snap-align:start}
.ck > a{position:relative;display:block;aspect-ratio:3/4;border-radius:22px;overflow:hidden;
  background:var(--paper2);color:var(--ink);border:1px solid var(--line);
  transition:transform .4s cubic-bezier(.2,.8,.3,1)}
.ck > a:hover{transform:translateY(-6px)}
.ck img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .9s cubic-bezier(.2,.7,.2,1)}
.ck > a:hover img{transform:scale(1.055)}

/* Nog geen foto? Dan een technisch vlak in plaats van een gekochte stockfoto:
   fijn raster, één zachte gloed in het accent en het dienstnummer als schim.
   ⚠️ Sinds 16-08 licht: het raster en de schim zijn donker-transparant in
   plaats van wit-transparant, anders staat er niets op een wit vlak. */
.ck-vlak{position:absolute;inset:0;background:
  radial-gradient(58% 46% at var(--gx,30%) var(--gy,22%),
    color-mix(in srgb,var(--ac) 16%,transparent) 0%,transparent 70%),
  repeating-linear-gradient(0deg,rgba(15,16,18,.05) 0 1px,transparent 1px 26px),
  repeating-linear-gradient(90deg,rgba(15,16,18,.05) 0 1px,transparent 1px 26px),
  linear-gradient(160deg,#ffffff 0%,#ececed 78%)}
.ck-schim{position:absolute;right:-4px;top:38%;font-size:clamp(120px,13vw,190px);
  line-height:.8;font-weight:300;letter-spacing:-.06em;color:rgba(15,16,18,.055)}
/* De waas hield witte tekst leesbaar boven een foto. Op een licht vlak is een
   heel lichte verloop naar wit genoeg om de tekst rustig te houden. */
.ck-waas{position:absolute;inset:0;background:linear-gradient(to top,
  rgba(255,255,255,.94) 0%,rgba(255,255,255,.72) 34%,rgba(255,255,255,.1) 72%,
  rgba(255,255,255,.3) 100%)}
.ck-boven{position:absolute;top:15px;left:15px;right:15px;display:flex;
  align-items:center;justify-content:space-between}
.ck-icoon{width:40px;height:40px;border-radius:999px;display:grid;place-items:center;
  border:1px solid rgba(15,16,18,.16);background:rgba(255,255,255,.7)}
.ck-icoon svg{width:17px;height:17px;fill:none;stroke:var(--ink);stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.ck-tel{font-size:var(--fs-micro);letter-spacing:.08em;padding:8px 13px;border-radius:999px;
  border:1px solid rgba(15,16,18,.16);color:var(--ink3);background:rgba(255,255,255,.7);
  font-variant-numeric:tabular-nums}
.ck-onder{position:absolute;left:19px;right:19px;bottom:19px}
.ck-eb{display:block;font-size:var(--fs-micro);letter-spacing:.15em;text-transform:uppercase;
  color:var(--mut)}
.ck-t{display:block;margin-top:8px;font-size:clamp(23px,2.2vw,32px);font-weight:400;
  letter-spacing:-.032em;line-height:1.03;color:var(--ink)}
.ck-d{display:block;margin-top:8px;font-size:var(--fs-ui);line-height:1.4;
  color:var(--ink3);letter-spacing:-.008em;max-width:26ch}
.ck-pijl{position:absolute;right:19px;bottom:21px;width:34px;height:34px;border-radius:999px;
  display:grid;place-items:center;background:var(--ink);color:#fff;
  opacity:0;transform:translateX(-6px);
  transition:opacity .3s ease,transform .3s cubic-bezier(.2,.8,.3,1)}
.ck > a:hover .ck-pijl,.ck > a:focus-visible .ck-pijl{opacity:1;transform:translateX(0)}
.ck > a:focus-visible{outline:2px solid var(--ac);outline-offset:3px}
@media(max-width:900px){
  .ck-d{display:none}             /* titel is genoeg op klein formaat */
}

/* ── veelgestelde vragen (sectie 5.0) ─────────────────────────────────────
   Variant C, gekozen 16-08-2026: de tien vragen als lijst links, het antwoord
   in een paneel rechts dat blijft staan bij het scrollen. Van de zeven
   proefvarianten de compactste — 1,1 scherm tegenover 1,5 en 2,8.

   ⚠️ Zelfde mechaniek als de tabbladen op /diensten/, bewust en met kennis
   van zaken gekozen. De opmaak staat los, want die tabbladen hebben een
   balkje, een nummer en een hover-opening die hier niet passen.            */
.vrg{display:grid;grid-template-columns:minmax(280px,1fr) 1.25fr;
  gap:clamp(28px,4vw,68px);align-items:start}
.vrg-l{display:flex;flex-direction:column;border-top:1px solid var(--line)}
/* Zweven wisselt het paneel (31-08). De regel moet dus laten zien dat hij
   aanwijsbaar is, en dat mag niets kosten: alleen transform en opacity, nooit
   padding of width — dat is de regel van 16-08 en de reden dat de tijdlijn toen
   stroef aanvoelde. Het streepje links is een pseudo-element dat van hoogte 0
   naar 1 schaalt; de tekst schuift 6 px mee. */
.vrg-t{position:relative;font:inherit;text-align:left;background:none;border:0;
  border-bottom:1px solid var(--line);padding:15px 2px 15px 14px;cursor:pointer;
  color:var(--mut);font-size:var(--fs-ui);line-height:1.4;
  letter-spacing:-.02em;
  transition:color .2s ease, transform .26s cubic-bezier(.2,.7,.2,1)}
.vrg-t::before{content:"";position:absolute;left:0;top:15px;bottom:15px;width:2px;
  background:var(--ac);transform:scaleY(0);transform-origin:top;
  transition:transform .26s cubic-bezier(.2,.7,.2,1)}
.vrg-t:hover,.vrg-t:focus-visible{color:var(--ink)}
.vrg-t:hover{transform:translateX(4px)}
.vrg-t[aria-selected="true"]{color:var(--ink);transform:translateX(6px)}
.vrg-t[aria-selected="true"]::before{transform:scaleY(1)}
.vrg-t:focus-visible{outline:2px solid var(--ac);outline-offset:2px;border-radius:8px}
.vrg-r{position:sticky;top:96px;background:var(--paper);
  border:1px solid var(--line);border-radius:8px;padding:clamp(26px,3vw,42px)}
.vrg-p:focus-visible{outline:2px solid var(--ac);outline-offset:6px;border-radius:8px}
.vrg-n{display:flex;align-items:center;gap:10px;font-size:var(--fs-micro);
  letter-spacing:.14em;color:var(--mut);margin-bottom:16px}
.vrg-n em{font-style:normal;letter-spacing:.12em;text-transform:uppercase}
.vrg-n em::before{content:"·";margin-right:10px}
.vrg-p h3{margin:0 0 8px;font-size:var(--fs-h3);font-weight:400;
  letter-spacing:-.02em;line-height:1.24;color:var(--ink)}
.vrg-p p{margin:0;color:var(--ink3);font-size:var(--fs-basis);line-height:1.62}
/* Alleen opacity en transform — geen hoogte, want het paneel wisselt van
   inhoud en de hoogte verschilt per antwoord. Zie de tijdlijn-les van 16-08. */
.vrg-p.komt{animation:vrgin .34s cubic-bezier(.22,1,.36,1) both}
@keyframes vrgin{from{opacity:0;transform:translateY(var(--vanaf,10px))}
  to{opacity:1;transform:none}}
@media(max-width:900px){
  .vrg{grid-template-columns:1fr;gap:22px}
  .vrg-r{position:static}
}
@media(prefers-reduced-motion:reduce){
  .vrg-p.komt{animation:none}
  .vrg-t,.vrg-t::before{transition:none}
  .vrg-t:hover,.vrg-t[aria-selected="true"]{transform:none}
}

/* ── quote-carrousel ─────────────────────────────────────────
   Naar wearestokt.com, opgemeten 21-08: kaart 370 px, radius 14, padding 32,
   stap 400 px (370 + 30 gap), verspringend, rij schuift 6,3 px/s, hover geeft
   accentkleur + schaal. Variant A: witte kaarten op een getinte band — een
   witte kaart op een witte pagina is geen kaart.                            */
.qb{padding:clamp(60px,7vw,104px) 0 clamp(74px,8vw,120px);overflow:hidden;
  background:var(--paper2)}
.qb-kop{text-align:center;padding:0 24px;margin-bottom:clamp(40px,4.2vw,64px)}
.qb-lbl{font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:.12em;
  color:var(--mut);text-transform:uppercase;margin:0}
.qb-h2{font-weight:300;letter-spacing:-.026em;line-height:1.08;margin:.35em 0 0;
  font-size:clamp(32px,5vw,62px);color:var(--ink);text-wrap:balance}
.qb-h2 sup{color:var(--ac);font-size:.6em;top:-.35em;position:relative}
.qb-sub{font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ac);margin:.9em 0 0}
/* Staat er zolang QUOTES_ECHT uit staat. Weg met één vlag, niet met de hand. */
.qb-let{max-width:56ch;margin:16px auto 0;font-size:var(--fs-ui);line-height:1.45;
  letter-spacing:-.01em;color:var(--mut)}

/* De rij. De ruime padding-top met dezelfde negatieve marge is er zodat de
   verspringende kaarten en de hover-schaal niet worden afgesneden door
   `overflow-x`; zonder dat knipt de eerste kaart bovenaan af.              */
.qb-rij{display:flex;gap:30px;align-items:flex-start;
  padding:170px clamp(24px,5vw,80px) 26px;margin-top:-64px;
  overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;cursor:grab}
.qb-rij::-webkit-scrollbar{display:none}
.qb-rij.sleept{cursor:grabbing;scroll-behavior:auto}
.qb-rij:focus-visible{outline:2px solid var(--ac);outline-offset:-4px;border-radius:8px}

.qb-k{position:relative;flex:0 0 370px;width:370px;margin:0;padding:32px;
  border-radius:8px;transform:translateY(var(--sprong,0));
  background:var(--paper);border:1px solid var(--line);color:var(--ink);
  transition:transform .38s cubic-bezier(.22,1,.36,1),
             background-color .38s ease,border-color .38s ease,color .38s ease}
.qb-k blockquote{margin:0 0 24px;font-size:var(--fs-basis);line-height:1.3;letter-spacing:-.014em;
  color:inherit;text-wrap:pretty}
.qb-k figcaption{display:flex;align-items:center;gap:13px}
.qb-av{width:46px;height:46px;border-radius:50%;flex:0 0 46px;
  background:var(--paper3);border:1px solid var(--line)}
.qb-wie{display:flex;flex-direction:column;gap:3px;min-width:0}
.qb-wie b{font-weight:400;font-size:var(--fs-ui);letter-spacing:-.015em;color:inherit}
.qb-wie em{font-style:normal;font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut);line-height:1.35}
.qb-mark{position:absolute;right:26px;bottom:26px;width:38px;height:27px;
  fill:currentColor;opacity:.14;pointer-events:none}
/* In de stroom, niet absoluut: als merk rechtsboven lag het over de eerste
   regel van het citaat heen. Een QA op contrast en overloop ziet dat niet —
   overlappende tekst is geen van beide.                                     */
.qb-vb{display:inline-block;margin-bottom:16px;font-family:var(--mono);font-size:var(--fs-micro);
  letter-spacing:.1em;text-transform:uppercase;color:var(--ac);background:#fdece7;
  border:1px solid rgba(184,66,38,.26);border-radius:999px;padding:4px 9px}

/* Hover: accent + groter. Alleen transform en kleuren — geen breedte, want dat
   is layout en herberekent de hele rij per frame (les 16-08).              */
@media(hover:hover) and (pointer:fine){
  .qb-rij:not(.sleept) .qb-k:hover{background:var(--ac);border-color:var(--ac);color:#fff;
    transform:translateY(var(--sprong,0)) scale(1.055)}
  .qb-rij:not(.sleept) .qb-k:hover .qb-wie em{color:#fbe9e3}
  .qb-rij:not(.sleept) .qb-k:hover .qb-av{background:#d4603f;border-color:#fbe9e3}
}
.qb-k:focus-within{background:var(--ac);border-color:var(--ac);color:#fff}
.qb-k:focus-within .qb-wie em{color:#fbe9e3}

/* Eigen cursor. Geen mix-blend-mode: een cursor herschildert elk frame en dat
   is precies het patroon dat het scrollen stroef maakt.                    */
.qb-cursor{position:fixed;left:0;top:0;width:80px;height:80px;border-radius:50%;
  display:grid;place-items:center;pointer-events:none;z-index:60;opacity:0;
  background:var(--ink);color:var(--paper);font-family:var(--mono);font-size:var(--fs-micro);
  letter-spacing:.06em;transition:opacity .18s ease,scale .18s ease;scale:.6}
.qb-cursor.aan{opacity:1;scale:1}
@media(hover:none),(pointer:coarse){.qb-cursor{display:none}}

@media(max-width:640px){
  .qb-rij{gap:18px;padding-top:40px;margin-top:-40px}
  .qb-k{flex:0 0 300px;width:300px;padding:26px;transform:none}
}
@media(prefers-reduced-motion:reduce){
  .qb-k{transition:none}.qb-cursor{display:none}
}

/* ── afsluitband ──────────────────────────────────────────────────────────── */
.ctaband .h2{max-width:22ch}
/* `.btn-licht` was de knop voor op een donkere band. Die banden zijn wit,
   dus hij is nu gelijk aan de gewone knop. */
.btn-licht{border-color:var(--line);color:var(--ink)}
.btn-licht:hover{border-color:var(--ink)}

/* ── beweging ─────────────────────────────────────────────────────────────
   Alles hieronder beweegt alleen `transform` en `opacity`. Geen blur, geen
   schaduw die per frame hertekend wordt — dat is hier de bekende oorzaak
   van stroef scrollen.                                                     */
/* De dienstkaarten hielden hun eigen verschuiving. `.rv` animeert sinds
   16-08 alleen nog opacity, dus de transitie voor transform staat nu hier —
   anders sprong de kaart in plaats van te bewegen. */
.rv.kaartin{transform:translateY(18px) scale(.99);
  transition:opacity .5s cubic-bezier(.22,1,.36,1),
             transform .5s cubic-bezier(.22,1,.36,1)}
.rv.kaartin.in{transform:none}
@media(prefers-reduced-motion:reduce){
  .pbar{display:none}
  .ck > a,.ck img,.ck-pijl{transition:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   SAMENSMELTING — 21-08-2026
   nikolaradeski.com (de beweging) + hubtown.co.in (de koele UI).
   Beide op 21-08 opnieuw gemeten in een echte browser, niet van een
   screenshot afgelezen. Wat we overnemen staat per blok in de kop.

   ⚠️ Vaste grenzen die hier NIET aan opgeofferd worden:
   - nul transitions op een layout-eigenschap (width, padding, grid-rows…)
   - geen backdrop-filter, geen filter:blur() dat per frame hertekent
   - alles wat beweegt is opacity of transform
   - prefers-reduced-motion zet elke beweging uit
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  /* Clash Display: de kopletter van nikolaradeski, gratis bij Fontshare,
     stond al in site/fonts/ sinds versie 04. */
  /* 21-08: Clash Display eruit. Lenny: "dit lettertype overal, niks
     dikgedrukt." Augen draait op ÉÉN gewicht — 96 van hun 97 tekstelementen
     staan op PP Neue Montreal Book 350, precies één op Light 300. Geen vet,
     geen tweede letter. Dat is hier overgenomen: --disp is nu gewoon --sans,
     dus de hele site staat op Geist. Clash Display blijft in site/fonts/
     staan voor het versielab, maar wordt door de site niet meer geladen. */
  --disp:var(--sans);
  /* hubtown's koele blauw. Bewust NAAST het groene accent, niet in plaats
     daarvan: het accent is het merk, dit is de instrumentkleur.
     #1f5f9e op wit = 5,73:1 — haalt AA voor tekst. Hun eigen #4db8ff niet. */
  /* ⚠️ 02-09-2026: dit was BLAUW (#1f5f9e / #5ea9e8), het instrumentaccent uit de
     samensmelting van 21-08. Blauw is er op 28-08 uit gegaan en HUISSTIJL.md kent
     het niet meer, maar deze drie tokens waren blijven staan — 39 zichtbare
     voorkomens, waaronder de ruitjes in de doorlopende band en de lijnen en punten
     in de reis. Nu de huisstijl: terracotta als tekst en klein vlak (5,46:1 op wit),
     koraal waar de ondergrond donker is. */
  --hud:#b84226; --hud-lt:#ff7a59;
  --hud-lijn:rgba(184,66,38,.26);
}

/* ── 1 · mono-labels ────────────────────────────────────────────────────────
   hubtown zet ALLE navigatie, knoppen en labels in Commit Mono, kapitalen,
   ruime letterafstand (55 elementen). Dat is het grootste deel van hun
   "koele" indruk — meer nog dan de kleur. Commit Mono is betaald; JetBrains
   Mono is de gratis tegenhanger en staat er al. */
.mono{font-family:var(--mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:var(--fs-micro);line-height:1.1;font-weight:400}
.mono-hud{color:var(--hud)}
.mono-dim{color:var(--mut)}

/* ── 2 · afgesneden hoeken ──────────────────────────────────────────────────
   Hun knoppen en panelen zijn geen afgeronde rechthoeken maar hebben één of
   twee weggesneden hoeken. clip-path, dus geen extra elementen. */
.chamf{clip-path:polygon(11px 0,100% 0,100% calc(100% - 11px),calc(100% - 11px) 100%,0 100%,0 11px)}
.chamf-r{clip-path:polygon(0 0,100% 0,100% calc(100% - 11px),calc(100% - 11px) 100%,0 100%)}

/* ── 3 · hoekmarkeringen ────────────────────────────────────────────────────
   Vier korte haakjes op de hoeken van een vlak. hubtown gebruikt ze om het
   hele venster te omkaderen; wij zetten ze om een blok. Puur ::before en
   ::after met een border — geen markup, geen beeld. */
.hoeken{position:relative}
.hoeken::before,.hoeken::after{content:'';position:absolute;width:15px;height:15px;
  border:1px solid var(--hud-lijn);pointer-events:none}
.hoeken::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.hoeken::after{bottom:-1px;right:-1px;border-left:0;border-top:0}

/* ── 4 · sectie-index ───────────────────────────────────────────────────────
   hubtown heeft links een vaste lijst (FUTURE / INNOVATION / …) waarvan de
   actieve regel oplicht met een klein blokje ervoor. Wij vullen hem met de
   secties van de pagina; de actieve wisselt mee met de scroll.
   Verborgen onder 1200 px — daar is geen kolom voor over. */
.sidx{position:fixed;left:clamp(10px,1.1vw,20px);top:50%;transform:translateY(-50%);
  z-index:40;display:none;flex-direction:column;gap:14px;width:22px}
@media(min-width:1240px){.sidx{display:flex}}

/* ══ Het meereizende spoor ═══════════════════════════════════════════════════
   Lenny 26-08: *"ik wil een mooie cursor door de website heen gaan elke keer
   als je scrollt"*. Dit is die markering: een dunne baan met een stip die
   met de scroll meezakt, en de sectie waar je bent licht op.

   ⚠️ NUL regels JavaScript. `--reisp` (voortgang over de hele pagina) staat al
   op <html>, geschreven door de bestaande planner in site.js. De stip hangt
   aan `transform: translateY(...)` — geen layout-eigenschap, dus geen
   herberekening per frame (regel van 16-08).
   ⚠️ De baan heeft een VASTE hoogte nodig: een percentage in translateY rekent
   tegen de eigen hoogte van de stip, niet tegen die van de baan. Vandaar
   --sidx-h, waar de links zich met space-between over verdelen.                */
.sidx-metbaan{--sidx-h:clamp(186px,23vh,272px);height:var(--sidx-h);
  justify-content:space-between;padding-left:13px}
.sidx-baan{position:absolute;left:2px;top:0;width:1px;height:100%;
  background:var(--line)}
.sidx-stip{position:absolute;left:50%;top:0;width:7px;height:7px;
  margin:-8px 0 0 -8px;border-radius:50%;background:var(--ac);
  border:2px solid var(--paper);
  transform:translateY(calc(var(--reisp,0) * var(--sidx-h)))}

/* Onder 1240px staat .sidx op display:none — daar zou dus niets meereizen.
   Zelfde signaal, andere vorm: een dunne balk bovenaan het scherm. */
.leesbalk{position:fixed;inset:0 0 auto;height:2px;z-index:60;
  background:var(--ac);transform-origin:0 50%;
  transform:scaleX(var(--reisp,0));pointer-events:none}
@media(min-width:1240px){.leesbalk{display:none}}
@media(prefers-reduced-motion:reduce){.sidx-stip,.leesbalk{transition:none}}
/* 21-08: de eerste versie toonde de NAAM in de kolom. Op 1440 px is de marge
   naast de tekstkolom 74 px, dus die namen lagen bovenop de pagina - gemeten:
   de knop "Het werk" was niet meer aanklikbaar. Nu is de kolom in rust 22 px
   breed (alleen het streepje) en klapt de naam pas bij hover of toetsenbord-
   focus naar rechts uit, over een gebied waar niets staat. */
.sidx a{position:relative;display:flex;align-items:center;height:14px;
  text-decoration:none;color:var(--mut)}
/* transform in plaats van width: `width` is een layout-eigenschap en die
   animeren we nergens (regel sinds 16-08). Vaste 22 px, in rust ingedrukt. */
.sidx a::before{content:'';width:22px;height:2px;background:currentColor;
  opacity:.5;transform:scaleX(.64);transform-origin:left center;
  transition:transform .25s ease,opacity .25s ease,background-color .25s ease}
.sidx a[aria-current="true"]::before{transform:none;opacity:1;background:var(--hud)}
.sidx a span{position:absolute;left:30px;white-space:nowrap;
  background:var(--paper);border:1px solid var(--line);padding:5px 9px;
  color:var(--ink);opacity:0;transform:translateX(-5px);pointer-events:none;
  transition:opacity .2s ease,transform .2s ease}
.sidx a:hover span,.sidx a:focus-visible span{opacity:1;transform:none}
.sidx a:hover::before{transform:none;opacity:1}

/* ── 5 · statusregel ────────────────────────────────────────────────────────
   Hun onderbalk (SOUND OFF | SCROLL TO EXPLORE | CHAT WITH US) in drie
   compartimenten. Onderaan zit bij ons de dock, dus deze staat BOVEN de
   voettekst als afsluiting van de pagina. */
.statusregel{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  display:grid;grid-template-columns:1fr auto 1fr}
.statusregel>*{padding:13px clamp(14px,2vw,26px);display:flex;align-items:center;gap:9px}
.statusregel>*+*{border-left:1px solid var(--line)}
.statusregel .rechts{justify-content:flex-end}
.statusregel i{width:5px;height:5px;background:var(--hud);display:block;
  animation:puls 2.6s ease-in-out infinite}
@keyframes puls{0%,100%{opacity:1}50%{opacity:.25}}

/* ── 6 · doorlopende band ───────────────────────────────────────────────────
   nikolaradeski: awb-marquee-content / awb-marquee-left. Eén transform die
   oneindig herhaalt; de inhoud staat er twee keer in zodat de lus naadloos
   is. Staat stil zodra je er met de muis op staat. */
.band{overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:16px 0;-webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.band-rij{display:flex;width:max-content;animation:schuif 34s linear infinite}
.band:hover .band-rij{animation-play-state:paused}
.band-set{display:flex;align-items:center;gap:clamp(26px,3.4vw,52px);
  padding-right:clamp(26px,3.4vw,52px)}
.band-set span{font-family:var(--disp);font-weight:350;font-size:clamp(19px,2.1vw,30px);
  letter-spacing:-.02em;white-space:nowrap;color:var(--ink)}
.band-set b{width:6px;height:6px;background:var(--hud);flex:none;transform:rotate(45deg)}
@keyframes schuif{to{transform:translate3d(-50%,0,0)}}

/* ── 7 · tekst die inkleurt tijdens het scrollen ────────────────────────────
   Bij hen een SplitType + ScrollTrigger-combinatie. Wij zetten elk woord in
   een span en laten de scroll-planner alleen `--p` (0…1) zetten; de kleur
   volgt uit een berekening, dus er is geen JS die kleuren schrijft. */
.inkleur{font-family:var(--disp);font-weight:350;letter-spacing:-.02em;
  font-size:clamp(26px,3.4vw,50px);line-height:1.16;margin:0;color:var(--ink)}
/* 21-08: de uit-stand stond op alpha .19 = 1,52:1 en dus onleesbaar. Bij
   nikolaradeski haalt die tekst het ook niet (#6d6d6d op #dbdbdb = 3,76:1),
   maar wij hebben dat bij klanten al twee keer laten aanpassen, dus hier
   niet overnemen. Berekend: op wit haalt zwart #0f1012 pas 3:1 (de norm voor
   tekst boven 24 px) vanaf alpha 0,44. Op .46 gezet - het verschil tussen
   middengrijs en zwart blijft goed zichtbaar, en wie niet scrollt of geen
   JS heeft kan de zin gewoon lezen. */
.inkleur w{display:inline-block;color:rgba(15,16,18,.46);
  transition:color .18s linear;white-space:pre}
.inkleur w.aan{color:var(--ink)}

/* ── 8 · balk die van vorm verandert ────────────────────────────────────────
   Alleen transform en border-radius (paint, geen layout). */
.vormbalk{height:5px;background:var(--hud);border-radius:22px;
  transform-origin:left center;transform:scaleX(.12);
  transition:transform .9s cubic-bezier(.22,1,.36,1),border-radius .9s ease}
.rv.zicht .vormbalk,.zicht>.vormbalk{transform:scaleX(1);border-radius:8px}

/* ── 9 · onthullen vanonder een rand ────────────────────────────────────────
   nikolaradeski heeft has-mask-background op 17 elementen. clip-path met een
   inset die opengaat; de inhoud schuift tegelijk mee omhoog. */
/* ⚠️ 21-08, gemeten: de eerste versie zette `clip-path:inset(100% 0 0 0)` op
   het element zelf. Dat is een DEADLOCK — een volledig weggeclipt element
   heeft voor de IntersectionObserver intersectionRatio 0, dus de waarnemer
   vuurt nooit, dus .zicht komt er nooit op, dus de clip gaat nooit open. Het
   blok bleef onzichtbaar en er was geen foutmelding. Nu een dekkend vlak dat
   wegschuift: het element zelf houdt gewoon zijn afmeting.
   De kleur is instelbaar, want een sectie met een andere ondergrond heeft een
   andere kleur nodig. */
.onthul{position:relative;overflow:hidden}
.onthul::after{content:'';position:absolute;inset:0;z-index:2;
  background:var(--onthul-kleur,var(--paper));
  transform:translate3d(0,0,0);
  transition:transform 1.05s cubic-bezier(.22,1,.36,1)}
.onthul>*{transform:translate3d(0,26px,0);opacity:0;
  transition:transform 1.05s cubic-bezier(.22,1,.36,1) .1s,opacity .8s ease .1s}
.onthul.zicht::after{transform:translate3d(0,-101%,0)}
.onthul.zicht>*{transform:none;opacity:1}

/* ── 10 · lagen op verschillende snelheid ───────────────────────────────────
   Alleen translate3d, aangestuurd door dezelfde scroll-planner. */
.laag{will-change:transform}

/* ── 11 · SVG die zichzelf tekent ───────────────────────────────────────────
   hubtown's keyframe heet letterlijk `draw`. Dit staat op de plek waar zij
   een 3D-scene met acht .glb-modellen hebben: een paar kB tegen 644. */
.tekent path,.tekent line,.tekent rect,.tekent circle,.tekent polyline{
  stroke-dasharray:var(--len,900);stroke-dashoffset:var(--len,900);
  transition:stroke-dashoffset 1.5s cubic-bezier(.4,0,.2,1)}
.tekent.zicht path,.tekent.zicht line,.tekent.zicht rect,
.tekent.zicht circle,.tekent.zicht polyline{stroke-dashoffset:0}

/* ── 12 · raster dat zich opbouwt ───────────────────────────────────────────
   Hun colFrom0/colFrom1/rowFrom0/rowFrom1: cellen die om en om van links en
   van rechts inschuiven. */
.opbouw>*{opacity:0;transform:translate3d(var(--dx,-18px),0,0);
  transition:opacity .55s ease,transform .55s cubic-bezier(.22,1,.36,1)}
.opbouw>*:nth-child(even){--dx:18px}
.opbouw.zicht>*{opacity:1;transform:none}
.opbouw.zicht>*:nth-child(1){transition-delay:0s}
.opbouw.zicht>*:nth-child(2){transition-delay:.07s}
.opbouw.zicht>*:nth-child(3){transition-delay:.14s}
.opbouw.zicht>*:nth-child(4){transition-delay:.21s}
.opbouw.zicht>*:nth-child(5){transition-delay:.28s}
.opbouw.zicht>*:nth-child(6){transition-delay:.35s}

/* ── 13 · gepinde kaartenstapel ─────────────────────────────────────────────
   Bij nikolaradeski blijft kaart 02 staan terwijl 03 eroverheen schuift, en
   de onderkant van de blijvende kaart vervaagt. position:sticky doet het
   plakken; de vervaging is een mask die met --p meebeweegt. */
/* 21-08: de kaarten liepen over de volle breedte (1290 px) terwijl de tekst
   maar 58ch is - rechts stond dus een leeg vlak. nikolaradeski heeft daar een
   gepinde beeldkaart. Wij hebben geen beeld, dus daar staat de index van de
   vijf diensten: hubtown's actieve-regel-patroon op de stapel eronder. */
.stapelwrap{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:clamp(24px,3vw,56px);align-items:start}
@media(max-width:980px){.stapelwrap{grid-template-columns:1fr}
  .stapelwrap .stapelidx{display:none}}
.stapelidx{position:sticky;top:clamp(96px,11vh,132px);
  border:1px solid var(--line);border-radius:0;padding:clamp(18px,2vw,26px);
  background:var(--paper2)}
.stapelidx>span{display:block;margin-bottom:16px}
.stapelidx ol{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:12px}
/* ⚠️ 02-09 gemeten: --mut (#6b6d72) op --paper2 haalt hier 4,31:1 en de norm is
   4,5. Bestond al vóór de grondproef en op elke grond. --ink3 is de zachtere
   lopende tekst van deze site en haalt er ruim boven. */
.stapelidx li{display:flex;gap:11px;align-items:baseline;color:var(--ink3);
  font-size:var(--fs-ui);transition:color .3s ease}
.stapelidx>span{color:var(--ink3)}
.stapelidx li b{font-family:var(--mono);font-size:var(--fs-micro);color:var(--hud);
  font-weight:400;flex:none}
.stapelidx li.aan{color:var(--ink)}
.stapelidx .schema{margin-top:16px;padding-top:18px;border-top:1px solid var(--line)}
.stapel{display:flex;flex-direction:column;gap:clamp(18px,2vw,30px)}
.stapel>li{list-style:none;position:sticky;top:clamp(96px,11vh,132px)}
.stapel .kaart{background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r);padding:clamp(22px,2.6vw,38px);
  box-shadow:0 18px 44px -30px rgba(15,16,18,.4)}
.stapel>li:not(:last-child) .kaart{
  -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 96px),transparent);
  mask-image:linear-gradient(180deg,#000 calc(100% - 96px),transparent)}
.stapel .nr{font-family:var(--mono);font-size:var(--fs-micro);color:var(--hud);
  letter-spacing:.14em}
.stapel h3{font-family:var(--disp);font-weight:350;letter-spacing:-.02em;
  font-size:clamp(23px,2.4vw,32px);margin:.35em 0 .5em}
.stapel p{margin:0;color:var(--ink3);max-width:58ch}
.stapel ul{margin:1.1em 0 0;padding:0 0 0 1.05em;color:var(--mut);
  font-size:var(--fs-ui)}
.stapel ul li{margin:.3em 0}
/* 21-08: deze noot stond in .mono (kapitalen, ruime letterafstand). Over drie
   regels is dat onleesbaar EN hij liep over de lijst erboven heen. Mono is
   voor labels van twee, drie woorden - niet voor een zin. */
.stapel .noot{margin-top:1.5em;padding-top:1.1em;border-top:1px solid var(--line);
  font-size:var(--fs-ui);color:var(--mut);max-width:58ch}
.stapel .noot b{color:var(--ink);font-weight:400}

/* ── 14 · display-koppen in Clash Display ───────────────────────────────────
   Gemeten bij nikolaradeski: H1 = Clash Display Semibold 86,4 px, regelhoogte
   0,95, letterafstand −0,5 px. Wij hadden Switzer 300. Dit is de wissel die
   je het snelst ziet. */
.display,.h2,.inkleur,.stapel h3{font-family:var(--disp)}
.display{font-weight:350;line-height:1.04;letter-spacing:-.022em}
.h2{font-weight:350;line-height:1.08;letter-spacing:-.022em}

/* ── beweging uit ───────────────────────────────────────────────────────── */
@media(prefers-reduced-motion:reduce){
  .band-rij{animation:none}
  .statusregel i{animation:none}
  .inkleur w{color:var(--ink)}
  .onthul::after{display:none}
  .onthul>*{transform:none;opacity:1}
  .opbouw>*{opacity:1;transform:none}
  .vormbalk{transform:scaleX(1)}
  .tekent path,.tekent line,.tekent rect,.tekent circle,.tekent polyline{
    stroke-dashoffset:0}
}

/* ── mobiel ─────────────────────────────────────────────────────────────── */
@media(max-width:760px){
  .statusregel{grid-template-columns:1fr}
  .statusregel>*+*{border-left:0;border-top:1px solid var(--line)}
  .statusregel .rechts{justify-content:flex-start}
  .stapel>li{position:static}
  .stapel>li:not(:last-child) .kaart{-webkit-mask-image:none;mask-image:none}
  .band-set span{font-size:var(--fs-basis)}
}


/* ══════════════════════════════════════════════════════════════════════════
   NACHTTHEMA — 21-08-2026, op verzoek van Lenny
   "de kaarten van nikolaradeski samengevoegd met de kleurcombinatie en het
   font van hubtown."

   Gemeten bij hubtown.co.in op 21-08, in een echte browser met GPU:
     achtergrond  rgb(2, 10, 24)      = #020a18   (4 grote vlakken)
     tekst        rgb(213, 224, 255)  = #d5e0ff   (65 elementen)
     lijnen       rgba(213, 224, 255, .2)          (dezelfde kleur op 20%)
   Hun hele systeem is ÉÉN kleur in verschillende doorzichtigheden op één
   ondergrond. Dat is hier één op één overgenomen.

   Letters: hun 'Grotesk' (Light 300 / Regular 400 / Bold 700) is een eigen
   gehoste letter die niet publiek te krijgen is. Space Grotesk is de vrije
   tegenhanger uit dezelfde familie, variabel over precies 300-700, 22 kB.
   'Commit Mono' is betaald -> JetBrains Mono, stond er al.

   Aanzetten met THEMA = "nacht" in bouw.py. Het witte thema blijft de
   standaard (besluit 16-08); dit blok raakt niets zolang het uit staat.
   ══════════════════════════════════════════════════════════════════════════ */
html[data-thema="nacht"], /* ══════════════════════════════════════════════════════════════════════════
   NACHTTHEMA — 21-08-2026, op verzoek van Lenny
   "de kaarten van nikolaradeski samengevoegd met de kleurcombinatie en het
   font van hubtown."

   Gemeten bij hubtown.co.in op 21-08, in een echte browser met GPU:
     achtergrond  rgb(2, 10, 24)      = #020a18   (4 grote vlakken)
     tekst        rgb(213, 224, 255)  = #d5e0ff   (65 elementen)
     lijnen       rgba(213, 224, 255, .2)          (dezelfde kleur op 20%)
   Hun hele systeem is ÉÉN kleur in verschillende doorzichtigheden op één
   ondergrond. Dat is hier één op één overgenomen.

   Letters: hun 'Grotesk' (Light 300 / Regular 400 / Bold 700) is een eigen
   gehoste letter die niet publiek te krijgen is. Space Grotesk is de vrije
   tegenhanger uit dezelfde familie, variabel over precies 300-700, 22 kB.
   'Commit Mono' is betaald -> JetBrains Mono, stond er al.

   Aanzetten met THEMA = "nacht" in bouw.py. Het witte thema blijft de
   standaard (besluit 16-08); dit blok raakt niets zolang het uit staat.
   ══════════════════════════════════════════════════════════════════════════ */
html[data-grond="antraciet"]{
  --paper:#020a18; --paper2:#071426; --paper3:#0c1c31;
  --ink:#d5e0ff; --ink2:rgba(213,224,255,.88); --ink3:rgba(213,224,255,.78);
  --mut:rgba(213,224,255,.60);
  --line:rgba(213,224,255,.20);          /* exact hubtowns lijnkleur */
  --line-d:rgba(213,224,255,.28);
  /* Terracotta haalt op #020a18 maar 3,63:1. Koraal — de tweede tint van
     dezelfde familie — haalt er 7,72:1 en blijft herkenbaar hetzelfde merk. */
  --ac:#ff7a59; --ac-lt:#ffa88f;
  /* nacht: op donker is koraal de tekstkleur (6,92:1 op #16181c) */
  --hud:#ff7a59; --hud-lt:#ff9d84; --hud-lijn:rgba(255,122,89,.30);
  /* Space Grotesk voor kop EN tekst, zoals hubtown; mono voor de labels. */
  --sans:'Space Grotesk','Switzer',-apple-system,BlinkMacSystemFont,system-ui,sans-serif;
  --disp:'Space Grotesk','Switzer',system-ui,sans-serif;
  color-scheme:dark;
}
html[data-thema="nacht"] body, html[data-grond="antraciet"] body{background:var(--paper);color:var(--ink)}

/* ── omgekeerde vlakken ────────────────────────────────────────────────────
   Klassen die op wit een LICHT vlak tekenen moeten op nacht een DONKER vlak
   worden, anders staat er een wit blok midden in een donkere pagina. */
html[data-thema="nacht"] .b-paper, /* ── omgekeerde vlakken ────────────────────────────────────────────────────
   Klassen die op wit een LICHT vlak tekenen moeten op nacht een DONKER vlak
   worden, anders staat er een wit blok midden in een donkere pagina. */
html[data-grond="antraciet"] .b-paper{background:var(--paper2)}
html[data-thema="nacht"] .b-paper2, html[data-grond="antraciet"] .b-paper2{background:var(--paper3)}
html[data-thema="nacht"] .b-paper3, html[data-grond="antraciet"] .b-paper3{background:var(--paper2)}
html[data-thema="nacht"] .b-ink, html[data-grond="antraciet"] .b-ink{background:var(--paper3);color:var(--ink)}

/* ── hardgecodeerd wit en zwart ───────────────────────────────────────────
   Er staan 20 losse #fff en 7 #000 in de stylesheet. Die worden hier per
   component teruggezet in plaats van in de basis, zodat het witte thema
   onaangeraakt blijft. */
html[data-thema="nacht"] .stapel .kaart, html[data-thema="nacht"] .stapelidx, /* ── hardgecodeerd wit en zwart ───────────────────────────────────────────
   Er staan 20 losse #fff en 7 #000 in de stylesheet. Die worden hier per
   component teruggezet in plaats van in de basis, zodat het witte thema
   onaangeraakt blijft. */
html[data-grond="antraciet"] .stapel .kaart, html[data-grond="antraciet"] .stapelidx{background:var(--paper2);border-color:var(--line)}
html[data-thema="nacht"] .sidx a span, html[data-grond="antraciet"] .sidx a span{background:var(--paper2);border-color:var(--line);
  color:var(--ink)}
html[data-thema="nacht"] .onthul::after, html[data-grond="antraciet"] .onthul::after{background:var(--onthul-kleur,var(--paper))}
html[data-thema="nacht"] .band-set span, html[data-grond="antraciet"] .band-set span{color:var(--ink)}
html[data-thema="nacht"] .band-set b, html[data-grond="antraciet"] .band-set b{background:var(--hud)}
html[data-thema="nacht"] .statusregel i, html[data-grond="antraciet"] .statusregel i{background:var(--ac)}
/* Uitgerekend, niet gegokt: #d5e0ff op #020a18 haalt de 3:1 voor grote
   tekst pas vanaf alpha .40 (3, 13:1). Op .42 gezet = 3, 34:1, met het
   verschil naar de volle kleur (15, 6:1) ruim zichtbaar. */
html[data-thema="nacht"] .inkleur w, /* Uitgerekend, niet gegokt: #d5e0ff op #020a18 haalt de 3:1 voor grote
   tekst pas vanaf alpha .40 (3, 13:1). Op .42 gezet = 3, 34:1, met het
   verschil naar de volle kleur (15, 6:1) ruim zichtbaar. */
html[data-grond="antraciet"] .inkleur w{color:rgba(213,224,255,.42)}
html[data-thema="nacht"] .inkleur w.aan, html[data-grond="antraciet"] .inkleur w.aan{color:var(--ink)}

/* De kop van hubtown is Bold in kapitalen; die van nikolaradeski ook.
   Hier het gewicht dat bij een variabele Space Grotesk hoort. */
html[data-thema="nacht"] .display, /* De kop van hubtown is Bold in kapitalen; die van nikolaradeski ook.
   Hier het gewicht dat bij een variabele Space Grotesk hoort. */
html[data-grond="antraciet"] .display{font-weight:350;letter-spacing:-.026em}
html[data-thema="nacht"] .h2, html[data-grond="antraciet"] .h2{font-weight:350;letter-spacing:-.022em}
html[data-thema="nacht"] .stapel h3, html[data-grond="antraciet"] .stapel h3{font-weight:350}

/* ── nachtthema: de componenten met eigen kleuren ──────────────────────────
   Gemeten met de contrastauditor: 130 fouten in zes groepen, allemaal
   plekken waar een kleur hardgecodeerd staat of waar een token van rol
   wisselt zodra de ondergrond omkeert. Dit is precies waar
   [[tweede-thema-token-vallen]] voor waarschuwt.

   ⚠️ De labbalk zet `--ac` en `--ac-lt` INLINE op <html> (site.js, setAc).
   Een inline style wint van elke stylesheet-regel, dus het donkere merkgroen
   #b84226 blijft staan en haalt op #020a18 maar 3, 63:1. Oplossing: de
   componenten die het accent op donker zetten wijzen hier naar --ac-lt, dat wél
   licht is. De accentschakelaar in de labbalk blijft daardoor werken. */

/* 1 · logo-blokje: achtergrond is --ink (op nacht licht), tekst was #fff */
html[data-thema="nacht"] .mark, /* ── nachtthema: de componenten met eigen kleuren ──────────────────────────
   Gemeten met de contrastauditor: 130 fouten in zes groepen, allemaal
   plekken waar een kleur hardgecodeerd staat of waar een token van rol
   wisselt zodra de ondergrond omkeert. Dit is precies waar
   [[tweede-thema-token-vallen]] voor waarschuwt.

   ⚠️ De labbalk zet `--ac` en `--ac-lt` INLINE op <html> (site.js, setAc).
   Een inline style wint van elke stylesheet-regel, dus het donkere merkgroen
   #b84226 blijft staan en haalt op #020a18 maar 3, 63:1. Oplossing: de
   componenten die het accent op donker zetten wijzen hier naar --ac-lt, dat wél
   licht is. De accentschakelaar in de labbalk blijft daardoor werken. */

/* 1 · logo-blokje: achtergrond is --ink (op nacht licht), tekst was #fff */
html[data-grond="antraciet"] .mark{color:var(--paper)}
html[data-thema="nacht"] .mark:hover, html[data-grond="antraciet"] .mark:hover{background:var(--ac);color:var(--paper)}

/* 2 · de zwevende navigatiepil en de hamburger stonden op een vast lichtgrijs */
html[data-thema="nacht"] .pill, html[data-thema="nacht"] .burger, /* 2 · de zwevende navigatiepil en de hamburger stonden op een vast lichtgrijs */
html[data-grond="antraciet"] .pill, html[data-grond="antraciet"] .burger{background:rgba(213,224,255,.10);
  border:1px solid var(--line)}
html[data-thema="nacht"] .pill a, html[data-grond="antraciet"] .pill a{color:var(--ink3)}
html[data-thema="nacht"] .pill a:hover, html[data-grond="antraciet"] .pill a:hover{background:rgba(213,224,255,.14);color:var(--ink)}
html[data-thema="nacht"] .pill a.cta, html[data-grond="antraciet"] .pill a.cta{background:var(--ink);color:var(--paper)}
html[data-thema="nacht"] .pill a.cta:hover, html[data-grond="antraciet"] .pill a.cta:hover{background:var(--ac);color:var(--paper)}
html[data-thema="nacht"] html.glas-echt .pill, html[data-grond="antraciet"] html.glas-echt .pill{background:rgba(213,224,255,.08)}

/* 3 · de teller op de dienstenkaarten: wit vlak met een donkere rand */
html[data-thema="nacht"] .ck-tel, /* 3 · de teller op de dienstenkaarten: wit vlak met een donkere rand */
html[data-grond="antraciet"] .ck-tel{background:rgba(2,10,24,.55);
  border-color:var(--line);color:var(--ink2)}

/* 4 · groen op donker — OPGELOST BIJ DE BRON, niet hier.
   Hier stond eerst een lijst componenten die naar --ac-lt werden gestuurd.
   Dat botste met de echte fix in site.js (setAc draait de twee tinten om op
   nacht): die componenten wezen daarna juist naar de DONKERE tint en waren
   weer fout. Twee mechanismen voor hetzelfde probleem werken tegen elkaar —
   nu is --ac zelf licht op nacht en hoeft geen enkel component iets te doen. */

/* 5 · knoppen: de primaire knop is --ink met witte tekst */
html[data-thema="nacht"] .btn-p, /* 4 · groen op donker — OPGELOST BIJ DE BRON, niet hier.
   Hier stond eerst een lijst componenten die naar --ac-lt werden gestuurd.
   Dat botste met de echte fix in site.js (setAc draait de twee tinten om op
   nacht): die componenten wezen daarna juist naar de DONKERE tint en waren
   weer fout. Twee mechanismen voor hetzelfde probleem werken tegen elkaar —
   nu is --ac zelf licht op nacht en hoeft geen enkel component iets te doen. */

/* 5 · knoppen: de primaire knop is --ink met witte tekst */
html[data-grond="antraciet"] .btn-p{background:var(--ink);color:var(--paper)}
html[data-thema="nacht"] .btn-p:hover, html[data-grond="antraciet"] .btn-p:hover{background:var(--ac);color:var(--paper)}
html[data-thema="nacht"] .btn-s, html[data-grond="antraciet"] .btn-s{border-color:var(--line);color:var(--ink)}
html[data-thema="nacht"] .btn-s:hover, html[data-grond="antraciet"] .btn-s:hover{background:rgba(213,224,255,.10)}

/* 6 · invoervelden en de chat */
html[data-thema="nacht"] input, html[data-thema="nacht"] textarea, html[data-thema="nacht"] select, /* 6 · invoervelden en de chat */
html[data-grond="antraciet"] input, html[data-grond="antraciet"] textarea, html[data-grond="antraciet"] select{background:var(--paper2);color:var(--ink);
  border-color:var(--line)}
html[data-thema="nacht"] input::placeholder, html[data-thema="nacht"] textarea::placeholder, html[data-grond="antraciet"] input::placeholder, html[data-grond="antraciet"] textarea::placeholder{color:var(--mut)}

/* ══════════════════════════════════════════════════════════════════════════
   HERO-REIS — 21-08-2026
   "Van een site die stilstaat naar een bedrijf waar aanvragen binnenkomen."

   Het model is hubtown.co.in: één doorlopende wereld waar je op scroll
   doorheen beweegt, met haltes die elk iets toevoegen. Hun uitvoering is
   WebGL met .ktx2-texturen; dit is hetzelfde IDEE in gestapelde lagen met
   perspectief — een paar kB in plaats van een halve megabyte.

   Vier haltes in plaats van hun zes: hun hero ís hun hele homepage, en deze
   site voert "8,3 naar 3,3 seconden" als argument.

   ⚠️ De scroll-planner in site.js schrijft ALLEEN --p (0…1) op de scene.
   Alle beweging volgt daaruit in CSS, dus er is geen JS die per frame
   stijlen zet. Alles wat beweegt is transform of opacity.
   ══════════════════════════════════════════════════════════════════════════ */
/* Vier haltes; de sticky-laag is één scherm hoog, dus er valt 3 schermen te
   scrollen. Meer geeft een trage reis, minder laat de haltes over elkaar
   heen buitelen. */
.hreis{position:relative;height:400svh}
.hreis-vast{position:sticky;top:0;height:100svh;overflow:hidden;
  display:grid;place-items:center}

/* ── het veld ─────────────────────────────────────────────────────────────
   Perspectief op de ouder, diepte via translateZ op de lagen. Geen filter,
   geen blend-mode: dat zijn onze twee bekende jank-oorzaken. */
/* 21-08, na de eerste proef: de scene stond over de volle breedte en het
   blok kwam daardoor bovenop de kop terecht. De tekst staat links (zoals de
   rest van de site), dus de scene hoort in de rechterhelft. */
.hr-scene{position:absolute;inset:0;perspective:1100px;
  perspective-origin:72% 46%;pointer-events:none}
.hr-laag{position:absolute;inset:0;transform-style:preserve-3d;
  will-change:transform}

/* raster: het lege veld waar nog niets staat */
.hr-raster{
  background-image:
    linear-gradient(to right,var(--hr-lijn) 1px,transparent 1px),
    linear-gradient(to bottom,var(--hr-lijn) 1px,transparent 1px);
  background-size:58px 58px;
  --hr-lijn:rgba(15,16,18,.10);
  transform:translate3d(0,0,calc(var(--p,0) * 320px)) ;
  opacity:calc(1 - var(--p,0) * .55);
  -webkit-mask-image:radial-gradient(ellipse 60% 64% at 72% 46%,#000 34%,transparent 76%);
  mask-image:radial-gradient(ellipse 60% 64% at 72% 46%,#000 34%,transparent 76%)}
html[data-thema="nacht"] .hr-raster, html[data-grond="antraciet"] .hr-raster{--hr-lijn:rgba(213,224,255,.15)}

/* ── halte 1: er staat iets ───────────────────────────────────────────────
   Eén blok dat oplicht. De schaal loopt door over de hele reis, zodat je
   er in halte 4 "boven" hangt. */
.hr-blok{position:absolute;left:72%;top:46%;width:clamp(104px,13vw,190px);
  aspect-ratio:1;margin:-6.5vw 0 0 -6.5vw;
  border:1px solid var(--ac);border-radius:8px;
  background:linear-gradient(150deg,
    color-mix(in srgb,var(--ac) 22%,transparent),
    color-mix(in srgb,var(--ac) 5%,transparent));
  box-shadow:
    0 0 0 1px color-mix(in srgb,var(--ac) 22%,transparent),
    0 0 calc(30px + var(--h1,0) * 70px) color-mix(in srgb,var(--ac) 26%,transparent);
  transform:
    translate3d(0,calc(var(--p,0) * -3vh),calc(var(--p,0) * 170px))
    scale(calc(.42 + var(--h1,0) * .58));
  opacity:var(--h1,0);
  transition:opacity .5s ease}

/* ── halte 2: het wordt gevonden ──────────────────────────────────────────
   Lijnen die van de rand naar het blok toe lopen. Ze tekenen zichzelf met
   stroke-dashoffset — dezelfde techniek als hubtowns `draw`-keyframe. */
/* 21-08: stond op inset:0 met preserveAspectRatio="slice". Die combinatie
   rekt de viewBox over het volle scherm en dan lopen de lijnen dwars door de
   kop heen. Nu alleen de rechterhelft, zodat de coördinaten in de SVG ook
   werkelijk betekenen wat ze zeggen. */
.hr-lijnen{position:absolute;inset:0 0 0 44%;width:56%;height:100%;
  transform:translate3d(0,0,calc(var(--p,0) * 110px))}
@media(max-width:820px){.hr-lijnen{inset:0;width:100%}}
.hr-lijnen path{fill:none;stroke:var(--ac);stroke-width:1.1;
  stroke-linecap:round;opacity:.55;
  stroke-dasharray:var(--len,700);
  stroke-dashoffset:calc(var(--len,700) * (1 - var(--h2,0)))}
.hr-lijnen .terug{stroke:var(--hud);
  stroke-dashoffset:calc(var(--len,700) * (1 - var(--h3,0)))}

/* stipjes die over de lijnen lopen zodra halte 3 begint */
.hr-punt{r:3.4;fill:var(--hud);opacity:calc(var(--h3,0) * .95)}

/* ── halte 4: het blijft draaien ──────────────────────────────────────────
   Meer blokken, verder weg: het netwerk. Ze komen pas in beeld als je
   uitzoomt, precies zoals hubtowns landschap. */
.hr-net{position:absolute;inset:0;opacity:var(--h4,0);
  transform:translate3d(0,0,calc(-140px + var(--p,0) * 190px))}
.hr-net i{position:absolute;display:block;width:var(--w,46px);aspect-ratio:1;
  border:1px solid color-mix(in srgb,var(--ac) 55%,transparent);
  border-radius:8px;
  background:color-mix(in srgb,var(--ac) 9%,transparent)}

/* ── de tekst ─────────────────────────────────────────────────────────────
   Eén blok dat op zijn plek blijft; alleen de inhoud wisselt per halte. */
.hreis-tekst{position:relative;z-index:2;width:min(var(--maxw),100% - 2*var(--gut));
  margin:0 auto}
/* De tekst blijft links van de scene. 52% laat de kop met rust en houdt de
   rechterhelft vrij voor wat er gebeurt. */
.hreis-tekst>*{max-width:min(54%,760px)}
@media(max-width:1100px){.hreis-tekst>*{max-width:min(64%,660px)}}
.hr-kop{font-family:var(--disp);font-weight:300;line-height:1.0;
  letter-spacing:-.022em;font-size:clamp(34px,4.6vw,64px);margin:0;
  max-width:16ch;text-wrap:balance}
.hr-lead{color:var(--mut);font-size:var(--fs-lead);max-width:46ch;
  margin:.75em 0 0}
/* 21-08, tweede ronde: eerst wisselde alleen het onderste blok en bleef de
   grote kop staan — Lenny: "ik zie steeds hetzelfde". Nu wisselt het HELE
   tekstblok, zoals bij hubtown: label, kop en lead horen bij één halte.
   De hoogte is vast, anders springt de pagina bij elke wissel. */
/* ⚠️ 24-08: hier stond een MET DE HAND GEKOZEN min-height en stonden de
   haltes op position:absolute;inset:0. Daardoor was de doos altijd 15em,
   ook als de inhoud hoger was - en de langste halte is 313px tegen 255px
   doos. Het gevolg: de laatste regel van de lead liep dwars door de
   voortgangsstippen, op ELKE breedte van 860px en hoger.
   Nu stapelen ze in EEN grid-cel: de doos neemt vanzelf de hoogte van de
   hoogste halte aan, de stapeling en de overgang blijven gelijk, en de
   pagina springt nog steeds niet bij een wissel. De clamp blijft staan als
   ONDERGRENS, niet meer als maat. */
.hr-haltes{position:relative;display:grid;min-height:clamp(13em,20vw,15em)}
.hr-halte{grid-area:1/1;opacity:0;
  transform:translate3d(0,18px,0);pointer-events:none;
  transition:opacity .5s ease,transform .5s cubic-bezier(.22,1,.36,1)}
.hr-halte.aan{opacity:1;transform:none;pointer-events:auto}
.hr-halte .mono{display:block;margin-bottom:1.1em}

/* ══ DE STAPPENREIS ═══════════════════════════════════════════════════════
   24-08: de vier stappen stonden als kaartentijdlijn op een witte sectie, met
   de 3D-wereld er half achter. Twee metaforen naast elkaar, en de kaarten waren
   op 1500px voor 37% een leeg decorvlak (gemeten door Codex). Nu hetzelfde
   model als de hero: een sticky sectie van vier schermen waarin vier
   tekstblokken elkaar afwisselen terwijl de wereld doorreist.
   De opbouw is bewust een kopie van .hreis / .hr-haltes, want dat model is
   uitgetest — inclusief de grid-stapeling, die de doos vanzelf de hoogte van de
   hoogste halte geeft (les van vanmorgen: een handmatige min-height loopt vast
   zodra één blok langer wordt). */
.stapreis{position:relative;height:400svh}
.stapreis-vast{position:sticky;top:0;height:100svh;overflow:hidden;
  display:grid;place-items:center}
/* ⚠️ De wereld is een canvas over het HELE venster, dus hij loopt ook door de
   tekstkolom. De hero heeft dat probleem niet: daar is de scene een eigen laag
   die alleen de rechterhelft beslaat. Hier lossen we het op met een sluier die
   links dekkend papier is en naar rechts wegvalt - tekst rustig, wereld zichtbaar
   op de helft waar hij hoort. Op een telefoon is er geen rechterhelft, dus daar
   wordt de sluier bijna volledig dekkend (zie de mobiele query hieronder). */
.stapreis-vast::before{content:"";position:absolute;inset:0;z-index:1;
  pointer-events:none;
  background:linear-gradient(90deg,
    var(--paper) 0%, var(--paper) 30%,
    color-mix(in srgb,var(--paper) 72%,transparent) 46%,
    transparent 64%)}
.stapreis-tekst{position:relative;z-index:2;
  width:min(var(--maxw),100% - 2*var(--gut));margin:0 auto}
/* de tekst links, de wereld houdt de rechterhelft — zelfde compositie als de hero */
.stapreis-tekst>*{max-width:min(54%,760px)}
@media(max-width:1100px){.stapreis-tekst>*{max-width:min(64%,660px)}}

.sr-boven{margin-bottom:clamp(24px,3.2vw,40px)}
.sr-boven .lbl{display:block;margin-bottom:.7em}
.sr-h2{font-family:var(--disp);font-weight:300;line-height:1.05;
  letter-spacing:-.02em;font-size:clamp(24px,2.6vw,38px);margin:0;
  max-width:22ch;text-wrap:balance}

.sr-haltes{position:relative;display:grid;min-height:clamp(12em,17vw,14em)}
.sr-halte{grid-area:1/1;opacity:0;transform:translate3d(0,18px,0);
  pointer-events:none;
  transition:opacity .5s ease,transform .5s cubic-bezier(.22,1,.36,1)}
.sr-halte.aan{opacity:1;transform:none;pointer-events:auto}

.sr-chip{display:inline-flex;align-items:center;gap:.5em;
  font-family:var(--mono);font-size:var(--fs-micro);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ac);
  border:1px solid color-mix(in srgb,var(--ac) 34%,transparent);
  border-radius:999px;padding:.42em .9em .42em .72em;margin-bottom:1.1em}
.sr-chip svg{width:14px;height:14px;flex:none}
.sr-nr{display:block;font-family:var(--mono);font-size:var(--fs-micro);
  letter-spacing:.14em;text-transform:uppercase;color:var(--mut);
  margin-bottom:.5em}
.sr-t{font-family:var(--disp);font-weight:300;line-height:1.05;
  letter-spacing:-.022em;font-size:clamp(30px,4vw,56px);margin:0 0 .38em;
  max-width:16ch;text-wrap:balance}
.sr-lead{color:var(--mut);font-size:var(--fs-lead);max-width:44ch;margin:0}

.sr-stippen{display:flex;gap:9px;align-items:center;
  margin-top:clamp(16px,2.4vw,24px)}
.sr-stippen i{display:block;width:26px;height:2px;background:var(--line);
  transition:background-color .35s ease}
.sr-stippen i.aan{background:var(--ac)}

/* mobiel: kortere reis, tekst over de volle breedte */
@media(max-width:820px){
  .stapreis{height:300svh}
  /* geen rechterhelft op een telefoon: de wereld blijft, maar gedempt, zodat
     de tekst over de volle breedte leesbaar is */
  .stapreis-vast::before{background:color-mix(in srgb,var(--paper) 86%,transparent)}
  .stapreis-tekst>*{max-width:none}
  .sr-t{max-width:none;font-size:clamp(26px,7.4vw,38px)}
  .sr-haltes{min-height:15em}
}

/* beweging uit: geen reis, maar het eindbeeld — alle vier de stappen onder
   elkaar leesbaar. Nooit een lege sectie. */
@media(prefers-reduced-motion:reduce){
  .stapreis{height:auto}
  .stapreis-vast{position:static;height:auto;padding:var(--ruimte-groot) 0}
  .sr-haltes{min-height:0;display:grid;gap:2.6em}
  .sr-halte{grid-area:auto;opacity:1;transform:none}
}

/* voortgangsstippen, links naast de tekst */
.hr-stippen{display:flex;gap:9px;align-items:center;margin-top:clamp(16px,2.4vw,24px)}
.hr-stippen i{display:block;width:26px;height:2px;background:var(--line);
  transform:scaleX(1);transform-origin:left}
.hr-stippen i.aan{background:var(--ac)}

/* ── mobiel ───────────────────────────────────────────────────────────────
   Een lange gekaapte scroll is op een telefoon vervelend, en het veld is
   daar te klein om diepte te lezen. Kortere reis, plattere scene. */
@media(max-width:820px){
  .hreis{height:300svh}
  .hr-scene{perspective:none}
  /* Op een telefoon is er geen rechterhelft: de scene gaat naar boven, de
     tekst eronder. Naast elkaar schalen werkt hier niet — dat was op 19-08
     bij hero A precies dezelfde fout. */
  .hr-scene{inset:auto 0 auto 0;top:6vh;height:34svh}
  .hr-blok{left:50%;width:clamp(86px,26vw,132px);margin-left:-13vw;margin-top:-13vw;top:50%}
  .hreis-vast{place-items:end center;padding-bottom:6vh}
  .hreis-tekst>*{max-width:none}
  .hr-kop{max-width:none;font-size:clamp(28px,7.8vw,40px)}
  .hr-haltes{min-height:16em}
}

/* ── beweging uit ─────────────────────────────────────────────────────────
   Geen reis, maar het EINDBEELD: alles staat er, alle vier de haltes
   onder elkaar leesbaar. Nooit een lege hero. */
@media(prefers-reduced-motion:reduce){
  .hreis{height:auto}
  .hreis-vast{position:static;height:auto;padding:var(--ruimte-groot) 0}
  .hr-scene{display:none}
  .hr-haltes{min-height:0;display:grid;gap:2.6em}
  /* grid-area terugzetten: in de basisregel staan ze in EEN cel gestapeld,
     hier horen ze juist onder elkaar. */
  .hr-halte{grid-area:auto;position:static;opacity:1;transform:none}
}

/* ══════════════════════════════════════════════════════════════════════════
   AUGEN-RUST — 21-08-2026, alleen op de binnenpagina's
   Besluit Lenny: "beide" — de homepage draagt de reis, de binnenpagina's
   krijgen de rust van augen.pro.

   Gemeten bij augen.pro op 21-08 in een echte browser:
     papier        rgb(254,254,254)   ≈ ons #ffffff
     tekst         rgb(15,16,18)      = LETTERLIJK onze --ink
     nav-pil       rgb(240,240,240)   ≈ onze pil
     H1            27 px              ← wij stonden op 84
   De kleuren klopten dus al. Het verschil zat volledig in de MAATVOERING:
   hun koppen zijn klein en bescheiden, de ruimte eromheen doet het werk.

   Hun sectiepatroon (screenshot `inspiratie/augen/`): een genummerd label in
   een eigen linkerkolom (0.1 / Our Mission), de inhoud rechts, een haarlijn
   per rij. Dat patroon hadden we al — `.cols` + `.lbl` + `.rule`; alleen de
   nummers en de maat ontbraken.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · koppen terug naar augen-maat ─────────────────────────────────────
   Op de homepage blijft Clash Display 600 staan (dat is nikolaradeski). Hier
   Switzer in een licht gewicht, zoals augen's PP Neue Montreal Light 300. */
html[data-stijl="augen"] .display{
  font-family:var(--sans);font-weight:300;
  font-size:clamp(28px,3.1vw,42px);line-height:1.12;letter-spacing:-.024em;
  max-width:24ch}
html[data-stijl="augen"] .h2{
  font-family:var(--sans);font-weight:300;
  font-size:clamp(23px,2.3vw,31px);line-height:1.16;letter-spacing:-.022em}
html[data-stijl="augen"] .lead{font-size:var(--fs-basis);max-width:52ch}

/* ── 2 · de paginakop krijgt lucht in plaats van een vlak ─────────────────
   augen heeft geen gekleurde koptekstband: één doorlopend wit vlak met een
   haarlijn eronder. */
html[data-stijl="augen"] .kop{
  background:transparent;
  padding-top:clamp(146px,15vw,208px);
  padding-bottom:clamp(44px,5vw,76px)}

/* ── 3 · labels ───────────────────────────────────────────────────────────
   ⛔ Hier stond een CSS-counter die elk label een nummer gaf (`0.1 / Diensten`).
   Besluit 16-08: hoofdstuknummers eruit, labels dragen alleen de naam. Dat is
   destijds in de generator uitgevoerd maar niet hier, en daardoor stonden ze er
   op 31-08 nog steeds — vijftien stuks, op zes pagina's.

   ⚠️ De les: het recept "tel in de gebouwde HTML, want nul in bouw.py is een
   aanname" gaat niet ver genoeg bij inhoud die CSS zelf genereert. `content:`,
   `counter()` en `::before` staan nergens in de HTML en tóch op het scherm. Voor
   die categorie moet je de gerenderde tekst uitlezen. */
html[data-stijl="augen"] .lbl b{font-weight:400;color:var(--ink3)}

/* ── 4 · meer ruimte tussen de blokken ────────────────────────────────────
   Bij augen is de linkerkolom grotendeels leeg en dat is precies wat rust
   geeft. Alleen op de binnenpagina's, zodat de homepage compact blijft. */
html[data-stijl="augen"] .block{
  padding-top:clamp(84px,8.5vw,132px);
  padding-bottom:clamp(84px,8.5vw,132px)}
html[data-stijl="augen"] .cols{gap:clamp(32px,5.5vw,96px);
  grid-template-columns:minmax(150px,1.15fr) 5fr}

/* ── 5 · haarlijn onder elke sectie ───────────────────────────────────────
   Hun rijen worden gescheiden door één lijn, niet door een kleurvlak. */
html[data-stijl="augen"] .block+.block{border-top:1px solid var(--line)}
html[data-stijl="augen"] .b-paper,
html[data-stijl="augen"] .b-paper2,
html[data-stijl="augen"] .b-paper3{background:transparent}

@media(max-width:900px){
  html[data-stijl="augen"] .cols{grid-template-columns:1fr}
  html[data-stijl="augen"] .kop{padding-top:clamp(108px,26vw,150px)}
}

/* ══════════════════════════════════════════════════════════════════════════
   ÉÉN GEWICHT — 21-08-2026
   Lenny: "dit lettertype overal, niks dikgedrukt."

   Gemeten bij augen.pro: 96 van hun 97 tekstelementen staan op PP Neue
   Montreal **Book 350**, precies één op Light 300. Geen vet, nergens. Dat is
   wat hun pagina rustig maakt — niet de kleur en niet de witruimte, maar dat
   er nooit iets schreeuwt.

   Geist is variabel 100-900, dus 350 kan hier exact worden ingesteld — geen
   afronding naar 300 of 400.
   ══════════════════════════════════════════════════════════════════════════ */
body{font-weight:350}

/* <b> en <strong> staan browser-breed op `bold`. Er staan er 108 in de
   pagina's, vooral als sectielabel en als nadruk in de dienstenlijsten.
   Nadruk komt hier van de KLEUR, niet van het gewicht — dezelfde keuze die
   augen maakt. */
b,strong{font-weight:400;color:var(--ink)}

/* De labels in de linkerkolom zijn geen nadruk maar een kop; die blijven op
   het basisgewicht en onderscheiden zich door hun plaats. */
.lbl b{font-weight:350}

/* Knoppen en navigatie: ook 350, anders steken ze alsnog uit. */
.btn,.pill a,.mark,.hr-halte b{font-weight:350}

/* Knopelementen erven het lettertype van de browser, niet van body — dus
   `font:inherit` op alles wat een <button> of <input> is. Gemeten: het
   kruisje van de chat stond als enige zichtbare element op Arial. */
button,input,select,textarea{font-family:inherit}

/* De grote cijfers op de cijferwand — dit is precies het beeld dat Lenny
   aanwees: licht, groot, met het label eronder in mono. */
.rdn-n,.bw-n,.cijfer b,[data-tel]{font-weight:300}


/* ══ De reis over de hele pagina ═══════════════════════════════════════════════
   Gemeten recept (inspiratie/reis/RECEPT.md): een wikkel van (reis+1) schermen
   met daarin één sticky laag van één scherm, alles op top:0.

   ⚠️ 23-08 herzien na meting. De eerste opzet had de STRUCTUUR wel en de
   CHOREOGRAFIE niet: --p liep netjes van 0 naar 1, maar stuurde alleen een
   verschuiving van 18 px aan. Dat kostte 8.018 px scroll voor 121 px beweging.
   Een gepinde etappe is een tijdlijn: als er niets op staat, staat de pagina
   stil terwijl de bezoeker scrollt. Nu draagt elke etappe een echte reeks —
   de dienstenrail schuift, de projecten komen op hun beurt.
   Er beweegt niets op een layout-eigenschap: --p stuurt transform en opacity. */
.etappe{min-height:calc((var(--reis,1) + 1) * 100svh)}
/* ⚠️ grid-template-columns:minmax(0,1fr) is geen sierraad. Zonder die regel is
   de kolom `auto` en dus max-content: de dienstenrij loopt bewust door buiten de
   marge, en daarmee rekte hij de hele sectie op tot 1560 px in een venster van
   1440. De wrap werd 120 px te breed, en de rechts uitgelijnde pijlen van de
   carrousel vielen buiten beeld — onzichtbaar én onklikbaar, verstopt door
   overflow:clip. Gemeten op 23-08; stond er sinds de reis erin ging. */
.toneel{position:sticky;top:0;min-height:100svh;display:grid;
  grid-template-columns:minmax(0,1fr);align-content:center;overflow:clip}
.toneel > section{padding-top:0;padding-bottom:0}

/* GEEN fade tussen etappes. De volgende etappe schuift er overheen, want dat is
   wat sticky van nature doet; een fade maakt aan begin en eind van elke etappe
   een leeg scherm, en dat is precies de dode scroll die dit recept vermijdt.
   Daarvoor moet elke etappe wel een dekkende grond hebben. */
.toneel{background:var(--paper)}

/* Vangrail. Past de inhoud niet in één scherm, dan pint de etappe niet.
   site.js meet dat per etappe en zet data-past="0". Zonder deze rem snijdt
   overflow:clip inhoud af — op 23-08 stond de kop van het bewijs daardoor op
   -41 px en was de tellerrij half weg. Een etappe die niet past is geen etappe. */
[data-etappe][data-past="0"]{min-height:0}
[data-etappe][data-past="0"] .toneel{position:static;min-height:0;display:block;overflow:visible}
[data-etappe][data-past="0"] .toneel > section{
  padding-top:var(--ruimte-midden);padding-bottom:var(--ruimte-midden)}

@media (min-width:861px){
  /* De dienstenrail die hier stond is opgeheven, zie ETAPPES in bouw.py. */
  /* de kaarten staan er meteen: een kaart die buiten de clip valt krijgt geen
     intersectie, en zou dus als onzichtbaar inschuiven en dan aanploffen */

  /* ── fasen zonder pinning · het bewijs ───────────────────────────────────
     Zes fasen: de vijf projecten op hun beurt, de tellerrij als slot. --p komt
     hier NIET uit een gepinde etappe maar uit de positie van de sectie in het
     venster (site.js), want deze sectie is 950 px hoog en past niet in één
     scherm. Zo kost de choreografie nul extra schermhoogte.
     --fase is 0 vóór de beurt en 1 erna; de laatste is klaar op 95%. Opacity
     gaat van 0 naar 1 zoals elke andere reveal op deze site — geen ondergrens,
     want een halve dekking is contrastverlies zolang je in die fase staat. */
  [data-fasen] .bw-r,[data-fasen] .bw-t{
    --fase:clamp(0, calc((var(--p,0) - var(--i,0) * .15) / .2), 1)}
  [data-fasen] .bw-r.rv,[data-fasen] .bw-t{
    opacity:var(--fase);
    transform:translate3d(0, calc((1 - var(--fase)) * 10px), 0)}
  [data-fasen] .bw-r:nth-child(1){--i:0}
  [data-fasen] .bw-r:nth-child(2){--i:1}
  [data-fasen] .bw-r:nth-child(3){--i:2}
  [data-fasen] .bw-r:nth-child(4){--i:3}
  [data-fasen] .bw-r:nth-child(5){--i:4}
  [data-fasen] .bw-t{--i:5}
}

/* Wie beweging heeft uitgezet krijgt de hele reeks ineens, voluit — en de rij
   moet dan gewoon met de hand te schuiven zijn.
   ⚠️ De selectors hieronder dragen [data-past="1"] mee en dat is geen sierraad:
   zonder dat wint de regel hierboven op specificiteit (0,3,0 tegen 0,2,0), ook
   binnen deze media query. Gemeten op 23-08: de rij stond dan op overflow:hidden
   terwijl de rail stilstond, waardoor de vijfde kaart onbereikbaar was. */
@media (prefers-reduced-motion: reduce){
  .toneel > section{opacity:1;transform:none}
  [data-fasen] .bw-r.rv,[data-fasen] .bw-t{opacity:1;transform:none}
}
/* op een telefoon is pinnen duurder dan het oplevert: gewoon laten scrollen */
@media (max-width:860px){
  .etappe{min-height:0}
  .toneel{position:static;min-height:0;display:block;overflow:visible}
  .toneel > section{opacity:1;transform:none;padding-top:var(--ruimte-midden);padding-bottom:var(--ruimte-midden)}
  [data-fasen] .bw-r.rv,[data-fasen] .bw-t{opacity:1;transform:none}
}

/* ══ DE WERELD — de routekaart achter de hele pagina ═══════════════════════════
   Gemeten bij hubtown: hun reisgevoel komt van één doorlopende wereld met een
   spoor dat je volgt, niet van losse effecten. Onze vertaling in wit: de VOLLE
   route ligt er in haarlijn (alles wat je kunt verwachten), en daaroverheen
   tekent de afgelegde weg zich in het accent, precies tot waar je nu bent.

   De kaart is 800vh hoog en schuift over ~1370vh scroll, dus hij beweegt
   LANGZAMER dan de pagina — daardoor reis je er langs in plaats van dat hij
   meebeweegt. Alles hangt aan --reisp op <html>; er beweegt niets op een
   layout-eigenschap. */
.wereld{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  contain:strict}
.wereld-raster{position:absolute;inset:0;opacity:.5;
  background-image:
    linear-gradient(to right, color-mix(in srgb,var(--ink) 4%,transparent) 1px,transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb,var(--ink) 4%,transparent) 1px,transparent 1px);
  background-size:clamp(48px,5vw,86px) clamp(48px,5vw,86px)}

/* ⚠️ Hier stond een gloedlaag in de vaste wereld, bedoeld om de achtergrond
   warmer te laten worden richting de bestemming. Gemeten: onzichtbaar. De
   secties liggen er met 72-100% dekkend wit overheen, dus van die gloed kwam
   7 punten op 255 door — onder de waarneembaarheidsgrens. Een laag die je niet
   ziet is geen laag. De aankomst krijgt nu zijn eigen tint, zie .aankomst.  */

/* ⚠️ Hier stond de doorlopende routelijn met knooppunten (23-08, overdag).
   Eruit: Lenny keurde hem af en een meting van acht bureausites gaf hem gelijk —
   geen enkele heeft een doorlopende lijn of een vaste voortgangsindicator, en
   allemaal hebben ze 12 tot 26 beelden waar wij er nul hadden. De reis zit nu
   in de opeenvolging van haltes MET beeld, zie .halte.
   Terughalen betekent: git, of _backup-beeld-0823/. */

/* ⚠️ 24-08 — hier stonden alle secties HALF doorzichtig (72-82%), zodat de
   wereld overal een beetje doorschemerde. Lenny: *"wat zijn die rare dingen op
   de achtergrond"* en *"de route gaat gewoon heel vaag uit"*. Dat is precies
   wat halve doorzichtigheid oplevert: overal een beetje wereld, nergens genoeg
   om iets te betekenen, en altijd achter tekst.
   Nu werkt het met VENSTERS. De secties zijn weer dicht, en op de plekken waar
   de reis er echt toe doet staat de wereld VOLLEDIG open. Zo verschijnt de
   inhoud terwijl je door de wereld reist, in plaats van eroverheen te zweven. */
.b-paper{background:var(--paper)}
.b-paper2{background:var(--paper2)}
.b-ink{background:var(--paper)}

/* ── de vensters ──────────────────────────────────────────────────────────
   Een venster laat de wereld helemaal door. De grond van de wereld IS het
   papierwit van de site, dus de leesbaarheid verandert niet - alleen de route
   en de haltes worden zichtbaar. */
.venster{background:transparent!important}
/* boven en onder een venster een korte overgang, zodat de wereld niet met een
   harde rand begint maar de sectie in schuift */
.venster::before,.venster::after{content:"";position:absolute;left:0;right:0;
  height:clamp(60px,7vw,110px);pointer-events:none;z-index:0}
.venster::before{top:0;background:linear-gradient(var(--paper),transparent)}
.venster::after{bottom:0;background:linear-gradient(transparent,var(--paper))}
/* ⚠️ 24-08, TWEEDE KEER VANDAAG: hier stond `.venster > *{position:relative;z-index:1}`
   om de inhoud boven deze twee verlopen te tillen. Die regel zette dus `position`
   in een regel die alleen over stapeling gaat — precies de fout waar vanmorgen
   de sectie-index al op omviel. Nu sloopte hij `position:sticky` van
   `.stapreis-vast`: gelijke specificiteit (0,1,0), deze regel staat later in het
   bestand, dus die won. De hele stappenreis plakte niet meer en de tekst stond
   492px boven het venster.
   Opgelost zonder `position`: de verlopen krijgen `z-index:-1`. De sectie is zelf
   al een stapelcontext (`main > section{position:relative;z-index:1}`), dus ze
   tekenen achter de inhoud van de sectie en toch nog boven het wereld-canvas. */
.venster::before,.venster::after{z-index:-1}
/* de voettekst laat de aankomstgloed door; hij dekte hem volledig af */
footer{background:transparent}
/* alles wat inhoud is, staat bóven de wereld */
/* ⚠️ 24-08: .sidx stond hier ook in. Die is op regel ~1149 `position:fixed`
   (een vaste index tegen de linkerrand), en deze regel zette hem terug op
   `relative`. Gevolg: de index ging 182px in de FLOW innemen, vóór .hreis,
   dus de hele pagina - en dus ook de sticky hero - schoof 182px omlaag. Op
   1280x720 en 1366x768 vielen de heroknoppen daardoor onder de vouw, en de
   index zelf tekende half buiten beeld linksboven in plaats van gecentreerd.
   Zichtbaar vanaf 1240px, want daaronder staat hij op display:none - daarom
   viel het op een smal venster niet op.
   Hij heeft z-index 40 in zijn eigen regel, dus voor "boven de wereld" is
   hier niets nodig. Zet nooit `position` in een regel die alleen stapeling
   bedoelt. */
header.top,footer,.dock,.statusregel{position:relative;z-index:1}
main{position:relative;z-index:1}
/* de inhoud staat boven de route, de route boven de wereld */
main > section{position:relative;z-index:1}

@media (prefers-reduced-motion: reduce){
  /* Geen voortgang die meeloopt met de scroll: dan is de hele route afgelegd
     en horen de haltes ook allemaal gemarkeerd te staan. Anders is de weg vol
     en zijn de haltes leeg, en dat spreekt elkaar tegen. */
}
/* op een telefoon kost een vaste laag meer dan hij oplevert; de route blijft,
   want die is de reis — alleen het raster eronder gaat uit */
@media (max-width:860px){
  .wereld{display:none}
  .b-paper{background:var(--paper)}
  .b-paper2{background:var(--paper2)}
  .b-ink{background:var(--paper)}
}

/* ══ DE HALTES — de tussenstukken op de route ═══════════════════════════════
   Waarom deze bestaan: hubtowns schermen dragen één zin en verder niets, en
   juist daardoor zie je hun wereld eronder. Onze secties zijn vol (kaarten,
   tabellen, lijsten) en dekten de routekaart volledig af — gemeten op 23-08:
   op de dienstensectie was er geen enkele pixel wereld te zien.
   Dus komt de lucht ertussen. Een halte heeft bewust GEEN achtergrond en geen
   kader: hier loopt de route zichtbaar doorheen, je komt aan, en dan volgt de
   inhoud van die halte. Tekst links, rechterhelft open voor de kaart. */
.halte{min-height:62svh;display:grid;align-content:center;
  padding:clamp(28px,5vh,64px) 0;position:relative}
/* Een halte met beeld hoeft geen extra lucht: het beeld zelf is de lucht.
   Gemeten 23-08: met de grote ruimte stond hij op 1,48 scherm terwijl de
   opname er maar 0,93 van vulde. */
.halte.met-beeld{min-height:0;padding:var(--ruimte-midden) 0 clamp(30px,3.4vw,52px)}
.halte .wrap{width:100%}
.halte-in{max-width:44ch}

/* ── het werkbeeld ──────────────────────────────────────────────────────────
   Elk beeld is een schermafdruk van een site die wij hebben gebouwd en die
   live staat. Model: linear.app — die heeft ook geen fotografie en zet bij
   elke sectie een opname van het eigen product, met een kaal indexnummer
   erboven. Een fijne rand en een lage schaduw zetten de opname op de pagina
   zonder dat het een plaatje-in-een-kader wordt. */
.halte-beeld{margin:clamp(16px,2.4vw,40px) 0 0}
.hb-vlak{display:block;overflow:hidden;border-radius:var(--r);
  border:1px solid var(--line);background:var(--paper2);
  box-shadow:0 1px 2px rgba(16,18,20,.05), 0 18px 44px -20px rgba(16,18,20,.16)}
.hb-vlak img{display:block;width:100%;height:auto}
.halte-beeld figcaption{margin-top:clamp(8px,1.2vw,16px);
  color:var(--mut);font-size:var(--fs-micro);letter-spacing:.06em}
/* twee opnames naast elkaar: dat IS het bewijs van "meer dan één markt" */
.halte-beeld.twee{display:grid;grid-template-columns:1fr 1fr;
  gap:clamp(12px,1.6vw,24px)}
.halte-beeld.twee figcaption{grid-column:1/-1}
/* op een telefoon passen twee opnames niet naast elkaar: dan zijn het twee
   postzegels. Gemeten op 390 px: 165 px per opname, onleesbaar. Onder elkaar. */
@media (max-width:860px){
  .halte-beeld.twee{grid-template-columns:1fr}
}

/* het beeld komt rustig omhoog als het in beeld komt; transform en opacity,
   niets dat layout aanraakt */
.halte-beeld{opacity:0;transform:translate3d(0,16px,0);
  transition:opacity .7s cubic-bezier(.22,1,.36,1),
             transform .7s cubic-bezier(.22,1,.36,1)}
.halte.zicht .halte-beeld{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  .halte-beeld{opacity:1;transform:none;transition:none}
}
.halte-nr{display:block;margin-bottom:clamp(8px,1.4vw,16px)}
.halte-naam{font-size:var(--fs-h2);font-weight:350;letter-spacing:-.022em;
  line-height:1.08;text-wrap:balance}
.halte-zin{margin-top:clamp(8px,1.2vw,16px);font-size:var(--fs-lead);
  color:var(--ink3);line-height:1.5;text-wrap:pretty}

/* Een streep die vanaf de halte naar rechts loopt, de kaart in. Hij groeit
   als de halte in beeld komt — dat maakt de aansluiting tussen de tekst en
   de route zichtbaar in plaats van dat het twee losse dingen blijven. */
.halte-in::after{content:"";display:block;height:1px;background:var(--ac);
  margin-top:clamp(16px,2vw,24px);opacity:.45;
  transform:scaleX(0);transform-origin:left center;
  transition:transform .9s cubic-bezier(.22,1,.36,1) .1s}
.halte.zicht .halte-in::after{transform:scaleX(1)}

/* ── de eindbestemming ──────────────────────────────────────────────────────
   Het einde van de reis mag zwaarder wegen dan een tussenhalte — en er ook
   anders uitzien. Vanaf hier kleurt de ondergrond mee: dit is de plek waar je
   aankomt, en dat hoort je te zien zonder dat iemand het opschrijft. */
.aankomst{min-height:78svh;
  background:linear-gradient(to bottom,
    transparent 0%,
    color-mix(in srgb,var(--ac) 4%,transparent) 45%,
    color-mix(in srgb,var(--ac) 7%,transparent) 100%)}
.aankomst + .ctaband{
  background:linear-gradient(to bottom,
    color-mix(in srgb,var(--ac) 7%,var(--paper)) 0%,
    color-mix(in srgb,var(--ac) 4%,var(--paper)) 100%)}
.aankomst .halte-in{max-width:52ch}
/* het beeldmerk als eindpunt: hier komt de reis aan, en dat is bij ons */
.aankomst .wrap{display:grid;grid-template-columns:1fr auto;
  align-items:center;gap:clamp(24px,4vw,64px)}
.aankomst-merk img{display:block;width:clamp(96px,13vw,190px);height:auto;
  opacity:.9}
@media (max-width:860px){
  .aankomst .wrap{grid-template-columns:1fr}
  .aankomst-merk img{width:84px}
}
.aankomst .halte-naam{font-size:clamp(34px,4.4vw,64px);letter-spacing:-.03em}

@media (max-width:860px){
  .halte{min-height:0;padding:var(--ruimte-midden) 0}
  .aankomst{min-height:0}
}

/* ══ DE 3D-REIS — de donkere hero ══════════════════════════════════════════════
   Nagebouwd naar hubtown.co.in. ⚠️ De hero is DONKER en dat is geen willekeur:
   lichtbanen bestaan alleen tegen donker. Hubtown, linear en de hele categorie
   doen het daarom zo. De rest van de site blijft wit (besluit 16-08).
   Uitzetten = HERO_3D op False in bouw.py; dan komt de oude scene terug. */
/* de wereld is nu een vaste laag achter de HELE pagina */
.wereld-3d{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.wereld-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* de hero-scene zelf is doorzichtig: de wereld eronder is de achtergrond */
.hr-scene.driedee{background:transparent}
/* ⚠️ Onderaan de hero een verloop naar het papierwit van de site. Zonder dit
   eindigt de donkere hero met een kaarsrechte lijn tegen de eerste lichte
   sectie — gemeten 23-08 op 26% scroll. De wereld eronder kleurt al mee, maar
   de secties hebben een vaste achtergrond en die kan dat niet volgen. */
.hreis:has(.driedee)::after{content:"";position:absolute;left:0;right:0;bottom:0;
  height:26vh;pointer-events:none;z-index:2;
  background:linear-gradient(to bottom, rgba(4,7,14,0) 0%,
    rgba(4,7,14,.55) 46%, var(--paper) 100%)}
/* de oude lagen zwijgen als de 3D-scene aan staat: twee werelden over elkaar
   is geen wereld */
.driedee .hr-raster,.driedee .hr-net,.driedee .hr-lijnen,.driedee .hr-blok{display:none}

/* De tekst staat nu op donker. Alleen binnen de hero — één blok, zodat er geen
   token omgekeerd hoeft te worden (dat is hier vier keer eerder misgegaan). */
.hreis:has(.driedee){background:#04070e;color:#eaf2f7}
/* ⚠️ Een donkere band achter de tekstkolom, als LAAG IN DE SCENE — niet als
   pseudo-element van de tekst. Reden: hij hoort bij de achtergrond. Hangt hij
   aan de tekst, dan verdwijnt hij mee zodra je de tekst verbergt, en dat is
   precies wat een eerlijke contrastmeting op een bewegende scene doet. Op 23-08
   leverde dat een meting op die na de reparatie niet veranderde — vals rood.
   Zonder band lopen de lichtbanen dwars door de tekst: contrast tot 1,10:1.
   Het vignet is niet genoeg; dat verzacht de randen, niet het midden. */
.hr-tekstband{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,
    rgba(4,7,14,.97) 0%, rgba(4,7,14,.95) 30%,
    rgba(4,7,14,.86) 48%, rgba(4,7,14,.35) 68%, rgba(4,7,14,0) 84%)}
@media (max-width:820px){
  .hr-tekstband{background:linear-gradient(180deg,
    rgba(4,7,14,.55) 0%, rgba(4,7,14,.92) 38%, rgba(4,7,14,.97) 100%)}
}
.hreis:has(.driedee) .hr-kop{color:#f2f7fa}
.hreis:has(.driedee) .hr-lead{color:#a8bccd}
.hreis:has(.driedee) .mono-hud{color:#5fd6ff}
.hreis:has(.driedee) .hr-kop .ac{color:#ff7a59}
.hreis:has(.driedee) .hr-stippen i{background:rgba(234,242,247,.28)}
.hreis:has(.driedee) .hr-stippen i.aan{background:#5fd6ff}
.hreis:has(.driedee) .btn-s{color:#eaf2f7;border-color:rgba(234,242,247,.34);
  background:transparent}
.hreis:has(.driedee) .btn-s:hover{background:rgba(234,242,247,.10);
  border-color:rgba(234,242,247,.55)}
.hreis:has(.driedee) .btn-p{background:var(--ac);color:#fff;border-color:transparent}
.hreis:has(.driedee) .btn-p:hover{background:#d4603f}
/* de sectie-index en de bovenbalk staan op de donkere hero */
.hreis:has(.driedee) ~ * .sidx a{color:var(--mut)}

@media (prefers-reduced-motion: reduce){
  /* de scene tekent één rustige stand en beweegt niet meer, zie reis3d.js */
  .hr-3d{opacity:.9}
}

/* ── het werk als lijst (31-08-2026) ──────────────────────────────────────────
   Naar lucerra.co/projects, gemeten op 25-08. Preview boven, lijst eronder; de
   aangewezen regel licht op en wisselt het beeld. Alles met de prefix `cl-`,
   want een lab dat de kale klassen van deze stylesheet erft is hier al drie
   keer misgegaan (.kop, .kaart, .lead).
   ⚠️ Geen enkele overgang op een layout-eigenschap: alleen opacity. */
.cl{margin-top:clamp(8px,1vw,16px)}

/* ⚠️ De previews stapelen in ÉÉN grid-cel, niet met position:absolute.
   Met absolute nam het vak zijn hoogte niet van de inhoud aan: de twee
   schermafdrukken hebben verschillende verhoudingen (1600×805 en 1600×894),
   dus de tweede stak 29 tot 39 px onder zijn vak uit en raakte op 900 px de
   lijst eronder. Gestapeld in een grid neemt het vak de hoogte van de hoogste
   preview aan en kan er niets meer uitsteken. Zelfde reparatie als bij de
   hero-haltes op 24-08. */
.cl-pvs{display:grid;margin-bottom:clamp(24px,3vw,40px)}
.cl-pv{margin:0;grid-area:1/1;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:18px;
  opacity:0;visibility:hidden;transition:opacity .42s cubic-bezier(.2,.7,.2,1)}
.cl-pv[data-aan]{opacity:1;visibility:visible}
.cl-pv-b{display:block;max-width:min(760px,58vw)}
.cl-pv-b img{display:block;width:100%;height:auto;border-radius:8px;
  border:1px solid var(--line);box-shadow:0 34px 76px -44px rgba(15,16,18,.55)}
/* Case 03 heeft nog geen schermafdruk. Geen leeg kader dat aankondigt dat er
   niets is — een paneel met de twee cijfers die er wél al zijn. */
/* ⚠️ De twee cases zonder schermafdruk (Halo AI, B.O.S.S) vulden 66% van het
   previewvak tegen 76-85% voor de twee mét beeld — een klein blokje midden in
   veel lucht, waardoor de wissel bij die twee nauwelijks opviel. Gemeten
   15-09: vak 503 px, paneel 330 px. `min-height` volgt nu de hoogte van de
   schermafdrukken, en het paneel krijgt dezelfde rand en schaduw zodat het
   visueel een gelijkwaardige kaart is in plaats van een gat. */
.cl-pv-t{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(22px,2.6vw,34px);width:min(760px,58vw);
  min-height:clamp(260px,29vw,400px);
  padding:clamp(30px,4vw,52px) 24px;border-radius:8px;background:var(--paper2);
  border:1px solid var(--line);box-shadow:0 34px 76px -44px rgba(15,16,18,.55)}
.cl-pv-t em{font-style:normal;font:500 11px/1 var(--mono,var(--sans));
  letter-spacing:.14em;text-transform:uppercase;color:var(--mut)}
.cl-pv-cf{display:flex;gap:clamp(24px,3.4vw,52px);flex-wrap:wrap;justify-content:center}
.cl-pv-cf span{display:flex;flex-direction:column;align-items:center;gap:4px;
  font-size:var(--fs-micro);color:var(--mut);text-align:center}
.cl-pv-cf b{font-size:clamp(30px,3.4vw,44px);font-weight:300;letter-spacing:-.02em;
  color:var(--ink);line-height:1}
.cl-pv figcaption{text-align:center;max-width:62ch;padding:0 16px}
.cl-pv figcaption b{display:block;font-size:clamp(17px,1.5vw,21px);font-weight:400;
  letter-spacing:-.015em;color:var(--ink)}
.cl-pv figcaption span{display:block;margin-top:8px;font-size:var(--fs-micro);line-height:1.55;
  color:var(--mut)}

/* ⚠️ `p, li, blockquote{max-width:68ch}` is een LEESBAARHEIDSregel voor lopende
   tekst, maar hij raakt élke <li> op de site — ook deze, waar de li geen zin is
   maar een rij in een tabelachtige lijst. Gemeten op 2560 px: li 764 px breed
   (68ch) binnen een ul van 1297 px, waardoor de regels links uitgelijnd oogden
   tegenover een gecentreerde preview erboven. Een kale elementkiezer die je
   nergens verwacht; grep bij zo'n uitlijningsklacht op `li{` in styles.css. */
.cl-lijst{list-style:none;margin:0;padding:0}
.cl-lijst li{max-width:none}
/* ⚠️ `width:100%` is hier geen opmaakdetail. Een <button> neemt de breedte van
   zijn INHOUD, ook met `display:grid` — de regels liepen daardoor tot 1090 px
   terwijl de preview erboven tot 1660 px doorliep, en dan oogt de lijst links
   uitgelijnd tegenover een gecentreerde preview. Gemeten op 2560 px, gevonden
   door een rand om beide te tekenen: de container stond wél goed (631-1929),
   alleen de knoppen erin niet. Zelfde familie als "een button laat blok-kinderen
   niet uitrekken" (DCSS, 04-08). */
.cl-lijst button{width:100%;display:grid;grid-template-columns:52px 1fr auto;align-items:baseline;
  gap:clamp(16px,2vw,28px);background:none;border:0;position:relative;
  border-top:1px solid var(--line);padding:16px 2px;text-align:left;cursor:pointer;
  font-family:inherit;color:var(--mut);transition:color .28s}
.cl-lijst li:last-child button{border-bottom:1px solid var(--line)}
/* ⭐ 15-09: de aangewezen regel was ALLEEN een kleurverschil (grijs -> wit).
   Technisch werkte de wissel — gemeten: preview volgt, aria-current klopt —
   maar Lenny zag het niet: *"als ik eroverheen ga, zie ik niet dat het
   aanpast."* Terecht, want de preview staat ver boven je muisaanwijzer en op
   de regel zelf gebeurt niets. Nu drie signalen tegelijk, allemaal op de regel
   waar de muis staat: een accentstreep die opengroeit, de regel die opschuift,
   en het nummer plus het label in de accentkleur.
   ⛔ Alleen transform, opacity en color — geen enkele layout-eigenschap
   (de jank-regel van 16-08). */
.cl-lijst button::before{content:"";position:absolute;left:-14px;top:14px;bottom:14px;
  width:2px;background:var(--ac);transform:scaleY(0);transform-origin:50% 0;
  transition:transform .3s cubic-bezier(.2,.7,.2,1)}
.cl-lijst button[aria-current]{color:var(--ink)}
.cl-lijst button[aria-current]::before{transform:scaleY(1)}
.cl-lijst button > *{transition:transform .3s cubic-bezier(.2,.7,.2,1),color .28s}
.cl-lijst button[aria-current] > *{transform:translateX(7px)}
.cl-lijst button[aria-current] .cl-nr,
.cl-lijst button[aria-current] .cl-tp{color:var(--ac)}
@media (prefers-reduced-motion: reduce){
  .cl-lijst button::before{transition:none}
  .cl-lijst button > *{transition:color .28s}
  .cl-lijst button[aria-current] > *{transform:none}
}
.cl-lijst button:focus-visible{outline:2px solid var(--ac);outline-offset:3px}
.cl-nr{font-size:var(--fs-micro);letter-spacing:.06em;color:inherit}
.cl-m{font-size:clamp(17px,1.55vw,22px);font-weight:400;letter-spacing:-.012em;color:inherit}
.cl-m i{font-style:normal;color:var(--mut);font-size:.78em}
.cl-tp{font-size:var(--fs-micro);letter-spacing:.06em;text-align:right;color:inherit;white-space:nowrap}
.cl-mob,.cl-mobtxt{display:none}

/* Smal scherm: hover bestaat niet, dus geen inhoud erachter verstoppen.
   De preview vervalt en elke regel draagt zijn eigen beeld. */
@media(max-width:820px){
  .cl-pvs{display:none}
  .cl-lijst button{grid-template-columns:44px 1fr;gap:4px 14px;padding:20px 2px 24px;
    color:var(--ink)}
  .cl-tp{grid-column:2;text-align:left;color:var(--mut)}
  .cl-mob{display:block;grid-column:1/-1;margin-top:16px}
  .cl-mob img{display:block;width:100%;height:auto;border-radius:8px;
    border:1px solid var(--line)}
  .cl-mob .cl-pv-t{width:100%;min-height:0;padding:30px 20px;gap:18px}
  .cl-mob .cl-pv-cf b{font-size:var(--fs-h3)}
  .cl-mobtxt{display:block;grid-column:1/-1;margin-top:16px}
  .cl-mobtxt b{display:block;font-size:var(--fs-basis);font-weight:400;letter-spacing:-.012em;
    color:var(--ink)}
  .cl-mobtxt span{display:block;margin-top:8px;font-size:var(--fs-ui);line-height:1.55;
    color:var(--mut)}
}
@media(prefers-reduced-motion:reduce){.cl-pv{transition:none}}

/* Beschikbaarheid onder de knop van de contactband (31-08-2026). Bewust klein en
   rustig: het is een feit dat de drempel wegneemt op het moment van klikken, geen
   aandachtsgrijper. Zie BESCHIKBAARHEID in bouw.py — blijft uit tot het getal klopt. */
.cta-besch{margin:16px 0 0;font-size:var(--fs-ui);line-height:1.55;color:var(--ink3);max-width:52ch}
.cta-besch b{font-weight:500;color:var(--ink)}


/* ══════════════════════════════════════════════════════════════════════════
   Opruimronde 31-08-2026 — zie _review/REVIEW-2026-08-31-design.md
   De vijftig losse font-size-waarden en de acht hoekstralen zijn hierboven bij
   de bron vervangen. Wat hier staat is wat er niet met een waarde op te lossen
   was.
   ══════════════════════════════════════════════════════════════════════════ */

/* Regellengte. Gemeten 103 tekens op de homepage en 172 op /werk/; leesbaar is
   45 tot 90. Dit begrenst alleen lopende tekst — koppen en labels blijven vrij. */
p, li, blockquote{max-width:68ch}
.lead, .aan-lead, .bw-lead{max-width:56ch}

/* Tikdoelen op WCAG 2.5.8 (24×24). De sectie-index stond op 9×14 px en de link
   onder het invulveld op 69×17. De streepjes blijven visueel even klein; alleen
   het aanraakvlak groeit. */
.sidx a{min-width:24px;min-height:24px;display:flex;align-items:center}
.aan-klein a{display:inline-block;padding:4px 2px}

/* iOS wacht 300 ms op een dubbeltik voordat een knop reageert, tenzij je dit
   zegt. Stond nergens in de stylesheet. */
a, button, input, label, summary, .tab{touch-action:manipulation}

/* Het amber van het "Voorbeeld"-merk was een losse waarde op één plek. Een
   waarschuwing hóórt af te wijken van het merkaccent, dus de kleur blijft — maar
   nu als token, zodat hij op één plek te wijzigen is.
   ⛔ Het HUD-blauw (#1f5f9e) blijft bewust staan. Op de proef vielen de kaders
      van het schema op /diensten/ bijna weg toen ik het naar de merkkleur trok:
      blauw haalt 5,89:1 op de grijze kaart, groen 4,80:1. Allebei boven de norm,
      maar blauw steekt merkbaar meer af en onderscheidt technische elementen van
      merkelementen. Of dat een tweede merkkleur waard is, is een besluit. */
/* was #8a4b00 (amber) — buiten de huisstijl, 02-09 */
:root{--let-op:#b84226}
.qb-vb{color:var(--let-op)}

/* ── merkblok onder de hero (31-08-2026) ─────────────────────────────────────
   Op verzoek van Lenny, in de plaats van de cijferwand: het beeldmerk, de slogan
   en waar we voor staan. Twee kolommen: het teken links groot, de woorden rechts. */
.mb{display:grid;grid-template-columns:minmax(200px,.7fr) 1.3fr;
  gap:clamp(30px,5vw,80px);align-items:start}
.mb-teken{display:block;width:clamp(120px,13vw,190px);height:auto}
.mb-slogan{margin:22px 0 0;font-size:var(--fs-lead);font-weight:300;
  letter-spacing:-.02em;color:var(--ink);max-width:14ch}
.mb-zin{margin:0 0 clamp(26px,3vw,40px);font-size:clamp(21px,2.2vw,30px);
  font-weight:300;letter-spacing:-.025em;line-height:1.28;color:var(--ink);
  max-width:26ch;text-wrap:balance}
/* vier items, dus vier kolommen op breed en twee daaronder — met auto-fit op 210px
   viel het vierde item alleen op een tweede rij en dat oogt onaf. */
.mb-lijst{display:grid;grid-template-columns:repeat(4,1fr);
  gap:0 clamp(22px,3vw,44px)}
.mb-r{border-top:1px solid var(--line);padding:16px 0}
.mb-r b{display:block;font-size:var(--fs-ui);font-weight:500;color:var(--ink)}
.mb-r span{display:block;margin-top:4px;font-size:var(--fs-ui);line-height:1.55;
  color:var(--ink3)}
/* het beeldmerk in de voettekst-cirkel */
.fmerk img{width:52px;height:auto;display:block}
/* 13-09: op grond=antraciet is de cirkel rgb(28,31,36) en het merkteken is
   bijna zwart (gem. rgb 15,17,18) -> onzichtbaar. Zelfde tegenzet als de
   kopbalk op r.168. Gemeten: alleen antraciet heeft hier een donkere grond. */
html[data-grond="antraciet"] .fmerk img{filter:invert(1)}
/* ⚠️ `.mb-teken` (het merkblok onder de hero) stond als enige van de vier
   merktekens op `filter:none` en was dus zwart op antraciet. Gemeten 15-09;
   Lenny: *"die logo daaronder mag echt wit zijn hoor."* De kopbalk, de reis en
   de voettekst hadden de omkering al. */
html[data-grond="antraciet"] .mb-teken{filter:invert(1)}
@media(max-width:860px){
  .mb{grid-template-columns:1fr;gap:28px}
  .mb-lijst{grid-template-columns:1fr 1fr}
  .mb-slogan{max-width:none}
}


/* ── proefbalk voor de achtergrond van de reis (02-09-2026) ─────────────────
   Tijdelijk gereedschap, niet de site. Staat boven de bestaande labbalk. */
.bgbalk{position:fixed;left:14px;bottom:64px;z-index:9998;display:flex;
  align-items:center;gap:4px;padding:5px 5px 5px 12px;border-radius:999px;
  background:rgba(14,16,19,.94);border:1px solid rgba(255,255,255,.18);
  font-family:var(--sans)}
.bgbalk .mono{font-family:var(--mono);font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:#9aa3ad;margin-right:6px}
.bgbalk button{min-height:34px;padding:0 13px;border:1px solid transparent;
  border-radius:999px;background:transparent;color:#e7ebef;cursor:pointer;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  transition:background-color .15s,color .15s,border-color .15s}
.bgbalk button:hover{border-color:rgba(255,255,255,.34)}
.bgbalk button[aria-pressed="true"]{background:var(--ac-lt);color:#14171a}
@media(max-width:860px){.bgbalk{display:none}}

/* ══ DE GROND VAN DE HELE SITE — proef 02-09-2026 ══════════════════════════
   Lenny: *"ik ben geen fan van dit witte achtergrond, kijk wat je daar kan doen
   overal op de website."* Dat draait het besluit van 16-08 om ("de site is wit").
   Vier antwoorden, allemaal binnen HUISSTIJL.md, te wisselen met de balk
   linksonder of met ?grond=… in het adres.

     papier     warm gebroken wit — de leegte wordt een vel in plaats van een gat
     zand       een stap verder: duidelijk niet-wit, rustig en warm
     antraciet  de opening van dit merk: 82 % donker met 1-2 % warm accent
     gemengd    het ritme van het voorstel zelf — donker openen, papier verder

   Hoe het werkt: de site tekent alles met vier tokens (--paper, --paper2,
   --paper3, --line) en drie tekstkleuren (--ink, --ink2/3, --mut). Een grond is
   dus een SET WAARDEN, geen nieuwe opmaak. `antraciet` leent bovendien de 34
   omkeerregels die het nachtthema van 21-08 al had (welke vlakken donker moeten
   worden), maar met de huisstijlwaarden erin — dat scheelde de hele inversie
   opnieuw uitzoeken.                                                          */

/* ── papier ─────────────────────────────────────────────────────────────── */
html[data-grond="papier"]{
  --paper:#f4f2ef; --paper2:#eceae6; --paper3:#e3e0da;
  --line:rgba(15,16,18,.15);
  /* ⚠️ 09-09-2026, gemeten: precies dezelfde fout als hieronder bij `zand`, en die
     is op 02-09 alleen daar gerepareerd. Op deze grond zakt --mut (#6b6d72) op
     --paper2 naar 4,31:1 terwijl de norm voor 12px 4,5 is — dat raakt élk grijs
     micro-label op een vlak: de vragen, de casecijfers, de quotekaarten. #5f6167
     haalt 5,15:1 op --paper2 en 4,70:1 op het donkerste vlak --paper3.
     Dit is de kern van [[grond-is-een-tokenset]]: een donkerder vel duwt grijs
     onder de norm, dus een grond is nooit alleen een achtergrondkleur. */
  --mut:#5f6167;
}
html[data-grond="papier"] body{background:var(--paper)}

/* ── zand ───────────────────────────────────────────────────────────────── */
html[data-grond="zand"]{
  --paper:#eae5dd; --paper2:#e1dbd1; --paper3:#d6cfc3;
  --line:rgba(15,16,18,.18);
  /* ⚠️ Gemeten: op deze grond zakt --mut (#6b6d72) naar 3,97-4,13:1 — de norm is
     4,5. Een donkerder vel vraagt donkerder bijtekst; dit is de kern van het
     verschil tussen een grond wisselen en een achtergrondkleur wisselen. #54565c
     haalt 4,7:1 op de grond zelf en 4,5:1 op het donkerste vlak (--paper3). */
  --mut:#54565c;
  /* --hud staat NIET inline (dat doet alleen --ac via de labbalk), dus dit token
     moet hier apart mee omlaag — anders blijft #b84226 staan op 3,97-4,36:1. */
  --hud:#a63a20; --hud-lijn:rgba(166,58,32,.26);
}
html[data-grond="zand"] body{background:var(--paper)}

/* ── antraciet ──────────────────────────────────────────────────────────────
   De structuur komt van het nachtthema; deze waarden zetten dat blok terug op de
   huisstijl. Blauwzwart #020a18 en Space Grotesk waren van vóór de wissel van
   01-09 en horen er niet meer bij.                                            */
html[data-grond="antraciet"]{
  --paper:#16181c; --paper2:#1c1f24; --paper3:#23272d;
  --ink:#f2f5f7; --ink2:rgba(242,245,247,.90); --ink3:rgba(242,245,247,.80);
  --mut:#9aa3ad;
  --line:rgba(255,255,255,.14); --line-d:rgba(255,255,255,.22);
  /* terracotta haalt op #16181c maar 3,1:1 — koraal haalt er 6,92:1 */
  --ac:#ff7a59; --ac-lt:#ffa88f;
  --hud:#ff7a59; --hud-lt:#ff9d84; --hud-lijn:rgba(255,122,89,.30);
  /* ⛔ NIET de letter meewisselen: Geist is de huisletter (HUISSTIJL §4). Het
     nachtthema zette Space Grotesk, en dat was een keuze van 21-08 die met de
     grond niets te maken heeft. */
  --sans:'Geist','Switzer',-apple-system,BlinkMacSystemFont,system-ui,sans-serif;
  --disp:'Geist','Switzer',system-ui,sans-serif;
  color-scheme:dark;
}
html[data-grond="antraciet"] body{background:var(--paper);color:var(--ink)}

/* ── gemengd ────────────────────────────────────────────────────────────────
   Papier als grond, maar de openende en afsluitende banden op antraciet — dat is
   letterlijk het ritme dat het branded-housing-voorstel zelf aanhoudt: 82 %
   donker op de omslag en de inhoudsopgave, wit op de inhoudspagina's.          */
html[data-grond="gemengd"]{
  --paper:#f4f2ef; --paper2:#eceae6; --paper3:#e3e0da;
  --line:rgba(15,16,18,.15);
}
html[data-grond="gemengd"] body{background:var(--paper)}
html[data-grond="gemengd"] .rz[data-bg="geen"] .rz-bg{background:#16181c}

.bgbalk.grondbalk{bottom:106px}

/* Op een donkere grond haalt terracotta het niet als tekst (3,25:1 gemeten op de
   'Concept'-regel in de voettekst). Koraal is daar de tekstkleur van dezelfde
   familie — HUISSTIJL §1. */
/* ⚠️ setAc DRAAIT de twee tinten om op een donkere grond, dus daar is `--ac` de
   lichte (koraal) en `--ac-lt` de donkere. Hier dus --ac, niet --ac-lt — met
   --ac-lt stond er weer terracotta op antraciet (3,25:1). */
html[data-grond="antraciet"] .todo{color:var(--ac)}
html[data-grond="antraciet"] .stapelidx li b{color:var(--ac)}


/* ══════════════════════════════════════════════════════════════════════════
   DRIE PILAREN — 09-09-2026
   De regel onder de merknaam, het uitklapmenu met een kop, de dienstkaarten
   op een pilaarpagina, en het blok "waar de AI zit".
   ══════════════════════════════════════════════════════════════════════════ */

/* de agency-regel: staat onder de slogan in de voettekst en in het merkblok */
.fagency{margin-top:8px;font-size:var(--fs-ui);color:var(--mut);letter-spacing:-.01em}
.mb-agency{font-family:var(--mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:var(--fs-micro);color:var(--ac);margin-bottom:14px}

/* de eerste regel van een uitklapmenu wijst naar de pilaar zelf */
.submenu .subkop{border-bottom:1px solid var(--line);border-radius:8px 8px 0 0;
  margin-bottom:6px;padding-bottom:11px}
.submenu .subkop b{color:var(--ac)}

/* een processtrook past zich aan het aantal stappen aan; hij stond hard op
   vijf kolommen en de flows van de dienstpagina's hebben er vier of vijf */
.flow{grid-template-columns:repeat(auto-fit,minmax(112px,1fr))}

/* het beeld boven aan een dienstpagina */
.pgbeeld{margin:0;overflow:hidden;border-radius:var(--r);background:var(--paper2)}
.pgbeeld img{display:block;width:100%;height:auto;aspect-ratio:16/7;object-fit:cover}

/* de dienstkaarten op een pilaarpagina */
.dks{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:clamp(14px,1.6vw,22px);margin-top:clamp(26px,3vw,40px)}
.dk{position:relative;display:flex;flex-direction:column;gap:10px;
  padding:clamp(22px,2.4vw,32px);border-radius:var(--r);background:var(--paper);
  box-shadow:var(--schaduw);text-decoration:none;color:inherit;
  transition:transform .3s cubic-bezier(.16,.84,.32,1),box-shadow .3s cubic-bezier(.16,.84,.32,1)}
.dk:hover,.dk:focus-visible{transform:translateY(-3px)}
.dk .dk-n{font-family:var(--mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:var(--fs-micro);color:var(--ac)}
.dk .dk-t{font-size:var(--fs-h3);font-weight:400;letter-spacing:-.02em;line-height:1.2}
.dk .dk-d{font-size:var(--fs-basis);color:var(--ink3);line-height:1.5}
.dk .dk-p{margin-top:auto;padding-top:14px;font-size:var(--fs-ui);color:var(--ac)}
.dk .dk-p i{font-style:normal;display:inline-block;transition:transform .3s cubic-bezier(.16,.84,.32,1)}
.dk:hover .dk-p i{transform:translateX(4px)}

/* "waar de AI zit" — twee kolommen: wel en niet */
.ai2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:clamp(16px,2vw,28px);margin-top:clamp(26px,3vw,40px)}
.ai2 h3{font-family:var(--mono);text-transform:uppercase;letter-spacing:.14em;
  font-size:var(--fs-micro);color:var(--ink3);font-weight:400;margin-bottom:16px}
.ai2 ul{display:grid;gap:14px}
.ai2 li{list-style:none}
.ai2 li b{display:block;font-weight:400;letter-spacing:-.015em;margin-bottom:4px}
.ai2 li span{display:block;font-size:var(--fs-basis);color:var(--ink3);line-height:1.55}
.ai2 .ai-wel li b::before{content:"";display:inline-block;width:9px;height:1px;
  background:var(--ac);vertical-align:middle;margin-right:9px}
.ai2 .ai-niet li b{color:var(--mut)}
.ai2 .ai-niet li b::before{content:"";display:inline-block;width:9px;height:1px;
  background:var(--line3,var(--line));vertical-align:middle;margin-right:9px}

/* de regel "wat we kunnen laten zien" */
.bewijsregel{margin-top:clamp(22px,2.6vw,32px);padding:clamp(18px,2vw,26px);
  border-radius:var(--r);background:var(--paper2)}
.bewijsregel span{display:block;font-family:var(--mono);text-transform:uppercase;
  letter-spacing:.14em;font-size:var(--fs-micro);color:var(--ink3);margin-bottom:8px}
.bewijsregel p{font-size:var(--fs-basis);color:var(--ink);line-height:1.55;max-width:44em}

/* verder binnen dezelfde pilaar */
.verder{display:flex;flex-wrap:wrap;gap:10px;margin-top:clamp(20px,2.4vw,30px)}
.verder a{display:inline-flex;align-items:center;gap:8px;padding:10px 16px;
  border-radius:99px;background:var(--paper2);text-decoration:none;color:var(--ink);
  font-size:var(--fs-ui);letter-spacing:-.01em;
  transition:background .25s cubic-bezier(.16,.84,.32,1)}
.verder a:hover,.verder a:focus-visible{background:var(--paper3)}
.verder a i{font-style:normal;color:var(--ac)}

@media (max-width:620px){
  .ai2{grid-template-columns:1fr}
}


/* ═══ PILAARPAGINA · vorm "Spoor" ═══════════════════════════════════════════
   Gekozen door Lenny op 13-09-2026 uit elf vormen (`_lab-pilaar/`). Naar
   cerebrium.ai, gemeten diezelfde dag: links een lijst die blijft staan en
   meeloopt met de scroll (actieve dienst donker, rest gedimd), rechts per
   dienst eerst het paneel, dan de kop, dan de tekst — die volgorde is hun
   vondst en hij werkt.

   ⛔ Alleen voor pilaren MET subdiensten (01 Web & Search, 02 Marketing &
      Content). Pilaar 03 is Halo AI en krijgt een eigen vorm.
   ⚠️ De kaart over het beeld is DEKKEND wit. Op .94 valt hij net onder de
      0,95-drempel van elke contrastmeter, die dan doorkijkt naar het donkere
      beeld eronder en 1,36 meldt waar het 10,5 is.
   Volledige verantwoording: inspiratie/REFERENTIE-cerebrium.md
   ════════════════════════════════════════════════════════════════════════ */
.pl-sr{padding:clamp(80px,10vw,140px) 0 clamp(60px,8vw,110px)}
.pl-sr-groot{font-size:clamp(34px,6.4vw,92px);font-weight:300;line-height:1.0;
  letter-spacing:-.04em;margin:0 0 clamp(48px,6vw,96px);max-width:20ch;color:var(--ink)}
.pl-sr-grid{display:grid;grid-template-columns:minmax(230px,400px) minmax(0,1fr);
  gap:clamp(30px,5vw,96px);align-items:start}
.pl-sr-zij{position:sticky;top:clamp(120px,16vh,190px)}
.pl-sr-lbl{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ac);display:block;margin-bottom:clamp(20px,2.6vw,36px)}
.pl-sr-lijst{display:flex;flex-direction:column;gap:clamp(6px,.8vw,12px)}
.pl-sr-lijst a{font-size:clamp(21px,2.3vw,32px);font-weight:400;letter-spacing:-.02em;
  text-decoration:none;line-height:1.18;color:var(--mut);transition:color .35s ease}
.pl-sr-lijst a.aan{color:var(--ink)}
.pl-sr-lijst a:hover{color:var(--ink)}
.pl-sr-b{scroll-margin-top:140px;padding-bottom:clamp(56px,8vw,120px)}
.pl-sr-paneel{position:relative;border-radius:16px;overflow:hidden;background:var(--paper3);
  aspect-ratio:16/10}
.pl-sr-im{width:100%;height:100%;object-fit:cover;display:block}
.pl-sr-kaart{position:absolute;left:clamp(14px,2vw,28px);right:clamp(14px,2vw,28px);
  bottom:clamp(14px,2vw,28px);background:#fff;border-radius:12px;
  padding:clamp(12px,1.5vw,20px)}
.pl-sr-fl{display:flex;flex-wrap:wrap;gap:6px}
.pl-sr-fl div{display:flex;gap:6px;align-items:baseline;font-size:var(--fs-micro);
  border:1px solid rgba(15,16,18,.16);border-radius:999px;padding:5px 11px}
.pl-sr-fl span{color:#b84226;font-variant-numeric:tabular-nums}
.pl-sr-fl em{font-style:normal;color:#3a3c41}
.pl-sr-b h2{font-size:clamp(23px,2.6vw,34px);font-weight:400;letter-spacing:-.02em;
  margin:clamp(22px,2.6vw,36px) 0 0;line-height:1.14}
.pl-sr-l{margin:16px 0 0;color:var(--ink3);font-size:var(--fs-lead);line-height:1.6;max-width:58ch}
/* ⚠️ 13-09: stond als PILLEN (flex-wrap + border-radius:999px). Gemeten over
   alle 24 punten: mediaan 9 woorden, langste 18 — dat zijn zinnen, geen labels.
   Ter vergelijking: de processtappen, die wél pillen zijn, hebben een mediaan
   van 1 woord. Een pil is voor twee of drie woorden; daarboven wordt het een
   afgeknot tekstblok. Zelfde regel als "mono is voor labels" (21-08). */
.pl-sr-p{list-style:none;padding:0;margin:22px 0 0}
.pl-sr-p li{font-size:var(--fs-ui);color:var(--ink3);padding:9px 0 9px 20px;
  position:relative;border-bottom:1px solid var(--line);line-height:1.5}
.pl-sr-p li::before{content:"";position:absolute;left:0;top:17px;width:9px;height:1px;
  background:var(--ac)}
.pl-sr-a{display:inline-block;margin-top:24px;color:var(--ac);font-size:var(--fs-ui);
  text-decoration:none}
@media(max-width:980px){
  .pl-sr-grid{grid-template-columns:1fr}
  .pl-sr-zij{position:static}
  .pl-sr-lijst{flex-direction:row;flex-wrap:wrap;gap:10px 18px}
  .pl-sr-lijst a{font-size:var(--fs-ui)}
}


/* ═══ BEWIJS PER DIENST ═════════════════════════════════════════════════════
   Wat we van deze dienst werkelijk hebben opgeleverd, met de cijfers erbij.
   Teksten: D.BEWIJS in diensten.py — zonder klantnamen, want ons werk is
   anoniem tot een klant tekent. Gebouwd 13/14-09 omdat de dienstpagina's
   dunner waren dan de pilaar erboven (250-333 woorden tegen 478-518).
   ════════════════════════════════════════════════════════════════════════ */
.bw-rij{display:grid;grid-template-columns:repeat(auto-fit,minmax(258px,1fr));
  gap:clamp(14px,1.8vw,26px);margin-top:clamp(26px,3.2vw,44px)}
.bw-i{border-top:1px solid var(--line);padding-top:clamp(16px,1.8vw,24px)}
.bw-i h3{font-size:var(--fs-ui);font-weight:400;margin:0;color:var(--ac);
  letter-spacing:.01em}
.bw-i p{margin:10px 0 0;font-size:var(--fs-ui);color:var(--ink3);line-height:1.55}
@media(max-width:640px){.bw-rij{grid-template-columns:1fr;gap:0}
  .bw-i{padding-block:16px}}


/* ═══ PILAAR-HERO ═══════════════════════════════════════════════════════════
   Richting A · Type, gekozen door Lenny op 13-09-2026 uit zes in
   `_lab-pilaarhero/`. Alleen typografie, geen stockfoto — ons eigen onderzoek
   van 25-08 (`meet-dienstbeeld.js`, twaalf bedrijven die dit werk verkopen):
   nul tonen een foto van mensen, nul tonen een serverruimte.

   ⭐ Hij dicht ook een inhoudsgat. Bij de omzetting naar de Spoor-vorm (13-09)
      viel het blok `midden` van de pilaarpagina en daarmee `p["intro"]` —
      41 tot 50 woorden per pilaar die daarna nergens meer stonden. Gemeten
      15-09: de intro van pilaar 01 kwam op /web/ niet voor.

   ⚠️ De NAAM is de h1 (daar zoekt iemand op), de belofte staat eronder als
      grote regel. Niet andersom, en niet allebei groot: twee grote koppen
      boven elkaar leest als een dubbele kop (les 23-08).
   ════════════════════════════════════════════════════════════════════════ */
.ph{padding:clamp(96px,12vw,168px) 0 clamp(42px,5vw,74px)}
.ph-lbl{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ac);display:block}
.ph-naam{font-size:clamp(18px,1.9vw,25px);font-weight:400;letter-spacing:-.008em;
  margin:15px 0 0;color:var(--ink3);line-height:1.3}
.ph-belofte{font-size:clamp(37px,6.3vw,90px);font-weight:300;line-height:.99;
  letter-spacing:-.042em;margin:12px 0 0;max-width:17ch;color:var(--ink)}
.ph-lead{max-width:56ch;margin:clamp(24px,3vw,38px) 0 0;font-size:var(--fs-lead);
  color:var(--ink3);line-height:1.6}
.ph-onder{margin:clamp(32px,4vw,54px) 0 0;padding-top:20px;
  border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:9px 28px;
  font-size:var(--fs-ui);color:var(--mut)}
.ph-onder a{color:var(--mut);text-decoration:none;transition:color .3s ease}
.ph-onder a:hover,.ph-onder a:focus-visible{color:var(--ink)}
@media(max-width:640px){.ph-onder{flex-direction:column;gap:11px}}
/* Het Spoor volgt direct op de hero; zijn eigen paddingtop van 140 px kwam
   bovenop die van de hero en gaf een leeg scherm ertussen (gemeten 15-09). */
/* ⚠️ `html[data-stijl="augen"] .block` heeft specificiteit (0,2,1) en won van
   een kale `.ph + .pl-sr` (0,2,0): gemeten 122,4 px waar 37 px hoorde. Beide
   scopes staan daarom uitgeschreven — een selectorlijst is geen voorvoegsel. */
.ph + .pl-sr,
html[data-stijl="augen"] .ph + .pl-sr,
/* Pilaar 03 heeft geen Spoor maar een gewone sectie eronder — sinds het
   openingsbeeld eraf is (15-09) stond daar 72 + 122 px lucht. */
.ph + .block,
html[data-stijl="augen"] .ph + .block{padding-top:clamp(18px,2.6vw,40px)}


/* ═══ HALO AI — DE OVERDRACHT ═══════════════════════════════════════════════
   Pilaar 03 is een endorsed brand: eigen naam, eigen prijsmodel, later een
   eigen site, hetzelfde bedrijf (besluit 02-09). Lenny, 13-09: *"iets heel
   aparts, dat echt de brand Halo presenteert, als een tak van Thiery &
   Pierce."* Gekozen uit vier vormen in `_lab-halo/` (`python3 _lab-halo/lab.py`);
   wisselen is de constante HALO_VORM in bouw.py.

   De band is de OMKERING van de grond: op een lichte site donker, op antraciet
   licht. Dat is wat "je stapt een andere ruimte binnen" doet.
   ════════════════════════════════════════════════════════════════════════ */
/* ⚠️ `background:var(--ink)` werkt hier NIET: op grond antraciet is `--ink`
   bijna wit (rgb 242,245,247) en dan staat er witte tekst op een witte band.
   Dat is de token-inversie die al vijf keer eerder toesloeg, en de zesde keer
   was deze. Daarom eigen tokens die maar ÉÉN ding betekenen, per grond
   expliciet gezet. De band is bewust de omkering van de grond: op een lichte
   site donker, op antraciet licht — dat is wat "je stapt een andere ruimte
   binnen" doet. */
.hl-ovd{--hl-bg:#16181c;--hl-tx:#f3f5f7;--hl-dim:rgba(255,255,255,.66);
  --hl-ln:rgba(255,255,255,.17);--hl-ac:#ff7a59;
  background:var(--hl-bg);color:var(--hl-tx);padding:clamp(54px,7vw,104px) 0}
html[data-grond="antraciet"] .hl-ovd{--hl-bg:#f2f2f4;--hl-tx:#14171a;
  --hl-dim:#3a3c41;--hl-ln:rgba(15,16,18,.14);--hl-ac:#b84226}
.hl-o-brug{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase}
.hl-o-van{color:var(--hl-dim)}
.hl-o-pijl{color:var(--hl-ac)}
.hl-o-naar{color:var(--hl-tx);border:1px solid var(--hl-ln);border-radius:999px;
  padding:6px 14px;letter-spacing:.12em}
.hl-o-h{font-size:clamp(28px,3.6vw,50px);font-weight:300;line-height:1.06;
  letter-spacing:-.03em;margin:clamp(22px,2.6vw,36px) 0 0;max-width:18ch;
  color:var(--hl-tx)}
.hl-ovd .ac{color:var(--hl-ac)}
.hl-o-zin{margin:20px 0 0;font-size:var(--fs-lead);line-height:1.6;
  color:var(--hl-dim);max-width:60ch}
.hl-o-rij{display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));
  gap:clamp(16px,2vw,30px);margin-top:clamp(30px,3.6vw,50px)}
.hl-o-f{display:flex;gap:14px;border-top:1px solid var(--hl-ln);padding-top:16px}
.hl-o-f > span{font-size:var(--fs-micro);color:var(--hl-ac);
  font-variant-numeric:tabular-nums;padding-top:3px}
.hl-o-f h3{font-size:var(--fs-ui);font-weight:400;margin:0;color:var(--hl-tx)}
.hl-o-f p{margin:8px 0 0;font-size:var(--fs-ui);color:var(--hl-dim);line-height:1.55}
.hl-o-noot{margin:clamp(28px,3.4vw,46px) 0 0;padding-top:18px;
  border-top:1px solid var(--hl-ln);font-size:var(--fs-ui);color:var(--hl-dim);
  line-height:1.6;max-width:70ch}
.hl-o-noot b{color:var(--hl-tx)}


/* ═══ CONTACT — stappen en vragen ═══════════════════════════════════════════
   15-09: /contact/ was 189 woorden (kop + formulier) tegenover 492-743 op de
   dienstpagina's. De inhoud komt uit STAPPEN en VRAGEN, niet uit nieuwe tekst.
   ════════════════════════════════════════════════════════════════════════ */
.ct-stappen{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));
  gap:clamp(16px,2vw,30px);margin-top:clamp(26px,3.2vw,44px)}
.ct-s{border-top:1px solid var(--line);padding-top:16px}
.ct-s > span{font-size:var(--fs-micro);color:var(--ac);font-variant-numeric:tabular-nums}
.ct-s h3{font-size:var(--fs-ui);font-weight:400;margin:9px 0 0;color:var(--ink)}
.ct-s p{margin:8px 0 0;font-size:var(--fs-ui);color:var(--ink3);line-height:1.55}
.ct-vragen{display:grid;grid-template-columns:repeat(auto-fit,minmax(272px,1fr));
  gap:clamp(18px,2.2vw,34px);margin-top:clamp(26px,3.2vw,44px)}
.ct-v h3{font-size:var(--fs-ui);font-weight:400;margin:0;color:var(--ac)}
.ct-v p{margin:10px 0 0;font-size:var(--fs-ui);color:var(--ink3);line-height:1.6}
@media(max-width:640px){.ct-stappen,.ct-vragen{grid-template-columns:1fr;gap:0}
  .ct-s,.ct-v{padding-block:16px}}


/* ?schoon=1 — labgereedschap weg voor een opname. Zie boot.js. */
html[data-schoon] .bgbalk,
html[data-schoon] #lab,
html[data-schoon] .plb,
html[data-schoon] .hlb,
html[data-schoon] .phb{display:none!important}


/* Honeypot in het contactformulier: uit beeld, niet uit de DOM.
   Geen display:none — sommige bots vullen juist alleen wat verborgen is via
   die eigenschap. Wel aria-hidden en tabindex=-1, zodat een schermlezer en
   het toetsenbord hem overslaan. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form .ok.fout{color:var(--ac)}
.form .ok.fout a{color:inherit}
.form button[disabled]{opacity:.55;cursor:progress}
