/* ===================================================================
   All Screens Videoproducties — one-page site
   Design tokens & structuur volgen het handoff-document 1-op-1.
   =================================================================== */

:root {
  /* Kleuren */
  --navy:        #0a0046;
  --cyaan:       #35c8f5;
  --magenta:     #e02df2;
  --paars:       #7a2ff0;
  --indigo:      #6403fa;
  --violet:      #8b52fb;
  --lichtblauw:  #bddcef;
  --canvas:      #161616;
  --creme:       #f5f4f0;
  --step-02:     #5f8df3;
  --step-04:     #b62bf5;
  --mail-link:   #7de3ff;

  /* Typografie */
  --font-display: 'Anton', 'Arial Narrow', sans-serif;
  --font-body:    'Space Grotesk', system-ui, -apple-system, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, monospace;

  /* Ritme */
  --gutter: 40px;
  --maxw:   1400px;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--creme);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, video { display: block; max-width: 100%; }
h1, h2, h3, p, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: var(--creme); text-decoration: none; }
a:hover { color: var(--cyaan); }

::selection { background: var(--magenta); color: #fff; }

:focus-visible {
  outline: 3px solid var(--cyaan);
  outline-offset: 3px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 16px; top: -100px; z-index: 100;
  background: var(--cyaan); color: var(--navy);
  padding: 12px 20px; border-radius: 999px;
  font-weight: 700; font-size: 14px;
  transition: top 0.2s;
}
.skip-link:focus { top: 16px; color: var(--navy); }

/* ── Animaties ────────────────────────────────────────────────────── */
@keyframes floaty {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-8px) rotate(1deg); }
}
@keyframes wiggle {
  0%, 100% { transform: rotate(-1.2deg); }
  50%      { transform: rotate(0.6deg); }
}
@keyframes gradient-slide {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
@keyframes dot-run {
  0%   { left: 4%; }
  100% { left: 95%; }
}
@keyframes hero-drift {
  0%, 100% { transform: scale(1.1) translate(0, 0); }
  50%      { transform: scale(1.2) translate(-2%, -2%); }
}

/* Tekst-effecten die op meerdere plekken terugkomen */
.tx-gradient {
  display: inline-block;
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: gradient-slide 6s ease-in-out infinite;
}
.tx-gradient--magenta { background-image: linear-gradient(90deg, var(--magenta), var(--paars), var(--navy), var(--magenta)); }
.tx-gradient--cyan    { background-image: linear-gradient(90deg, var(--cyaan), var(--magenta), var(--cyaan)); animation-duration: 7s; }

.tx-dot { display: inline-block; }
.tx-dot--magenta { color: var(--magenta); animation: wiggle 2.4s ease-in-out infinite; }
.tx-dot--cyan    { color: var(--cyaan); }
.tx-float        { animation: floaty 4s ease-in-out infinite; }

.tx-tilt   { display: inline-block; transform: rotate(-1.4deg); }
.tx-tilt-r { transform: rotate(0.8deg); }

/* ── Gedeelde onderdelen ──────────────────────────────────────────── */
.section-label {
  font-family: var(--font-mono);
  font-size: 24px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(10, 0, 70, 0.55);
}
.section-label--light { color: rgba(245, 244, 240, 0.75); }

.btn {
  display: inline-block;
  border-radius: 999px;
  padding: 16px 36px;
  font-weight: 700;
  font-size: 16px;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.btn--cyan    { background: var(--cyaan); color: var(--navy); }
.btn--cyan:hover    { background: #fff; color: var(--navy); }
/* Magenta naast cyaan: cyaan is de hoofdknop (contact), magenta de
   tweede stem. Tekst is navy en geen wit — wit haalt op magenta maar
   3,60:1 en navy 5,29:1, en alleen navy komt boven de 4,5:1 die voor
   tekst geldt. */
.btn--magenta { background: var(--magenta); color: var(--navy); }
.btn--magenta:hover { background: #fff; color: var(--navy); }

/* Placeholder-slots voor nog aan te leveren beeld (logo's, foto's) */
[data-slot] { position: relative; }
[data-slot] .slot__ph {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  padding: 10px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  line-height: 1.5;
  color: rgba(10, 0, 70, 0.45);
  background: repeating-linear-gradient(45deg, rgba(10,0,70,0.04) 0 8px, transparent 8px 16px);
  border-radius: inherit;
}
[data-slot].is-empty .slot__ph { display: flex; }
[data-slot].is-empty [data-slot-img] { visibility: hidden; }

/* ── 1. Hero ──────────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  /* Bovenaan altijd de hoogte van de navigatiebalk plus lucht: op een laag
     scherm schuift de kop anders onder de balk. */
  padding: calc(var(--nav-h, 88px) + 24px) var(--gutter) 80px;
  overflow: hidden;
}
.hero__fallback {
  position: absolute; inset: 0;
  background:
    radial-gradient(60% 60% at 20% 20%, rgba(53,200,245,0.55), transparent 70%),
    radial-gradient(60% 60% at 80% 30%, rgba(224,45,242,0.5), transparent 70%),
    linear-gradient(160deg, var(--navy) 0%, #2a0b6b 50%, var(--canvas) 100%);
  animation: hero-drift 18s ease-in-out infinite;
}
.hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.hero__overlay {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(22,22,22,0.35) 0%, rgba(22,22,22,0.1) 40%, rgba(22,22,22,0.85) 100%);
}
.hero__inner {
  position: relative;
  z-index: 1;
  max-width: var(--maxw);
  /* Halverwege tussen gecentreerd en tegen de linkermarge aan: de vrije
     ruimte links is gehalveerd, de rest schuift naar rechts mee. */
  margin-left: max(0px, calc((100% - var(--maxw)) / 4));
  margin-right: auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  /* Linksonder in plaats van gecentreerd: het midden van het kader is waar
     de montage zijn werk doet, en daar wil je geen kop overheen. */
  align-items: flex-start;
  text-align: left;
}
.hero__title {
  font-family: var(--font-display);
  font-size: clamp(34px, 5vw, 74px);
  line-height: 1.06;
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  text-wrap: balance;
  /* De showreel gaat van donkere zaal naar fel daglicht. De kop leesbaar
     houden met een schaduw op de letters is beter dan de hele film
     donkerder maken — dan zie je het werk niet meer waar het om gaat. */
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.55), 0 1px 4px rgba(0, 0, 0, 0.4);
}
.hero__title-line2 { display: inline-block; margin-top: 0.1em; }
.hero__actions {
  margin-top: 26px;
  display: flex;
  gap: 12px;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
}
/* De twee knoppen op deze rij, hoofdknop en wegwijzer, hebben dezelfde
   maat: gelijke padding, gelijk corps en gelijke regelhoogte. Tot
   27 oktober stond er ook een magenta pil tussen (zie .nav__tag). De
   wegwijzer heeft daarnaast nog een eigen regel verderop voor zijn kleur;
   die raakt de maat niet. */
.hero__actions .btn {
  /* Precies een kwart kleiner dan de maat van 19 augustus: 15 -> 11,25,
     30 -> 22,5 en 19 -> 14,25. De regelhoogte is relatief en schaalt dus
     vanzelf mee, waardoor de hoogte exact op driekwart uitkomt: 53,75
     wordt 40,3125. */
  padding: 11.25px 22.5px;
  font-size: 14.25px;
  line-height: 1.25;
}

/* ── Navigatie ────────────────────────────────────────────────────── */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px var(--gutter);
  pointer-events: none;
  /* Kleur en fond komen van de sectie eronder; initNavContrast zet
     data-op. Zonder JS blijft de donkere stand staan, en die klopt voor
     de hero waar de balk begint. */
  color: var(--creme);
  transition: color 0.35s ease;
}
.nav > * { pointer-events: auto; }

/* Het fond: sinds 27 oktober een vol vlak in de kleur van de sectie
   eronder, in plaats van een verloop dat onderaan doorzichtig werd. Tekst
   die onder de balk door schuift, verdwijnt nu netjes; door het verloop
   liep ze door de links heen. Elke sectie geeft haar kleur mee als
   --nav-bg (hieronder), en initNavContrast zet die op de balk. Boven
   de twee video's is dat fond doorzichtig: daar staat de navigatie
   gewoon op het beeld.

   De tekstkleur wisselt mee (data-op): op cyaan haalt witte tekst maar
   1,78:1 en op lichtblauw 1,30:1, navy 9,7:1 en 13,3:1. */
.nav::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-color: var(--nav-bg, var(--canvas));
  transition: background-color 0.35s ease;
}
.nav[data-op="licht"] { color: var(--navy); }

/* De kleur van de balk boven elke sectie: altijd die van het blok zelf.
   Boven de headerclip en de showreel geen vlak, maar het beeld.
   Contact is violet, op verzoek: crème haalt daar 4,06:1, net onder de
   4,5:1 die voor tekst van deze grootte geldt. Indigo haalde 6,5:1. */
.hero, .reel { --nav-bg: transparent; }
.clients, .faq, .footer { --nav-bg: var(--canvas); }
.process { --nav-bg: var(--lichtblauw); }
.collective { --nav-bg: var(--indigo); }
.contact { --nav-bg: var(--violet); }

/* Op het beeld een zachte schaduw onder de letters: de clip gaat van
   een donkere zaal naar fel daglicht, en zonder schaduw verdwijnt crème
   tegen een lichte lucht. initNavContrast zet data-fond. */
.nav[data-fond="beeld"] {
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.65), 0 0 14px rgba(0, 0, 0, 0.35);
}

/* Een sprong naar een sectie landt net onder de balk, op elk scherm: de
   balk ligt nooit over een kop.
   --nav-h zet initNavHoogte in main.js, want op een smalle telefoon loopt
   de balk over twee regels; 88px is de terugval zonder JavaScript. */
main > section, .footer { scroll-margin-top: var(--nav-h, 88px); }
/* Uitzondering: de showreel. Daar staat de balk doorzichtig op het beeld,
   dus landt de sprong bovenaan het kader. Landde hij onder de balk, dan zag
   je door de balk heen de knoppen onderaan de headerclip. */
.reel { scroll-margin-top: 0; }
.faq__item { scroll-margin-top: calc(var(--nav-h, 88px) + 16px); }

.nav__brand {
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  flex-shrink: 0;
  margin-right: 24px;
}
/* .nav__brand is een <a> en pakt daarmee de globale linkkleur. Die moet
   hier van .nav erven, anders blijft de merknaam altijd crème — ook op
   de lichte secties waar dat onleesbaar is. */
.nav__brand,
.nav__brand:hover { color: inherit; }

/* ── Logo: 18 losse toestellen uit één sprite-atlas ──────────────────
   Elk <i> is één toestel. Alle maten staan in de eenheden van het
   bronbeeld (2754 x 1076) en worden met --k naar schermformaat
   geschaald: één variabele wijzigen schaalt het hele logo mee. */
.logo {
  --logo-h: 55px;                    /* 15% groter dan de oorspronkelijke 48px */
  --k: calc(var(--logo-h) / 1076);   /* bronpixel → schermpixel */
  --amp: calc(var(--logo-h) * 0.07); /* hoe ver de toestellen uiteengaan */
  /* inline-block is nodig: als <span> zou het logo inline zijn en
     hoogte/breedte negeren. In de nav maskeert flex dat, daarbuiten niet. */
  display: inline-block;
  position: relative;
  flex-shrink: 0;
  width: calc(2754 * var(--k));
  height: var(--logo-h);
  vertical-align: middle;
}
.logo i {
  position: absolute;
  left: calc(var(--x) * var(--k));
  top: calc(var(--y) * var(--k));
  width: calc(var(--w) * var(--k));
  height: calc(var(--h) * var(--k));
  background-image: url(../assets/screens-atlas.png);
  background-repeat: no-repeat;
  /* Atlasmaat en -positie, ook in bronpixel-eenheden. */
  background-size: calc(2779.7 * var(--k)) calc(1501.9 * var(--k));
  background-position: calc(var(--ax) * var(--k) * -1) calc(var(--ay) * var(--k) * -1);
  animation:
    logo-adem 6.4s ease-in-out var(--dl) infinite alternate,
    var(--flikker) var(--fd) linear var(--fdl) infinite;
}
/* De clips liggen ín het beeldvlak van hun eigen toestel, bovenop de
   geschilderde ruis van de sprite. De randing volgt de beeldbuis, zodat
   er geen video over de cyaan omlijsting valt. Positie en maat staan per
   toestel in het style-attribuut, in procenten van het toestel — daardoor
   schuift de video mee met de ademhaling en het flikkeren. */
.logo i > video {
  position: absolute;
  display: block;
  object-fit: cover;
  /* Vult het beeldvlak; de onderliggende ruis blijft de terugval als een
     clip niet laadt (main.js verbergt de video dan). */
}

.logo i.fa { --flikker: logo-flikker-a; }
.logo i.fb { --flikker: logo-flikker-b; }
.logo i.fc { --flikker: logo-flikker-c; }

/* Radiaal naar buiten en weer terug. De buitenste toestellen bewegen
   verder (--a) en lopen iets achter (--dl), waardoor het als één
   ademende tros leest in plaats van als losse trilling. */
@keyframes logo-adem {
  from { transform: translate(0, 0); }
  to {
    transform: translate(
      calc(var(--ux) * var(--a) * var(--amp)),
      calc(var(--uy) * var(--a) * var(--amp))
    );
  }
}

/* Korte, harde dips — het gedrag van een beeldbuis die even wegvalt.
   Drie patronen, met per toestel een eigen duur en fase, zodat er nooit
   twee tegelijk knipperen. */
@keyframes logo-flikker-a {
  0%, 17.4%, 18.6%, 100% { opacity: 1; }
  17.6%, 18.4% { opacity: 0.28; }
}
@keyframes logo-flikker-b {
  0%, 46.4%, 47.2%, 62.4%, 63.4%, 100% { opacity: 1; }
  46.6%, 47% { opacity: 0.35; }
  62.6%, 63.2% { opacity: 0.62; }
}
@keyframes logo-flikker-c {
  0%, 33.4%, 34.6%, 78.4%, 79.2%, 100% { opacity: 1; }
  33.6%, 34.4% { opacity: 0.5; }
  78.6%, 79% { opacity: 0.22; }
}
.nav__wordmark {
  font-size: 23px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: inherit;
}
/* De typering naast de naam: dezelfde mono als de labels, zonder pil.
   Een dun streepje scheidt haar van het woordmerk. margin-right: auto
   houdt ze tegen de naam en duwt de links naar rechts. */
.nav__tag {
  margin: 0 auto 0 0;
  padding-left: 16px;
  border-left: 1px solid color-mix(in srgb, currentColor 35%, transparent);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  white-space: nowrap;
}
.nav__tag a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.nav[data-op="donker"] .nav__tag a:hover { color: var(--cyaan); }
.nav[data-op="licht"] .nav__tag a:hover { color: var(--magenta); }
.nav__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 12px 24px;
  min-width: 0;
  font-size: 16px;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.nav__links a { color: inherit; transition: color 0.2s; }
.nav[data-op="donker"] .nav__links a:hover { color: var(--cyaan); }
.nav[data-op="licht"] .nav__links a:hover { color: var(--magenta); }

/* ── 3. Klanten ───────────────────────────────────────────────────── */
/* Sinds 27 oktober op canvas, het zwart van onderaan; daarvoor cyaan.
   De logo's blijven op hun eigen vak: wit voor wie donkere letters
   heeft, zwart voor wie officieel alleen licht bestaat. Zo blijft elk
   logo in zijn eigen kleuren leesbaar, zonder dat wij ze herkleuren.
   Op 28 oktober stonden ze een paar uur in grijs op wit (commit
   e164f96); op verzoek weer in kleur. */
.clients {
  background: var(--canvas);
  color: var(--creme);
}
.clients__inner {
  padding: 110px var(--gutter);
  max-width: var(--maxw);
  margin: 0 auto;
}
.clients__title {
  margin-bottom: 44px;
  font-family: var(--font-display);
  font-size: clamp(60px, 8vw, 112px);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.05;
  text-wrap: balance;
  transform: rotate(-1.2deg);
  transform-origin: left center;
}
/* Flex en geen grid: met elf merken blijft er bij elk kolomaantal een
   halve rij over (3+3+3+2, op tabletbreedte 2+2+2+2+2+1). Een grid zet
   die links; flex centreert hem, zodat het blok in balans blijft. */
.clients__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
}
.client {
  flex: 0 0 calc((100% - 2 * 20px) / 3);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  transition: transform 0.25s;
}
.client:hover { transform: translateY(-6px) rotate(-1deg); }
.client__tile {
  width: 100%;
  height: 110px;
  background: #fff;
  border: 1px solid #fff;
  border-radius: 12px;
  padding: 18px;
  transition: box-shadow 0.25s;
}
/* Op zwart doet een donkere schaduw niets; een zachte cyaan gloed wel. */
.client:hover .client__tile { box-shadow: 0 10px 30px rgba(53, 200, 245, 0.22); }
/* Phantom of the Opera bestaat officieel alleen in wit: hun eigen site en
   linkpreview tonen het logo wit op zwart. Liever die eigen presentatie
   dan een zwarte versie die wij zelf zouden maken. Zo ook Titanic (wit) en
   Studio Ghibli in Concert (lichtroze): beide komen van een donkere
   affiche. Lanterna Magica (goud) oogde op wit bleek. */
/* Op de zwarte sectie krijgt het zwarte vak een lichte rand, anders
   loopt het in de ondergrond over. */
.client__tile--zwart { background: #000; border-color: rgba(245, 244, 240, 0.28); }
.client__tile img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Onder de tegels staat sinds 27 oktober geen merknaam meer: die staat in
   de alt-tekst van het logo. Alleen werk in opdracht van June20 krijgt een
   regel, "In opdracht van June20"; Stage Magic staat met zijn eigen logo in
   een vak. Vroeger stond daar de naam, met de partner vet eronder; daarvoor
   "via". Sinds 28 oktober wit en groter, op verzoek: eerst stond de regel
   op 11 px in gedempt crème. */
.client__label {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
  text-align: center;
}

/* ── 4. Het collectief ────────────────────────────────────────────── */
.collective {
  background: var(--indigo);
  color: var(--creme);
}
.collective__inner {
  padding: 110px var(--gutter);
  max-width: 1560px;
  margin: 0 auto;
}
.collective__title {
  margin-bottom: 64px;
  font-family: var(--font-display);
  font-size: clamp(64px, 9vw, 132px);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1;
}
.collective__sub {
  margin: -40px 0 56px;
  font-size: 19px;
  color: rgba(245, 244, 240, 0.8);
}
.photowall {
  border-radius: 20px;
  padding: 10px;
  background: linear-gradient(135deg, var(--cyaan) 0%, var(--magenta) 100%);
  transition: transform 0.3s;
}
.photowall:hover { transform: scale(1.005); }
.photowall__grid {
  border-radius: 12px;
  overflow: hidden;
  background: #0c0c0c;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
}
.photowall__cell {
  position: relative;
  margin: 0;
  min-width: 0;
  overflow: hidden;
  aspect-ratio: 3 / 3.6;
}
.photowall__cell img {
  width: 100%; height: 100%;
  object-fit: cover;
}
.photowall__cell .slot__ph {
  color: rgba(245, 244, 240, 0.5);
  background: repeating-linear-gradient(45deg, rgba(245,244,240,0.05) 0 8px, transparent 8px 16px);
}

/* ── 5. Wat we doen ───────────────────────────────────────────────── */
.process {
  background: var(--lichtblauw);
  color: var(--navy);
  min-height: 100svh;
  display: flex;
  align-items: stretch;
}
/* De slotzin zweeft midden in de ruimte die overblijft onder de tijdlijn.
   Twee automatische marges verdelen die ruimte gelijk, zodat het klopt bij
   elke schermhoogte in plaats van bij één vast getal. */
.process__inner {
  /* Onderpadding 64 in plaats van 110: de twee automatische marges
     verdelen de vrije ruimte gelijk, maar de onderpadding kwam daar nog
     bovenop. Met 64 vallen de ruimte boven en onder de slotzin gelijk. */
  padding: 130px var(--gutter) 64px;
  width: 100%;
  display: flex;
  flex-direction: column;
}
.process__closer { margin-top: auto; }
.process__closer-sub { margin-bottom: auto; }
.process__title {
  margin-bottom: 56px;
  font-family: var(--font-display);
  font-size: 4.9vw;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.05;
  white-space: nowrap;
  text-align: center;
}
.process__title > span { display: inline-block; }
/* De enige alinea lopende tekst op de pagina; vooral voor de vindbaarheid,
   dus rustig en gecentreerd onder de kop. Navy op 80% haalt op lichtblauw
   nog ruim 9:1. */
.process__intro {
  max-width: 640px;
  margin: -24px auto 56px;
  text-align: center;
  font-size: 18px;
  line-height: 1.55;
  color: rgba(10, 0, 70, 0.8);
  text-wrap: balance;
}
.w-van    { transform: rotate(-2deg) translateY(-0.08em); }
.w-eerste { animation: floaty 5s ease-in-out infinite; }
.w-idee   { background: var(--navy); color: var(--creme); padding: 0 0.14em; transform: rotate(1.6deg); }
.w-tot    { transform: rotate(-1deg); }
/* Sinds 28 oktober geen verloop en geen omlijning meer: elk gekleurd
   woord is één kleur, op een eigen blok, zoals "idee". Crème haalt op
   paars 5,0:1. Op magenta maar 3,0:1, daarom staat "elk scherm" in navy
   (5,3:1). */
.w-video  { background: var(--paars); color: var(--creme); padding: 0 0.14em; transform: rotate(-1.4deg); }
.w-op     { transform: translateY(0.1em) rotate(1.2deg); }
.w-scherm {
  background: var(--magenta);
  color: var(--navy);
  padding: 0 0.14em;
  animation: wiggle 3.2s ease-in-out infinite;
}

.timeline {
  position: relative;
  margin-bottom: 64px;
}
.timeline__line {
  position: absolute;
  top: 34px; left: 4%; right: 5%;
  height: 3px;
  background: linear-gradient(90deg, var(--cyaan), var(--paars), var(--magenta));
  border-radius: 2px;
}
.timeline__dot {
  position: absolute;
  top: 30px;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--navy);
  box-shadow: 0 0 14px var(--paars);
  /* 70% trager: de snelheid gaat naar 30%, dus de overtocht duurt
     6 / 0,3 = 20 seconden in plaats van 6. */
  animation: dot-run 20s linear infinite;
}
.timeline__steps {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 16px;
}
.step {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
  transition: transform 0.25s;
}
.step:hover { transform: translateY(-8px); }
.step__badge-wrap {
  position: relative;
  width: 104px; height: 104px;
  border-radius: 50%;
  border: 3px solid var(--cyaan);
  overflow: hidden;
  background: var(--navy);
  box-shadow: 0 0 24px #35c8f555;
}
.step__icon { width: 100%; height: 100%; object-fit: cover; }

.step__num {
  position: absolute;
  bottom: 4px; right: 4px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--cyaan);
  color: var(--navy);
  font-family: var(--font-display);
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.step--02 .step__badge-wrap { border-color: var(--step-02); box-shadow: 0 0 24px #5f8df355; }
.step--02 .step__num        { background: var(--step-02); }
.step--03 .step__badge-wrap { border-color: var(--paars);  box-shadow: 0 0 24px #7a2ff055; }
.step--03 .step__num        { background: var(--paars); }
.step--04 .step__badge-wrap { border-color: var(--step-04); box-shadow: 0 0 24px #b62bf555; }
.step--04 .step__num        { background: var(--step-04); }
.step--05 .step__badge-wrap { border-color: var(--magenta); box-shadow: 0 0 24px #e02df255; }
.step--05 .step__num        { background: var(--magenta); }

.step__title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.step__text {
  /* 12px in plaats van 14: daarmee passen ook de twee langste
     omschrijvingen op één regel, zodat de rij gelijk uitkomt. Gemeten:
     ze hebben 12,3px nodig bij een kolom van 355px. */
  font-size: 12px;
  line-height: 1.55;
  color: rgba(10, 0, 70, 0.65);
}

.process__closer {
  font-family: var(--font-display);
  font-size: clamp(24px, 3vw, 40px);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-align: center;
  text-wrap: balance;
  color: var(--navy);
}
/* De woorden van de slotzin dragen sinds 28 oktober dezelfde blokjes als
   de kop: idee op navy, video op paars, elk scherm op magenta, en de
   cyaan punt. inline-block, anders draaien ze niet mee. */
.process__closer > span { display: inline-block; }
.process__closer-sub {
  margin-top: 12px;
  text-align: center;
  font-size: 15px;
  color: rgba(10, 0, 70, 0.65);
}

/* ── 6. Contact ───────────────────────────────────────────────────── */
.contact {
  background: var(--violet);
  color: var(--creme);
  min-height: 100svh;
  display: flex;
  align-items: center;
}
.contact__inner {
  max-width: var(--maxw);
  width: 100%;
  margin: 0 auto;
  padding: 110px var(--gutter);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
}
.contact__title {
  margin: 0 0 40px;
  font-family: var(--font-display);
  font-size: clamp(40px, 5vw, 72px);
  line-height: 0.98;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
/* "actie" — magenta op violet haalt maar 1,24:1 contrast. De witte rand
   geeft het woord een harde grens tegen zowel de achtergrond (4,47:1) als
   de eigen vulling (3,60:1), waardoor het leesbaar wordt zonder de
   merkkleur op te geven. paint-order zet de rand áchter de vulling, zodat
   de letters op volle dikte blijven in plaats van uitgehold te worden.
   Op 26 oktober even zwart geweest (4,70:1 en 5,83:1), op verzoek terug
   naar wit. */
.contact__title span {
  color: var(--magenta);
  -webkit-text-stroke: 0.055em #fff;
  paint-order: stroke fill;
}
.contact .section-label { margin-bottom: 16px; }

/* Het collectief, bovenaan het contactblok (sinds 27 oktober): label en
   kop links, de uitleg rechts, op dezelfde twee kolommen als het contact
   eronder. De uitleg is minstens 24 px: crème haalt op violet geen 4,5:1,
   maar tekst van die grootte heeft genoeg aan 3:1. */
.contact__collectief {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 72px;
  align-items: end;
  padding-bottom: 56px;
  border-bottom: 1px solid rgba(245, 244, 240, 0.25);
}
.contact__collectief .section-label { grid-column: 1 / -1; }
.contact__collectief .contact__title { margin: 0; }
.contact__lead {
  max-width: 32ch;
  font-size: clamp(24px, 2.1vw, 30px);
  line-height: 1.35;
  text-wrap: pretty;
}

/* Het aanspreekpunt: foto, naam en functie op hetzelfde donkere paneel als
   het formulier ernaast. Kleine crème tekst haalt op het violet zelf geen
   4,5:1 (wit 4,06, navy 4,27 — zie de navigatietabel in HANDOVER 3.3); op
   dit paneel ruim 8:1. */
.contact__persoon {
  display: flex;
  align-items: center;
  gap: 18px;
  max-width: 440px;
  margin: 0 0 32px;
  padding: 18px 22px;
  background: rgba(10, 0, 70, 0.45);
  border: 1px solid rgba(245, 244, 240, 0.2);
  border-radius: 16px;
}
.contact__foto {
  flex: 0 0 auto;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 3px var(--creme);
  background: var(--canvas);
}
.contact__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Zonder foto: initialen in plaats van het gestreepte vlak van de logotegels. */
.contact__foto .slot__ph {
  padding: 0;
  font-family: var(--font-display);
  font-size: 30px;
  letter-spacing: 0.02em;
  color: var(--creme);
  background: var(--violet);
}
.contact__persoon figcaption {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.contact__naam {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--creme);
}
.contact__functie {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(245, 244, 240, 0.8);
}

.contact__details {
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-size: 17px;
}
.contact__row {
  display: flex;
  gap: 16px;
  align-items: baseline;
}
.contact__row dt {
  color: rgba(245, 244, 240, 0.4);
  font-family: var(--font-mono);
  font-size: 13px;
  width: 56px;
  flex-shrink: 0;
}
.contact__row dd { margin: 0; white-space: nowrap; }
/* Alleen de mail krijgt de accentkleur; tel is klikbaar maar blijft crème. */
.contact__row a { color: inherit; }
.contact__row a[href^="mailto:"] { color: var(--mail-link); }
.contact__row a:hover { color: #fff; }

/* De honingpot staat buiten beeld in plaats van display:none: sommige
   bots slaan verborgen velden bewust over, een veld buiten beeld vullen
   ze wel in. Mensen en schermlezers zien hem niet (aria-hidden). */
.form__hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-self: start;
  background: rgba(10, 0, 70, 0.45);
  border: 1px solid rgba(245, 244, 240, 0.2);
  border-radius: 16px;
  padding: 36px;
  backdrop-filter: blur(6px);
}
.form__input {
  background: var(--canvas);
  border: 1px solid rgba(245, 244, 240, 0.15);
  border-radius: 10px;
  color: var(--creme);
  padding: 15px 18px;
  font-size: 15px;
  font-family: var(--font-body);
  outline: none;
  transition: border-color 0.2s;
}
.form__input::placeholder { color: rgba(245, 244, 240, 0.45); }
.form__input:focus { border-color: var(--cyaan); }
.form__input:user-invalid { border-color: var(--magenta); }
textarea.form__input { resize: vertical; min-height: 120px; }

.form__submit {
  align-self: flex-start;
  background: var(--creme);
  color: var(--canvas);
  border: 0;
  border-radius: 999px;
  padding: 15px 36px;
  font-size: 15px;
  font-weight: 700;
  font-family: var(--font-body);
  cursor: pointer;
  transition: background 0.2s;
}
.form__submit:hover { background: var(--cyaan); }
.form__submit[disabled] { opacity: 0.6; cursor: progress; }

.form__status {
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.6;
  color: rgba(245, 244, 240, 0.75);
}
.form__status:empty { display: none; }
.form__status.is-error { color: #ffd2fb; }
.form__status.is-ok    { color: var(--mail-link); }

/* ── 7. Veelgestelde vragen ───────────────────────────────────────── */
/* Canvas onder het violet van Contact (sinds 27 oktober staan de vragen
   na Contact) en zo één zwart vlak met de footer. Crème haalt hier
   16,4:1, de antwoorden op 80% nog ruim 10:1, cyaan en magenta allebei
   meer dan 4,5:1. */
.faq {
  background: var(--canvas);
  color: var(--creme);
}
.faq__inner {
  max-width: 960px;
  margin: 0 auto;
  padding: 110px var(--gutter);
}
.faq .section-label { margin-bottom: 16px; }
.faq__title {
  margin: 0 0 48px;
  font-family: var(--font-display);
  font-size: clamp(40px, 5vw, 72px);
  line-height: 0.98;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-wrap: balance;
}
.faq__lijst { border-top: 1px solid rgba(245, 244, 240, 0.2); }
.faq__item { border-bottom: 1px solid rgba(245, 244, 240, 0.2); }
/* Het plusteken staat absoluut en niet via flex: Safari maakte van een
   <summary> lang geen flexcontainer. Open draait het een kwartslag naar
   een kruisje. */
.faq__vraag {
  position: relative;
  padding: 24px 56px 24px 0;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.35;
  list-style: none;
  cursor: pointer;
  transition: color 0.2s;
}
.faq__vraag::-webkit-details-marker { display: none; }
.faq__vraag:hover { color: var(--cyaan); }
.faq__vraag::after {
  content: '+';
  position: absolute;
  top: 50%;
  right: 4px;
  font-family: var(--font-mono);
  font-size: 32px;
  font-weight: 400;
  line-height: 1;
  color: var(--cyaan);
  transform: translateY(-50%);
  transition: transform 0.25s ease, color 0.2s;
}
.faq__item[open] > .faq__vraag::after {
  color: var(--magenta);
  transform: translateY(-50%) rotate(45deg);
}
.faq__antwoord {
  max-width: 68ch;
  padding: 0 0 28px;
  font-size: 17px;
  line-height: 1.6;
  color: rgba(245, 244, 240, 0.8);
}

/* ── Footer ───────────────────────────────────────────────────────── */
.footer {
  border-top: 1px solid rgba(245, 244, 240, 0.1);
  padding: 40px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: rgba(245, 244, 240, 0.4);
}
.footer__cookies {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
}
.footer__cookies:hover { color: var(--creme); }
.footer__cookies[hidden] { display: none; }
.footer__link { color: inherit; }
.footer__link:hover { color: var(--creme); }
.cookies__tekst a { color: var(--mail-link); }

/* ── Cookievraag ─────────────────────────────────────────────────────
   Alleen in beeld als Google Ads aanstaat (CONFIG.googleAds.id). Weigeren
   staat even groot en even dichtbij als akkoord gaan: zo hoort het. De
   [hidden]-regel is nodig omdat display:flex anders van hidden wint. */
.cookies {
  position: fixed;
  z-index: 50;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  width: min(560px, calc(100% - 32px));
  padding: 18px 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 18px;
  background: var(--canvas);
  color: var(--creme);
  border: 1px solid rgba(245, 244, 240, 0.2);
  border-radius: 16px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
}
.cookies[hidden] { display: none; }
.cookies__tekst {
  flex: 1 1 260px;
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
}
.cookies__knoppen { display: flex; gap: 10px; }
.cookies__knop {
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: 999px;
  border: 1px solid rgba(245, 244, 240, 0.55);
  background: transparent;
  color: var(--creme);
  cursor: pointer;
}
.cookies__knop--ja {
  background: var(--cyaan);
  border-color: var(--cyaan);
  color: var(--navy);
}
.cookies__knop:focus-visible { outline: 3px solid var(--cyaan); outline-offset: 2px; }

/* ===================================================================
   Responsive — niet uitgewerkt in het prototype, hier ingevuld
   volgens dezelfde ritmes (grids vallen terug naar 2 en 1 kolom).
   =================================================================== */

@media (max-width: 1279px) {
  /* Smaller dan een ruime laptop past de typering niet meer tussen naam en
     links: de links zouden over drie of vier regels breken. Ze krijgt
     dan een eigen regel onder de naam, over de volle breedte. De balk
     wordt iets hoger, en --nav-h groeit mee. Sinds de lange link
     "Het Collectief & Contact" erbij kwam, gebeurt dat onder 1280 in
     plaats van onder 1201 px: daartussen braken de links anders over
     twee rijen. */
  .nav { flex-wrap: wrap; row-gap: 4px; }
  .nav__tag {
    order: 3;
    flex-basis: 100%;
    margin: 0;
    padding-left: 0;
    border-left: 0;
    font-size: 10px;
    letter-spacing: 0.1em;
  }
  /* De links blijven naast de naam en breken zo nodig binnen hun eigen
     ruimte; zonder dit schuiven ze als geheel naar een eigen rij. */
  .nav__links { flex: 1 1 0; }
}

@media (max-width: 1024px) {
  :root { --gutter: 28px; }

  .contact__inner {
    grid-template-columns: 1fr;
    gap: 48px;
  }
  .form { align-self: stretch; }
  .contact__collectief { grid-template-columns: 1fr; padding-bottom: 48px; }
  .contact__lead { margin-top: 24px; }

  /* Kop mag wrappen zodra één regel niet meer leesbaar is */
  .process__title {
    white-space: normal;
    font-size: clamp(34px, 6.6vw, 76px);
    line-height: 1.12;
  }
  .timeline__line, .timeline__dot { display: none; }
  .timeline__steps { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px 16px; }
  .process__inner { padding: 110px var(--gutter) 90px; }
}

@media (max-width: 860px) {
  .client { flex-basis: calc((100% - 20px) / 2); }

  .photowall__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .photowall__cell:nth-child(3) {
    grid-column: span 2;
    aspect-ratio: 16 / 9;
  }

  .clients__inner,
  .collective__inner,
  .faq__inner { padding: 80px var(--gutter); }
  .contact__inner { padding: 96px var(--gutter); }

  .collective__sub { margin: -28px 0 40px; font-size: 17px; }
}

@media (max-width: 680px) {
  :root { --gutter: 20px; }

  .nav { padding: 12px var(--gutter); }
  .logo { --logo-h: 41px; }

  /* Op telefoon geen dertien videodecoders in een vaste balk: het logo is
     hier 36px en de schermen zijn een paar pixels. De geschilderde ruis
     blijft staan. main.js start ze op deze breedte ook niet op. */
  .logo i > video { display: none; }
  .nav__wordmark { font-size: 20px; }
  .nav__brand { gap: 10px; margin-right: 14px; }
  /* Vijf links sinds FAQ erbij kwam (27 oktober): de tussenruimte 14 in
     plaats van 16 px, zodat ze vanaf 441 px nog op één rij passen. */
  .nav__links { font-size: 15px; gap: 8px 14px; }
  /* Op een telefoon: naam en typering op de eerste regel, de links over
     de volle breedte eronder. --nav-h groeit vanzelf mee, dus geen
     sectie schuift onder de hogere balk. */
  .nav { flex-wrap: wrap; row-gap: 6px; }
  .nav__tag {
    order: 0;
    flex: 1 1 0;
    padding-left: 10px;
    border-left: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    white-space: normal;
  }
  .nav__links { flex: 0 0 100%; justify-content: flex-start; }

  /* Onderaan 72 in plaats van 56: daar staat de bediening van de clip, en
     de knoppenrij schoof er 12 px overheen. */
  .hero { padding: calc(var(--nav-h, 81px) + 20px) var(--gutter) 72px; }
  /* De knoppen op de clip een vijfde kleiner: 32 in plaats van 40 px hoog.
     Op een telefoon namen ze anders een groot stuk van het beeld in. */
  .hero__actions .btn { padding: 8.5px 17px; font-size: 12px; }
  .hero__actions { margin-top: 28px; gap: 12px; }
  .btn { padding: 14px 26px; font-size: 15px; }

  .section-label { font-size: 18px; }
  .clients__title { margin-bottom: 32px; }
  .collective__title { margin-bottom: 48px; }
  .faq__title { margin-bottom: 32px; }
  .faq__vraag { padding: 20px 44px 20px 0; font-size: 18px; }
  .faq__antwoord { font-size: 16px; }

  .timeline__steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .step__badge-wrap { width: 88px; height: 88px; }


  .form { padding: 24px; }
  .contact__row dd { white-space: normal; }
  .footer { padding: 32px var(--gutter); font-size: 11px; }
}

@media (max-width: 440px) {
  .client { flex-basis: 100%; }
  .timeline__steps { grid-template-columns: 1fr; }

  /* De merknaam blijft staan, ook op de smalste telefoon: het beeldmerk
     alleen leest niet als "All Screens". In plaats van hem te verbergen
     worden logo, naam en links een maat compacter. */
  .logo { --logo-h: 35px; }
  .nav__wordmark { font-size: 17px; }
  .nav__brand { gap: 8px; margin-right: 10px; }
  /* 13 px en 10 px tussenruimte: zo passen de vijf links op één rij
     tot 375 px breed. Op nog smallere schermen breken ze over twee. */
  .nav__links { font-size: 13px; gap: 6px 10px; letter-spacing: 0.01em; }
}

/* Op telefoonbreedte houdt de merknaam te weinig ruimte over: de links
   vallen dan over vier regels naast het merk. Daarom breekt de balk zelf
   af — merk boven, links daaronder over de volle breedte, twee regels. */
@media (max-width: 440px) {
  .nav { flex-wrap: wrap; row-gap: 4px; }
  .nav__brand { margin-right: 0; }
  .nav__tag { margin-left: 10px; padding-left: 10px; }
  .nav__links { width: 100%; justify-content: flex-start; }
}

/* Op de smalste telefoons (320 px) blijft er naast de naam maar een
   strookje van 66 px over, en wordt de typering een kolom van vier
   regels. Daar krijgt ze een eigen regel tussen naam en links. */
@media (max-width: 360px) {
  .nav__tag {
    flex-basis: 100%;
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
  }
  /* Vijf links op één rij tot 360 px, de breedte van veel Android-
     telefoons. Op 320 px breken ze nog over twee rijen. */
  .nav__links { font-size: 12.5px; gap: 6px 8px; }
}

/* ── Beweging beperken ────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  /* De header-video NIET verbergen: dat is nu de showreel, geen sfeerbeeld.
     Hij blijft staan op zijn posterframe en start niet vanzelf; de
     bedieningsknoppen laten hem alsnog afspelen. */
  .hero__video { animation: none; }
  .hero__fallback { animation: none; }

  /* Expliciet uit: de regel hierboven zet de duur op vrijwel nul, en een
     alternate-animatie zou dan op zijn EINDpositie blijven staan — de
     toestellen zouden permanent uit elkaar liggen. */
  .logo i { animation: none; opacity: 1; transform: none; }
}

/* ===================================================================
   Header-bediening — de showreel speelt automatisch en stil
   =================================================================== */

/* WCAG 2.2.2 eist een pauzeermogelijkheid voor bewegend beeld dat
   vanzelf start, langer dan vijf seconden duurt en naast andere inhoud
   staat. De header voldoet aan alle drie, dus de pauzeknop is verplicht
   — niet optioneel, en prefers-reduced-motion dekt het niet af. */
.hero__controls {
  position: absolute;
  z-index: 2;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  display: flex;
  gap: 10px;
  /* Bij binnenkomst staan de knoppen centraal onderaan: de video wacht
     daar op een druk op play. Zodra de aftiteling begint schuiven ze mee
     naar rechts, en bij het opnieuw starten van de lus komen ze terug.
     Zelfde duur en versoepeling als de letters, zonder vertraging, zodat
     het één beweging is. */
  left: 50%;
  transform: translateX(-50%);
}
.hero.is-eindkaart .hero__controls {
  left: 100%;
  transform: translateX(calc(-100% - 20px - env(safe-area-inset-right, 0px)));
}

/* "Made with AI" rechtsonder op de clip. Aan het eind van elke lus schuift
   de bediening (48 px hoog) naar precies die hoek; het label schuift dan
   mee omhoog, zodat ze elkaar nooit raken en de vermelding blijft staan.
   Omhoog gaat meteen, omlaag pas na een halve seconde: bij de herstart
   vertrekken de knoppen met ±0,3 s vertraging uit de hoek (volgEindkaart),
   en het label mag niet eerder terug zijn dan zij weg zijn. */
.hero__ai {
  position: absolute;
  z-index: 2;
  right: calc(20px + env(safe-area-inset-right, 0px));
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(245, 244, 240, 0.85);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  transition: bottom 0.9s cubic-bezier(0.22, 0.68, 0.24, 1) 0.5s;
}
.hero.is-eindkaart .hero__ai {
  bottom: calc(20px + 48px + 14px + env(safe-area-inset-bottom, 0px));
  transition-delay: 0s;
}
/* Op een telefoon staan de knoppen onder elkaar en vullen ze in de
   eindstand de hele onderrand: rechtsonder is daar geen plek. Het label
   gaat dan naar rechtsboven, net onder de navigatie. */
@media (max-width: 680px) {
  .hero__ai,
  .hero.is-eindkaart .hero__ai {
    top: calc(var(--nav-h, 81px) + 14px);
    bottom: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__controls,
  .hero__ai { transition: none; }
}
/* ── Meeloopbalk ──────────────────────────────────────────────────────
   Een dunne streep op de onderrand van het beeld die meeloopt met de
   speelduur, zodat je ziet hoe lang iets duurt zonder dat er cijfers bij
   hoeven. Eén vlakke kleur, geen verloop: hij moet af te lezen zijn, niet
   opvallen. Dezelfde balk ligt onder de header en onder de showreel.

   De baan eronder is bijna zwart. Zonder die baan verdwijnt het begin van
   de streep op een licht shot, en juist aan het begin wil je zien dat er
   nog niets verstreken is. */
.voortgang {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 3;
  height: 3px;
  background: rgba(0, 0, 0, 0.35);
  overflow: hidden;
  pointer-events: none;
}
.voortgang__vul {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--cyaan);
  /* Schalen in plaats van de breedte zetten: dat scheelt de browser bij
     elke tijdsprong een herberekening van de opmaak, en die sprongen komen
     een paar keer per seconde binnen. Geen transition erop — de sprongen
     zijn al klein genoeg, en een overgang maakt er naijling van. */
  transform: scaleX(0);
  transform-origin: left center;
}

/* ── Wegwijzer naar de showreel ───────────────────────────────────────
   Staat naast 'Plan een gesprek' in .hero__actions en beweegt daardoor
   vanzelf mee met de eindkaart: de FLIP-animatie pakt dat hele blok in
   één keer, dus hier is niets aparts voor nodig.

   Bewust groter dan de knop ernaast, en dat is niet alleen vormgeving.
   Bij 19px en gewicht 700 telt de tekst als 'large text', waar WCAG 3:1
   vraagt in plaats van 4,5:1. Wit op magenta haalt 3,60:1 en komt daar
   dus net boven — op de kleinere maat van de knop ernaast zou wit
   zakken. Maak je hem ooit kleiner, zet de tekst dan terug op navy: dat
   haalt 5,29:1 en mag op elke maat. */
.hero__scroll {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
/* Maat en padding komen uit de gedeelde regel bij .hero__actions; hier
   staat alleen nog wat deze knop eigen is. */
.hero__actions .hero__scroll { color: #fff; }
/* Anders houdt de regel hierboven het wit ook vast op het witte
   hoververvlak. */
.hero__actions .hero__scroll:hover { color: var(--navy); }
/* Kleiner dan de regelhoogte van de tekst, zodat de pijl de knop niet
   nóg hoger maakt. Mee verkleind met de knop: 20 -> 15. */
.hero__scroll svg {
  width: 15px;
  height: 15px;
  flex: none;
  animation: scroll-wenk 2.4s ease-in-out infinite;
}
@keyframes scroll-wenk {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

@media (prefers-reduced-motion: reduce) {
  .hero__scroll svg { animation: none; }
}

.hero__ctrl,
.reel__ctrl {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(8px) saturate(120%);
  color: #fff;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}
.hero__ctrl:hover,
.reel__ctrl:hover { background: rgba(0, 0, 0, 0.68); }
.hero__ctrl:active,
.reel__ctrl:active { transform: scale(0.94); }
.hero__ctrl svg,
.reel__ctrl svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
  /* Een showreel gaat van wit strand naar zwarte zaal; zonder schaduw
     verdwijnt het icoon op de lichte shots. */
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.7));
}
/* De twee knoppen van de showreel krijgen elk een eigen merkkleur, zodat
   je aan de kleur al ziet dat het om twee verschillende dingen gaat:
   cyaan stuurt het beeld, magenta het geluid. Dat is hetzelfde paar dat
   de rest van de pagina aanhoudt — cyaan voor de hoofdknop, magenta voor
   de accenten en de tekstselectie.

   Het icoon is navy en niet wit. Doorgerekend op de merkkleuren:
   wit op cyaan haalt 1,96:1 en navy 9,74:1; wit op magenta 3,60:1 en
   navy 5,29:1. Navy wint dus twee keer, en ruim.

   De knop in de header houdt zijn doorzichtige zwart: die ligt over
   wisselend beeld zonder kader eromheen, en is bovendien geen keuze maar
   een eis (WCAG 2.2.2, zie 3.6 in de overdracht). */
.reel__ctrl[data-reel-play]  { background: var(--cyaan); }
.reel__ctrl[data-reel-sound] { background: var(--magenta); }
.reel__ctrl[data-reel-play],
.reel__ctrl[data-reel-sound] {
  color: var(--navy);
  border-color: rgba(255, 255, 255, 0.9);
  backdrop-filter: none;
}
.reel__ctrl[data-reel-play]:hover  { background: #6bdbf9; }
.reel__ctrl[data-reel-sound]:hover { background: #eb63f6; }
/* Het vlak geeft nu zelf het contrast; de schaduw onder het icoon maakt
   navy op cyaan alleen maar troebel. */
.reel__ctrl[data-reel-play] svg,
.reel__ctrl[data-reel-sound] svg { filter: none; }

/* Dubbele ring: op wisselend videobeeld is één kleur nooit genoeg. */
.hero__ctrl:focus-visible,
.reel__ctrl:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.65);
}


/* ── Eindkaart: de tekst voegt zich naar de aftiteling ────────────────
   De showreel eindigt met het ALL SCREENS-logo, gecentreerd, met de
   tekst tussen 52% en 67% van de beeldhoogte. Drie seconden voor het
   einde schuift onze kop daaronder: gecentreerd, op één regel en
   kleiner, zodat het blok — dat aan de onderkant hangt — vanzelf lager
   uitkomt dan het logo in beeld. */
/* De logotekst in de showreel eindigt op 67% van de beeldhoogte (gemeten
   op de frames). Midden tussen dat punt en de onderkant is 83,5%; daar
   gaat het blok nog een kwart van de overgebleven ruimte omlaag:
   83,5 + (100 - 83,5) x 0,25 = 87,6%, en daarna nog eens 15% van wat er
   overbleef: 87,6 + (100 - 87,6) x 0,15 = 89,5%. */
.hero.is-eindkaart .hero__inner {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: 89.5%;
  transform: translateY(-50%);
  width: auto;
  max-width: none;
  margin: 0;
  /* In de eindstand komen de magenta regel en de knop naast elkaar op één
     lijn. De kop krijgt de volle breedte, waardoor die twee vanzelf op de
     volgende regel belanden en daar samen gecentreerd staan. */
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  column-gap: 14px;
  text-align: center;
}
/* Op een telefoon staan de drie knoppen onder elkaar en is het blok te
   hoog om rond 89,5% te centreren: de onderste knop kwam dan tot 7 px van
   de rand, over de bediening en de meeloopbalk heen. Daar hangt het in
   de eindstand aan dezelfde onderlijn als ervoor, 72 px boven de rand. */
@media (max-width: 680px) {
  .hero.is-eindkaart .hero__inner {
    top: auto;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    transform: none;
  }
}
.hero.is-eindkaart .hero__title { flex: 0 0 100%; }
.hero.is-eindkaart .hero__title {
  /* Eén regel, met de ondergrens laag genoeg dat hij ook op een smalle
     telefoon niet hoeft af te breken. */
  font-size: clamp(14px, 3.1vw, 46px);
  line-height: 1.15;
  white-space: nowrap;
}
/* Op één regel: naast het logo in beeld hoort dit een onderschrift te
   zijn, geen tweede kop. */
.hero.is-eindkaart .hero__title br { display: none; }
.hero.is-eindkaart .hero__title-line2 { margin-top: 0; }
/* Een gewone spatie in content klapt dicht; vandaar een harde spatie. */
.hero.is-eindkaart .hero__title-line2::before { content: '\00a0'; }
.hero.is-eindkaart .hero__actions { justify-content: center; margin-top: 20px; }

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

/* Letters kunnen alleen transformeren als ze een eigen box hebben; het
   woord-omhulsel voorkomt dat de regel middenin een woord afbreekt. */
.hero__title .wrd { white-space: nowrap; }
.hero__title .ltr {
  display: inline-block;
  will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
  .hero__title .ltr,
  .hero__actions { transition: none !important; transform: none !important; }
}

/* ── Showreel ─────────────────────────────────────────────────────────
   De echte reel, direct onder de header en over de volle breedte van het
   venster — net als de header zelf: geen marge, geen afgeronde hoeken,
   rand tot rand.

   Het beeld is 2,06:1 en geen 16:9: de bron had letterbox-balken
   ingebakken en beide headerversies zijn daarop bijgesneden. Daarom
   aspect-ratio en geen vaste hoogte — zo groeit de hoogte mee met de
   breedte en blijft het beeld onbesneden, hoe breed het venster ook is. */
.reel {
  position: relative;
  background: var(--canvas);
}
.reel__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 2.06 / 1;
  overflow: hidden;
  background: #000;
}
.reel__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* De startknop dekt het hele beeld en is met opzet onzichtbaar: het
   posterframe ís de knop, precies zoals gevraagd — geen playknop of
   overlay ervoor. Voor de muis maakt dat niets uit, voor toetsenbord en
   schermlezer is dit het aangrijpingspunt. Alleen bij toetsenbordfocus
   wordt hij zichtbaar, anders is hij niet te vinden. */
.reel__start {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
}
.reel__start:focus-visible {
  outline: 3px solid #fff;
  outline-offset: -6px;
  box-shadow: inset 0 0 0 8px rgba(0, 0, 0, 0.55);
}
.reel__start[hidden] { display: none; }

/* "The real stuff" rechtsonder, de tegenhanger van "Made with AI" op de
   headerclip: zelfde letter, zelfde plek. Boven de onzichtbare startknop,
   maar zonder kliks te vangen, zodat een klik op het label gewoon de reel
   start. De bediening staat hier gecentreerd en schuift niet, dus het
   label hoeft nergens voor uit te wijken. */
.reel__label {
  position: absolute;
  z-index: 2;
  right: calc(20px + env(safe-area-inset-right, 0px));
  bottom: 24px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  color: rgba(245, 244, 240, 0.85);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
  pointer-events: none;
}

/* Gecentreerd onderaan het kader, net als de knoppen in de header bij
   binnenkomst. Anders dan daar blijven ze hier staan: dit blok kent geen
   eindkaart om voor uit de weg te gaan. */
.reel__controls {
  position: absolute;
  z-index: 2;
  left: 50%;
  transform: translateX(-50%);
  bottom: 20px;
  display: flex;
  gap: 14px;
}
.reel__controls[hidden] { display: none; }

@media (max-width: 680px) {
  .reel__controls { bottom: 12px; gap: 10px; }

  /* De bedieningsknoppen op beide video's een kwart kleiner: 36 in plaats
     van 48 px. Op een showreel van 180 px hoog namen ze anders een kwart
     van het beeld in. Ruim boven de 24 px die WCAG 2.5.8 als minimale
     raakvlak vraagt. Deze regels staan hier, ná de gewone maat hogerop in
     het bestand: in een eerdere mediaquery zouden ze verliezen. */
  .hero__ctrl,
  .reel__ctrl { width: 36px; height: 36px; }
  .hero__ctrl svg,
  .reel__ctrl svg { width: 17px; height: 17px; }
  .hero__controls { gap: 8px; }
}
