/* Erfverhaal, richting 2 "De brief". Eén stijl voor alle pagina's in website/brief/.
   Kleur komt uit ../../tokens.css, dat elke pagina vóór dit blad laadt; hier staat geen kleurwaarde.
   Tokens volgen website/Tokens.dc.html; oker volgt website/Oker.dc.html (negen plekken, nooit knop, vlak of tekst).
   Secties: kop, opening, tekstsectie, beeldsectie, stappen, oproep, formulier, voet (zie WEBSITE.md). */

@import url("./letters/fonts.css");

:root {
  /* kleur: uit ../../tokens.css, hier geen eigen waarden */

  /* vorm */
  --r-s: 10px;
  --r-m: 14px;
  --r-l: 22px;

  /* het skelet: één kolom, één zijmarge, één maat tussen secties */
  --kolom: 1180px;
  --rand: clamp(20px, 4vw, 56px);
  --sectie: 96px;          /* verticale maat tussen twee secties */
  --sectie-in: 64px;       /* binnenmaat van een vlak van rand tot rand (oproep) */
  --opening-boven: 56px;   /* ruimte boven de opening, onder de kop */
  --raakvlak: 44px;          /* ondergrens voor een tikdoel, WCAG 2.5.5 */
  --bedien-ruimte: 18px;     /* binnenruimte boven en onder in een knop of veld */
  /* DE HOOGTE VAN EEN BEDIENING, en knop en veld landen er allebei op. Uitkomst van de binnenruimte plus de
     regelhoogte van een knoplabel, en nooit onder het tikdoel: 2 x 18 + 16 = 52px. Er stond geen token, en
     daardoor liepen de twee uit elkaar: een knop kwam op 52px uit zijn eigen som, terwijl `input.veld` sinds
     15 september 2026 een vaste `height: var(--raakvlak)` droeg en dus op 44px bleef. Dat verschil van acht
     punten is wat Ernst op 20 september 2026 zag, met een knop naast een e-mailveld. */
  --bedien-hoogte: max(var(--raakvlak), calc(2 * var(--bedien-ruimte) + var(--t-knop)));
  --kop-ruimte: 14px;        /* ruimte boven en onder de inhoud van de kop */
  --kop-hoogte: calc(var(--raakvlak) + 2 * var(--kop-ruimte));   /* uitkomst, geen eis: 72px */
  --kolomgat: 64px;        /* tussen twee kolommen */
  --blok: 32px;            /* tussen kop en inhoud binnen een sectie */
  --regel: 18px;           /* tussen regels binnen een blok */

  /* de typeschaal: elke lettergrootte op de site is een van deze */
  --t-mono-klein: 11px;
  --t-mono: 12px;
  --t-bijschrift: 14px;
  --t-klein: 15px;
  --t-knop: 16px;
  --t-tekst: 17px;
  --t-stap: 18px;
  --t-h3: 19px;
  --t-getal-klein: 22px;
  --t-getal-strook: 30px;     /* het getal in de cijferstrook van de flowkaart */
  --t-lead: var(--t-tekst);   /* een maat voor alle lopende tekst; de opening onderscheidt zich met ruimte en breedte */
  --t-kaft: clamp(18px, 2.2vw, 26px);
  --t-opening-h2: clamp(22px, 2.4vw, 30px);
  --t-oproep-h2: clamp(24px, 2.4vw, 32px);
  --t-h2: clamp(28px, 3.2vw, 38px);
  --t-getal: clamp(36px, 4vw, 52px);
  --t-h1: clamp(30px, 5.2vw, 66px);
  --t-h1-lang: clamp(24px, 3.4vw, 44px); /* een lange H1 die toch op één regel moet */
  --t-h1-kaart: clamp(26px, 4.4vw, 36px); /* de H1 op een flowkaart: hij deelt de kaart met de vraag eronder */
  --t-groot: clamp(64px, 7vw, 92px);

  /* beweging */
  --duur: 900ms;
  --verloop: cubic-bezier(.16, 1, .3, 1);
  --afstand: 48px;
  --stagger: 90ms;
  --lijn-duur: 1600ms;
}
@media (max-width: 1010px) {
  :root { --sectie: 44px; --sectie-in: 40px; --opening-boven: 32px; --kop-ruimte: 8px; --kolomgat: 28px; --blok: 24px; --afstand: 30px; }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: clip; }
body {
  margin: 0;
  background: var(--papier);
  color: var(--diep);
  font-family: 'Atkinson Hyperlegible', system-ui, sans-serif;
  font-size: var(--t-tekst);
  line-height: 1.65;
  color-scheme: light;
  -webkit-font-smoothing: antialiased;
}
/* Links in lopende tekst, 12 september 2026. Ernst vroeg of deze links de zichtbaarheidstoets
   overleven. Antwoord: op contrast wel (kobalt op papier haalt de eis ruim), maar ze waren alleen
   aan hun KLEUR te herkennen, en dat faalt voor wie kleur niet ziet. De contrastpoort mat de
   verkeerde eigenschap: hij meet of tekst leesbaar is, niet of een link opvalt tussen tekst.
   Daarom onderstrepen links in lopende tekst nu. Navigatie, knoppen, kruimelpad en kaartjes zijn
   aan hun vorm en plek te herkennen en houden geen streep. linkpoort.py meet dit. */
a { color: var(--kobalt); text-decoration: underline; text-underline-offset: .18em;
    text-decoration-thickness: from-font; text-decoration-color: var(--wassing); }
a:hover { text-decoration-color: currentColor; }
/* Alles wat zijn eigen vorm heeft draagt geen streep. */
.kop a, .voet a, .knop, .kruimel a, .vraag summary a, .stap a, a.tegel, a.kaart,
.prijsregel .naam a, .menu, nav a { text-decoration: none; }
a:hover { color: var(--diep); }
img, video { display: block; max-width: 100%; }
h1, h2, h3, p, ul { margin: 0; }
ul { padding: 0; list-style: none; }
b, strong { font-weight: 700; }
.nw { white-space: nowrap; }
.wrap { width: min(100% - 2 * var(--rand), var(--kolom)); margin-inline: auto; }
main > .sectie:last-child { padding-bottom: var(--sectie); } /* de oproep sluit direct op de voet aan; een tekstsectie als laatste krijgt de afstand eronder */

/* ---------- letter ---------- */
.kicker { font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--oker-tekst); }
.op-blauw .kicker { color: var(--papier); }   /* gemeten: oker op kobalt haalt 4,16 en dat is onder de eis voor kleine tekst */

/* Tekst op een blauw vlak: de zachte inkt is daar onleesbaar (gemeten 1,01). */
.op-blauw .klein, .op-blauw .tekst, .op-blauw p { color: var(--vlak); }
.op-blauw .h2, .op-blauw .h1 { color: var(--wit); }
/* De koppenregel, 12 september 2026. Ernst vroeg waarom een H3 kobalt was en een H2 van bijna
   dezelfde maat diep. Er was geen reden: kobalt droeg vijf betekenissen tegelijk (H1, H3, link,
   knop, merk) en diep twee. Vanaf nu draagt elke kop diep, en betekent kobalt precies één ding:
   je kunt erop klikken. Het merk in de kop en het logo houden hun eigen kleur.
   Afbreken: H2 en H3 balanceren hun regels (text-wrap: balance), H1 breekt niet af. Dat laatste
   is een besluit van Ernst: "Het Voorouderboek" hoort op één regel. */
.h1 { font: 800 var(--t-h1)/.98 'Archivo', system-ui, sans-serif; letter-spacing: -.032em; color: var(--diep); white-space: nowrap; }
.h1.een-regel { white-space: nowrap; }
.h1.lang { font-size: var(--t-h1-lang); }
@media (max-width: 600px) { .h1.lang { white-space: normal; } } /* een lange H1 past op een telefoon niet op één regel; alleen daar mag hij breken */
.h2 { font: 800 var(--t-h2)/1.06 'Archivo', system-ui, sans-serif; letter-spacing: -.022em; color: var(--diep); text-wrap: balance; }
.h3 { font: 800 var(--t-h3)/1.2 'Archivo', system-ui, sans-serif; letter-spacing: -.01em; color: var(--diep); text-wrap: balance; }
/* Regelafstand 1,65 als elke alinea, sinds 18 september 2026 (Ernst: lopende tekst mag nergens anders zijn opgemaakt;
   infra/poorten/tekstmaat.py weegt het). Tot die dag 1,55: de eerste alinea las strakker dan de rest. */
.lead { font-size: var(--t-lead); line-height: 1.65; max-width: 52ch; }
.tekst { max-width: 62ch; }
.breed-56 { max-width: 56ch; }
.breed-60 { max-width: 60ch; }
.breed-62 { max-width: 62ch; }
/* Geen tekstbreedte: de alinea loopt over de hele kolom. Besluit Ernst,
   15 september 2026, voor de openingsalinea van de voorpagina. */
.breed-vol { max-width: none; }

/* HET BOEK IN EEN DIEP VLAK, 15 september 2026. Ernst: "ik wil het boek in zo'n
   blauw blok met ronde randen hebben staan". De bladeraar stond los op het papier,
   waardoor de bladzijden er niet uitkwamen en de kop erboven los leek te staan. */
/* Lichtblauw en niet diep, sinds 15 september 2026 (Ernst). --vlak is hetzelfde blauw als
   de kaders "In een regel" in het boek zelf, dus het boek ligt op zijn eigen kleur. */
.boekvlak { background: var(--vlak); border-radius: var(--r-l); padding: 28px; }
@media (max-width: 1010px) { .boekvlak { padding: 14px; border-radius: var(--r-m); } }
.kolom.dicht { gap: 10px; }
.klein { font-size: var(--t-klein); line-height: 1.65; color: var(--tekst-zacht); }
.cijfer { font: 800 var(--t-mono)/1.3 'IBM Plex Mono', monospace; color: var(--oker-tekst); letter-spacing: .04em; }
.mono { font: 400 var(--t-mono)/1.5 'IBM Plex Mono', monospace; letter-spacing: .06em; text-transform: uppercase; color: var(--oker-tekst); }
.groot { font: 800 var(--t-groot)/1 'Archivo', system-ui, sans-serif; letter-spacing: -.04em; color: var(--oker); font-variant-numeric: tabular-nums; }
.euro { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; letter-spacing: -.01em; }

/* koppen die per regel binnenkomen: beweging.js splitst in .regel */
.regels .regel { display: block; overflow: hidden; }
.regels .regel > span { display: block; }
.js .regels.klaar .regel > span { transform: translateY(110%); transition: transform calc(var(--duur) + 200ms) var(--verloop); transition-delay: calc(var(--r, 0) * 110ms); }
.js .regels.klaar.in .regel > span { transform: none; }

/* ---------- het merk: wit op blauw, oker op papier, nooit anders ---------- */
.merk { display: inline-flex; align-items: center; }
.merk img { height: 30px; width: auto; }
.merk .wit { display: none; }
.op-blauw .merk .oker { display: none; }
.op-blauw .merk .wit { display: block; }

/* ---------- knop en veld ---------- */
.knop {
  display: inline-flex; align-items: center; justify-content: center;
  /* De hoogte is een uitkomst van binnenruimte plus regelhoogte, geen vast getal: bij een
     ander label of een andere lettermaat kan de ondergrens zo niet verdwijnen. */
  min-height: var(--bedien-hoogte); padding: var(--bedien-ruimte) 26px;
  background: var(--kobalt); color: var(--wit);
  font: 700 var(--t-knop)/1 'Atkinson Hyperlegible', system-ui, sans-serif;
  border-radius: var(--r-m); border: 0; cursor: pointer; white-space: nowrap;
  transition: background 200ms, transform 200ms;
}
.knop:hover { background: var(--diep); color: var(--wit); transform: translateY(-1px); }
.knop--licht { background: var(--wit); color: var(--kobalt); }
.knop--licht:hover { background: var(--papier); color: var(--diep); }

.veld {
  display: flex; align-items: center; min-height: var(--bedien-hoogte);
  /* Een veld draagt een rand en tekst die één punt groter is dan een knoplabel. Zijn
     binnenruimte is daarom 3,5 minder, zodat knop en veld naast elkaar even hoog uitkomen.
     Die 3,5 is gemeten in de browser en niet gerekend: de invoervelden van Chrome tellen hun
     eigen regelbox mee. De hoogte blijft een uitkomst; maatpoort.mjs bewaakt dat beide op
     dezelfde hoogte landen en boven de ondergrens blijven. */
  padding: calc(var(--bedien-ruimte) - 3.5px) 16px; width: 100%;
  appearance: none; -webkit-appearance: none;
  border: 1.5px solid var(--tekst-stil); border-radius: var(--r-m); background: var(--wit);
  font: 400 var(--t-tekst)/1 'Atkinson Hyperlegible', system-ui, sans-serif; color: var(--diep);
  line-height: 1;
}
/* Een keuzelijst en een tekstvak naast of onder elkaar landen op dezelfde hoogte: niet
   via de binnenruimte (die telt in Chrome per soort anders) maar via één vaste hoogte, de
   ondergrens van een tikdoel. Gezien op scherm 2, 15 september 2026: de keuzelijst "Anders"
   en het tekstvak eronder verschilden zichtbaar in hoogte. textarea houdt zijn eigen regel. */
input.veld, select.veld { height: var(--bedien-hoogte); padding-top: 0; padding-bottom: 0; }
.veld::placeholder { color: var(--tekst-stil); }
.veld:focus { outline: none; border: 2px solid var(--kobalt); }
label.etiket { display: block; font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--tekst-zacht); margin-bottom: 10px; }
.knoprij { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.knoprij span { font-size: var(--t-klein); line-height: 1.65; color: var(--tekst-zacht); max-width: 34ch; }
.op-blauw .knoprij span { color: var(--vlak); }
/* Veld en knop staan naast elkaar, overal. Besluit Ernst, 12 september 2026: tot dan zette de
   flow de knop IN de rij en zetten de pagina's hem eronder, twee patronen voor hetzelfde
   onderdeel. De knop hoort in de rij. Onder 560 px is daar geen plek voor en stapelt hij, want
   een knop van 44 px hoog naast een veld van 44 px past niet op een telefoon. */
.naamrij { display: flex; gap: 10px; align-items: stretch; width: 100%; max-width: 560px; }
.naamrij .veld { flex: 1 1 auto; min-width: 0; }
.naamrij .knop { flex: 0 0 auto; white-space: nowrap; }

/* ---------- tegel ---------- */
.tegel { background: var(--wit); aspect-ratio: 1; overflow: hidden; position: relative; border-radius: var(--r-s); }
.tegel img { width: 100%; height: 100%; object-fit: cover; }
.tegel.orn::after, .leeg.orn::after { content: ''; position: absolute; inset: 0; pointer-events: none; background: url(./beeld/orn-oker.png) center / 100% 100% no-repeat; }
.leeg { background: var(--wit); aspect-ratio: 1; border-radius: var(--r-s); position: relative; background-image: radial-gradient(var(--vlak) 1.4px, transparent 1.5px); background-size: 12px 12px; background-position: center; }

/* ---------- de okeren haarlijn tekent zichzelf ---------- */
.lijn { height: 1px; background: var(--lijn-oker); transform-origin: left; }
.js .lijn { transform: scaleX(0); transition: transform var(--lijn-duur) var(--verloop); }
.js .lijn.in { transform: scaleX(1); }
.boven-lijn { position: relative; padding-top: var(--regel); }
.boven-lijn > .lijn { position: absolute; left: 0; right: 0; top: 0; }

/* ---------- onthullen bij scrollen ---------- */
.js .onthul { opacity: 0; transform: translateY(var(--afstand)); transition: opacity var(--duur) var(--verloop), transform var(--duur) var(--verloop); transition-delay: calc(var(--i, 0) * var(--stagger)); }
.js .onthul.tegel, .js .onthul.leeg { transform: translateY(24px) scale(.94); }
.js .onthul.in { opacity: 1; transform: none; }

/* Het breekpunt is 1010 en niet 900, sinds 12 september 2026. Zie beweging.js voor de reden:
   het merkteken kromp mee tot nul bij 901, en met een vast merk loopt de balk over tot 1010.
   smal() in beweging.js draagt hetzelfde getal en die twee horen gelijk te blijven. */

/* ---------- sectie 1: de kop, één op alle pagina's ---------- */
.kop { position: sticky; top: 0; z-index: 20; background: var(--papier); border-bottom: 1px solid var(--lijn); transition: background 400ms, border-color 400ms; }
.kop .wrap { display: flex; align-items: center; justify-content: space-between; height: var(--kop-hoogte); gap: 24px; }
/* De ruimte tussen de onderdelen van de kop: 24 in plaats van 32, 12 september 2026. Met een
   vijfde item erbij (Voorbeeld, naar /het-voorbeeldboek) liep de kop bij 32 px over tussen 901
   en 979 px. Het ontwerpsysteem gaat dezelfde kant op; deze regel loopt daarop vooruit. */
.kop .merk, .kop nav, .kop .knop, .kop .menu { display: flex; align-items: center; gap: 24px; }

/* Het merkteken krimpt niet mee. Zonder deze regel is het een gewoon flexkind van een rij die
   te smal is, en omdat de navlinks white-space: nowrap dragen vangt het merk de hele klap in
   zijn eentje op: gemeten bij 901 px was het 0 van de 128 px breed, dus het logo was weg. Geen
   van onze poorten mat dat, want er liep niets over: de kop paste juist doordat het merk werd
   vernield. Gevonden door de boxsessie op 12 september 2026, die het in hun eigen component
   repareerde en toen zag dat het bij ons ook stond. */
/* RAAKVLAK OOK OP HET MERKTEKEN, 22 september 2026. Dezelfde bevinding als de navlinks
   hieronder: `a.merk` was 94x22 (het beeld, geen letter) op elke breedte boven 1010px, en
   kreeg zijn 44px raakvlak tot nu toe alleen in de smalle media query verderop. Zelfde
   reparatie, zelfde reden: `--kop-hoogte` reserveert de ruimte al, dit vult hem. */
.kop .merk { flex: none; min-height: var(--raakvlak); }
/* RAAKVLAK EN NIET ALLEEN LETTERHOOGTE, 22 september 2026. Deze regel gaf de link zijn eigen
   doosje ter grootte van zijn letter (15px, `line-height: 1` op `--t-klein`), terwijl `.kop .wrap`
   er al `--kop-hoogte` (60-72px) voor reserveert via `align-items: center` op de rij. Het beeld
   klopte dus, het raakvlak niet: een audit van die dag mat 15px hoog op 1024 en 1440px breed,
   ruim onder de 24px van WCAG 2.5.8 en de 44px die dit systeem elders als `--raakvlak` voert
   (zie regel 1029, 1030 en 1443 hierboven, die precies hetzelfde patroon al gebruiken). `min-height`
   plus `inline-flex`/`align-items: center` vult de ruimte die er al stond zonder hem te vergroten:
   de rij blijft `--kop-hoogte`, de tekst blijft op dezelfde plek, alleen het onzichtbare doosje
   eromheen wordt net zo hoog als wat er al gereserveerd was. Dat gold tot vandaag alleen onder
   `html:not(.js) .kop nav a:not(.knop)` hieronder (de val zonder javascript); met javascript, dus
   op bijna elk bezoek, ontbrak hij. */
.kop nav a:not(.knop) { font: 600 var(--t-klein)/1 'Archivo', system-ui, sans-serif; white-space: nowrap; line-height: 1;
  min-height: var(--raakvlak); display: inline-flex; align-items: center; }
.kop nav a.knop { margin-left: 8px; }
.kop .menu { display: none; background: none; border: 0; padding: 8px; cursor: pointer; color: var(--kobalt); line-height: 0; }
/* de kop is dekkend papier met een haarlijn eronder zodra hij over inhoud staat.
   Op de kobalten opening van de voorpagina: doorzichtig, wit merk, lichte links. De kop zelf is op elke
   pagina hetzelfde fragment; de pagina bepaalt zijn kleur via :has, en het script zet .gewisseld zodra de opening voorbij is */
body:has(.opening.op-blauw) .kop:not(.gewisseld) { background: transparent; border-bottom-color: transparent; }
body:has(.opening.op-blauw) .kop:not(.gewisseld) .merk .oker { display: none; }
body:has(.opening.op-blauw) .kop:not(.gewisseld) .merk .wit { display: block; }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) nav a { color: var(--vlak); }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) nav a:hover { color: var(--wit); }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) nav a.knop { color: var(--kobalt); background: var(--wit); }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) nav a.knop:hover { color: var(--diep); background: var(--papier); }
body:has(.opening.op-blauw) .kop:not(.gewisseld) .menu { color: var(--wit); }
html.no-js body:has(.opening.op-blauw) .kop { background: var(--kobalt); }
@media (max-width: 1010px) {
  .kop nav { display: none; }
  .kop .menu { display: inline-flex; }
  /* het menu: een vel van boven in papier, de vier links groot onder elkaar, de knop onderaan */
  .kop.open nav { display: flex; flex-direction: column; align-items: stretch; gap: 0; position: fixed; left: 0; right: 0; top: var(--kop-hoogte); bottom: 0; background: var(--papier); padding: 12px var(--rand) var(--rand); border-top: 1px solid var(--lijn); overflow-y: auto; }
  .kop.open nav a:not(.knop) { padding: 18px 0; font: 800 var(--t-h2)/1.1 'Archivo', system-ui, sans-serif; letter-spacing: -.022em; color: var(--kobalt); border-bottom: 1px solid var(--lijn); }
  .kop.open nav a.knop { margin: auto 0 0; align-self: stretch; }
}

/* ---------- sectie 2: de opening ---------- */
.opening { padding-top: var(--opening-boven); }
/* Het beeld staat in de DOM binnen .woord, tussen de belofte en de uitleg (zie opening() in
   bouw.py). Op breed hoort het rechts, dus daar lost .woord zichzelf op in het raster en krijgt
   het beeld de tweede kolom over alle rijen. Zo is er één volgorde in de DOM en toch twee
   layouts, zonder order: die laat de leesvolgorde en de kijkvolgorde uit elkaar lopen. */
/* Punt 20, Ernst 14 september 2026: op /cadeau stonden het kopje, de kop en de inleiding
   met gaten van zestig pixels uit elkaar, terwijl ze op de productbladzijden tegen elkaar
   staan. De oorzaak is het raster: het boek spant alle rijen, en is het hoger dan de tekst,
   dan wordt die extra hoogte over de tekstrijen verdeeld. `grid-auto-rows: min-content` laat
   elke rij zo hoog zijn als zijn inhoud, en het beeld hangt dan onder de tekst uit in plaats
   van hem uit elkaar te trekken. */
.opening .wrap { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
  column-gap: var(--kolomgat); row-gap: 28px; align-items: start;
  align-content: start; grid-auto-rows: min-content; }
.opening.zonder-beeld .wrap { grid-template-columns: minmax(0, 8fr) minmax(0, 3fr); }
.opening .woord { display: contents; }
.opening .woord > * { grid-column: 1; }
/* Punt 17 en 23: de tekening stond op de product- en cadeaubladzijden ONDER de tekst, als een
   groot wit vierkant met wit ernaast. Dat kwam doordat alleen `.boek` naar de tweede kolom
   werd getild en `.beeldvak` en `.cadeau-beeld` in de eerste bleven staan. Alle drie zijn het
   het beeld van de opening, dus alle drie horen ze rechts. */
.opening .woord > .beeldkolom { grid-column: 2; grid-row: 1 / calc(var(--rijen, 4) + 1); align-self: start; }
/* DE BEELDKOLOM MAG DE TEKSTRIJEN NIET UIT ELKAAR TREKKEN, punt 20 van Ernst. Een element dat
   rijen overspant duwt die rijen uit elkaar zodra het hoger is dan de tekst ernaast. Op
   /cadeau stond het kopje zestig pixels van de kop af en de kop zestig van de inleiding,
   terwijl ze op een productbladzijde tegen elkaar staan; het verschil was de hoogte van de
   kaft. Vandaar dat het beeld uit de rijberekening wordt gehaald: het staat op zijn eigen
   plek rechts en de tekst links zakt weer in elkaar. De breedte volgt de kolomverdeling
   7fr/4fr die hierboven staat, zodat er maar op één plek een verhouding staat.
   Alleen op breed: onder 1010 px stapelt de opening en staat het beeld gewoon in de stroom. */
/* Het beeld zit in een eigen kolomdoos, zodat de positionering op die doos kan en niet op de
   kaft zelf: `.boek` draagt een aspect-ratio en absoluut geplaatste kinderen, en daar hoort
   geen breedteberekening overheen. */
@media (min-width: 1011px) {
  .opening .wrap { position: relative; }
  /* DE SECTIE MOET DE HOOGTE VAN DE KAFT RESERVEREN, 15 september 2026. Ernst zag de kaft over de
     tekst van de volgende sectie liggen op /het-voorouderboek, /producten en /cadeau. Gemeten op
     1440px, /het-voorouderboek: de opening is 377 hoog en loopt tot y=450, de beeldkolom is 551
     hoog en loopt tot y=680. Tweehonderddertig pixels kaft over de tekst eronder.

     Dat is geen losse fout maar de prijs van de twee regels hierboven: `grid-auto-rows: min-content`
     haalt het beeld uit de rijhoogte (punt 20, anders trekt het de tekstrijen uit elkaar) en
     `position: absolute` haalt het helemaal uit de stroom. Allebei terecht, en samen betekenen ze
     dat niets meer hoogte voor het beeld vraagt. Op een bladzijde met veel tekst zie je het niet;
     op een korte wel.

     Hier vraagt de sectie die hoogte alsnog, zonder dat het beeld terug de rijberekening in hoeft.
     De som volgt dezelfde maten die de kaft zelf gebruikt en staat daarom nergens dubbel:
     de wrap is `min(100% - 2 * --rand, --kolom)`, kolom twee is daarvan `4/11` na aftrek van het
     kolomgat, `.boek` is `min(100%, 380px)` bij `aspect-ratio: 3/4`, en er staat 16 + 28 px boven.
     Geen procenten, want een procent in `min-height` slaat op de hoogte van de ouder en niet op de
     breedte; dat is precies de val waar de twee eerdere pogingen in het blok hieronder in liepen. */
  /* PER VORM, want de beeldkolom draagt drie dingen en ze zijn niet even hoog. De eerste versie
     reserveerde overal de hoogte van de kaft; op /audioboek en /cadeau/voor-oma staat daar een
     vierkante tegel van 260 px en dan stond er 291 px leeg papier onder. Gemeten 15 september
     2026 op 1440 px: beeldkolom 260 hoog, reservering 551. Zonder herkenbare vorm reserveert de
     sectie niets, zoals daarvoor. */
  .opening .wrap {
    --kolom-twee: calc((min(100vw - 2 * var(--rand), var(--kolom)) - var(--kolomgat)) * 4 / 11);
    min-height: var(--beeld-hoog, 0px);
  }
  /* De kaft: min(kolom, 380) breed bij 3/4, met 16 + 28 px boven (zie `.opening .boek`). */
  .opening:has(.beeldkolom .boek) .wrap {
    --beeld-hoog: calc(min(var(--kolom-twee), 380px) * 4 / 3 + 16px + 28px);
  }
  /* Het vel: min(kolom, 380) breed op 1 : 1,414 (A2 en de open kalender zijn allebei A-formaat), met 16 + 28 px boven. */
  .opening:has(.beeldkolom .vel) .wrap {
    --beeld-hoog: calc(min(var(--kolom-twee), 380px) * 1.414 + 16px + 28px);
  }
  /* De tegel: min(kolom, 260) breed en vierkant (zie `.beeldvak .tegel`, `.cadeau-beeld .tegel`). */
  .opening:has(.beeldkolom .tegel) .wrap {
    --beeld-hoog: min(var(--kolom-twee), 260px);
  }
  /* De blauwe opening laat de kaft met opzet in de volgende sectie hangen (`margin-bottom: -170px`
     hierboven). Daar hoort die honderdzeventig pixels er dus af, anders reserveert de sectie ruimte
     voor een overhang die de bedoeling is. */
  .opening.op-blauw .wrap { min-height: calc(var(--beeld-hoog, 170px) - 170px); }
  .opening .woord > .beeldkolom {
    /* EEN ABSOLUUT GEPLAATST RASTERELEMENT HEEFT ZIJN EIGEN RASTERVAK ALS REFERENTIE, en dat
       is precies wat hier nodig is: het vak is al kolom 2 over alle rijen. Twee pogingen
       hiervoor rekenden een breedte uit de kolomverdeling en kwamen op zeventig pixels uit,
       omdat 100% daar de kolom was en niet de wrap. Vier nullen is eenduidiger dan een som. */
    position: absolute; inset: 0 0 auto 0;
    display: flex; justify-content: flex-end;
  }
}
@media (max-width: 1010px) { .opening .woord > .beeldkolom { display: flex; justify-content: center; } }
.opening .h2 { max-width: 26ch; }
/* Punt 2: de regel onder de knop hoort bij de knop en niet bij de onderrand. Hij stond op de
   rijafstand van het raster (28 px) van de knop af en tegen het einde van het kobalt aan, en
   las daardoor als een losse voetnoot. Nu tegen de knop, en er komt lucht onder het vlak. */
.opening .knoprij + .klein { margin-top: -18px; }
/* Punt 13: het naamveld in de opening van de voorpagina, in de kleuren van het kobalt. Het
   etiket en de regel eronder staan daar op wit en op --vlak, want --tekst-zacht is op kobalt
   niet te lezen. Het veld zelf is al wit. */
.opening .veldrij { max-width: 40rem; }
.opening .veldrij form { display: flex; flex-direction: column; gap: 8px; }
.opening.op-blauw .veldrij .etiket { color: var(--wit); }
.opening.op-blauw .veldrij .klein { color: var(--vlak); max-width: 52ch; }
.opening.op-blauw { padding-bottom: 40px; }
.opening .boek { justify-self: end; margin-top: calc(16px + 28px); } /* bovenkant boek op de bovenkant van de H1: kicker plus gat */
/* op kobalt (de voorpagina): het boek hangt over de harde rand naar het papier */
.opening.op-blauw { color: var(--wit); background: var(--kobalt); margin-top: calc(-1 * var(--kop-hoogte)); padding-top: calc(var(--kop-hoogte) + var(--opening-boven)); }
/* Besluit Ernst, 12 september 2026: alleen "Het Voorouderboek" draagt op de voorpagina de
   okerkleur. Op het kobaltvlak is dat --oker-op-blauw (#E3AE63); de gewone oker is daar te
   donker. De H2 eronder blijft wit, anders wordt het goud een tweede tekstkleur in plaats van
   een accent op de naam van het boek. */
.opening.op-blauw .h1 { color: var(--oker-op-blauw); }
.opening.op-blauw .h2 { color: var(--wit); }
.opening.op-blauw .lead { color: var(--vlak); }
/* Punt 1, Ernst 14 september 2026: "het boek komt net niet ver genoeg onder de kobalt hero
   sectie uit". Het was 70 px; op een kaft van 380 bij 507 is dat een zevende en dat leest als
   een ongelukje in plaats van als een keuze. Nu een derde van de hoogte. */
.opening.op-blauw .boek { margin-bottom: -170px; }
/* Het boek steekt 70 px onder het blauw uit. Tot 12 september telde de volgende sectie die
   70 px bij haar eigen maat op, en dan stond er 214 px leeg papier waar overal elders 96 px
   staat. Het boek staat rechts en de tekst links, dus ze hoeven elkaar niet te ontwijken:
   de sectie houdt nu gewoon de maat van elke andere sectie. */
.opening.op-blauw + .sectie { padding-top: var(--sectie); }
/* De mobiele uitzondering die hier stond (70 px extra omdat het boek over de eerste alinea
   heen viel) is vervallen: op smal staat het boek nu midden in de opening en steekt het
   nergens meer onderuit. De regel staat in het blok onder 900 px. */
@media (max-width: 1010px) {
  /* Smal: één kolom, en .woord wordt weer een gewone doos, zodat het beeld op zijn plek in de
     DOM valt (na de belofte, voor de uitleg). De maten krimpen mee, anders staat de omslag
     alsnog grotendeels onder de vouw. Gemeten op 390 bij 844. */
  .opening .wrap, .opening.zonder-beeld .wrap { grid-template-columns: 1fr; gap: 0; }
  .opening .woord { display: flex; flex-direction: column; gap: 20px; }
  .opening .woord > *, .opening .woord > .boek { grid-column: auto; grid-row: auto; }
  /* Het boek stak 70 px onder het blauw uit toen het als laatste stond. Nu staat er tekst
     achter, dus die overhang zou over de uitleg heen vallen: op smal geen overhang, en de
     volgende sectie hoeft er dan ook niet meer voor uit te wijken. */
  .opening.op-blauw .boek { margin-bottom: 0; }
  .opening.op-blauw + .sectie { padding-top: var(--sectie); }
  .opening .woord { padding-bottom: 8px; }
  /* PUNT P2 VAN DE MOBIELE OPMERKINGEN, 14 september 2026. Ernst: "De hero toont geen boek
     meer, alleen tekst plus het naamveld. Er moet een oplossing komen zodat het boek
     zichtbaar blijft op home."

     DE OORZAAK, en het is een as die van betekenis wisselt. `.beeldkolom` draagt
     `align-self: start`, gezet voor het RASTER op breed: daar is dat de verticale as en zorgt
     het dat de kaft bovenaan zijn kolom blijft staan. Onder 1010px wordt `.woord` een
     flexkolom, en in een flexkolom is align-self de HORIZONTALE as: `start` betekent dan
     krimp naar je inhoud. De inhoud is `.boek`, en dat is `width: min(100%, 300px)` van een
     ouder die op dat moment nul breed is. Gemeten op 500px: beeldkolom 0x0, boek 0x0, kaft
     0x0. Niets te zien, en aan geen van de regels af te lezen.

     Op smal dus weer uitrekken. Het boek staat dan waar het in de DOM staat: na de belofte en
     voor de uitleg. */
  .opening .woord > .beeldkolom { align-self: stretch; }
  .opening .boek { justify-self: center; width: min(100%, 300px); margin-top: 0; }
  /* OP SMAL DRIJFT HET BOEK NIET, 19 september 2026. beweging.js schuift `.opening .boek .drijf`
     bij het scrollen omhoog, twaalf procent van de scrolafstand. Op breed staat het boek naast de
     tekst en is dat een lichte beweging. Op smal staat het in de stroom ONDER de tekst, en op
     /producten staat daar sinds de deluxe (#732) een prijsblok van vier regels boven: wie tot het
     boek scrolt, heeft zo'n 600 px gescrold en ziet de kaft 70 px over "Bekijk" en de maat heen
     schuiven (Ernst, iPhone, 19 september 2026). Dezelfde fout als in de kostkaart hieronder, en
     dezelfde oplossing: deze regel wint van de inline transform, welke beweging.js Safari ook
     vasthoudt. */
  .opening .boek .drijf { transform: none !important; }
  /* Het boek steekt 70 px onder het blauw uit. Tot 12 september telde de volgende sectie die
   70 px bij haar eigen maat op, en dan stond er 214 px leeg papier waar overal elders 96 px
   staat. Het boek staat rechts en de tekst links, dus ze hoeven elkaar niet te ontwijken:
   de sectie houdt nu gewoon de maat van elke andere sectie. */
.opening.op-blauw + .sectie { padding-top: var(--sectie); }
/* De mobiele uitzondering die hier stond (70 px extra omdat het boek over de eerste alinea
   heen viel) is vervallen: op smal staat het boek nu midden in de opening en steekt het
   nergens meer onderuit. De regel staat in het blok onder 900 px. */
}

/* ---------- het boek als voorwerp (letterlijk uit het prototype) ---------- */
.boek { position: relative; width: min(100%, 380px); aspect-ratio: 3 / 4; will-change: transform; }
.boek .drijf { position: absolute; inset: 0; will-change: transform; }
.boek .kaft { position: absolute; inset: 0; border-radius: 4px var(--r-m) var(--r-m) 4px; overflow: hidden; background: var(--wit); box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 24px 60px -30px rgba(18, 50, 92, .35); }
.boek .kaft img { width: 100%; height: 100%; object-fit: cover; }
.boek .rug { position: absolute; left: 0; top: 0; bottom: 0; width: 10px; background: linear-gradient(90deg, rgba(18, 50, 92, .22), rgba(18, 50, 92, 0)); border-radius: 4px 0 0 4px; pointer-events: none; }
.boek .titel { position: absolute; left: 8%; right: 8%; top: 7.5%; display: flex; flex-direction: column; gap: 6px; }
/* Punt 7, Ernst 14 september 2026: op de kaft stond ERFVERHAAL in okeren kapitalen, en dat
   hoort het hele merk te zijn: het boekje plus het woordmerk, zoals op het omslag dat hij
   naast de site legde. De maat hangt aan de kaft en niet aan een vast getal, zodat het
   merkteken meeschaalt met de miniatuur in een prijsregel en met de grote kaft op de
   voorpagina. */
.boek .titel .k { display: block; width: 46%; height: auto; }
.boek .titel .t { font: 800 var(--t-kaft)/1 'Archivo', system-ui, sans-serif; letter-spacing: -.03em; color: var(--diep); white-space: nowrap; }
/* De regel eronder is dezelfde als op de echte omslag (boek/omslag.html): wiens voorouders het
   boek beschrijft. Zonder die regel toont de mockup een boek zonder familie erin. */
/* De regel schaalt mee met de kafttitel. Met een vaste 11 px liep hij op een kleine kaft over
   de tekening heen en brak "Tiel" naar een derde regel. */
.boek .titel .voor { font-size: calc(var(--t-kaft) * .4); line-height: 1.4;
  color: var(--tekst-zacht); margin-top: .35em; text-wrap: balance; }
.boek .titel .voor b { font-weight: 700; color: var(--diep); }
/* DE KAFT OP DE SITE MOET DE KAFT VAN HET BOEK ZIJN, 15 september 2026. Ernst: "de tekst op de
   kaft van het boek staat nog niet zoals op de echte cover van het boek". Drie verschillen met
   boek/omslag-v2.html, alle drie hier en in bouw.py rechtgezet.

   De streep. Op de omslag is hij 72px breed en staat hij tussen de titel en de regel eronder
   (.voor__streep, delft.css:273). Hier lag hij als een volle lijn over de onderrand van de
   kaft. De maten zijn verhoudingen van de kaftbreedte, want de omslag is 794px breed en deze
   kaft is dat nooit: 72/602 van de tekstkolom is 12%.

   De kerngetallen. De omslag draagt er vijf op een lichte plaat onderaan (.voor__kern,
   delft.css:276). Die ontbraken hier helemaal. De maten volgen dezelfde verhoudingen:
   links en rechts 72/794 = 9%, onder 56/1123 = 5%, het getal 22/52 en het woordje 12.5/52 van
   de kafttitel.

   Op een miniatuur, zoals in een prijsregel, is die plaat onleesbaar. De containervraag weegt
   de werkelijke breedte van de kaft en niet de plek waar hij staat, zodat er geen lijst van
   uitzonderingen ontstaat die bij de volgende plaatsing weer achterloopt. */
.boek .titel .streep { display: block; width: 12%; height: 2px; background: var(--oker); margin: .3em 0 .1em; }
.boek .kern { position: absolute; left: 9%; right: 9%; bottom: 5%;
  /* De plaat is het papier van de site. De omslag zet hier rgba(247,245,239,.92) neer; dat is
     --papier op 92 procent. Hier staat hij dekkend, want componentpoort weegt de GEREKENDE
     kleur in de browser, en die is bij elke doorzichtigheid een getal dat niet in tokens.css
     staat, ook bij een color-mix op een token. Op een kaft van hoogstens 380 px is het verschil
     tussen 92 en 100 procent dekking niet te zien; een kleur buiten het stelsel wel. */
  background: var(--papier);
  border-radius: calc(var(--t-kaft) * .27);
  padding: calc(var(--t-kaft) * .31) calc(var(--t-kaft) * .5);
  display: flex; justify-content: space-between; align-items: baseline; gap: calc(var(--t-kaft) * .2); }
.boek .kern .g { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.boek .kern .g b { font: 800 calc(var(--t-kaft) * .42)/1 'Archivo', system-ui, sans-serif;
  /* --oker-tekst en niet --oker (17 september 2026): op de kaft van de site staan deze cijfers op 7,5
     tot 11 px, en --oker op papier haalt 3,81:1 waar AA 4,5:1 eist; de kleurpoort was er rood op. */
  color: var(--oker-tekst); letter-spacing: -.01em; white-space: nowrap; }
.boek .kern .g b i { font-style: normal; font-weight: 400; }
.boek .kern .g--plaats b { color: var(--diep); }
.boek .kern .w { font: 700 calc(var(--t-kaft) * .24)/1.2 'Atkinson Hyperlegible', system-ui, sans-serif;
  letter-spacing: .14em; text-transform: uppercase; color: var(--kobalt); margin-top: .3em; white-space: nowrap; }
.boek { container-type: inline-size; }
@container (max-width: 220px) { .boek .kern { display: none; } }
.js .boek { opacity: 0; transform: translateY(24px) scale(.985); transition: opacity 1100ms var(--verloop) 150ms, transform 1100ms var(--verloop) 150ms; }
.js .boek.in { opacity: 1; transform: none; }

/* ---------- sectie 3 en 4: tekstsectie en beeldsectie delen het ritme ---------- */
.sectie { padding-top: var(--sectie); display: flex; flex-direction: column; gap: var(--blok); }
.kolom { display: flex; flex-direction: column; gap: var(--regel); }
.kolom > * { min-width: 0; max-width: 100%; }
.twee { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--kolomgat); align-items: start; }
@media (max-width: 1010px) { .twee { grid-template-columns: minmax(0, 1fr); } }
/* Punt 5: de kolommen stonden op 2fr tegen 3fr, dus links brak over drie regels en rechts
   over twee. Ze dragen hetzelfde soort tekst en horen dus even breed te zijn. */
.brief .vork { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.brief .vork > div { display: flex; flex-direction: column; gap: 10px; padding-top: 0; }
/* De cadeau-ingangen als kaart. Het hele blok is de link, dus er hoeft nergens een woord
   onderstreept te worden om te laten zien dat je kunt klikken. Zelfde vorm als .pkaart. */
.vork { display: grid; gap: var(--kolomgat); grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.vorkkaart { display: flex; flex-direction: column; gap: 8px; padding: 20px;
  background: var(--wit); border-radius: var(--r-m); text-decoration: none;
  box-shadow: 0 1px 0 rgb(18 50 92 / .08), 0 12px 28px -22px rgb(18 50 92 / .35);
  transition: transform 200ms, box-shadow 200ms; }
.vorkkaart:hover { transform: translateY(-2px); box-shadow: 0 1px 0 rgb(18 50 92 / .10), 0 18px 34px -22px rgb(18 50 92 / .45); }
.vorkkaart .h3 { color: var(--kobalt); }
.vorkkaart p { color: var(--tekst-zacht); font-size: var(--t-klein); line-height: 1.65; }
@media (max-width: 1010px) { .brief .vork { grid-template-columns: 1fr; } }
.prijs { display: flex; align-items: baseline; gap: 8px; }
.feiten { display: flex; flex-direction: column; gap: 14px; }
.feiten li { display: grid; grid-template-columns: 96px 1fr; gap: 16px; align-items: baseline; font-size: var(--t-klein); }
.feiten li b { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; color: var(--oker); letter-spacing: -.02em; }

/* beeldsectie: de film, een klein vlak midden op de pagina, loopt vanzelf */
.reis { background: linear-gradient(var(--papier), var(--wit) 25%, var(--wit) 75%, var(--papier)); margin-top: 0; padding-top: var(--sectie); padding-bottom: 0; }
/* De houder reserveert de hoogte met aspect-ratio, zodat er niets verspringt terwijl de film laadt. */
.reis .film { position: relative; width: min(100% - 2 * var(--rand), var(--kolom)); aspect-ratio: 16 / 9; margin-inline: auto;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent), linear-gradient(transparent, #000 8%, #000 90%, transparent); -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent), linear-gradient(transparent, #000 8%, #000 90%, transparent); mask-composite: intersect; }
/* Het eerste beeld staat hier en niet in het attribuut poster: een poster is één bestand voor elk
   scherm, en op een telefoon is dat 184 kB tegen 52. Zo krijgt de telefoon poster-mobiel.jpg en de
   rest poster.jpg, zonder javascript, en staat het beeld er voordat de film een frame heeft. */
/* De knop die de film stilzet. Hij hangt in de hoek van het beeld, niet erover: de regel dat er
   geen tekst over het beeld komt blijft staan, en een bediening is geen tekst. Zonder javascript
   staat hij er niet, want dan doet hij niets. */
.filmknop { display: none; }
/* Sinds 15 september 2026 is dit dezelfde knop als het afspelen van een stem in de flow en de
   pijlen van de bladeraar: `.ikoonknop` hieronder. Alleen zijn plek in de hoek van het beeld is
   van hem. (Ernst, Comments 2: "pause en play moet 1 figuur zijn dat afwisselt, ook bij de
   animatie, zelfde stijl".) */
.js .filmknop { position: absolute; right: 10px; bottom: 10px; z-index: 2; }
.filmknop__aan { display: none; }
.filmknop[aria-pressed="true"] .filmknop__uit { display: none; }
.filmknop[aria-pressed="true"] .filmknop__aan { display: inline; }
.reis video { width: 100%; height: 100%; object-fit: cover; background: var(--wit) url(./beeld/poster.jpg) center / cover no-repeat; }
@media (max-width: 700px) { .reis video { background-image: url(./beeld/poster-mobiel.jpg); } }
@media (max-width: 1010px) { .reis .film { width: min(100% - 2 * var(--rand), 480px); } }

/* De kop boven de film en de regel eronder. Ernst, 12 september 2026: de film stond zonder context
   op de pagina. De regel blijft dat er geen tekst OVER het beeld komt; deze staat erboven en
   eronder. Eerst stonden er vier tijdvakken naast elkaar, maar vier kolommen maken drie nieuwe
   uitlijnlijnen en de layoutpoort staat er hoogstens twee toe. Nu is het één regel op de kolom. */
.reis .wrap:first-child { margin-bottom: calc(var(--sectie) * .5); }
.reis .wrap:last-child { padding-top: 22px; padding-bottom: 0; }
.reis .wrap:last-child .tekst { color: var(--tekst-zacht); max-width: var(--leesbreedte, 62ch); }

/* beeldsectie: bladeren, de bladen uit het boek. De strook zit in een kader van kolombreedte en komt daar nooit buiten.
   Standaard (zonder script, op een telefoon, bij minder beweging) veegt u het kader. */
.bladeren .plak { display: flex; flex-direction: column; gap: var(--blok); }
.bladeren .plak > * { min-width: 0; }
.bladeren .kader { overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.bladeren .kader::-webkit-scrollbar { display: none; }
.bladeren .strook { display: flex; gap: 28px; width: max-content; }
.bladeren .blad { flex: none; width: min(78vw, 320px); display: flex; flex-direction: column; gap: 10px; scroll-snap-align: start; }
.bladeren .blad img { width: 100%; height: auto; aspect-ratio: 495 / 700; object-fit: cover; background: var(--wit); border-radius: 4px; box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 20px 50px -30px rgba(18, 50, 92, .35); }
.bladeren .blad p { font-size: var(--t-klein); line-height: 1.65; color: var(--tekst-zacht); }
.bladeren .blad .nummer { font: 800 var(--t-mono)/1.3 'IBM Plex Mono', monospace; color: var(--oker-tekst); letter-spacing: .06em; }
.bladeren .lat { position: relative; height: 1px; background: var(--lijn-oker); }
.bladeren .lat .vol { position: absolute; left: 0; top: 0; height: 1px; background: var(--oker); width: 0; }
/* breed en bewegend: de sectie zet zich vast op precies één schermhoogte en de scroll schuift alleen de strook */
.js .bladeren.breed { display: block; padding-top: 0; margin-top: var(--sectie); }
.js .bladeren.breed .plak { position: sticky; top: 0; height: 100vh; padding-top: var(--kop-hoogte); display: flex; flex-direction: column; justify-content: center; gap: var(--blok); overflow: hidden; }
.js .bladeren.breed .kader { overflow: hidden; scroll-snap-type: none; }
.js .bladeren.breed .strook { will-change: transform; }
.js .bladeren.breed .blad { width: calc(52vh * 495 / 700); }

/* beeldsectie: drie tegels met tekst */
.drie { display: flex; flex-direction: column; gap: var(--regel); }
/* De linkerkolom is zo breed als het beeld en niet tweevijfde van de rij, 15 september 2026.
   Ernst: "nu zit er nog enorm veel whitespace tussen de tekst en het plaatje". Dat gat was
   niet het kolomgat maar de kolom zelf: 2fr breed met een tegel van 120px erin. */
.drie > div { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 10px 28px; align-items: start; padding-top: var(--regel); border-top: 1px solid var(--lijn); }
.drie .tegel { width: 120px; }
/* DE TITEL BOVEN BEELD EN TEKST, EN GEEN WIT VLAK, 19 september 2026. Ernst op zijn iPhone: de
   titel staat over de volle breedte boven het blok, daaronder beeld links en tekst rechts. De
   tekeningen zijn png's met alfa, dus de tegel draagt hier geen ondergrond en geen ronde hoek. */
.drie > div > .h3 { grid-column: 1 / -1; margin: 0; }
.drie .tegel { background: none; border-radius: 0; }
.drie .tegel img { object-fit: contain; }
/* PUNT P5 EN P6, 14 september 2026. Hier stond dat dit blok onder 1010px naar EEN kolom gaat,
   en dat maakte van elk van de drie uitlegblokken een stapel van beeld, titel en een alinea
   van vijf regels. Ernst: "De akten, De plaatsen, De beroepen ... zijn te hoog" en "de tekst
   hoort rechts van de afbeelding en de titel".

   Het blijven dus twee kolommen, ook op een telefoon: links het beeld met de titel eronder,
   rechts de tekst. De tegel krimpt mee, want 120px naast een tekstkolom van 330 laat te
   weinig over om te lezen. Gemeten op 500px: het blok is ongeveer de helft korter. */
@media (max-width: 1010px) {
  .drie > div { grid-template-columns: minmax(96px, 34%) minmax(0, 1fr); column-gap: 18px; }
  .drie .tegel { width: 100%; max-width: 120px; }
}

/* beeldsectie: de kwartierstaat die zich vult */
.zoekrij { display: flex; flex-direction: column; align-items: flex-start; }
.telling { display: flex; gap: 48px; flex-wrap: wrap; }
.telling > p { display: flex; flex-direction: column; gap: 4px; }
.telling b { font: 800 var(--t-getal)/1 'Archivo', system-ui, sans-serif; color: var(--oker); letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.telling span { font-size: var(--t-klein); }
.wand { background: var(--kobalt); border-radius: var(--r-l); padding: clamp(14px, 2.4vw, 28px); }
.zoekwand .wrap { display: flex; flex-direction: column; gap: var(--blok); }
.wand .rij { display: grid; gap: 6px; }
.wand .rij.acht { grid-template-columns: repeat(8, minmax(0, 1fr)); }
.wand .rij.vier { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.wand .rij.twee { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wand .rijnaam { font: 400 var(--t-mono)/1.3 'IBM Plex Mono', monospace; letter-spacing: .12em; text-transform: uppercase; color: var(--vlak); margin: 14px 0 8px; }
.wand .rijnaam:first-child { margin-top: 0; }
.wand .kaart { position: relative; aspect-ratio: 1; perspective: 1200px; }
.wand .kaart .zijden { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform 1100ms var(--verloop); }
.wand .kaart .zijde { position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden; border-radius: var(--r-s); overflow: hidden; }
.wand .kaart .zijde .tegel, .wand .kaart .zijde .leeg { width: 100%; height: 100%; border-radius: var(--r-s); }
.wand .kaart .voor { transform: rotateY(180deg); }
.wand .kaart .voor.orn::after { content: ''; position: absolute; inset: 0; background: url(./beeld/orn-oker.png) center / 100% 100% no-repeat; pointer-events: none; }
.wand .kaart .naam { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 10px 8px; font: 700 var(--t-mono)/1.2 'Atkinson Hyperlegible', system-ui, sans-serif; color: var(--wit); background: linear-gradient(rgba(18, 50, 92, 0), rgba(18, 50, 92, .92)); border-radius: 0 0 var(--r-s) var(--r-s); }
.wand .rij.acht .naam { display: none; }
.wand .rij.twee .naam { font-size: var(--t-bijschrift); padding: 18px 12px 10px; }
@media (max-width: 600px) { .wand .rij.vier .naam { display: none; } }
.wand .kaart.om .zijden { transform: rotateY(180deg); }
/* Gevonden is gevonden, altijd. Dit hing tot 12 september 2026 aan .no-js, en dat beschermt
   tegen "geen javascript" maar niet tegen "javascript werkt en beweging.js niet". Die wortelklasse
   wordt gezet door een inline script dat altijd slaagt; beweging.js is een apart bestand dat kan
   uitblijven of eerder kan omvallen. Gemeten met dat bestand geblokkeerd: acht tegels droegen
   gevonden, nul waren omgedraaid, en de teller zei 8 van 14. Acht gevonden en niets te zien, en
   dat is geen leeg scherm maar een tegenspraak.
   Nu is de omgedraaide kant de standaard en zet beweging.js zelf de klasse .telt op de wand om
   ze tijdelijk terug te zetten. Alleen een levend script kan die toestand dus maken, en datzelfde
   script telt hem meteen terug. Gevonden door de boxsessie. */
.wand .kaart.gevonden .zijden { transform: rotateY(180deg); }
.wand.telt .kaart.gevonden .zijden { transform: none; }
.wand.telt .kaart.gevonden.om .zijden { transform: rotateY(180deg); }

/* beeldsectie: de parade, de enige beweging die versiering mag zijn */
.wachten .wrap { display: flex; flex-direction: column; gap: var(--regel); }
.parade { background: var(--vlak); border-radius: var(--r-l); padding: 28px 0; overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.parade .strook { display: flex; gap: 14px; width: max-content; animation: parade 46s linear infinite; }
.parade .tegel { width: 132px; flex: none; }
@keyframes parade { to { transform: translateX(-50%); } }
.voortgang { display: flex; flex-direction: column; gap: 10px; max-width: 560px; }
.voortgang b { font: 800 var(--t-getal)/1 'Archivo', system-ui, sans-serif; color: var(--oker); letter-spacing: -.03em; }
.voortgang .staaf { height: 1px; background: var(--lijn-oker); position: relative; }
.voortgang .staaf i { position: absolute; left: 0; top: 0; height: 1px; background: var(--oker); width: 21%; }

/* beeldsectie: cadeau, tekst naast één tegel */
.cadeau-beeld { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: var(--kolomgat); align-items: center; }
/* Kleiner dan het boek en rechts uitgelijnd, want het is een tekening bij de tekst en niet
   het product zelf. 320 px gecentreerd was op een breed scherm bijna de halve kolom. */
.cadeau-beeld { justify-self: end; }
.cadeau-beeld .tegel { width: min(100%, 260px); }
@media (max-width: 1010px) { .cadeau-beeld { grid-template-columns: 1fr; } }

/* ---------- sectie 5: de stappen ---------- */
.stappen { display: flex; flex-direction: column; gap: var(--regel); }
.stap { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 10px var(--kolomgat); align-items: start; }
.twee .kolom .stap { grid-template-columns: minmax(0, 1fr); }
.stap .t { font: 800 var(--t-h3)/1.2 'Archivo', system-ui, sans-serif; letter-spacing: -.01em; }
@media (max-width: 1010px) { .stappen { gap: 24px; } .stap { grid-template-columns: minmax(0, 1fr); } }

/* ---------- sectie 6: de oproep met naamveld, op papier; kobalt is alleen de opening en de knoppen ---------- */
.oproep .kolom { max-width: 62ch; }
.oproep .naamrij { margin-top: 4px; }

/* ---------- sectie 7: het formulier (de flow) ---------- */
.formulier .kolom { max-width: 640px; }
.formulier .velden { display: flex; flex-direction: column; gap: var(--regel); }

/* de flow: twee schermen op één pagina; het script toont er één */
.js .scherm[hidden] { display: none; }
.scherm-naam { font: 400 var(--t-mono-klein)/1 'IBM Plex Mono', monospace; letter-spacing: .12em; text-transform: uppercase; color: var(--oker-tekst); border-top: 1px solid var(--lijn); padding-top: 24px; }
.js .scherm-naam { display: none; }

/* ---------- sectie 8: de voet, één op alle pagina's ---------- */
.voet { background: var(--diep); color: var(--wit); padding-block: var(--sectie-in) 40px; }
.voet .kols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 32px; }
@media (max-width: 1010px) { .voet .kols { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.voet .kols p { font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--wassing); margin-bottom: 10px; }
.voet a { color: var(--wit); display: block; font-size: var(--t-klein); margin-top: 8px; }
.voet a:hover { color: var(--vlak); }
.voet .melden { display: flex; flex-direction: column; gap: 10px; max-width: 640px; border-top: 1px solid var(--lijn-oker-op-diep); margin-top: 44px; padding-top: 24px; }
.voet .melden .t { font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--wassing); }
.voet .melden .regel, .voet .melden .etiket { color: var(--wit); }
.voet .melden .klein { color: var(--wassing); }
.voet .melden .naamrij { margin-block: 4px; }
.voet .onder { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; border-top: 1px solid var(--lijn-oker-op-diep); margin-top: 44px; padding-top: 24px; }
/* ZELFDE RAAKVLAK, ZELFDE PLEK GEMIST, 22 september 2026. Het voetmerkteken (94x22, `.merk img`
   hierboven op vaste 22px) had zijn 44px tot nu toe ook alleen onder 1010px (regel verderop);
   web-audit vond hem op /index, /producten en de rest op 1024 en 1440px. */
.voet .onder .merk { margin: 0; min-height: var(--raakvlak); }
.voet .onder .merk img { height: 22px; }
.voet .onder .mono { color: var(--wassing); text-transform: none; letter-spacing: 0; }

/* ---------- minder beweging: alles staat stil en de pagina is compleet ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .onthul, .js .boek, .js .lijn, .js .regels.klaar .regel > span { opacity: 1; transform: none; transition: none; }
  .kop { transition: none; }
  .js .bladeren.breed { height: auto; }
  .js .bladeren.breed .plak { position: static; height: auto; }
  .js .bladeren.breed .kader { overflow-x: auto; }
  .parade .strook { animation: none; }
  .wand .kaart .zijden { transition: none; }
  .knop { transition: none; }
}

/* ---------- stilstaand voor een schermafdruk: ?stil in de url, beweging.js zet html.stil ---------- */
html.stil { scroll-behavior: auto; }
html.stil.js .onthul, html.stil.js .boek, html.stil.js .lijn, html.stil.js .regels.klaar .regel > span { opacity: 1; transform: none; transition: none; }
html.stil .kop { transition: none; }
html.stil.js .bladeren.breed { height: auto; }
html.stil.js .bladeren.breed .plak { position: static; height: auto; }
html.stil.js .bladeren.breed .kader { overflow-x: auto; }
html.stil .parade .strook { animation: none; }
html.stil .wand .kaart .zijden { transition: none; }

/* ---------- componenten voor de tekstpagina's (uit de oude site, woordelijk) ---------- */
.kruimel { display: flex; flex-wrap: wrap; gap: 8px; font: 400 var(--t-klein)/1.65 'Atkinson Hyperlegible', system-ui, sans-serif; color: var(--tekst-zacht); }
.kruimel .streep { color: var(--tekst-stil); }
.kruimel span:last-child { color: var(--diep); }
.lijst { display: flex; flex-direction: column; gap: 10px; padding-left: 0; max-width: 62ch; }
.lijst li { position: relative; padding-left: 22px; }
.lijst li::before { content: ''; position: absolute; left: 0; top: .62em; width: 8px; height: 8px; border-radius: 50%; background: var(--oker); }
ol.lijst { counter-reset: li; }
ol.lijst li::before { content: counter(li) '.'; counter-increment: li; background: none; width: auto; top: 0; font: 800 var(--t-klein)/1.65 'IBM Plex Mono', monospace; color: var(--oker-tekst); }
/* Het vlak steekt links en rechts even ver buiten de tekstkolom uit (28px), zodat de tekst erin
   op dezelfde x begint en eindigt als de tekst erbuiten. De breedte moet er expliciet bij staan en
   het vlak moet de kolomregel overstemmen: `.kolom > * { max-width: 100% }` verderop hield het vlak
   even breed als de kolom, terwijl de negatieve marge het 28px naar links schoof. Daardoor stak het
   links 28px uit en viel het rechts 28px binnen de kolom, en was de tekst erin 56px smaller dan de
   tekst erbuiten. Gemeten aan de x van de tekst binnen en buiten het vlak, niet op het oog. */
.vlak-blok, .kolom > .vlak-blok { background: var(--vlak); border-radius: var(--r-l); padding: 24px 28px; margin-inline: -28px; width: calc(100% + 56px); max-width: calc(100% + 56px); display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 1010px) { .vlak-blok, .kolom > .vlak-blok { margin-inline: 0; width: 100%; max-width: 100%; padding-block: 18px; } }

.vraag { max-width: 62ch; border-bottom: 1px solid var(--lijn); }
.vraag summary { cursor: pointer; list-style: none; padding: 14px 32px 14px 0; position: relative; font: 800 var(--t-h3)/1.2 'Archivo', system-ui, sans-serif; letter-spacing: -.01em; color: var(--diep); }
.vraag summary::-webkit-details-marker { display: none; }
.vraag summary::after { content: '+'; position: absolute; right: 0; top: 10px; font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; color: var(--oker); }
.vraag[open] summary::after { content: '\2212'; }
.vraag summary:focus-visible { outline: 2px solid var(--kobalt); outline-offset: 4px; border-radius: var(--r-s); }
.vraag .antwoord { padding: 0 0 18px; }
.vork { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--kolomgat); }
.twee .kolom .vork { grid-template-columns: minmax(0, 1fr); gap: var(--blok); } /* een vork in de rechterkolom maakt geen derde lijn */
.vork > div { display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 1010px) { .vork { grid-template-columns: 1fr; } }
.beeldvak { display: flex; justify-content: flex-end; }
.beeldvak { justify-self: end; }
.beeldvak .tegel { width: min(100%, 260px); }
/* HET VEL, sinds 18 september 2026 (Ernst: de productafbeelding van de poster was niet aantrekkelijk en de kalender
   toonde geen voorbeeld). De poster en de kalender staan als heel product op de bladzijde, zo groot als de kaft
   van het boek: het vel van A2, of de kalender zoals hij open hangt (beeldpagina boven, maandpagina onder, A3).
   Het beeld komt uit wat de motor voor de voorbeeldfamilie maakte (beeld/boek/poster.jpg, beeld/boek/kalender.jpg);
   een haarlijn eromheen, geen schaduw, geen kader, op het papier van de site. */
.vel { aspect-ratio: 1 / 1.414; border: 1px solid var(--lijn); background: var(--wit); overflow: hidden; }
.vel img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top; padding: 0; }
.beeldvak .vel { width: min(100%, 380px); margin-top: calc(16px + 28px); }
/* in een prijsregel naast de naam, zo breed als de tegel; op een productkaart vult het vel het beeldvak (4:3, de
   bovenkant van het vel) zonder de lucht die een tekening daar krijgt */
.prijsregel .tegelklein .vel { width: 96px; }
.pkaart__beeld.vel { aspect-ratio: 4 / 3; border: 0; border-bottom: 1px solid var(--lijn); }
.pkaart__beeld.vel img { object-fit: cover; object-position: top; padding: 0; }
@media (max-width: 1010px) { .beeldvak .vel { width: min(100%, 300px); margin-top: 0; } }
@media (max-width: 1010px) { .opening .boek { margin-top: 0; } .beeldvak { justify-content: center; } .beeldvak .tegel { width: min(100%, 300px); } }
.raster-drie { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--kolomgat); }
@media (max-width: 1010px) { .raster-drie { grid-template-columns: 1fr; gap: 32px; } }
.product { display: flex; flex-direction: column; gap: 8px; color: var(--diep); }
.product:hover { color: var(--diep); }
.product .h3 { margin-top: 6px; }
.product .prijs-klein { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; color: var(--oker); letter-spacing: -.02em; }
.prijs-klein span { display: block; font: 400 var(--t-klein)/1.65 'Atkinson Hyperlegible', system-ui, sans-serif; color: var(--tekst-zacht); margin-top: 4px; letter-spacing: 0; }
.drie-stappen { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1010px) { .drie-stappen { grid-template-columns: 1fr; } }
/* juridisch: één kolom van 62 tekens, genummerde secties, inhoudsopgave bovenaan */
.sectie.jur { padding-top: var(--blok); gap: 12px; }
.jur p, .jur .lijst, .jur .tabel { max-width: 62ch; }
.inhoud ol { counter-reset: none; display: flex; flex-direction: column; gap: 2px; padding-left: 0; list-style: none; }
/* RAAKVLAK, 22 september 2026. Elke link hier was alleen zijn eigen letterhoogte (15-21px, al
   op telefoonbreedte) met niets eromheen: anders dan de kop hierboven had deze lijst nooit ruimte
   voor een raakvlak gereserveerd. `min-height: var(--raakvlak)` plus `inline-flex`/`align-items:
   center` geeft de link zelf de 44px, en `gap` op `.inhoud ol` gaat van 6 naar 2px zodat de hele
   lijst niet veel langer wordt dan hij al was: de ruimte kwam uit het raakvlak, niet uit een
   grotere lijst. Geldt op elke bladzijde met een `.inhoud`-nav: voorwaarden, privacy, herroeping,
   cadeau, producten, het-voorouderboek. */
.inhoud a { font-weight: 700; display: inline-flex; align-items: center; min-height: var(--raakvlak); }

/* ---------- de flow (maak/): velden, feitenrijen, keuzes, de boom ---------- */

/* De zoekplaat: vier vlakken die om beurten oplichten terwijl de motor leest. Geen
   voortgangsbalk met een einde, want een klim weet niet hoeveel generaties er nog komen; een
   balk die naar een eind kruipt dat niemand kent, is een belofte. Overgezet uit het oude
   site.css (ev-proces__plaat) op 15 september 2026, nu in de tokens van de site. */
.zoekplaat { --plaat-duur: 2.4s; display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px; height: 6px; width: min(100%, 240px); }
.zoekplaat i { background: var(--wassing); opacity: .35; border-radius: 2px; animation: zoekpuls var(--plaat-duur) ease-in-out infinite; }
.zoekplaat i:nth-child(2) { animation-delay: calc(var(--plaat-duur) / 4); }
.zoekplaat i:nth-child(3) { animation-delay: calc(var(--plaat-duur) / 2); }
.zoekplaat i:nth-child(4) { animation-delay: calc(var(--plaat-duur) * .75); }
@keyframes zoekpuls { 0%, 100% { opacity: .25; background: var(--wassing); } 40% { opacity: 1; background: var(--oker); } }
@media (prefers-reduced-motion: reduce) { .zoekplaat i { animation: none; opacity: .6; } }

/* De zoekbalk: vast onderaan het venster op scherm 3, 4, 6 en 7 zolang de motor leest en het
   eerste hoofdstuk schrijft. Besluit Ernst, 15 september 2026: hij stond na de herbouw als blok
   in de kaart en was dan niet in beeld zodra iemand scrolde. Onder de toestemmingsbalk (z 50),
   boven de rest. `body.met-zoekbalk` houdt onderaan ruimte, zodat de balk niets bedekt. */
.zoekbalk { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; background: var(--vlak); border-top: 1px solid var(--lijn); padding-bottom: env(safe-area-inset-bottom, 0px);
  transform: translateY(100%); transition: transform 320ms ease; }
.zoekbalk:not([hidden]) { transform: none; }
@media (prefers-reduced-motion: reduce) { .zoekbalk { transition: none; } }
.zoekbalk__in { width: min(100% - 2 * var(--rand), var(--kolom)); margin-inline: auto; padding: 14px 0; display: flex; align-items: center; gap: 24px; }
.zoekbalk__wat { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.zoekbalk__akte { font: 400 var(--t-klein)/1.4 'Atkinson Hyperlegible', system-ui, sans-serif; color: var(--diep); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; }
.zoekbalk__bij { font: 400 var(--t-mono)/1.4 'IBM Plex Mono', monospace; letter-spacing: .04em; color: var(--tekst-zacht); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin: 0; }
.zoekbalk__teller { display: grid; gap: 2px; height: 4px; width: min(100%, 320px); }
.zoekbalk__teller i { background: var(--wassing); opacity: .35; }
.zoekbalk__teller i.af { opacity: 1; }
.zoekbalk__teller i.nu { background: var(--oker); opacity: 1; }
.zoekbalk__knop { flex: none; }
.zoekbalk__klok { font: 800 var(--t-mono)/1.4 'IBM Plex Mono', monospace; letter-spacing: .04em; color: var(--oker-tekst); font-variant-numeric: tabular-nums; }
/* De ruimte onderaan is de hoogte van de balk plus lucht, en die hoogte is geen getal dat iemand opschreef:
   het script meet hem en zet hem in --zoekbalk-h (zie _voortgangsbalk.html). Gemeten 22 september 2026 op
   een telefoon van 390 punten: de balk is daar 169 hoog omdat zijn tekst over twee regels loopt, terwijl er
   152 gereserveerd stond; er verdween dus zeventien punten inhoud achter de balk. De waarden hieronder zijn
   alleen de stand vóór het eerste script, zodat de pagina niet springt. `met-zoekbalk` komt van de server op
   de schermen die de balk kennen, en het script houdt hem bij. */
:root { --zoekbalk-h: 96px; --zoekbalk-lucht: 48px; }
body.met-zoekbalk { padding-bottom: calc(var(--zoekbalk-h) + var(--zoekbalk-lucht)); }
@media (max-width: 900px) { .zoekbalk__archief { display: none; } }
@media (max-width: 600px) {
  /* Op een telefoon knipte de knop de tekst af ("Uw eerste hoofdstu..."), gemeten op 390px,
     16 september 2026. De tekst mag hier over twee regels lopen en de knop wordt smaller. */
  .zoekbalk__in { gap: 12px; padding: 10px 0; align-items: flex-end; }
  .zoekbalk__akte, .zoekbalk__bij { white-space: normal; overflow: visible; text-overflow: clip; }
  .zoekbalk__knop { padding: 10px 14px; font-size: var(--t-klein); }
  .zoekbalk__teller { display: none; }
  :root { --zoekbalk-h: 170px; }   /* twee regels tekst boven elkaar; het script meet de echte hoogte */
}
.velden { display: flex; flex-direction: column; gap: var(--blok); max-width: 640px; }
.velden-rij { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
@media (max-width: 600px) { .velden-rij { grid-template-columns: 1fr; } }
.persoon { display: flex; flex-direction: column; gap: 12px; }
textarea.veld { height: auto; padding: 12px 16px; line-height: 1.5; resize: vertical; font-family: 'Atkinson Hyperlegible', system-ui, sans-serif; }

/* ---------- de vier veldmaten ---------- */
/* Een veld dat alleen staat werd zo breed als de kolom, en een jaartal van vier cijfers kreeg dan
   een vak van zeshonderd pixels. Een veld krijgt daarom de maat van wat erin past. De maten zijn
   geteld naar de langste inhoud die we in de praktijk zien: een achternaam met tussenvoegsel, een
   e-mailadres, een jaartal, een postcode of huisnummer. De maat is een bovengrens, dus op een smal
   scherm krimpt het veld gewoon mee. Een tekstvak houdt de volle kolom: daar is de regellengte
   juist wat je wilt. Alleen deze vier klassen mogen de breedte van een veld zetten. */
.veld--naam { max-width: 420px; }   /* achternaam, voornaam, plaats, naam op het omslag */
.veld--mail { max-width: 480px; }   /* e-mailadres */
.veld--jaar { max-width: 160px; }   /* jaartal, vier cijfers */
.veld--kort { max-width: 140px; }   /* postcode, huisnummer */
.cijferblok { display: flex; flex-direction: column; max-width: 62ch; }
.rij-feit { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px solid var(--lijn); font-size: var(--t-klein); }
.rij-feit b { font-variant-numeric: tabular-nums; color: var(--diep); text-align: right; }
.balken { display: flex; flex-direction: column; gap: 8px; max-width: 62ch; }
.balk { display: grid; grid-template-columns: 120px 1fr 48px; align-items: center; gap: 12px; font-size: var(--t-klein); }
/* --deel is het aandeel van de langste staaf, als percentage. Het was --i met een afgeronde
   deler, en dat tekende 50 procent waar 45,7 hoorde. */
.balk i { display: block; height: 8px; border-radius: 4px; background: var(--kobalt); width: var(--deel, 100%); }
.balk b { text-align: right; font-variant-numeric: tabular-nums; color: var(--oker-tekst); }
.schuif { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.schuif input { width: 22px; height: 22px; accent-color: var(--kobalt); color: var(--kobalt); margin: 0; }
.keuzerij { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--lijn); cursor: pointer; }
.keuzerij input { width: 22px; height: 22px; accent-color: var(--kobalt); color: var(--kobalt); margin: 0; }
.keuzerij > span { display: flex; flex-direction: column; }
.vraag.keuze summary { display: grid; grid-template-columns: 1fr auto auto; gap: 16px; align-items: baseline; padding-right: 32px; }
.vraag.keuze summary .klein { font-family: 'Atkinson Hyperlegible', system-ui, sans-serif; font-weight: 400; letter-spacing: 0; }
.vraag .antwoord.kolom { display: flex; flex-direction: column; gap: var(--regel); }
/* Een veld met zijn naam erboven, die blijft staan als je typt (scherm 2 van /maak/, 18 september 2026). Lichter dan
   label.etiket: op dat scherm staan achtentwintig velden, en achtentwintig kapitaalregels lezen als geschreeuw. */
.veldlabel { display: flex; flex-direction: column; gap: 6px; }
.veldlabel > span { font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--tekst-zacht); }
/* Een nieuwe kant van de familie begint met wat lucht, zodat "Moeders kant" niet aan de vorige Oma vastzit. */
.vraag .antwoord.kolom > .kicker:not(:first-child) { margin-top: 10px; }
form .kaartstrook > .kicker:not(:first-child) { margin-top: 10px; }
.velden-rij:has(.veldlabel) { row-gap: 16px; }
.kolom > * { min-width: 0; max-width: 100%; }
.akte-kaart { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--kolomgat); align-items: start; }
.akte-kaart img { width: 100%; height: auto; border-radius: 4px; background: var(--wit); box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 20px 50px -30px rgba(18, 50, 92, .35); }
/* Geen scan, geen lege kolom. Als het archief geen plaat heeft, verbergt het script de img
   en viel de tekst in de smalle eerste kolom, met een lege brede kolom ernaast. Gezien op
   scherm 3 bij de tweede akte van timmermans, 15 september 2026. */
.akte-kaart:has(> img[hidden]) { grid-template-columns: 1fr; }
@media (max-width: 600px) { .akte-kaart { grid-template-columns: 1fr; } }
.blad-groot img { width: min(100%, 495px); height: auto; border-radius: 4px; background: var(--wit); box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 24px 60px -30px rgba(18, 50, 92, .35); }
.boomweergave { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--blok); }
.boomweergave .generatie { display: flex; flex-direction: column; gap: 4px; }
@media (max-width: 600px) { .boomweergave { grid-template-columns: 1fr; } }
/* Het echte veld is het zichtbare vakje: geen verborgen invoer met een getekende span ernaast,
   zodat de focusring op iets valt dat je ziet. Zie B007 in de audit van het ontwerpsysteem. */
.product { position: relative; cursor: pointer; display: block; }
.product input { position: absolute; left: 8px; top: 8px; z-index: 1; margin: 0; width: 24px; height: 24px;
  appearance: none; -webkit-appearance: none; background: var(--wit); border: 2px solid var(--kobalt);
  border-radius: 50%; cursor: pointer; }
/* De aan-stand wordt met currentColor getekend, niet met een eigen kleur: in de hoge-contrastmodus
   van Windows (forced-colors) vervangt het systeem de kleuren, maar currentColor loopt mee. */
.product input:checked { background:
  radial-gradient(circle at 50% 50%, currentColor 0 5px, transparent 5px) no-repeat, var(--wit); color: var(--kobalt); }
.product input:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }
@media (forced-colors: active) {
  /* Gemeten 12 september 2026 in Chrome: in deze modus wordt een background-image WEGGEGOOID,
     ook als hij in currentColor staat, dus de aan-stand verdwijnt dan. currentColor alleen is
     hier niet genoeg. Daarom hier wel forced-color-adjust: none, en tekenen met systeemkleuren,
     die de gebruiker zelf heeft gekozen. */
  .product input { border-color: CanvasText; background: Canvas; forced-color-adjust: none; }
  .product input:checked { background: radial-gradient(circle at 50% 50%, Highlight 0 5px, Canvas 5px) no-repeat; border-color: Highlight; }
  .product input:focus-visible { outline: 3px solid Highlight; outline-offset: 3px; }
  .product:has(input:checked) .tegel { outline-color: Highlight; }
}
.product:has(input:checked) .tegel { outline: 3px solid var(--kobalt); outline-offset: 4px; }

/* ---------- het boekvenster: de bladeraar van /boek/, ingesloten ----------

   PUNT P4, 14 september 2026. Ernst wilde "echte blader-functionaliteit, netjes ingebed in de
   flow van de pagina". De bladeraar staat op /boek/ en wordt hier ingesloten; zie de kop van
   bladeren_sectie() in bouw.py voor waarom een iframe en geen inline kopie.

   DE MAAT HANGT AAN DE BLADZIJDE EN NIET AAN HET VENSTER. Een bladzijde van het boek is A4,
   dus staand 1 op 1,41; een spread is twee bladzijden naast elkaar. Op breed past de spread
   en is de verhouding 1,41 breed op 1 hoog; op smal toont de bladeraar een bladzijde en staat
   hij rechtop. Een vaste hoogte in pixels zou op de ene telefoon een halve bladzijde tonen en
   op de andere een strook grijs eronder.

   De hoogte is begrensd op 78vh: een venster dat hoger is dan het scherm laat de lezer
   scrollen in twee richtingen tegelijk, en dat is precies de horizontale scrol die weg moest. */
/* De voorproef zolang het insluiten niet mag; zie de kop van bladeren_sectie() in bouw.py. */
.boekvoorproef { display: flex; justify-content: center; }
.boekvoorproef img { width: min(100%, 320px); height: auto; border-radius: 4px var(--r-m) var(--r-m) 4px;
  box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 24px 60px -30px rgba(18, 50, 92, .35); }

.boekvenster { width: 100%; border: 1px solid var(--lijn); border-radius: var(--r-l);
  overflow: hidden; background: var(--papier); aspect-ratio: 1.41 / 1; max-height: 78vh; }
.boekvenster iframe { width: 100%; height: 100%; border: 0; display: block; }
@media (max-width: 1010px) { .boekvenster { aspect-ratio: 1 / 1.3; max-height: 72vh; } }

/* ---------- prijsregel en feitenlijst: de twee lijstvormen naast een gewone lijst; nergens een tabel ---------- */
.verborgen { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.prijsregels { display: flex; flex-direction: column; }
.prijsregel { display: grid; grid-template-columns: 96px minmax(0, 1fr); align-items: start; gap: 8px 20px; padding: 14px 0; border-bottom: 1px solid var(--lijn); }
.prijsregel.kaal { grid-template-columns: minmax(0, 1fr); }
.twee .kolom .prijsregel { grid-template-columns: minmax(0, 1fr); }
.prijsregel .regelrechts { display: flex; align-items: baseline; justify-content: space-between; gap: var(--kolomgat); min-width: 0; }
/* PUNT P7, de tweede helft. Hier ging de prijsregel onder 1010px naar EEN kolom, en dan staat
   het beeld alleen op een regel met een halve schermbreedte dode ruimte ernaast, en de naam,
   de omschrijving en de prijs eronder. Ernst: "De hele opbouw van dit blok is niet mooi."
   Dezelfde reparatie als bij de uitlegblokken (P5 en P6): twee kolommen houden, met het beeld
   in een smalle. Gemeten op 500px: het blok ging van 466 naar 300 pixels. */
@media (max-width: 1010px) {
  .prijsregel { grid-template-columns: minmax(96px, 30%) minmax(0, 1fr); column-gap: 18px; }
  .prijsregel.kaal { grid-template-columns: minmax(0, 1fr); }
}
.prijsregel .tegelklein { width: 96px; }
.prijsregel .tegelklein .tegel, .prijsregel .tegelklein .boek { width: 96px; }
/* PUNT P7 VAN DE MOBIELE OPMERKINGEN, 14 september 2026. Ernst: "bij de cover ontbreekt de
   tekst die erbij hoort." Hier stond dat de titel en de streep op de kleine kaft WEG gingen,
   dus de miniatuur toonde alleen de illustratie: een Delfts landschap zonder merk en zonder
   naam. Dat is geen kaft maar een plaatje, en op de bladzijde waar de prijs van dat boek
   staat is dat precies het verkeerde.

   De maat schaalt mee met de tegel en niet met het scherm. `--t-kaft` is op de voorpagina
   `clamp(18px, 2.2vw, 26px)`; op een tegel van 96px past daar geen woord van zeventien
   letters in. Hij staat hier op 8px, en dan meet "Het Voorouderboek" in Archivo 800 ongeveer
   75px binnen de 80px die het titelvak breed is.

   De regel eronder ("De voorouders van ...") blijft wel weg: op vier tiende van 8px is dat
   3,2px, en dat is geen tekst meer maar een grijze veeg. */
.prijsregel .tegelklein .boek { --t-kaft: 8px; }
.prijsregel .tegelklein .boek .titel { gap: 2px; }
.prijsregel .tegelklein .boek .titel .voor { display: none; }
.prijsregel .naam { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.prijsregel .naam a { color: var(--diep); }
.prijsregel .naam a:hover { color: var(--kobalt); }
.prijsregel .omschrijving { font-size: var(--t-klein); color: var(--tekst-zacht); }
/* ---------- ÉÉN PRIJSNOTATIE VOOR DE HELE SITE, 14 september 2026 ----------

   Ernst, punt P1 van de mobiele opmerkingen: "Prijsweergave is overal stuk ... de bedragen en
   het woord euro breken willekeurig af en lijnen inconsistent uit: soms staat euro naast het
   getal, soms eronder, en in de ergste gevallen valt het woord uiteen (eur / o) of het getal
   zelf (14 / 9)."

   DE OORZAAK, en het was een reparatie die erger was dan de kwaal. In de mobiele regel
   hieronder stond `white-space: normal; max-width: 50%; overflow-wrap: anywhere`. Dat laatste
   geeft de browser toestemming om MIDDEN IN EEN WOORD af te breken, en met een kolom van een
   halve schermbreedte doet hij dat ook. Zo ontstaan "eur / o" en "14 / 9". Iemand heeft ooit
   een overloop willen dichten en heeft daarmee elke prijs op de site laten breken.

   WAT HET NU IS. Het bedrag op een regel, het woord eronder, geen van beide ooit afbrekend.
   Dat is precies wat Ernst vraagt en het is ook de enige stand die op elke breedte hetzelfde
   leest: naast elkaar of eronder hangt anders van de toevallige kolombreedte af.

   ONGESCOPED, want dit is de notatie en niet de opmaak van een lijst. Tot vandaag stond hij
   alleen onder `.prijsregel`, en de productkaarten op /het-voorouderboek droegen daarom een
   eigen notatie: `<p class="mono pkaart__prijs">39 euro</p>`, en `.mono` zet kapitalen, dus
   daar stond "39 EURO". Dat was de derde notatie op dezelfde bladzijde. */
.prijs-getal { color: var(--oker); font-variant-numeric: tabular-nums; }
.prijs-getal b { display: block; font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif;
  letter-spacing: -.02em; color: var(--oker); white-space: nowrap; }
.prijs-getal small { display: block; font: 400 var(--t-klein)/1.65 'Atkinson Hyperlegible', system-ui, sans-serif;
  color: var(--tekst-zacht); white-space: nowrap; text-transform: none; letter-spacing: 0; }
.prijs-getal .euro-klein { color: var(--oker-tekst); }
/* Rechts uitgelijnd in een prijsregel, waar de naam links staat; in een productkaart lijnt hij
   mee met de naam en de regel eronder, want daar is links de leesrichting van het hele blokje. */
.prijsregel .prijs-getal { text-align: right; }

@media (max-width: 600px) { .prijsregel .omschrijving { grid-column: 1 / -1; } .prijsregel .prijs-getal b { font-size: var(--t-h3); } }
/* Punt 18: de labelkolom was 160 px en daar past "VERZENDING IN NEDERLAND" niet in, dus die
   brak over twee regels terwijl rechts van de waarde een halve bladzijde leeg bleef. De lijst
   liep bovendien tot 62ch en stond daardoor smal in een brede kolom. Het label krijgt de
   ruimte die het langste label vraagt, en de waarde de rest. */
.feitenlijst { display: flex; flex-direction: column; margin: 0; }
.feitenlijst .feit { display: grid; grid-template-columns: minmax(200px, 15em) minmax(0, 1fr); gap: 12px 24px; padding: 10px 0; border-bottom: 1px solid var(--lijn); align-items: baseline; }
.feitenlijst dt { font: 800 var(--t-mono)/1.4 'Archivo', system-ui, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--tekst-zacht); }
.feitenlijst dd { margin: 0; }
@media (max-width: 600px) { .feitenlijst .feit { grid-template-columns: 1fr; gap: 2px; } }

/* ================================================================================
   Mobiel, reparatie 12 september
   Gemeten met mobielpoort.mjs op iPhone SE (375), iPhone 15 (393), Pixel 7 (412)
   en 320 px als ondergrens, met apparaat-emulatie en touch. Alles hieronder staat
   in een media query voor smalle schermen; het brede ontwerp verandert niet.
   ================================================================================ */

/* ---- raakvlakken: wat een duim raakt is minstens 44 px hoog ---- */
@media (max-width: 1010px) {
  .kop .menu { width: 44px; height: 44px; padding: 10px; align-items: center; justify-content: center; }
  .kop .merk { min-height: 44px; }
  .kruimel { gap: 0 8px; align-items: center; }
  .kruimel a, .kruimel span { min-height: 44px; display: inline-flex; align-items: center; }
  .voet .kols a { min-height: 44px; display: flex; align-items: center; margin-top: 0; }
  .voet .onder .merk { min-height: 44px; }
  .voet .melden .etiket { margin-bottom: 6px; }
  .schuif { min-height: 44px; }
  .keuzerij { min-height: 44px; }
}

/* ---- formulieren: veld op volle breedte, knop eronder ---- */
@media (max-width: 600px) {
  .naamrij { flex-direction: column; max-width: 100%; gap: 12px; }
  .naamrij .veld { flex: none; width: 100%; }
  .naamrij .knop { width: 100%; }
  .velden { max-width: 100%; }
  .knoprij { flex-direction: column; align-items: stretch; gap: 14px; }
  .knoprij .knop { width: 100%; }
  .knoprij span { max-width: 100%; }
  /* een knoplabel dat niet past mag breken in plaats van buiten zijn rij te vallen */
  .knop { white-space: normal; text-align: center; height: auto; min-height: 52px;
          padding: 12px 20px; max-width: 100%; line-height: 1.3; }
}

/* ---- 320 px: geen kop past daar nog op één regel ---- */
@media (max-width: 380px) {
  .h1, .h1.een-regel, .boek .titel .t { white-space: normal; }
  .h1 { overflow-wrap: break-word; }
}

/* ---- beeld schaalt altijd mee, ook waar een breedte in de opmaak staat ---- */
@media (max-width: 1010px) {
  img, video { height: auto; }
  .reis .film { width: min(100% - 2 * var(--rand), 480px); }
  .opening .boek { width: min(100%, 300px); }
}

/* ---- zonder javascript is er geen knop die het menu opent: dan staan de
        links zelf in de kop, onder het merk, in plaats van verborgen ---- */
@media (max-width: 1010px) {
  html:not(.js) .kop .wrap { height: auto; flex-wrap: wrap; padding-block: 10px; row-gap: 4px; }
  html:not(.js) .kop .menu { display: none; }
  html:not(.js) .kop nav { display: flex; flex-wrap: wrap; gap: 0 18px; width: 100%; }
  html:not(.js) .kop nav a:not(.knop) { min-height: 44px; display: inline-flex; align-items: center; }
  html:not(.js) .kop nav a.knop { margin-left: 0; margin-block: 6px; width: 100%; }
}

/* ---- de kop blijft leesbaar waar hij over inhoud staat ----
   Op de voorpagina is de kop doorzichtig zolang de blauwe opening in beeld is;
   het script maakt hem daarna dekkend met .gewisseld. Bij minder beweging stopt
   dat script voor die stap, en dan liep de tekst onleesbaar onder de kop door.
   Zelfde oplossing als bij geen javascript: de kop blijft dan gewoon kobalt. */
@media (prefers-reduced-motion: reduce) {
  body:has(.opening.op-blauw) .kop:not(.gewisseld) { background: var(--kobalt); border-bottom-color: transparent; }
}
html.stil body:has(.opening.op-blauw) .kop:not(.gewisseld) { background: var(--kobalt); border-bottom-color: transparent; }

/* Elk keuzevakje en elk keuzerondje in de flow draagt de merkkleur, ook als het buiten een
   van de bekende rijen staat; anders valt het terug op de zwarte standaard van de browser. */
main input[type="checkbox"], main input[type="radio"] { accent-color: var(--kobalt); color: var(--kobalt); }

/* ================================================================================
   De kaartopzet van de flow
   Goedgekeurd op de opzet in website/opzet/bouw-kaart2.py. Elk scherm in maak/ is
   één kaart op het papier, en de kaart leest van boven naar beneden als vraag,
   cijfers, bewijs, verder. De stroken doen het werk dat witruimte eerst deed: ze
   scheiden met een lijn of met kleur, zodat er binnen de kaart geen gat groter dan
   32 px hoeft te vallen.

   Twee afwijkingen van de opzet, en waarom. De opzet tekent de kaartrand en de
   scheiding in de cijferstrook met twee doorzichtige blauwtinten van 16 en 18
   procent. Die staan niet in tokens.css, en kleurpoort.py en kleurmeting.mjs wijzen
   ze allebei af. De kaartrand draagt daarom --lijn, de kleur die de site al voor
   een haarlijn gebruikt, en de scheiding op het blauwe vlak draagt --wassing, want
   --lijn verdwijnt op --vlak.
   ================================================================================ */

/* ---- het vel en de kaart ---- */
.flowvel { padding: 48px var(--rand) 64px; }
.kaart-flow { max-width: 920px; margin-inline: auto; background: var(--wit);
  border: 1px solid var(--lijn); border-radius: var(--r-l); overflow: hidden; }

/* GEBALANCEERD OP EEN HOGE TABLET, 22 september 2026. `main` groeide altijd maar tot zijn
   inhoud en bleef boven in de viewport hangen; op een gewoon scherm valt dat niet op, want
   de kaart plus het kleine lettertje eronder vullen de hoogte al. Gemeten met web-audit op
   iPad Pro portrait (1024x1366) op scherm 1 van de flow: de kaart eindigt rond y480, het
   kleine lettertje rond y650, en wat daaronder overblijft van de 1366px is leeg papier -
   ruim de helft van de viewport, terwijl de kaart met al zijn witruimte er verweesd bovenin
   bij staat. Dit vult zich alleen op als `main` de viewport nog niet vult: `min-height`
   reikt tot onder de kop, en `justify-content: center` doet verder niets zolang de inhoud
   (scherm 6 met zijn vier stemvelden, of scherm 3 met de kandidaten) al genoeg weegt. Precies
   hetzelfde patroon staat al bij `.bladeren.breed .plak` hierboven (100vh, justify-content:
   center), dus dit is geen nieuw idee voor deze stijl, alleen de eerste keer dat `main` van
   de bestelflow het ook krijgt. */
main:has(> .flowvel) { min-height: calc(100vh - var(--kop-hoogte)); display: flex; flex-direction: column; justify-content: center; }

/* ---- de voortgangslijn: de teller stopt bij 7 en verdwijnt daarna (besluit V5) ---- */
.stapbalk { height: 3px; background: var(--lijn); position: relative; }
.stapbalk i { position: absolute; left: 0; top: 0; bottom: 0; display: block;
  background: var(--kobalt); width: calc(var(--i, 0) / 7 * 100%); }

/* ---- de stroken van de flowkaart ----
   Heetten tot 12 september 2026 .strook, net als de schuivende galerijstroken van .bladeren en
   .parade. Eén naam voor twee dingen, en de cascade beslist per eigenschap en niet per regel:
   deze generieke regel staat later en zette flex-direction op column, ook op de galerij, die
   zelf geen richting zette. Die werd daardoor 345 px breed en 4985 px hoog, en pikte ook deze
   vulling op. Een specifiekere selector helpt niet tegen een eigenschap die je niet noemt, dus
   de naam is gesplitst in plaats van de richting bijgezet. Gevonden door de manager-sessie. */
.kaartstrook { display: flex; flex-direction: column; gap: var(--regel); padding: 32px 40px; }
/* Alleen min-width: 0. Een max-width van 100% hier zou elke maat van een component
   overstemmen die even zwaar weegt en eerder staat: het tekstvak van scherm 6 werd zo
   840 px breed in plaats van de 640 die .velden zet, en het vlak-blok verloor zijn
   uitstek. Gemeten aan de breedte van het tekstvak, niet op het oog. */
.kaartstrook > * { min-width: 0; }
.kaartstrook + .kaartstrook { border-top: 1px solid var(--lijn); }
/* Een strook waarvan elk kind verborgen is (de zoektocht die klaar is, het blok "dun boek" dat
   niet van toepassing is) stond als lege band met een lijn erboven. Ernst zag er drie onder
   elkaar op scherm 4, 15 september 2026. Zo'n strook is er dan niet. Scripts tellen niet mee. */
.kaartstrook:not(:has(> :not([hidden], script))) { display: none; }
.kaart-flow .h1 { white-space: normal; }
.kaart-h1 { font-size: var(--t-h1-kaart); }
/* De knop staat onderaan in een eigen strook, met de kleine uitleg ernaast: wie de
   cijfers leest hoeft niet terug omhoog (reparatie 4 van de opzet). */
.kaartstrook--voet { flex-direction: row; align-items: center; gap: 24px; flex-wrap: wrap; }
.kaartstrook--voet .knoprij { flex: none; }
.voet-uitleg { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 260px; max-width: 46ch; }

/* ---- de cijferstrook: getal boven label, hoogstens twee in oker ---- */
.kaartstrook--cijfers { background: var(--vlak); flex-direction: row; flex-wrap: wrap;
  align-items: stretch; gap: 0; padding-block: 22px; }
.cijfer-een { display: flex; flex-direction: column; gap: 2px; padding-inline: 26px; }
.cijfer-een:first-child { padding-left: 0; }
.cijfer-een + .cijfer-een { border-left: 1px solid var(--wassing); }
.cijfer-getal { font: 800 var(--t-getal-strook)/1 'Archivo', system-ui, sans-serif;
  letter-spacing: -.03em; color: var(--diep); font-variant-numeric: tabular-nums; }
.cijfer-een.oker .cijfer-getal { color: var(--oker); }
.cijfer-label { font-size: var(--t-bijschrift); line-height: 1.4; color: var(--diep); }

/* ---- het bewijs: een balkgetal draagt de kaart niet, de balk doet dat al
        (reparatie 1 van de opzet: oker verrijkt, het neemt niet over) ---- */
.kaart-flow .balk b { font: 400 var(--t-klein)/1 'IBM Plex Mono', monospace; color: var(--tekst-zacht); }

/* ---- op een telefoon: de kaart vult de zijmarge, de cijfers stapelen ---- */
@media (max-width: 600px) {
  .flowvel { padding: 24px var(--rand) 40px; }
  .kaartstrook { padding: 24px; }
  .kaartstrook--cijfers { flex-direction: column; padding-block: 20px; }
  .cijfer-een { padding-inline: 0; padding-block: 14px; }
  .cijfer-een:first-child { padding-top: 0; }
  .cijfer-een:last-child { padding-bottom: 0; }
  .cijfer-een + .cijfer-een { border-left: 0; border-top: 1px solid var(--wassing); }
  .kaartstrook--voet { flex-direction: column; align-items: stretch; }
  .voet-uitleg { max-width: 100%; }
}


/* ---------- de voorbeeldpagina ----------
   Twee onderdelen die nergens anders voorkomen: de overgang (een akte die een zin wordt) en de
   lezer (de bladzijden zelf). Alles hierin gebruikt de maten en kleuren die er al zijn: er is
   maar één radius (--r-m), de papierschaduw is het vaste paar dat ook onder het boek en de
   bladen ligt, en de afstanden komen uit --regel, --blok, --kolomgat en --sectie-in. */

/* De overgang. Het blauwe vlak draagt de akte en haar tekst; de bladzijde komt er als wit vel
   onderuit, met een inspringing links en rechts zodat het leest als iets dat eronder vandaan
   schuift en niet als een tweede blok. */
.overgang { margin-top: var(--blok); }
/* De onderruimte is dubbel, en dat is niet cosmetisch. De witte kaart schuift met een negatieve
   marge onder dit vlak vandaan; is die marge even groot als de onderruimte, dan valt de bovenkant
   van de kaart precies op de onderkant van het beeld. Onder 1200 px valt dat niet op omdat de
   tekstkolom langer is dan de scan, maar vanaf 1200 px is de scan het langste element en raakte
   de kaart hem exact aan: gemeten 0 px ertussen. Met een dubbele onderruimte blijft er altijd
   evenveel lucht als de kaart overlapt. Gezien door Ernst, 12 september 2026. */
.overgang__akte { background: var(--vlak); border-radius: var(--r-m);
  padding: var(--blok) var(--blok) calc(var(--blok) * 2);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--kolomgat);
  align-items: start; }
.overgang__akte img { width: 100%; height: auto; border-radius: 4px; background: var(--wit);
  box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 20px 50px -30px rgba(18, 50, 92, .35); }
.overgang__akte > div { display: flex; flex-direction: column; gap: var(--regel); }
/* De geciteerde regel uit de akte is een eigen rol en geen kleine tekst. Hij droeg tot
   13 september 2026 ook .klein, en toen de letterpoort eindelijk over deze pagina keek meldde
   hij: rol "klein" rendert IBM Plex Mono waar Atkinson hoort. De poort had gelijk. Mono is hier
   met opzet, want dit is wat er op het papier staat en geen lopende tekst; dus hoort hij die
   rol niet te claimen. Maat en kleur staan nu hier, zodat hij niets meer leent. */
.akteregel { font: 400 var(--t-klein)/1.85 'IBM Plex Mono', monospace; color: var(--tekst-zacht); }
.overgang__akte .klein { padding-top: var(--regel); border-top: 1px solid var(--wassing); }
.overgang__blad { background: var(--wit); border: 1px solid var(--lijn); border-radius: var(--r-m);
  padding: var(--blok); margin: calc(-1 * var(--blok)) var(--sectie-in) calc(-1 * var(--regel));
  position: relative; display: flex; flex-direction: column; gap: var(--regel);
  box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 24px 60px -30px rgba(18, 50, 92, .35); }

/* De boektekst wordt gezet zoals in het boek: uitgevuld met afbreking aan. Zonder lang="nl" op
   het element breekt de browser op de verkeerde plek af en zonder afbreking krijgt uitvullen
   rivieren. Besluit van Ernst, 12 september 2026. */
.boektekst { font: 400 var(--t-tekst)/1.65 'Atkinson Hyperlegible', system-ui, sans-serif;
  text-align: justify; hyphens: auto; -webkit-hyphens: auto; }

/* Een zin waarvan wij de akte zelf gelezen hebben. Geen kleurvlak alleen: de onderlijn draagt
   het verschil ook zonder kleur, en het tagje zegt welke akte het is. */
.uit-de-akte { background: var(--oker-vlak); color: inherit;
  box-shadow: 0 1px 0 var(--oker); padding: 1px 0; }
.uit-de-akte .tag { font: 400 var(--t-mono-klein)/1 'IBM Plex Mono', monospace;
  color: var(--oker-tekst); margin-left: 4px; vertical-align: super; }

/* De lezer: de bladzijden liggen naast elkaar en schuiven horizontaal, met de scrolklik per
   blad. Op een telefoon veegt dat vanzelf; met een toetsenbord doen de pijltjes het, en de
   strook is focusbaar zodat dat ook werkelijk kan. */
.bladen { display: flex; gap: var(--blok); overflow-x: auto; scroll-snap-type: x mandatory;
  padding: var(--regel) 0 2px; margin-top: var(--regel);
  scrollbar-width: thin; overscroll-behavior-x: contain; }
.lezer { padding-bottom: 0; }
.lezer + .sectie { padding-top: var(--blok); }
.lezer .bladen { margin-top: 0; }
.bladen:focus-visible { outline: 2px solid var(--kobalt); outline-offset: 6px; border-radius: var(--r-m); }
.blad { flex: 0 0 auto; width: min(100%, 495px); scroll-snap-align: start; }
/* De bladen zijn even hoog als het langste, want ze liggen naast elkaar en een rij van
   ongelijke vellen leest als een fout. Maar een kort blad hoeft niet vol: de tekst staat boven
   en de bronnen onder, en het wit ertussen is de bladspiegel van een gedrukte bladzijde. Dat is
   hier geen ongebruikte ruimte maar de vorm van het ding dat wordt getoond. */
.bladvel { background: var(--wit); border: 1px solid var(--lijn); border-radius: 4px;
  padding: var(--regel) var(--blok) var(--blok); height: 100%;
  display: flex; flex-direction: column; gap: var(--regel);
  box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 20px 50px -30px rgba(18, 50, 92, .35); }
.bladnr { color: var(--tekst-stil); }
.bronnen { margin-top: auto; padding-top: var(--regel); border-top: 1px solid var(--lijn);
  display: flex; flex-direction: column; gap: 6px; }
.bronregel { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 10px;
  align-items: baseline; }
.bronregel p { margin: 0; }
.bronregel .klein { grid-column: 2; }

@media (max-width: 1010px) {
  /* De dubbele onderruimte is er om de overlappende kaart lucht te geven; op smal is er geen
     overlap, dus hij is hier niet nodig en maakt hij alleen een gat. */
  .overgang__akte { grid-template-columns: 1fr; gap: var(--blok); padding-bottom: var(--blok); }
  .overgang__akte img { max-width: 320px; }
  /* Geen overlap meer zodra de kaart even breed is als het vlak. De kaart hoort onder het vlak
     vandaan te komen, en dat leest alleen als hij smaller is: op breed springt hij 64 px in aan
     weerszijden. Onder 1010 is die inspring nul, en dan is dezelfde negatieve marge geen effect
     meer maar twee even brede blokken die elkaar overlappen. Gezien door Ernst op zijn telefoon,
     13 september 2026. Op smal staat de kaart dus gewoon onder het vlak, met de normale afstand;
     de volgorde vlak-dan-kaart vertelt daar hetzelfde zonder truc. */
  .overgang__blad { margin: 10px 0 0; }
  .blad { width: min(100%, 340px); }
  .bladvel { padding: var(--blok) 22px; }
}


/* ---------- de productsectie onderaan /het-voorouderboek ----------
   Twee rijen en geen plank, en dat is een inhoudelijk verschil: de eerste rij verandert het
   boek dat wij maken, de tweede staat ernaast. Zie _productsectie.py voor de meting die
   eronder ligt. Alles hierin gebruikt de maten die er al zijn. */
.producten-erbij .rijkop { padding-top: var(--regel); margin-top: var(--regel);
  border-top: 1px solid var(--lijn); display: flex; flex-direction: column; gap: 4px; }
.producten-erbij .rijkop.tweede { margin-top: var(--blok); }
.praster { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
  margin-top: var(--regel); }
.praster:last-of-type { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* De productkaart. Dezelfde rand, radius en witte grond als elke andere kaart; het beeld staat
   op wit en draagt geen ornament, want het staat al in een doos. */
/* GEEN PADDING OP DE KAART ZELF, 15 september 2026. Ernst: "het is gewoon niet zoals een
   webshop dit aan zou bieden". Wat het een icoontegel maakte was de witrand rondom het beeld:
   een vierkant plaatje met achttien pixels lucht eromheen leest als een pictogram in een doos.
   Een webshop zet het beeld tegen de bovenrand en de woorden eronder. De kaart knipt daarom af
   op zijn eigen radius en de ruimte zit alleen nog onder het beeld. */
.pkaart { display: flex; flex-direction: column; gap: 0; text-decoration: none; color: inherit;
  background: var(--wit); border: 1px solid var(--lijn); border-radius: var(--r-m);
  padding: 0; overflow: hidden; }
.pkaart:hover { border-color: var(--wassing); }
.pkaart__beeld { display: block; background: var(--wit); border-radius: 0; overflow: hidden;
  aspect-ratio: 4 / 3; border-bottom: 1px solid var(--lijn); }
/* HET BEELD PAST IN ZIJN KADER, 16 september 2026 (Ernst, Comments 3): de illustraties zijn niet
   4:3 en `cover` sneed er boven en onder een stuk af; op /het-voorouderboek stond elk boek
   half buiten beeld. Nu `contain` met wat lucht eromheen, gecentreerd: het hele beeld, kleiner,
   op wit. Alleen hier; foto's elders houden `cover`. */
.pkaart__beeld img { width: 100%; height: 100%; object-fit: contain; object-position: center; padding: 7%; box-sizing: border-box; display: block; }
/* PUNT P8 VAN DE MOBIELE OPMERKINGEN, 14 september 2026. Ernst: "Het blok met de
   kwartierstaat, de kalender en binnenwerk in kleur oogt rommelig, mede door P1 maar niet
   alleen daardoor."

   Wat het rommelig maakte is niet de prijs maar de UITLIJNING. Elke kaart is even breed en
   even hoog, maar de regel onder de naam is op de ene kaart een regel en op de andere twee.
   De prijs stond direct onder die regel, dus hij hing op elke kaart op een andere hoogte en
   het oog zag een rafelrand waar een rij hoorde te staan.

   De woordkolom vult nu de kaart en de prijs wordt naar de onderrand geduwd. Twee kaarten
   naast elkaar hebben hun prijs daarmee op dezelfde lijn, wat de tekst erboven ook doet. */
.pkaart__woord { display: flex; flex-direction: column; gap: 3px; flex: 1;
  padding: 12px 14px 14px; }
.pkaart__woord p { margin: 0; }
.pkaart__naam { font-family: 'Archivo', system-ui, sans-serif; font-weight: 800;
  line-height: 1.25; letter-spacing: -.01em; color: var(--diep); }
.pkaart__regel { line-height: 1.65; }
.pkaart__prijs { color: var(--oker-tekst); margin-top: auto; padding-top: 8px; }

/* ---------- WAT HET KOST ALS KAARTEN, 19 september 2026 (P7 en P8) ----------
   Ernst koos uit drie voorbeelden de kaarten in een raster: de extra's als gelijke kaarten met een
   beeld van gelijke maat, in twee groepen, "In het boek" en "Ernaast", zoals op /het-voorouderboek.
   Het zijn .pkaart'en, dus dezelfde rand, dezelfde beeldmaat en dezelfde prijsnotatie als daar.

   Wat er anders is dan op /het-voorouderboek: een regel met de levertijd. Die plakte tot vandaag
   als "gedrukt, 9 werkdagen" achter de omschrijving. Naast de prijs past hij op een telefoon niet
   (hij brak over twee regels, gezien op 390 px), dus hij staat erboven, op een eigen regel. */
.kostgroepen { margin-top: var(--regel); }
.kostgroep__kop { font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif; letter-spacing: .16em;
  text-transform: uppercase; color: var(--tekst-stil); margin: var(--regel) 0 10px; }
.kostraster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
/* Dezelfde kleine maat als elke andere lopende tekst (tekstmaat.py, besluit Ernst 18 september 2026); alleen de kleur is stiller. */
.pkaart__meta { font-size: var(--t-klein); line-height: 1.65; color: var(--tekst-stil); margin-top: 2px !important; }
.kostkaart .pkaart__regel { overflow-wrap: break-word; }
/* DE PRIJS OP DE ONDERRAND, en dat stond er al in (P8, 14 september) maar deed niets: `.pkaart__woord p
   { margin: 0 }` is specifieker dan `.pkaart__prijs` en zette de `margin-top: auto` weer op nul. Gezien
   op 19 september 2026: op /wat-het-kost en /het-voorouderboek hing de prijs direct onder de tekst, op
   elke kaart op een andere hoogte. */
.pkaart__woord .pkaart__prijs { margin-top: auto; }
/* Een kaart die alleen op zijn rij staat, wordt een brede kaart met het beeld links. Drie in het
   boek en vier ernaast laat er anders op elke breedte een staan. */
.kostraster > .kostkaart:last-child:nth-child(3n+1) { grid-column: 1 / -1; flex-direction: row; }
.kostraster > .kostkaart:last-child:nth-child(3n+1) .pkaart__beeld { flex: 0 0 34%; border-bottom: 0; border-right: 1px solid var(--lijn); }
@media (max-width: 600px) {
  .kostraster { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .kostraster > .kostkaart:last-child:nth-child(3n+1) { grid-column: auto; flex-direction: column; }
  .kostraster > .kostkaart:last-child:nth-child(3n+1) .pkaart__beeld { flex: none; border-right: 0; border-bottom: 1px solid var(--lijn); }
  .kostraster > .kostkaart:last-child:nth-child(2n+1) { grid-column: 1 / -1; flex-direction: row; }
  .kostraster > .kostkaart:last-child:nth-child(2n+1) .pkaart__beeld { flex: 0 0 42%; border-bottom: 0; border-right: 1px solid var(--lijn); }
}
/* De vergelijkingslijst: "StamboomLatenMaken.nl" is een woord zonder spatie, en op een telefoon
   liep het over de prijs heen (gezien op 390 px, 19 september 2026). Alleen de naam mag breken,
   nooit de prijs (zie de notatieregel hierboven). */
.prijsregel.kaal .naam .h3 { overflow-wrap: anywhere; }
/* PRECIES ZOALS B, 19 september 2026. Ernst: "Ik zei B maar kreeg heel iets anders." De eerste bouw
   nam de kaarten van /het-voorouderboek over en zette er twee groepen bij; B heeft het boek als brede kaart,
   één raster, elk beeld heel op een lichtblauw vlak en vierkante hoeken. De prijs staat in de notatie van de
   site (Ernst, dezelfde dag: "de sitenotatie, euro eronder"). */
.kostboek { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 20px; background: var(--wit);
  border: 1px solid var(--lijn); padding: 18px; }
.kostboek__beeld { background: var(--vlak); display: grid; place-items: center; padding: 18px; }
.kostboek__beeld .tegelklein, .kostboek__beeld .tegelklein .boek { width: 150px; }
.kostboek__beeld .tegelklein .boek { --t-kaft: 12px; }
/* HET BOEK IN DE KAART STAAT STIL, 19 september 2026. beweging.js liet het eerste boek op de bladzijde
   meedrijven met een inline transform, en Safari hield de oude beweging.js vast (de scripts in de wortel
   droegen geen Cache-Control). Deze regel wint van die inline stijl, dus het boek blijft in zijn vlak,
   welke versie van het script er ook draait. Ernst zag het twee keer op zijn telefoon. */
.kostboek .boek, .kostboek .boek .drijf { transform: none !important; }
.kostboek__tekst { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.kostboek__tekst .h3 a { color: var(--diep); text-decoration: none; }
.kostboek__tekst .prijs-getal { margin-top: auto; padding-top: 10px; }
@media (max-width: 600px) {
  .kostboek { grid-template-columns: minmax(0, 1fr); gap: 14px; padding: 16px; }
}
.kostkaart { border-radius: 0; }
.kostbeeld { background: var(--vlak); }
.kostbeeld img { object-fit: contain; padding: 8%; mix-blend-mode: multiply; }
/* DE MATEN VAN B, exact (Ernst, 19 september 2026, tweede keer: "wat je nu laat zien is niet B"). Het
   verschil zat in de maat: B is compact, met witte ruimte rondom het lichtblauwe beeldvak en kleinere
   tekst op de kaart. tekstmaat.py laat .kostkaart en .kostboek daarom buiten de regel van 15 en 17 px. */
.kostraster { gap: 12px; }
.kostkaart { padding: 10px; gap: 4px; background: var(--wit); border: 1px solid var(--lijn); }
/* Vierkant en bijna vol, 19 september 2026 (Ernst: "de andere producten staan er te klein in"). In een
   vlak van 4 bij 3 kwam een staand vel als de kwartierstaat niet verder dan de helft van de breedte. */
.kostkaart .pkaart__beeld { aspect-ratio: 1 / 1; background: var(--vlak); border: 0; margin-bottom: 4px; display: grid; place-items: center; }
.kostkaart .pkaart__beeld img { width: 100%; height: 100%; max-width: none; max-height: none; padding: 5%; box-sizing: border-box; object-fit: contain; mix-blend-mode: multiply; }
.kostkaart .pkaart__woord { padding: 0; gap: 0; }
.kostkaart .pkaart__naam { font-size: 14.5px; line-height: 1.25; }
.kostkaart .pkaart__regel { font-size: 13.5px; line-height: 1.45; margin-top: 2px !important; hyphens: auto; }
.kostkaart .pkaart__meta { font-size: 12px; line-height: 1.35; margin-top: 6px !important; }
.kostkaart .pkaart__prijs { padding-top: 8px; }
.kostraster > .kostkaart:last-child:nth-child(3n+1) { gap: 16px; }
.kostraster > .kostkaart:last-child:nth-child(3n+1) .pkaart__beeld { flex: 0 0 32%; margin: 0; border: 0; }
@media (max-width: 600px) {
  .kostraster > .kostkaart:last-child:nth-child(2n+1) { gap: 12px; }
  .kostraster > .kostkaart:last-child:nth-child(2n+1) .pkaart__beeld { flex: 0 0 42%; margin: 0; border: 0; }
}
/* SCHERM 7 ZODRA HET ARCHIEF TE KOOP IS, 24 september 2026 (roadmap E1). Twee regels, allebei achter
   `.kaart-flow--archief`. Die klasse zet kies.html alleen als `archief.te_koop` aan staat, en zolang die
   schakelaar uit staat (vandaag) verandert er aan dit scherm dus geen pixel; gemeten door de bladzijde met de
   schakelaar uit naast die van main te leggen op 360, 390, 768 en 1440 px.

   1. HET VINKJE STOND OP DE NAAM. Een kaart die als enige op zijn rij staat legt de tekst naast het beeld in
      plaats van eronder, en dan begint de naam op dezelfde hoogte als het vinkje dat rechtsboven in de kaart
      hangt (.kieskaart input, absoluut op 16 px). Gemeten op 360 en 390 px met Het Familiearchief deluxe, de
      langste naam in de catalogus: het vinkje lag over de laatste letters van "Familiearchief". Ruimte
      vrijhouden aan de rechterkant helpt niet: op 360 px is de naamkolom 142 px en "Familiearchief" alleen al
      110 px, dus wat er rechts af gaat loopt links weer over. Het vinkje gaat daarom naar de bovenhoek van het
      beeld, waar het in de rasterkaarten ernaast ook al over een beeld staat.
   2. HET BEDRAG BRAK NA HET EUROTEKEN. Gemeten op 360 px met een deluxe mandje met het archief erin: de regel
      "Het Familiearchief deluxe EUR 249,00, samen met de hardcover" duwde de rechterkolom zo smal dat er "EUR"
      op de ene regel stond en "249,00" op de volgende. `.kieskaart .prijs-klein` doet in de kaarten ernaast
      al hetzelfde.

   Allebei zijn ze op zichzelf ook een verbetering voor het scherm zoals het vandaag staat; ze staan achter de
   klasse omdat E1 belooft dat er met de schakelaar uit niets verandert. Gaat die aan, dan mogen ze onvoorwaardelijk. */
.kaart-flow--archief .kostraster > .kieskaart:last-child:nth-child(3n+1) input { right: auto; left: 16px; }
.kaart-flow--archief #bon .rij-feit b { white-space: nowrap; }
@media (max-width: 600px) {
  .kaart-flow--archief .kostraster > .kieskaart:last-child:nth-child(2n+1) input { right: auto; left: 16px; }
}
.kostboek { padding: 16px; gap: 14px; }
.kostboek__beeld { padding: 16px; }
.kostboek__tekst .h3 { font-size: 22px; line-height: 1.2; }
.kostboek__tekst .klein { font-size: 13.5px; line-height: 1.45; }
.kostboek__tekst .pkaart__meta { font-size: 12px; line-height: 1.35; margin-top: 6px; }
/* DE KAARTEN VAN B IN DE BESTELFLOW, scherm 7 (19 september 2026: "ook in de maak flow"). Een kaart is
   een label met het vinkje rechtsboven op het beeldvak; aangevinkt krijgt hij een kobalt rand. Het vinkje is
   het echte veld, dus de tabtoets en een schermlezer werken zoals bij de rijen ervoor. */
.kiesraster { margin: 8px 0 18px; }
.kieskaart { position: relative; cursor: pointer; }
.kieskaart input { position: absolute; top: 16px; right: 16px; z-index: 1; width: 24px; height: 24px; margin: 0; accent-color: var(--kobalt); }
.kieskaart .pkaart__woord > span { display: block; }
.kieskaart.gekozen, .kieskaart:has(input:checked) { border-color: var(--kobalt); box-shadow: inset 0 0 0 1px var(--kobalt); }
.kieskaart:focus-within { outline: 2px solid var(--kobalt); outline-offset: 2px; }
.kieskaart .prijs-klein { font: 800 17px/1 'Archivo', system-ui, sans-serif; color: var(--diep); letter-spacing: -.02em; white-space: nowrap; }

@media (max-width: 1010px) {
  .praster, .praster:last-of-type { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Op smal staan de kaarten onder elkaar en wordt de afstand van de laatste prijs naar de
     volgende rijkop groter dan de sectiemaat toestaat. De kop komt daar dichter op zijn rij. */
  .producten-erbij .rijkop.tweede { margin-top: 10px; }
}
@media (max-width: 600px) {
  /* Punt 12, Ernst 14 september 2026: "op desktop is dit goed, maar op mobile is dit te
     groot". Op een kolom werd elke kaart zo breed als het scherm, met een vierkant beeld
     eronder, en dan is een rij van vijf producten vijf schermen hoog. Twee naast elkaar
     houdt de kaart klein genoeg om te overzien; op 390 px is dat ongeveer 165 px per kaart. */
  .praster, .praster:last-of-type { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* De kaft op de voorbeeldpagina. Op de voorpagina staat het boek rechtop naast de belofte; hier
   ligt het iets gedraaid op het papier, alsof het is neergelegd om open te slaan. Hetzelfde
   meedrijven op de scrol doet beweging.js, want die zoekt .boek .drijf en niet de voorpagina. */
.boek--gelegd { transform: rotate(-2.5deg); }
/* Dezelfde papierschaduw als onder het boek op de voorpagina en onder de bladen; een eigen
   dekking verzinnen maakt een tweede schaduw in het systeem en de kleurpoort weigert hem. */
.boek--gelegd .kaft { box-shadow: 0 1px 0 rgba(18, 50, 92, .14), 0 24px 60px -30px rgba(18, 50, 92, .35); }
@media (prefers-reduced-motion: reduce) { .boek--gelegd { transform: none; } }


/* De inhoudsopgave van de lezer. Eerst een rij genummerde knoppen; op ware grootte bleek dat
   met twintig hoofdstukken vijf regels en 260 px hoog te worden op een telefoon, vóór het boek
   zelf, en een nummer zegt niet waar een hoofdstuk over gaat. Nu een uitklaplijst met de namen:
   één regel tot je hem opent, en hij werkt zonder javascript. De links zijn ankers. */
.hinhoud { margin-top: var(--regel); border-top: 1px solid var(--lijn); padding-top: var(--regel); }
.hinhoud summary { cursor: pointer; list-style: none; min-height: var(--raakvlak);
  display: flex; align-items: center; gap: 8px; color: var(--kobalt);
  font: 400 var(--t-klein)/1.2 'Atkinson Hyperlegible', system-ui, sans-serif; }
.hinhoud summary::-webkit-details-marker { display: none; }
.hinhoud summary::after { content: ''; width: 8px; height: 8px; border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 200ms var(--verloop); }
.hinhoud[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.hlijst { list-style: none; padding: 0; margin: var(--regel) 0 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 2px; }
.hlijst a { display: flex; align-items: center; gap: 12px; min-height: var(--raakvlak);
  padding: 4px 8px; text-decoration: none; color: var(--diep); border-radius: var(--r-m); }
.hlijst a:hover { background: var(--vlak); }
.hlijst .hnr { font: 400 var(--t-klein)/1 'IBM Plex Mono', monospace; color: var(--oker-tekst);
  min-width: 22px; }


/* ---------------------------------------------------------------- de toestemmingsbalk
   Hij ligt onder aan het scherm en schuift de bladzijde niet op: een balk die de inhoud
   verspringt op het moment dat iemand aan het lezen is, is erger dan de vraag zelf.
   De knoppen staan naast elkaar en wikkelen op een telefoon onder de tekst. */
.toestemming {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  /* Punt 3, Ernst: de balk stond op --diep en dat is een tweede blauw onder het kobalt van de
     opening. Nu de kleur van de bladzijde zelf, met een lijn erboven zodat hij toch een balk
     blijft en niet in de voet oplost. De twee knoppen houden hun ene maat en hun twee
     kleuren; op papier is de kobalte knop de sterkste en de witte de tweede, en ze zijn even
     groot, wat bij een cookievraag de bedoeling is. */
  background: var(--papier); color: var(--diep);
  border-top: 1px solid var(--lijn);
  box-shadow: 0 -2px 24px rgb(18 50 92 / .10);
}
.toestemming__in {
  width: min(100% - 2 * var(--rand), var(--kolom)); margin-inline: auto; padding: 18px 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px;
}
.toestemming__t {
  font: 800 var(--t-mono)/1.3 'Archivo', system-ui, sans-serif;
  letter-spacing: .16em; text-transform: uppercase; color: var(--oker-tekst);
  flex: 0 0 100%;
}
.toestemming__p { font-size: var(--t-klein); line-height: 1.5; color: var(--tekst-zacht); flex: 1 1 32ch; margin: 0; }
.toestemming__knoppen { display: flex; gap: 10px; flex-wrap: wrap; }

/* De meldingen bij het aanmeldformulier. Ze staan in het document en zijn verborgen;
   js/aanmelding.js kiest welke er zichtbaar wordt. Wat een melding ZEGT is een besluit
   van wie de bladzijde schrijft, WELKE er nu geldt van het script. */
.melding { border-left: 3px solid currentColor; padding-left: 12px; }
/* PUNT 6, EN DIT WAS EEN FOUT VAN VANOCHTEND. `#ev-done` draagt `hidden` en hoort dus weg tot
   iemand zijn adres heeft achtergelaten, maar `.voet .melden` zet `display: flex` en een
   klasseregel wint van het `hidden`-attribuut. Daardoor stond "Genoteerd. U hoort van ons..."
   altijd in de voet, onder een formulier dat nog niet was ingevuld. */
[hidden] { display: none !important; }
.voet .melding--fout { color: var(--oker-op-blauw); }
.voet .melding--goed { color: var(--wit); }


/* ------------------------------------------------------------------ de ikoonknop
   EÉN KNOP VOOR ALLES DAT EEN TEKEN DRAAGT EN GEEN WOORD, 15 september 2026 (Ernst, Comments 2).
   Tot die dag had de afspeelknop van een stem in de flow geen klasse (kaal), droeg de bladeraar
   een eigen pil met tekst, en stond de filmknop op de homepagina in een derde vorm. Nu: rond,
   ter grootte van het raakvlak, kobalt op wit met een kobalt rand; ingedrukt (aria-pressed) wit
   op kobalt. Twee tekens erin, `__uit` en `__aan`, en aria-pressed kiest welke zichtbaar is.
   De bladeraar draagt dezelfde regels in zijn schaduwwortel (js/bladeraar.js), met de kleuren
   als getal omdat een schaduwwortel de tokens niet ziet; verander je dit, verander daar mee. */
.ikoonknop, .js .filmknop {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: var(--raakvlak); height: var(--raakvlak); min-height: var(--raakvlak); padding: 0;
  border: 1.5px solid var(--kobalt); border-radius: 999px; background: var(--wit); color: var(--kobalt);
  cursor: pointer; line-height: 0; transition: background 200ms, color 200ms, transform 200ms;
}
.ikoonknop:hover, .js .filmknop:hover { background: var(--papier); border-color: var(--diep); color: var(--diep); }
.ikoonknop[aria-pressed="true"], .js .filmknop[aria-pressed="true"] { background: var(--kobalt); color: var(--wit); }
.ikoonknop:disabled { opacity: .35; cursor: default; }
.ikoonknop:focus-visible, .js .filmknop:focus-visible { outline: 2px solid var(--kobalt); outline-offset: 3px; }
.ikoonknop__aan { display: none; }
.ikoonknop[aria-pressed="true"] .ikoonknop__uit { display: none; }
.ikoonknop[aria-pressed="true"] .ikoonknop__aan { display: inline; }

/* ------------------------------------------------------------------ de productrij
   Van links naar rechts: vinkje, beeld, naam met de regel eronder, prijs; een lijn ertussen.
   Dezelfde rij op scherm 6 (dicht, in een <summary>) en op scherm 7. */
.keuzerij--product { grid-template-columns: auto 64px 1fr auto; }
.keuzerij__beeld { width: 64px; height: 64px; border-radius: var(--r-s); background: var(--vlak); overflow: hidden; }
.keuzerij__beeld img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Het vinkje van Het Familiearchief op scherm 7 (20 september 2026). Dezelfde rijvorm als de producten erboven,
   maar het is de laatste rij in zijn eigen strook, dus zonder de haarlijn eronder: die zou een lege band suggereren.
   De zin loopt door als gewone tekst en niet als de twee regels van een productnaam. */
.keuzerij--toestemming { border-bottom: 0; align-items: start; }
.keuzerij--toestemming input { margin-top: 2px; }
.keuzerij--toestemming > span { display: block; max-width: 60ch; }
.keuzerij .prijs-klein { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; color: var(--diep); letter-spacing: -.02em; white-space: nowrap; }
.vraag.keuze summary { grid-template-columns: auto 1fr auto auto; align-items: center; }
.vraag.keuze summary .keuze__vink { width: 22px; height: 22px; accent-color: var(--kobalt); margin: 0; cursor: pointer; }
.vraag.keuze summary .prijs-klein { color: var(--diep); }
.rij-feit--los { border-bottom: 0; }

/* ------------------------------------------------------------------ de bon
   Regels zonder lijn; een lijn boven de eerste btw-regel en boven het totaal. */
#bon .rij-feit, .rij-feit--regel { border-bottom: 0; padding: 6px 0; }
#bon .rij-feit--eerste { border-top: 1px solid var(--lijn); margin-top: 8px; padding-top: 12px; }
#bon .rij-feit--som { color: var(--tekst-zacht); }
#bon .rij-feit--totaal { border-top: 1px solid var(--lijn); margin-top: 8px; padding-top: 12px; font-weight: 700; }
#bon .rij-feit--totaal b { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; }

/* ------------------------------------------------------------------ het winkelmandje
   Een icoon in de kop met een teller, en een lade van rechts. Het script (js/mandje.js) zet de
   knop in de kop en de lade in de body; zonder script staat er niets, want dan valt er niets op
   te halen. Op de site en in de flow dezelfde kop, dus dezelfde regels. */
/* Het mandje in de kop is doorzichtig en draagt de kleur van de navtekst (Ernst, 16 september 2026):
   geen rand, geen vlak; op de blauwe opening dus in de vlakkleur en daarna in kobalt, net als de links. */
/* WAAR HET STAAT, Ernst, 16 september 2026: rechts bij de knop, en alleen als er iets in zit. Gemeten op de
   live site die dag: op 1280 px stond het mandje alleen aan de rechterrand, 80 px voorbij "Begin met een
   naam", en op 390 px zweefde het midden in de balk tussen merk en menuknop. De kop is een rij met
   ruimte-ertussen en het mandje was het derde kind. Nu: het menu (met de knop als laatste) schuift naar
   rechts en het mandje staat er strak naast; op de telefoon staat het naast de menuknop. Leeg is het weg:
   niemand rekent af vanuit het mandje, het onthoudt alleen wat op een productpagina is aangevinkt tot
   scherm 7, en een leeg icoon trekt de aandacht van de knop die wel iets doet. De teller is de schakelaar:
   `.mandje__tel` is leeg zolang het mandje leeg is (js/mandje.js), en :has leest dat. */
.kop nav { margin-left: auto; }
.kop .mandje { position: relative; margin-left: -8px; background: none; border: 0; color: var(--kobalt); }
.kop .mandje:has(.mandje__tel:empty) { display: none; }
/* Op de telefoon (het menu is dan een knop) staat het mandje naast die knop. Deze regel staat hier en niet
   bij de andere telefoonregels van de kop, omdat hij na `.kop .mandje` hierboven moet komen om te winnen. */
@media (max-width: 1010px) { .kop .mandje { margin-left: auto; margin-right: -8px; } }
.kop .mandje:hover { background: none; color: var(--diep); }
.kop .mandje[aria-expanded="true"] { background: none; color: var(--diep); }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) .mandje { color: var(--vlak); }
body:has(.opening.op-blauw) .kop:not(.gewisseld):not(.open) .mandje:hover { color: var(--wit); }
.kop .mandje__tel { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--oker); color: var(--wit); font: 800 11px/18px 'Archivo', system-ui, sans-serif; text-align: center; }
.kop .mandje__tel:empty { display: none; }
.mandje-lade { position: fixed; inset: 0; z-index: 40; display: none; }
.mandje-lade[open] { display: block; }
.mandje-lade__grond { position: absolute; inset: 0; background: rgba(18, 50, 92, .35); }
.mandje-lade__vel { position: absolute; top: 0; right: 0; bottom: 0; width: min(440px, 100%); background: var(--papier);
  display: flex; flex-direction: column; box-shadow: -12px 0 40px rgba(18, 50, 92, .18); }
.mandje-lade__kop { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--lijn); }
.mandje-lade__lijf { flex: 1; overflow: auto; padding: 8px 24px; }
.mandje-lade__voet { padding: 20px 24px; border-top: 1px solid var(--lijn); display: flex; flex-direction: column; gap: 14px; }
.mandje-lade .knop { width: 100%; }
.mandje-regel { display: grid; grid-template-columns: 1fr auto; gap: 4px 16px; padding: 14px 0; border-bottom: 1px solid var(--lijn); align-items: baseline; }
.mandje-regel__naam { font-weight: 700; color: var(--diep); }
.mandje-regel__prijs { font: 800 var(--t-getal-klein)/1 'Archivo', system-ui, sans-serif; color: var(--diep); white-space: nowrap; }
.mandje-regel__doen { grid-column: 1 / -1; display: flex; gap: 18px; font-size: var(--t-klein); }
.mandje-regel__doen a, .mandje-regel__doen button { background: none; border: 0; padding: 0; color: var(--kobalt); text-decoration: underline; cursor: pointer; font: inherit; }
.mandje-leeg { padding: 32px 0; color: var(--tekst-zacht); }
