/* CampingCloud — etalagepagina (apex).
   Handgeschreven CSS, geen build, geen framework, geen externe bron.
   De kleuren zijn de tokens uit client/src/index.css, zodat de etalage
   familie is van de backoffice.

   LET OP bij wijzigen:
   - --woud-solid is ELK gevuld vlak met witte tekst en blijft in beide modi
     #394F26. --woud is voor koppen en linktekst op lichte vlakken en kantelt
     in donkere modus naar een lichtgroen. Verwissel ze niet.
   - De grijsschaal is in donkere modus OMGEKEERD: --gray-50 is daar de
     donkerste en --gray-900 de lichtste.
   - --gras nooit als tekstkleur op wit: dat haalt 4,5:1 niet.
   - Beweging heeft hier een functie: de kleurvlekken maken het widgetglas
     zichtbaar, de hero-shader maakt rook en de modulekaarten reageren bij een
     muis of trackpad op de aanwijzer. Alles staat stil bij reduced-motion. Voeg geen
     beweging bij zonder eerst dezelfde vraag te beantwoorden: wat toont die
     beweging dat een stilstaand beeld niet toont?

   TWEE LETTERS, NIET MEER: koppen (h1/h2/h3), de merknaam en het ronde
   merkvlak staan in Fraunces (zelf gehost, zie @font-face verderop); al het
   andere blijft Inter/system. Zet geen derde familie ertussen.

   DE TYPOGRAFISCHE LADDER — hier bijblijven, niet ertussenin gaan zitten.
   Deze pagina telde op 17-08-2026 achttien lettergroottes, waaronder de reeks
   13 / 13,5 / 14 / 14,5 / 15 / 15,5 px: allemaal losse afstellingen per blok,
   en een halve pixel draagt geen hiërarchie. Wat er nu staat:

     11px  bovenkop in kapitalen (.label)
     12px  tabelkop in kapitalen
     13px  bijschrift, trefwoordpil, codeblok
     14px  microtekst — voorbeeldbalk, zoekbrugbijschrift, stroomchip, themaknop
     15px  secundaire tekst — .klein, kaart- en puntenalinea's, lijstregels,
           knoppen, tabelcellen
     17px  lopende tekst (body)
     18px  h3 en de merknaam
     clamp(24,3.4vw,28)  h2, ook op het groene vlak
     clamp(30,5.4vw,44)  h1
     24px  is géén tekstmaat maar de letters in het ronde merkvlak.
     clamp(24,4.5vw,30)  hoort alleen bij de losse 404-/betaalpagina.

   Regellengte: 52ch naast trefwoordpillen, 60ch als normale lange regel, 68ch
   in het brede eerlijkheidsvlak. Andere waarden zijn afstelling, geen systeem. */

:root {
  /* ⚠️ VERTELT DE BROWSER DAT DEZE PAGINA ZELF EEN DONKERE STAND HEEFT.
     Zonder deze regel gaat Chrome ervan uit dat de pagina alleen licht kan, en
     zet hij bij een donkere systeeminstelling zijn eigen automatische
     inversie aan — bovenóp onze eigen donkere kleuren. Dat geeft twee lagen
     donker, omgekeerde afbeeldingen en scrollbalken die niet meer bij de rest
     passen. Met `light dark` zegt de pagina: ik regel het zelf, laat mijn
     kleuren met rust, en teken alleen de systeemonderdelen (scrollbalken,
     formulierbesturing) in de juiste stand.
     Gevonden bij het narekenen van de etalage in donkere modus, 16-08-2026. */
  color-scheme: light dark;

  /* ⚠️ EN DAAROM WORDT HIJ HIERONDER GEPIND ZODRA DE BEZOEKER ZELF KIEST.
     `light dark` betekent: volg het SYSTEEM. Kiest iemand met een licht systeem
     hier de donkere stand, dan is de pagina donker terwijl zijn gebruikte
     color-scheme licht blijft — en dat is precies waar het glas op stukliep.
     Chrome maakt het canvas van een iframe namelijk DEKKEND zodra de
     color-scheme van dat iframe verschilt van die van de omliggende pagina. De
     widget pint zijn eigen scheme op de luminantie van zijn kaart (analytics.js),
     dus dan staat er donker tegenover licht en verft Chrome een ondoorzichtig
     vlak achter de widget. Gemeten in een losse proef: gelijke schemes → de
     achtergrond van de ouderpagina schijnt door (rgb 228,53,64 van de testkleur);
     ongelijke schemes → rgb(18,18,18), een dicht vlak. Dat is waarom er in de
     donkere stand niets van de kleurvlekken te zien was.
     De twee regels hieronder houden het gebruikte schema gelijk aan wat de
     bezoeker ziet — in beide richtingen, want een donker systeem plus een
     bewuste keuze voor licht gaf een dekkend WIT vlak. */
}
:root[data-thema="donker"] { color-scheme: dark; }
:root[data-thema="licht"] { color-scheme: light; }
:root {
  /* De dekking van de drie kleurvlekken achter het glas. Als variabele en niet
     als vaste waarde in de rgba(), omdat ze in de donkere stand een heel andere
     orde van grootte hebben — zie het donkerblok verderop. */
  --bol-alfa-groen: .78;
  --bol-alfa-geel: .90;
  --bol-alfa-teal: .50;

  --woud: #394F26;
  --woud-solid: #394F26;
  --zon: #FFDC00;
  --gras: #6CAA2E;
  --duinen: #F9F2A7;
  /* Tegel achter de modulepictogrammen: een groene zweem tussen wit en
     --gras in; in het donker een trap boven --surface. */
  --tegel: #EDF3E3;

  --surface: #FFFFFF;
  --bg: #F9FAFB;
  --gray-50: #F9FAFB;
  --gray-200: #E5E7EB;
  --gray-300: #D1D5DB;
  --gray-500: #6B7280;
  --gray-600: #4B5563;
  --gray-700: #374151;
  --gray-800: #1F2937;

  /* ⚠️ GEEN GEKLEURDE VLEKKEN MEER OP DE PAGINA ZELF (17-08-2026).
     Hier stonden drie radiale vlekken over dit verloop heen — dezelfde truc als
     achter de widgets. Sinds die vlekken dáár bewegen en dus echt iets doen,
     concurreerden de stilstaande vlekken hier alleen nog met de widget: twee keer
     hetzelfde effect vlak naast elkaar, waarvan er één niets betekent.
     Wat blijft is één rustig diagonaal verloop, genoeg om de sectie van de witte
     pagina te onderscheiden. Wil je hier ooit weer kleur, doe het dan niet met
     radiale vlekken — dan lijkt het glas van de widget een toevallige voortzetting
     van de achtergrond in plaats van iets van de widget zelf. */
  --sfeer: linear-gradient(135deg, #eef3ea, #f5f1e2 55%, #e9f1e8);

  /* De nauwelijks zichtbare, groen getinte kaartschaduw van de backoffice. */
  --kaart-schaduw: 0 1px 2px rgba(28, 35, 24, .06), 0 1px 3px rgba(28, 35, 24, .04);

  /* Het glas van de kop. Geen var(--surface) met een alfa erachter: die kleur
     is dekkend bedoeld en zou in de donkere stand een heel andere dekking
     nodig hebben. Twee losse waarden is eerlijker dan één die twee keer iets
     anders moet betekenen. */
  --kop-glas: rgba(255, 255, 255, .72);
  --kop-rand: rgba(28, 35, 24, .10);
  --kop-sluier: linear-gradient(to bottom, rgba(255, 255, 255, .55) 0%, rgba(255, 255, 255, .22) 55%, rgba(255, 255, 255, 0) 100%);
}

/* ── Handmatige keuze wint van het systeem ──────────────────────────────────
   /assets/thema.js zet data-thema op <html>. Twee selectoren, want het moet
   allebei kanten op werken: een bezoeker met een LICHT systeem die donker kiest
   (:root[data-thema="donker"]) én een met een DONKER systeem die licht kiest —
   die laatste kan alleen door de media-query hieronder uit te sluiten, vandaar
   de :not() daar. Zonder die :not() zou "licht kiezen" op een donker systeem
   niets doen, omdat de media-query even specifiek is en later staat. */
:root[data-thema="donker"] {
  /* ⚠️ In het donker moeten de kleurvlekken juist ZWAK zijn, en dat is geen
     smaakverschil maar dezelfde som andersom. Op licht staat er donkere tekst op
     een lichte kaart en mag de achtergrond niet té donker worden; op donker staat
     er lichte tekst op een donkere kaart en mag de achtergrond niet te LICHT
     worden. De gedempte tint komt daar uit op rgb(161,163,162), en die haalt
     4,5:1 zolang wat erachter ligt onder luminantie 0,042 blijft — de kale kaart
     zit op 0,007, dus er is weinig ruimte. Doorgerekend op de stapel van alle
     drie: 0,0415. Op de dekkingen van de lichte stand zou datzelfde punt op 0,25
     uitkomen, ruim zes keer over de grens.
     Het ziet er niet zwak uit: tegen een bijna zwarte kaart is een beetje kleur
     al goed te zien. */
  --bol-alfa-groen: .22;
  --bol-alfa-geel: .15;
  --bol-alfa-teal: .32;

  --woud: #A8C586;
  --woud-solid: #394F26;
  --zon: #FFDC00;
  --gras: #7CB937;
  --duinen: #4A421E;
  --tegel: #28311E;

  --surface: #1E241A;
  --bg: #161B12;
  --gray-50: #161B12;
  --gray-200: #2D3525;
  --gray-300: #3C4632;
  --gray-500: #9AA88B;
  --gray-600: #B6C2A5;
  --gray-700: #D0D9BF;
  --gray-800: #E6ECDD;

  --sfeer: linear-gradient(135deg, #0f130c, #0d120e 55%, #0b0f0c);

  --kaart-schaduw: 0 1px 2px rgba(0, 0, 0, .30), 0 1px 3px rgba(0, 0, 0, .20);

  /* In het donker mag het glas dieper: een lichte sluier over een donkere
     pagina wordt grijs en trekt juist de aandacht. */
  --kop-glas: rgba(18, 23, 15, .66);
  --kop-rand: rgba(255, 255, 255, .10);
  --kop-sluier: linear-gradient(to bottom, rgba(6, 9, 5, .62) 0%, rgba(6, 9, 5, .28) 55%, rgba(6, 9, 5, 0) 100%);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-thema="licht"]) {
    /* Zwakke kleurvlekken; de onderbouwing staat bij het blok hierboven. */
    --bol-alfa-groen: .22;
    --bol-alfa-geel: .15;
    --bol-alfa-teal: .32;

    --woud: #A8C586;
    --woud-solid: #394F26;
    --zon: #FFDC00;
    --gras: #7CB937;
    --duinen: #4A421E;
    --tegel: #28311E;

    --surface: #1E241A;
    --bg: #161B12;
    --gray-50: #161B12;
    --gray-200: #2D3525;
    --gray-300: #3C4632;
    --gray-500: #9AA88B;
    --gray-600: #B6C2A5;
    --gray-700: #D0D9BF;
    --gray-800: #E6ECDD;

    --sfeer: linear-gradient(135deg, #0f130c, #0d120e 55%, #0b0f0c);

    --kaart-schaduw: 0 1px 2px rgba(0, 0, 0, .30), 0 1px 3px rgba(0, 0, 0, .20);

    /* Zelfde waarden als in het blok hierboven. */
    --kop-glas: rgba(18, 23, 15, .66);
    --kop-rand: rgba(255, 255, 255, .10);
    --kop-sluier: linear-gradient(to bottom, rgba(6, 9, 5, .62) 0%, rgba(6, 9, 5, .28) 55%, rgba(6, 9, 5, 0) 100%);
  }
}

/* ── Basis ─────────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

/* ── Koplettertype ────────────────────────────────────────────────────────
   Fraunces (SIL OFL, licentie in /assets/fonts/OFL.txt), ZELF gehost — de
   regel "geen externe lettertypen" gaat over derde partijen, niet over eigen
   bestanden; font-src 'self' in de CSP dekt dit al. De bestanden komen van
   Google Fonts' subset-API met de SOFT-as vastgezet op 100 en WONK op 0:
   dat geeft de zachte, ronde schreven (de Recoleta-look) — download je ooit
   nieuwe bestanden, hou die as-waarden aan, anders staat er ineens een
   scherpe hoge-contrast-serif. Het gewicht is variabel 300–700 in één
   bestand; latin en latin-ext samen ± 115 kB. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

html { -webkit-text-size-adjust: 100%; }

/* ⚠️ MOET MEE MET EEN PLAKKENDE KOP. Zonder deze regel springt een klik op
   "Bekijk de schermen" (#watererinzit) naar een plek die precies onder de kop
   begint — de eerste regel van de sectie zit dan achter het glas. */
html { scroll-padding-top: 76px; }

body {
  margin: 0;
  font-family: Inter, system-ui, -apple-system, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  font-size: 17px;
  line-height: 1.65;
  font-weight: 400;
  color: var(--gray-700);
  background: var(--bg);
  overflow-x: hidden;
}

/* Koppen in Fraunces (zie @font-face bovenin); de lopende tekst blijft Inter.
   line-height 1.25 i.p.v. 1.2: de serif heeft iets grotere staarten en oren. */
h1, h2, h3 {
  font-family: 'Fraunces', Georgia, 'Times New Roman', serif;
  line-height: 1.25;
  margin: 0;
}
p { margin: 0; }
img, svg { max-width: 100%; }

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

/* Eén zichtbare focusring voor alles wat bediend kan worden. In --woud, niet
   in --gras: een ring van #6CAA2E op wit haalt de 3:1 voor UI-onderdelen niet. */
a:focus-visible, .knop:focus-visible {
  outline: 2px solid var(--woud);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Op het donkergroene merkvlak is --woud onzichtbaar; daar geel. */
.merkvlak a:focus-visible { outline-color: var(--zon); }

.omhulsel {
  max-width: 1040px;
  margin-inline: auto;
  padding-inline: clamp(20px, 5vw, 40px);
}

.strook { padding-block: clamp(48px, 7vw, 76px); }
/* Twee secties op dezelfde achtergrond stapelen hun onder- en bovenpadding:
   gemeten stonden er twee gaten van 152 px in de pagina, zonder kleurwissel of
   lijn ertussen. Dat leest niet als ritme maar als een gat. Secties waar de
   achtergrond wél verspringt (.sfeer, .merkvlak) worden hier niet geraakt, want
   die zijn geen directe sibling van een andere .omhulsel.strook. */
.omhulsel.strook + .omhulsel.strook { padding-top: 0; }

/* Kleine bovenkop boven elke sectie. --gray-500, niet --gray-400: die haalt
   maar 2,54:1 op wit. */
.label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gray-500);
}
/* Op de sfeer-secties een trap donkerder. --gray-500 haalt 4,83:1 op wit en
   4,63:1 op --bg, maar op het sfeer-verloop nog maar 4,29:1 — en onder de
   groene radiale vlek (rgba(108,170,46,.20) op 12% 8%, precies waar het eerste
   label staat) zakt het naar 3,62:1. Dit is 11px vet in kapitalen, dus geen
   "grote tekst": de eis is 4,5:1. --gray-600 komt op 5,67:1 op het donkerste
   punt en is optisch dezelfde trap. Donkere modus was al in orde (5,29–7,46:1)
   en wordt hierdoor alleen lichter. Zelfde ingreep als bij .uitgelicht .label. */
.sfeer .label { color: var(--gray-600); }

h2 {
  font-size: clamp(24px, 3.4vw, 28px);
  font-weight: 600;
  /* geen negatieve letter-spacing meer: die was afgesteld op Inter, de serif
     zet zichzelf al nauw genoeg */
  color: var(--woud);
  margin-top: 6px;
}

.leidend { margin-top: 14px; max-width: 60ch; }
.klein { font-size: 15px; color: var(--gray-600); }

/* ── Skip-link ─────────────────────────────────────────────────────────── */

.overslaan {
  position: absolute;
  left: -9999px;
  top: 0;
}
.overslaan:focus {
  position: fixed;
  left: 12px;
  top: 12px;
  z-index: 10;
  background: var(--surface);
  color: var(--woud);
  border: 1px solid var(--gray-200);
  border-radius: 6px;
  padding: 10px 16px;
  font-weight: 500;
  text-decoration: none;
  box-shadow: var(--kaart-schaduw);
}

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

/* De kop blijft boven in beeld hangen en is van glas: wat eronder doorloopt
   blijft zichtbaar, vervaagd. Dat werkt hier omdat er ECHT iets onderdoor
   schuift — de hero met zijn bewegende achtergrond, en verderop de schermen.

   ⚠️ `sticky` en niet `fixed`. Sticky houdt zijn plek in de opmaak, dus de rest
   van de pagina begint gewoon eronder. Met fixed zou de hero de eerste 66 px
   onder de kop verdwijnen en had elke sectie een compensatie nodig.

   Het wegschuiven bij naar beneden scrollen doet /assets/kop.js door .kop-weg
   te zetten; de beweging zelf staat hier. */
.kop {
  /* ⚠️ HIER STOND `sticky`, MET EEN COMMENTAAR WAAROM DAT BETER WAS DAN
     `fixed`. Dat argument gold zolang de kop bóven de hero stond. Nu moet de
     hero eronderdoor beginnen — de bewegende achtergrond loopt door tot de
     bovenrand van het venster — en dan is fixed juist de goede keuze: hij haalt
     de kop uit de opmaak, zodat de hero op y=0 begint. De compensatie die ik
     toen wilde vermijden staat er nu bewust: .hero-vlak krijgt padding-top
     zodat de tekst niet achter het glas valt. Eén sectie die dat weet is
     goedkoper dan de hele pagina die opschuift. */
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* Boven de shader-canvas van de hero (die zit in de sectie eronder) en boven
     de widget-iframes, maar onder de cookiebalk. */
  z-index: 50;
  background: var(--kop-glas);
  border-bottom: 1px solid var(--kop-rand);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  backdrop-filter: blur(14px) saturate(150%);
  transition: transform .32s ease;
}
/* ⚠️ ZONDER backdrop-filter GEEN HALFDOORZICHTIGE KOP. Een browser die het niet
   kent (oudere Firefox met de instelling uit) zou anders door een kop van 72%
   dekking heen naar de bewegende hero kijken, en dat maakt de merknaam
   onleesbaar. Dan liever gewoon dicht. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .kop { background: var(--surface); }
}
.kop-weg { transform: translateY(-100%); }

/* Bovenaan de pagina is de kop niet van glas maar helemaal weg: de hero loopt
   dan tot de bovenrand van het venster door en de merknaam staat er los
   overheen. Zodra je scrolt komt het glas terug, want dan schuift er tekst
   onderdoor die anders onleesbaar wordt. /assets/kop.js zet deze klasse.
   ⚠️ De overgang loopt over background én rand, niet alleen over transform —
   zonder dat verschijnt het glas met een sprong op de eerste pixel scroll. */
.kop {
  transition: transform .32s ease, background-color .25s ease, border-color .25s ease;
}
.kop-bovenaan {
  /* ⚠️ NIET HELEMAAL DOORZICHTIG, MAAR EEN SLUIER DIE NAAR BENEDEN UITLOOPT.
     Kaal doorzichtig zag er goed uit tot de rook een felle wolk pal achter de
     merknaam schoof: lichtgroene letters op lichtgroene wolk, onleesbaar. Deze
     sluier valt niet op als balk — hij heeft geen ondergrens — maar geeft de
     letters altijd iets om op te staan. De hoogte is ruimer dan de kop zelf,
     anders zie je waar hij ophoudt. */
  background: var(--kop-sluier);
  /* ⚠️ ZONDER no-repeat LOOPT ER EEN STREEP OVER DE HERO. Een verloop wordt op
     de PADDING-box geschaald (70 px) maar geschilderd over de BORDER-box
     (71 px), dus die laatste pixelrij toont de eerste tint van het verloop
     opnieuw — een lichte streep in de lichte stand, een donkere in de donkere.
     Gemeten: rij 70 gaf 229 waar de buren op 200 stonden. */
  background-repeat: no-repeat;
  border-bottom-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.kop .omhulsel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-block: 14px;
}

.merk { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.merk-vierkant {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 8px;
  background: var(--zon);
  display: grid;
  place-items: center;
}
/* Het merk is zelf ook geel: het gele vlak eronder vormt de achtergrond ervan,
   dus staat er alleen het groen van de caravan op. Breedte in procenten zodat
   de marge meeschaalt als het vlak van maat verandert. */
.merk-vierkant img { width: 88%; }
/* Merknaam in dezelfde serif als de koppen: zo leest hij als woordmerk. */
.merk-naam { font-family: 'Fraunces', Georgia, serif; color: var(--woud); font-weight: 600; font-size: 18px; }

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

.knop {
  display: inline-block;
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.2;
  padding: 11px 20px;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color .15s, filter .15s, border-color .15s;
}

/* Hoofdactie: de gele .btn-primary uit de backoffice. */
/* ⚠️ De RAND is geen versiering. Het gele vlak haalt tegen de hero-gradient maar
   1,20:1 (gemeten op de live pagina, 17-08-2026): de tekst erin is prima
   leesbaar, maar de knop zelf had geen zichtbare begrenzing — precies wat WCAG
   1.4.11 voor een bedieningselement vraagt. --woud werkt in beide standen: donker
   op licht, licht op donker. */
.knop-geel {
  background: var(--zon);
  color: var(--woud-solid);
  border: 1px solid var(--woud);
  border-radius: 6px;
}
.knop-geel:hover { filter: brightness(.96); }

/* De pilvormige CTA van het inlogscherm. De hover licht het groen op in plaats
   van naar --gras te springen: witte tekst op #6CAA2E haalt 4,5:1 niet. */
.knop-pil { background: var(--woud-solid); color: #FFFFFF; border-radius: 9999px; }
.knop-pil:hover { filter: brightness(1.18); }

/* De rand is --gray-500 en NIET --gray-200. Dit is de enige begrenzing die deze
   knop heeft, en WCAG 1.4.11 vraagt 3:1 voor de omtrek van iets bedienbaars.
   Waar de knop echt staat, haalde --gray-200 dat bij lange na niet: op de
   sfeer-hero 1,07–1,10:1 en op de witte los-kaart van 404.html 1,24:1, met een
   vlak dat daar 1,00:1 tegen zijn ondergrond geeft (wit op wit). In donkere
   modus net zo (1,05–1,47:1). Alleen het woord erin verried dan nog dat het een
   knop was, pal naast de felgele hoofdknop. --gray-500 haalt 3,4:1 op wit en
   3,6:1 op de sfeer. Hover gaat een trap donkerder in plaats van lichter:
   --gray-300 zou het contrast juist wegnemen. */
.knop-ghost {
  background: var(--surface);
  color: var(--gray-700);
  border-color: var(--gray-500);
  border-radius: 6px;
}
.knop-ghost:hover { background: var(--gray-50); border-color: var(--gray-600); }

.knoppen { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

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

.sfeer { background: var(--sfeer); }
/* ⚠️ DE BOVENSTE PADDING DRAAGT DE KOP. Die staat `fixed` en neemt dus geen
   ruimte meer in; zonder deze marge zou het label achter het glas verdwijnen.
   71 px is de hoogte van de kop, plus lucht. Verandert de kop van hoogte, dan
   verandert dit getal mee. */
.hero { padding-top: calc(71px + clamp(64px, 10vw, 120px)); padding-bottom: clamp(72px, 11vw, 132px); }

.hero h1 {
  font-size: clamp(30px, 5.4vw, 44px);
  font-weight: 600;
  color: var(--woud);
  margin-top: 10px;
  max-width: 620px;
}
.hero .klein { margin-top: 22px; max-width: 60ch; }

/* ── Hero met shader-achtergrond ──────────────────────────────────────────
   De hero volgt dezelfde stand als de pagina. In licht ligt donkere rook op
   een warme ondergrond; in donker licht dezelfde rook op uit bijna zwart.

   ⚠️ OOK HIER ZIJN BEIDE DONKERSELECTOREN NODIG. data-thema bedient de eigen
   keuze, de media-query de systeemkeuze zolang licht niet uitdrukkelijk is
   gekozen. Dit is hetzelfde voorrangspatroon als bij de tokens op regel 111. */
.hero-vlak {
  position: relative;
  overflow: hidden;
  /* Ook zonder canvas een afgemaakte hero: dit verloop is waar de shader
     overheen tekent, en wat er staat als WebGL ontbreekt. */
  background: linear-gradient(135deg, #eef3ea, #f5f1e2 55%, #e9f1e8);
}
.sfeer.hero-vlak { background-image: linear-gradient(135deg, #eef3ea, #f5f1e2 55%, #e9f1e8); }

.shaderdoek {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  /* Pas zichtbaar als het script zegt dat er echt getekend wordt; anders zou er
     één beeldje lang een zwart vlak over het verloop staan. */
  opacity: 0;
  transition: opacity .8s ease;
}
.shaderdoek-aan { opacity: 1; }

/* De rook houdt de afmetingen van de hero, maar eindigt niet meer op exact
   dezelfde horizontale lijn. Browsers met CSS-maskers krijgen onder de hero
   een korte, uitvloeiende staart over de volgende sectie. De extra hoogte zit
   alleen in het absoluut geplaatste canvas en vergroot de hero dus niet.

   De zoekbalk blijft erboven liggen door zijn z-index. Zonder masker houden we
   bewust de oude, afgeknipte versie: een rechthoekige canvas-uitloop zou erger
   zijn dan de harde naad die dit oplost. shader.js rekent de ruis nog steeds
   met de echte herohoogte, zodat de wolken in de hero niet worden uitgerekt. */
@supports ((mask-image: linear-gradient(#000, transparent)) or (-webkit-mask-image: linear-gradient(#000, transparent))) {
  .hero-vlak {
    --rook-uitloop: clamp(96px, 12vw, 150px);
    overflow: visible;
  }
  .shaderdoek {
    height: calc(100% + var(--rook-uitloop));
    -webkit-mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--rook-uitloop)), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--rook-uitloop)), transparent 100%);
  }
}

/* De inhoud ligt op het canvas. */
.hero-vlak .omhulsel { position: relative; z-index: 1; }

.hero-vlak .label { color: var(--woud); }
.hero-vlak h1 {
  color: var(--woud);
  text-shadow: none;
}

/* De ghostknop krijgt in licht een doorschijnend wit vlak: herkenbaar als knop,
   zonder het zachte verloop achter de hele bediening weg te schilderen. */
.hero-vlak .knop-ghost {
  background: rgba(255, 255, 255, .55);
  border-color: var(--gray-500);
  color: var(--gray-700);
}
.hero-vlak .knop-ghost:hover { background: rgba(255, 255, 255, .82); border-color: var(--gray-600); }

:root[data-thema="donker"] .hero-vlak {
  background:
    radial-gradient(120% 90% at 72% 18%, #2a2408 0%, rgba(42, 36, 8, 0) 62%),
    linear-gradient(160deg, #12160f 0%, #0d100b 55%, #0a0d09 100%);
}
:root[data-thema="donker"] .hero-vlak .label { color: rgba(255, 220, 0, .85); }
:root[data-thema="donker"] .hero-vlak h1 { color: #FFFFFF; text-shadow: 0 2px 24px rgba(0, 0, 0, .45); }
:root[data-thema="donker"] .hero-vlak .knop-ghost { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .38); color: #FFFFFF; }
:root[data-thema="donker"] .hero-vlak .knop-ghost:hover { background: rgba(255, 255, 255, .14); border-color: #FFFFFF; }

@media (prefers-color-scheme: dark) {
  :root:not([data-thema="licht"]) .hero-vlak {
    background:
      radial-gradient(120% 90% at 72% 18%, #2a2408 0%, rgba(42, 36, 8, 0) 62%),
      linear-gradient(160deg, #12160f 0%, #0d100b 55%, #0a0d09 100%);
  }
  :root:not([data-thema="licht"]) .hero-vlak .label { color: rgba(255, 220, 0, .85); }
  :root:not([data-thema="licht"]) .hero-vlak h1 { color: #FFFFFF; text-shadow: 0 2px 24px rgba(0, 0, 0, .45); }
  :root:not([data-thema="licht"]) .hero-vlak .knop-ghost { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .38); color: #FFFFFF; }
  :root:not([data-thema="licht"]) .hero-vlak .knop-ghost:hover { background: rgba(255, 255, 255, .14); border-color: #FFFFFF; }
}

/* ── Kaarten ───────────────────────────────────────────────────────────── */

.kaarten {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  margin-top: 32px;
}
.kaart {
  background: var(--surface);
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  box-shadow: var(--kaart-schaduw);
  padding: 22px;
}
.kaart svg { display: block; color: var(--woud); }
.kaart h3 {
  font-size: 18px;
  font-weight: 600;
  color: var(--woud);
  margin: 14px 0 10px;
}
.kaart > h3:first-child { margin-top: 0; }
.kaart p { font-size: 15px; line-height: 1.6; }

/* ── De inhoud van de modulekaarten ───────────────────────────────────────
   Opbouw van boven naar onder: pictogramtegel + kop, vinkjeslijst, eventueel
   de widgetbadge, en onderaan de koppeling naar de plek op deze pagina waar
   de module te zien is. De kaart is daarvoor een kolom, zodat de koppeling
   in alle kaarten van een rij op dezelfde onderrand ligt.

   - De pictogrammen delen de 24px-lijnstijl (stroke 1.7, ronde uiteinden)
     met de losse pictogrammen bij "En verder"; hier staan ze op een tegel in
     --tegel zodat de kaartkop meer gewicht krijgt dan een kaal lijntje.
   - De trefwoordpillen worden BINNEN .modulekaarten een lijst met vinkjes en
     haarlijnen: een vinkje betekent "zit in de module", en dat is precies wat
     de pillen al opsomden. Elders blijven .schermpillen gewone pillen. Het
     vinkje is --woud, niet --gras: --gras haalt op wit de 3:1 voor
     betekenisdragende niet-tekst niet (2,9:1).
   - De widgetbadge staat op --duinen en draagt dezelfde groene stip als de
     demoblokken in het widgetblok: zelfde markering, zelfde betekenis.
   Maten uit de ladder: 13px voor de badge (trefwoordpil-maat), 15px voor
   lijstregels en koppeling. */
.modulekaarten .kaart { display: flex; flex-direction: column; align-items: flex-start; }
.kaart-kop { display: flex; align-items: center; gap: 12px; }
.kaart-kop h3 { margin: 0; }
.kaart-tegel {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  background: var(--tegel);
  border-radius: 12px;
  color: var(--woud);
}
.kaart-tegel svg { display: block; }
.modulekaarten .schermpillen { display: block; align-self: stretch; }
.modulekaarten .schermpillen li {
  position: relative;
  padding: 7px 0 7px 26px;
  font-size: 15px;
  color: var(--gray-700);
  background: none;
  border: 0;
  border-radius: 0;
}
.modulekaarten .schermpillen li + li { border-top: 1px solid var(--gray-200); }
.modulekaarten .schermpillen li::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 14px;
  width: 10px;
  height: 5px;
  border-left: 2px solid var(--woud);
  border-bottom: 2px solid var(--woud);
  transform: rotate(-45deg);
}
/* De badge staat direct onder de kaartkop en zegt wáár de module leeft:
   op --duinen met de groene demo-stip als er een widget voor de eigen website
   is, in een neutrale tegel-tint als de module alleen in de backoffice
   bestaat. Elke kaart draagt er precies één. */
p.kaart-widget,
p.kaart-backoffice {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--woud);
  border-radius: 999px;
}
p.kaart-widget { background: var(--duinen); }
p.kaart-widget::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--gras);
  flex: none;
}
p.kaart-backoffice { background: var(--tegel); }

/* ── De "In de maak"-kaart ────────────────────────────────────────────────
   Eén kaart mag beloven wat er nog niet is, zolang hij dat zelf hardop zegt:
   gestippelde rand, een badge zonder vulling, open rondjes in plaats van
   vinkjes (een vinkje betekent "zit erin", en dat is hier nog niet waar) en
   geen koppeling — er is nog niets op deze pagina om naartoe te springen. */
.kaart-komend { border-style: dashed; }
/* Ook de accentlijn blijft uit: die hoort bij modules die er zijn. De extra
   .kaart in de selector is nodig — het accentlijn-blok staat verderop in dit
   bestand en zou anders op volgorde winnen. */
.modulekaarten .kaart.kaart-komend::before { content: none; }
p.kaart-nogniet {
  display: inline-flex;
  align-items: center;
  margin-top: 14px;
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 500;
  color: var(--gray-600);
  border: 1px dashed var(--gray-300);
  border-radius: 999px;
}
.kaart-komend .schermpillen li::before {
  width: 8px;
  height: 8px;
  border: 2px solid var(--gray-300);
  border-radius: 50%;
  transform: none;
  top: 13px;
  left: 2px;
}
.kaart-koppeling {
  margin-top: auto;
  padding-top: 16px;
  font-size: 15px;
  font-weight: 500;
  color: var(--woud);
}

/* ── Bewegende modulekaarten ──────────────────────────────────────────────
   Dit is de dependency-vrije vertaling van een tilt-cardcomponent naar deze
   statische pagina. kaart-tilt.js zet de vier custom properties hieronder per
   animatieframe via de CSSOM-API (element.style.setProperty) — dat valt
   buiten de CSP-controle op het style-attribuut, zie de uitleg in dat
   bestand. De kaart kantelt maximaal 7 graden: genoeg om diepte te zien,
   rustig genoeg om de trefwoorden te blijven lezen. Bij het verlaten gaan
   alleen de hoeken terug naar nul; de glanspositie blijft staan zodat de vlek
   ter plekke uitdooft. Zonder JavaScript zijn alleen de afgeronde kaart,
   accentlijn en rijkere schaduw zichtbaar. */
.modulekaarten .kaarten { perspective: 1200px; }
.modulekaarten .kaart {
  --kaart-rx: 0deg;
  --kaart-ry: 0deg;
  --kaart-glans-x: 50%;
  --kaart-glans-y: 50%;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 14px;
  padding: 24px;
  box-shadow: 0 10px 28px rgba(28, 35, 24, .08), 0 2px 7px rgba(28, 35, 24, .05);
  transform: perspective(1000px) rotateX(var(--kaart-rx)) rotateY(var(--kaart-ry));
  transform-style: preserve-3d;
  transition: transform .28s cubic-bezier(.16, 1, .3, 1),
              box-shadow .28s cubic-bezier(.16, 1, .3, 1),
              border-color .28s ease;
}
.modulekaarten .kaart::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  z-index: 2;
  height: 3px;
  background: linear-gradient(90deg, var(--woud), var(--gras) 58%, var(--zon));
}
.modulekaarten .kaart::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at var(--kaart-glans-x) var(--kaart-glans-y), rgba(57, 79, 38, .18), transparent 52%);
  transition: opacity .24s ease;
}
.modulekaarten .kaart > * {
  position: relative;
  z-index: 1;
  transform: translateZ(18px);
}
.modulekaarten .kaart h3 {
  font-size: 20px;
  letter-spacing: -.01em;
}
.modulekaarten .kaart-tilt-actief {
  will-change: transform;
}
.modulekaarten .kaart-tilt-actief:hover {
  border-color: var(--gray-300);
  box-shadow: 0 18px 42px rgba(28, 35, 24, .14), 0 5px 13px rgba(28, 35, 24, .07);
}
.modulekaarten .kaart-tilt-actief:hover::after { opacity: 1; }


:root[data-thema="donker"] .modulekaarten .kaart {
  box-shadow: 0 12px 30px rgba(0, 0, 0, .26), 0 2px 8px rgba(0, 0, 0, .18);
}
:root[data-thema="donker"] .modulekaarten .kaart::after {
  background: radial-gradient(circle at var(--kaart-glans-x) var(--kaart-glans-y), rgba(255, 220, 0, .15), transparent 52%);
}
:root[data-thema="donker"] .modulekaarten .kaart-tilt-actief:hover {
  box-shadow: 0 20px 46px rgba(0, 0, 0, .42), 0 6px 15px rgba(0, 0, 0, .24);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="licht"]) .modulekaarten .kaart {
    box-shadow: 0 12px 30px rgba(0, 0, 0, .26), 0 2px 8px rgba(0, 0, 0, .18);
  }
  :root:not([data-thema="licht"]) .modulekaarten .kaart::after {
    background: radial-gradient(circle at var(--kaart-glans-x) var(--kaart-glans-y), rgba(255, 220, 0, .15), transparent 52%);
  }
  :root:not([data-thema="licht"]) .modulekaarten .kaart-tilt-actief:hover {
    box-shadow: 0 20px 46px rgba(0, 0, 0, .42), 0 6px 15px rgba(0, 0, 0, .24);
  }
}

/* ── Live voorbeeld: de échte boekingswidget ───────────────────────────────
   Draait op de demo-omgeving. Lezen mag daar sinds 14-08 van buitenaf;
   boeken niet — de widget zegt dat zelf zodra iemand op verzenden drukt.

   Het omhulsel is met opzet terughoudend: een lichte rand en een strookje
   erboven met de mededeling dát het een voorbeeld is. Zonder dat strookje
   denkt een bezoeker dat hij op de site van een camping is beland; met een
   zwaar kader lijkt het een screenshot in plaats van iets waar hij in mag
   klikken. */
/* ⚠️ GEEN EIGEN KADER MEER (17-08-2026). Hier stonden een rand, een radius, een
   schaduw en een grijze titelbalk omheen. Het probleem: de widget tékent zichzelf
   al als kaart met schaduw, en de rijen dáárin zijn ook weer omlijnd. Dat waren
   drie geneste afgeronde rechthoeken en het las als een schermafbeelding in een
   venster met titelbalk, in plaats van als een blok dat gewoon op de pagina staat.
   Wat er nu staat is een bijschriftregel bovenaan en daaronder de widget zelf —
   dezelfde volgorde en hetzelfde stipje als bij de schermen in sectie 2. */
.voorbeeld {
  margin-top: 32px;
  /* Geen achtergrond op DIT blok: het draagt ook de bijschriftregel, en een
     gekleurd vlak daaronder leest als een toevallige band naast de widget. De
     structuur die het glas moet vervagen staat op het iframe zelf, hieronder. */
}

/* Van titelbalk naar bijschriftregel: geen vlak, geen lijn, geen inspringing —
   hij hoort bij de tekst van de sectie en niet bij een venster. */
.voorbeeld-balk {
  display: flex;
  align-items: baseline;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  font-size: 14px;
  color: var(--gray-600);
}
.voorbeeld-balk strong { color: var(--woud); font-weight: 600; }
.voorbeeld-stip {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--gras); flex: none;
}
/* STARTHOOGTE, geen eindhoogte. /assets/voorbeeldhoogte.js vangt het
   hoogtebericht van de widget op en overschrijft deze waarde zodra het binnen is,
   zodat er geen schuifbalk ín het iframe zit. Wat hier staat is dus wat je ziet
   in de milliseconden vóór dat bericht, en wat je houdt als JavaScript uitstaat —
   dan is de widget met een schuifbalk gewoon te gebruiken.
   Ruim genoeg voor de kalenderstap — de hoogste — en op een telefoon meebewegend
   met het scherm zodat het blok nooit
   meer dan driekwart van de pagina opslokt. */
.voorbeeld-frame {
  display: block;
  width: 100%;
  border: 0;
  height: min(76vh, 780px);
  min-height: 520px;
  /* ⚠️ GEEN DEKKEND vlak — dat zou de glaskaart in het iframe zijn eigen kleur
     laten vervagen in plaats van iets met structuur. Het widgetdocument heeft
     zelf html/body op transparent staan.
     Wél deze vier doorschijnende vlekken, en die staan hier met opzet op het
     IFRAME en niet op .voorbeeld: zo dekken ze exact het vlak van de widget en
     lopen ze niet door onder het bijschrift.

     Waarom ze er zijn: de demo staat op stijl 'glas' en daar was op de etalage
     niets van te zien. Gemeten op de live pagina kwam het kaartvlak eruit als
     rgb(251,249,239) tegen rgb(245,240,221) van de pagina — dus doorschijnend,
     het wérkte, maar een blur van 18 px over een egaal crèmeverloop heeft niets
     om te vervagen.
     ⚠️ De vlekken zijn 200 tot 340 px GROOT, en dat is geen smaak: een blur
     veegt alles weg wat kleiner is dan zijn straal. Een eerste poging met een
     stippenraster van 1,5 px was door het glas volledig onzichtbaar.
     Bij een tenant op 'standaard' is de kaart dekkend en zie je hier niets van;
     er verandert dan dus niets. */
  background: transparent;
}

/* ── Lijstjes met icoon ────────────────────────────────────────────────── */

.lijst { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 14px; }
.lijst li { display: flex; align-items: flex-start; gap: 12px; }
.lijst svg { flex: none; margin-top: 3px; color: var(--woud); }

.lijst-breed { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 18px 28px; }

/* ── Randvoorwaarden ───────────────────────────────────────────────────── */

.punten {
  display: grid;
  gap: 26px 32px;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  margin-top: 32px;
}
.punten h3 { font-size: 18px; font-weight: 600; color: var(--woud); margin-bottom: 6px; }
.punten p { font-size: 15px; line-height: 1.6; }

/* ── Uitgelicht blok ───────────────────────────────────────────────────── */

/* Het gele streepje links is hetzelfde accent dat in de zijbalk het actieve
   item markeert — geel als lijn in plaats van als vlak. */
.uitgelicht {
  background: var(--duinen);
  border-radius: 8px;
  box-shadow: inset 3px 0 0 var(--zon);
  padding: clamp(24px, 4vw, 36px);
}
.uitgelicht .label { color: var(--gray-600); }
.uitgelicht p { color: var(--gray-800); max-width: 68ch; }
.uitgelicht p + p { margin-top: 16px; }

/* ── Merkvlak: contact en voettekst ────────────────────────────────────── */

.merkvlak { background: var(--woud-solid); color: #FFFFFF; }
/* Geen eigen maat meer: h2 is h2. Wit op groen maakt een kop niet
   belangrijker, en clamp(26,3.8vw,32) was een tweede h2-schaal zonder reden. */
.merkvlak h2 { color: #FFFFFF; }
.merkvlak p { color: rgba(255, 255, 255, .70); }
.merkvlak a { color: rgba(255, 255, 255, .70); }
.merkvlak a:hover { color: #FFFFFF; }

.merk-rond {
  width: 64px;
  height: 64px;
  border-radius: 9999px;
  background: var(--zon);
  display: grid;
  place-items: center;
  margin-bottom: 22px;
}
/* Smaller dan in het vierkant: een liggend beeld in een cirkel heeft aan de
   hoeken meer lucht nodig, anders raakt de caravan de rand. */
.merk-rond img { width: 70%; }

.contact p { font-size: 18px; font-weight: 300; line-height: 1.6; max-width: 60ch; }
.contact .adres { margin-top: 20px; font-size: 15px; }

/* De opacity-trap 50 haalt op dit groen maar 3,95:1 en 60 net niet (4,46:1).
   Daarom staat de fijne tekst op .64 — optisch dezelfde trap, wel leesbaar. */
.fijn { color: rgba(255, 255, 255, .64); font-size: 14px; }

.voet { border-top: 1px solid rgba(255, 255, 255, .15); padding-block: 28px; }
.voet-regels {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 24px;
}
.voet .fijn { margin-top: 14px; }

/* ── Losse pagina's (betaling-verwerkt, 404) ───────────────────────────── */

.los {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 32px 20px;
}
.los-kaart {
  background: var(--surface);
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  box-shadow: var(--kaart-schaduw);
  padding: clamp(28px, 6vw, 44px);
  max-width: 560px;
  width: 100%;
  text-align: center;
}
.los-kaart .merk-vierkant { margin: 0 auto 20px; }
.los-kaart h1 {
  font-size: clamp(24px, 4.5vw, 30px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--woud);
}
.los-kaart p { margin-top: 16px; }
.los-kaart .knoppen { justify-content: center; }

/* ── Bewegingsvoorkeur ─────────────────────────────────────────────────── */

/* Beweging stopt hier centraal; kaart-tilt.js controleert dezelfde voorkeur en
   zet de kanteling dan niet eens aan. */
@media (prefers-reduced-motion: reduce) {
  /* De rondlopende kleurvlekken achter het glas stoppen; ze blijven staan waar
     ze op dat moment stonden, dus het glas blijft zichtbaar glas. */
  .glasbol { animation: none; }

  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ── Cookiebalk ────────────────────────────────────────────────────────── */

/* De toestemmingsvraag voor de meting (zie /assets/ga.js).

   `display: none` is het uitgangspunt en niet het `hidden`-attribuut: een
   latere `display: flex` hier zou `hidden` stilzwijgend overrulen, en dan staat
   de balk bij iedereen in beeld die al gekozen heeft. Met een klasse kan dat
   niet misgaan.

   Onderaan vastgezet en niet als scherm-vullend blok: de bezoeker moet de
   pagina kunnen lezen terwijl hij de vraag beantwoordt. Een vraag die de
   inhoud gijzelt tot je 'ja' zegt, is geen vrije keuze. */
.cookiebalk { display: none; }

.cookiebalk-zichtbaar {
  display: block;
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 20;
  background: var(--surface);
  border-top: 1px solid var(--gray-300);
  /* Eigen schaduw naar boven; --kaart-schaduw valt de verkeerde kant op. */
  box-shadow: 0 -2px 8px rgba(28, 35, 24, .10);
}

.cookiebalk-binnen {
  max-width: 1040px;
  margin-inline: auto;
  padding: 16px clamp(20px, 5vw, 40px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 28px;
}

/* 58ch houdt de regel leesbaar op een breed scherm; min-width 0 laat hem op een
   telefoon gewoon krimpen in plaats van de knoppen weg te duwen. */
.cookiebalk-tekst {
  margin: 0;
  flex: 1 1 320px;
  min-width: 0;
  max-width: 60ch;
  font-size: 14px;
  color: var(--gray-700);
}

/* De knoppen blijven bij elkaar en vallen als paar onder de tekst op een smal
   scherm. Allebei even groot: weigeren mag niet moeilijker zijn dan akkoord. */
.cookiebalk-knoppen {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  flex: 0 0 auto;
}
.cookiebalk-knoppen .knop { min-width: 132px; text-align: center; }

/* De heropen-knop in de voettekst. Ziet eruit als de links ernaast, maar is een
   <button>: hij gaat nergens heen, hij opent de vraag opnieuw. */
.voet-knop {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: rgba(255, 255, 255, .70);
  text-decoration: underline;
  cursor: pointer;
}
.voet-knop:hover { color: #FFFFFF; }
.voet-knop:focus-visible { outline: 2px solid var(--zon); outline-offset: 2px; }

/* ── De drie kleinere widgetvoorbeelden ────────────────────────────────── */

/* Naast elkaar zodra er ruimte is, onder elkaar op een telefoon. `auto-fit` met
   een minimum van 300px doet dat zonder breekpunten: drie kolommen op een breed
   scherm, twee op een tablet, één op een telefoon. minmax(0, …) omdat een
   grid-spoor anders niet onder de inhoud van het iframe krimpt. */
/* ⚠️ ÉÉN KOLOM, OOK OP EEN BREED SCHERM. Deze drie stonden naast elkaar omdat
   ze compacter zijn dan de boekingswidget. In de praktijk werkte dat tegen ze:
   een widget van ~300 px breed is smaller dan waarvoor hij ontworpen is (de
   boekingswidget rekent op 480 px, de stalling- en evenementformulieren zetten
   hun velden pas naast elkaar boven 620 px), dus je zag drie samengeknepen
   versies in plaats van hoe ze bij een klant op de site staan. Volle breedte is
   een eerlijker demo — dat is het hele doel van dit blok. */
/* De gap is meegegroeid met de schermstroken hierboven (17-08-2026): met 16 px
   liepen de drie voorbeelden optisch in elkaar over, terwijl elk er één op
   zichzelf is. Nu dezelfde ademruimte als tussen de backoffice-schermen, zodat
   de hele pagina één ritme heeft: elk voorbeeld is een blok, met lucht ertussen. */
.voorbeeld-drie {
  display: grid;
  grid-template-columns: 1fr;
  /* GEEN eigen bovengrens meer (17-08-2026). De drie widgets stonden hier eerst
     op 840 en daarna op 720 px omdat ze zichzelf op hun eigen maximum centreerden
     en dan insprongen ten opzichte van hun bijschrift. Sinds ze met `&breedte=vol`
     geladen worden vullen ze de kolom net als de boekingswidget, en hoort die kap
     hier weg — anders staan de drie kleine voorbeelden opnieuw smaller dan het
     grote. Meeschalen naar een telefoon doet het omhulsel zelf. */
  gap: clamp(28px, 4vw, 40px);
  margin-top: clamp(28px, 4vw, 40px);
}

/* De eigen marge van .voorbeeld zou hier bovenop de raster-gap komen. */
.voorbeeld-drie .voorbeeld { margin-top: 0; }

/* Korter dan de boekingswidget: die moet een kalender van twee maanden kwijt,
   deze drie niet. Ook dit is een STARThoogte — voorbeeldhoogte.js past hem aan
   zodra de widget zijn eigen hoogte doorgeeft. */
.voorbeeld-frame-kort {
  height: min(48vh, 420px);
  min-height: 340px;
}

/* De zoekbalk is één regel hoog, geen widget met stappen. Deze starthoogte is
   dus geen ruime schatting maar bijna de eindhoogte: liggend ~75 px, gestapeld
   op een telefoon ~125 px. Daarom hier ook `height` in plaats van een vh-maat —
   meebewegen met de schermhoogte heeft bij een balk geen betekenis.

   ⚠️ 130 px is met opzet de GESTAPELDE hoogte en niet de liggende. Deze pagina
   weet niet hoe breed het iframe straks staat, en te hoog beginnen kost een
   strookje wit dat na het eerste hoogtebericht wegvalt; te laag beginnen zou de
   balk afsnijden zolang JavaScript nog niet aan bod is gekomen — en dán zit de
   knop Zoeken buiten beeld. Liever een half tel wit dan een onbruikbare balk.

   Zonder JavaScript blijft deze hoogte staan; de eigen schuifbalk van het
   iframe vangt het verschil op. */
/* ⚠️ GEEN kleurvlekken achter de ZOEKBALK. Die staan op .voorbeeld-frame en zijn
   bedoeld voor de hoge widgetkaarten: daar zie je ze door het glas als een zachte
   waas. De zoekbalk is maar ~96 px hoog, dus datzelfde patroon valt er in zijn
   volle sterkte dwars doorheen — en dan ligt er groen-geel-teal over de
   belangrijkste bediening van de pagina, inclusief de knop Zoeken. */
/* ── De glasachtergrond: drie kleurvlekken die achter het glas rondlopen ──────
   Waarom er überhaupt iets ligt: de demo staat op stijl 'glas'. Gemeten kwam het
   kaartvlak op de live pagina eruit als rgb(251,249,239) tegen rgb(245,240,221)
   van de pagina — doorschijnend, het wérkte, maar een blur van 18 px over een
   egaal crèmeverloop heeft niets om te vervagen. Er moet dus iets áchter liggen
   dat het glas kan vervormen.

   ⚠️ DE VLEKKEN ZIJN GROOT (60-90 % van de kaart) en dat is geen smaak: een blur
   veegt alles weg wat kleiner is dan zijn straal. Een eerste poging met een
   stippenraster van 1,5 px was door het glas volledig onzichtbaar.

   ⚠️ DE MASKER-EN-CLIPLAAG IS EEN APART ELEMENT, en dat is de les van 17-08.
   Masker en `inset` stonden eerst op de bewegende laag zelf. Maar een masker
   werkt in de eigen ruimte van het element en de transform verplaatst die ruimte
   daarna: bij `translate(.., 6%) scale(1.2)` schoof het uitgemaskeerde deel
   omhoog en gleed de dekkende kant naar beneden voorbij de inset, waar alleen de
   `overflow: hidden` van het omhulsel hem nog afsneed. Resultaat was een
   rechthoekige, verzadigde strook van 8 px onder de kaart — gemeten
   rgb(218,220,127) tegen rgb(237,240,224) van de pagina. Die las als een
   slagschaduw onder de widget, en dat was ook precies wat erover gemeld werd.
   Sinds de clip en het masker op de STILSTAANDE .glaslaag staan kan geen enkele
   beweging er nog onderuit komen. Zet ze dus nooit terug op .glasbol.

   ⚠️ Dit is de ENIGE animatie op deze pagina, en daarmee een uitzondering op de
   regel bovenaan dit bestand. Ze is verdedigbaar omdat ze niets aankondigt en
   nergens om aandacht vraagt: drie traag rondlopende kleurvlekken áchter glas,
   die je alleen ziet omdat het glas ze vervormt. Precies dat maakt zichtbaar dát
   het glas is. Bij `prefers-reduced-motion` staat alles stil. */
.voorbeeld-glas { position: relative; border-radius: 14px; }

/* De laag die clipt en uitvloeit. Stilstaand — zie de waarschuwing hierboven.
   `bottom: 16px`: het iframe is een paar pixels hoger dan de kaart van de widget
   en in die kier ligt geen glas. Wat daar komt, komt er rauw te liggen. */
.glaslaag {
  position: absolute;
  inset: 0 0 16px;
  z-index: 0;
  overflow: hidden;
  border-radius: 14px;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 80px);
  mask-image: linear-gradient(to top, transparent 0, #000 80px);
  transition: opacity .45s ease;
}

/* Tijdelijk gedimd zolang de widget zijn hoogte nog niet gemeld heeft; dan ligt
   er nog geen glas overheen en zou je tegen een blok rauwe kleur aankijken.
   /assets/voorbeeldhoogte.js zet en verwijdert deze klasse — en doet dat in
   deze richting zodat een bezoeker zónder JavaScript de volle kleur houdt in
   plaats van een permanent verbleekte pagina. */
.glas-wacht > .glaslaag { opacity: .2; }

/* Eén vlek. Het ELEMENT is even groot als de laag; de vlek zelf is een radiale
   verloop-schijf díérin, van --bol-b bij --bol-h groot en in het midden geplaatst.

   ⚠️ DAT IS EEN BEWUSTE OMWEG, en de eerste opzet deed het anders: een klein
   element met het middelpunt op de linkerbovenhoek. Percentages in `translate()`
   gaan over de EIGEN maat van het element, dus daar betekende `translate(88%)`
   "88 % van de bolbreedte" en niet "88 % van de kaart". Met bollen van
   verschillende maten legde elke bol een andere afstand af en stonden ze op
   willekeurige momenten alle drie tegelijk buiten beeld — gemeten op de
   stallingskaart: geen enkele vlek zichtbaar. Nu is het element even groot als de
   laag, en betekent `translate(30%, -20%)` gewoon 30 % van de kaartbreedte naar
   rechts en 20 % van de kaarthoogte omhoog. De banen hieronder zijn daardoor te
   lezen zonder rekenwerk. */
.glasbol {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(closest-side, var(--bol-kleur), transparent 100%);
  background-size: var(--bol-b) var(--bol-h);
  background-position: center;
  background-repeat: no-repeat;
  will-change: transform;
}

/* ── Drie kleuren, drie eigen banen ──────────────────────────────────────────
   Drie kleuren uit de huisstijl, en drie banen die elkaar nergens napraten:
   andere hoekpunten, andere volgorde, andere omlooptijd. De tijden (17, 23 en
   29 s) zijn met opzet onderling ondeelbaar — twee vlekken op 16 en 24 s staan
   elke 48 seconden weer precies gelijk, en dán ziet het eruit als één beweging
   met een kopie ernaast. Op deze drie duurt het ruim drie uur voor het beeld zich
   herhaalt.
   Elke baan is een RONDGANG (0 % en 100 % gelijk) en geen heen-en-weer: bij
   `alternate` loopt een vlek zijn eigen spoor terug, en dat ziet het oog.

   ⚠️ DE DEKKINGEN ZIJN DOORGEREKEND, NIET GEKOZEN. Wat de bezoeker ziet is de
   vlek, dan de pagina eronder, en daar de glaskaart (dekking .62) overheen. Voor
   die stapel is per kleur uitgerekend welke luminantie het kaartvlak overhoudt;
   de gedempte tekst van de widget staat sinds 17-08 op 7:1 en verdraagt 0,61:
     geel .90 → 0,86   groen .78 → 0,72   teal .50 → 0,73
     groen ÉN teal over elkaar → 0,64 · alle drie → 0,70
   Teal is de donkerste en stond eerst op .80; dat gaf 0,62 en op de overlap met
   groen 0,58 — daar zakte de gedempte tekst onder de norm. Wil je hem feller,
   verhoog dan eerst TEKST_EIS_GLAS in server/public/widget/analytics.js. */
.glasbol-1 { --bol-b: 78%; --bol-h: 88%; --bol-kleur: rgba(108, 170, 46, var(--bol-alfa-groen)); animation: bol-1 17s linear infinite; }
.glasbol-2 { --bol-b: 72%; --bol-h: 94%; --bol-kleur: rgba(255, 214, 0, var(--bol-alfa-geel));  animation: bol-2 23s linear infinite; }
.glasbol-3 { --bol-b: 84%; --bol-h: 82%; --bol-kleur: rgba(31, 122, 140, var(--bol-alfa-teal)); animation: bol-3 29s linear infinite; }

/* De uitslagen zijn procenten van de KAART (zie de uitleg bij .glasbol). Een
   vlek is 70-85 % van de kaart breed, dus ±44 % schuiven brengt hem van de ene
   rand naar de andere zonder dat de kaart ooit kaal komt te staan. Elke baan
   raakt alle vier de hoeken in een eigen volgorde: dat is wat "een eigen koers"
   hier betekent — niet dezelfde ronde met een andere vertraging. */
@keyframes bol-1 {
  0%   { transform: translate(-40%, -28%) scale(1); }
  25%  { transform: translate(28%, -6%) scale(1.12); }
  50%  { transform: translate(44%, 30%) scale(.96); }
  75%  { transform: translate(-12%, 36%) scale(1.06); }
  100% { transform: translate(-40%, -28%) scale(1); }
}
@keyframes bol-2 {
  0%   { transform: translate(36%, 32%) scale(1.08); }
  26%  { transform: translate(-30%, -24%) scale(.94); }
  52%  { transform: translate(10%, -34%) scale(1.16); }
  78%  { transform: translate(46%, -4%) scale(1); }
  100% { transform: translate(36%, 32%) scale(1.08); }
}
@keyframes bol-3 {
  0%   { transform: translate(-8%, 40%) scale(.98); }
  30%  { transform: translate(42%, -18%) scale(1.1); }
  58%  { transform: translate(-38%, 4%) scale(1.04); }
  82%  { transform: translate(18%, -36%) scale(.92); }
  100% { transform: translate(-8%, 40%) scale(.98); }
}

/* ── Per widget een ander moment in dezelfde baan ────────────────────────────
   Vier keer hetzelfde patroon naast elkaar leest als behang: je ziet dan dat het
   een truc is in plaats van dat elke widget zijn eigen glas heeft. CSS kent geen
   toeval, dus het is met de hand verdeeld: een NEGATIEVE animation-delay zet elke
   vlek op een ander punt van zijn rondgang, meteen bij het laden. Omdat de drie
   omlooptijden onderling ondeelbaar zijn, komt geen enkel tweetal widgets ooit in
   dezelfde stand.
   De kaarten verschillen bovendien in vorm (684 px hoog tegen 420 px), en omdat
   de vlekken in procenten staan levert dezelfde baan daar vanzelf een andere
   kromming op. */
/* ⚠️ ACHTER DE ZOEKBALK LIGT GEEN GLASLAAG MEER (17-08-2026, weggehaald).
   Hier stond `.glaslaag-balk` met een eigen inset en uitvloeier, plus drie
   animation-delays. De reden dat hij weg is: een kleurvlek heeft hoogte nodig om
   onder het glas te verdwijnen, en de zoekbalk is één regel (~85 px liggend). De
   kleur kwam er in de rand ómheen uit en las precies als de omlijsting waar dit
   blok níét over gaat — zie de waarschuwing bij .voorbeeld-frame, die dit al
   voorspelde. Sinds ook de kaart eromheen geen rand en geen padding meer heeft,
   is er helemaal geen vlak meer waar zo'n vlek zinnig onder kan liggen.
   Wil je de balk ooit tóch glas geven, geef hem dan éérst hoogte — anders komt
   dezelfde kleurrand terug. */

#probeerhet .glasbol-1 { animation-delay: -3s; }
#probeerhet .glasbol-2 { animation-delay: -11s; }
#probeerhet .glasbol-3 { animation-delay: -19s; }

.voorbeeld-drie .voorbeeld:nth-of-type(1) .glasbol-1 { animation-delay: -9s; }
.voorbeeld-drie .voorbeeld:nth-of-type(1) .glasbol-2 { animation-delay: -2s; }
.voorbeeld-drie .voorbeeld:nth-of-type(1) .glasbol-3 { animation-delay: -24s; }

.voorbeeld-drie .voorbeeld:nth-of-type(2) .glasbol-1 { animation-delay: -14s; }
.voorbeeld-drie .voorbeeld:nth-of-type(2) .glasbol-2 { animation-delay: -17s; }
.voorbeeld-drie .voorbeeld:nth-of-type(2) .glasbol-3 { animation-delay: -6s; }

.voorbeeld-drie .voorbeeld:nth-of-type(3) .glasbol-1 { animation-delay: -6s; }
.voorbeeld-drie .voorbeeld:nth-of-type(3) .glasbol-2 { animation-delay: -20s; }
.voorbeeld-drie .voorbeeld:nth-of-type(3) .glasbol-3 { animation-delay: -13s; }

/* Het iframe erbovenop; zonder deze regel stapelt de glaslaag eroverheen. */
.voorbeeld-glas > .voorbeeld-frame { position: relative; z-index: 1; }

.voorbeeld-frame-balk {
  height: 130px;
  min-height: 0;
}

/* ── De zoekbalk op de rand van de hero ────────────────────────────────────
   De balk hangt half over de hero en half over de sectie eronder. Dat is het
   patroon van elke boekingssite (Booking, Harderzee, Goedehope) en het doet
   inhoudelijk iets: het zegt "hier begint het zoeken", nog vóór de eerste
   verkoopzin.

   ⚠️ DE NEGATIEVE MARGE ZIT OP DE BRUG, NIET OP DE HERO.
   De hero is een `.sfeer`-sectie met een verlopende achtergrond. Zou je hém
   omhoogtrekken of laten overlopen, dan verschuift de rand van dat verloop mee
   en verschilt de kleur onder de balk per schermbreedte. Nu blijft de sectiegrens
   waar hij is en schuift alleen de balk eroverheen — de rand loopt zichtbaar
   ácht​er de kaart door, wat precies het bedoelde effect is.

   De waarde is met opzet KLEINER dan de halve kaarthoogte (~87 px liggend). Bij
   exact de helft zou de kaart op een telefoon — waar de balk stapelt en ~130 px
   wordt — te ver de hero in kruipen en over de laatste tekstregel vallen. 40 px
   straddelt op beide breedtes zichtbaar zonder ooit tekst te raken. */
.zoekbrug {
  position: relative;
  z-index: 2;
  margin-top: -40px;
  /* Deze ruimte hoort bij de brug en niet bij de sectie eronder: zo blijft de
     afstand tot de volgende kop gelijk, ook als de balk van hoogte verandert. */
  margin-bottom: 34px;
}
.zoekbrug-kaart {
  /* Idem: de zoekbalk is glas, dus hier geen dekkend vlak eronder. */
  background: transparent;
  /* ⚠️ GEEN KADER MEER, OP GEEN ENKELE BREEDTE (17-08-2026). Hier stonden een
     rand van 1 px, een radius van 14 en 6 px padding. De widget in het iframe ís
     al een pil met een eigen rand, dus dat leverde twee kaders om één balk — met
     in de 6 px ertussen ook nog de kleurvlekken van de glaslaag, die daar als een
     gekleurde omlijsting naar buiten kwamen.
     Eerst is het kader alleen op de desktop weggehaald en op de telefoon blijven
     staan (de gestapelde balk zou zonder omlijsting uiteenvallen, was de
     gedachte); een uur later is ook dat vervallen — het gaf twee verschillende
     antwoorden op dezelfde vraag, en de gestapelde balk heeft zelf al een radius
     van 16 en een rand. Wat overblijft is de widget en verder niets.
     Wat het losliggen over de sectiegrens draagt: de pil zelf en de negatieve
     marge van .zoekbrug, die hem zichtbaar over de naad tilt. */
  /* ⚠️ GEEN SCHADUW MEER (17-08-2026). Hier stond
     `0 10px 30px rgba(16,32,12,.13), 0 2px 6px rgba(16,32,12,.07)` met als
     redenering: de kaart ligt over de naad tussen de hero en de strook eronder,
     en moet van allebei die achtergronden lósliggen, anders leest hij als een
     vlek op de naad.
     Die redenering klopt nog steeds, maar de schaduw was zwaarder dan de rest
     van de pagina verdraagt — en sinds de widgetkaarten hun slagschaduw kwijt
     zijn, was dit de enige plek waar er nog eentje stond. Wat het losliggen
     draagt is de negatieve marge die hem over de sectiegrens tilt.
     Wordt de balk hierdoor ooit tóch een vlek op de naad, zoek het dan in de
     pil van de widget zelf — niet in een schaduw die terugkomt. */
}
/* Onder de 640 px stapelt de balk tot ~130 px en wordt de overlap krapper;
   dan liever iets minder ver eroverheen dan een kaart die de hero-tekst raakt.

   ⚠️ HIER STOND KORT EEN UITZONDERING: kader wél op de telefoon, niet op de
   desktop. Die is er weer uit — de widget tekent gestapeld zijn eigen omlijsting
   (border-radius 16 en een rand op .mcw-zoekbalk, zie zoeken.html) en had er dus
   nooit een tweede omheen nodig. Wat hier overblijft is alleen de overlap. */
@media (max-width: 640px) {
  .zoekbrug { margin-top: -26px; margin-bottom: 26px; }
}


/* ── Licht/donker-schakelaar in de kop ─────────────────────────────────────
   Klein en rustig: hij hoort bij de navigatie, niet bij de inhoud. Het bolletje
   is een maan die vol wordt in de donkere stand — genoeg om herkend te worden
   zonder een icoonbibliotheek binnen te halen op een pagina die er geen heeft. */
.kop-rechts { display: flex; align-items: center; gap: 10px; }
.thema-knop {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 999px;
  /* --gray-500 en niet --gray-200: die laatste haalde 1,15:1 tegen het kopvlak,
     waardoor de knop als tekst las in plaats van als knop. Op een smal scherm
     verdwijnt bovendien het woord "Donker" en draagt de omtrek hem alleen. */
  border: 1px solid var(--gray-500); background: var(--surface);
  color: var(--gray-700); font: inherit; font-size: 14px; cursor: pointer;
}
.thema-knop:hover { border-color: var(--gray-600); color: var(--gray-800); }
.thema-knop:focus-visible { outline: 2px solid var(--woud); outline-offset: 2px; }
.thema-icoon {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid currentColor;
  /* Wassende maan: een binnenschaduw eet de linkerhelft op. */
  box-shadow: inset 4px 0 0 0 currentColor;
}
.thema-knop[aria-pressed="true"] .thema-icoon { box-shadow: inset 0 0 0 7px currentColor; }
@media (max-width: 560px) { .thema-knop .thema-tekst { display: none; } }

/* ══ Stap 1 van het etalage-ontwerp, 17-08-2026 (docs/ETALAGE_ONTWERP.md) ═════
   Drie bouwstenen die tekst vervangen in plaats van hem te verplaatsen:
   een talentabel, het insluitfragment als codeblok, en de "wat er niet in
   zit"-lijst. Geen nieuwe kleuren, geen nieuwe
   lettergroottes buiten de bestaande reeks, geen animatie, geen JavaScript.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Talentabel: vervangt vijftig woorden proza over welke taal waar geldt.
      Rolt horizontaal in zijn EIGEN omhulsel, zodat de pagina zelf nooit
      horizontaal schuift (body heeft overflow-x: hidden, maar dat verbergt de
      tabel dan gewoon in plaats van hem bereikbaar te houden). ─────────────── */
.taaltabel-rol { overflow-x: auto; margin-top: 22px; }
.taaltabel { border-collapse: collapse; font-size: 15px; min-width: 460px; }
.taaltabel caption { text-align: left; margin-bottom: 10px; }
.taaltabel th, .taaltabel td {
  padding: 8px 14px;
  border-bottom: 1px solid var(--gray-200);
  text-align: left;
}
/* --gray-600 en niet --gray-500, om dezelfde reden als bij .sfeer .label: deze
   tabel staat op het sfeer-verloop en daar haalt --gray-500 nog 4,25:1 (gemeten).
   Dit is 12 px in kapitalen, dus geen grote tekst — de eis is 4,5:1. */
.taaltabel thead th {
  font-size: 12px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--gray-600);
}
.taaltabel td + td, .taaltabel th + th { text-align: center; width: 64px; }
.taaltabel tbody th { font-weight: 400; color: var(--gray-700); }
/* Op een telefoon past de tabel wél in zijn geheel, mits de vier taalkolommen
   smaller worden: 320 px beschikbaar = ~160 voor de rijkop + 4 × 40. Zonder dit
   blok blijft `min-width: 460px` staan en moet de bezoeker zijwaarts vegen om
   FR en EN te zien — precies de twee kolommen waar het verschil in zit. */
@media (max-width: 560px) {
  .taaltabel { min-width: 0; width: 100%; font-size: 14px; }
  .taaltabel th, .taaltabel td { padding: 8px 4px; }
  .taaltabel td + td, .taaltabel th + th { width: 40px; }
}

/* ── Codeblok: het insluitfragment. Tien regels code lezen als beeld en niet
      als tekst, en ze maken "of uw websitebouwer plaatst het" controleerbaar.

      pre-wrap en niet pre: dit blok staat in de tweekoloms .punten-opmaak en is
      daar ~460 px breed, terwijl de <script>-regel er ~530 nodig heeft. Met
      `pre` verdwijnt het einde van die regel achter de rand — met verborgen
      schuifbalken (macOS, en elke schermafdruk) leest dat als een fragment dat
      halverwege ophoudt. Liever een omgeslagen regel dan een onzichtbare.
      De inspringing van de attributen blijft staan, want pre-wrap houdt spaties
      aan het regelbegin. overflow-x blijft als vangnet voor een heel smal
      scherm. ─────────────────────────────────────────────────────────────── */
.codeblok {
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--gray-50);
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.55;
  color: var(--gray-700);
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/* ── Wat er niet in zit: dezelfde feiten als de geschrapte alinea, halve
      gevoelsmassa. Elke regel begint met een WOORD en niet met het symbool, dus
      de betekenis hangt niet aan het kruisje; dat is aria-hidden. ──────────── */
.niet-lijst { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 10px; }
.niet-lijst li { display: flex; align-items: flex-start; gap: 10px; font-size: 15px; }
.niet-lijst svg { flex: none; margin-top: 4px; color: var(--gray-500); }

/* ── Drie overgangen die nergens een marge hadden ──────────────────────────
   Deze onderdelen zijn los toegevoegd en leunden op de marge van hun buur; die
   was er niet. Het resultaat was aangeplakte blokken: de talentabel 22 px na een
   groot widgetkader, en de bijzin en de Duitse afdruk met nul ruimte. */
.voorbeeld-drie + .taaltabel-rol { margin-top: clamp(28px, 4vw, 40px); }
.codeblok + .klein { display: block; margin-top: 10px; }
.klein + .schermstrook { margin-top: clamp(28px, 4vw, 40px); }
/* Deze twee regels zijn er omdat .label en .klein zelf geen marge hebben: elders
   op de pagina staan ze bovenaan een sectie, hier middenin een lopend blok.
   Zonder deze marges plakken de tussenkop en de agendafeed-zin tegen de alinea
   en de lijst ernaast. */
.uitgelicht p + .label { display: block; margin-top: 26px; }
.niet-lijst + .klein { display: block; margin-top: 14px; }

/* ══ Stap 2 van het etalage-ontwerp, 17-08-2026 ══════════════════════════════
   Sectie 2 toont echte schermen in plaats van zes alinea's. De regel achter de
   keuze: beeld alléén waar de boodschap een PATROON is (balken op een raster,
   blokken in een schuur, tafels op een vloer). Een prijsmatrix, een factuur en
   een vragenbouwer zijn tekstschermen; die blijven kaarten, want een uitsnede
   daarvan is op een telefoon een grijze vlek.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Stroomstrip: de weg door het programma. Chips en géén SVG-tekening: zo
      wikkelt hij vanzelf op 320 px, schaalt hij mee met de lettergrootte die de
      bezoeker instelt, is hij selecteerbaar en klopt hij in beide standen
      zonder een tweede bestand. De pijl is de claim "in één programma". ───── */
.stroom { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 26px; }
.stroom-stap {
  display: inline-block;
  padding: 5px 12px;
  border: 1px solid var(--gray-300);
  border-radius: 9999px;
  background: var(--surface);
  font-size: 14px;
  color: var(--gray-700);
  white-space: nowrap;
}
.stroom-pijl { color: var(--gray-500); font-size: 14px; }

/* ── Schermstrook: één scherm op de VOLLE breedte van het omhulsel, met de
      tekst eronder. Beeld naast tekst zou de afdruk tot ~55 % verkleinen en dan
      zijn de letters in het planbord 5 à 6 px — dan toon je een patroon en geen
      scherm. Op volle breedte staat hij op ~83 %. ─────────────────────────── */
.schermronde { margin-top: clamp(32px, 5vw, 48px); display: grid; gap: 0; }

/* Elke module is een eigen blok met een eigen kop, en de scheiding moet je
   kunnen ZIEN: drie schermen onder elkaar met alleen witruimte ertussen leest
   als één lange reeks, en dan is niet duidelijk of een bijschrift bij het beeld
   erboven of erónder hoort. Vandaar de haarlijn plus ruime tussenruimte, en de
   kop bóven het beeld in plaats van eronder. */
.schermstrook { display: grid; gap: 18px; }
/* De haarlijn verantwoordt ruimte aan twee kanten, maar niet twee keer een volle
   sectieafstand: marge plus padding was samen 80-120 px, meer dan de afstand
   tussen hele secties. Nu 56-80 px. */
.schermstrook + .schermstrook {
  margin-top: clamp(28px, 4vw, 40px);
  padding-top: clamp(28px, 4vw, 40px);
  border-top: 1px solid var(--gray-200);
}
/* Van de schermreeks naar "En verder:" stond 14 px — minder dan de 18 px binnen
   één strook, waardoor de nieuwe groep aan de vorige plakte. */
.schermronde + .leidend { margin-top: clamp(28px, 4vw, 40px); }
/* Een klein rondje in de merkkleur vóór de modulenaam: het merkt het begin van
   een blok zonder een tweede lettergrootte of nog een lijn toe te voegen. */
.schermkop {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 18px;
  font-weight: 600;
  color: var(--woud);
  margin-bottom: 8px;
}
.schermkop::before {
  content: "";
  flex: none;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--gras);
}
.schermhoofd p { font-size: 15px; line-height: 1.6; max-width: 52ch; }
.schermpillen { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 0; padding: 0; list-style: none; }
.schermpillen li {
  font-size: 13px;
  color: var(--gray-600);
  background: var(--gray-50);
  border: 1px solid var(--gray-200);
  border-radius: 6px;
  padding: 3px 9px;
}
.schermkader {
  border: 1px solid var(--gray-300);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--kaart-schaduw);
}
/* <picture> is een inline omhulsel; zonder deze regel staat er onder een
   verborgen beeldstand een regelhoogte aan witruimte in het kader. */
.schermkader picture { display: block; font-size: 0; }
.schermkader img { display: block; width: 100%; height: auto; }
.schermbijschrift {
  font-size: 13px;
  color: var(--gray-500);
  padding: 8px 12px;
  border-top: 1px solid var(--gray-200);
  background: var(--gray-50);
}

/* Boven het beeld: kop plus zin links, trefwoorden rechts. Stapelt vanzelf. */
@media (min-width: 720px) {
  .schermhoofd { display: grid; grid-template-columns: 1.25fr 1fr; gap: 28px; align-items: start; }
  .schermhoofd .schermpillen { margin-top: 2px; }
}

/* ── Licht/donker voor de schermafdrukken.
      `<picture media="(prefers-color-scheme: dark)">` valt af: die media-query
      ziet het data-thema-attribuut van de themaknop niet, dus een bezoeker die
      met de knop schakelt houdt het verkeerde beeld. Daarom twee <img>-en die
      met CSS worden gewisseld, allebei lazy en met dezelfde alt — het verborgen
      element valt uit de toegankelijkheidsboom, dus er wordt niets dubbel
      voorgelezen.

      ⚠️ De klasseselector moet mét het element mee (`.schermkader img.scherm-
      donker`): `.schermkader img` hierboven is 0-1-1 en wint van een kale
      `.scherm-donker` (0-1-0). Zonder dat stonden beide standen onder elkaar.
      De :not() is dragend om dezelfde reden als bij de kleurtokens bovenaan:
      zonder hem doet "licht kiezen" op een donker systeem niets. ──────────── */
.schermkader img.scherm-donker { display: none; }
:root[data-thema="donker"] .schermkader img.scherm-donker { display: block; }
:root[data-thema="donker"] .schermkader img.scherm-licht { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-thema="licht"]) .schermkader img.scherm-donker { display: block; }
  :root:not([data-thema="licht"]) .schermkader img.scherm-licht { display: none; }
}

/* De drie kaarten die géén beeld krijgen, dragen wel dezelfde trefwoordpillen.
   .kaart p heeft een eigen regelafstand; de pillen erna houden hun eigen marge. */
.kaart .schermpillen { margin-top: 12px; }
