/* =============================================================================
   JANSENDEVELOPMENTS DESIGN SYSTEM — COMPONENTS
   Versie:  2.16.0
   Docs:    /design-system/README.md
   Rol:     gedeelde componentklassen voor ALLE (sub)domeinen. Uitsluitend
            opgebouwd uit semantische tokens (tokens.css) — geen hex, geen
            losse px, geen eigen media queries voor typografie (fluid tokens
            regelen dat). Laadvolgorde: theme.js → tokens.css → base.css →
            components.css → subdomein-CSS.

   Gegroeid volgens de fase-2-afspraak: hier staat alleen wat gebouwde
   pagina's daadwerkelijk gebruiken — geen speculatieve componenten.
   Domein-specifieke componenten leven bij hun domein (promotieregel:
   tweede gebruiker → hierheen verplaatsen, nooit kopiëren).
   ============================================================================= */


/* ═══ TEKSTSTIJL-CLASSES ══════════════════════════════════════════════════
   Eén class per tekststijl uit tokens.css — nooit losse font-properties
   combineren in pagina-CSS. Kale h1–h4/blockquote/code krijgen hun stijl
   al via base.css; deze classes zijn voor elk ander element. */
.text-display {
  font-family: var(--text-display-family);
  font-size: var(--text-display-size);
  line-height: var(--text-display-line);
  font-weight: var(--text-display-weight);
  letter-spacing: var(--text-display-tracking);
}
.text-h1 { font: var(--text-h1-weight) var(--text-h1-size)/var(--text-h1-line) var(--text-h1-family); letter-spacing: var(--text-h1-tracking); }
.text-h2 { font: var(--text-h2-weight) var(--text-h2-size)/var(--text-h2-line) var(--text-h2-family); letter-spacing: var(--text-h2-tracking); }
.text-h3 { font: var(--text-h3-weight) var(--text-h3-size)/var(--text-h3-line) var(--text-h3-family); }
.text-h4 { font: var(--text-h4-weight) var(--text-h4-size)/var(--text-h4-line) var(--text-h4-family); }
.text-lead { font: var(--text-lead-weight) var(--text-lead-size)/var(--text-lead-line) var(--text-lead-family); }
.text-body { font: var(--text-body-weight) var(--text-body-size)/var(--text-body-line) var(--text-body-family); }
.text-body-s { font: var(--text-body-s-weight) var(--text-body-s-size)/var(--text-body-s-line) var(--text-body-s-family); }
.text-caption { font: var(--text-caption-weight) var(--text-caption-size)/var(--text-caption-line) var(--text-caption-family); }
.text-quote {
  font: var(--text-quote-weight) var(--text-quote-size)/var(--text-quote-line) var(--text-quote-family);
  font-style: var(--text-quote-style);
}
.text-stat {
  font: var(--text-stat-weight) var(--text-stat-size)/var(--text-stat-line) var(--text-stat-family);
  letter-spacing: var(--text-stat-tracking);
}
.text-code { font: var(--text-code-weight) var(--text-code-size)/var(--text-code-line) var(--text-code-family); }

/* Eyebrow — kicker boven een kop; standaard in accentkleur */
.text-eyebrow {
  font-family: var(--text-eyebrow-family);
  font-size: var(--text-eyebrow-size);
  line-height: var(--text-eyebrow-line);
  font-weight: var(--text-eyebrow-weight);
  letter-spacing: var(--text-eyebrow-tracking);
  text-transform: var(--text-eyebrow-transform);
  color: var(--color-text-accent);
}

/* Mono spec-annotatie — het "code-handschrift" uit het Atelier-concept:
   metadata, maten, herkomst-labels naast Fraunces-koppen. */
.text-spec {
  font: var(--text-code-weight) var(--text-code-size)/var(--text-code-line) var(--text-code-family);
  color: var(--color-text-muted);
}

/* Kleur-utilities — CSP verbiedt inline style-attributen (style-src 'self'),
   dus gedempte/accent-tekst altijd via deze classes. */
.text-muted  { color: var(--color-text-muted); }
.text-accent { color: var(--color-text-accent); }
.text-brand  { color: var(--color-text-brand); }

/* Tekstlink — de ENIGE plek die underline geeft (reset houdt <a> kaal) */
.text-link {
  color: var(--color-text-link);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: from-font;
  transition: color var(--duration-fast) var(--ease-out);
}
.text-link:hover { color: var(--color-accent-hover); }


/* ═══ BUTTONS ═════════════════════════════════════════════════════════════
   <a class="btn ..."> of <button class="btn ...">. States komen uit de
   afgeleide tokens — nooit eigen hover-kleuren verzinnen.

   HET KNOPPENSYSTEEM (vastgelegd met Ruud, 2026-07-08) — vier soorten:
   1. DEFAULT   .btn--outline  normale achtergrond · controlhoogte
   2. PROMINENT .btn--primary  accent/brand-achtergrond · controlhoogte
   3. LINK      .btn--link     geen achtergrond · hugt de tekst ·
                               nav-onderstreep bij hover — puur navigatie
                               (terug, sluiten, footer, "open in …")
   4. CHIP      .chip          aan/uit-keuze · hugt de tekst (§CHIP)
   Alle vier: text / icoon+text / text+icoon / alleen icoon.
   (.btn--danger is de gevaar-variant van default, uitsluitend destructief.) */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  height: var(--size-control-m);
  padding-inline: var(--space-m);
  border-radius: var(--radius-m);
  font-family: var(--text-button-family);
  font-size: var(--text-button-size);
  line-height: var(--text-button-line);
  font-weight: var(--text-button-weight);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-spring);
}
.btn:hover  { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--color-bg-accent);
  color: var(--color-text-on-accent);
}
.btn--primary:hover  { background: var(--color-accent-hover); }
.btn--primary:active { background: var(--color-accent-pressed); }

/* DEFAULT — normale (raised) achtergrond, zichtbaar op elk vlak */
.btn--outline {
  border: var(--border-thin) solid var(--color-line-strong);  /* WCAG 1.4.11 */
  color: var(--color-text);
  background: var(--color-bg-raised);
}
.btn--outline:hover  { border-color: var(--color-line-accent); }
.btn--outline:active { background: var(--color-pressed-overlay); }

/* LINK — puur navigatie: geen achtergrond, hugt de tekst, en dezelfde
   geanimeerde onderstreep als de menubalk-links. Voor terug- en
   sluitknoppen, footer-links en "open in …"-verwijzingen. */
.btn--link {
  position: relative;
  height: auto;
  padding: 0;
  border-radius: 0;
  color: var(--color-text);
}
.btn--link::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: calc(-1 * var(--space-3xs));
  height: var(--border-thick);
  background: var(--color-line-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-base) var(--ease-out);
}
.btn--link:hover { transform: none; color: var(--color-text-accent); }
.btn--link:active { transform: none; }
.btn--link:hover::after { transform: scaleX(1); }

/* Van Ruud (2026-07-06, harde regel): ÉÉN knophoogte door het hele merk —
   size-varianten verschillen alleen in padding/tekstmaat, nooit in hoogte.
   Hetzelfde geldt voor alle invoervelden (--size-control-m is dé maat). */
.btn--large {
  padding-inline: var(--space-l);
}
.btn--small {
  padding-inline: var(--space-s);
  font-size: var(--text-nav-size);
}

/* Icoon in een knop (jd_icon(), shared/chrome.php) — verzoek Ruud
   2026-07-07: iconen waar ze context en scanbaarheid toevoegen. */
.btn svg {
  flex: none;
  width: var(--size-icon-s);
  height: var(--size-icon-s);
}

/* Gevaar-knop — UITSLUITEND voor destructieve acties (verwijderen,
   uitschakelen). Moet er altijd onmiskenbaar als delete-knop uitzien
   (verzoek Ruud 2026-07-07) — dus nooit stilletjes naast een gewone
   outline-knop dezelfde vorm zonder de rode signatuur. */
.btn--danger {
  border: var(--border-thin) solid var(--color-text-error);
  color: var(--color-text-error);
  background: transparent;
}
.btn--danger:hover  { background: var(--color-bg-error-soft); }
.btn--danger:active { background: var(--color-bg-error-soft); }

/* Gevarenzone: een definitieve actie (verwijderen) zit bewust achter een
   uitklap én oogt als gevaar (rood kader, gedempte achtergrond) — nooit
   "per ongeluk klikbaar" naast een gewone knop. Gepromoveerd uit
   component.css toen account. (gebruikersbeheer) hem ook nodig kreeg. */
.detail-danger summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  cursor: pointer;
  color: var(--color-text-error);
}
.detail-danger summary svg { width: var(--size-icon-s); height: var(--size-icon-s); }
.detail-danger__form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-xs);
  padding: var(--space-s);
  margin-top: var(--space-xs);
  border: var(--border-thin) dashed var(--color-text-error);
  border-radius: var(--radius-m);
  background: var(--color-bg-error-soft);
}


/* ═══ CHIP — aan/uit-keuze in een groep ═══════════════════════════════════
   Voor keuzemenu's en schakelbare toestanden: plek-tabs (uitgelicht.php),
   rol-tabs op de toegangspas, zichtbaarheids-toggles op detailpagina's.
   Gepromoveerd uit account.css (.access-demo__tab) toen de andere domeinen
   hem ook nodig kregen. De actieve staat is ONMISKENBAAR (accentvulling +
   aria-pressed) — een chip zonder duidelijke active state is een bug.
   Gebruik: <button class="chip" aria-pressed="true|false"> of <a class="chip"
   aria-current="page">. Iconen erin volgen de .btn-maatvoering. */
/* Chips HUGGEN de tekst (besluit Ruud 2026-07-08): de tekstmaat bepaalt de
   hoogte — bewust géén controlhoogte, dat onderscheidt een chip van een
   knop en past bij zijn rol als lichte keuze/status. */
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding-block: var(--space-3xs);
  padding-inline: var(--space-s);
  border: var(--border-thin) solid var(--color-line-strong);   /* WCAG 1.4.11 */
  border-radius: var(--radius-full);
  font-family: var(--text-nav-family);
  font-size: var(--text-nav-size);
  font-weight: var(--text-nav-weight);
  color: var(--color-text);
  background: transparent;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.chip svg { flex: none; width: var(--size-icon-s); height: var(--size-icon-s); }
.chip:hover { background: var(--color-hover-overlay); }
.chip[aria-pressed="true"],
.chip[aria-current="page"] {
  background: var(--color-bg-accent);
  border-color: var(--color-bg-accent);
  color: var(--color-text-on-accent);
}
.chip:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 2px;
}
.chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}
/* Icoon-chip: vierkant, alleen een icoon (altijd met aria-label + title).
   Volgt de knop-maat en het knop-hovergedrag (fix 2026-07-08: de generieke
   chip-hover maakte hem transparant → "onzichtbaar" boven een kaart). */
.chip--icon {
  padding: var(--space-3xs);
  border-radius: var(--radius-m);
  background: var(--color-bg-raised);
  box-shadow: var(--shadow-s);
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-spring);
}
.chip--icon:hover {
  background: var(--color-bg-raised);
  border-color: var(--color-line-accent);
  transform: translateY(-2px);
}
.chip--icon:active { transform: translateY(0); }
/* Aangezette chip blijft óók bij hover onmiskenbaar gevuld */
.chip[aria-pressed="true"]:hover {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-text-on-accent);
}


/* ═══ SITE-CHROME: HEADER ═════════════════════════════════════════════════
   Eén header voor alle (sub)domeinen; per domein verschillen alleen de
   nav-items (data via PHP-include) en het accent (data-site). */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: var(--border-thin) solid var(--color-line);
  /* Zachte themawissel — zelfde timing als body (base.css), anders klapt
     de header hard om terwijl de pagina vloeiend overgaat. */
  transition: background-color var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.site-header__inner {
  min-height: var(--size-header);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
}
.site-header__logo {
  font-family: var(--font-display);
  font-size: var(--text-h4-size);
  font-weight: 640;
  letter-spacing: -0.01em;
  color: var(--color-text-brand);       /* brand, nooit accent — bureau-anker */
  white-space: nowrap;
}
.site-header__logo .logo-mark { font-style: italic; }
.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-xs) var(--space-m);
  flex-wrap: wrap;
  justify-content: flex-end;
}
.nav-link {
  position: relative;
  font-family: var(--text-nav-family);
  font-size: var(--text-nav-size);
  line-height: var(--text-nav-line);
  font-weight: var(--text-nav-weight);
  color: var(--color-text);
  padding-block: var(--space-3xs);
}
.nav-link::after {                       /* geanimeerde onderstreep */
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: var(--border-thick);
  background: var(--color-line-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-base) var(--ease-out);
}
.nav-link:hover::after,
.nav-link[aria-current="page"]::after { transform: scaleX(1); }
.nav-link[aria-current="page"] { color: var(--color-text-accent); }

/* Thematoggle — zon/maan wisselt via [data-theme]. Volgt de button-styling
   (verzoek Ruud 2026-07-07): zelfde hoogte, radius, rand en states als
   .btn--outline — het is gewoon een knop met alleen een icoon. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-control-m);
  height: var(--size-control-m);
  border-radius: var(--radius-m);
  border: var(--border-thin) solid var(--color-line-strong);  /* WCAG 1.4.11 */
  color: var(--color-icon);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-spring);
}
.theme-toggle:hover  { background: var(--color-hover-overlay); transform: translateY(-2px); }
.theme-toggle:active { background: var(--color-pressed-overlay); transform: translateY(0); }
.theme-toggle svg { width: var(--size-icon-s); height: var(--size-icon-s); }
.theme-toggle .icon-moon { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun  { display: none; }
[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* Zwevende themaknop — linksonder in de viewport (verzoek Ruud 2026-07-07:
   de knop hoort geen ruimte in de menubalk in te nemen). Alleen voor
   uitgelogde bezoekers (ingelogd zit hij in het avatar-menu). Op mobiel
   verbergt html.js hem: daar zit de wissel in het overlay-menu. Zonder JS
   is er geen overlay-menu → dan blijft hij als vangnet gewoon staan. */
.theme-fab {
  position: fixed;
  left: var(--space-m);
  bottom: var(--space-m);
  z-index: var(--z-header);
  background: var(--color-bg-raised);
  box-shadow: var(--shadow-l);
}
.theme-fab:hover { background: var(--color-bg-raised); box-shadow: var(--shadow-overlay); }
@media (max-width: 859.98px) {
  html.js .theme-fab { display: none; }
}

/* ═══ AVATAR-MENU (ingelogd) ══════════════════════════════════════════════
   Uitklapbaar accountmenu in de menubalk: avatar + gebruikersnaam, met
   daarin accountcentrum, themawissel en (op account.) uitloggen. Native
   <details> — werkt zonder JS; site.js sluit hem bij klik-ernaast/Escape. */
.avatar-menu { position: relative; }
.avatar-menu__summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  min-height: var(--size-control-m);
  padding: 0 var(--space-2xs);
  border-radius: var(--radius-m);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out);
}
.avatar-menu__summary::-webkit-details-marker { display: none; }
.avatar-menu__summary:hover { background: var(--color-hover-overlay); }
.avatar-menu__summary:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 0;
}
.avatar-menu__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size-icon-xl);
  height: var(--size-icon-xl);
  border-radius: var(--radius-full);
  background: var(--color-bg-accent);
  color: var(--color-text-on-accent);
  font-family: var(--font-display);
  font-size: var(--text-body-s-size);
  font-weight: 640;
}
.avatar-menu__name {
  font-family: var(--text-nav-family);
  font-size: var(--text-nav-size);
  font-weight: var(--text-nav-weight);
  color: var(--color-text);
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Chevron: klein driehoekje dat meedraait met open/dicht */
.avatar-menu__chev {
  width: var(--size-icon-s);
  height: var(--size-icon-s);
  background: var(--icon-select-chevron, none) center / contain no-repeat;
  transition: rotate var(--duration-base) var(--ease-out);
}
.avatar-menu[open] .avatar-menu__chev { rotate: 180deg; }
.avatar-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-2xs));
  min-width: 230px;
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding: var(--space-2xs);
  background: var(--color-bg-raised);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-overlay);
  z-index: calc(var(--z-header) + 1);
}
.avatar-menu__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  min-height: var(--size-control-m);
  padding-inline: var(--space-xs);
  border-radius: var(--radius-m);
  font-family: var(--text-nav-family);
  font-size: var(--text-nav-size);
  font-weight: var(--text-nav-weight);
  color: var(--color-text);
  transition: background-color var(--duration-fast) var(--ease-out);
}
a.avatar-menu__item:hover { background: var(--color-hover-overlay); }
.avatar-menu__item--row { cursor: default; }
/* Uitlogknop (account.): volle breedte binnen het paneel */
.avatar-menu__panel form { display: contents; }
.avatar-menu__panel .btn { justify-content: flex-start; width: 100%; }
/* Mobiel: de nav (en dus het menu) verdwijnt achter de burger — het
   overlay-menu neemt het over (site.js kloont link + themawissel). */


/* ═══ SITE-CHROME: OVERLAY-MENU (mobiel) ═══════════════════════════════════
   Gebouwd door site.js uit de bestaande nav-links (progressive enhancement:
   zonder JS blijft de gewone flex-wrap-nav gewoon staan — daarom verbergen
   de media queries hieronder alleen onder html.js). Breakpoint 860px: daar
   past de langste header (main: 5 links + inlog + toggle) niet meer. */
@media (max-width: 859.98px) {
  html.js .site-nav { display: none; }
}
.nav-burger {
  display: none;
  position: relative;
  width: var(--size-control-m);
  height: var(--size-control-m);
  border-radius: var(--radius-m);
  cursor: pointer;
}
@media (max-width: 859.98px) {
  html.js .nav-burger { display: inline-flex; }
}
.nav-burger span {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--size-icon-m);
  height: var(--border-thick);
  background: var(--color-icon);
  translate: -50% -50%;
  transition: rotate var(--duration-base) var(--ease-out),
              translate var(--duration-base) var(--ease-out);
}
.nav-burger span:first-child  { translate: -50% calc(-50% - var(--space-3xs)); }
.nav-burger span:last-child   { translate: -50% calc(-50% + var(--space-3xs)); }
.nav-burger.is-open span:first-child { translate: -50% -50%; rotate: 45deg; }
.nav-burger.is-open span:last-child  { translate: -50% -50%; rotate: -45deg; }
.nav-burger:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 0;
}

/* KRITIEK: [hidden] expliciet honoreren — de display: flex hieronder wint
   anders van de UA-regel voor [hidden] en de onzichtbare overlay vangt dan
   elke klik op de hele pagina af. */
.nav-overlay[hidden] { display: none; }
.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-xl);
  padding: calc(var(--size-header) + var(--space-l)) var(--container-gutter) var(--space-xl);
  background: var(--color-bg);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-out);
}
.nav-overlay.is-open { opacity: 1; }
html.nav-overlay-open { overflow: hidden; }          /* scroll-lock */
html.nav-overlay-open .site-header { z-index: calc(var(--z-modal) + 1); }
.nav-overlay__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}
/* Menu-items op display-formaat — het menu als designmoment */
.nav-overlay__link {
  font-family: var(--font-display);
  font-size: var(--text-h1-size);
  line-height: var(--text-h1-line);
  font-weight: var(--text-h1-weight);
  color: var(--color-text);
  translate: 0 var(--space-s);
  opacity: 0;
  transition: translate var(--duration-slow) var(--ease-out),
              opacity var(--duration-slow) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.nav-overlay.is-open .nav-overlay__link { translate: 0 0; opacity: 1; }
.nav-overlay__link:nth-child(2) { transition-delay: 40ms; }
.nav-overlay__link:nth-child(3) { transition-delay: 80ms; }
.nav-overlay__link:nth-child(4) { transition-delay: 120ms; }
.nav-overlay__link:nth-child(5) { transition-delay: 160ms; }
.nav-overlay__link:nth-child(6) { transition-delay: 200ms; }
.nav-overlay__link:nth-child(n+7) { transition-delay: 240ms; }
.nav-overlay__link:hover,
.nav-overlay__link.is-current { color: var(--color-text-accent); font-style: italic; }
.nav-overlay__foot {
  display: flex;
  align-items: center;
  gap: var(--space-s);
}
@media (prefers-reduced-motion: reduce) {
  .nav-overlay,
  .nav-overlay__link { transition: none; translate: 0 0; }
}


/* ═══ SITE-CHROME: FOOTER ═════════════════════════════════════════════════
   VAST grid i.p.v. flex + space-between: kolomposities zijn zo op élk
   (sub)domein identiek, onafhankelijk van hoe breed de tekst in een kolom
   is. Kolom 1 (identiteit) krijgt bewust meer ruimte dan de linkkolommen. */
.site-footer {
  border-top: var(--border-thin) solid var(--color-line);
  background: var(--color-bg-sunken);
  /* Zachte themawissel — zelfde timing als body (base.css). */
  transition: background-color var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
.site-footer__inner {
  padding-block: var(--space-xl);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-l) var(--space-2xl);
}
@media (min-width: 640px) {
  .site-footer__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .site-footer__inner {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
  }
}
.site-footer__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
/* Footer-links zijn link-knoppen (knoppensysteem §3): zelfde geanimeerde
   onderstreep als de menubalk. */
.site-footer__col a {
  position: relative;
  align-self: flex-start;
  transition: color var(--duration-fast) var(--ease-out);
}
.site-footer__col a::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  bottom: calc(-1 * var(--space-3xs));
  height: var(--border-thick);
  background: var(--color-line-accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-base) var(--ease-out);
}
.site-footer__col a:hover { color: var(--color-text-accent); }
.site-footer__col a:hover::after { transform: scaleX(1); }


/* ═══ HERO ════════════════════════════════════════════════════════════════
   Full-screen hero op elke (sub)domein-homepage: header + hero = precies
   één viewport. De visual-invulling is per domein anders (eigen CSS). */
.hero {
  min-height: calc(100svh - var(--size-header));
  display: flex;
  align-items: center;
  padding-block: var(--space-2xl);
}


/* ═══ PAGINA-LAYOUT ═══════════════════════════════════════════════════════
   Witruimte altijd via gap op de container — nooit sibling-margins. */
.page {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xl);
  padding-block: var(--space-2xl) var(--space-4xl);
}
.page-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  max-width: var(--container-text);
}
/* Binnenpagina-koppen op display-formaat (vormtaal: poster is exclusief
   voor de homepage-hero; dit is de maat eronder). */
.page-header h1 {
  font-family: var(--text-display-family);
  font-size: var(--text-display-size);
  line-height: var(--text-display-line);
  font-weight: var(--text-display-weight);
  letter-spacing: var(--text-display-tracking);
}
.section {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}
.section__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  max-width: var(--container-text);
}

/* Verticale stapels met vaste tussenruimte */
.stack-2xs { display: flex; flex-direction: column; gap: var(--space-2xs); }
.stack-xs  { display: flex; flex-direction: column; gap: var(--space-xs); }
.stack-s   { display: flex; flex-direction: column; gap: var(--space-s); }
.stack-m   { display: flex; flex-direction: column; gap: var(--space-m); }
.stack-l   { display: flex; flex-direction: column; gap: var(--space-l); }

/* Vloeiend kaart-grid: auto-fit → werkt op élke tussenmaat zonder breakpoint */
.card-grid {
  display: grid;
  /* auto-fit: bewust — de meeste .card-grid's tonen een vast, klein aantal
     kaarten (diensten, koppelingen, component-home) die juist WEL de volle
     breedte mogen vullen. Een filterbare grid met wisselende resultaten
     (zoals de bibliotheek) wil dat NIET — zie #libraryGrid in component.css. */
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: var(--space-m);
}


/* ═══ CARD ════════════════════════════════════════════════════════════════ */
.card {
  background: var(--color-bg-raised);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-l);
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
a.card, button.card {
  transition: transform var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out),
              border-color var(--duration-base) var(--ease-out);
}
a.card:hover, button.card:hover {
  transform: translateY(-4px);
  border-color: var(--color-line-accent);
  box-shadow: var(--shadow-m);
}


/* ═══ ATELIER-MATERIAAL (creatieve overhaul 2026-07-06) ═══════════════════
   Het merkverhaal letterlijk: vlakken zijn papier, cards zijn fysieke
   artefacten die óp de pagina liggen. Drie bouwstenen:

   .grain            papierkorrel op een vlak (subtiel, per thema getoetst)
   .card--artefact   card als artefact: geen lijntje maar materiaal —
                     papierverloop, dubbele schaduw, strooihoek via --tilt,
                     hover = optillen. Combineren met een geplakt label:
                     <article class="card card--artefact">
                       <span class="card__tab">component/ui · 04</span> …
   .measure          maatlijn met eindstreepjes + mono-label (marginalia)
   .mark-cross       registratiekruisje (marginalia, altijd aria-hidden)   */

.grain { position: relative; }
.grain::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--texture-grain);
  opacity: var(--texture-grain-opacity);
  border-radius: inherit;
  pointer-events: none;
}

.card--artefact {
  position: relative;
  border: 0;
  border-radius: var(--radius-s);         /* papier: krappere hoek dan een paneel */
  background-image: linear-gradient(155deg, transparent 55%, var(--tint-paper));
  box-shadow: var(--shadow-artefact);
  rotate: var(--tilt, 0deg);              /* strooihoek: zet --tilt op --tilt-a/b/c/d */
}
a.card--artefact, button.card--artefact {
  transition: rotate var(--duration-base) var(--ease-out),
              translate var(--duration-base) var(--ease-out),
              box-shadow var(--duration-base) var(--ease-out);
}
a.card--artefact:hover, button.card--artefact:hover {
  transform: none;                        /* geen dubbele lift via de card-hover */
  rotate: 0deg;                           /* je pakt hem op: hij trekt recht… */
  translate: 0 calc(var(--space-2xs) - var(--space-s));  /* …en komt van de tafel */
  box-shadow: var(--shadow-artefact-lift);
  border-color: transparent;
}
@media (prefers-reduced-motion: reduce) {
  a.card--artefact:hover, button.card--artefact:hover { rotate: var(--tilt, 0deg); translate: 0 0; }
}

/* Geplakt label — hoek-tab met mono-tekst, half over de rand van het
   artefact geplakt (tape-gevoel: iets doorschijnend, eigen strooihoek). */
.card__tab {
  position: absolute;
  top: 0;
  left: var(--space-m);
  translate: 0 -50%;
  rotate: var(--tilt-c);
  padding: var(--space-3xs) var(--space-xs);
  background: color-mix(in srgb, var(--color-label-neutral) 85%, transparent);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-s);
  font: var(--text-badge-weight) var(--text-badge-size)/var(--text-badge-line) var(--font-mono);
  letter-spacing: var(--text-badge-tracking);
  color: var(--color-text-muted);
  white-space: nowrap;
  max-width: calc(100% - var(--space-xl));
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Maatlijn — mono-label tussen twee lijnen met eindstreepjes, het
   tekentafel-handschrift. Decoratief: altijd aria-hidden in de markup. */
.measure {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  border-inline: var(--border-thin) solid var(--color-line-strong);
  font: var(--text-code-weight) var(--text-caption-size)/var(--text-code-line) var(--text-code-family);
  color: var(--color-text-muted);
  white-space: nowrap;
}
.measure::before,
.measure::after {
  content: '';
  flex: 1;
  min-width: var(--space-s);
  height: var(--border-thin);
  background: var(--color-line-strong);
}

/* Visuele stempel per item-type — abstract vlak in accent-tinten, voor
   gecureerde items en bibliotheek-ingangen. Gepromoveerd uit main/assets/
   www.css toen component. hem ook nodig had (promotieregel). */
.specimen__visual {
  flex: none;
  width: var(--size-icon-xl);
  height: var(--size-icon-xl);
  border-radius: var(--radius-s);
}
.specimen__visual--component {
  background: var(--color-bg-accent);
  border-radius: var(--radius-s) var(--radius-full) var(--radius-s) var(--radius-s);
}
.specimen__visual--icon {
  background: var(--color-bg-accent-soft);
  border: var(--border-thick) solid var(--color-line-accent);
  border-radius: var(--radius-full);
}
.specimen__visual--tool {
  background: linear-gradient(135deg, var(--color-bg-accent) 50%, var(--color-bg-accent-soft) 50%);
}
/* Vrij gecureerd item zonder bibliotheek-bron (curatie-type 'custom') */
.specimen__visual--custom {
  background: var(--color-bg-accent-soft);
  border: var(--border-thick) solid var(--color-line-accent);
  border-radius: var(--radius-s);
}

/* Registratiekruisje — drukwerk-marginalia */
.mark-cross {
  display: inline-block;
  width: var(--size-icon-s);
  height: var(--size-icon-s);
  background:
    linear-gradient(var(--color-line-strong), var(--color-line-strong)) center / var(--border-thin) 100% no-repeat,
    linear-gradient(var(--color-line-strong), var(--color-line-strong)) center / 100% var(--border-thin) no-repeat;
  opacity: 0.6;
}


/* ═══ BADGE / LABEL ═══════════════════════════════════════════════════════ */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-full);
  background: var(--color-label-neutral);
  color: var(--color-text);
  font-family: var(--text-badge-family);
  font-size: var(--text-badge-size);
  line-height: var(--text-badge-line);
  font-weight: var(--text-badge-weight);
  letter-spacing: var(--text-badge-tracking);
}
.badge--green  { background: var(--color-label-green); }
.badge--yellow { background: var(--color-label-yellow); }
.badge--orange { background: var(--color-label-orange); }
.badge--red    { background: var(--color-label-red); }
.badge--purple { background: var(--color-label-purple); }
.badge--blue   { background: var(--color-label-blue); }


/* ═══ FORMULIEREN ═════════════════════════════════════════════════════════
   De reset maakt velden volledig kaal; deze classes kleden ze aan.
   Interactieve randen via --color-line-strong (WCAG 1.4.11). */
.form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-width: var(--container-narrow);
}
.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}
.form-field__label {
  font-family: var(--text-form-label-family);
  font-size: var(--text-form-label-size);
  line-height: var(--text-form-label-line);
  font-weight: var(--text-form-label-weight);
}
.form-field__input {
  min-height: var(--size-control-m);
  padding: var(--space-2xs) var(--space-xs);
  /* Duidelijke fill (verzoek Ruud 2026-07-07: velden zonder achtergrond
     lazen als "één brei") — sunken op elke ondergrond herkenbaar als
     invoervlak; bij focus licht hij op naar de basiskleur. */
  background: var(--color-bg-sunken);
  border: var(--border-thin) solid var(--color-line-strong);
  border-radius: var(--radius-m);
  font-family: var(--text-form-input-family);
  font-size: var(--text-form-input-size);
  line-height: var(--text-form-input-line);
  transition: border-color var(--duration-fast) var(--ease-out),
              background-color var(--duration-fast) var(--ease-out);
}
.form-field__input:hover { border-color: var(--color-line-accent); }
.form-field__input:focus-visible { background: var(--color-bg); }

/* ÉÉN controlhoogte, ook echt (audit 2026-07-07: min-height + padding liet
   velden naar 42–49px groeien naast 40px-knoppen). Eénregelige velden
   krijgen de exacte hoogte; alleen textarea mag groeien. */
input.form-field__input,
select.form-field__input {
  height: var(--size-control-m);
  padding-block: 0;
}

/* Bestand-kiezen: de native knop in de stijl van .btn--outline — een
   file-input mag nooit als systeem-kaal element tussen de DS-velden staan. */
input[type="file"].form-field__input {
  padding: var(--space-3xs);
  cursor: pointer;
  display: flex;
  align-items: center;
}
input[type="file"].form-field__input::file-selector-button {
  margin-right: var(--space-xs);
  height: calc(var(--size-control-m) - 2 * var(--space-3xs) - 2 * var(--border-thin));
  padding-inline: var(--space-s);
  border: var(--border-thin) solid var(--color-line-strong);
  border-radius: var(--radius-s);
  background: var(--color-bg-raised);
  color: var(--color-text);
  font-family: var(--text-button-family);
  font-size: var(--text-nav-size);
  font-weight: var(--text-button-weight);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out);
}
input[type="file"].form-field__input::file-selector-button:hover {
  background: var(--color-hover-overlay);
}

/* ═══ KEUZEVELDEN (checkbox) ══════════════════════════════════════════════
   Eén DS-checkbox voor alle domeinen (verzoek Ruud 2026-07-07): eigen
   getekend vinkvak i.p.v. het systeem-vinkje — accentvulling + wit vinkje
   bij aangevinkt, zelfde focus-ring als elk ander control. Gebruik met een
   omhullend label (bv. .user-card__perm). */
input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: var(--size-icon-m);
  height: var(--size-icon-m);
  border: var(--border-thin) solid var(--color-line-strong);
  border-radius: var(--radius-s);
  background: var(--color-bg-sunken);
  cursor: pointer;
  display: inline-grid;
  place-items: center;
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
}
input[type="checkbox"]::before {
  content: '';
  width: 60%;
  height: 60%;
  scale: 0;
  transition: scale var(--duration-fast) var(--ease-out);
  background: var(--color-text-on-accent);
  /* vinkje als mask, zodat de kleur een token blijft */
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / contain no-repeat;
}
input[type="checkbox"]:hover { border-color: var(--color-line-accent); }
input[type="checkbox"]:checked {
  background: var(--color-bg-accent);
  border-color: var(--color-bg-accent);
}
input[type="checkbox"]:checked::before { scale: 1; }
input[type="checkbox"]:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 2px;
}
/* Select: de reset (base.css) haalt de native chevron weg — hier komt de
   eigen indicator voor terug (kleur per thema: --icon-select-chevron in
   tokens.css). Een dropdown mag nooit op een tekstveld lijken. */
select.form-field__input {
  padding-right: calc(var(--space-xs) + var(--size-icon-m));
}
/* De uitgeklapte lijst zelf mee-thematiseren (Chrome/Edge/Firefox honoreren
   background/color op option; verder is de popup OS-chrome). */
select.form-field__input option {
  background: var(--color-bg-raised);
  color: var(--color-text);
}
select.form-field__input {
  background-image: var(--icon-select-chevron);
  background-repeat: no-repeat;
  background-position: right var(--space-xs) center;
  background-size: var(--size-icon-s);
}
.form-field__input:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 0;
  border-color: var(--color-line-accent);
}
.form-field__help {
  font-family: var(--text-form-help-family);
  font-size: var(--text-form-help-size);
  line-height: var(--text-form-help-line);
  color: var(--color-text-muted);
}

/* ═══ FORMULIER-GRID — velden naast elkaar, ALTIJD uitgelijnd ═════════════
   Dé oplossing voor wrappende labels (structurele fix 2026-07-08): elk
   .form-field spant drie subgrid-rijen (label / veld / hulptekst), zodat
   alle velden in een rij op precies dezelfde hoogte beginnen — hoe lang
   een label of bijschrift ook wordt. Gebruik .form-grid--2/--3 voor het
   aantal kolommen op desktop; mobiel stapelt alles.
   (Browsers zonder subgrid vallen terug op het oude gedrag — geen breuk.) */
.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-s);
  align-items: start;
}
.form-grid > .form-field {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  gap: var(--space-3xs);
  align-content: start;
}
/* label rij 1, veld rij 2, hulptekst rij 3 — expliciet, zodat een veld
   zónder hulptekst de rijen niet laat verspringen */
.form-grid > .form-field > .form-field__label { grid-row: 1; align-self: end; }
.form-grid > .form-field > .form-field__input { grid-row: 2; }
.form-grid > .form-field > .form-field__help  { grid-row: 3; }
@media (min-width: 768px) {
  .form-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .form-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ═══ ALERTS ══════════════════════════════════════════════════════════════ */
.alert {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding: var(--space-s);
  border-radius: var(--radius-l);
  font-size: var(--text-body-s-size);
  line-height: var(--text-body-s-line);
  transition: opacity var(--duration-slow) var(--ease-out),
              transform var(--duration-slow) var(--ease-out);
}
.alert--success { background: var(--color-bg-success-soft); color: var(--color-text-success); }
.alert--error   { background: var(--color-bg-error-soft);   color: var(--color-text-error); }
.alert--warning { background: var(--color-bg-warning-soft); color: var(--color-text-warning); }
.alert--info    { background: var(--color-bg-info-soft);    color: var(--color-text-info); }

/* Bevestigende meldingen ("Welkom terug." e.d.) verdwijnen vanzelf — zie
   site.js (verzoek Ruud 2026-07-08, merkbreed). Fouten/waarschuwingen
   blijven staan tot de gebruiker de pagina verlaat, want die verdienen
   bewuste aandacht i.p.v. vanzelf te verdwijnen. */
.alert.is-verdwijnend {
  opacity: 0;
  transform: translateY(calc(-1 * var(--space-2xs)));
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .alert { transition: none; }
}


/* ═══ BIBLIOTHEEK-LAYOUT ══════════════════════════════════════════════════
   Voor elke filterbare bibliotheekpagina (componenten, iconen, straks meer):
   sticky categorie-sidebar + resultaten. Sidebar schaalt mee met een
   groeiende categorielijst (scrollt zelf); onder 1024px stapelt alles. */
.library-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-l);
  align-items: start;
}
@media (min-width: 1024px) {
  .library-layout { grid-template-columns: 240px minmax(0, 1fr); }
  .library-sidebar {
    position: sticky;
    top: calc(var(--size-header) + var(--space-m));
    max-height: calc(100svh - var(--size-header) - var(--space-2xl));
    overflow-y: auto;
  }
}
.library-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}
.library-sidebar__title {
  font-family: var(--text-caption-family);
  font-size: var(--text-caption-size);
  font-weight: var(--text-caption-weight);
  color: var(--color-text-muted);
  padding: var(--space-2xs) var(--space-xs);
}
.library-sidebar__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs);
  min-height: var(--size-control-m);
  padding: var(--space-3xs) var(--space-xs);
  border-radius: var(--radius-m);
  font-family: var(--text-nav-family);
  font-size: var(--text-nav-size);
  line-height: var(--text-nav-line);
  font-weight: var(--text-nav-weight);
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.library-sidebar__item:hover { background: var(--color-hover-overlay); }
.library-sidebar__item[aria-pressed="true"] {
  background: var(--color-bg-accent-soft);
  color: var(--color-text-accent);
}
.library-sidebar__count {
  font-family: var(--text-code-family);
  font-size: var(--text-badge-size);
  color: var(--color-text-muted);
}

/* Zoekbalk voor bibliotheken */
.searchbar__input {
  width: 100%;
  height: var(--size-control-m);   /* één veldhoogte, merkbreed */
  padding-inline: var(--space-s);
  background: var(--color-bg);
  border: var(--border-thin) solid var(--color-line-strong);  /* WCAG 1.4.11 */
  border-radius: var(--radius-m);
  font-family: var(--text-form-input-family);
  font-size: var(--text-form-input-size);
  transition: border-color var(--duration-fast) var(--ease-out);
}
.searchbar__input:hover { border-color: var(--color-line-accent); }
.searchbar__input:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: 0;
  border-color: var(--color-line-accent);
}

/* Lege staat voor bibliotheken/overzichten */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-2xl) var(--space-l);
  border: var(--border-thin) dashed var(--color-line-strong);
  border-radius: var(--radius-l);
  text-align: center;
  color: var(--color-text-muted);
}


/* ═══ CTA-SCÈNE ═══════════════════════════════════════════════════════════
   Slotakkoord onderaan een pagina: één gecentreerde CTA-kaart ("briefje op
   tafel"). De invulling is per domein anders (main: .cta-note-vel; component/
   account: eigen kaart), het toneel is gedeeld. Gepromoveerd uit main/assets/
   www.css toen de subdomeinen hun eigen CTA kregen (promotieregel). */
.cta-scene {
  display: flex;
  justify-content: center;
  padding-block: var(--space-xl) var(--space-l);
}


/* ═══ CTA-STRIP ═══════════════════════════════════════════════════════════
   Zachte accent-balk voor roadmap/aankondigingen. Gepromoveerd uit
   component. toen account. hem ook nodig had (promotieregel). */
.cta-strip {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-l);
  background: var(--color-bg-accent-soft);
  border: var(--border-thin) solid var(--color-line);
  border-radius: var(--radius-xl);
}


/* ═══ UTILITIES ═══════════════════════════════════════════════════════════ */
/* Verbergen via JS (filters, tabs). Gepromoveerd uit component.
   !important is hier bewust en correct: een state-utility moet ALTIJD winnen
   van display-declaraties in later geladen subdomein-CSS (zelfde
   specificiteit → anders wint de laatste regel en blijft alles zichtbaar). */
.is-hidden { display: none !important; }


/* ═══ VORMTAAL-PATRONEN ═══════════════════════════════════════════════════
   De drie layout-patronen naast de card-grid (gebruiksregels en voorbeelden:
   docs/VORMTAAL.md). Doel: pagina's met ritme en scèniek — geen kaart-behang.

   .text-poster  typografie op affiche-formaat (tokens: --text-poster-*)
   .bleed        scène van viewportrand tot viewportrand (breekt bewust uit
                 de container — géén vrijbrief: alleen voor volwaardige
                 secties, en de INHOUD lijnt weer uit op de containermaat
                 via --bleed-pad)
   .strip        horizontale scroll-band met snappende items
   .spread       editorial 12-kolomsgrid met asymmetrische plaatsing        */

.text-poster {
  font-family: var(--text-poster-family);
  font-size: var(--text-poster-size);
  line-height: var(--text-poster-line);
  font-weight: var(--text-poster-weight);
  letter-spacing: var(--text-poster-tracking);
}

/* 100vw is inclusief de scrollbalk-breedte — zonder deze clip zou elke
   bleed-pagina een horizontale scrollbalk van een paar pixels krijgen.
   clip (niet hidden): breekt position: sticky van de header niet. */
html, body { overflow-x: clip; }

.bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  /* Inhoud terug op de containermaat: als zijpadding gebruiken */
  --bleed-pad: max(var(--container-gutter), calc((100vw - var(--container-max)) / 2));
}

.strip {
  display: flex;
  gap: var(--space-m);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* Uitlijning: eerste item op de containerlijn, laatste kan uitscrollen.
     scroll-padding móét de zijpadding spiegelen: zonder die regel snapt de
     browser het eerste item tegen de viewportrand (snapport = container
     zónder padding) zodra hij her-snapt na een layoutwijziging. */
  padding-inline: var(--bleed-pad, var(--container-gutter));
  scroll-padding-inline: var(--bleed-pad, var(--container-gutter));
  padding-block: var(--space-2xs) var(--space-s);   /* ruimte voor schaduw + balk */
  scrollbar-width: thin;
  scrollbar-color: var(--color-line-strong) transparent;
}
.strip > * {
  flex: none;
  scroll-snap-align: start;
  width: min(360px, 82vw);
}

.spread {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-l);
}
@media (min-width: 900px) {
  .spread { grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .spread__major { grid-column: 1 / 8; }
  .spread__minor {
    grid-column: 9 / 13;
    margin-top: var(--space-3xl);   /* bewuste asymmetrie — geen gelijke rijen */
  }
}


/* ═══ SCROLL-REVEAL ═══════════════════════════════════════════════════════
   Element start onzichtbaar en glijdt in beeld zodra het de viewport
   binnenkomt (JS zet .is-visible via IntersectionObserver — zie
   design-system/motion.js-patroon in de site-JS). Zonder JS of met
   prefers-reduced-motion is alles gewoon direct zichtbaar. */
.reveal {
  opacity: 0;
  transform: translateY(var(--space-s));
  transition: opacity var(--duration-slow) var(--ease-out),
              transform var(--duration-slow) var(--ease-out);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}
/* No-JS-vangnet: <html> krijgt .js via het motion-script; zonder dat blijft
   alles zichtbaar. */
html:not(.js) .reveal { opacity: 1; transform: none; }

/* Stagger: binnen een .reveal[data-stagger]-container komen de directe
   kinderen ná elkaar binnen (site.js zet de oplopende transition-delay). */
.reveal[data-stagger] > * {
  opacity: 0;
  translate: 0 var(--space-s);
  transition: opacity var(--duration-slow) var(--ease-out),
              translate var(--duration-slow) var(--ease-out);
}
.reveal[data-stagger].is-visible > * { opacity: 1; translate: 0 0; }
html:not(.js) .reveal[data-stagger] > * { opacity: 1; translate: 0 0; }
@media (prefers-reduced-motion: reduce) {
  .reveal[data-stagger] > * { opacity: 1; translate: 0 0; transition: none; }
}
