/*
 * styles.css — enige stylesheet van de VSL-landingspagina.
 *
 * Fundament: docs/art-direction.md (gemeten waarden referentiesite + brand kit)
 * en de video-deck "VSL 50K Investeerders". Waarden die uit de deck zelf zijn
 * gemeten (pixelsampling op de PDF-renders) staan met hun herkomst erbij.
 * Ontwerp- en schrapbeslissingen staan in docs/ontwerpbeslissingen.md.
 *
 * Volgorde: 1 tokens · 2 reset · 3 typografie · 4 header · 5 hero ·
 * 6 video · 7 CTA + embed · 7B lichte zone (papier) · 8 bronnenblok ·
 * 9 footer · 10 bevestiging · 11 motion.
 *
 * KLEURZONES (docs/kleuronderzoek.md, optie C — 24-08-2026):
 * de pagina is donker tot en met de video en licht vanaf de boeking. De
 * donkere zone gebruikt de tokens uit §1 zoals ze zijn; de lichte zone zet
 * in §7B dezelfde SEMANTISCHE tokens opnieuw met papierwaarden, zodat elke
 * bestaande regel automatisch de juiste polariteit krijgt. Alleen wat een
 * hardgecodeerde witte/zwarte waarde had, staat daar als losse override.
 */

/* ========================================================================== */
/* 1. Tokens                                                                   */
/* ========================================================================== */

:root {
  /* --- Kleur --------------------------------------------------------------
     Basis uit de brand kit (§3 Kleurenpalet). De vlakken en lijnen zijn
     gemeten op de deck-renders: een deck-kaart is #151515 met een #2B2B2B
     hairline — bijna geen vulverschil, de RAND doet het werk. Dat is precies
     het tegenovergestelde van "overal dezelfde grijze doos". */
  --color-bg: #121212;              /* brand kit, primair. Nooit als tekst. */
  --color-heading: #ffffff;         /* brand kit, alleen koppen */
  --color-body: #fafafa;            /* brand kit, secundair */
  --color-dim: #c6c3b8;             /* GEMETEN in de deck: de warme tweede
                                       tekstregel ("Of: een gevestigde ...").
                                       10,6:1 op #121212. Warm, niet grijs. */
  --color-muted: #969696;           /* brand kit, neutraal. 6,33:1 = AA. */
  --color-faint: #6f6f6f;           /* alleen non-tekst: lijnen, pijltjes */

  --color-accent: #ff7544;          /* brand kit accent-start, 5,9:1 op bg */
  --color-accent-to: #f9a640;
  --gradient-accent: linear-gradient(100deg, #ff7544, #f9a640);
  --color-cta-text: #121212;

  /* Vlakken: near-black met warmte, geen uniform grijs */
  --surface-1: #171717;             /* uitklapblok, de enige "kaart" */
  --surface-2: #141414;             /* genest vlak binnen surface-1 */
  --surface-sunken: #0d0d0d;        /* de promptcode: dieper dan de pagina */
  --surface-warm: linear-gradient(180deg,
      rgba(255, 133, 62, 0.11), rgba(255, 133, 62, 0.02));

  --line: rgba(255, 255, 255, 0.1);  /* ≈ #2B2B2B, gemeten deck-kaartrand */
  --line-soft: rgba(255, 255, 255, 0.06);

  /* --- Lichte zone ("papier") ---------------------------------------------
     docs/kleuronderzoek.md §6.2. Alle achtergrond- en tekstkleuren zijn
     uitgelezen op watdoetmijnkapitaal.nl (de eigen site van de
     opdrachtgever); het accent is afgeleid van #FF7544 met behoud van tint.
     Er komt geen nieuwe paletkleur bij.

     De lichte kaart voor de iClosed-embed (--color-card-light c.s.) is
     vervallen: de widget staat sinds deze ronde rechtstreeks op het papier
     (§6.5 — widget-achtergrond #F3F5F8 staat op 1,01:1 tegen #F7F4EE, dus
     een kaart eronder maakt hem juist weer zichtbaar als vreemd element). */
  --paper: #f7f4ee;              /* achtergrond lichte zone */
  --paper-alt: #f1ede4;          /* verdiept vlak: de promptcode */
  --paper-card: #ffffff;         /* bron- en promptkaart */
  --ink: #1b2430;                /* 14,26:1 op --paper */
  --ink-soft: #4e5a68;           /*  6,41:1 op --paper */
  --rule: #e4ded2;               /* hairline, decoratief */
  --accent-on-paper: #b4451c;    /*  5,02:1 op --paper */
  --accent-on-paper-hi: #8f3615; /*  7,07:1 op --paper */

  /* --- Typografie ---------------------------------------------------------
     Twee gewichten beschikbaar (PT Serif 700, Inter 400). Hiërarchie komt dus
     uit grootte, kleur, ruimte en tracking — nergens font-weight 500/600, dat
     zou de browser als synthetisch vet renderen. */
  --font-serif: "PT Serif", Georgia, "Times New Roman", serif;
  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Mobiel-eerst, 375 → 1280. Body 16px op mobiel (was 17px met lh 1,65:
     te groot en te luchtig voor een telefoon), 17px vanaf desktop. */
  --fs-body: clamp(1rem, 0.9448rem + 0.2210vw, 1.0625rem);   /* 16 → 17 */
  --fs-lead: clamp(1.0625rem, 0.9793rem + 0.3320vw, 1.125rem); /* 17 → 18 */
  /* 22,5 → 44 (mobielvloer omlaag van 28→22,5px, opdracht eigenaar
     25-08-2026: drie regels op mobiel i.p.v. vier — scrolafstand tot video
     en boekingswidget weegt zwaarder dan het gewicht van de kop, een
     eerdere afweging die hiermee bewust wordt overruled. 22,5px is
     empirisch gemeten in de browser (Range.getClientRects() geteld per
     regel) als de grootste maat die op 360px breed nog drie regels geeft —
     de smalste van de drie geteste telefoonbreedtes (360/375/390). Vloer
     geldt dus <=360px; vanaf daar loopt de kop fluid door naar dezelfde
     44px op 1280px als voorheen. Bijvangst: bij 375px en 390px valt de
     kop dan ook op drie regels (22,85px resp. 23,2px — allebei ruim onder
     hun eigen individuele drieregel-maximum van 23,5px/24,5px), dus geen
     enkele van de drie geteste breedtes valt terug op vier regels. */
  --fs-h1: clamp(1.4063rem, 0.8804rem + 2.3370vw, 2.75rem);
  --fs-h2: clamp(1.375rem, 1.0295rem + 1.4917vw, 2.125rem);  /* 22 → 34 */
  --fs-h3: clamp(1.25rem, 1.1387rem + 0.4420vw, 1.5rem);     /* 20 → 24 */
  --fs-small: 0.8125rem;   /* 13px */
  --fs-tiny: 0.75rem;      /* 12px */
  --fs-label: clamp(0.6875rem, 0.6599rem + 0.1105vw, 0.75rem); /* 11 → 12 */

  --lh-body: 1.6;
  --lh-head: 1.14;

  /* --- Verticaal ritme ----------------------------------------------------
     Eén schaal, 4px-grid. Elke sectie haalt zijn ruimte hieruit; geen enkele
     losse marge meer. Dat is wat de gaten van honderden pixels veroorzaakte. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  --rhythm: clamp(2.5rem, 1.6713rem + 3.5359vw, 4.5rem);      /* 40 → 72 */
  --rhythm-lg: clamp(3.5rem, 2.4643rem + 4.4199vw, 6rem);     /* 56 → 96 */

  /* --- Vorm ---------------------------------------------------------------
     Eén radiusschaal: 10px knoppen, 14px vlakken, pill voor de sticky CTA. */
  --radius-button: 10px;
  --radius-card: 14px;
  --radius-inner: 10px;
  --shadow-frame: 0 2px 6px rgba(0, 0, 0, 0.4), 0 24px 60px -28px rgba(0, 0, 0, 0.9);

  /* --- Layout ------------------------------------------------------------- */
  --container: 880px;       /* was 1088px (gemeten referentiesite); teruggebracht 24-08-2026 zodat de video breder blijft dan de tekst én de regellengte prettiger leest */
  --gutter: 20px;           /* gemeten mobiele containerpadding */
  --measure: 62ch;          /* leesregel bodytekst */

  /* Maximale videobreedte: net onder de 1600px van poster.jpg, zodat het
     eerste frame nooit opgeschaald hoeft te worden. Zie ontwerpbeslissingen. */
  --video-max: 1000px;      /* was 1440px; bij 1000px is het frame 536px hoog i.p.v. 772px — 236px winst richting de vouw */

  /* --- Iconen -------------------------------------------------------------
     Zelf getekend, inline, als mask-image. Geen icoonbibliotheek, geen extern
     bestand, geen glyph buiten de fontsubset. */
  --icon-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6.2 3.6h6.2v6.2'/%3E%3Cpath d='M12.4 3.6 3.6 12.4'/%3E%3C/svg%3E");
}

/* ========================================================================== */
/* 2. Reset                                                                    */
/* ========================================================================== */

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

html {
  /* De pagina begint donker. Expliciet gezet zodat scrollbars en
     UA-controls in de donkere zone deterministisch donker zijn; de lichte
     zone zet dit in §7B terug naar `light`. Het bijbehorende
     <meta name="color-scheme" content="light dark"> staat in beide
     HTML-bestanden (docs/kleuronderzoek.md §6.6). */
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Vangnet tegen horizontale overflow. Op <html> en niet op <body>, zodat de
     fixed sticky-CTA nergens geclipt kan worden. */
  overflow-x: clip;
}

body,
h1,
h2,
h3,
p,
ul,
ol,
figure,
blockquote,
pre,
dl,
dd {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

img,
svg {
  display: block;
  max-width: 100%;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

a {
  color: inherit;
}

/*
 * BUGFIX. Elementen met het `hidden`-attribuut kregen hieronder een expliciete
 * display (grid/flex) en wonnen daarmee van de UA-regel [hidden]{display:none}
 * — gelijke specificiteit, en de auteursstijl komt later. Gevolg: de
 * "De agenda wordt geladen"-melding én de foutmelding bleven zichtbaar bovenop
 * de geladen iClosed-widget. Raakt ook #confirm-when en de optionele
 * `hidden` op .tv-logos.
 */
[hidden] {
  display: none !important;
}

/* ========================================================================== */
/* 3. Typografie en basis                                                      */
/* ========================================================================== */

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-body);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.container {
  width: 100%;
  max-width: calc(var(--container) + 2 * var(--gutter));
  margin-inline: auto;
  padding-inline: var(--gutter);
}

@media (min-width: 768px) {
  :root {
    --gutter: 32px;
  }
}

h1,
h2,
h3 {
  font-family: var(--font-serif);
  font-weight: 700;
  color: var(--color-heading);
  letter-spacing: -0.015em;
  line-height: var(--lh-head);
  /* Lost "Vraag het eerst aan een / AI" en de vier ongelijke H1-regels op. */
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-h1);
  letter-spacing: -0.02em;
}

/* Accent op het slotakkoord van de H1 ("100% jouw eigendom.") — opdracht
   eigenaar, 25-08-2026. Eén omhullende span om de hele zinsnede (inclusief
   punt, dat oogt afgemaakter dan een wit leesteken direct na gradienttekst),
   nooit meerdere spans die de zin voor een schermlezer/vertaalmachine
   opknippen.

   EFFEN FALLBACK EERST, buiten @supports. Browsers zonder
   `background-clip: text` (of forced-colors/high-contrast-modi) krijgen dus
   gewoon deze kleur — nooit transparante/onzichtbare tekst. #ff7544, het
   startpunt van de gradient, haalt 7,03:1 tegen --color-bg (#121212); het
   eindpunt --color-accent-to (#f9a640) haalt 9,42:1 — beide eigen gemeten
   (WCAG-formule), ruim boven de 3:1-drempel voor grote tekst waar deze kop
   (--fs-h1) in valt. Geverifieerd door het @supports-blok hieronder
   tijdelijk uit te zetten: dan blijft precies deze effen kleur staan. */
.h1-accent {
  color: var(--color-accent);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
  .h1-accent {
    /* Gradient ÓP de letters, niet erachter (brand kit: "gradient nooit
       achter tekst" verbiedt een gradientvlak als achtergrond van tekst —
       background-clip: text is een andere techniek, de gradient wordt de
       vulling van de glyphs zelf). Zelfde gradient en richting als de
       CTA-knop (.button, var(--gradient-accent) = linear-gradient(100deg,
       #ff7544, #f9a640)), voor merkconsistentie. */
    background: var(--gradient-accent);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
  }
}

h2 {
  font-size: var(--fs-h2);
  line-height: 1.18;
}

h3 {
  font-size: var(--fs-h3);
  line-height: 1.2;
}

/* Eyebrow: geen font-weight, hiërarchie komt uit tracking + kleur + case.
   Exact het patroon van elke deck-slide (grijs, gesperd, klein). */
.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 3px;
}

/* ========================================================================== */
/* 4. Masthead                                                                 */
/* ========================================================================== */

/*
 * Merkstempel, geen navigatiebalk. Daarom:
 * - full-bleed: de balk loopt over de volle paginabreedte en zit niet
 *   ingeklemd in de leescontainer van 1088px;
 * - zo laag als netjes kan: 48px totaal op mobiel, 54px vanaf 768px — exact de
 *   hoogtes die de oude rasterlockup ook had;
 * - achtergrond exact --color-bg. Dat hoeft sinds 24-08-2026 niet meer omdat er
 *   een ondergrond in een asset zit ingebakken (bm-logo.svg en nrto-mark.png
 *   zijn allebei transparant), maar de balk hoort donker: het WOORDMERK in
 *   bm-logo.svg is wit, dus op een licht vlak zou het verdwijnen. Wil de
 *   masthead ooit licht worden, dan is de zwarte logovariant nodig
 *   (docs/brand-assets/color-and-black-full-logo.svg).
 *
 * De dunne gradientstreep die eerst los boven de pagina zweefde is vervangen
 * door de haarfijne accentlijn hieronder: 1px, links warm, naar rechts
 * uitdovend in de gewone hairline. Hij scheidt de masthead van het videoblok
 * (het dubbele-logo-probleem) en geeft de signatuurgradient een functie in
 * plaats van een willekeurige plek.
 */
.site-header {
  position: relative;
  background: var(--color-bg);
  padding-inline: var(--gutter);
}

.site-header::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(255, 117, 68, 0.6),
    rgba(249, 166, 64, 0.24) 34%,
    rgba(255, 255, 255, 0.07) 68%,
    rgba(255, 255, 255, 0.06)
  );
}

/*
 * De lockup: logo — scheidingslijn — keurmerk, in die volgorde, net als in de
 * deck. `align-items: center` zet ze op één optische middenlijn; de gap van 8px
 * is de gemeten afstand uit de oude rasterlockup (7,6px bij 88px breed).
 */
.site-header .header-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: 10px;
}

/*
 * MAATVOERING — optisch, niet op gelijke pixelhoogte.
 *
 * Het keurmerk is staand (0,604:1) en het logo liggend (3,592:1). Op gelijke
 * hoogte gezet oogt het keurmerk veel te klein en het logo veel te groot; dat
 * is precies waarom de deck ze óók niet op gelijke hoogte zet. Uitgemeten in de
 * oude rasterlockup (693×240): het keurmerk vult daar 93% van de hoogte, het
 * logo 54% — een verhouding van 1,72:1. Die verhouding is hier overgenomen:
 * logo 17px hoog, keurmerk 28px hoog. Daarmee blijft de balk op 48px, exact de
 * hoogte die hij had.
 *
 * Bewust klein gehouden: het eerste videoframe heeft de OUDE lockup ingebakken
 * (mét wit tegeltje en het "nrto KEURMERK"-woordmerk) rechtsboven in het beeld,
 * en dat frame kan niet veranderen — het is een frame uit de video. Twee
 * NRTO-weergaven vlak na elkaar mogen niet als fout lezen. Wat ze uit elkaar
 * houdt: (1) duidelijk verschillende schaal, (2) tegenovergestelde uitlijning —
 * de header staat links, het ingebakken merk rechtsboven in de poster, dus ze
 * staan diagonaal en nooit onder elkaar, (3) sinds deze ronde staat het
 * videoframe bovendien 12px van de schermrand met een eigen radius, dus het is
 * zichtbaar een ander object in een andere laag. Dezelfde redenering die het
 * dubbele-logoprobleem oploste, lost dit op.
 *
 * `height` + `width: auto`: de beeldverhouding komt uit de intrinsieke
 * width/height-attributen in de HTML, dus exact en zonder afrondingsrek.
 */
.header-logo {
  width: auto;
  height: 17px;
}

.header-nrto {
  width: auto;
  height: 28px;
}

/* De verticale scheidingslijn uit de deck, als CSS en niet als afbeelding.
   --color-faint staat in de tokens voor precies dit soort non-tekst-lijnen. */
.header-divider {
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: var(--color-faint);
}

@media (min-width: 768px) {
  .site-header .header-bar {
    gap: var(--space-3);
    padding-block: 11px;
  }
  .header-logo {
    height: 19px;
  }
  .header-nrto {
    height: 32px;
  }
  .header-divider {
    height: 20px;
  }
}

/* ========================================================================== */
/* 5. Titelblok                                                                */
/* ========================================================================== */

.hero {
  padding-top: clamp(1.75rem, 1.1287rem + 2.6519vw, 3.25rem);   /* 28 → 52 */
  padding-bottom: clamp(1.75rem, 1.3357rem + 1.7680vw, 2.75rem); /* 28 → 44 */
}

/* Op mobiel de volle kolombreedte: elke ch-limiet maakt de kop smaller en dus
   hoger, en hoogte hier is scrolafstand tot de video. text-wrap:balance zorgt
   voor gelijke regels; de max-width op desktop houdt de regellengte leesbaar
   bij 56px (ca. 45-55 tekens). */
@media (min-width: 768px) {
  /* 38ch is bij 56px ongeveer 1064px: net binnen de leescontainer van 1088px.
     Daarmee valt de kop op desktop in twee gelijke regels in plaats van de zes
     smalle regels die een engere kolom oplevert. Elke extra regel hier is
     scrolafstand tot de video, en dat weegt hier zwaarder dan de vuistregel
     van 45-60 tekens (die geldt voor lopende tekst, niet voor een display-kop
     van twee regels). */
  .hero h1 {
    max-width: 38ch;
  }
}

/* ========================================================================== */
/* 6. Video                                                                    */
/* ========================================================================== */

/*
 * De video is het zwaartepunt van het eerste scherm.
 * Mobiel: een smalle marge van 12px links en rechts (opdracht eigenaar,
 * 24-08-2026) in plaats van full-bleed. 12px is bewust ruim onder de gutter
 * van de tekstkolom (20px): de video blijft daarmee duidelijk breder dan de
 * tekst eronder en houdt het zwaartepunt van het eerste scherm, maar plakt
 * niet meer tegen de schermrand. Met die marge wordt het frame een los
 * object, dus krijgt het rondom een hairline en een kleine radius
 * (--radius-inner, 10px — geen nieuwe waarde in de schaal).
 * Desktop: breekt uit de leescontainer (1088px) tot maximaal --video-max.
 */
.video-section {
  padding-inline: 12px;
}

.video-stage {
  width: 100%;
  margin-inline: auto;
}

.video-frame {
  position: relative;
  width: 100%;
  /* Tella's eigen 853×458-verhouding. Reserveert de hoogte vóór de poster
     geladen is, dus CLS = 0. Ongewijzigd. */
  padding-bottom: 53.6458%;
  overflow: hidden;
  /* Hairline BIJGEWERKT (25-08-2026, opdracht eigenaar): de video viel in
     rusttoestand weg tegen de pagina — de poster is zelf een donkere slide
     en de pagina is #121212, dus er was nauwelijks scheiding. Gemeten
     (WCAG-luminantieformule): de oude hairline (1px, wit op 10% alpha) komt
     samengesteld op #2A2A2A, en dat gaf maar 1,31:1 contrast tegen de
     pagina — zelfs de haarlijn van de deck-kaart zelf (#2B2B2B op de
     deck-achtergrond) meet niet hoger (1,32:1), dus letterlijk dezelfde
     waarde overnemen loste niets op. Deze regel gaat naar 1,89:1: nog altijd
     een haarlijn, geen kader, maar wel afleesbaar. Bewust WARM getint
     (rgba met R>G>B) in plaats van neutraal wit-op-zwart — dat is de "warme
     neutrale tint" van de brand kit, geen kleur die er niet al hoort te
     staan. Werkt onafhankelijk van wat er ín het frame staat: de rand ligt
     over de PAGINA-achtergrond, niet over de poster, dus dit blijft ook
     werken als de poster later een lichtere, beeldvullende still wordt
     (voorstel van de eigenaar, nog niet uitgevoerd). Dit is nog altijd de
     vlakke 1px `border` zelf, geen blur — de box-shadow-laag hieronder is
     een BEWUST aparte, tweede techniek, zie die motivering. */
  border: 1px solid rgba(255, 214, 191, 0.24);
  border-radius: var(--radius-inner);
  /*
   * De warme amber-GLOED van vóór 24-08-2026 (rgba(255,133,62,.32), 84px
   * blur, GEEN negatieve spread — dus een los vlak dat ruim buiten het frame
   * zweefde) blijft verwijderd. docs/kleuronderzoek.md §2.5/§5.2/§6.1: dit
   * was het enige detail in de donkere zone dat het info-productgenre
   * signaleert, en het hele voordeel van optie C boven optie D hangt eraan
   * dat dat signaal verdwijnt. Met de marge van 12px zou 84px blur zonder
   * negatieve spread bovendien zichtbaar tegen de schermrand aanlopen.
   *
   * TOEGEVOEGD (25-08-2026, opdracht eigenaar): een veel terughoudender
   * tweede laag, als "schermlicht" i.p.v. gloed — expliciet gevraagde
   * techniek, welbewust anders opgebouwd dan de verwijderde variant:
   *   - alpha .10 i.p.v. .32 (ruim onder de oude waarde, zoals gevraagd);
   *   - 40px blur i.p.v. 84px;
   *   - -8px spread: trekt de oorsprong van de schaduw ÍN het frame, zodat
   *     het licht oogt alsof het van het scherm zelf af komt (fysiek
   *     plausibel — een scherm straalt, het zweeft niet als los vlak erachter,
   *     wat bij 0 spread wél zo oogt).
   * Deze laag ligt, net als de hairline, in de PAGINA-achtergrond buiten het
   * frame — dus ook onafhankelijk van de posterinhoud, en blijft werken als
   * de poster later lichter wordt (zie de motivering bij de hairline
   * hierboven). Op 30–50px afstand van de paperzone-naad eronder (§7B), dus
   * zonder botsing met die kleurovergang; visueel gecontroleerd op 375×812
   * en 1440×900, rust én "watching" (zie rapport).
   */
  box-shadow: var(--shadow-frame), 0 0 40px -8px rgba(255, 133, 62, 0.1);
  /* Was #0f0f0f (donkerder dan de pagina, dus het frame "zonk weg" i.p.v.
     op te tillen). Nu --surface-1 (#171717, hetzelfde token als het
     uitklapblok bij de bronnen — geen nieuwe kleur): iets lichter dan de
     pagina, zodat het frame ook zónder de posterafbeelding als lichtste
     vlak van het eerste scherm leest. Raakt in de praktijk vooral het
     LQIP-moment vóór de poster geladen is, want de poster zelf dekt de rest
     af. */
  background-color: var(--surface-1);
  /* LQIP: 24×13 blur-placeholder, zodat er nooit een leeg vlak staat. */
  background-image: url("data:image/webp;base64,UklGRjwAAABXRUJQVlA4IDAAAAAwAwCdASoYAA0APu1kqk4ppaQiMAgBMB2JaQAAetEUCNsAAP7v5gGfzmb2zfpwgAA=");
  background-size: cover;
  background-position: center;
}

@media (min-width: 768px) {
  .video-section {
    padding-inline: var(--gutter);
  }
  .video-stage {
    max-width: var(--video-max);
  }
  .video-frame {
    /* Op desktop een groter object, dus de grote radius uit de schaal. De
       oude, verwijderde gloed blijft ook hier weg; het nieuwe, terughoudende
       schermlicht schaalt gewoon mee (vaste px-waarden, geen breakpoint-
       specifieke aanpassing nodig) — zie de motivering bij .video-frame
       hierboven. */
    border-radius: var(--radius-card);
  }
}

.video-frame > * {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.video-frame picture {
  display: block;
}

.video-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-frame iframe {
  border: 0;
}

.video-facade {
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

/*
 * De play-knop stond midden op de posterregel en sneed de kop van de slide
 * doormidden. Hij staat nu rechtsonder in het frame: de enige zone die in het
 * eerste videoframe leeg is. Het hele frame blijft klikbaar, dus de conventie
 * "klik in het midden" werkt gewoon.
 *
 * Uitvoering: geen platte schijf meer maar een gelaagd object — halo-ring,
 * gradientvlak, binnenrand-highlight en een warme, gerichte schaduw.
 */
.play-button {
  position: absolute;
  /* Rechts, verticaal gecentreerd. In het eerste videoframe loopt geen enkele
     tekstregel voorbij 83% van de breedte; de rechterkolom is over de volle
     hoogte leeg, op de ingebakken lockup in de bovenste 10% na. Deze plek
     raakt dus geen letter én valt op 375x812 én op 1280x800 volledig binnen
     het eerste scherm — rechtsonder lukt dat op desktop niet, omdat de video
     daar 644px hoog is. De hele facade blijft klikbaar, dus "klik in het
     midden" werkt gewoon nog. */
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--gradient-accent);
  color: var(--color-cta-text);
  /* Gelaagd in plaats van vlak: lichtrand boven, schaduwrand onder, een warme
     gerichte gloed en een gewone diepteschaduw. De binnenrand kost geen extra
     ruimte, dus hij kan altijd aan. */
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.24),
    inset 0 1px 0 rgba(255, 255, 255, 0.42),
    inset 0 -1px 0 rgba(0, 0, 0, 0.18),
    0 8px 24px -6px rgba(255, 117, 68, 0.45),
    0 3px 10px rgba(0, 0, 0, 0.55);
  transition: transform 240ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* De halo-ring bloeit alleen bij hover open: in rust zou hij extra ruimte
   innemen en dan raakt hij de posterregel erboven wel. */
.play-button::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 133, 62, 0);
  transition: inset 260ms cubic-bezier(0.16, 1, 0.3, 1),
    border-color 260ms ease-out;
}

.video-facade:hover .play-button {
  transform: translateY(-50%) scale(1.04);
}

.video-facade:hover .play-button::after {
  inset: -10px;
  border-color: rgba(255, 133, 62, 0.45);
}

.play-button svg {
  width: 17px;
  height: 21px;
  margin-left: 3px; /* optische centrering van de driehoek */
  fill: currentColor;
}

@media (min-width: 768px) {
  .play-button {
    right: 28px;
    width: 68px;
    height: 68px;
  }
  .play-button svg {
    width: 23px;
    height: 28px;
    margin-left: 4px;
  }
}

/* ========================================================================== */
/* 7. CTA + iClosed-embed                                                      */
/* ========================================================================== */

/* ---------------------------------------------------------------------------
 * WISSELBLOK ONDER DE VIDEO (fase 1 / fase 2)
 *
 * BIJGEWERKT — reparatie van het lege gat in de rustfase (zie
 * docs/ontwerpbeslissingen.md §20). In rust (geen `data-phase` op <body>)
 * reserveert dit slot GEEN ruimte meer voor de link: geen grid-rij, geen
 * onderpadding, geen min-height. Alleen het gewone sectieritme boven (32px
 * mobiel, 40px desktop — zie RITME hieronder) blijft altijd staan, in élke
 * fase, zodat de donkere zone niet strak tegen de video aan schuurt. Pas
 * zodra `data-phase` verschijnt (`watching` of `booking` — dezelfde selector
 * voor beide, dus de hoogte wisselt daarna nooit meer) opent de rij zich en
 * komt de 16/20px eronder terug. Dat mag: de link verschijnt als
 * rechtstreeks gevolg van de klik op play, en CLS sluit shifts binnen 500ms
 * na gebruikersinput uit (`hadRecentInput`) — geverifieerd met een
 * PerformanceObserver, zie §20.
 *
 * Techniek: `grid-template-rows: 0fr → 1fr` op dit element, niet
 * `display:none` (dat laat geen overgang toe). `.alt-lead` heeft daarom
 * `overflow: hidden` nodig — anders dwingt een grid-item zijn eigen
 * inhoudshoogte af, ook als de rij op `0fr` staat. De transitie
 * (`grid-template-rows`, `padding-bottom`, `min-height`) staat op de
 * basisregel hieronder, dus zowel de JS-route (`body[data-phase]`) als de
 * CSS-benadering verderop in dit bestand lopen door dezelfde animatie.
 *
 * RITME (opdracht eigenaar, 24-08-2026). Het slot was 84px hoog met de link
 * optisch gecentreerd, waardoor de afstand video → link (ca. 21px) veel
 * kleiner was dan link → boekingskaart (ca. 53px). Dat las als een fout. De
 * ruimte is nu expliciet en symmetrisch, uit de bestaande 4px-schaal:
 *
 *   video ─ 32px ─ link ─ 16px ─ [3px naadbalk] ─ 16px ─ boekingskaart
 *
 * dus 32px witruimte boven én 32px witruimte onder de link, met de naad als
 * lijn daarin (mobiel; desktop 40/20+20). De 16px onder de naad staat op
 * `.cta-section`, de 16px erboven op dit slot. Zie ook `.paper-zone` in §7B.
 * -------------------------------------------------------------------------*/

.phase-slot {
  display: grid;
  grid-template-rows: 0fr;
  align-content: center;
  min-height: 0;
  /* Boven blijft het gewone sectieritme van de tekening hierboven altijd
     staan — óók in rust — zodat de donkere zone niet strak (benauwd) tegen de
     video aan schuurt zolang er niets te tonen is. Alleen de link zelf (de
     grid-rij) en de 16px eronder zijn fase-afhankelijk: dat is de ruimte die
     in rust nergens voor dient. */
  padding-top: var(--space-8);
  padding-bottom: 0;
  transition:
    grid-template-rows 900ms ease-out,
    padding-bottom 900ms ease-out,
    min-height 900ms ease-out;
  /* Uitgelijnd op de VIDEO (12px), niet op de tekstkolom (20px): deze regel
     hoort visueel bij het frame erboven, en de 16px extra breedte is precies
     wat de zin nodig heeft om op één regel te blijven passen. */
  padding-inline: 12px;
}

/* Fase `watching` én `booking` delen deze selector: de gereserveerde ruimte
   is in beide identiek, dus de hoogte wisselt tussen die twee nooit — alleen
   `.alt-lead`'s opacity/visibility doet dat (verderop in dit bestand).
   Ondergrens = de WCAG-raakvlakmaat. De link zelf is 44,8px hoog (12px tekst,
   lh 1.4, 14px padding-block) en dus al boven de 44px; deze regel is dus een
   vangnet, geen sturende waarde. */
body[data-phase] .phase-slot {
  grid-template-rows: 1fr;
  min-height: 44px;
  padding-bottom: var(--space-4);
}

@media (min-width: 768px) {
  .phase-slot {
    padding-top: var(--space-10);
    padding-inline: var(--gutter);
  }

  body[data-phase] .phase-slot {
    padding-bottom: var(--space-5);
  }
}

.alt-lead {
  /* Flex i.p.v. een gewone regelbox: dan is de hoogte van dit blok exact de
     hoogte van de link, zonder strut-ruimte eromheen. Dat houdt het slot
     voorspelbaar en dus CLS-vrij. */
  display: flex;
  align-items: center;
  /* Horizontale centrering van de link zelf. Dit blok (`.alt-lead`) staat via
     `margin-inline: auto` al optisch gecentreerd op de VIDEO — gemeten:
     de bounding box van #video-frame en van dit blok vallen op dezelfde
     x-as, op 375/1280/1440px, want beide worden onafhankelijk gecentreerd
     binnen dezelfde volle paginabreedte (het verschil tussen --container en
     --video-max verandert daar niets aan). Zonder `justify-content` valt de
     link binnen dit blok terug op de flexdefault (`flex-start`) en plakt hij
     dus tegen de linkerrand van dit — overigens al correct gecentreerde —
     blok. Dát was de daadwerkelijke oorzaak van de scheve link, niet het
     containerbreedteverschil. */
  justify-content: center;
  /* Nodig voor de grid-rij-truc op `.phase-slot`: zonder dit dwingt een
     grid-item zijn eigen inhoudshoogte af (automatic minimum size), ook als
     de rij op `grid-template-rows: 0fr` staat. Met `overflow: hidden` is die
     automatische minimumgrootte 0 en klapt het element echt dicht. */
  overflow: hidden;
  max-width: 560px;
  margin-inline: auto;
  width: 100%;
  /* Rusttoestand: aanwezig in de DOM, niet zichtbaar en niet focusbaar. */
  opacity: 0;
  visibility: hidden;
  transition: opacity 900ms ease-out, visibility 0s linear 900ms;
}

/* Fase 1. Was een omkaderde actie van twee regels op bodyformaat; dat woog
   te zwaar voor wat het is — een uitweg, geen hoofdactie — en concurreerde
   met de boeking (opdracht eigenaar, 24-08-2026). Nu één regel, kleiner, geen
   kader, geen vlak: een gewone tekstlink met de pijl, in dezelfde
   onderstreepte behandeling als de secundaire variant onder de embed. De
   tekst is woordelijk ongewijzigd. */
.alt-lead-link {
  display: inline-block;
  /* 14px boven en onder: brengt het raakvlak op 44,8px zonder de link zelf
     zwaarder te maken, en houdt de witruimte boven en onder de tekstregel
     symmetrisch (zie de tekening bij `.phase-slot`). */
  padding-block: 14px;
  /* 12px op mobiel, niet 13px: bij 13px past de zin in een kolom van 335px
     net niet op één regel (360px nodig) en valt hij terug op twee regels —
     precies wat hier weg moest. Gemeten met de echte Inter-subset. */
  font-size: var(--fs-tiny);
  line-height: 1.4;
  color: var(--color-dim);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.24);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  transition: color 200ms ease-out, text-decoration-color 200ms ease-out;
}

@media (min-width: 768px) {
  .alt-lead-link {
    font-size: var(--fs-small);
  }
}

.alt-lead-link:hover,
.alt-lead-link:focus-visible {
  color: var(--color-body);
  text-decoration-color: var(--color-accent);
}

/* De 16px hieronder is de onderste helft van het symmetrische ritme rond de
   alt-videolink; zie de tekening bij `.phase-slot`. */
.cta-section {
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
}

@media (min-width: 768px) {
  .cta-section {
    padding-top: var(--space-5);
  }
}

/*
 * De boekingswidget staat sinds 24-08-2026 rechtstreeks op het papier
 * (docs/kleuronderzoek.md §6.5): geen lichte kaart, geen schaduw, geen
 * gradient-accentlijn. De widget-achtergrond #F3F5F8 staat op 1,01:1 tegen
 * #F7F4EE — die constructies losten een probleem op dat in de lichte zone
 * niet meer bestaat en maakten hem juist weer zichtbaar als vreemd element.
 * Alleen de max-width uit §6.5 blijft, zodat hij in het paginaritme staat.
 *
 * De hairline die §6.5 optioneel aanbiedt staat er wél, maar TRANSPARANT: de
 * widget tekent zelf al een omkaderd wit paneel, dus een tweede kader
 * eromheen leest als kaart-in-kaart. De 1px blijft staan omdat hij in fase
 * `booking` van kleur wisselt (zie §7 hieronder) — een border-color-wissel
 * verandert nooit een afmeting, een border-width wél.
 */
.booking-card {
  position: relative;
  margin-inline: auto;
  max-width: 560px;
  border-radius: var(--radius-card);
  border: 1px solid transparent;
  /* Bewust GEEN overflow:hidden — de widget stelt zijn eigen hoogte bij via een
     iclosed.widget_height-postMessage en dat mag niet geblokkeerd worden. */
  overflow: visible;
  /* De kaart blijft in elke fase volledig bruikbaar; alleen het gewicht
     verschuift. Uitsluitend opacity en border-color — nooit afmetingen. */
  transition: opacity 900ms ease-out, border-color 900ms ease-out;
}

.booking-inner {
  position: relative;
  padding: var(--space-4);
  /* Hoogte vooraf gereserveerd, zodat de widget geen layout shift veroorzaakt. */
  min-height: 620px;
}

@media (min-width: 768px) {
  .booking-inner {
    padding: var(--space-6);
  }
}

.iclosed-widget {
  width: 100%;
}

.booking-placeholder {
  position: absolute;
  inset: var(--space-4);
  display: grid;
  place-content: center;
  gap: var(--space-3);
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  border-radius: var(--radius-inner);
  background: var(--paper-alt);
}

.booking-placeholder::before {
  content: "";
  justify-self: center;
  width: 40px;
  height: 2px;
  border-radius: 999px;
  background: var(--gradient-accent);
  opacity: 0.6;
}

.booking-fallback {
  position: absolute;
  inset: var(--space-4);
  display: grid;
  place-content: center;
  gap: var(--space-5);
  text-align: center;
  padding: var(--space-6);
  color: var(--ink);
}

.booking-fallback p {
  max-width: 32ch;
  margin-inline: auto;
  font-size: 0.9375rem;
  line-height: 1.5;
}

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 12px 24px;
  border-radius: var(--radius-button);
  background: var(--gradient-accent);
  color: var(--color-cta-text);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  line-height: 1.5;
  letter-spacing: 0.005em;
  text-decoration: none;
  white-space: nowrap;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 6px 18px -8px rgba(255, 117, 68, 0.55);
  transition: transform 160ms ease-out;
}

.button:active {
  transform: translateY(1px);
}

/* De regel ONDER de embed. Hairline erboven zodat hij bij de widget hoort en
   niet als losse zwevende zin op de pagina staat.
   De capaciteitsregel (`CTA.capaciteit`) is per 24-08-2026 van de pagina
   gehaald op verzoek van de eigenaar; zie docs/content.js. Alleen de kleine
   alt-videolink staat hier nog. */
.cta-foot {
  max-width: 560px;
  margin: var(--space-8) auto 0;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-soft);
}

/* De kleine, secundaire variant onder de embed. Stond eerst als leeg
   gereserveerd slot te wachten tot fase "booking" en gaf zo een leeg gat van
   ~110px in de rustfase (opgemerkt na livecheck door de eigenaar, 24-08-2026).
   Nu permanent zichtbaar in alle drie de fasen: het slot is dus nooit meer
   leeg, en omdat de afmeting nooit wisselt blijft de fasewissel elders nog
   steeds CLS-vrij. Gevolg: tijdens "watching" staat dezelfde zin tijdelijk
   twee keer op het scherm (hier en prominent onder de video) — bewust. */
.alt-video {
  display: flex;
  align-items: center;
  min-height: 44px;
}

.alt-video a {
  /* inline-block i.p.v. inline-flex: dan werkt text-wrap op de tekst zelf en
     valt de regel netter af. Het raakvlak blijft ruim 44px hoog door de
     padding plus regelhoogte. */
  display: inline-block;
  padding-block: 8px;
  text-wrap: balance;
  font-size: var(--fs-small);
  color: var(--color-dim);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.24);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.alt-video a:hover,
.alt-video a:focus-visible {
  color: var(--color-body);
  text-decoration-color: var(--color-accent);
}


/* ---------------------------------------------------------------------------
 * FASEN — contract met main.js
 *
 * main.js hoort <body data-phase="..."> te zetten:
 *   (attribuut afwezig)  rust: nog niet op play geklikt
 *   "watching"           vanaf de klik op play tot 30 kijkseconden
 *   "booking"            vanaf 30 kijkseconden
 *
 * "Kijkseconden" = verstreken tijd waarin het videoblok zichtbaar is
 * (IntersectionObserver) én het tabblad actief is. Die klok bestaat al in
 * main.js: `startProgressProxy()` telt precies zo. Zie het rapport en
 * docs/ontwerpbeslissingen.md §16 voor de gevraagde `createPlaybackClock()`.
 *
 * Zolang dat attribuut er niet is, draait de CSS-benadering onderaan dit blok.
 * -------------------------------------------------------------------------*/

/* --- fase 1: watching ---------------------------------------------------- */

body[data-phase="watching"] .alt-lead {
  opacity: 1;
  visibility: visible;
  transition: opacity 900ms ease-out, visibility 0s;
}

/* 0,85 en niet lager: de widget moet terugtreden, niet uitgeschakeld lijken.
   Onder ongeveer 0,8 leest een formulier als `disabled` en durven mensen er
   niet meer op te klikken, terwijl hij in deze fase gewoon bruikbaar is.
   Gemeten op papier: de eigen inkt van de widget (#1F2A37 op #F3F5F8) staat
   op vol gewicht op 13,31:1 en bij opacity 0,85 over #F7F4EE nog op 8,46:1 —
   ruim AA, ook in de teruggetreden fase. */
body[data-phase="watching"] .booking-card {
  opacity: 0.85;
}

/* --- fase 2: booking ----------------------------------------------------- */

body[data-phase="booking"] .alt-lead {
  opacity: 0;
  visibility: hidden;
}

/* .alt-video (de kleine, secundaire variant) heeft hier geen eigen regel meer:
   sinds 24-08-2026 is hij in alle fasen permanent zichtbaar, zie de comment
   bij .alt-video zelf hieronder in dit bestand. */

/* Op papier kan het warme aureool van de donkere versie niet meer: schaduw
   en gloed rond de widget zijn in §6.5 juist afgeschaft. Het positieve
   signaal is nu de hairline zelf, die op het beslismoment naar het
   papieraccent gaat — de enige oranje-op-licht-move die
   docs/kleuronderzoek.md §6.4 regel 5 toestaat (een 1px/1.5px kader in
   #B4451C, nooit de gradient als dunne lijn). Alleen kleur en opacity, dus
   nog steeds geen enkele afmeting die verandert. */
body[data-phase="booking"] .booking-card {
  opacity: 1;
  border-color: var(--accent-on-paper);
}

/* ---------------------------------------------------------------------------
 * CSS-BENADERING zolang main.js data-phase nog niet zet.
 *
 * NADRUKKELIJK EEN BENADERING, geen vervanging:
 * - start klopt: main.js verwijdert de facade en hangt de iframe in
 *   #video-frame, dus :has(iframe) betekent exact "er is op play geklikt";
 * - de 30 seconden zijn WANDKLOKSECONDEN, geen kijkseconden. Deze variant
 *   pauzeert niet als de bezoeker wegscrolt of van tabblad wisselt. Dat kan
 *   CSS niet, en er wordt hier niets geraden: de beperking staat hier en in
 *   docs/ontwerpbeslissingen.md §16 expliciet vermeld.
 *
 * Het hele blok staat achter body:not([data-phase]) en stapt dus vanzelf
 * opzij op het moment dat main.js de fasen gaat aansturen.
 * -------------------------------------------------------------------------*/

@keyframes phase-alt-in {
  from {
    opacity: 0;
    visibility: hidden;
  }
  to {
    opacity: 1;
    visibility: visible;
  }
}

@keyframes phase-alt-out {
  from {
    opacity: 1;
    visibility: visible;
  }
  to {
    opacity: 0;
    visibility: hidden;
  }
}

@keyframes phase-card-demote {
  0%,
  100% {
    opacity: 0.85;
  }
}

@keyframes phase-card-promote {
  from {
    opacity: 0.85;
    border-color: transparent;
  }
  to {
    opacity: 1;
    border-color: var(--accent-on-paper);
  }
}

body:not([data-phase]) .video-section:has(iframe) ~ #video-cta .alt-lead {
  animation:
    phase-alt-in 900ms ease-out both,
    phase-alt-out 900ms ease-out 30s both;
}

/* Zelfde reservering als `body[data-phase] .phase-slot` hierboven, voor de
   route waarin main.js het attribuut nog niet heeft gezet. `#video-cta` is
   hetzelfde element als `.phase-slot`; de transitie staat al op de
   basisregel, dus deze overgang loopt door dezelfde 900ms als de JS-route. */
body:not([data-phase]) .video-section:has(iframe) ~ #video-cta {
  grid-template-rows: 1fr;
  min-height: 44px;
  padding-bottom: var(--space-4);
}

@media (min-width: 768px) {
  body:not([data-phase]) .video-section:has(iframe) ~ #video-cta {
    padding-bottom: var(--space-5);
  }
}

body:not([data-phase]) .video-section:has(iframe) ~ .paper-zone .booking-card {
  animation:
    phase-card-demote 900ms ease-out both,
    phase-card-promote 900ms ease-out 30s both;
}

/* Geen fallback-regel meer voor .alt-video: die is sinds 24-08-2026 in alle
   fasen permanent zichtbaar en heeft dus geen wandkloktimer nodig. Zou deze
   regel hier blijven staan, dan verbergt hij het element juist opnieuw tot
   t=30s — precies het gat dat net is opgelost. */

/* ========================================================================== */
/* 7B. Lichte zone — "papier"                                                  */
/* ========================================================================== */

/*
 * Optie C uit docs/kleuronderzoek.md: donker tot en met de video, licht vanaf
 * de boeking. Eén naad, precies op het punt waar de bezoeker van rol wisselt
 * (kijken → controleren en beslissen), en op precies dezelfde plek waar de
 * deck zelf ook omschakelt.
 *
 * Werkwijze: dit blok zet dezelfde SEMANTISCHE tokens opnieuw met de
 * papierwaarden uit §6.2. Elke bestaande regel (bronkaarten, claims, prompt,
 * footer) verandert daardoor mee zonder gedupliceerd te worden. Alleen wat een
 * hardgecodeerde witte of zwarte waarde had, staat hieronder als losse
 * override — en de vier vaste regels voor oranje op licht (§6.4).
 *
 * .site-footer staat buiten <main> en dus buiten .paper-zone, maar hoort bij
 * dezelfde zone; vandaar de gedeelde selector.
 */

.paper-zone,
.site-footer {
  /* Formuliercontrols en scrollbars binnen o.a. de iClosed-iframe blijven
     licht (§6.6). */
  color-scheme: light;

  --color-heading: var(--ink);   /* 14,26:1 op --paper */
  --color-body: var(--ink);      /* 14,26:1 op --paper */
  --color-dim: var(--ink);       /* lopende tekst: op papier één inktniveau */
  --color-muted: var(--ink-soft); /* 6,41:1 op --paper — metadata en labels */
  --color-accent: var(--accent-on-paper); /* 5,02:1 — o.a. de focusring */

  --surface-1: var(--paper-card); /* bronkaart, wit */
  --surface-2: var(--paper-card); /* promptkaart, wit */
  --surface-sunken: var(--paper-alt); /* de promptcode, #F1EDE4 (§6.5) */

  --line: var(--rule);
  --line-soft: var(--rule);

  background: var(--paper);
  color: var(--color-body);
}

/*
 * DE NAAD (§6.3). Harde snede, geen verloop over de volle breedte: een
 * overgang van #121212 naar #F7F4EE produceert in het midden een modderig
 * warmgrijs dat in geen van beide paletten thuishoort. Direct boven de lichte
 * zone een 3px balk in de signatuurgradient, full-bleed — hetzelfde detail als
 * de bovenrand van de masthead. Zo is de naad een merkelement in plaats van
 * een breuk.
 *
 * In de flow (display:block), niet absoluut: de 3px telt zo mee in het ritme
 * rond de alt-videolink (zie de tekening bij `.phase-slot`) en kan nooit over
 * inhoud heen vallen.
 */
.paper-zone::before {
  content: "";
  display: block;
  height: 3px;
  background: var(--gradient-accent);
}

/* --- Losse overrides: alles wat een harde wit-/zwartwaarde had ------------ */

/* Onderstrepingen waren gebaseerd op wit-transparant en zijn op papier
   onzichtbaar. currentColor op 1px is hier de rustigste oplossing en
   introduceert geen kleur die niet in §6.2 staat. */
.paper-zone .alt-video a,
.paper-zone .prompt-copy,
.site-footer .footer-links a {
  text-decoration-color: currentColor;
}

/* De kleine alt-videolink blijft secundair: inkt-zacht, niet het accent — het
   accent op papier is voorbehouden aan de bronlinks en de CTA. */
.paper-zone .alt-video a {
  color: var(--ink-soft);
}

.paper-zone .alt-video a:hover,
.paper-zone .alt-video a:focus-visible {
  color: var(--accent-on-paper-hi);
  text-decoration-color: currentColor;
}

/* "Open in ChatGPT". De volle gradient mag op licht alleen als CTA-vulling,
   naadbalk of massieve balk (§6.4 regel 4); als omkaderde knop is dit het
   toegestane patroon: kader in #B4451C, warme vulling, inkt als tekst.
   Gemeten: #1B2430 op de vulling = 14,5:1. */
.paper-zone .button-prompt {
  background: rgba(180, 69, 28, 0.08);
  box-shadow: none;
}

.paper-zone .button-prompt:hover,
.paper-zone .button-prompt:focus-visible {
  background: rgba(180, 69, 28, 0.13);
}

/* De afloop onder de promptcode liep naar transparant-zwart. */
.paper-zone .prompt-fade {
  background: linear-gradient(to top, var(--paper-alt), rgba(241, 237, 228, 0));
}

/* Bronlinks: #B4451C, onderstreept, hover #8F3615 (§6.5). Onderstrepen is
   hier expliciet voorgeschreven — niet alleen kleuren. */
.paper-zone .source-list a {
  color: var(--accent-on-paper);
  text-decoration: underline;
  text-decoration-color: currentColor;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.paper-zone .source-list a:hover,
.paper-zone .source-list a:focus-visible {
  color: var(--accent-on-paper-hi);
}

.paper-zone .derden-list a:hover,
.paper-zone .derden-list a:focus-visible {
  color: var(--accent-on-paper-hi);
}

/* Leescomfort in het bronnenblok (§6.5): de winst van positieve polariteit
   gaat naar comfort, niet naar compactheid. Lopende tekst minimaal 16px,
   bronmetadata minimaal 15px. Alleen de lopende tekst en de bronregels; de
   gesperde uppercase-labels blijven een UI-label en houden hun maat. */
.paper-zone .claim-body {
  font-size: 1rem;
}

.paper-zone .source-list a,
.paper-zone .sources-summary-lead,
.paper-zone .sources-peildatum {
  font-size: 0.9375rem;
}

.paper-zone .sources-peildatum {
  letter-spacing: 0;
}

/* De tv-tegels. rtl7.svg en rtlz.svg hebben een ZWARTE 7 respectievelijk Z en
   staan nu op een witte bronkaart: de lichtgrijze tegel #EDEDED valt daar weg,
   dus die wordt het verdiepte papiervlak. videoland.svg is één wit pad en
   houdt zijn donkere tegel — die scheidt zich op papier vanzelf, dus de
   hairline eromheen (die op #121212 nodig was) vervalt. */
.paper-zone .tv-logo--light {
  background: var(--paper-alt);
}

.paper-zone .tv-logo--dark {
  border-color: transparent;
}

/* ========================================================================== */
/* 8. "Controleer het zelf"                                                    */
/* ========================================================================== */

.sources {
  /* Kleiner dan het standaardritme: de gereserveerde band van de kleine
     alt-videolink hierboven levert al ruimte, en samen zou dat een gat geven. */
  padding-top: var(--space-6);
  padding-bottom: var(--rhythm-lg);
}

/* De enige echte "kaart" op de pagina. Near-black met een hairline: de rand
   doet het werk, niet een grijze vulling (gemeten deck-patroon). */
.sources-block {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface-1);
}

summary {
  list-style: none;
  cursor: pointer;
}

summary::-webkit-details-marker {
  display: none;
}

.sources-summary {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-6);
  border-radius: var(--radius-card);
}

@media (min-width: 768px) {
  .sources-summary {
    padding: var(--space-8);
  }
}

.sources-summary h2 {
  font-size: var(--fs-h3);
}

.sources-summary-lead {
  grid-column: 1 / -1;
  max-width: 60ch;
  margin-top: var(--space-2);
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--color-muted);
}

.sources-summary:hover .sources-summary-lead {
  color: var(--color-dim);
}

.chevron {
  width: 20px;
  height: 20px;
  color: var(--color-muted);
  transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1);
}

details[open] > summary .chevron {
  transform: rotate(180deg);
}

.sources-body {
  padding: var(--space-5) var(--space-6) var(--space-6);
  border-top: 1px solid var(--line-soft);
}

/* De peildatum. Klein en secundair, maar de eerste regel die zichtbaar wordt
   zodra het blok opengaat — hij is een vertrouwenssignaal, geen voetnoot. */
.sources-peildatum {
  font-size: var(--fs-tiny);
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--color-muted);
}

@media (min-width: 768px) {
  .sources-body {
    padding: 0 var(--space-8) var(--space-8);
  }
}

.source-group {
  padding-top: var(--space-12);
}

.sources-body > .sources-peildatum + .source-group,
.confirm-block > .source-group:first-child {
  padding-top: var(--space-8);
}

.source-group > h3 {
  max-width: 24ch;
  margin-bottom: var(--space-5);
}

/* --- Groep A: de AI-prompt ------------------------------------------------
   Was een monospace-muur van bijna een heel scherm. Nu: kleinere mono, vaste
   maximumhoogte met eigen scroll, en de kopieerknop binnen het eerste scherm
   van het blok. */

.prompt-card {
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-inner);
  background: var(--surface-2);
  overflow: hidden;
}

.prompt-scroll {
  position: relative;
  max-height: 168px;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--line-soft);
}

@media (min-width: 768px) {
  .prompt-scroll {
    max-height: 208px;
  }
}

.prompt-card pre {
  margin: 0;
  padding: var(--space-4) var(--space-5);
}

.prompt-card code {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.78125rem; /* 12,5px */
  line-height: 1.55;
  color: var(--color-dim);
  white-space: pre-wrap;
  word-break: break-word;
}

/* Zachte afloop onderaan het scrollvlak: signaleert dat er meer staat, zonder
   een scrollbar-cue of een extra tekstregel. */
.prompt-fade {
  position: sticky;
  bottom: 0;
  height: 28px;
  margin-top: -28px;
  pointer-events: none;
  background: linear-gradient(to top, var(--surface-sunken), rgba(13, 13, 13, 0));
}

/* Eén kolom: de primaire knop op volle breedte, daaronder het alternatief.
   Naast elkaar zou de kopieerlink meeconcurreren, en juist die volgorde is het
   punt van deze wijziging. */
.prompt-actions {
  display: grid;
  justify-items: start;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5) var(--space-4);
}

/* PRIMAIR: "Open in ChatGPT". Accentrand met een warme vulling — bewust niet
   de volle gradient: die blijft van de boekings-CTA, en de brand kit staat
   maar één opvallend accent per scherm toe. Binnen dit blok is dit onmiskenbaar
   de hoofdactie. */
.button-prompt {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  padding: var(--space-3) var(--space-6);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-button);
  background: rgba(255, 117, 68, 0.14);
  font-size: var(--fs-body);
  color: var(--color-heading);
  text-decoration: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: background-color 180ms ease-out;
}

.button-prompt:hover,
.button-prompt:focus-visible {
  background: rgba(255, 117, 68, 0.22);
}

.button-prompt:active {
  transform: translateY(1px);
}

/* SECUNDAIR: kopiëren. Tekstlink, geen kader, maar wel 44px raakvlak. */
.prompt-copy {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  font-size: 0.875rem;
  color: var(--color-muted);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.22);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.prompt-copy:hover,
.prompt-copy:focus-visible {
  color: var(--color-body);
  text-decoration-color: currentColor;
}

.copy-status:not(:empty) {
  font-size: var(--fs-small);
  color: var(--color-dim);
}

.prompt-note {
  margin-top: calc(var(--space-2) * -1);
  font-size: var(--fs-tiny);
  line-height: 1.5;
  color: var(--color-muted);
}

/* --- Groep B: de zeven uitspraken ------------------------------------------
   Waren zeven grijze dozen in een grijze doos. Nu regels met een hairline
   ertussen — het lijstpatroon uit de deck (slide "Wat wij doen, wat jij doet"):
   lichter, editorialer en het maakt de kaart als geheel weer één object. */

.claim-list {
  display: grid;
  border-top: 1px solid var(--line-soft);
}

.claim-card {
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--line-soft);
}

.claim-quote {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--color-heading);
  text-wrap: pretty;
  max-width: 46ch;
}

/*
 * ONDERWERPSLABEL boven de quote (toegevoegd 24-08-2026, opdracht eigenaar).
 *
 * Het probleem: de quotes zijn zonder de video betekenisloos. "In twintig jaar
 * ruim 16x zo groot" — 16x wát? De onderbouwing die dat uitlegt zit ingeklapt,
 * dus wie niet uitklapt leest fragmenten zonder onderwerp. Dat ondermijnt
 * precies het doel van dit blok.
 *
 * Het label benoemt alleen het onderwerp en is per kaart rechtstreeks af te
 * leiden uit de onderbouwing in diezelfde kaart. Geen cijfers, geen jaartallen,
 * geen bijvoeglijke naamwoorden die daar niet staan. De quotes zelf zijn
 * woordelijk ongewijzigd. De labels staan in docs/content.js (`onderwerp`).
 *
 * Vorm: exact het eyebrow-patroon van de deck (klein, gesperd, uppercase,
 * gedempt). GEEN eigen font-weight-waarde erven van .claim-quote (700) — dat
 * zou Inter synthetisch vet renderen; vandaar de expliciete 400.
 *
 * Twee bewuste constructiekeuzes:
 * 1. Het label staat ALS SPAN BINNEN de <blockquote>, niet als los <p>
 *    ervoor. Zo is het één element en leest een schermlezer label en quote als
 *    één geheel voor, en het kan per definitie niet in de koppenhiërarchie
 *    belanden — het is geen kop, het is een label.
 * 2. In de HTML staat het label in gewone zinsvorm ("bol in Nederland en
 *    België"); de kapitalen komen uit `text-transform`. Schermlezers spellen
 *    echte ALL-CAPS-tekst soms letter voor letter, en zo blijft de
 *    merkschrijfwijze "bol" (kleine letter) bewaard in de bron.
 */
.claim-label {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: var(--fs-label);
  line-height: 1.4;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-muted);
}

@media (min-width: 768px) {
  .claim-quote {
    font-size: 1.1875rem;
  }
}

.claim-details {
  margin-top: var(--space-2);
}

.claim-summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  font-size: var(--fs-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.claim-summary:hover {
  color: var(--color-dim);
}

.claim-summary .chevron {
  width: 14px;
  height: 14px;
}

.claim-body {
  margin-top: var(--space-2);
  max-width: var(--measure);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--color-dim);
}

.claim-body + .claim-body {
  margin-top: var(--space-3);
}

.source-list {
  margin-top: var(--space-3);
  display: grid;
  padding-left: var(--space-4);
  border-left: 1px solid var(--line-soft);
}

.source-list a {
  display: block;
  padding-block: var(--space-3);
  min-height: 44px;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--color-muted);
  text-decoration: none;
}

.source-list a:hover,
.source-list a:focus-visible {
  color: var(--color-body);
}

/* Extern-link-pijltje. Zelfgetekende inline SVG als mask, zodat hij de
   linkkleur overneemt (currentColor) zonder icoonbibliotheek en zonder een
   glyph die buiten de subset van onze twee fonts valt. */
.source-list a::after,
.derden-list a > span:first-child::after {
  content: "";
  display: inline-block;
  width: 0.72em;
  height: 0.72em;
  margin-left: 0.4em;
  vertical-align: -0.02em;
  background-color: currentColor;
  opacity: 0.5;
  -webkit-mask: var(--icon-external) center / contain no-repeat;
  mask: var(--icon-external) center / contain no-repeat;
}

.source-list a:hover::after,
.source-list a:focus-visible::after,
.derden-list a:hover > span:first-child::after,
.derden-list a:focus-visible > span:first-child::after {
  opacity: 0.85;
}

/* --- Groep C: externe validatie ------------------------------------------- */

.derden-list {
  display: grid;
  border-top: 1px solid var(--line-soft);
}

.derden-list li {
  border-bottom: 1px solid var(--line-soft);
}

.derden-list a {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-block: var(--space-4);
  min-height: 52px;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--color-body);
  text-decoration: none;
}

.derden-list a:hover,
.derden-list a:focus-visible {
  color: var(--color-heading);
}

.derden-list a span:first-child {
  flex: 1;
}

/*
 * Het NRTO-keurmerk naast de registerlink. Sinds 24-08-2026 het nieuwe
 * merkbestand nrto-mark.png (145×240, transparant), alleen proportioneel
 * geschaald naar 29×48 — geen filter, geen opacity, geen herkleuring, geen
 * hertekening. Geen tegel eromheen: het merkteken is open getekend met een
 * transparante body, dus het neemt de ondergrond over. Dat is precies waarom
 * het in beide kleurzones werkt; een vlak eronder zou daar een rechthoekige
 * plek achter zetten.
 */
.nrto-mark {
  flex: 0 0 auto;
  width: 29px;
  height: 48px;
}

.derden-tv {
  margin-top: var(--space-6);
  max-width: var(--measure);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--color-dim);
}

/* Afgeronde tegels per logo. De logo's zelf blijven ongewijzigd (geen filter,
   geen herkleuring), alleen proportioneel geschaald — elk krijgt de ondergrond
   waarvoor het getekend is:
   - rtl7.svg en rtlz.svg hebben een ZWARTE "7" respectievelijk "Z"
     (style="fill:#000000") en vallen dus weg op #121212 → lichte tegel.
   - videoland.svg is één wit pad (fill="#ffffff") en valt weg op een lichte
     tegel → donkere tegel met hairline.
   Wordt een van deze bestanden ooit vervangen door een variant met een andere
   kleur, wissel dan de tegelklasse mee. */
.tv-logos {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.tv-logo {
  display: flex;
  align-items: center;
  height: 40px;
  padding-inline: var(--space-3);
  border-radius: var(--radius-inner);
}

.tv-logo--light {
  background: #ededed;
}

.tv-logo--dark {
  background: var(--color-bg);
  border: 1px solid var(--line);
}

.tv-logo img {
  height: 15px;
  width: auto;
}

/* ========================================================================== */
/* 9. Footer                                                                   */
/* ========================================================================== */

.site-footer {
  border-top: 1px solid var(--line-soft);
  padding-block: var(--space-12) var(--space-12);
}

/*
 * Hiërarchie stond op zijn kop: de disclaimer was groter dan de
 * bedrijfsgegevens. Nu is de identiteit van het bedrijf de primaire regel en
 * staat de risico-disclaimer als afsluitende kleine letter onder een hairline —
 * kleiner, maar met een leesbare regelhoogte en een kleur op 10,6:1 contrast,
 * dus nog steeds geen weggemoffelde 10px-grijs (review-brand-voice, R6).
 */
.footer-identity {
  max-width: var(--measure);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--color-body);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-6);
  margin-top: var(--space-2);
}

.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.875rem;
  color: var(--color-muted);
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.2);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--color-body);
  text-decoration-color: currentColor;
}

.footer-fine {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-soft);
}

.footer-fine p {
  max-width: var(--measure);
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--color-dim);
}

.footer-fine p + p {
  margin-top: var(--space-2);
  color: var(--color-muted);
  font-size: var(--fs-tiny);
}

/* ========================================================================== */
/* 10. Bevestigingspagina                                                      */
/* ========================================================================== */

.confirm {
  padding-top: clamp(2rem, 1.3787rem + 2.6519vw, 3.5rem);
  padding-bottom: var(--space-10);
}

.confirm h1 {
  max-width: 14ch;
}

/* Hiërarchie zonder extra fontgewicht: de eerste alinea groter en off-white,
   de rest op bodyformaat in de warme tweede tekstkleur. */
.confirm-intro {
  margin-top: var(--space-5);
  max-width: 52ch;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--color-dim);
}

.confirm-intro:first-of-type {
  margin-top: var(--space-6);
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--color-body);
}

.confirm-when {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface-warm);
  max-width: 52ch;
}

.confirm-when .eyebrow {
  display: block;
  margin-bottom: var(--space-1);
}

.confirm-when strong {
  font-family: var(--font-serif);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--color-heading);
}

/* Op de bevestigingspagina loopt dezelfde naad: donker t/m het titelblok
   (`.confirm`, 40px lucht eronder), dan de 3px accentbalk, dan papier. De
   40px hieronder maakt die overgang symmetrisch. Het hele bronnenblok staat
   daarmee ook hier op papier — precies het blok waarvoor optie C is gekozen. */
.confirm-block {
  padding-top: var(--space-10);
  padding-bottom: var(--rhythm-lg);
}

.confirm-block .source-group:first-child {
  padding-top: 0;
}

.confirm-block .source-group > h2 {
  font-size: var(--fs-h3);
  max-width: 24ch;
  margin-bottom: var(--space-5);
}

/* ========================================================================== */
/* 11. Motion                                                                  */
/* ========================================================================== */

/*
 * Eén beweging op de pagina: een trage fade-in van 900ms ease-out met 12px
 * verplaatsing — exact de waarden die op de referentiesite zijn gemeten.
 * Uitgevoerd met een scroll-driven animation, dus zonder JavaScript en zonder
 * risico op CLS. Browsers zonder ondersteuning (o.a. Firefox) tonen simpelweg
 * de eindstaat: het is een verrijking, geen voorwaarde.
 *
 * Bewust NIET op de hero en de video: die zijn boven de vouw, en een LCP-
 * element op opacity 0 zetten kost LCP-tijd.
 */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      animation: reveal-in linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 20%;
    }
  }
}

@keyframes reveal-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
}
