/* ═══════════════════════════════════════════════════════════════════════════
   buro barbara — interiors for happy people
   ---------------------------------------------------------------------------
   Eén stylesheet voor alle pagina's.

     1. tokens          — kleuren, ritme, timing
     2. basis           — reset en typografie
     3. topbar + menu   — op elke pagina
     4. footer          — op elke pagina
     5. aanlandpagina   — intro, hero, statement, partners
     6. about           — vast beeld links, scrollende tekst rechts
     7. projecten       — grid links, geselecteerd project rechts
     8. responsive
     9. beweging beperken

   De achtergrondkleur van een sectie staat in het data-bg attribuut in de
   HTML. Het scrollscript mengt die kleuren vloeiend in elkaar.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ═══ 1. TOKENS ═════════════════════════════════════════════════════════ */

:root {
  /* — haar palet, rechtstreeks uit de renders gepikt ————————————————— */
  --c-butter : #F7F4D0;   /* aanlandpagina                */
  --c-sky    : #BBDDFF;   /* about, projecten, footer     */
  --c-paper  : #F6F4F0;   /* projectengrid, partners      */
  --c-ink    : #282828;   /* logo en tekst                */
  --c-brown  : #7F5122;   /* "interiors for happy people" */
  --c-mint   : #00CCBA;   /* accent uit haar eigen kast   */
  --c-rose   : #EDC8C3;   /* menu, nieuw in menuv2        */
  --c-taupe  : #C59A6D;   /* footer onder de uitnodiging  */

  /* live waarden — elke frame door het scrollscript bijgewerkt */
  --bg : var(--c-butter);
  --fg : var(--c-ink);

  /* — ritme ————————————————————————————————————————————————————————— */
  --gut     : clamp(1.15rem, 3.2vw, 3rem);
  --split   : 50%;                            /* de twee vlakken raken elkaar in het midden */
  --ease    : cubic-bezier(.16, 1, .3, 1);    /* out-expo, voor reveals      */
  --ease-io : cubic-bezier(.76, 0, .24, 1);   /* in-out, voor panelen        */

  /* — timing van de intro ———————————————————————————————————————————— */
  --t-curtain : 2.05s;
  --t-hero    : 2.55s;
}


/* ═══ 2. BASIS ══════════════════════════════════════════════════════════ */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Poppins", "Futura", "Century Gothic", system-ui, sans-serif;
  font-weight: 300;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-loading { overflow: hidden; }

/* scroll-lock zolang het menu open staat (scrollbarbreedte gecompenseerd) */
body.is-locked { overflow: hidden; padding-right: var(--sbw, 0px); }
body.is-locked .topbar { padding-right: calc(var(--gut) + var(--sbw, 0px)); }

img, svg { display: block; max-width: 100%; height: auto; }
ul, ol   { list-style: none; margin: 0; padding: 0; }
a        { color: inherit; text-decoration: none; }
button   { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, p { margin: 0; font-weight: inherit; }

::selection { background: var(--c-mint); color: var(--c-ink); }

:focus-visible { outline: 2px solid currentColor; outline-offset: 6px; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: fixed; top: 0; left: 50%;
  transform: translate(-50%, -120%);
  z-index: 1000;
  padding: .75rem 1.25rem;
  background: var(--c-ink); color: var(--c-butter);
  font-size: .9rem;
  transition: transform .3s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* line-reveal: <p class="reveal"><i>tekst</i></p> */
.reveal   { display: block; overflow: hidden; padding-bottom: .18em; }
.reveal i { display: block; font-style: normal; transform: translateY(115%); transition: transform .95s var(--ease); }
.reveal.is-in i { transform: translateY(0); }

.eyebrow {
  font-size: clamp(.82rem, 1.02vw, .97rem);
  font-weight: 400;
  letter-spacing: .015em;
  opacity: .62;
}


/* ═══ 3. TOPBAR + MENU ══════════════════════════════════════════════════ */

.topbar {
  position: fixed; top: 0; left: 0;
  width: 100%;
  z-index: 850;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 2.2vw, 1.75rem) var(--gut);
  pointer-events: none;
  transition: transform .55s var(--ease-io), opacity .3s linear;
}
.topbar > * { pointer-events: auto; }

body.menu-open .topbar { color: var(--menu-fg, #282828); }
body.menu-open .topbar__brand { opacity: 0 !important; }

.topbar__brand {
  position: absolute;
  left: var(--gut); top: 50%;
  transform: translateY(-50%);
  font-size: clamp(.85rem, 1.1vw, 1rem);
  font-weight: 400;
  letter-spacing: .015em;
  opacity: 0;                       /* verschijnt pas als de hero weg is */
  transition: opacity .4s linear;
}

/* De + staat altijd exact in het midden. Dat is meteen de scheidingslijn
   tussen de twee vlakken op about en projecten, dus hij hoeft nergens te
   verspringen — ook niet als het menu opengaat. */
.plus {
  position: absolute;
  left: 50%; top: clamp(.7rem, 1.5vw, 1.15rem);
  transform: translateX(-50%);
  display: grid; justify-items: center; gap: .3rem;
  padding: .25rem .6rem .4rem;
  opacity: 0;
  animation: fade-in .9s var(--ease) forwards;
  cursor: pointer;
}
body.page-home .plus { animation-delay: var(--t-hero); }

/* Botergeel zolang hij op het herobeeld ligt; daarna wordt de pagina zelf
   botergeel en zou geel op geel wegvallen. Niet in het open menu: daar geldt
   de tekstkleur van het menuvlak. */
body.page-home.op-hero:not(.menu-open) .plus { color: var(--c-butter); }

/* Maat kwam uit haar renders: 41px op een doek van 1410 = 2.9%. Nu een slag
   groter en met een dikkere streek, want te veel mensen zagen niet dat het
   een knop was. Het woord eronder doet daarvoor het meeste werk. */
.plus__icon {
  position: relative;
  width: clamp(34px, 3.3vw, 50px); height: clamp(34px, 3.3vw, 50px);
  transition: transform .7s var(--ease-io);
}
.plus__icon i { position: absolute; left: 50%; top: 50%; background: currentColor; }
.plus__icon i:nth-child(1) { width: 100%; height: 2.6px; transform: translate(-50%, -50%); }
.plus__icon i:nth-child(2) { width: 2.6px; height: 100%; transform: translate(-50%, -50%); }

/* Het woord onder de +. Dít is de eigenlijke oplossing: een + alleen leest als
   versiering, met een woord eronder als knop. Staat gecentreerd, zodat de +
   op de scheidingslijn blijft liggen. */
.plus__label {
  font-size: clamp(.66rem, .78vw, .8rem);
  font-weight: 400;
  letter-spacing: .13em;
  text-transform: uppercase;
  opacity: .75;
  transition: opacity .35s linear;
}
.plus:hover .plus__label,
.plus:focus-visible .plus__label { opacity: 1; }

.plus:hover .plus__icon           { transform: rotate(90deg); }
.plus.is-open .plus__icon         { transform: rotate(135deg); }
.plus.is-open:hover .plus__icon   { transform: rotate(225deg); }

@keyframes fade-in { to { opacity: 1; } }
@keyframes rise-in { to { transform: translateY(0); } }

/* — het paneel ————————————————————————————————————————————————————— */
.menu {
  position: fixed; inset: 0;
  z-index: 800;
  background: var(--menu-bg, #EDC8C3);
  color: var(--menu-fg, #282828);
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(5rem, 12vh, 8rem) var(--gut) clamp(3rem, 7vh, 4.5rem);
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path .95s var(--ease-io), visibility 0s linear .95s,
              background-color 1.2s linear, color 1.2s linear;
}
.menu.is-open {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path .95s var(--ease-io), visibility 0s linear 0s;
}

/* De vier vlakken liggen op elkaar; welk vlak een pagina toont staat in de
   HTML (data-menu-vlak op <body>) en verandert niet meer zolang het menu open
   is. Posities komen uit haar mockups: percentages van het paneel, dus ze
   kloppen op elke schermmaat. */
.menu__vlakken { position: absolute; inset: 0; }

.menu__vlak {
  position: absolute; margin: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity .9s linear;
}

/* Het beeld komt op zodra het menu opengaat, net achter de veeg aan en in
   hetzelfde ritme als de menu-items. Het hangt aan .is-open en niet alleen
   aan .is-actief: het vlak staat nu al goed vóór je opent, dus zonder deze
   koppeling zou de overvloeier bij het laden al voorbij zijn en sprong het
   beeld er ineens in. */
.menu__vlak.is-actief { transition-delay: 0s; }
.menu.is-open .menu__vlak.is-actief { opacity: 1; transition-delay: .3s; }

.menu__vlak img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.05);
  transition: transform 1.9s var(--ease);
}
.menu.is-open .menu__vlak.is-actief img { transform: none; transition-delay: .3s; }

.menu__vlak--1 { left: 53%; right: 8%; top: 0;   height: 52%; }
.menu__vlak--2 { left: 79%; right: 0;  top: 37%; bottom: 0; }
.menu__vlak--3 { left: 60%; right: 0;  top: 0;   height: 54%; }
.menu__vlak--4 { left: 72%; right: 0;  top: 15%; bottom: 0; }

.menu__list {
  position: relative; z-index: 1;
  font-size: clamp(2.1rem, 6.4vw, 4.6rem);
  line-height: 1.1;
  letter-spacing: -.02em;
}

.menu__item a { display: inline-block; transition: opacity .45s linear, transform .55s var(--ease); }

.menu__mask { display: block; overflow: hidden; padding-bottom: .1em; }
.menu__mask > span {
  display: inline-block; position: relative;
  transform: translateY(118%);
  transition: transform .55s var(--ease);
}
.menu.is-open .menu__mask > span { transform: translateY(0); }
.menu.is-open .menu__item:nth-child(1) .menu__mask > span { transition-delay: .30s; }
.menu.is-open .menu__item:nth-child(2) .menu__mask > span { transition-delay: .38s; }
.menu.is-open .menu__item:nth-child(3) .menu__mask > span { transition-delay: .46s; }
.menu.is-open .menu__item:nth-child(4) .menu__mask > span { transition-delay: .54s; }
.menu.is-open .menu__item:nth-child(5) .menu__mask > span { transition-delay: .62s; }

.menu__mask > span::after {
  content: "";
  position: absolute; left: 0; bottom: .1em;
  width: 100%; height: 1.5px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform .55s var(--ease);
}

.menu__list:hover .menu__item a { opacity: .35; }
.menu__list .menu__item a:hover,
.menu__list .menu__item a:focus-visible,
.menu__item a[aria-current="page"] { opacity: 1; }
.menu__item a:hover { transform: translateX(.06em); }
.menu__item a:hover .menu__mask > span::after,
.menu__item a:focus-visible .menu__mask > span::after,
.menu__item a[aria-current="page"] .menu__mask > span::after { transform: scaleX(1); }

.menu__foot {
  position: absolute;
  left: var(--gut); right: var(--gut); bottom: clamp(1.5rem, 4vh, 2.75rem);
  z-index: 1;
  display: flex; flex-wrap: wrap; gap: .5rem clamp(1.25rem, 3vw, 2.5rem);
  font-size: clamp(.82rem, 1vw, .95rem);
  letter-spacing: .015em;
  opacity: 0; transform: translateY(1rem);
  transition: opacity .7s linear .55s, transform .7s var(--ease) .55s;
}
.menu.is-open .menu__foot { opacity: .72; transform: translateY(0); }
.menu__foot a { border-bottom: 1px solid currentColor; opacity: .75; }
.menu__foot a:hover { opacity: 1; }


/* ═══ 4. FOOTER ═════════════════════════════════════════════════════════ */

/* De footer is de afsluiter van de pagina en mag niet luid zijn. De maten
   hieronder komen uit haar mockup: baseline rond 23px, contactregel rond 15px,
   logo rond 120px breed. Hij doet niet mee aan de kleurovergang — elke pagina
   zet zijn eigen kleur via de inline --footer-bg. */
/* De footer kiest zijn eigen achtergrond per pagina via --footer-bg. De
   tekstkleur volgt: standaard inkt, maar op een donkere achtergrond zet de
   pagina --footer-fg op botergeel. */
.footer {
  position: relative;
  background: var(--footer-bg, var(--c-sky));
  color: var(--footer-fg, var(--c-ink));
  padding: clamp(1.75rem, 4vh, 2.75rem) var(--gut) clamp(1.25rem, 3vh, 2rem);
}

.footer__inner { max-width: 1360px; margin-inline: auto; }

.footer__nav {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .3em;
  margin-bottom: clamp(1.5rem, 4vh, 2.75rem);
  font-size: clamp(.82rem, 1.05vw, .95rem);
  letter-spacing: .015em;
}
.footer__nav a { opacity: .7; transition: opacity .3s linear; }
.footer__nav a:hover,
.footer__nav a:focus-visible { opacity: 1; }

.footer__onder {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: end;
  gap: clamp(1.25rem, 3vh, 2rem) clamp(2rem, 6vw, 5rem);
}

.footer__logo { width: clamp(90px, 8.3vw, 130px); color: inherit; }

.footer__rechts {
  display: flex; flex-direction: column; align-items: flex-end;
  gap: clamp(.5rem, 1.4vh, .9rem);
  text-align: right;
}

.footer__tagline {
  /* haar bruin, behalve als de footer zelf al bruin is */
  color: var(--footer-accent, var(--c-brown));
  font-size: clamp(1.05rem, 1.6vw, 1.5rem);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -.005em;
}

.footer__contact {
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: .4rem clamp(1rem, 2.4vw, 2.25rem);
  font-size: clamp(.78rem, 1.02vw, .92rem);
  letter-spacing: .01em;
  opacity: .8;
}
.footer__contact address { font-style: normal; }
.footer__contact a { position: relative; }
.footer__contact a::after {
  content: ""; position: absolute; left: 0; bottom: -.15em;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform .5s var(--ease);
}
.footer__contact a:hover::after { transform: scaleX(1); }


/* ═══ 5. AANLANDPAGINA ══════════════════════════════════════════════════ */

/* — intro curtain ————————————————————————————————————————————————— */
.intro {
  position: fixed; inset: 0;
  z-index: 900;
  display: grid; place-items: center;
  background: var(--c-ink); color: var(--c-butter);
  animation: curtain-up 1.15s var(--ease-io) var(--t-curtain) forwards;
}
@keyframes curtain-up { to { transform: translateY(-101%); visibility: hidden; } }

/* De vier woorden staan los over het vlak verspreid, zoals in haar schets:
   "licht" linksboven, "ruimte" rechts eronder, dan een grote sprong naar
   "&" en "geluk" in het midden onderaan. De verhouding tussen de drie
   verticale gaten is 1 : 2 : 1 — precies zoals zij ze tekende. De hele groep
   staat wel iets hoger dan op haar schets, anders raakt "geluk" op een laag
   venster de onderrand. */
.intro__lines {
  position: relative;
  width: min(1180px, 84vw);

  /* svh en niet vh. Op een telefoon rekent vh met de hoogte zónder adresbalk,
     terwijl die balk er bij het laden juist wél staat — op een iPhone scheelt
     dat zo'n 180 px, en dan valt "geluk" op 86% buiten beeld. svh rekent met
     de kleinste hoogte, dus met de balk erbij. De regel met vh blijft staan
     voor browsers die svh nog niet kennen. */
  height: 100vh;
  height: 100svh;

  /* De 13svh houdt de regelhoogte kleiner dan het kleinste verticale gat
     (16,6%), zodat "licht" en "ruimte" ook op een laag venster niet tegen
     elkaar lopen. Zonder die grens groeit de letter met de breedte mee
     terwijl de gaten met de hoogte meegaan. */
  font-size: clamp(2.4rem, min(13vw, 13vh), 7rem);
  font-size: clamp(2.4rem, min(13vw, 13svh), 7rem);
  font-weight: 200; line-height: .96; letter-spacing: -.02em;
}
/* De regel hangt met haar midden op de opgegeven hoogte. De .1em corrigeert
   voor de padding onderaan, die er alleen is om staarten (de g van geluk)
   niet te laten afsnijden door de overflow. */
.intro__line {
  position: absolute; left: 0; right: 0;
  transform: translateY(calc(-50% + .1em));
  display: block; overflow: hidden; padding-bottom: .2em;
}
/* text-align erft door naar de <i>, die het woord bij het openen omhoog schuift */
.intro__line                { top: 18%;   }                    /* licht  */
.intro__line--i1 { top: 34.6%; text-align: right;  }           /* ruimte */
.intro__line--i2 { top: 69.4%; text-align: center; }           /* &      */
.intro__line--i3 { top: 86%;   text-align: center; }           /* geluk  */
.intro__line i {
  display: block; font-style: normal;
  transform: translateY(110%);
  animation: rise-in 1s var(--ease) forwards;
}
.intro__line:nth-child(1) i { animation-delay: .20s; }
.intro__line:nth-child(2) i { animation-delay: .34s; }
.intro__line:nth-child(3) i { animation-delay: .48s; }
.intro__line:nth-child(4) i { animation-delay: .62s; }

/* — hero ——————————————————————————————————————————————————————————— */
/* Even hoog als het beeld zelf. Stond op 175vh: dan bleef de gepinde hero nog
   75vh hangen voor de volgende sectie eroverheen kwam, en dat voelde als
   wachten. Nu scrolt hij meteen door. */
.hero { position: relative; height: 100vh; }

.hero__pin {
  position: sticky; top: 0;
  z-index: 20;
  height: 100vh;
  overflow: hidden;
  display: grid; place-items: center;
  padding: 0 var(--gut);
  color: var(--c-butter);
}

.hero__photo {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%;
}

/* het woordmerk zelf staat precies in het midden van het scherm; de baseline
   hangt eronder zonder die centrering te verstoren */
.hero__lockup {
  position: relative; z-index: 1;
}

/* De 90vh begrenst het merk ook op de hoogte. Zonder dat wordt het op een
   breed maar laag venster zo hoog dat de knop over de scroll-hint valt; het
   merk is namelijk 1,9 keer zo breed als hoog. Op een gewoon scherm bindt
   deze grens niet. */
.wordmark { width: min(clamp(15rem, 48vw, 48rem), 90vh); }
.wordmark img {
  width: 100%; height: auto;
  /* haalt de dunne letters los van de lichte plekken in de foto zonder dat je
     er een schaduw in herkent */
  filter: drop-shadow(0 0 18px rgba(40, 40, 40, .32));
  clip-path: inset(0 100% 0 0);
  animation: wipe-in 1.5s var(--ease) var(--t-hero) forwards;
}

.hero__tagline, .hero__hint { text-shadow: 0 0 14px rgba(40, 40, 40, .4); }
@keyframes wipe-in { to { clip-path: inset(var(--knip-t, 0%) 0 var(--knip-b, 0%) 0); } }

/* Baseline en knop staan in de stroom onder het woordmerk, zodat de hele
   groep in het midden van het scherm komt. Hingen ze eronder buiten de stroom
   — zoals eerst, toen alleen het woordmerk gecentreerd moest staan — dan telt
   hun hoogte niet mee en zakt de knop tot tegen de scroll-hint. */
.hero__onder {
  margin-top: clamp(1rem, 3.5vh, 2.5rem);
  text-align: center;
}

.hero__tagline {
  overflow: hidden;
  padding-bottom: .18em;
  font-size: clamp(1rem, 1.9vw, 1.75rem);
  letter-spacing: .01em;
}

.hero__cta {
  margin-top: clamp(1.25rem, 3.5vh, 2.25rem);
  opacity: 0;
  animation: fade-in 1s var(--ease) calc(var(--t-hero) + .95s) forwards;
}
.hero__tagline i {
  display: block; font-style: normal;
  transform: translateY(115%);
  animation: rise-in 1s var(--ease) calc(var(--t-hero) + .5s) forwards;
}

.hero__hint {
  position: absolute; z-index: 1;
  left: 0; right: 0;
  /* De pin is 100vh hoog, maar op een telefoon staat de adresbalk daar bij het
     laden overheen — op een iPhone zo'n 180 px. Onderaan die pin valt dus
     buiten beeld. Het verschil tussen vh en svh ís precies die balk, dus
     hiermee schuift de hint er net boven. Op een scherm zonder balk is dat
     verschil nul en blijft de gewone marge staan. */
  bottom: max(clamp(1.5rem, 4vh, 2.75rem), calc(100vh - 100svh + 1rem));
  text-align: center;
  overflow: hidden; padding-bottom: .3em;
  font-size: .76rem; letter-spacing: .16em; text-transform: uppercase;
  opacity: .75;
}
.hero__hint i {
  display: block; font-style: normal;
  transform: translateY(120%);
  animation: rise-in .9s var(--ease) calc(var(--t-hero) + .8s) forwards;
}

/* — statement ——————————————————————————————————————————————————————— */
.statement { position: relative; height: 210vh; }

.statement__pin {
  position: sticky; top: 0;
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 var(--gut);
}

.statement__eyebrow {
  width: min(1040px, 82vw);
  margin: 0 auto clamp(1.75rem, 4vh, 3rem);
}

.statement__text {
  max-width: min(1040px, 82vw);
  margin-inline: auto;
  font-size: clamp(1.3rem, 3.05vw, 2.6rem);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -.005em;
}
.statement__text .word { display: inline-block; opacity: .3; white-space: pre; }

/* De uitnodiging komt pas als de tekst uitgelezen is; het scrollscript stuurt
   de opacity, zie [data-na-de-woorden] in main.js. */
.statement__cta {
  /* width, niet max-width: in een flexkolom laten auto-marges het blok anders
     krimpen tot de inhoud, en dan lijnt de knop niet uit met de tekst */
  width: min(1040px, 82vw);
  margin: clamp(1.75rem, 4.5vh, 3rem) auto 0;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(.75rem, 2vw, 1.5rem);
  opacity: 0;
  will-change: opacity, transform;
}
.statement__cta-aanloop {
  font-size: clamp(.95rem, 1.5vw, 1.2rem);
  opacity: .75;
}

/* de knop keert de twee kleuren van de sectie om bij hover */
.knop {
  display: inline-block;
  padding: .72em 1.5em;
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: clamp(.9rem, 1.25vw, 1.05rem);
  letter-spacing: .01em;
  transition: background-color .45s var(--ease), color .45s var(--ease);
}
.knop:hover,
.knop:focus-visible { background: var(--fg); color: var(--bg); }

/* Op de hero ligt de knop op een foto. Alleen een lijn valt daar te weinig
   op, dus staat hij gevuld botergeel; bij hover keert hij om naar inkt. */
.knop--licht {
  background: var(--c-butter); color: var(--c-ink);
  border-color: var(--c-butter);
  filter: drop-shadow(0 2px 16px rgba(40, 40, 40, .35));
}
.knop--licht:hover,
.knop--licht:focus-visible {
  background: var(--c-ink); color: var(--c-butter);
  border-color: var(--c-ink);
}

/* — partners ———————————————————————————————————————————————————— */
.partners { padding: clamp(5rem, 13vh, 9rem) var(--gut) clamp(5rem, 14vh, 10rem); }

.partners__inner { max-width: 1360px; margin-inline: auto; }

.partners__title {
  font-size: clamp(1.6rem, 3.1vw, 2.8rem);
  font-weight: 300;
  letter-spacing: -.015em;
  /* Krap onder de kop: de tussenruimte hoort nu onder de inleidende zin, niet
     tussen kop en zin. */
  margin-bottom: clamp(.75rem, 2vh, 1.25rem);
}
.partners__lead {
  max-width: 62ch;
  font-size: clamp(.95rem, 1.35vw, 1.15rem);
  line-height: 1.5;
  opacity: .75;
  margin-bottom: clamp(3rem, 9vh, 6rem);
}

/* Drie kolommen, één per partner. Stond op vijf toen er nog tien plaatshouders
   waren. */
.partners__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(2.5rem, 6vh, 5rem) clamp(1.5rem, 4vw, 4rem);
  align-items: center;
}
.partners__cell {
  display: grid; place-items: center;
  opacity: 0; transform: translateY(1.6rem);
  transition: opacity .8s linear var(--d, 0s), transform .95s var(--ease) var(--d, 0s);
}
.partners__cell.is-in { opacity: 1; transform: none; }
/* Volle breedte, niet krimpend om het beeld heen. Anders hangt de breedte van
   het anker af van het beeld en die van het beeld van het anker — dat rekent
   de browser uit op nul, en dan verdwijnt het logo. */
.partners__cell a { display: grid; place-items: center; width: 100%; }

/* De drie logo's hebben heel verschillende verhoudingen: die van Hasa is ruim
   acht keer zo breed als hoog, de andere twee ongeveer twee. Op breedte
   schalen zou Hasa een dun streepje maken naast twee blokken. Vandaar een
   begrenzing op de hoogte, zodat ze optisch even zwaar wegen. */
.partners__cell img {
  display: block;
  width: auto; max-width: 100%;
  max-height: 96px; height: auto;
  /* Altijd op volle kleur. Ze stonden op .72 en lichtten pas bij hover op,
     maar dat maakt haar partners grauw — en nergens op deze site staat iets
     in grijstinten. */
  transition: transform .6s var(--ease);
}
/* met .partners__cell ervoor, anders wint de regel hierboven op specificiteit */
.partners__cell .partners__breed { max-height: 34px; }

.partners__cell:hover img { transform: scale(1.06); }


/* ═══ 6. ABOUT ══════════════════════════════════════════════════════════ */

.split { display: grid; grid-template-columns: var(--split) 1fr; }

/* Foto en uitsnede moeten pixel-op-pixel samenvallen, anders zie je een rand
   om haar heen. Ze delen daarom dezelfde --foto-pos en dezelfde animatie. */
.split__media {
  --foto-pos: 30% 50%;
  position: sticky; top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--c-paper);
}

.split__scene { position: absolute; inset: 0; }

.split__photo,
.split__uitsnede {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: var(--foto-pos);
  transform: scale(1.06);
  animation: settle 1.8s var(--ease) .1s forwards;
}
.split__photo    { z-index: 0; }
.split__uitsnede { z-index: 2; }
@keyframes settle { to { transform: scale(1); } }

/* Breedte en linkermarge overgenomen uit haar render, zodat de "bar"-regel
   altijd op dezelfde plek eindigt, ongeacht de schermverhouding.

   Het logo ligt er twee keer overheen: de bovenste regel achter haar, de
   onderste ervoor. --knip-t en --knip-b zeggen welk deel elke laag toont; ze
   zitten ook in de wipe-in animatie, zodat die snede blijft staan terwijl het
   logo van links naar rechts openveegt. */
.split__logo {
  position: absolute;
  left: 3.1%; width: 78%;
  top: 50%; transform: translateY(-50%);
  color: #fff;
  clip-path: inset(var(--knip-t, 0%) 100% var(--knip-b, 0%) 0);
  animation: wipe-in 1.6s var(--ease) .35s forwards;
}
/* de twee regels raken elkaar op 59% van de merkhoogte */
.split__logo--achter { z-index: 1; --knip-b: 41%; }
.split__logo--voor   { z-index: 3; --knip-t: 59%; }

.split__panel { background: var(--bg); color: var(--fg); }

/* Elke paragraaf is een gepind blok: het blok geeft de scrollruimte, de
   .split__pin erin blijft staan terwijl je scrolt. Die scrollvoortgang stuurt
   het oplichten van de woorden — hetzelfde principe als "Wat ik doe" op de
   aanlandpagina. */
.split__block { min-height: var(--blok-h, 165vh); }

.split__pin {
  position: sticky; top: 0;
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2.5rem, 7vh, 5rem) clamp(1.6rem, 4.6vw, 5rem);
}
.split__pin .eyebrow { margin-bottom: clamp(.9rem, 2.2vh, 1.5rem); }

/* Kleiner dan een statement: dit is lopende tekst van meer dan honderd
   woorden, die moet op één scherm passen én leesbaar blijven. */
.split__text {
  max-width: 34em;
  /* ook aan de schermhoogte gekoppeld: een blok van ruim honderd woorden moet
     binnen de gepinde 100vh blijven, anders valt de onderkant weg */
  font-size: clamp(.95rem, min(1.55vw, 2.25vh), 1.35rem);
  font-weight: 300;
  line-height: 1.38;
}
.split__text p + p { margin-top: .95em; }
.split__text strong { font-weight: 500; }
.split__text .word { display: inline-block; opacity: .3; white-space: pre; }


/* — de uitnodiging ——————————————————————————————————————————————
   Foto links, kleurvlak rechts, elk de helft: de middellijn van het scherm
   loopt hier door. Titel en knop staan gecentreerd in het vlak. Anders dan de
   vlakken hierboven pint hier niets: het paneel krijgt een vol scherm en de
   footer komt daar los onder. */
/* De sectie is hoger dan het scherm; die overmaat is de haak. De wikkel
   blijft staan tot ze op is, daarna schuift de footer eronder omhoog. */
.uitro { min-height: 158vh; background: var(--bg); color: var(--fg); }

.uitro__pin {
  position: sticky; top: 0;
  height: 100vh;
  /* Vijftig-vijftig: de middellijn van het scherm loopt hier door, net als op
     de andere gesplitste pagina's. Haar render had de foto smaller, maar zij
     wil de doorlopende lijn. */
  display: grid; grid-template-columns: var(--split) 1fr;
}

/* De foto vult de hele linkerhelft, en snijdt daarvoor alleen bij wat de kolom
   vraagt — 17 tot 29% van de hoogte, afhankelijk van het scherm. Het bestand
   zelf is onbijgesneden (staand, 2:3), dus elk formaat neemt precies genoeg.

   35% legt de snede aan de juiste kant: de muur boven haar hoofd blijft, de
   sjaal onderaan wijkt. Het kaartje zit op 28 tot 64% van de hoogte en valt
   dus op elk schermformaat volledig binnen beeld. */
.uitro__foto { overflow: hidden; background: var(--c-paper); }
.uitro__foto img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 35%; }

.uitro__paneel {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: clamp(1.75rem, 6.5vh, 3.5rem);
  padding: clamp(2rem, 6vh, 4rem) clamp(1.25rem, 3.2vw, 3.5rem);
  text-align: center;
  /* Wit, zodat ook de knop eronder wit erft. De titel rekent in em van deze
     maat, gekoppeld aan zowel breedte als hoogte zodat hij op een laag venster
     niet tegen de knop loopt. */
  color: #fff;
  font-size: clamp(1.9rem, min(4.5vw, 8vh), 4.75rem);
}

.uitro__titel {
  font-size: 1em;
  font-weight: 300; line-height: 1.08; letter-spacing: -.02em;
  max-width: 14em;
}

/* De knop is dezelfde als elders op de site. Hij erft de witte tekstkleur van
   het paneel, dus de rand is wit; bij hover keert hij om. Hier stond eerst een
   kruisje met een grote regel erboven — die regel zei precies wat de knop zegt,
   dus dat was twee keer hetzelfde. */
.uitro__knop { margin-top: clamp(.5rem, 2vh, 1.25rem); }


/* — wat ik doe ————————————————————————————————————————————————————
   Zelfde mechanisme als de aboutpagina: elk deel is een eigen scherm dat
   blijft staan terwijl je scrolt, en die scrollvoortgang laat de tekst woord
   voor woord oplichten. Het verschil met about is dat de foto hier per deel
   van kant wisselt — zigzag, zoals in haar mockup. */
.wid__deel { min-height: var(--blok-h, 200vh); }

.wid__pin {
  position: sticky; top: 0;
  height: 100vh;
  display: grid; grid-template-columns: var(--split) 1fr;
}
.wid__paneel, .wid__foto { grid-row: 1; }
.wid__paneel { grid-column: 1; }
.wid__foto   { grid-column: 2; }
/* de zigzag: bij de omgekeerde delen staat de foto links */
.wid__deel--omgekeerd .wid__paneel { grid-column: 2; }
.wid__deel--omgekeerd .wid__foto   { grid-column: 1; }

/* het kleurvlak morpht mee met het scrollscript, net als op about */
.wid__paneel {
  background: var(--bg); color: var(--fg);
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2.5rem, 7vh, 5rem) clamp(1.6rem, 4.6vw, 5rem);
}

.wid__titel {
  font-size: clamp(1.4rem, 2.6vw, 2.3rem);
  font-weight: 300; line-height: 1.05; letter-spacing: -.02em;
  margin-bottom: clamp(.8rem, 2vh, 1.4rem);
}

/* Kleiner dan een statement: dit is lopende tekst die binnen één gepind
   scherm moet passen. Ook aan de schermhoogte gekoppeld, anders valt de
   onderkant weg op een laag venster. */
.wid__woorden {
  max-width: 34em;
  font-size: clamp(.88rem, min(1.45vw, 2.05vh), 1.25rem);
  font-weight: 300;
  line-height: 1.4;
}
.wid__woorden p + p,
.wid__woorden li + li { margin-top: .9em; }
.wid__woorden .word { display: inline-block; opacity: .3; white-space: pre; }

/* de vijf stappen lopen door over twee delen, vandaar een eigen nummer */
.wid__stappen { list-style: none; }
.wid__stap {
  font-size: 1.15em;
  font-weight: 400; line-height: 1.2; letter-spacing: -.01em;
  margin-bottom: .3em;
}
.wid__nr { margin-right: .4em; }

.wid__foto { position: relative; margin: 0; overflow: hidden; }
.wid__foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* zij spiegelt dit beeld in haar mockup, zodat de donkere laptop onder het
   witte woord komt te liggen; ongespiegeld valt "hoe?" op wit papier weg */
.wid__foto--gespiegeld img { transform: scaleX(-1); }

/* Zij wil dat deze woorden opvallen. Ze stonden op 4,2vw en gewicht 200 — het
   lichtste dat er is — en verdwenen daardoor in de foto. Nu ruim anderhalf keer
   zo groot en op 400.

   Zwaarder dan 500 heeft geen zin: de site laadt Poppins in 200, 300, 400 en
   500, en daarboven gaat de browser zelf verdikken. Dat oogt rommelig.

   De schaduw is meegegroeid, anders valt een grotere letter juist wég op een
   lichte foto. */
.wid__woord {
  position: absolute; left: clamp(1rem, 2.5vw, 2.5rem); bottom: clamp(1rem, 3vh, 2.5rem);
  /* Groter én dunner, niet vet. De maat komt uit het beeld dat zij doorstuurde:
     daar is "wat?" 361 van de 1411 px breed, dus 25,6% van de vensterbreedte.
     Bij gewicht 200 levert 11,5vw precies dat op — nagemeten 346 px bij 11vw en
     377 px bij 12vw op een venster van 1411.

     De bovengrens houdt het op een heel breed scherm binnen de perken; de
     ondergrens geeft het op een telefoon genoeg gewicht, want daar vult de foto
     de volle breedte in plaats van de helft. */
  font-size: clamp(3.2rem, 11.5vw, 14rem);
  font-weight: 200; letter-spacing: -.02em; line-height: 1;
  color: #fff;
  text-shadow: 0 2px 28px rgba(40, 40, 40, .45);
}


/* — contact ——————————————————————————————————————————————————————
   Uit haar mockup in "Website - contactv3" (doek 1410 x 1049):
   de foto loopt van de middenlijn (51%) tot 6% voor de rechterrand, en is
   18% tot 81% hoog. Verhouding van het beeld 0,92. De tekst staat links. */
.contact {
  min-height: 100vh;
  display: grid; grid-template-columns: var(--split) 1fr;
  align-items: center;
  /* Geen horizontale padding op het raster zelf en geen gap: alleen zo valt
     de kolomgrens samen met de middenlijn van het scherm, en begint de foto
     daar precies zoals bij haar. De marges zitten in de kolommen. */
  padding-block: clamp(6rem, 15vh, 10rem) clamp(4rem, 10vh, 7rem);
  background: var(--bg); color: var(--fg);
}

.contact__tekst {
  max-width: 34em;
  padding-left: var(--gut);
  padding-right: clamp(2rem, 5vw, 5rem);
}
.contact__foto { padding-right: clamp(1.5rem, 6vw, 6rem); }

.contact__titel {
  font-size: clamp(1.7rem, 3.4vw, 3rem);
  font-weight: 300; line-height: 1.05; letter-spacing: -.02em;
  margin-bottom: clamp(1rem, 2.5vh, 1.75rem);
}
.contact__lead {
  max-width: 42ch;
  font-size: clamp(.95rem, 1.35vw, 1.15rem); line-height: 1.5; opacity: .8;
}
.contact__knop { margin-top: clamp(1.75rem, 4.5vh, 2.75rem); }

/* het tweede spoor: wie liever mailt of belt dan meteen een uur vastlegt */
.contact__direct { margin-top: clamp(2.5rem, 7vh, 4.5rem); }
.contact__vraag {
  font-size: clamp(.95rem, 1.35vw, 1.15rem);
  margin-bottom: clamp(.6rem, 1.5vh, 1rem);
}
.contact__regel {
  display: flex; align-items: baseline; gap: .5em;
  font-size: clamp(.95rem, 1.35vw, 1.15rem); line-height: 1.7;
}
.contact__streep { opacity: .45; }
.contact__regel a {
  position: relative;
  transition: opacity .3s linear;
}
/* zelfde onderstreping als in de footer: groeit aan bij hoveren */
.contact__regel a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -.12em;
  border-bottom: 1px solid currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
.contact__regel a:hover::after,
.contact__regel a:focus-visible::after { transform: scaleX(1); }

/* De foto vult de rechterkolom in de breedte, zoals bij haar. Op een breed
   maar laag venster zou hij daardoor hoger worden dan het scherm; de
   bovengrens snijdt hem dan symmetrisch bij in plaats van hem te verkleinen,
   zodat de kolom gevuld blijft. */
/* een <figure> heeft in de browser standaard 40px zijmarge — hier niet */
.contact__foto { margin: 0; }
.contact__foto img {
  display: block;
  width: 100%; height: auto;
  max-height: 72vh;
  /* iets boven het midden: bij bijsnijden verdwijnt liever wat tafel dan de
     kast met de turkooizen deuren — dat is haar eigen werk */
  object-fit: cover; object-position: 50% 40%;
}


/* ═══ 7. PROJECTEN ══════════════════════════════════════════════════════ */

/* De twee hulplijnen uit haar tekening staan hier één keer. Beide helften
   rekenen eruit, zodat ze bij elk schermformaat op dezelfde hoogte eindigen:
   rechts is --lijn-onder de onderkant van de foto (niet van het tekstje),
   links is het de onderkant van het tweede vierkant. */
.projects {
  display: grid; grid-template-columns: var(--split) 1fr; align-items: start;

  --lijn-boven: 10vh;
  --lijn-onder: 74vh;

  /* wit tussen twee vierkanten; hier hangt ook de titel in */
  --vak-gat: clamp(4.25rem, 9vh, 6.5rem);

  /* Twee vierkanten plus één tussenruimte vullen precies de band tussen de
     hulplijnen: --lijn-boven + 2 x --vak + --vak-gat = --lijn-onder.
     De 60% is een noodrem voor vensters die veel hoger dan breed zijn — daar
     zou het vierkant niet meer in de kolom passen. Op alles van 4:3 tot
     21:9 komt hij niet in de buurt en klopt de lijn tot op de pixel. */
  --vak: min(calc((var(--lijn-onder) - var(--lijn-boven) - var(--vak-gat)) / 2), 60%);
}

/* — links: alles onder elkaar, vierkant, met veel lucht ————————————— */
.projects__list {
  background: var(--c-paper);
  /* het eerste vierkant begint op de bovenste hulplijn */
  padding-top: var(--lijn-boven);
  padding-inline: var(--gut);
  /* Voet onderaan: zonder deze ruimte is de kolom te kort om het plakkende
     rechterpaneel vast te houden tot het laatste project, en zakt de foto weg
     onder de onderste hulplijn. Dit is precies genoeg — geen pixel meer. */
  padding-bottom: max(clamp(5rem, 12vh, 9rem),
                      calc(100vh - var(--lijn-boven) - var(--vak)));
}

.projects__grid {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--vak-gat);
}

/* Elk project klikt bij het scrollen vast op dezelfde hoogte, zodat de
   verhouding uit haar tekening blijft kloppen hoe ver je ook gescrold bent.
   "proximity" en niet "mandatory": het snapt als je in de buurt komt, maar
   houdt je nergens gevangen. */
html:has(.page-projecten) { scroll-snap-type: y proximity; }

.project {
  width: var(--vak);
  scroll-snap-align: start;
  scroll-margin-top: var(--lijn-boven);
}

.project__btn { display: block; position: relative; width: 100%; text-align: left; color: inherit; }

.project__thumb {
  display: block; overflow: hidden;
  aspect-ratio: 1 / 1;
  background: rgba(40, 40, 40, .06);
}
.project__thumb img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.1s var(--ease);
}
.project__btn:hover .project__thumb img,
.project__btn:focus-visible .project__thumb img { transform: scale(1.05); }

/* De titel staat buiten de stroom, in de tussenruimte onder het vierkant.
   Zo is de hoogte van een project precies het vierkant en blijft de onderste
   hulplijn kloppen. Klikken op de titel werkt gewoon: hij hoort bij de knop. */
/* right: auto en niet 0. Aan de breedte van het vierkant vastgeklonken brak
   "Vanseveren meets Perriand" over twee regels, en dan klopt de uitlijning van
   de kolom niet meer. Nu loopt de titel gewoon door naar rechts, de lege ruimte
   in: daar is 465 px en de langste titel heeft er 242 nodig. */
.project__meta {
  display: block;
  position: absolute; top: 100%; left: 0; right: auto;
  padding-top: .7rem;
}
.project__title {
  display: block;
  white-space: nowrap;
  font-size: clamp(.95rem, 1.25vw, 1.15rem);
  font-weight: 400; letter-spacing: -.01em;
  transition: color .4s linear;
}

/* Haar werk staat altijd in kleur. Hier dimden de andere projecten eerst weg
   naar grijstinten zodra je er één aanwees; dat mag niet — nergens grijs.
   Het aanwijzen is al te zien aan het beeld dat licht opschaalt. */
.has-active .project.is-active .project__title { color: var(--c-brown); }

.project__data, .project__text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* — rechts: kleurvlak per project ————————————————————————————————
   Verhoudingen uit haar mockup: bovenaan lucht met de teller, dan het beeld
   over de volle breedte, daaronder titel en beschrijving. */
.projects__view {
  position: sticky; top: 0;
  height: 100vh;
  background: var(--project-bg, var(--c-sky));
  color: var(--project-fg, var(--c-ink));
  display: grid;
  grid-template-rows: var(--lijn-boven) calc(var(--lijn-onder) - var(--lijn-boven)) 1fr;
  /* rij 1 blijft leeg op de teller na; expliciet plaatsen, want de
     sluitknop is hier display:none en telt niet mee als rij */
  transition: background-color .7s linear, color .7s linear;
}

.viewer__stage {
  grid-row: 2;
  position: relative;
  overflow: hidden;
  background: inherit;
}
.viewer__stage img {
  /* Het beeld wordt nooit afgesneden: het groeit tot het één van de twee
     randen van de band raakt — de volle breedte van het paneel of de hoogte
     tussen de twee hulplijnen — en wat overblijft is de projectkleur. Dat is
     haar aantekening "als de foto hier niet past opvullen met
     achtergrondkleur", nu ook voor vierkante en staande beelden.

     De onderkant blijft op de onderste hulplijn liggen, want dat is de lijn
     waar de linkerkolom op uitlijnt. */
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
  opacity: 0; transform: scale(1.03);
  transition: opacity .7s linear, transform 1.4s var(--ease);
}
.viewer__stage img.is-active { opacity: 1; transform: scale(1); }

/* Witte pijlen zonder vlak eronder, in de onderhoeken van het beeldvlak. Ze
   blijven op hun plek staan, ook als de foto smaller is dan het paneel: dan
   staan ze naast het beeld op de projectkleur in plaats van erop. Dat is een
   bewuste keuze — een balk die per beeld van breedte verspringt leest onrustig. */
.viewer__nav {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-between;
  padding: clamp(.5rem, 1.5vw, 1.25rem);
  pointer-events: none;
}
.viewer__arrow {
  pointer-events: auto;
  width: clamp(30px, 3vw, 44px); height: clamp(30px, 3vw, 44px);
  display: grid; place-items: center;
  color: #fff;
  filter: drop-shadow(0 1px 6px rgba(40, 40, 40, .55));
  transition: transform .4s var(--ease), opacity .3s linear;
  opacity: .7;
}
.viewer__arrow:hover { transform: scale(1.15); opacity: 1; }
.viewer__arrow svg { width: 100%; height: 100%; }

.viewer__count {
  position: absolute; z-index: 1;
  top: clamp(.75rem, 2vh, 1.5rem); right: clamp(1rem, 2.5vw, 2.5rem);
  font-size: clamp(1.1rem, 1.9vw, 1.7rem);
  font-weight: 300; letter-spacing: .01em;
  opacity: .5;
}

.viewer__info {
  grid-row: 3;
  align-self: start;
  /* Gebruikt de volle breedte van het paneel. Stond eerst op 46ch — de
     klassieke leesbreedte — maar dat liet de rechterhelft leeg terwijl er
     onder de foto juist weinig hoogte is. Haar teksten van rond de zestig
     woorden passen alleen zo. */
  max-width: 100%;
  padding: clamp(.9rem, 2.4vh, 1.6rem) clamp(1.6rem, 3.4vw, 3.5rem) clamp(.9rem, 2.4vh, 1.6rem);
}
.viewer__title {
  font-size: clamp(1.5rem, 2.8vw, 2.4rem);
  font-weight: 300; line-height: 1.05; letter-spacing: -.02em;
  margin-bottom: .45rem;
}
.viewer__text { font-size: clamp(.88rem, 1.15vw, 1.05rem); line-height: 1.45; opacity: .8; }
/* Haar beschrijving kan uit meerdere alinea's bestaan. Het gat ertussen is
   instelbaar, want bij een lange tekst trekt het script het samen. */
.viewer__text p + p { margin-top: var(--alinea-gat, .7em); }
.zonder-js { display: none; }
/* als Sanity onbereikbaar is */
.projects__fout { max-width: 34ch; font-size: .95rem; line-height: 1.5; opacity: .75; }

.viewer__info > * { transition: opacity .35s linear, transform .5s var(--ease); }
.projects__view.is-swapping .viewer__info > * { opacity: 0; transform: translateY(.5rem); }

.projects__close { display: none; }


/* De boekingspagina staat niet in deze stylesheet. Die is niets dan de agenda
   van Microsoft in een iframe over het volle scherm, met twee regels css in
   het bestand zelf. Zie boeken.html. */


/* ═══ 8. RESPONSIVE ═════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
  /* De splitsing blijft, maar op een smallere kolom past haar tekst van ruim
     honderd woorden niet meer binnen één gepind scherm. Hier scrollt ze dus
     gewoon; het scrollscript ziet vanzelf dat de pin niet meer sticky is. */
  .split__block { min-height: auto; }
  .split__pin {
    position: static;
    min-height: 0;
    padding: clamp(3rem, 8vh, 5rem) clamp(1.6rem, 4vw, 3rem);
  }
}

@media (max-width: 900px) {
  .partners__grid { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 820px) {
  /* — about op smal scherm: hetzelfde principe als op desktop, maar dan
       horizontaal gesplitst. Het beeld blijft bovenaan hangen, de tekst
       schuift eronder door.

       Belangrijk: het beeld is positioned (sticky) en tekent dus boven gewone
       inhoud, maar de woorden krijgen tijdens hun reveal een eigen stacking
       context (opacity/transform) en zouden anders dwars over de foto komen.
       Daarom krijgt het paneel expliciet een lagere laag dan het beeld. — */
  .split { grid-template-columns: 1fr; }

  /* hoogte van het vaste beeld — het tekstblok haakt hier precies onder aan */
  .split { --media-h: 42vh; }
  .split__media { height: var(--media-h); min-height: 290px; z-index: 2; }
  .split__panel { position: relative; z-index: 1; }

  /* De uitnodiging stapelt net als de vlakken erboven: foto bovenaan, het
     kleurvlak eronder. Geen vaste schermhoogte meer — op een telefoon zou de
     tekst dan tegen de randen lopen. */
  /* Wat ik doe stapelt: foto boven, tekst eronder, niets gepind. De teksten
     zijn te lang voor een half scherm op een telefoon. */
  .wid__deel { min-height: auto; }
  .wid__pin { position: static; height: auto; grid-template-columns: 1fr; }
  /* Met .wid__deel ervoor, anders wint de zigzagregel hierboven en zet die het
     kleurvlak in een tweede kolom die hier niet bestaat. Dan kwamen twee
     teksten achter elkaar te staan en twee foto's, in plaats van om beurten. */
  .wid__deel .wid__paneel,
  .wid__deel .wid__foto { grid-column: 1; grid-row: auto; }
  .wid__foto { order: -1; height: var(--media-h, 42vh); min-height: 260px; }
  .wid__paneel { padding: clamp(2.5rem, 9vw, 4rem) var(--gut); }
  .wid__woorden { max-width: 100%; font-size: clamp(.95rem, 4.1vw, 1.2rem); }

  /* contact stapelt: eerst de tekst, dan de foto */
  .contact {
    grid-template-columns: 1fr;
    min-height: auto;
    padding: clamp(5.5rem, 14vh, 8rem) var(--gut) clamp(3rem, 8vh, 5rem);
    gap: clamp(2.5rem, 7vh, 4rem);
  }
  .contact__tekst { max-width: 100%; padding: 0; }
  .contact__foto { padding: 0; }
  .contact__foto img { max-height: none; }

  .uitro { min-height: auto; }
  .uitro__pin { position: static; grid-template-columns: 1fr; height: auto; }
  .uitro__foto { height: var(--media-h, 42vh); min-height: 290px; }
  .uitro__paneel {
    padding: clamp(3rem, 9vh, 5rem) var(--gut);
    font-size: clamp(1.7rem, 8.5vw, 3rem);
  }

  /* elke paragraaf begint netjes onder het beeld en schuift er daarna achter
     weg — precies het scrollritme van de desktopversie */
  /* Geen pin meer op een telefoon: onder het beeld blijft nog geen 55vh over
     en haar tekst is ruim honderd woorden. Vastzetten zou de onderkant
     afsnijden. De tekst scrollt hier dus gewoon — onder het beeld door, dat
     wél blijft staan. Het scrollscript ziet vanzelf dat de pin niet meer
     sticky is en laat de woorden dan met het beeld mee oplichten. */
  .split__block { min-height: auto; }
  .split__pin {
    position: static;
    min-height: 0;
    padding: clamp(2rem, 6vh, 3rem) var(--gut) clamp(2.5rem, 8vh, 4rem);
  }

  /* — projecten: één kolom, het paneel schuift van onder in — */
  .projects { grid-template-columns: 1fr; }
  .projects__list { padding: clamp(5.5rem, 14vh, 8rem) var(--gut) clamp(3rem, 8vh, 5rem); }
  /* op een telefoon is er geen tweede kolom om ruimte voor te laten */
  .project { width: 78%; }
  /* geen twee kolommen meer om uit te lijnen: gewone stroom en maten */
  .projects__grid { gap: clamp(2rem, 6vh, 4rem); }
  .project__meta { position: static; }

  .projects__view {
    position: fixed; inset: 0;
    z-index: 900;
    height: 100dvh;
    /* Geen raster hier maar een gewone kolom. Met rijen perste het raster het
       beeldvlak samen zodra de tekst lang werd — de rij mag naar nul krimpen
       omdat het beeld erin absoluut staat — en schoof de tekst over de foto.
       Als kolom houdt elk deel zijn eigen hoogte en scrolt het paneel. */
    display: flex; flex-direction: column;
    gap: clamp(1.25rem, 3.5vh, 2rem);
    padding: clamp(3.75rem, 9vh, 5rem) var(--gut) clamp(2rem, 6vh, 3rem);
    transform: translateY(100%);
    transition: transform .8s var(--ease-io);
    overflow-y: auto;
  }
  .viewer__count { justify-self: end; align-self: end; padding-right: 0; }
  .viewer__stage { aspect-ratio: 4 / 3; flex: 0 0 auto; }
  .viewer__info  { flex: 0 0 auto; }
  .viewer__info { padding: 0; max-width: 100%; }
  .projects__view.is-open { transform: translateY(0); }
  .projects__view .viewer__info { align-self: start; max-width: 100%; }

  /* de + uit de topbar zit in de weg zodra het paneel openstaat */
  body.panel-open .topbar { opacity: 0; pointer-events: none; }

  .projects__close {
    position: absolute; top: 1rem; right: var(--gut);
    display: grid; place-items: center;
    width: 44px; height: 44px;
  }
  .projects__close::before,
  .projects__close::after {
    content: ""; position: absolute;
    width: 22px; height: 1.5px; background: currentColor;
  }
  .projects__close::before { transform: rotate(45deg); }
  .projects__close::after  { transform: rotate(-45deg); }

  .viewer__nav, .viewer__count { opacity: 1; }
}

@media (max-width: 720px) {
  .hero { height: 160vh; }
  .wordmark { width: min(82vw, 26rem); }
  .hero__tagline { font-size: 1.12rem; }

  .statement { height: 195vh; }
  .statement__text { max-width: 100%; font-size: clamp(1.25rem, 5.6vw, 1.9rem); }
  .statement__cta { width: 100%; }
  .statement__eyebrow { width: 100%; }

  .menu__list  { font-size: clamp(2rem, 11vw, 3.2rem); }

  /* Op een telefoon is er geen ruimte naast de lijst. Het beeld gaat naar de
     bovenste helft en de lijst zakt naar beneden, zodat ze elkaar niet raken. */
  .menu { justify-content: flex-end; padding-bottom: clamp(6rem, 17vh, 9rem); }
  .menu__vlak--1 { left: 30%; right: 6%; top: 9%; height: 30%; }
  .menu__vlak--2 { left: 48%; right: 0;  top: 6%; height: 34%; }
  .menu__vlak--3 { left: 38%; right: 0;  top: 8%; height: 31%; }
  .menu__vlak--4 { left: 44%; right: 0;  top: 5%; height: 35%; }

  .partners__grid { grid-template-columns: repeat(2, 1fr); }

  .split__text { max-width: 100%; font-size: clamp(.95rem, 4.1vw, 1.25rem); }

  .footer__onder { grid-template-columns: 1fr; }
  .footer__rechts { align-items: flex-start; text-align: left; }
  .footer__contact { justify-content: flex-start; }
}

@media (max-width: 520px) {
  .topbar__brand { font-size: .8rem; }
}


/* ═══ 9. BEWEGING BEPERKEN ══════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0s !important;
  }

  .reveal i,
  .intro__line i,
  .hero__tagline i,
  .hero__hint i,
  .menu__mask > span { transform: none; opacity: 1; }
  .menu__vlak img { transform: none; }

  .wordmark img, .split__logo { clip-path: none; }
  .split__photo, .split__uitsnede { transform: none; }
  .plus { opacity: 1; }
  .partners__cell { opacity: 1; transform: none; }
  .statement__text .word, .split__text .word { opacity: 1 !important; }
  .statement__cta { opacity: 1 !important; transform: none; }

  .hero { height: 130vh; }
  .statement { height: 120vh; }
  .split__block { min-height: auto; }
  .split__pin { position: static; min-height: auto; }
}
