/* ═══════════════════════════════════════════════════════════════════
   Sarah Koedam — onepager
   Alle kleuren staan in het :root-blok hieronder. Wil je de site
   hercoloreren, dan hoef je alleen daar iets aan te passen: nergens
   anders in dit bestand of in de SVG's zit een kleur ingebakken.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* huisstijl */
  --zwart: #000000;
  --geel: #FFDD59;
  --creme: #FFF3EE;

  /* afgeleide tekstkleuren */
  --op-geel: var(--zwart);
  --op-zwart: var(--creme);
  --accent-op-zwart: var(--geel);

  /* letterbreedte — Archivo heeft een echte breedte-as.
     80% is exact gelijk aan de losse familie Archivo Narrow; lager mag ook,
     de as loopt door tot 62%. */
  --tekstbreedte: 72%;
  --kopbreedte: 90%;

  /* ritme */
  /* De fotokolom bepaalt ook hoever de hero-foto is ingezoomd: de foto vult de
     kolom in de breedte (object-fit: cover), dus een smallere kolom laat méér
     van de foto zien. 34vw toont ongeveer 77% van de foto in de hoogte, 36vw
     nog maar 70%. */
  --fotokolom: clamp(15rem, 34vw, 43rem);
  --marge: clamp(1.25rem, 4vw, 5rem);
  --sectie-ruimte: clamp(3.5rem, 8vw, 8rem);
}

/* ── lettertype ─────────────────────────────────────────────────── */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('../assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('../assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── basis ──────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  font-family: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-weight: 400;
  font-stretch: var(--tekstbreedte);
  line-height: 1.5;
  color: var(--op-geel);
  background: var(--geel);
  overflow-x: hidden;
}

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

h1, h2, h3 { margin: 0; font-weight: 900; letter-spacing: -0.01em; line-height: 0.88; }

/* De grote koppen staan breder dan de lopende tekst: 90% is afgemeten op het
   ontwerp (0,623 em per teken tegen 0,620 daar). De tagline hoort bij het
   titelblok en gaat mee, zodat die even breed uitkomt als "koedam".
   De strakke letterafstand van -0.03em geldt alleen hier; op tekstformaat
   plakken de woorden er anders aan elkaar. */
.hero__titel,
.sectie__tekst h2.groot-geel { font-stretch: var(--kopbreedte); }

.hero__titel h1,
.sectie__tekst h2.groot-geel { letter-spacing: -0.03em; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }

:where(a, button, [tabindex]):focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

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

.skiplink {
  position: absolute;
  left: var(--marge);
  top: -100%;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--zwart);
  color: var(--creme);
  font-weight: 700;
  text-decoration: none;
}
.skiplink:focus { top: 0.75rem; }

/* ── de pill: een dunne ellips, terugkerend vormelement ─────────── */

.pill {
  display: inline-block;
  padding: 0.7em 1.9em;
  border: 1px solid currentColor;
  border-radius: 50%;
  /* Dezelfde maat en hetzelfde gewicht als de lopende tekst (.lopend) en als de
     tekst in een projectbalk: Rens zag 14 augustus 2026 dat het label
     "projecten" 10% kleiner en iets zwaarder stond dan de regel ernaast. Deze
     regel geldt voor álle ellipsen, zodat ze onderling gelijk blijven. */
  font-size: clamp(1.05rem, 2.05vw, 2.4rem);
  font-weight: 400;
  line-height: 1.15;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s ease, color 0.2s ease;
}

a.pill:hover,
a.pill:focus-visible {
  background: var(--pill-hover-vlak, var(--zwart));
  color: var(--pill-hover-tekst, var(--geel));
  border-color: var(--pill-hover-vlak, var(--zwart));
}

/* De algemene focusomtrek is currentColor, en die wordt hierboven geel — op de
   gele hero tekende hij zichzelf dus onzichtbaar. Zwart werkt op alle drie de
   vlakken; staat de balk toevallig op een zwarte sectie, dan is de gele vulling
   het teken. */
a.pill:focus-visible { outline-color: var(--zwart); }

/* Het sectielabel was ruimer dan de navigatie-pill — een bredere ellips op een
   groter korps, afgemeten op het ontwerp. Rens wilde 8 augustus 2026 dat alle
   ellipsen even groot zijn als de knoppen in de hero, dus staat hier alleen nog
   de ruimte eronder: maat en padding komen nu uit .pill zelf. */
.pill--label {
  margin-bottom: clamp(1.5rem, 3.5vw, 3rem);
}

/* ── vormen als masker ──────────────────────────────────────────── */
/* De SVG's bevatten geen kleur; de kleur komt hier uit CSS-variabelen. */

.tegel {
  background-color: var(--tegel-bg, transparent);
  position: relative;
  overflow: hidden;
}
.tegel::before {
  content: '';
  position: absolute;
  inset: 0;
  background-color: var(--vorm-kleur, currentColor);
  -webkit-mask: var(--vorm-src) center / cover no-repeat;
          mask: var(--vorm-src) center / cover no-repeat;
}

/* De koppeling tussen data-vorm en de vorm zelf staat in css/vormen.css,
   waar ze als data-URI zijn ingebakken. */

/* Een tegel met een foto in plaats van een vorm (linksonder bij "over mij").
   Het ::before moet hier écht uit: zonder data-vorm is --vorm-src leeg, en dan
   valt het masker weg en blijft er een dichtgekleurd vlak over de foto staan.
   De foto ligt absoluut in de tegel zodat zijn eigen hoogte de rij van het
   raster niet oprekt — de rijen zijn fr-eenheden en die hebben auto als
   ondergrens. De uitsnede maakt de CSS, net als bij de hero. */
.tegel--foto { --tegel-bg: var(--zwart); }
.tegel--foto::before { content: none; }
.tegel--foto img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}

/* De bloem uit het concept is drie kleuren: gele bladen, zwarte tussenruimte
   en een licht hart. Dat kan met twee lagen: het negatief (06) legt de zwarte
   tussenruimte, de bladen (05) komen daar bovenop, en het hart — dat in geen
   van beide vormen zit — laat de tegelachtergrond zien. */
.tegel[data-kleur='bloem-drieklank'] {
  --tegel-bg: var(--creme);
}
.tegel[data-kleur='bloem-drieklank']::before {
  background-color: var(--zwart);
  -webkit-mask-image: var(--bloem-lijnen-src);
          mask-image: var(--bloem-lijnen-src);
}
.tegel[data-kleur='bloem-drieklank']::after {
  content: '';
  position: absolute;
  inset: 0;
  background-color: var(--geel);
  -webkit-mask: var(--vorm-src) center / cover no-repeat;
          mask: var(--vorm-src) center / cover no-repeat;
}

[data-kleur='zwart-op-geel']  { --tegel-bg: var(--geel);  --vorm-kleur: var(--zwart); }
[data-kleur='zwart-op-creme'] { --tegel-bg: var(--creme); --vorm-kleur: var(--zwart); }
[data-kleur='geel-op-zwart']  { --tegel-bg: var(--zwart); --vorm-kleur: var(--geel); }
[data-kleur='geel-op-creme']  { --tegel-bg: var(--creme); --vorm-kleur: var(--geel); }

/* ═══════════════════ 1. home ═══════════════════════════════════ */

.hero {
  display: grid;
  /* de bovengrens van --fotokolom ligt bewust hoog: op een breed scherm moet
     de fotokolom mee blijven groeien, anders verschraalt de compositie */
  grid-template-columns: var(--fotokolom) minmax(0, 1fr);
  min-height: 100svh;
  background: var(--geel);
}

.hero__zijkolom {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* flex-basis 0 in plaats van auto: anders telt de eigen hoogte van de foto
   mee voor de hoogte van de hero, en rekt die op tot voorbij het scherm.
   Nu vult de foto precies de ruimte die de tegels overlaten. */
.hero__foto {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  background: var(--zwart);
}
/* picture moet de hoogte doorgeven, anders valt de img terug op zijn
   eigen formaat en loopt hij buiten het kader */
.hero__foto picture {
  display: block;
  width: 100%;
  height: 100%;
}
.hero__foto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* de foto is het volledige origineel; deze uitsnede houdt lucht boven haar
     hoofd en laat de onderrand net onder haar broekband vallen */
  object-position: 50% 38%;
}

/* Vaste hoogte in plaats van aspect-ratio: de foto brengt zijn eigen
   hoogte mee en zou de tegels anders platdrukken. De bovengrens houdt
   op een lage vensterhoogte genoeg ruimte over voor de foto. */
.hero__tegels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  flex: 0 0 auto;
  height: min(calc(var(--fotokolom) * 0.45), 32vh);
}

/* links een smalle marge zodat de titel bijna tegen de foto aan staat,
   rechts de gewone paginamarge voor de navigatie — zoals in het concept */
.hero__inhoud {
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 2.5vw, 2.25rem) var(--marge) var(--marge)
           clamp(1rem, 2vw, 2rem);
  min-width: 0;
}

.hoofdnav ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: clamp(0.5rem, 3vw, 3rem);
}

/* de middelste pill hangt iets hoger — dat losse ritme zit ook in het concept */
.hoofdnav li:nth-child(2) { margin-top: -0.75em; }

/* De drie pills zweven zachtjes op en neer. Bewust klein: --zweef is de
   uitslag naar één kant, dus de hele beweging is het dubbele daarvan.
   Elke pill heeft een eigen tempo en een negatieve vertraging, zodat ze
   meteen uit de pas lopen in plaats van als één blok te wippen.
   Bij hover staat de beweging stil; dat maakt aanklikken rustiger.
   (De reduced-motion-regel onderaan zet dit voor wie dat instelt uit.) */
@keyframes zweven {
  from { transform: translateY(calc(var(--zweef) * -1)); }
  to   { transform: translateY(var(--zweef)); }
}

.hoofdnav .pill {
  --zweef: 0.22rem;
  animation: zweven 5.5s ease-in-out infinite alternate;
}
.hoofdnav li:nth-child(1) .pill { animation-duration: 6.3s; animation-delay: -1.4s; }
.hoofdnav li:nth-child(2) .pill { animation-duration: 5.1s; animation-delay: -3.2s; --zweef: 0.28rem; }
.hoofdnav li:nth-child(3) .pill { animation-duration: 7.2s; animation-delay: -0.6s; }

.hoofdnav .pill:hover,
.hoofdnav .pill:focus-visible { animation-play-state: paused; }

/* Zijwaartse drift en een lichte kanteling. Twee losse eigenschappen naast
   `transform`, zodat er drie bewegingen over elkaar heen kunnen lopen zonder
   dat ze elkaar overschrijven: `transform` doet op en neer, `translate` doet
   links en rechts, `rotate` kantelt. */
@keyframes zwenken {
  from { translate: calc(var(--zij) * -1) 0; }
  to   { translate: var(--zij) 0; }
}
@keyframes kantelen {
  from { rotate: calc(var(--kantel) * -1); }
  to   { rotate: var(--kantel); }
}

/* Alleen op desktop: daar is ruimte om de knoppen losser neer te zetten. Op een
   telefoon staan ze op 320px met 6,6px over naast elkaar (beslissing 21), dus
   daar kan er geen millimeter bij.

   Ongelijker staan gebeurt door de buitenste twee juist te laten zákken, niet
   door de middelste verder op te tillen: die houdt op 1833px maar 8px lucht tot
   de bovenrand, want de padding daar loopt tegen zijn clamp aan terwijl de
   letter nog groeit. De tussenruimtes verschillen ook: de middelste krijgt er
   wat bij, de rechter wat af.

   Willekeuriger bewegen gebeurt met drie omlooptijden per pill die niet op
   elkaar delen (bijvoorbeeld 6,3 · 8,9 · 11,3s). De drie assen komen daardoor
   pas na minuten weer op hetzelfde punt samen, dus de beweging herhaalt zich
   niet zichtbaar. De uitslagen blijven klein — het moet drijven, niet dansen. */
@media (min-width: 901px) {
  /* De verspringing hangt aan de pill en niet aan de li: op de li is 1em de
     bodymaat van 16px, terwijl de knop op 1833px 37,6px groot is. Met em op de
     li bleef het verschil daar 21px op een knop van 98px hoog — nauwelijks
     zichtbaar. Zo groeit het mee met de letter. */
  .hoofdnav li {
    --zij: 0.16rem;
    animation: zwenken 8.9s ease-in-out infinite alternate;
  }
  .hoofdnav li:nth-child(1) { animation-duration: 8.9s;  animation-delay: -2.7s; }
  .hoofdnav li:nth-child(2) { animation-duration: 7.7s;  animation-delay: -0.9s; --zij: 0.22rem;
                              margin-left: 0.7rem; }
  .hoofdnav li:nth-child(3) { animation-duration: 10.3s; animation-delay: -5.5s; --zij: 0.13rem;
                              margin-left: -0.35rem; }
  .hoofdnav li:nth-child(1) .pill { margin-top: 0.5em; }
  .hoofdnav li:nth-child(3) .pill { margin-top: 0.22em; }

  .hoofdnav .pill {
    --kantel: 0.7deg;
    animation-name: zweven, kantelen;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
  }
  .hoofdnav li:nth-child(1) .pill {
    --zweef: 0.3rem;
    animation-duration: 6.3s, 11.3s;
    animation-delay: -1.4s, -4.1s;
  }
  .hoofdnav li:nth-child(2) .pill {
    --zweef: 0.38rem; --kantel: 1deg;
    animation-duration: 5.1s, 9.4s;
    animation-delay: -3.2s, -6.8s;
  }
  .hoofdnav li:nth-child(3) .pill {
    --zweef: 0.26rem; --kantel: 0.5deg;
    animation-duration: 7.2s, 12.7s;
    animation-delay: -0.6s, -8.3s;
  }

  /* de drift zit op de li, dus die moet ook stil komen te staan bij hover */
  .hoofdnav li:hover { animation-play-state: paused; }
}

/* de titel hangt onder de navigatie, niet onderaan de hero */
.hero__titel {
  margin-top: clamp(1.5rem, 9vh, 8rem);
}

.hero__titel h1 {
  font-size: clamp(3rem, 14.3vw, 19rem);
  line-height: 0.85;
  margin-left: -0.045em;   /* optisch uitlijnen: de 's' hangt iets uit */
}

.tagline {
  margin-top: clamp(0.4rem, 1vw, 1.2rem);
  font-size: clamp(0.95rem, 2.75vw, 3.6rem);
  font-weight: 700;
  letter-spacing: -0.015em;
}

/* ── compacte navigatie na de hero ──────────────────────────────── */

.snelnav {
  position: fixed;
  top: clamp(0.6rem, 1.5vw, 1.1rem);
  right: var(--marge);
  z-index: 50;
  opacity: 0;
  transform: translateY(-0.75rem);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.snelnav[hidden] { display: none; }
.snelnav.is-zichtbaar { opacity: 1; transform: none; }
/* Tussen "onzichtbaar" en "weg" zit de uitfade. Zonder deze regel vangt die
   doorzichtige balk in die tijd nog klikken op, en blijft hij dat doen als de
   overgang nooit afloopt — bijvoorbeeld omdat het tabblad naar de achtergrond
   gaat. */
.snelnav:not(.is-zichtbaar) { pointer-events: none; }

.snelnav ul {
  display: flex;
  gap: 0.4rem;
}
/* de zwevende navigatie blijft klein — die mag de inhoud niet overstemmen */
.snelnav .pill {
  --pill-hover-vlak: var(--geel);
  --pill-hover-tekst: var(--zwart);
  background: var(--zwart);
  color: var(--creme);
  border-color: var(--creme);
  padding: 0.6em 1.5em;
  font-size: clamp(0.85rem, 1.05vw, 1.05rem);
}

/* ═══════════════════ secties ═══════════════════════════════════ */

/* Geen scroll-margin-top: een klik op "over mij", "projecten" of "contact"
   landt precies op de bovenrand van de sectie. Er stond 4.5rem, zodat de
   zweefbalk het sectielabel niet zou bedekken; dat speelt niet meer sinds de
   labels links staan (beslissing 18) en de balk rechtsboven zweeft. */
.sectie {
  display: grid;
  grid-template-columns: 52fr 48fr;
  align-items: stretch;
}

.sectie--donker {
  background: var(--zwart);
  color: var(--op-zwart);
}

/* op desktop vult een donkere sectie het scherm, zoals in het ontwerp */
@media (min-width: 901px) {
  .sectie--donker { min-height: 100svh; }
}

/* De projectensectie staat licht tussen de twee zwarte secties in. Het is de
   crème uit de huisstijl, niet #fff: die kleur komt ook in de tegels terug en
   houdt de site op drie kleuren.

   Onderaan staat bewust géén ruimte: de sluitlijn van de projectenlijst raakt
   direct de zwarte contactsectie. Die strook crème las als een lege witte balk
   vóór contact in plaats van als lucht — op elke breedte, dus ook op desktop.
   Boven blijft de ruimte wél staan; daar scheidt hij het label van de sectie
   erboven. */
.sectie--licht {
  display: block;
  background: var(--creme);
  color: var(--op-geel);
  padding: var(--sectie-ruimte) var(--marge) 0;
}

.sectie__tekst {
  padding: clamp(1.5rem, 3vw, 4rem) clamp(1.5rem, 3vw, 3rem)
           var(--sectie-ruimte) var(--marge);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  min-width: 0;
}

.sectie__tekst .pill--label { align-self: flex-start; }

/* Kop en lopende tekst staan bewust op hetzelfde formaat: in het ontwerp is
   "Hoi, ik ben Sarah!" geen groot opschrift maar gewoon de eerste regel. */
.sectie__tekst h2 {
  font-size: clamp(1.15rem, 2.05vw, 2.4rem);
  line-height: 1.15;
}

.lopend {
  margin-top: clamp(0.7rem, 1.4vw, 1.6rem);
  max-width: 46ch;
  font-size: clamp(1.05rem, 2.05vw, 2.4rem);
  line-height: 1.3;
}

.lopend--accent { color: var(--accent-op-zwart); }

/* de grote kop krijgt zijn eigen strakke regelafstand terug: de regel
   hierboven zet 1.15 voor de kleine sectiekoppen, en dat gold hier ook */
.sectie__tekst h2.groot-geel {
  color: var(--accent-op-zwart);
  font-size: clamp(2.35rem, 5.7vw, 6rem);
  line-height: 0.88;
}

/* zelfde formaat als de lopende tekst bij "over mij"; de streep verschijnt
   pas bij hover, zoals in het ontwerp — de link staat op zijn eigen regel
   onder het kopje, dus hij blijft ook zonder streep herkenbaar */
.mail {
  font-size: clamp(1.05rem, 2.05vw, 2.4rem);
  font-weight: 400;
  text-decoration: none;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.mail:hover,
.mail:focus-visible {
  color: var(--accent-op-zwart);
  text-decoration: underline;
}

/* ── mozaïeken ──────────────────────────────────────────────────── */

.mozaiek {
  display: grid;
  min-height: clamp(20rem, 40vw, 34rem);
}

/* De twee kolommen delen niet op dezelfde hoogte: de linkerkolom knikt op 38%,
   de rechter op 31%. Dat verspringen zit ook in het oorspronkelijke concept en
   houdt het raster levendig. Drie rijen geven beide knikpunten. */
.mozaiek--over {
  grid-template-columns: 63fr 37fr;
  grid-template-rows: 31fr 7fr 62fr;
}
.mozaiek--over .tegel:nth-child(1) { grid-column: 1; grid-row: 1 / 3; } /* starburst */
.mozaiek--over .tegel:nth-child(2) { grid-column: 2; grid-row: 1 / 2; } /* bloem     */
.mozaiek--over .tegel:nth-child(3) { grid-column: 1; grid-row: 3 / 4; } /* foto      */
.mozaiek--over .tegel:nth-child(4) { grid-column: 2; grid-row: 2 / 4; } /* golf      */

/* Spiegelbeeld van de over-sectie: hier staat de smalle kolom links en liggen
   de knikpunten juist laag — links op 68%, rechts op 62%. */
.mozaiek--contact {
  grid-template-columns: 37fr 63fr;
  grid-template-rows: 62fr 6fr 32fr;
}
.mozaiek--contact .tegel:nth-child(1) { grid-column: 1; grid-row: 1 / 3; } /* golf        */
.mozaiek--contact .tegel:nth-child(2) { grid-column: 2; grid-row: 1 / 2; } /* zonnestraal */
.mozaiek--contact .tegel:nth-child(3) { grid-column: 1; grid-row: 3 / 4; } /* bloem       */
.mozaiek--contact .tegel:nth-child(4) { grid-column: 2; grid-row: 2 / 4; } /* starburst   */

/* ═══════════════════ 3. projecten ══════════════════════════════ */

/* Links, net als de labels bij "over mij" en contact. Het label stond eerst
   rechts en schoof daar bij het scrollen onder de zweefbalk door; links is dat
   over. Zie beslissing 18 in CLAUDE.md. */
.projecten__kop {
  display: flex;
  justify-content: flex-start;
  margin-bottom: clamp(1.5rem, 4vw, 3.5rem);
}
.projecten__kop .pill--label { margin-bottom: 0; }

/* De projecten staan als balken onder elkaar, niet als kaarten met foto's:
   één regel per productie, gescheiden door zwarte lijnen. Die lijnen lopen
   door tot de schermrand — vandaar de negatieve marge, die de padding van
   .sectie--licht opheft. De regels zetten hem er zelf weer in, zodat de tekst
   wél op de gewone marge begint maar het gele vlak bij hover de volle
   breedte pakt. */
.projecten__lijst {
  margin-inline: calc(var(--marge) * -1);
  border-top: 4px solid currentColor;
}

.projectregel { border-bottom: 2px solid currentColor; }
.projectregel:last-child { border-bottom-width: 4px; }

.projectregel__rij {
  display: grid;
  grid-template-columns:
    minmax(0, 1.5fr) minmax(0, 1.1fr) minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 0.35rem clamp(0.9rem, 1.8vw, 2.25rem);
  padding: clamp(0.9rem, 1.8vw, 1.9rem) var(--marge);
  text-decoration: none;
  transition: background-color 0.18s ease, padding-left 0.18s ease;
}

/* Bij hover kleurt de hele balk geel — op de crème sectie is dat de omslag met
   het meeste verschil, en het houdt de tekst gewoon zwart. De regel schuift
   daarbij een stukje op, zodat de hele balk als één knop voelt. */
a.projectregel__rij:hover,
a.projectregel__rij:focus-visible {
  background: var(--geel);
  padding-left: calc(var(--marge) + clamp(0.5rem, 1.2vw, 1.5rem));
}

/* De omtrek bij toetsenbordfocus valt naar binnen: de balk loopt tot de
   schermrand, dus buiten het vlak is geen ruimte om hem te tekenen. */
a.projectregel__rij:focus-visible { outline-offset: -0.6rem; }

/* Titel, opdrachtgever en rol staan alle drie op de maat van de lopende tekst
   elders op de site; alleen de titel is vet. Zo leest de regel als één zin en
   niet als een kop met bijschrift. */
.projectregel__titel,
.projectregel__opdrachtgever,
.projectregel__rol,
.projectregel__jaar {
  font-size: clamp(1.05rem, 2.05vw, 2.4rem);
  line-height: 1.2;
}

/* Producties houden hun eigen schrijfwijze — geen lowercase hier, anders wordt
   "SyncDorst" ineens "syncdorst". */
.projectregel__titel {
  font-weight: 700;
  letter-spacing: -0.015em;
}

/* Het jaartal staat in dezelfde letter als de rest van de regel — geen eigen
   breedte of letterafstand meer. Alleen de cijfers krijgen een vaste breedte,
   zodat de kolom van boven naar beneden uitlijnt; dat is dezelfde letter, geen
   andere. */
.projectregel__jaar {
  font-variant-numeric: tabular-nums;
  /* Elke regel is zijn eigen raster, dus een leeg jaartal zou die ene regel
     scheef trekken. Deze ondergrens is de breedte van vier cijfers en houdt
     de kolom overeind, ook als er niets staat. */
  min-width: 4.6ch;
}

.projectregel__pijl {
  justify-self: end;
  /* net iets kleiner dan de tekst: op dezelfde maat wordt het pijltje log */
  font-size: clamp(1rem, 1.75vw, 2.05rem);
  line-height: 1;
  transition: transform 0.25s ease;
}
a.projectregel__rij:hover .projectregel__pijl,
a.projectregel__rij:focus-visible .projectregel__pijl {
  transform: translate(0.15em, -0.15em);
}

/* ═══════════════════ responsief ════════════════════════════════ */

@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    min-height: auto;
  }
  .hero__zijkolom { order: 2; }
  .hero__inhoud { order: 1; padding-top: var(--marge); }
  /* hier is er geen resthoogte om te vullen, dus bepaalt de verhouding
     de hoogte weer — met basis 0 zou de foto tot niets inklappen */
  /* De hoogte van de foto hangt hier aan de vensterbreedte én de vensterhoogte.
     Alleen aan de breedte — zoals met een aspect-ratio — liep het mis: bij een
     venster van 899px werd de foto 599px hoog, en juist bij het versmallen van
     het venster groeide hij dus mee in plaats van mee te krimpen. */
  .hero__zijkolom { --fotohoogte: min(50vw, 38svh); }
  .hero__foto { flex: 0 0 auto; height: var(--fotohoogte); }
  /* liggend kader uit een staande foto: hier past maar een smalle band, dus
     staat de uitsnede hoger dan op desktop — net genoeg lucht boven haar hoofd */
  .hero__foto img { object-position: 50% 32%; }
  /* De tegels zijn hier een smalle band, geen vierkanten: over de volle breedte
     zou een vierkante tegel een halve schermbreedte hoog worden en dat drukt de
     foto en de tekst weg. De 45% is dezelfde verhouding als op desktop, waar de
     tegelrij 0,45 × de fotokolom is. De vorm wordt bijgesneden (cover), wat bij
     deze ronde vormen goed uitpakt. */
  .hero__tegels { height: calc(var(--fotohoogte) * 0.45); }
  .hero__titel { margin-top: clamp(2rem, 8vw, 4rem); }
  .hero__titel h1 { font-size: clamp(3rem, 15vw, 7rem); }
  .tagline { font-size: clamp(0.95rem, 3.4vw, 1.5rem); }

  .sectie { grid-template-columns: 1fr; }
  .sectie__tekst { padding: var(--sectie-ruimte) var(--marge); }
  /* In één kolom heeft de leesbreedte van 46ch geen nut meer: de tekst stond
     dan als een smalle strook links terwijl het kopje ernaast wél de volle
     breedte pakte. Op 375px viel dat niet op (46ch is daar breder dan de
     kolom), maar vanaf ongeveer 410px groeit het gat rechts mee — bij 900px
     bleef er bijna 500px leeg. Hier vult de tekst dus de kolom. */
  .lopend { max-width: none; }

  /* Ook de mozaïeken worden een band: vier vierkanten op één rij in plaats van
     een blok van 2×2. Dat blok was op een telefoon een schermbreedte hoog en
     nam samen met de hero het halve document in beslag. */
  .mozaiek { min-height: 0; }
  .mozaiek--over,
  .mozaiek--contact {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-template-rows: auto;
  }
  .mozaiek--over .tegel,
  .mozaiek--contact .tegel { aspect-ratio: 1; }
  /* De verspringende plaatsing van desktop terugdraaien. Let op de :nth-child:
     zonder die extra zwaarte winnen de regels van desktop en blijft het
     mozaïek drie rijen hoog. */
  .mozaiek--over .tegel:nth-child(n),
  .mozaiek--contact .tegel:nth-child(n) { grid-column: auto; grid-row: auto; }

  /* In een vierkante tegel valt er van een staande vorm boven en onder een
     stuk weg (mask-size: cover). Bij de golf zat de massa daardoor bovenin en
     bleef de onderste 31% van de tegel leeg — een strook achtergrondkleur
     onder de vorm, in beide mozaïeken. Het masker aan de bovenrand hangen laat
     de vorm juist tot onderaan doorlopen. De andere vijf vormen zijn liggend
     of vierkant: die worden links en rechts bijgesneden, dus voor hen maakt de
     verticale uitlijning niets uit. */
  .mozaiek .tegel::before,
  .mozaiek .tegel[data-kleur='bloem-drieklank']::after {
    -webkit-mask-position: center top;
            mask-position: center top;
  }

  /* Vijf kolommen naast elkaar wordt hier te krap: de balk wordt een blokje.
     Titel en pijl op de eerste regel, daaronder opdrachtgever, rol en jaar. */
  .projectregel__rij {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 0.15rem;
  }
  .projectregel__titel         { grid-column: 1; grid-row: 1; }
  .projectregel__pijl          { grid-column: 2; grid-row: 1; align-self: center; }
  .projectregel__opdrachtgever { grid-column: 1 / -1; grid-row: 2; }
  .projectregel__rol           { grid-column: 1 / -1; grid-row: 3; }
  .projectregel__jaar          { grid-column: 1 / -1; grid-row: 4; }
  /* een leeg veld mag geen lege regel opleveren */
  .projectregel__opdrachtgever:empty,
  .projectregel__rol:empty,
  .projectregel__jaar:empty { display: none; }
}

@media (max-width: 560px) {
  /* krappere pills zodat de drie naast elkaar op één regel blijven */
  .pill { padding: 0.6em 1.35em; }
  .hoofdnav ul { gap: 0.4rem; }
}

/* De pills staan sinds 14 augustus 2026 op de maat van de lopende tekst
   (1.05rem onderaan de clamp in plaats van 0.9rem). Dat is 17% groter dan
   daarvoor, en op 320px pasten de drie hero-knoppen daardoor niet meer naast
   elkaar: ze vielen op twee regels. Alleen daar staan ze dus krapper — de maat
   van de letter blijft overal gelijk, want dat was juist de bedoeling.
   Op 320px houdt dit ze op één regel, met 6,6px over van de 269px die
   .hero__inhoud daar binnen zijn padding overhoudt. */
@media (max-width: 400px) {
  .hoofdnav .pill { padding: 0.6em 1.05em; }
  .hoofdnav ul { gap: 0.3rem; }
}

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