/* ═══════════════════════════════════════════════════════════
   Vordero Marketing — Shared Design Tokens & Base Styles
   Canonical source: docs/vordero/design/tokens.css
   Updated: 2026-05-29
   ═══════════════════════════════════════════════════════════ */

/* ── RESET ─────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── TOKENS (light mode = default) — Petrol + Slate (design system v2) ── */
:root {
  /* Brand — teal. #0d9488 is de MERK-mark (logo, accenten, labels).
     Interactieve vullingen gebruiken --btn-* hieronder: wit op #0d9488 haalt
     maar ~3.7:1 en zakt onder WCAG AA, wit op teal-700 haalt het wel. */
  --brand:    #0d9488;
  --brand-h:  #0f766e;
  --brand-p:  #134e4a;
  --brand-ll: rgba(13,148,136,.08);
  --brand-md: rgba(13,148,136,.18);

  /* Interactieve vulling (knoppen) — gelijk aan de app z'n --primary */
  --btn-bg:   #0f766e;
  --btn-bg-h: #115e59;
  --btn-fg:   #ffffff;

  /* Light surface (default) — slate */
  --bg:    #f8fafc;
  --bg-2:  #f1f5f9;
  --bg-3:  #e2e8f0;
  --bg-4:  #cbd5e1;

  /* Text — slate. Contrast tegen --bg (#f8fafc):
     text 17.9:1 · text-2 7.2:1 · text-3 5.3:1 · text-4 3.3:1.
     --text-4 haalt AA voor bodytekst NIET en is dus decoratief:
     alleen voor randen, iconen en losse micro-labels, nooit voor zinnen. */
  --text:   #0f172a;
  --text-2: #475569;
  --text-3: #5a6b80;
  --text-4: #7d8b9e;
  /* Tekst op een vlak dat in beide modi donker is: een foto, de nachtband, een
     gevulde merkknop. Bewust géén thema-afhankelijk token, en bewust wél een
     token: DESIGN.md (Tekstveilig, v9) verbiedt een rauwe hex in `color:`,
     ook waar het vlak nooit van kleur verandert, en de poort in
     scripts/ci/checks/productbeeld.mjs leest dat letterlijk. */
  --wit:    #ffffff;
  /* De slagschaduw op een kaart in de nachtband, die in beide modi donker is.
     Dieper dan --shadow-strong, want op nacht is een schaduw van 28% niet te
     zien. Zelfde redenering als --wit: invariant vlak, dus invariant token. */
  --nacht-schaduw: rgba(0, 0, 0, 0.85);

  /* Border */
  --border:   rgba(15,23,42,.08);
  --border-2: rgba(15,23,42,.14);

  /* Status */
  --green: #16A34A;
  --red:   #DC2626;
  --amber: #d97706;

  /* 23-09-2026: tien ongelezen tokens van oude lagen weg (--nav-bg, --deco-*,
     --dot-1px, --cta-*, --pricing-feat-*, --incasso-mid-*). Zie het register
     in docs/vordero/vindbaarheid-2026-08-20/VOORTGANG.md. */
  /* Schaduw — vlak gehouden, gelijk aan de app. Zware drop-shadows lezen
     als landingspagina-sjabloon, vlakke vlakken lezen als software. */
  --shadow-strong: rgba(15,23,42,.07);
  --shadow-card: rgba(15,23,42,.06);
  /* Amber, voor `.tool-let-op`. De randkleur is weg: DESIGN.md (Kantlijn)
     schafte de amberkleurige kantlijn af. */
  --amber-ui-bg: rgba(217,119,6,.10);
  --amber-ui-color: #b45309;

  /* Radius — de trap van de SITE. Hier stond "zelfde trap als de app
     (8/10/14/18)", en dat was onwaar: de app leidt zijn trap af van
     `--radius: 0.625rem` en komt uit op 6/8/10/12/14/22/26, waarin 18 niet
     bestaat. Gecorrigeerd 06-09 (golf 9 fase 4). */
  --r:    8px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  /* 24 is de kaartradius van de SITE (DESIGN.md, De marketingsite: "24 is een
     kaart die de site tekent, 18 een voorwerp dat hij toont"). In de app is de
     kaart sinds v7 (24-08) 12 en niet 18; die 18 stond hier nog als verouderd
     citaat en is 06-09 rechtgezet. Hij ontbrak in deze
     trap, waardoor `border-radius: 24px` als rauw getal op twintig plekken in
     acht bestanden stond, met op `functies.astro:350` zelfs een commentaar dat
     naar DESIGN.md verwees. Een maat die je twintig keer overtypt hoort een
     token te zijn. Toegevoegd 01-09. */
  --r-2xl: 24px;

  /* Motion — zelfde vocabulaire als de app (globals.css). Elke pagina
     hardcodeerde tot nu toe zijn eigen cubic-beziers; nieuw werk gebruikt
     deze drie en niets anders. */
  --ease-out-soft: cubic-bezier(.22, 1, .36, 1);
  /* --ease-spring verwijderd (B13, golf 0): nul gebruikers; in de app is diezelfde token in v5 al weg. */
  --ease-standard: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: .18s;
  --dur-base: .3s;
  --dur-slow: .55s;

  /* `--grain-url` stond hier: een SVG-ruis-data-URI van ~400 byte. Zijn enige
     lezer was `.has-grain::after`, en die klasse staat op geen enkele pagina
     (22-09-2026, alle 52). Token en klasse zijn samen weg. */

  /* Font. Inter sinds 06-09-2026, op Vincents keuze in golf 9: de homepage
     neemt fora's maatsysteem letterlijk over, en dan hoort de letter erbij.
     Geist blijft de letter van de app. De impeccable-detector noemt Inter
     "overused"; dat is hier een merkbesluit en geen bevinding. */
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; /* impeccable-disable-line overused-font -- merkbesluit */
  font-feature-settings: "ss01" on, "ss02" on, "cv01" on;
}

/* ── DARK MODE ──────────────────────────────────────────────── */
html[data-mode="dark"] {
  /* Brand — teal-400 op donker (zelfde als app dark) */
  --brand:    #2dd4bf;
  --brand-h:  #5eead4;
  --brand-p:  #99f6e4;
  --brand-ll: rgba(45,212,191,.10);
  --brand-md: rgba(45,212,191,.20);
  /* Op donker draagt de aanvoerder petrol met WITTE tekst (28-08, K-2).
     Hier stond merkpetrol #2dd4bf met donkere tekst; die leest als een
     tweede merkkleur en niet als dezelfde knop die op licht staat. Wit op
     #0f766e haalt 5,0:1, ruim boven de 4,5. Merkpetrol blijft wat hij is,
     een tekst- en accentkleur op donker, en gaat van --btn-bg af. */
  --btn-bg:   #0f766e;
  --btn-bg-h: #13867d;
  --btn-fg:   #ffffff;
  /* Slate-donker (zelfde familie als app dark) */
  --bg:    #0b1120;
  --bg-2:  #131c2b;
  --bg-3:  #1e293b;
  --bg-4:  #283548;
  /* Contrast tegen --bg (#0b1120): text 15.8:1 · text-2 9.1:1 · text-3 6.8:1 ·
     text-4 5.0:1. De oude waarden (#64748b/#475569) haalden 3.96:1 en 2.49:1
     en zakten dus onder AA op precies de plekken met fijne tekst. */
  --text:   #e2e8f0;
  --text-2: #a8b6c8;
  --text-3: #8b9cb3;
  --text-4: #74869d;
  --border:   rgba(226,232,240,.08);
  --border-2: rgba(226,232,240,.14);
  --green: #4ade80;
  --red:   #f87171;
  --amber: #fbbf24;
  --shadow-strong: rgba(0,0,0,.28);
  --shadow-card: rgba(0,0,0,.3);
  --amber-ui-bg: rgba(251,191,36,.12);
  --amber-ui-color: #FBBF24;
}

/* ── BASE ───────────────────────────────────────────────── */
/* clip in plaats van hidden: overflow-x:hidden maakt html/body zelf
   scrollcontainers, en dan hechten view()-timelines zich dáár aan in
   plaats van aan de viewport (waardoor scroll-reveals als "finished"
   starten). clip knipt hetzelfde af zonder scrollcontainer te worden. */
/* GOLF 10 (08-09, criterium 8): `auto`, niet `smooth`. Lenis is de enige
   scrollmotor (`landschap.ts`/`Basis.astro`); een browser-eigen smooth-scroll
   erbovenop geeft twee motoren op dezelfde as. */
html { scroll-behavior: auto; overflow-x: clip; }
body {
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}
a { color: inherit; text-decoration: none; }

/* ── LAYOUT ─────────────────────────────────────────────── */
.container {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ── BUTTONS ────────────────────────────────────────────── */
.btn {
  /* v6-dialect: 44px vaste hoogte (was ~40px via padding, en var(--r) = 8px
     radius die nergens anders in het systeem voorkomt). Een marketingknop is
     een doel en geen gereedschap — groter dan de 36px van de app-knop, maar
     dezelfde radius (10px = --r-md, gelijk aan DESIGN.md's inset-radius). */
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 0 22px;
  border-radius: var(--r-md);
  font-size: 15px; font-weight: 600;
  border: none; cursor: pointer;
  font-family: inherit;
  transition: background-color .15s, box-shadow .15s, border-color .15s;
  text-decoration: none;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: 0 1px 2px rgba(15,23,42,.06);
}
.btn-primary:hover {
  background: var(--btn-bg-h);
  box-shadow: 0 2px 6px rgba(15,23,42,.10);
}

/* HET GENESTELDE PIJLTJE (01-09, V-C uit de kritiekronde).
   De pijl zit in zijn eigen cirkel tegen de binnenrand, en niet naakt naast de
   tekst. Hij is een `::after` en dus een flex-item, zodat de `gap: 8px` van
   `.btn` de afstand al regelt; `margin-right` trekt hem tegen de padding aan.

   BEWEGING. Alleen `transform` en `opacity`, 150ms (de duur voor een tint) op
   `--ease-out-soft`. Geen veer en geen stuiter: de skill die dit voorstelde
   vraagt om spring physics, en die staan sinds v5 niet meer in de tokens.

   OP ELKE PAGINA-CTA EN NIET ALLEEN OP `.btn-primary`. De uitgelichte
   prijskaart gebruikt `.plan-knop--vol` en het slot `.slot-knop`; zonder die
   twee zou de ene CTA een pijl dragen en de andere niet, en dat is slechter
   dan geen pijl. De kopknop krijgt hem niet: die is klein en herhaalt alleen.

   NIET OP DE DUIMBALK. Die knop is volle breedte en gecentreerd; een pijl in
   de hoek van een balk van 358px leest als een tweede handeling in plaats van
   als versiering van dezelfde. */
.btn-primary::after,
.plan-knop--vol::after,
.slot-knop::after {
  content: "";
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  margin-right: -10px;
  border-radius: 999px;
  background-color: rgba(255, 255, 255, 0.18);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5 8.5 3.5M4.2 3.5h4.3v4.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  transition:
    transform 150ms var(--ease-out-soft),
    background-color 150ms var(--ease-out-soft);
}
.btn-primary:hover::after,
.plan-knop--vol:hover::after,
.slot-knop:hover::after {
  transform: translate(2px, -1px);
  background-color: rgba(255, 255, 255, 0.28);
}
.duimbalk .btn-primary::after { content: none; }
/* Alleen onder html[data-rust], de schakelaar in Basis.astro (05-09). */
html[data-rust] .btn-primary::after,
html[data-rust] .plan-knop--vol::after,
html[data-rust] .slot-knop::after { transition-duration: 1ms; }
/* `.btn-ghost` en `.btn-lg` stonden hier. Geen van beide staat op een element,
   op geen van de 52 pagina's, en geen van beide komt in de bron voor: de site
   kent alleen `.btn` en `.btn-primary`. Een tweede knopvorm hoort bij een
   besluit, niet bij een stylesheet die hem vast klaarzet. */

/* ── VIEW TRANSITIONS ───────────────────────────────────────
   Cross-document paginaovergangen, native. Gemaakt voor precies deze
   architectuur (statische MPA, clean URLs op Vercel). Browsers zonder
   ondersteuning (vooral Firefox) doen een gewone navigatie; niemand
   merkt iets. De nav krijgt een eigen naam zodat hij blijft staan
   terwijl de rest van de pagina cross-fadet: dat is wat het als een
   app laat voelen in plaats van als losse documenten. */
@view-transition { navigation: auto; }
/* Altijd (05-09, Vincent): de site negeert prefers-reduced-motion; zie Basis.astro. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .22s;
  animation-timing-function: var(--ease-standard);
}
/* Alleen onder html[data-rust], de schakelaar in Basis.astro (05-09). */
html[data-rust]::view-transition-group(*),
html[data-rust]::view-transition-old(*),
html[data-rust]::view-transition-new(*) { animation: none !important; }

/* ── NAV, en waar hij gebleven is ─────────────────────────────
   Hier stond tot 22-09-2026 een complete tweede navigatie: .nav, .nav-inner,
   .nav-links, de dropdowns, .nav-mobile en .nav-actions. 152 regels die door
   `Kop.astro` (.kop-*) zijn vervangen en die daarna zijn blijven staan.

   Waarom het weg mocht, en hoe dat gemeten is: elk van die selectors raakte
   NUL elementen op alle 52 gebouwde pagina's (via de sitemap plus /404 en
   /onboarding/bedankt, die niet in de sitemap staan), en geen van de klassen
   kwam ergens in `apps/marketing/src` of `public/` voor. `Nav.astro:544`
   noemde ze zelf al "de oude nav-login-link".

   Zoek je navigatiestijlen: `Kop.astro`. Het volledige register van wat hier
   nog meer is weggehaald staat in
   docs/vordero/vindbaarheid-2026-08-20/VOORTGANG.md. ── */

/* ── FOCUS ──────────────────────────────────────────────────
   Toetsenbordgebruikers hadden site-breed geen enkele zichtbare
   focus-indicator. Eén gedeelde ring voor alles wat focusbaar is.

   `--focus-halo` is de tweede toon, en hij bestaat voor precies één situatie:
   een ring die op fotografie ligt. Op een egale grond haalt één kleur de 3:1
   van WCAG 2.2 SC 1.4.11 gewoon; op een foto niet, want die heeft donkere
   hoeken én een lichte highlight. Gemeten 29-08 over de 98.049 pixels onder
   de navbalk in de hero: merkpetrol haalt daar in het slechtste geval 1,02:1
   en wit 1,81:1. Een witte ring mét deze halo eromheen haalt 3,87:1, omdat per
   pixel de een of de ander draagt.

   Alleen gebruiken waar een ring op een beeld of een verloop ligt. Op een
   egaal vlak is hij overbodig en tekent hij een tweede rand die er niet hoort. */
:root {
  /* De plaat uit ons eigen app-icoon: het vlak waar het merkteken op staat.
     Bewust geen `--nacht` (#0b1120): die is blauwig en deze is neutraal, en het
     verschil is precies wat het icoon zijn eigen materiaal geeft. Hij stond tot
     29-08 als letterlijke waarde in Orbit.astro, en toen de mobiele merkenrij
     zijn anker terugkreeg werd dat een tweede kopie. Twee gebruikers is het
     moment waarop een waarde een naam hoort te krijgen. */
  --merkplaat: #0b0d0e;
  --focus-halo: rgba(0, 0, 0, 0.7);
  /* Dezelfde gedachte, voor type op fotografie (29-08, K-5). Een tekstgloed en
     geen sluier over de foto: hij zit tegen de letter aan, dus op de donkere
     delen van een opname is hij onzichtbaar en op de lichte plekken geeft hij
     de letter zijn eigen grond mee. Gemeten op de hero: de onderregel stond
     over het grootste deel van zijn lengte op 15,3:1, maar zakte op de lichtste
     twee procent van de foto naar 1,32:1 (mobiel) en 1,21:1 (desktop). Een
     sluier over de hele foto lost dat ook op, en dat is precies het trucje dat
     Hero.astro zelf afwijst. */
  --foto-tekstgloed: 0 1px 2px rgba(0, 0, 0, 0.6), 0 0 5px rgba(0, 0, 0, 0.85);
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r);
}
.btn:focus-visible {
  outline: 2px solid var(--text);
  outline-offset: 3px;
}

/* ── SECTIONS ───────────────────────────────────────────── */
.section { padding: 96px 0; }
.section-alt { background: var(--bg-2); }
/* `.section-header` (met zijn `h2` en `p`) stond hier, plus de linkse variant
   en `.section-eyebrow` verderop. Elke sectie tekent zijn eigen kop sinds de
   fora-golven; de gedeelde gecentreerde vorm raakt geen enkel element meer. */

/* ── FOOTER ─────────────────────────────────────────────── */
/* Ook `.footer` zelf is weg (23-09-2026). Hij leefde, maar alleen om te
   worden uitgezet: `Footer.astro` overschreef zijn padding en moest zijn
   `border-top` met `border-top: none` neutraliseren, anders stond er een
   haarlijn boven de voet op elke pagina. Nu tekent `Footer.astro` de voet
   helemaal zelf, zoals `Nav.astro` de kop, en is die workaround ook weg.
   Gemeten: élke berekende eigenschap van de voet en al zijn kinderen, plus
   ::before en ::after, gelijk op alle 52 pagina's.

   De binnenkant van de footer stond hier: .footer-inner, .footer-brand(-logo,
   -name, p), .footer-by, .footer-col(ul, h4, a) en .footer-bottom. Elf regels
   uit de tijd vóór Astro — het commentaar erbij verwees naar
   `partials/footer.html` en `tools/stitch.mjs`, en die bestaan geen van beide
   nog in dit repo. `Footer.astro` tekent de voet sinds de fora-golf zelf, en
   geen van de elf klassen staat nog op een element (22-09-2026, alle 52
   pagina's). De responsive-helft van .footer-inner ging mee, waarmee het hele
   `@media (max-width: 960px)`-blok leeg raakte.

   `.footer` zelf blijft staan: die leeft, want `Footer.astro` gebruikt hem.
   Hij is wel een aparte kwestie — zie `Footer.astro:144`, dat zijn
   `border-top` met `border-top: none` moet uitzetten. Dat is een wijziging
   aan levende opmaak en hoort niet in een opruiming van dode code. */

/* ── RESPONSIVE ─────────────────────────────────────────── */
@media (max-width: 600px) {
  .section { padding: 64px 0; }
}

/* ═══════════════════════════════════════════════════════════
   DESIGN-FUNDAMENT v2 (register: zelfverzekerd en rustig)
   Typografie draagt de pagina; teal is het enige accent; motion is
   kort en bevestigend. Alles hieronder is de gedeelde vocabulaire
   waar de herontwerpronde op bouwt.
   ═══════════════════════════════════════════════════════════ */

/* ── TYPESCHAAL ─────────────────────────────────────────────
   Vaste trap in plaats van per-element font-sizes. De display-maat
   is bewust groot (tot 72px): in dit register is de kop het beeld. */
.t-display {
  font-size: clamp(44px, 6.5vw, 72px);
  font-weight: 800; line-height: 1.04;
  letter-spacing: -.035em;
  text-wrap: balance;
}
.t-h1 {
  font-size: clamp(36px, 5vw, 56px);
  font-weight: 800; line-height: 1.08;
  letter-spacing: -.03em;
  text-wrap: balance;
}
.t-h2 {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 700; line-height: 1.15;
  letter-spacing: -.03em;
  text-wrap: balance;
}
.t-lead  { font-size: clamp(17px, 2vw, 20px); line-height: 1.6; color: var(--text-2); text-wrap: pretty; }

/* Van de trap zijn .t-display, .t-h1, .t-h2 en .t-lead in gebruik. De onderste
   helft — .t-h3, .t-body, .t-small, .t-label en .t-stat — raakte geen enkel
   element meer: componenten zetten hun eigen maten sinds de fora-golven. De
   trap blijft dus bestaan, maar alleen waar hij gedragen wordt.
   Let op bij een nieuwe sectie: neem een maat hier weer op in plaats van er
   een los getal neer te zetten. */

/* ── GRAIN: weg op 23-09-2026 ──
   Hier stond een statische ruis-overlay: `.has-grain` plus een `::after` met
   `--grain-url`, en een donkere variant. De opzet was opt-in per sectie, en
   dat is nooit ingezet — geen enkele pagina draagt de klasse. Het token is
   bovenin meeverwijderd, want `.has-grain::after` was zijn enige lezer.
   De regel `.section--dark .has-grain::after` verderop ging mee. ── */

/* ── REDUCED MOTION ─────────────────────────────────────────
   Eén vangnet voor de hele site, overgenomen uit de app
   (app-next/app/globals.css). Elke pagina had hiervoor zijn eigen
   opt-in-guards per selector, waardoor er gaten vielen: pricing en
   starten draaiden GSAP ongeacht de voorkeur, en de chat-demo in de
   hero animeerde altijd. Een blanket-regel dekt ook alles wat we
   hierna nog bouwen, in plaats van dat elke nieuwe animatie er weer
   handmatig aan gedacht moet worden.

   Niet op 0 maar op 0.01ms: animaties moeten hun eindstaat wél
   bereiken (een `forwards`-animatie die nooit draait laat het element
   op opacity 0 staan), ze mogen alleen geen waarneembare beweging
   maken. */
/* Alleen onder html[data-rust], de schakelaar in Basis.astro (05-09). */
html[data-rust] *,
html[data-rust] *::before,
html[data-rust] *::after {
  animation-duration: .01ms !important;
  animation-iteration-count: 1 !important;
  scroll-behavior: auto !important;
  transition-property: color, background-color, border-color,
    text-decoration-color, fill, stroke, opacity, box-shadow,
    outline-color !important;
}

/* ═══════════════════════════════════════════════════════════
   ELEVATED v3 — premiumlaag voor de herontwerpronde
   Register: rustig, licht, product-first. Eén teal-signatuur
   (aurora), één kinetische kop-toets, subtiele diepte. Alles
   theme-aware via de tokens hierboven en gated op reduced-motion.
   Dit is de gedeelde vocabulaire die over alle pagina's uitrolt.
   ═══════════════════════════════════════════════════════════ */

/* Van de ELEVATED-laag zijn `.bg-aurora` en `.hl-underline` weg (23-09-2026).

   `.bg-aurora` was de "dure" hero-achtergrond met twee radial-gradients;
   `.hl-underline` trok bij het laden een lijn onder een sleutelwoord, met
   `@keyframes hl-draw` en een eigen reduced-motion-variant. Allebei bedoeld
   als de signatuur van de herontwerpronde, allebei nooit op een pagina gezet:
   de fora-golven brachten een ander beeld mee. De keyframes en de
   `html[data-rust]`-regel hadden geen andere lezer en gingen mee.

   Wat van deze laag wél leeft, staat hieronder. */

/* `.floaty` verwijderd (v10). Nul gebruikers, en de reden erboven was letterlijk
   "de indruk van een levend systeem": dat is versiering, en DESIGN.md zegt sinds
   v9 dat doorlopende beweging moet laten zien dat het product iets doet dat in
   werkelijkheid ook beweegt. Gevonden door de nieuwe bewegingspoort. */

/* ═══════════════════════════════════════════════════════════
   COMPOSITIE-TOOLKIT v4 — ritme-varianten, bento, frame, donker moment
   Breekt de "verticale stapel gecentreerde secties". Elke pagina componeert
   hieruit i.p.v. overal de centered .section + gecentreerde .section-header.
   Puur additief: bestaande selectors ongewijzigd, dus geen pagina verandert
   tot een pagina deze klassen daadwerkelijk gebruikt.
   ═══════════════════════════════════════════════════════════ */

/* De varianten op `.section-header` (`--left`, met `.section-eyebrow` en zijn
   `.num`) stonden hier. Ze bestonden om de gecentreerde mold te doorbreken,
   maar `.section-header` zelf is nu ook weg: geen van beide werd ooit gebruikt.
   `.eyebrow` hieronder is een ander ding en leeft wel. */

/* De losse eyebrow boven een kop. Stond tot 28-08 als hetzelfde blok van
   zeven regels in vijf paginabestanden, en op vier andere pagina's
   (/contact, /tools, /vergelijk, elke rekentool) helemaal niet: daar was
   `class="eyebrow"` een gewoon woord van 16px in inkt, boven een h1. Eén
   definitie, hier. Onderscheid met `.section-eyebrow`: die hoort bij een
   `.section-header--left`, draagt petrol en kan een nummer bevatten; deze
   is de stille variant in `--text-3`. */
.eyebrow {
  display: block;
  margin-bottom: 12px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-3);
}

/* ── BENTO: weg op 22-09-2026 ──
   Hier stond een bento-raster (.bento, .b-cell, .b-anchor, .b-wide, .b-half,
   .b-tall, .b-full) met de harde regel dat het alleen mocht bij drie of meer
   inhoudstypes met één ankercel. Die regel is nooit toegepast: gemeten raakte
   geen van de zeven klassen ook maar één element op de 52 gebouwde pagina's,
   en geen ervan kwam in de bron voor. Zijn responsive-helft stond los in
   "Toolkit responsive" en is tegelijk weggehaald.

   De secties hieronder (.pv, het productbeeld) zijn NIET weggehaald: die
   leven, onder meer op /onboarding/bedankt. ── */

/* ═══════════════════════════════════════════════════════════
   PRODUCTBEELD (.pv) — het enige frame voor een beeld van het product

   Vervangt vier verschillende nagebouwde browserbalken (.vdemo-chrome,
   .frame-chrome, .sv-bar, .mockup-topbar) door één vorm zonder balk. Dat
   was al de MOCK-regel uit het kritiekregister van 18-08 ("18px radius,
   paneelschaduw, GEEN nagebouwde browserbalk met stoplichtjes") en die is
   nooit uitgevoerd.

   Een productbeeld is bewust géén schermafdruk en géén nagebouwd scherm,
   maar een BEWERKT FRAGMENT: één idee, geen zijbalk, geen zoekbalk, geen
   paginakop. De bronnen die Vincent aandroeg zijn daar eensluidend over
   ("a cluster of edited interface elements"; "showing people everything
   wouldn't be as powerful as showing a marketer a fragment"). Het
   vocabulaire — kolomnamen, statuspillen, bedragopmaak — komt wél uit de
   echte app, anders wordt het vaag. Zie DESIGN.md, "De marketingsite".

   Alles op tokens, dus licht en donker uit één bron. Een rauwe hex hier is
   een fout die de donkere modus breekt; de poort in
   scripts/ci/checks/productbeeld.mjs bewaakt dat.
   ═══════════════════════════════════════════════════════════ */
.pv { margin: 0; position: relative; }
.pv-naam { color: var(--text); font-weight: 600; }

/* Een aantal, percentage of duur — nooit de bedragrol (de kental-regel).

   De 26 staat buiten de typetrap van de site, en dat mag hier: DESIGN.md,
   Typografie, geeft één afgebakende uitzondering en dat is precies deze —
   "binnen een `figure.pv`". Een productbeeld is een getekend scherm met een
   eigen tokenset, geen tekst van de site. Buiten een `.pv` geldt de trap wel. */
.pv-kental {
  font-size: 26px; /* impeccable-disable-line design-system-font-size -- DESIGN.md: binnen een figure.pv staat de maat buiten de trap */
  font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--text);
}

/* De Semantiek-regel: tint met de kleur als tekst, nooit een gevuld vlak.
   Verwerkingsstanden (concept, verzonden) zijn neutraal — de
   Proces-familie: een mail die aankomt is geen goed nieuws over geld. */
.pv-pil {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: 999px; padding: 3px 10px;
  font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
/* De vier tinten (`--ok`, `--warn`, `--danger`, `--neutraal`) zijn weg: de
   frames die `.pv-pil` gebruiken zetten er geen enkele op. De Semantiek-regel
   hierboven geldt nog steeds zodra er wél een toestand getoond moet worden. */

/* ── De rest van de .pv-woordenschat: weg op 23-09-2026 ──
   Hier stond het volledige tabelvocabulaire van het productbeeld:

     het vlak zelf   .pv-vlak, .pv-body, .pv-bijschrift
     de tabel        .pv-kop, .pv-rij (+ :last-child), .pv-groei, .pv-sub
     de Ledger-regel .pv-bedrag (+ i), .pv-label, .pv-som (+ drie totaalrijen)
     de rest         .pv-callout, .pv-duo (+ een eigen @media), .pv-stap
                     (zeven regels met rail en stip), .pv-chip, .pv-knop,
                     .pv-groot, en .bignum

   Zesendertig selectors, nul elementen op alle 52 pagina's, en geen ervan in
   de bron. De frames die het productbeeld nu tekenen — HeroFrame, SlotFrame,
   Productframe, Stapels — gebruiken `.pv` als figure en daarbinnen `.pv-naam`,
   `.pv-kental` en `.pv-pil`; hun opmaak staat in hun eigen scoped `<style>`.
   Die vier zijn dan ook blijven staan.

   De regels hierboven (de MOCK-regel, de Ledger-regel, de Semantiek-regel,
   de kental-regel) gelden onverkort; ze staan in DESIGN.md, "De marketingsite",
   en de poort scripts/ci/checks/productbeeld.mjs bewaakt ze. Wat weg is, is de
   ongebruikte CSS — niet het ontwerpbesluit. ── */

/* ── SECTION--DARK — full-bleed donker moment ─────────────────
   Scope't de dark-tokens lokaal → elke mockup-class die var(--…) leest,
   rendert donker binnen deze sectie (light-default blijft site-breed).
   overflow-x:clip ONLY (nooit hidden/transform op ancestors → breekt sticky).
   De drie --btn-tokens MOETEN mee en staan op petrol met wit, gelijk aan de
   donkere modus (28-08, K-2): dezelfde knop op elke grond, 5,0:1. */
.section--dark {
  --brand:#2dd4bf; --brand-h:#5eead4; --brand-p:#99f6e4;
  --brand-ll:rgba(45,212,191,.10); --brand-md:rgba(45,212,191,.22);
  --btn-bg:#0f766e; --btn-bg-h:#13867d; --btn-fg:#ffffff;
  --bg:#0b1120; --bg-2:#131c2b; --bg-3:#1e293b; --bg-4:#283548;
  --text:#e2e8f0; --text-2:#a8b6c8; --text-3:#8b9cb3; --text-4:#74869d;
  --border:rgba(226,232,240,.08); --border-2:rgba(226,232,240,.14);
  --green:#4ade80; --red:#f87171; --amber:#fbbf24;
  --shadow-strong:rgba(0,0,0,.28); --shadow-card:rgba(0,0,0,.3);
  background: var(--bg); color: var(--text);
  position: relative; overflow-x: clip;
}

/* ── 1. De letters staan hier, niet bij Google ──────────────────────────────
   Bevinding P-050. Elke pagina laadde Geist via fonts.googleapis.com met twee
   preconnects, dus het IP-adres van elke bezoeker ging naar een derde partij
   vóór er iets in beeld stond, terwijl /pricing en de privacypagina beloven dat
   alles in Frankfurt staat. De bevinding stond in het register als AFGEROND
   (commit 9d698bb6) en was dat aantoonbaar niet: de link stond er nog op alle
   elf pagina's. Vandaar dat dit hier staat en niet in een takenlijst.
   Inter is SIL OFL 1.1, opgehaald met tools/haal-assets.mjs.

   Het latijnse subset met de gewichtsas (48 kB, kleiner dan de 70 kB van
   Geist). Fora zet voor zijn H3 "Inter Display", de optische variant voor
   grote maten; het zichtbare verschil daarvan is de strakkere letterafstand,
   en die dragen wij al per rol uit `fora.generated.css` (-0,03em op H3). Een
   tweede bestand voor die ene rol is die 25 kB niet waard.

   Nageteld op 18-09-2026 (fase 5): die rol staat in fora's hele site op één
   element, "Custom price" op de Enterprise-kaart, en ons `--fora-h3` wordt nul
   keer aangeroepen. De variant van dit bestand mét optische as is 73.080 bytes
   tegen 48.444, op de eerste verf van elke route. Vincent bevestigde het
   besluit: één bestand, één as, en geen `font-optical-sizing` op de site. */
@font-face {
  font-family: "Inter"; /* impeccable-disable-line overused-font -- merkbesluit */
  src: url("/fonts/Inter-Variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ── 2. Contrast per oppervlak ─────────────────────────────────────────────
   De tabel bovenaan dit bestand documenteert contrast tegen ÉÉN achtergrond
   (--bg). Er zijn er vijf. De detector vond 111 contrastfouten waarvan het
   grootste deel uit precies dat gat kwam:

     --text-3 op --bg    5.3:1  haalt AA
     --text-3 op --bg-3  4.4:1  haalt AA NIET   ← 35 treffers
     --brand  op --bg    3.6:1  haalt AA NIET   ← 14 treffers, als tekstkleur
     --text-4 op --bg    3.3:1  decoratief, en toch in zinnen gebruikt

   Twee nieuwe tokens sluiten dat gat. Ze zijn donkerder dan hun voorganger en
   verder niets; wie tekst op een doek- of randvlak zet, gebruikt deze.

   EN DE HARDE REGEL DIE ERBIJ HOORT: --brand is een merkkleur, geen tekstkleur.
   Wit op #0d9488 haalt 3.7:1, en de omgekeerde richting haalt hetzelfde. Er
   stonden negen labels en kickers in --brand op de homepage, allemaal onder AA,
   allemaal in de kleinste letter van de site. Gebruik --brand-tekst. */
:root {
  --text-3-op-vlak: #465468;   /* 7.0:1 op --bg-3 (#e2e8f0) */
  --brand-tekst:    #0b6d64;   /* 4.8:1 op --bg, 4.5:1 op --bg-2 */
}
html[data-mode="dark"] {
  --text-3-op-vlak: #a9b6c7;
  --brand-tekst:    #5eead4;
}

/* ── 3. Elevatie krijgt een lichtbron ──────────────────────────────────────
   Er was één schaduwwaarde en één randwaarde, aan alle vier de kanten gelijk,
   op alles. Een demovenster van 570px en een logopil van 80px droegen dezelfde
   rand. Daarom leest elk vlak als een sticker in plaats van een oppervlak.

   De redenering die hier stond ("zware drop-shadows lezen als sjabloon, vlakke
   vlakken lezen als software") klopt half en blijft staan. Wat eraan ontbrak:
   Linear is óók vlak, en elk vlak daar heeft een lichtere bovenrand dan
   onderrand. Vlak mét lichtbron leest als software; vlak zonder leest als
   ongerenderd.

   Drie tiers. Tier 3 staat op precies één object per venster: het onderwerp.

   DE DONKERE VARIANT IS GEEN NAKOMERTJE. Een witte binnenrand wordt op #0B1120
   een grijze kras. Dit repo is daar al een keer op stukgelopen met
   --shadow-card, en daarom staan de gepaarde waarden hier in dezelfde regel
   en niet in een latere commit.

   WAT HIERVAN OVER IS (23-09-2026). De drie klassen `.vlak-1/2/3` stonden op
   geen enkel element; wat er wél van gebruikt wordt zijn de schaduwtokens, die
   pagina's rechtstreeks met `box-shadow: var(--vlak-N)` lezen (`Basis.astro`,
   `blog/wat-je-mag-vorderen.astro`). Die blijven dus staan — maar alleen 1 en
   2, want `--vlak-3` had buiten zijn eigen klasse geen enkele lezer. Met de
   klassen verdwenen ook `--licht-boven` en `--rand-boven`, inclusief hun
   donkere paar: de lichtbron uit de alinea hierboven wordt nergens meer
   opgevraagd. Komt hij terug, dan komt het paar terug, samen, in één commit. */
:root {
  --vlak-1: 0 1px 2px var(--shadow-card);
  --vlak-2: 0 2px 4px var(--shadow-card), 0 12px 24px -12px var(--shadow-strong);
}

/* ── 4. Vervallen: de warme tint (15-09-2026) ──────────────────────────────
   Hier stonden `--warm`, `--warm-vlak` en `--warm-rand`: één warme tint voor de
   founding-sectie. Vincent, 14-09-2026: "drop anything orange we dont use that
   color and logo anymore". Geen pagina gebruikte de tokens nog (`git grep` op
   `var(--warm` gaf niets). Het nummer blijft staan, zodat de verwijzingen naar
   5 en verder kloppen. Amber blijft, maar alleen semantisch (`--amber*`). */

/* ── 5. Een druk moet voelbaar zijn ────────────────────────────────────────
   DESIGN.md schrijft scale(0.98) voor bij een druk. De app deed dat, de site
   niet: hier stond translateY(1px). Op mobiel, waar geen hover bestaat, was er
   dus geen enkele terugkoppeling tussen de tik en de navigatie, op precies de
   knop waarvoor de hele pagina bestaat. */
.btn:active { transform: scale(.98); }

/* Hover is een muisding. Zonder deze poort blijft een knop op een aanraakscherm
   in zijn hover-toestand hangen tot je ergens anders tikt. */
@media (hover: none) {
  .btn:hover { transform: none; }
}

/* ── 6. De donkere band herschaalt ook de golf 7-tokens ────────────────────
   `.section--dark` zet elk oorspronkelijk token lokaal op zijn donkere waarde,
   zodat een component daarbinnen donker rendert op een lichte pagina. De
   tokens die deze golf toevoegde stonden daar niet in, en dan krijgt een
   donkere band de LICHTE waarden: een binnenrand van 70% wit is op #0B1120 geen
   subtiele lichtvang maar een streep. Precies de fout waar dit repo al eens op
   is stukgelopen met --shadow-card, en de reden dat het gepaarde donkere token
   in dezelfde commit hoort als het lichte. Die regel geldt nog steeds.

   Van de vier zijn er op 23-09-2026 twee over. `--licht-boven` en
   `--rand-boven` werden alleen door `.vlak-1/2/3` gelezen, en die klassen zijn
   met deze golf weg.

   `--text-3-op-vlak` stond hier bijna ook tussen, want `var()` leest hem
   nergens. Dat was een verkeerde lezing van het getal: hij is geen restant maar
   een voorziening, met een contrastcijfer en een harde regel in de sectie
   hierboven ("wie tekst op een doek- of randvlak zet, gebruikt deze"). Hem hier
   weghalen terwijl `:root` hem houdt, zou bovendien precies de fout maken die
   de alinea hierboven beschrijft: een donkere band zou dan de LICHTE waarde
   krijgen. Nul gebruikers is voor een token dus geen bewijs van dood. */
.section--dark {
  --text-3-op-vlak: #a9b6c7;
  --brand-tekst: #5eead4;
}

/* ── 7. Het merkvlak draait niet mee met het thema ─────────────────────────
   Een betaalmerk is andermans huisstijl. Visa is #1434CB, PayPal #002991,
   Apple Pay zwart: op een donkere chip verdwijnen die alle drie. In de donkere
   modus stonden er zo drie lege cirkels in de koppeling-orbit.

   Dit token blijft daarom in beide modi wit. Dat is geen vergeten donkere
   variant maar het punt: een logo hoort op het vlak waarvoor zijn eigenaar hem
   getekend heeft, en dat is bij al deze merken wit. Qonto en Puzzle zetten hun
   orbit-logo's om dezelfde reden op een dekkende plaat. */
:root, html[data-mode="dark"], .section--dark {
  --merkvlak: #ffffff;
  --merkvlak-rand: rgba(15,23,42,.10);
  --merkvlak-inkt: #0f172a;
}

/* ── 8. Twee secties in hetzelfde hoofdstuk staan dichter op elkaar ─────────
   Elke sectie had dezelfde padding boven en onder, dus tussen twee secties van
   hetzelfde hoofdstuk stond evenveel lucht als tussen twee hoofdstukken. Op de
   homepage werd dat bij drie doek-secties achter elkaar een gat van honderd-
   achtentwintig pixels dat niets markeert.

   De band zegt al dat twee secties bij elkaar horen; de ruimte moet dat dan
   niet tegenspreken. Alleen padding-top halveren, niet allebei: de eerste
   sectie van een hoofdstuk houdt zijn volle aanloop. */
.section-alt + .section-alt,
.section--dark + .section--dark,
.section:not(.section-alt):not(.section--dark) + .section:not(.section-alt):not(.section--dark) {
  padding-top: 24px;
}

/* ── 9. De fotohero, golf 7b ───────────────────────────────────────────────
   Twee maten die er nog niet waren, en die er moeten zijn omdat een
   volle-breedte fotohero andere natuurkunde heeft dan een kop in een kolom.

   `--maat-hero` gaat boven de displaytrap uit (die stopt op 72px). Op een foto
   van rand tot rand moet de kop het beeld aankunnen; op 72px leest hij als een
   onderschrift. Qonto zit op dezelfde hoogte. Dit is de enige plek waar deze
   maat mag staan. Het plafond stond op 64 en staat sinds 28-08 op 56: de kop
   is met K-1 drie regels geworden en de langste ("Herinneren, aanmanen,
   innen.") moet binnen de donkere linkerzone van de foto blijven staan.

   `--foto-grond` is de kleur onder de foto: de tint van de opname zelf, zodat
   er tijdens het laden geen wit vlak staat waar een donkere foto komt, en zodat
   de knoptekst op wit dezelfde inkt heeft als het beeld. Bewust géén
   slate-token: die is blauwig en de foto is warm. Sinds 28-08 een tint lichter
   (K-6): op #14100c leest de flits vóór het lazy laden als een zwart gat, en
   het is de grond van een werkplaats, geen leegte. */
:root {
  --maat-hero: clamp(36px, 3.9vw, 56px);
  --maat-hero-smal: clamp(28px, 8vw, 40px);
  --foto-grond: #1f1a14;
  /* De hoogte van de navigatiebalk, zodat een sectie die eronder door moet
     lopen niet met een los getal hoeft te raden. */
  --nav-hoogte: 68px;
}

/* ── 10. De gedeelde in-beeld-onthulling ───────────────────────────────────
   Overgenomen uit de Copilot-ronde van 27-08, en bewust maar voor de helft.
   Die ronde zette er ook een `--ease-onthul: cubic-bezier(.16,1,.3,1)`, een
   `--dur-onthul: .62s` en een `--dur-focaal: 1.05s` bij. De eerste twee zijn
   `--ease-out-soft` en `--dur-slow` met een andere naam, en twee namen voor
   dezelfde curve is hoe een designsysteem in tweeen valt. De derde beschreef
   de lengte van een geregisseerd moment in een hero die niet meer bestaat, en
   een token zonder gebruikers is precies de stille rot waar dit repo al eerder
   op is stukgelopen. Geen van drieen staat er dus; gebruik de bestaande.

   HET CONTRACT, en dat is waarom er `html[data-js]` voor staat. Zonder
   JavaScript staat elk productbeeld in zijn eindstand. De begintoestand wordt
   pas geschreven als het inline-script in Basis.astro `data-js` heeft gezet, en
   dat gebeurt voor de eerste verf. Faalt dat script, dan is er geen
   begintoestand en verbergt de onthulling dus niets.

   Basis.astro zet `data-in` op elk `[data-inbeeld]` zodra het in beeld komt,
   een keer en niet meer terug. De component beschrijft zelf wat er dan
   beweegt; dit blok zorgt alleen dat het tot dat moment niet te zien is. */
html[data-js] [data-inbeeld]:not([data-in]) [data-onthul] {
  opacity: 0;
}
/* Beweging is een dimmer en geen noodstop: onder reduced-motion staat alles
   meteen in de eindstand, ook wat nog niet in beeld is geweest. */
/* Alleen onder html[data-rust], de schakelaar in Basis.astro (05-09). */
html[data-rust][data-js] [data-inbeeld]:not([data-in]) [data-onthul] { opacity: 1; }
