/* ==========================================================================
   Generieke basis-mock — app.css
   --------------------------------------------------------------------------
   Leunt volledig op de design-systeem-tokens (style-guide.css + components.css)
   die per project meegekopieerd worden: --color-*, --space-*, --radius-*,
   --text-*, --font-*, --shadow-*. Geen project-kennis; werkt op ELK van de
   triad-design-systemen.
   ========================================================================== */
/* PRIMAIR ALS TEKSTKLEUR. Een merkkleur die als VLAK werkt (oranje knop met donkere tekst) haalt als
   tekst op wit vaak geen AA (#FF6B35 = 2,8:1). Daarom leest alle tekst-in-primair deze ene variabele.
   `:where()` geeft 'm specificiteit 0: een design-systeem dat `--mock-primary-ink` in z'n `:root` zet
   (bv. een donkerdere tint) wint altijd, ook al laadt app.css erna. Zonder die declaratie is het
   gewoon de primaire kleur, dus bestaande systemen zien niets veranderen. */
:where(html) { --mock-primary-ink: var(--color-primary, #3a7ca5); }
/* DE TOAST is altijd een donker vlak met witte tekst. Hij leende eerst `--color-text-heading`, maar dat
   is een TEKST-kleur: een systeem met lichte koppen of `inherit` gaf wit op wit (enervisie 10-03).
   Eigen variabele, vaste donkere default; een design-systeem mag 'm zetten (dan wint het, zie boven). */
:where(html) { --mock-toast-bg: #1a2230; }

* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--color-bg, #f6f8fb);
  color: var(--color-text, #1a2230);
  font-family: var(--font-body, system-ui, sans-serif);
  font-size: var(--text-base, 1rem);
  line-height: var(--leading-normal, 1.5);
  -webkit-font-smoothing: antialiased;
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.app-header {
  position: sticky; top: 0; z-index: 20;
  background: var(--color-bg-surface, #fff);
  border-bottom: 1px solid var(--color-border, #dfe4ec);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.05));
}
/* De paginabreedte komt uit het DESIGN-SYSTEEM (`--container-max`), niet uit een hardcode hier.
   Stond hier `1280px`, terwijl de content-container het token volgde: header en content lijnden dan
   niet uit — het logo en de Inloggen-knop stonden tientallen pixels naast de inhoud eronder. Eén
   token stuurt nu de hele pagina; de fallback geldt alleen voor een DS zonder dat token. */
.app-header-inner {
  display: flex; align-items: center; gap: var(--space-4, 1rem);
  padding: var(--space-4, 1rem) var(--space-6, 1.5rem);
  max-width: var(--container-max, 1280px); margin: 0 auto; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: var(--space-3, .75rem); text-decoration: none; color: inherit; }
.brand-mark {
  display: grid; place-items: center; width: 40px; height: 40px; flex: 0 0 auto;
  border-radius: var(--radius-md, 10px); font-size: 1.3rem;
  background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff);
}
.brand-text { display: flex; flex-direction: column; }
.wordmark { font-family: var(--font-heading, inherit); font-weight: 700; font-size: var(--text-lg, 1.125rem); color: var(--color-text-heading, inherit); }
.tagline { font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684); }
.chapters { display: flex; gap: var(--space-2, .5rem); margin-left: auto; flex-wrap: wrap; }
.chapter-chip {
  font-size: var(--text-xs, .75rem); font-weight: 600;
  padding: 2px var(--space-3, .75rem); border-radius: var(--radius-pill, 999px);
  background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666);
  border: 1px solid var(--color-border, #dfe4ec);
}

/* App-weergave (voelt als de echte app) ↔ model-weergave (toont build-chrome) */
.mode-toggle {
  display: inline-flex; align-items: center; gap: var(--space-2, .5rem);
  margin-left: var(--space-3, .75rem); padding: .35rem var(--space-3, .75rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-pill, 999px);
  background: var(--color-bg-surface, #fff); cursor: pointer;
  font-size: var(--text-xs, .75rem); font-weight: 600; color: var(--color-text-secondary, #4a5666);
}
.mode-toggle:hover { background: var(--color-bg-surface-hover, #f7f9fc); }
.mode-toggle .mt-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-text-muted, #6b7684); }
.mode-app .mode-toggle { margin-left: auto; }
.mode-app .mode-toggle .mt-dot { background: var(--color-success, #2e7d47); }
/* App-weergave verbergt de model-/bouw-chrome: chapters, tagline, de Formulieren-tab. */
.mode-app #chapters, .mode-app .tagline, .mode-app .hub-tab[data-kind="forms"] { display: none; }
/* De tagline beschrijft de mock, niet de app: standaard weg, alleen in de model-weergave van de
   editor. Zo staat 'ie ook niet in beeld zolang het script nog laadt (gebruiker, 01-10). */
body:not(.mode-model) .tagline { display: none; }

/* `type="search"` tekent in Chromium z'n EIGEN wis-kruisje; naast onze `.search-clear` stonden er
   dus twee wis-knoppen in één veld. De onze blijft (die zit in de DS-taal en heeft een label). */
.search-input::-webkit-search-cancel-button,
.search-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }

/* ── Hub-nav (tabs) ─────────────────────────────────────────────────────── */
.hub-nav {
  position: relative; display: flex; gap: var(--space-1, .25rem);
  padding: 0 var(--space-6, 1.5rem); max-width: var(--container-max, 1280px); margin: 0 auto;
  overflow-x: auto; scrollbar-width: thin;
  /* Past het menu niet, dan werd het laatste label midden in een woord afgekapt ("Admin
     registrere") — dat leest als een fout, niet als "er is meer". Een uitvloeiende rand zegt
     dat je verder kunt scrollen; is er niets meer, dan vervaagt er lege ruimte en zie je niets. */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 2.5rem), transparent);
}
.hub-tab {
  display: inline-flex; align-items: center; gap: var(--space-2, .5rem);
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
  background: none; border: none; cursor: pointer; white-space: nowrap;
  /* SECONDARY, niet muted. `--color-text-muted` is de DECORATIEVE grijstint; een menu-label
     draagt betekenis en moet AA halen. Gemeten 09-02 over twee design-systemen: muted gaf
     4,31:1 en 2,88:1 op wit (beide onder 4,5), secondary 6,78:1 en 5,74:1. Zelfde reden voor
     `.persona-label` en `.vh-count` hieronder. */
  color: var(--color-text-secondary, #4a5666); font-size: var(--text-sm, .875rem); font-weight: 600;
  border-bottom: 2px solid transparent;
}
.hub-tab:hover { color: var(--color-text, #1a2230); }
.hub-tab[aria-selected="true"] { color: var(--mock-primary-ink, #3a7ca5); }
.ht-glyph { width: 16px; height: 16px; display: inline-flex; }
.ht-glyph svg { width: 16px; height: 16px; }
.ht-count {
  font-size: var(--text-xs, .7rem); font-weight: 700; min-width: 18px; text-align: center;
  padding: 0 6px; border-radius: var(--radius-pill, 999px);
  background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666);
}
.hub-tab[aria-selected="true"] .ht-count { background: var(--color-primary-soft, #e3eef5); color: var(--mock-primary-ink, #3a7ca5); }
.hub-indicator {
  position: absolute; bottom: 0; left: 0; height: 2px; width: 0; opacity: 0;
  background: var(--color-primary, #3a7ca5); transition: transform .2s ease, width .2s ease;
}

/* ── Shell + view ───────────────────────────────────────────────────────── */
.app-shell { max-width: var(--container-max, 1280px); margin: 0 auto; padding: var(--space-6, 1.5rem); }
.view { display: flex; flex-direction: column; gap: var(--space-4, 1rem); }
/* Kop en toolbar lijnen op DEZELFDE as. Stonden op `flex-end` en `center`, met gaps uit twee
   reeksen door elkaar — twee ritmes onder elkaar, en dat zie je zonder het te kunnen benoemen
   (gebruiker, 21-09: "de margins en paddings kunnen beter"). */
.view-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3, .75rem); flex-wrap: wrap; }
.vh-title { display: flex; align-items: baseline; gap: var(--space-3, .75rem); flex-wrap: wrap; }
.vh-title h1 { margin: 0; font-family: var(--font-heading, inherit); font-size: var(--text-2xl, 1.5rem); color: var(--color-text-heading, inherit); }
.vh-count { font-size: var(--text-xs, .75rem); font-weight: 600; line-height: 1; color: var(--color-text-secondary, #4a5666);
  background: var(--color-bg-muted, #eef2f7); border-radius: 999px; padding: .3em .6em; align-self: center;
  font-variant-numeric: tabular-nums; }
.vh-count:empty { display: none; }
.head-actions { display: flex; gap: var(--space-2, .5rem); }

/* ── Toolbar (filter + zoek) ────────────────────────────────────────────── */
/* Chips links, zoek rechts — ook als er géén chips zijn. Met `space-between` en één kind
   plakte het zoekveld links onder de titel, wat leest als een tweede kop in plaats van een
   gereedschap. */
.toolbar { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3, .75rem); flex-wrap: wrap; }
.toolbar > .chips { margin-right: auto; }
/* Het omgezette component hangt z'n zoekveld in een neutrale houder; die moet meerekken, anders
   krijgt het veld z'n min-breedte niet en kapt de placeholder alsnog af. */
.toolbar > [data-bind-search] { display: flex; flex: 1 1 14rem; min-width: 0; max-width: 24rem; justify-content: flex-end; }
.toolbar > [data-bind-search] .search-field { width: 100%; }
.toolbar > [data-bind-filter] { margin-right: auto; }
.chips { display: flex; gap: var(--space-2, .5rem); flex-wrap: wrap; }
.chip {
  /* Tokens, geen losse pixels: een chip hoort dezelfde verticale maat te hebben als een veld. */
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-pill, 999px); cursor: pointer;
  line-height: 1.2;
  font-size: var(--text-sm, .875rem); font-weight: 600;
  background: var(--color-bg-surface, #fff); color: var(--color-text-secondary, #4a5666);
  border: 1px solid var(--color-border, #dfe4ec);
}
.chip:hover { border-color: var(--color-border-strong, #c2cad6); }
.chip.is-active { background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); border-color: var(--color-primary, #3a7ca5); }
/* Het zoekveld IS een invoerveld en hoort dus de maat van `.form-control` te dragen: dezelfde
   padding, dezelfde radius, dezelfde focus-ring. Het had een hardgecodeerde `4px` en alleen een
   randkleur bij focus — een andere hoogte en een andere focus-taal dan elk ander veld op het
   scherm. En `min-width: 240px` kón niet krimpen, dus in een smalle kolom kapte de placeholder
   af midden in een woord ("Zoek in aangemelde bezoe"). Nu krimpt en groeit 'ie mee. */
.search-field {
  display: flex; align-items: center; gap: var(--space-2, .5rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 10px);
  padding: var(--space-2, .5rem) var(--space-3, .75rem);
  flex: 1 1 14rem; min-width: 0; max-width: 24rem;
}
.search-field:focus-within {
  border-color: var(--color-border-focus, var(--color-primary, #3a7ca5));
  box-shadow: 0 0 0 3px var(--color-primary-glow, rgba(58,124,165,.15));
}
.search-ico { display: inline-flex; color: var(--color-text-muted, #6b7684); }
.search-ico svg { width: 16px; height: 16px; }
.search-input { border: none; outline: none; background: none; flex: 1; font-size: var(--text-sm, .875rem); color: inherit; min-width: 0; }
.search-clear { border: none; background: none; cursor: pointer; color: var(--color-text-muted, #6b7684); display: inline-flex; padding: 2px; }
.search-clear svg { width: 14px; height: 14px; }
/* Alleen zichtbaar als er GEFILTERD wordt ("3 van 8"). Het totaal staat al naast de titel;
   twee keer hetzelfde getal op één rij leest als een fout. */
.search-count { font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684);
  white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ── Tabel ──────────────────────────────────────────────────────────────── */
.table-wrap {
  overflow-x: auto; border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-lg, 12px); background: var(--color-bg-surface, #fff);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.04));
}
/* Gegroepeerde DETAIL_LIST: master-kop boven elke rij-sub-tabel. */
.group-header {
  display: flex; flex-wrap: wrap; gap: var(--space-3, .75rem);
  margin: var(--space-3, .75rem) 0 calc(var(--space-2, .5rem) * -1) 0;
  padding-bottom: var(--space-2, .5rem);
  border-bottom: 2px solid var(--color-border, #dfe4ec);
}
.group-header:first-child { margin-top: 0; }
.group-key { font-size: var(--text-sm, .875rem); }
.group-key-label { color: var(--color-text-muted, #64748b); }
.group-key-val { font-weight: 700; color: var(--color-text, #1e293b); }
/* width:auto + min-width:100% => smalle tabellen vullen de breedte, brede tabellen
   (bv. de diepste drill-laag met veel kolommen + rij-acties) scrollen i.p.v. te knijpen. */
.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm, .875rem); }
.data-table td, .data-table th { white-space: nowrap; }
.data-table thead th {
  text-align: left; font-weight: 700; font-size: var(--text-xs, .75rem); letter-spacing: .01em;
  color: var(--mock-muted-op-vlak); padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-bottom: 1px solid var(--color-border, #dfe4ec); white-space: nowrap;
}
.data-table th.th-num, .data-table td.cell-num { text-align: right; }
.data-table tbody td {
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-bottom: 1px solid var(--color-border, #eef1f6); vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--color-bg-surface-hover, #f7f9fc); }
.cell-primary { font-weight: 600; color: var(--color-text-heading, inherit); }
.cell-num, .mono { font-family: var(--font-mono, ui-monospace, monospace); font-variant-numeric: tabular-nums; }
/* Getallen lijnen op plaatswaarde ook zonder mono-font (canon §2/§5: tabulaire cijfers). */
.data-table td.cell-num, .data-table th.th-num { font-variant-numeric: tabular-nums; }
.row-clickable { cursor: pointer; }
.row-clickable:focus-visible { outline: 2px solid var(--color-primary, #3a7ca5); outline-offset: -2px; }
/* Actie-kolom: krimp tot inhoud (width:1% → alle slack naar de data-kolommen) MAAR de knoppen
   zélf mogen NIET krimpen (flex:0 0 auto). Zonder dat laat de flex de knoppen inkrimpen, valt de
   min-content van de cel weg en knijpt de tabel de knop-cel dood → knop puilt over de laatste
   tekst-cel (de overlap-bug, erger bij veel kolommen). */
.data-table th.th-actions, .data-table td.cell-actions { width: 1%; text-align: right; white-space: nowrap; min-width: max-content; }
/* De knoppen zeggen zelf wat ze doen: "ACTIES" als kop is ruis. Onzichtbaar, maar een schermlezer
   leest de kolomnaam nog (ook in oudere artefacten, die de tekst letterlijk dragen). */
.data-table th.th-actions { font-size: 0; }
/* Een design-systeem mag niet aannemen dat de LAATSTE kolom de actiekolom is (`td:last-child
   { text-align: right }`): een lijst met één kolom zette z'n namen dan rechts (Bestaande rollen,
   23-09). Uitlijning volgt de soort cel — acties en getallen rechts, de rest links. */
.data-table td:last-child:not(.cell-actions):not(.cell-num),
.data-table th:last-child:not(.th-actions):not(.th-num) { text-align: left; width: auto; white-space: normal; }
/* De kop "Acties" is er voor de schermlezer, niet voor het oog (font-size 0 hierboven). Transparant,
   niet muted: axe meet onzichtbare tekst anders gewoon op contrast (3,2:1 in rogers-legacy, 24-09). */
.data-table th.th-actions { color: transparent; }
.row-actions { display: inline-flex; flex-wrap: nowrap; gap: var(--space-2, .5rem); align-items: center; justify-content: flex-end; }
.row-actions .btn { flex: 0 0 auto; white-space: nowrap; }
.btn.has-menu { display: inline-flex; align-items: center; gap: .35rem; }
.btn.has-menu .menu-caret { display: inline-flex; opacity: .6; }
.btn.has-menu .menu-caret svg { width: 13px; height: 13px; }
/* Rij-actie-chooser (DETAIL-hub) — klein, rustig kaartje; canon §9 (restraint) + §1 (spacing). */
.row-menu {
  position: absolute; z-index: 80; min-width: 180px; padding: var(--space-1, .25rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 10px); box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.16));
  display: flex; flex-direction: column; gap: 1px;
}
.row-menu-item {
  appearance: none; border: 0; background: none; text-align: left; cursor: pointer;
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-sm, 7px);
  font: inherit; color: var(--color-text, #1c2530); white-space: nowrap;
}
.row-menu-item:hover, .row-menu-item:focus-visible { background: var(--color-bg-surface-hover, #f2f5f9); outline: none; }
/* ── Status: te ZIEN, niet te lezen ────────────────────────────────────────
   Een statuskolom waarin elke waarde dezelfde kleur heeft, is een kolom die je moet lezen. De
   renderer kent de woorden van een project niet, maar wél de FAMILIE waartoe een status hoort —
   `statusToon()` (app.js) normaliseert de waarde naar `data-toon="ok|wacht|stop|neutraal"`. Zo
   krijgt élk project meteen betekenis, en blijft `data-v` beschikbaar voor de bespoke-laag die
   één specifieke waarde wil bijkleuren. Onbekend → neutraal; nooit een verzonnen kleur. */
.status-tag {
  display: inline-flex; align-items: center; gap: .4em;
  padding: 2px var(--space-2, .5rem); border-radius: var(--radius-sm, 6px);
  font-size: var(--text-xs, .75rem); font-weight: 600;
  background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666);
}
/* Het stipje draagt de kleur; de tekst blijft leesbaar zwart-op-licht (contrast > kleurcode —
   WCAG 1.4.1: kleur mag nooit de enige drager zijn, dus het WOORD blijft de bron van waarheid). */
.status-tag::before {
  content: ''; width: .5em; height: .5em; border-radius: 50%; flex: 0 0 auto;
  background: var(--color-text-muted, #6b7684);
}
/* De familie-kleur bepaalt de TINT, niet de leesbaarheid: het vlak is een lichte menging met de
   ondergrond, de tekst een menging met de TEKSTKLEUR van het palet. Dat laatste is het verschil
   tussen een formule die alleen in lichte thema's werkt en één die overal werkt: op een licht palet
   mengt 'ie naar donker, op een donker palet naar licht — precies wat leesbaarheid vraagt. */
.status-tag[data-toon="ok"] {
  background: color-mix(in srgb, var(--color-success, #2e7d47) 14%, var(--color-bg-surface, #fff));
  color: color-mix(in srgb, var(--color-success, #2e7d47) 42%, var(--color-text, #1a2230));
}
.status-tag[data-toon="ok"]::before { background: var(--color-success, #2e7d47); }
.status-tag[data-toon="wacht"] {
  background: color-mix(in srgb, var(--color-warning, #b8791a) 14%, var(--color-bg-surface, #fff));
  color: color-mix(in srgb, var(--color-warning, #b8791a) 38%, var(--color-text, #1a2230));
}
.status-tag[data-toon="wacht"]::before { background: var(--color-warning, #b8791a); }
.status-tag[data-toon="stop"] {
  background: color-mix(in srgb, var(--color-error, #c0392b) 12%, var(--color-bg-surface, #fff));
  color: color-mix(in srgb, var(--color-error, #c0392b) 42%, var(--color-text, #1a2230));
}
.status-tag[data-toon="stop"]::before { background: var(--color-error, #c0392b); }
.pill { display: inline-block; padding: 2px var(--space-2, .5rem); border-radius: var(--radius-pill, 999px); font-size: var(--text-xs, .75rem); font-weight: 600; }
.pill-on { background: var(--color-success-bg, #e6f6ec); color: var(--color-success, #2e7d47); }
.pill-off { background: var(--color-bg-muted, #eef2f7); color: var(--color-text-muted, #6b7684); }

/* ── Buttons (val terug op DS .btn als aanwezig, anders eigen) ───────────── */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2, .5rem); cursor: pointer;
  padding: var(--space-2, .5rem) var(--space-4, 1rem); border-radius: var(--radius-md, 10px);
  font-size: var(--text-sm, .875rem); font-weight: 600; border: 1px solid transparent; font-family: inherit;
  text-decoration: none; line-height: 1;
}
.btn-sm { padding: 4px var(--space-3, .75rem); font-size: var(--text-xs, .8rem); }
.btn-primary { background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); }
.btn-primary:hover { background: var(--color-primary-bright, var(--color-primary, #2f6a8e)); }
.btn-secondary { background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230); border-color: var(--color-border, #dfe4ec); }
.btn-secondary:hover { border-color: var(--color-border-strong, #c2cad6); }
/* Rij-actie: stil van zichzelf. Binnen een rij bestaat geen primaire knop — `intent` stuurt
   alléén de tekstkleur, nooit een vlak. Zo blijft de zwaarste vorm op het scherm gereserveerd voor
   de ENE scherm-actie bovenaan, en verdwijnt de knoppenmuur uit de tabel. (canon §3) */
/* STIL, maar niet onzichtbaar. Een rij-actie mag nooit de zwaarste knop op het scherm zijn (dat
   is de scherm-actie bovenaan), maar zónder rand las "Afmelden" als gewone tekst aan de
   rechterrand — je kon niet zien dat het een knop was (gebruiker, 21-09). Een dunne rand op het
   oppervlak is genoeg affordance en houdt de hiërarchie intact. */
.btn-row {
  background: var(--color-bg-surface, #fff);
  border-color: var(--color-border, #dfe4ec);
  font-weight: 500;
  color: var(--color-text-secondary, #4a5666);
}
/* Een destructieve knop in een knoppenrij: stil van gewicht, duidelijk van kleur. Nooit gevuld —
   dan zou de zwaarste knop op het scherm de handeling zijn die je zelden wilt. */
.btn.is-danger { color: var(--color-danger, var(--color-error, #b3261e));
  border-color: var(--color-danger-soft, var(--color-error-bg, #f3c9c6)); background: var(--color-bg-surface, #fff); }
.btn.is-danger:hover { background: var(--color-danger-soft, var(--color-error-bg, #fdecec));
  border-color: var(--color-danger, var(--color-error, #b3261e)); }
.btn-row:hover { background: var(--color-bg-muted, #eef2f7); color: var(--color-text, #1a2230);
  border-color: var(--color-border-strong, #c2cad6); }
.btn-row:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 1px; }
.btn-row.is-accent { color: var(--mock-primary-ink, #3a7ca5); }
.btn-row.is-accent:hover { background: var(--color-primary-soft, var(--color-bg-muted, #eef2f7)); color: var(--mock-primary-ink, #3a7ca5); }
.btn-row.is-danger { color: var(--color-danger, var(--color-error, #b3261e)); }
.btn-row.is-danger:hover { background: var(--color-danger-soft, var(--color-error-bg, #fdecec)); color: var(--color-danger, var(--color-error, #b3261e)); }
/* De ⋯-overloop: even stil, maar altijd even breed zodat de actie-kolom niet per rij verspringt. */
.row-actions .btn-row.has-menu { min-width: 2rem; justify-content: center; letter-spacing: .08em; }
.row-menu-item.is-accent { color: var(--mock-primary-ink, #3a7ca5); }
.row-menu-item.is-danger { color: var(--color-danger, var(--color-error, #b3261e)); }
.row-menu-item.is-danger:hover, .row-menu-item.is-danger:focus-visible { background: var(--color-danger-soft, var(--color-error-bg, #fdecec)); }
.btn-ghost { background: none; color: var(--color-text-muted, #6b7684); padding: 4px; }
.btn-ghost:hover { color: var(--mock-primary-ink, #3a7ca5); }
.btn-ico svg, .btn-ghost svg { width: 16px; height: 16px; }

/* Refresh-icoon bij een `reload`-mode stateview-component (lijst/detail) — subtiel, huisstijl
   (leunt op .btn-ghost: muted → hover primary). Spint kort tijdens het her-fetchen. */
.vh-actions, .head-actions { display: inline-flex; align-items: center; gap: var(--space-2, .5rem); }
.refresh-btn svg { width: 16px; height: 16px; display: block; }
.refresh-btn.is-spinning svg { animation: refresh-spin .6s linear infinite; transform-origin: 50% 50%; }
@keyframes refresh-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .refresh-btn.is-spinning svg { animation: none; } }

/* ── Toestanden: leeg · gefilterd-leeg · ladend · mislukt ──────────────────
   Een scherm dat alleen in de gelukkige toestand klopt, is niet af. Vier vormen, één huis: een
   ladende lijst toont de VORM die komt (skeleton, geen spinner), een lege lijst toont wat je kunt
   doen, een leeg filter zegt dat het aan het filter ligt, en een mislukte fetch geeft het toe. */
.state-actions { display: flex; gap: var(--space-2, .5rem); justify-content: center; margin-top: var(--space-4, 1rem); flex-wrap: wrap; }
.empty-state.is-error p { color: var(--color-error, #a4231c); }
/* Skeleton: dezelfde rijhoogte als de echte tabel, zodat er niets verspringt zodra de data er is. */
.skeleton-table { padding: var(--space-2, .5rem) 0; }
.skeleton-row {
  display: flex; gap: var(--space-4, 1rem); align-items: center;
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-bottom: 1px solid var(--color-border-subtle, #eef1f6);
}
.skeleton-row:last-child { border-bottom: none; }
.skeleton-cell {
  height: .75rem; border-radius: var(--radius-sm, 6px); flex: 1 1 auto;
  background: linear-gradient(90deg,
    var(--color-bg-muted, #eef2f7) 0%, var(--color-bg-subtle, #f6f8fb) 50%, var(--color-bg-muted, #eef2f7) 100%);
  background-size: 200% 100%; animation: skel 1.2s ease-in-out infinite;
}
.skeleton-cell.is-kort { flex: 0 0 18%; }
@keyframes skel { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton-cell { animation: none; } }

/* ── De bodem ──────────────────────────────────────────────────────────────
   Zonder footer houdt een pagina onder de tabel gewoon op — dat leest als een half geladen scherm.
   Stil, informatief, geen decoratie: waar je bent, met welke rol je kijkt, en de weg terug. */
.app-footer {
  color: var(--mock-muted);
  margin-top: var(--space-16, 4rem); padding: var(--space-5, 1.25rem) 0 var(--space-8, 2rem);
  border-top: 1px solid var(--color-border-subtle, #eef1f6);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2, .5rem) var(--space-4, 1rem);
  font-size: var(--text-xs, .75rem); color: var(--mock-muted);
}
.app-footer .af-brand { font-weight: 600; color: var(--color-text-secondary, #4a5666); }
.app-footer .af-sep { opacity: .5; }
.app-footer a { color: var(--color-text-secondary, #4a5666); text-decoration: none; }
.app-footer a:hover { color: var(--mock-primary-ink, #3a7ca5); text-decoration: underline; }

/* Een verrijkt component zonder eigen kop: alleen de ververs-knop, rechts. */
.view-head.is-alleen-actie { justify-content: flex-end; margin-bottom: var(--space-2, .5rem); }

/* ── Empty state ────────────────────────────────────────────────────────── */
.empty-state { text-align: center; padding: var(--space-8, 2rem) var(--space-4, 1rem); color: var(--color-text-muted, #6b7684); }
/* Design-systemen geven lopende tekst een leesbreedte (`p { max-width }`). In een gecentreerd blok
   plakt die alinea dan links; auto-marges houden 'm in het midden. */
.empty-state p { max-width: 44ch; margin-left: auto; margin-right: auto; }
.empty-state .state-actions { display: flex; justify-content: center; gap: var(--space-2, .5rem); margin-top: var(--space-4, 1rem); }
.muted { color: var(--color-text-muted, #6b7684); }

/* ── Breadcrumb ─────────────────────────────────────────────────────────── */
.crumbs { display: flex; align-items: center; gap: var(--space-2, .5rem); flex-wrap: wrap; font-size: var(--text-sm, .875rem); }
.crumb {
  display: inline-flex; align-items: center; gap: 4px; border: none; background: none; cursor: pointer;
  color: var(--mock-primary-ink, #3a7ca5); font-weight: 600; padding: 2px 4px; font-family: inherit; font-size: inherit;
}
.crumb:hover { text-decoration: underline; }
.crumb-glyph svg { width: 15px; height: 15px; }
.crumb-sep { color: var(--color-text-muted, #b3bcc9); }
.crumb.is-current { color: var(--color-text-heading, inherit); font-weight: 700; }

/* ── Formulieren-hub ────────────────────────────────────────────────────── */
.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--space-3, .75rem); }
.form-card {
  display: flex; align-items: center; gap: var(--space-3, .75rem); text-align: left; cursor: pointer;
  padding: var(--space-4, 1rem); border-radius: var(--radius-lg, 12px);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec); font-family: inherit;
}
.form-card:hover { border-color: var(--color-primary, #3a7ca5); box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,.06)); }
.fc-glyph { display: grid; place-items: center; width: 36px; height: 36px; flex: 0 0 auto; border-radius: var(--radius-md, 10px); background: var(--color-primary-soft, #e3eef5); color: var(--mock-primary-ink, #3a7ca5); }
.fc-glyph svg { width: 18px; height: 18px; }
.fc-body { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.fc-title { font-weight: 600; color: var(--color-text-heading, inherit); }
.fc-sub { font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684); }
.fc-go { color: var(--color-text-muted, #b3bcc9); display: inline-flex; }
.fc-go svg { width: 18px; height: 18px; }

/* ── Drawer ─────────────────────────────────────────────────────────────── */
.scrim { position: fixed; inset: 0; background: rgba(15, 23, 35, .45); opacity: 0; visibility: hidden; transition: opacity .2s ease; z-index: 40; }
.scrim.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed; top: 0; right: 0; height: 100%; width: min(440px, 100%); z-index: 50;
  background: var(--color-bg-surface, #fff); box-shadow: var(--shadow-xl, -8px 0 30px rgba(0,0,0,.18));
  display: flex; flex-direction: column; transform: translateX(100%); transition: transform .24s ease;
}
.drawer.open { transform: translateX(0); }
/* Dicht = weg. Buiten beeld geschoven viel de schaduw (−8px, 30px blur) nog als grijze strook langs
   de rechterrand van élke mock-pagina, en de knoppen erin waren met Tab bereikbaar. */
.drawer:not(.open) { box-shadow: none; visibility: hidden; transition: transform .24s ease, visibility 0s linear .24s; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3, .75rem); padding: var(--space-5, 1.25rem) var(--space-6, 1.5rem); border-bottom: 1px solid var(--color-border, #dfe4ec); }
.dh-title { display: flex; align-items: center; gap: var(--space-3, .75rem); }
.dh-title h3 { margin: 0; font-family: var(--font-heading, inherit); font-size: var(--text-lg, 1.125rem); }
.dh-glyph { display: grid; place-items: center; width: 34px; height: 34px; border-radius: var(--radius-md, 10px); background: var(--color-primary-soft, #e3eef5); color: var(--mock-primary-ink, #3a7ca5); }
.dh-glyph svg { width: 18px; height: 18px; }
.drawer-close { border: none; background: none; cursor: pointer; color: var(--color-text-muted, #6b7684); padding: 4px; display: inline-flex; }
.drawer-close svg { width: 20px; height: 20px; }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--space-6, 1.5rem); }

/* Read-only detail-inzage (openDetail) */
.detail-list { display: flex; flex-direction: column; gap: 0; }
.detail-row {
  display: grid; grid-template-columns: minmax(7rem, 34%) 1fr; gap: var(--space-4, 1rem);
  padding: var(--space-3, .75rem) 0; border-bottom: 1px solid var(--color-border, #eef1f6);
}
.detail-row:last-child { border-bottom: none; }
/* Eén waarde is een getalkaart, geen formulier-regel: het getal groot, het label eronder. Stond
   als "Huidig tegoed (minuten)" links en "320" ver rechts — het belangrijkste getal van de app
   las als een voetnoot (23-09). */
.detail-list:has(> .detail-row:only-child) > .detail-row {
  display: flex; flex-direction: column-reverse; align-items: flex-start; gap: var(--space-1, .25rem);
  padding: var(--space-2, .5rem) 0 0;
}
.detail-list:has(> .detail-row:only-child) > .detail-row dd {
  font-size: calc(var(--text-2xl, 1.5rem) * 1.6); line-height: 1.1; font-weight: 650;
  font-variant-numeric: tabular-nums;
}
.detail-list:has(> .detail-row:only-child) > .detail-row dt {
  font-size: var(--text-xs, .75rem); text-transform: uppercase; letter-spacing: .04em;
}
.detail-list:has(> .detail-row:only-child) > .detail-row > * { text-align: left; align-self: flex-start; }
.detail-row dt { color: var(--color-text-muted, #6b7684); font-size: var(--text-xs, .75rem); font-weight: 700; letter-spacing: .01em; align-self: center; overflow-wrap: anywhere; }
.detail-row dd { margin: 0; color: var(--color-text-heading, inherit); font-weight: 500; overflow-wrap: anywhere; }
.detail-row dd.mono { font-family: var(--font-mono, ui-monospace, monospace); }
/* Een record-lijst in een detail (`deelnemers: List<Deelnemer>`): het label erboven en de tabel over
   de volle breedte, want naast een label van 34% is een tabel met drie kolommen onleesbaar smal. Op
   een telefoon scrolt alleen de tabel horizontaal, niet de pagina. */
.detail-row:has(.detail-tabel-wrap, .detail-tabel-leeg) { grid-template-columns: minmax(0, 1fr); gap: var(--space-2, .5rem); }
.detail-row:has(.detail-tabel-wrap) dd { min-width: 0; }
.detail-row:has(.detail-tabel-wrap) dt { align-self: start; }
.detail-tabel-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.detail-tabel { width: 100%; border-collapse: collapse; font-size: var(--text-sm, .875rem); font-weight: 400; }
.detail-tabel th {
  text-align: left; padding: var(--space-2, .5rem) var(--space-3, .75rem);
  color: var(--color-text-muted, #6b7684); font-size: var(--text-xs, .75rem); font-weight: 700;
  background: var(--color-bg-subtle, #f6f8fb); border-bottom: 1px solid var(--color-border, #dfe4ec); white-space: nowrap;
}
.detail-tabel td {
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-bottom: 1px solid var(--color-border-subtle, #eef1f6);
  color: var(--color-text, inherit); white-space: nowrap;
}
.detail-tabel tbody tr:last-child td { border-bottom: none; }
.detail-tabel-leeg { color: var(--color-text-muted, #6b7684); font-weight: 400; font-style: italic; }
.detail-kids { margin-top: var(--space-5, 1.25rem); padding: var(--space-3, .75rem) var(--space-4, 1rem); border-radius: var(--radius-md, 10px); background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666); font-size: var(--text-sm, .875rem); }
.drawer-foot { display: flex; justify-content: flex-end; gap: var(--space-2, .5rem); padding: var(--space-5, 1.25rem) var(--space-6, 1.5rem); border-top: 1px solid var(--color-border, #dfe4ec); }

/* ── Bevestig-dialoog (design-systeem modal, gecentreerd) ──────────────────── */
.confirm-overlay { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  padding: var(--space-4, 1rem); background: rgba(15, 23, 35, .5); opacity: 0; transition: opacity .16s ease; }
.confirm-overlay.open { opacity: 1; }
.confirm-modal { width: 100%; max-width: 420px; background: var(--color-bg-surface, #fff);
  border-radius: var(--radius-lg, 14px); box-shadow: var(--shadow-lg, 0 20px 50px rgba(15, 23, 35, .25)); overflow: hidden;
  transform: translateY(8px) scale(.98); opacity: 0; transition: transform .18s ease, opacity .18s ease; }
.confirm-overlay.open .confirm-modal { transform: none; opacity: 1; }
.confirm-body { display: flex; gap: var(--space-4, 1rem); padding: var(--space-6, 1.5rem) var(--space-6, 1.5rem) var(--space-5, 1.25rem); }
/* Een vraag zonder uitleg-regel: compact, de kop is de hele boodschap. */
.confirm-body.is-vraag { padding-bottom: var(--space-4, 1rem); }
.confirm-body.is-vraag .confirm-title { margin: 0; }
.confirm-ico { flex: none; width: 40px; height: 40px; border-radius: var(--radius-pill, 999px);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-error-soft, #fdecea); color: var(--color-error, #c0392b); }
.confirm-ico.is-neutral { background: var(--color-primary-soft, #e3eef5); color: var(--mock-primary-ink, #3a7ca5); }
.confirm-ico svg { width: 22px; height: 22px; }
.confirm-text { flex: 1; min-width: 0; }
.confirm-title { margin: 2px 0 var(--space-2, .5rem); font-family: var(--font-heading, inherit);
  font-size: var(--text-lg, 1.125rem); font-weight: 700; color: var(--color-text-heading, #1a2230); }
.confirm-msg { margin: 0; font-size: var(--text-sm, .9rem); line-height: 1.5; color: var(--color-text-secondary, #4a5666); }
.confirm-foot { display: flex; justify-content: flex-end; gap: var(--space-2, .5rem);
  padding: var(--space-4, 1rem) var(--space-6, 1.5rem) var(--space-6, 1.5rem); }
.btn-danger { background: var(--color-error, #c0392b); color: #fff; border-color: var(--color-error, #c0392b); }
.btn-danger:hover { filter: brightness(.94); }
@media (prefers-reduced-motion: reduce) {
  .confirm-overlay, .confirm-modal { transition: none; }
  .confirm-overlay .confirm-modal { transform: none; }
}

.form-wrapper { display: flex; flex-direction: column; gap: var(--space-4, 1rem); }
/* Empty-state van een 0-of-1 singleton-DETAIL_FORM: de melding staat bovenaan, de form-velden
 * blijven zichtbaar maar uitgegrijsd/disabled tot de bron een record heeft. */
.form-wrapper.is-empty-singleton .form-group { opacity: .55; }
.form-wrapper.is-empty-singleton :is(input, select, textarea):disabled { cursor: not-allowed; background: var(--color-bg-muted, #f4f6f9); }
.form-group { display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.form-label { font-size: var(--text-sm, .875rem); font-weight: 600; color: var(--color-text-secondary, #4a5666); text-transform: none; letter-spacing: normal; }
.form-control {
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-md, 10px);
  border: 1px solid var(--color-border, #dfe4ec); background: var(--color-bg, #fff); color: inherit;
  font-family: inherit; font-size: var(--text-sm, .875rem);
}
.form-control:focus { outline: none; border-color: var(--color-border-focus, var(--color-primary, #3a7ca5)); box-shadow: 0 0 0 3px var(--color-primary-glow, rgba(58,124,165,.15)); }
.checkbox-set { display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.checkbox-item { display: flex; align-items: center; gap: var(--space-2, .5rem); font-size: var(--text-sm, .875rem); cursor: pointer; }
/* Foutmelding bij een veld — ONDER het veld, en hij blijft staan tot je 'm oplost.
   Waarom niet (alleen) een toast: die verdwijnt na 2,6s en staat ver van de handeling. NN/g +
   Baymard: inline, aangrenzend, persistent. WCAG 3.3.1 eist de fout IN TEKST (een shake + rode
   rand is geen tekst) en 1.4.1 verbiedt kleur als enige drager — vandaar het glyph én de tekst.
   Het veld verwijst ernaar met aria-describedby (ARIA21/G85), dus een schermlezer leest 'm
   voor bij focus. Kleur = de bestaande --color-error-token, geen nieuwe. */
.field-error { display: flex; align-items: flex-start; gap: var(--space-2, .5rem);
  font-size: var(--text-xs, .8125rem); color: var(--color-error, #c0392b); }
.field-error::before { content: "!"; flex: none; width: 14px; height: 14px; border-radius: 50%;
  background: var(--color-error, #c0392b); color: #fff; font-size: 10px; font-weight: 700;
  line-height: 14px; text-align: center; }
.form-control[aria-invalid="true"] { border-color: var(--color-error, #c0392b); }
.form-control[aria-invalid="true"]:focus { border-color: var(--color-error, #c0392b);
  box-shadow: 0 0 0 3px var(--color-error-glow, rgba(192,57,43,.15)); }
/* Globale melding (server-/domeinfout) — ONDER het formulier, bij de knop waar je drukte.
   role=alert + aria-live: WCAG 4.1.3 wil een statusmelding programmatisch bereikbaar hebben
   zónder dat 'ie focus steelt. */
.form-alert { display: flex; align-items: flex-start; gap: var(--space-2, .5rem);
  padding: var(--space-3, .75rem); border-radius: var(--radius-md, 10px);
  border: 1px solid var(--color-error, #c0392b);
  background: var(--color-error-bg, rgba(192,57,43,.06));
  color: var(--color-error, #c0392b); font-size: var(--text-sm, .875rem); }
.form-alert::before { content: "!"; flex: none; width: 16px; height: 16px; border-radius: 50%;
  background: var(--color-error, #c0392b); color: #fff; font-size: 11px; font-weight: 700;
  line-height: 16px; text-align: center; }
/* ── Wachtwoord: eisen + live voortgang ──────────────────────────────────────
   De eisen staan er vóórdat je typt (NN/g: vertel de regel, straf 'm niet af) en vinken live af.
   Kleur draagt niets alleen: elke regel heeft een ✓/○-glyph én tekst (WCAG 1.4.1), en het verschil
   tussen "voldaan" en "nog niet" zit óók in gewicht en glyph. Alle waarden komen uit de project-
   tokens met een neutrale fallback, zodat dit meekleurt met elk design-systeem. */
.pw-row { display: flex; align-items: stretch; gap: var(--space-2, .5rem); }
.pw-row .form-control { flex: 1 1 auto; min-width: 0; }
.pw-toggle { flex: none; padding: 0 var(--space-3, .75rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px);
  background: var(--color-bg-surface, #fff); color: var(--color-text-muted, #5a6472);
  font-size: var(--text-xs, .8125rem); font-weight: 600; cursor: pointer; }
.pw-toggle:hover { color: var(--color-text, #1e2430); border-color: var(--color-text-muted, #5a6472); }
.pw-toggle:focus-visible { outline: 2px solid var(--color-primary, #3a7ca5); outline-offset: 2px; }
.pw-affordance { margin-top: var(--space-2, .5rem); }
.pw-rules { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 2px var(--space-3, .75rem); }
.pw-rule { display: flex; align-items: center; gap: var(--space-2, .5rem);
  font-size: var(--text-xs, .8125rem); color: var(--color-text-muted, #5a6472); }
.pw-rule-mark { flex: none; width: 1rem; text-align: center; font-weight: 700; }
.pw-rule.is-met { color: var(--color-success, #1f6440); font-weight: 600; }
/* Alleen de overgang naar "voldaan" is een kleine bevestiging — geen beweging bij elke toets. */
.pw-rule.is-met .pw-rule-mark { animation: pw-tick .18s ease-out; }
@keyframes pw-tick { from { transform: scale(.6); opacity: .4; } to { transform: scale(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pw-rule.is-met .pw-rule-mark { animation: none; } }
.pw-status { margin: var(--space-2, .5rem) 0 0; min-height: 1em;
  font-size: var(--text-xs, .8125rem); color: var(--color-text-muted, #5a6472); }

/* Geslaagde registratie — dezelfde vorm als .form-alert, maar bevestigend. */
.form-success { display: flex; align-items: flex-start; gap: var(--space-3, .75rem);
  padding: var(--space-4, 1rem); border-radius: var(--radius-md, 10px);
  border: 1px solid var(--color-success, #1f6440);
  background: var(--color-success-bg, rgba(31,100,64,.07));
  color: var(--color-success, #1f6440); font-size: var(--text-sm, .875rem); }
.form-success p { margin: 0; }
.form-success-mark { flex: none; width: 20px; height: 20px; border-radius: 50%;
  background: var(--color-success, #1f6440); color: #fff; font-size: 12px; font-weight: 700;
  line-height: 20px; text-align: center; }

.shake { animation: shake .35s ease; }
@media (prefers-reduced-motion: reduce) { .shake { animation: none; } }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }

/* ── Toast ──────────────────────────────────────────────────────────────── */
.toast-stack { position: fixed; bottom: var(--space-6, 1.5rem); left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; gap: var(--space-2, .5rem); z-index: 60; }
.toast {
  display: flex; align-items: center; gap: var(--space-2, .5rem); padding: var(--space-3, .75rem) var(--space-4, 1rem);
  background: var(--mock-toast-bg, #1a2230); color: #fff; border-radius: var(--radius-md, 10px);
  box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,.2)); font-size: var(--text-sm, .875rem);
  animation: toast-in .2s ease; max-width: 90vw;
}
.toast.is-error { background: var(--color-error, #c0392b); }
.toast.leaving { opacity: 0; transform: translateY(8px); transition: opacity .2s ease, transform .2s ease; }
.t-glyph { display: inline-flex; font-weight: 700; }
.t-glyph svg { width: 16px; height: 16px; }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* ── CMS-laag — vrije mensenlaag-blokken (tekst + beeld), tussen de model-widgets ─
   Redactionele content, geen data-widget: rustig, leesbaar, leunt op de DS-tokens.
   Zichtbaar in app- én model-weergave (het is product-content, geen build-chrome). */
.cms-block { margin-bottom: var(--space-5, 1.25rem); max-width: 72ch; }
.cms-block:last-child { margin-bottom: 0; }
.cms-richtext {
  color: var(--color-text-secondary, #4a5666);
  font-size: var(--text-base, 1rem); line-height: var(--leading-relaxed, 1.65);
}
.cms-richtext > :first-child { margin-top: 0; }
.cms-richtext > :last-child { margin-bottom: 0; }
.cms-richtext h1, .cms-richtext h2, .cms-richtext h3 {
  font-family: var(--font-heading, inherit); color: var(--color-text-heading, #1a2230);
  line-height: var(--leading-snug, 1.3); margin: var(--space-4, 1rem) 0 var(--space-2, .5rem);
}
.cms-richtext h2 { font-size: var(--text-xl, 1.25rem); }
.cms-richtext h3 { font-size: var(--text-lg, 1.125rem); }
.cms-richtext p { margin: 0 0 var(--space-3, .75rem); }
.cms-richtext a { color: var(--mock-primary-ink, #3a7ca5); }
.cms-richtext ul, .cms-richtext ol { margin: 0 0 var(--space-3, .75rem); padding-left: 1.4em; }
.cms-richtext strong { color: var(--color-text, #1a2230); }
/* Een "callout"-variant: wikkel content in <div class="cms-note"> voor een intro-kaartje. */
.cms-richtext .cms-note, .cms-block.cms-note {
  background: var(--color-bg-muted, #eef2f7); border: 1px solid var(--color-border, #dfe4ec);
  border-left: 3px solid var(--color-primary, #3a7ca5);
  border-radius: var(--radius-md, 10px); padding: var(--space-4, 1rem) var(--space-5, 1.25rem);
}
.cms-image { margin: 0 0 var(--space-5, 1.25rem); }
.cms-image img {
  display: block; max-width: 100%; height: auto;
  border-radius: var(--radius-md, 10px); border: 1px solid var(--color-border, #dfe4ec);
}
.cms-image figcaption {
  margin-top: var(--space-2, .5rem); font-size: var(--text-xs, .75rem);
  color: var(--color-text-muted, #6b7684);
}

/* ── In-mock content-editor (page-builder-chrome) ───────────────────────────
   Alleen zichtbaar in bewerk-modus (body.cms-editing) — de editor-geserveerde mock. */
.cms-zone { display: flex; flex-direction: column; }
.cms-edit-toggle.is-on { background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); border-color: transparent; }
.cms-edit-toggle.is-on .mt-dot { background: #fff; }

/* Bewerkbaar blok: omlijst, met een zwevende toolbar erboven. */
.cms-edit-wrap {
  position: relative; margin-bottom: var(--space-5, 1.25rem);
  border: 1px dashed var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px);
  padding: var(--space-4, 1rem); transition: border-color .15s ease;
}
.cms-edit-wrap:hover, .cms-edit-wrap:focus-within { border-color: var(--color-primary, #3a7ca5); }
.cms-edit-wrap > .cms-block { margin-bottom: 0; }
.cms-tb {
  position: absolute; top: -14px; right: var(--space-3, .75rem);
  display: flex; align-items: center; gap: 2px; padding: 2px;
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-pill, 999px); box-shadow: var(--shadow-md, 0 4px 12px rgba(0,0,0,.1));
  opacity: 0; transition: opacity .15s ease;
  /* Boven het blok zelf: een opmaak die het beeld over z'n hele plek spant (position:absolute),
     legde het anders óver de werkbalk en was de 🗑 onbereikbaar (28-09). */
  z-index: 5;
}
.cms-edit-wrap:hover .cms-tb, .cms-edit-wrap:focus-within .cms-tb { opacity: 1; }
/* In een zone van een opgemaakte pagina staat het blok vaak in een afgeronde lijst met
   overflow:hidden (een beeld-plek); boven de rand werd de werkbalk daar afgesneden. */
.cms-zone .cms-edit-wrap > .cms-tb { top: var(--space-2, .5rem); }
.cms-tb-btn {
  display: inline-flex; align-items: center; justify-content: center; min-width: 26px; height: 26px;
  padding: 0 .45rem; border: 0; background: transparent; border-radius: var(--radius-pill, 999px);
  cursor: pointer; font-size: var(--text-xs, .75rem); font-weight: 700; color: var(--color-text-secondary, #4a5666);
}
.cms-tb-btn:hover { background: var(--color-bg-muted, #eef2f7); }
.cms-tb-btn.is-b { font-family: Georgia, serif; }
.cms-tb-btn.cms-tb-tgt { font-weight: 600; color: var(--mock-primary-ink, #3a7ca5); }
.cms-tb-btn.cms-tb-del:hover { background: var(--color-error, #c0392b); color: #fff; }
.cms-tb-sep { width: 1px; height: 16px; background: var(--color-border, #dfe4ec); margin: 0 2px; }

/* Contenteditable: leeg-placeholder + focus-ring. */
.cms-editable:focus { outline: none; }
.cms-editable:empty::before { content: attr(data-ph); color: var(--color-text-muted, #6b7684); pointer-events: none; }
figcaption.cms-editable { min-height: 1.2em; }

/* Beeld-blok in bewerk-modus. */
.cms-img-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2, .5rem);
  padding: var(--space-6, 1.5rem); min-height: 120px; cursor: pointer; text-align: center;
  border: 1px dashed var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px);
  background: var(--color-bg-muted, #eef2f7); color: var(--color-text-muted, #6b7684); font-size: var(--text-sm, .875rem);
}
.cms-img-empty svg { width: 28px; height: 28px; opacity: .6; }
.cms-img-btn {
  display: inline-flex; align-items: center; gap: var(--space-2, .5rem); margin-top: var(--space-2, .5rem);
  padding: .35rem var(--space-3, .75rem); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 8px); background: var(--color-bg-surface, #fff); cursor: pointer;
  font-size: var(--text-xs, .75rem); font-weight: 600; color: var(--color-text-secondary, #4a5666);
}
.cms-img-btn:hover { background: var(--color-bg-surface-hover, #f7f9fc); }
.cms-img-btn svg { width: 14px; height: 14px; }

/* Add-balk: dashed strook met + Tekst / + Afbeelding. */
.cms-add {
  display: flex; gap: var(--space-2, .5rem); justify-content: center;
  margin-bottom: var(--space-5, 1.25rem); padding: var(--space-3, .75rem);
  border: 1px dashed var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px);
  background: var(--color-bg-muted, #eef2f7);
}
.cms-add-btn {
  display: inline-flex; align-items: center; gap: var(--space-1, .25rem);
  padding: .35rem var(--space-4, 1rem); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-pill, 999px); background: var(--color-bg-surface, #fff); cursor: pointer;
  font-size: var(--text-xs, .75rem); font-weight: 600; color: var(--color-text-secondary, #4a5666);
}
.cms-add-btn:hover { border-color: var(--color-primary, #3a7ca5); color: var(--mock-primary-ink, #3a7ca5); }
.cms-add-plus { display: inline-flex; } .cms-add-plus svg { width: 14px; height: 14px; }

/* ── Finetune-chat (refine-mock) ────────────────────────────────────────────
   Zwevend paneel rechtsonder; praat met de refine-mock-skill (headless). */
@keyframes mc-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.mc-msg { max-width: 85%; padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-md, 10px); font-size: var(--text-sm, .875rem); line-height: 1.5; white-space: pre-wrap; }
.mc-user { align-self: flex-end; background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); border-bottom-right-radius: 3px; }
.mc-assistant { align-self: flex-start; background: var(--color-bg-muted, #eef2f7); color: var(--color-text, #1a2230); border-bottom-left-radius: 3px; }
.mc-error { align-self: flex-start; background: var(--color-error, #c0392b); color: #fff; }
.mc-typing .mc-dots { letter-spacing: 2px; animation: mc-blink 1.2s infinite; }
@keyframes mc-blink { 0%,100% { opacity: .3; } 50% { opacity: 1; } }
.mc-input {
  flex: 1; resize: none; padding: var(--space-2, .5rem) var(--space-3, .75rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, 8px);
  font: inherit; font-size: var(--text-sm, .875rem); color: var(--color-text, #1a2230);
  background: var(--color-bg, #f6f8fb);
}
.mc-input:focus { outline: 2px solid var(--color-primary, #3a7ca5); outline-offset: -1px; }

@media (max-width: 640px) {
  .chapters { width: 100%; margin-left: 0; }
  .vh-title h1 { font-size: var(--text-xl, 1.25rem); }
}

/* Canon §9 / WCAG 2.3.3 — respecteer een verlaagd-motion-voorkeur: schakel niet-essentiële
   transities + animaties uit. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* ── "Bekijk als"-menu (productie-preview, editor-only) ─────────────────────
   Zwevend lijstje onder de knop; opent de pagina chrome-loos in een nieuw tabblad. */
.preview-menu {
  position: fixed; z-index: 95; top: 4.5rem; right: var(--space-6, 1.5rem);
  display: flex; flex-direction: column; min-width: 14rem;
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 10px); box-shadow: var(--shadow-md, 0 6px 20px rgba(0,0,0,.12));
  overflow: hidden;
}
.preview-menu[aria-hidden="true"] { display: none; }
.preview-item {
  padding: var(--space-2, .5rem) var(--space-4, 1rem); border: 0; background: none; text-align: left;
  font: inherit; font-size: var(--text-sm, .875rem); color: inherit; cursor: pointer;
}
.preview-item:hover, .preview-item:focus-visible { background: var(--color-bg-subtle, #f3f5f9); }

/* ══ PAGE-VIEW (F1) — landing/chrome + page-block layout ═══════════════════ */
.page-block.layout-stack { display: flex; flex-direction: column; gap: var(--space-5, 1.5rem); }
.page-block.layout-row { display: flex; gap: var(--space-4, 1rem); flex-wrap: wrap; }
.page-hero {
  display: grid; grid-template-columns: 1.1fr .9fr; gap: var(--space-6, 2rem); align-items: center;
  padding: clamp(1.5rem, 4vw, 3.5rem) var(--space-6, 2rem) var(--space-4, 1rem);
}
.page-hero-body h1 { font-size: clamp(2rem, 5vw, 3.2rem); line-height: 1.05; letter-spacing: -.02em; margin: 0 0 var(--space-3, .75rem); color: var(--color-text-heading, #1c2530); }
/* Lopende tekst → secondary, niet muted (zie de toelichting bij `.hub-tab`). */
.page-hero-sub { font-size: var(--text-lg, 1.125rem); line-height: 1.5; color: var(--color-text-secondary, #4a5666); max-width: 46ch; margin: 0; }
.page-hero-media { aspect-ratio: 4 / 3; border-radius: var(--radius-lg, 14px); display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--color-bg-surface-hover, #eef2f6), var(--color-border, #dfe4ec)); }
.ph-note { color: var(--color-text-muted, #94a1ad); font-size: var(--text-sm, .875rem); }
/* Losse CTA-knop in de landing-stack lijnt met de hero-padding uit. */
.page-block > a.btn { align-self: flex-start; margin: 0 var(--space-6, 2rem); }
/* Geen ruimte opzij: de kop lijnt uit met de schermen eronder, die staan ook tegen de kantlijn (08-10). */
.page-section { padding: var(--space-4, 1rem) 0 var(--space-6, 2rem); max-width: 72ch; }
.page-section h2 { font-size: var(--text-xl, 1.5rem); margin: 0 0 var(--space-2, .5rem); color: var(--color-text-heading, #1c2530); }
.page-section p { color: var(--color-text-secondary, #4a5666); margin: 0; line-height: 1.6; }
.page-chrome { padding: var(--space-3, .75rem) var(--space-6, 2rem); color: var(--color-text-muted, #6b7683); }
@media (max-width: 720px) { .page-hero { grid-template-columns: 1fr; } .page-hero-media { order: -1; } }

/* ══ LOGO (add-logo-skill) — header-beeldmerk (subtiel) + landing-banner (groter) ═══ */
.brand-mark.has-logo { background: none; color: inherit; width: auto; min-width: 40px; height: 40px; padding: 0; }
.brand-mark.has-logo svg { height: 100%; width: auto; display: block; }
.landing-logo-banner { display: flex; justify-content: center; padding: clamp(1rem, 3vw, 2.5rem) var(--space-6, 2rem) 0; }
.landing-logo-banner svg { max-width: min(420px, 62%); height: auto; }

/* ══ Composeerbare AI-landing — de wrapper om de vrije auteur-HTML. De auteur gebruikt DS-klassen
   (page-hero, page-section, …) die hierboven al gestyled zijn; dit geeft alleen de container-breedte
   + ademruimte en de slot-hooks een minimale plek. ═══ */
/* GEEN horizontale padding: deze wrapper zit ín `.app-shell`, en die levert de zijmarge al. Deed
   'ie het wél, dan kreeg de landing een dubbele goot en stond de hero-kaart 24px verder naar binnen
   dan het logo in de header — precies de scheve uitlijning die je op productie zag. */
.mock-landing-artifact { max-width: var(--container-max, 1180px); margin: 0 auto; padding: 0 0 var(--space-8, 3rem); }
.mock-landing-artifact .mock-landing-screen { margin: var(--space-6, 2rem) 0; }
.mock-landing-artifact .cms-zone { margin: var(--space-5, 1.5rem) 0; }
/* Een verrijkte vorm die z'n eigen kaart meebrengt (`.inline-form` in het artefact): de omhulling
   (`.form-wrapper`) tekent dan geen tweede kaart eromheen. Gaf een witte rand met 24px opvulling
   rond het profiel en het registratieformulier, en liet het paneel ernaast niet uitlijnen (10-06). */
.form-wrapper:has(> .inline-form) { padding: 0; border: 0; box-shadow: none; background: transparent; }

/* Detail met acties: het formulier verschijnt náást het detail (openPopup). */
.naast { display: grid; grid-template-columns: minmax(0, max-content) minmax(320px, 440px); gap: var(--space-6, 2rem);
  align-items: start; }
.naast-paneel { position: relative; position: sticky; top: var(--space-6, 2rem);
  animation: naast-in .16s ease-out; }
.naast-paneel .inline-form { position: relative; }
.naast-paneel .inline-form-title { padding-right: var(--space-8, 2.5rem); }
.naast-paneel .naast-sluit { position: absolute; top: var(--space-4, 1rem); right: var(--space-4, 1rem); z-index: 1; }
@keyframes naast-in { from { opacity: 0; transform: translateX(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .naast-paneel { animation: none; } }
/* Een landing-component zonder slot in de opmaak (bv. het registratieformulier): onder de opmaak, zelfde breedte. */
.mock-landing-los { max-width: var(--container-max, 1180px); margin: 0 auto; padding: 0 var(--space-4, 1rem) var(--space-8, 3rem); }
/* Een geplaatst-maar-niet-geslot component (fallback) lijnt LINKS uit met de tekstkolom
 * i.p.v. te centreren — anders "zweeft" een inline-form (max-width + margin:auto) rechts
 * naast de links-uitgelijnde tekst. */
.mock-landing-artifact .mock-landing-placed { margin: var(--space-6, 2rem) 0; }
.mock-landing-artifact .mock-landing-placed .inline-form { margin-left: 0; margin-right: auto; }
/* Bewerk-modus: een beeld in de landing is klikbaar om te vervangen. */
.mock-landing-artifact img.lp-img-editable { cursor: pointer; outline: 2px dashed transparent; outline-offset: 3px; transition: outline-color .12s; }
.mock-landing-artifact img.lp-img-editable:hover { outline-color: var(--color-primary, #2e7d47); }

/* ═══ RBAC — persona-login (§5b). CL-niveau: DS-tokens, heldere hiërarchie, toetsenbord + focus. ═══ */
/* Topbar: de ingelogde rol + uitloggen (of een inlog-knop). */
.persona-bar { display: inline-flex; align-items: center; gap: var(--space-3, .75rem);
  margin-left: auto; min-width: 0; flex-wrap: wrap; }
.persona-chip { display: inline-flex; align-items: center; gap: var(--space-2, .5rem);
  padding: var(--space-1, .25rem) var(--space-3, .75rem); border-radius: var(--radius-pill, 999px);
  background: var(--color-bg-muted, #eef1f4); color: var(--color-text-secondary, #4b5563);
  font-size: var(--text-sm, .875rem); font-weight: 600; white-space: nowrap; min-width: 0; }
/* De rollenlijst is de enige buigzame kant van de chip: met meerdere rollen (en zeker in de
   ontwerp-stand "alle rollen") groeide 'ie ongelimiteerd en duwde de héle header breder dan het
   scherm — waarna de telefoon de pagina uitzoomde in plaats van te stapelen. Gemeten 09-02:
   1288px chip → 1379px layout-viewport op een toestel van 390. Afkappen dus; de titel draagt
   de volledige tekst. */
.persona-roles { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.persona-dot { width: .5rem; height: .5rem; border-radius: 50%; background: var(--color-success, #16a34a);
  box-shadow: 0 0 0 3px var(--color-success-bg, rgba(22,163,74,.15)); flex: none; }
.persona-label { color: var(--color-text-secondary, #4a5666); font-weight: 500; }
.persona-name { color: var(--color-text-heading, #1a2230); }
.persona-login, .persona-logout { cursor: pointer; font-family: inherit; font-size: var(--text-sm, .875rem);
  font-weight: 600; border-radius: var(--radius-md, .5rem); padding: var(--space-2, .5rem) var(--space-3, .75rem);
  border: 1px solid var(--color-border, #d7dce2); background: var(--color-bg-surface, #fff);
  color: var(--color-text-secondary, #4b5563); transition: background .12s, border-color .12s, color .12s; }
.persona-login { border-color: transparent; background: var(--color-primary, #2e7d47); color: var(--color-text-on-primary, #fff);
  display: inline-flex; align-items: center; text-decoration: none; }
.persona-login:hover { background: var(--color-primary-bright, #2e7d47); }
.persona-logout:hover { background: var(--color-bg-surface-hover, #f4f6f8); border-color: var(--color-border-strong, #b6bdc7); color: var(--color-text, #1a2230); }
.persona-login:focus-visible, .persona-logout:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; }

/* Het accountmenu: je naam (de chip) is een knop; eronder je gegevens, je wachtwoord, en Uitloggen. */
.account-menu { position: relative; display: inline-flex; min-width: 0; }
.account-menu-knop { cursor: pointer; border: 1px solid transparent; font-family: inherit; }
.account-menu-knop:hover { border-color: var(--color-border, #d7dce2); }
.account-menu-knop:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; }
.account-menu-pijl { display: inline-flex; width: 1rem; height: 1rem; flex: none; transform: rotate(90deg);
  transition: transform .12s; color: var(--color-text-secondary, #4b5563); }
.account-menu-knop[aria-expanded="true"] .account-menu-pijl { transform: rotate(-90deg); }
.account-menu-lijst { position: absolute; right: 0; top: calc(100% + var(--space-2, .5rem)); z-index: 50;
  min-width: 14rem; max-width: calc(100vw - 2rem); padding: var(--space-1, .25rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #d7dce2);
  border-radius: var(--radius-md, .5rem); box-shadow: var(--shadow-md, 0 8px 24px rgba(16,24,40,.12));
  display: flex; flex-direction: column; }
.account-menu-lijst[hidden] { display: none; }
.account-menu-lijst .persona-logout-form { display: flex; }
.account-menu-item { display: block; width: 100%; text-align: left; cursor: pointer; font-family: inherit;
  font-size: var(--text-sm, .875rem); font-weight: 500; color: var(--color-text, #1a2230); text-decoration: none;
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border: 0; border-radius: var(--radius-sm, .375rem);
  background: transparent; min-height: 40px; }
.account-menu-item:hover, .account-menu-item:focus-visible { background: var(--color-bg-surface-hover, #f4f6f8); outline: none; }
.account-menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--color-border-focus, #2e7d47); }
.account-menu-scheiding { height: 1px; margin: var(--space-1, .25rem) 0; background: var(--color-border, #d7dce2); }

/* De login-poort: een gecentreerde kaart met rol-keuzes (multi-select) + de god-view-optie. */
.login-gate { display: flex; align-items: flex-start; justify-content: center;
  padding: var(--space-16, 4rem) var(--space-6, 2rem); min-height: 60vh; }
.login-card { width: 100%; max-width: 26rem; background: var(--color-bg-surface, #fff);
  border: 1px solid var(--color-border, #d7dce2); border-radius: var(--radius-lg, .875rem);
  box-shadow: var(--shadow-lg, 0 12px 32px rgba(20,30,45,.12)); padding: var(--space-8, 3rem) var(--space-6, 2rem);
  text-align: center; }
.login-brand { max-width: 8rem; margin: 0 auto var(--space-5, 1.5rem); }
.login-brand svg { max-width: 100%; height: auto; }
.login-title { font-family: var(--font-heading, inherit); font-size: var(--text-2xl, 1.5rem);
  color: var(--color-text-heading, #1a2230); margin: 0 0 var(--space-2, .5rem); }
.login-sub { font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684);
  line-height: var(--leading-relaxed, 1.6); margin: 0 0 var(--space-6, 2rem); }
.login-roles { display: flex; flex-direction: column; gap: var(--space-2, .5rem); margin-bottom: var(--space-5, 1.5rem); }
.login-role { display: flex; align-items: center; gap: var(--space-3, .75rem); width: 100%;
  padding: var(--space-3, .75rem) var(--space-4, 1rem); cursor: pointer; font-family: inherit;
  font-size: var(--text-base, 1rem); font-weight: 600; text-align: left;
  color: var(--color-text, #1a2230); background: var(--color-bg-surface, #fff);
  border: 1px solid var(--color-border, #d7dce2); border-radius: var(--radius-md, .5rem);
  transition: border-color .12s, background .12s, box-shadow .12s; }
.login-role:hover { border-color: var(--color-border-strong, #b6bdc7); background: var(--color-bg-surface-hover, #f4f6f8); }
.login-role:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; }
.login-role-check { display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 1.25rem; height: 1.25rem; border-radius: var(--radius-sm, .375rem); font-size: .75rem;
  color: transparent; border: 1.5px solid var(--color-border-strong, #b6bdc7); background: transparent; transition: all .12s; }
.login-role.on { border-color: var(--color-primary, #2e7d47); background: var(--color-primary-soft, rgba(46,125,71,.08)); box-shadow: 0 0 0 1px var(--color-primary, #2e7d47) inset; }
.login-role.on .login-role-check { color: var(--color-text-on-primary, #fff); background: var(--color-primary, #2e7d47); border-color: var(--color-primary, #2e7d47); }
.login-submit { width: 100%; padding: var(--space-3, .75rem); cursor: pointer; font-family: inherit;
  font-size: var(--text-base, 1rem); font-weight: 700; color: var(--color-text-on-primary, #fff);
  background: var(--color-primary, #2e7d47); border: none; border-radius: var(--radius-md, .5rem); transition: background .12s, opacity .12s; }
.login-submit:hover:not(:disabled) { background: var(--color-primary-bright, #2e7d47); }
.login-submit:disabled { opacity: .45; cursor: not-allowed; }
.login-submit:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; }
.login-divider { height: 1px; background: var(--color-border, #d7dce2); margin: var(--space-5, 1.5rem) 0; }
.login-all { background: none; border: none; cursor: pointer; font-family: inherit; font-weight: 600;
  font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684); text-decoration: underline; text-underline-offset: 3px; }
.login-all:hover { color: var(--mock-primary-ink, #2e7d47); }
.login-all:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; border-radius: var(--radius-sm, .375rem); }

/* ═══ ECHT login-formulier (crate) — de velden op de inlogpagina en in de poort. DS-tokens; één
   kolom, labels boven de velden, ruime raakvlakken (WCAG 2.2 2.5.8). ═══ */
.login-field { display: flex; flex-direction: column; gap: var(--space-2, .5rem); margin-bottom: var(--space-4, 1rem); }
.login-label { font-size: var(--text-sm, .875rem); font-weight: 600; color: var(--color-text-heading, #1a2230); }
.login-input { width: 100%; box-sizing: border-box; min-height: 2.75rem; padding: var(--space-3, .75rem);
  font-family: inherit; font-size: var(--text-base, 1rem); color: var(--color-text, #1a2230);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border-strong, #b6bdc7);
  border-radius: var(--radius-md, .5rem); transition: border-color .15s ease, box-shadow .15s ease; }
.login-input:focus { outline: none; border-color: var(--color-primary, #2e7d47);
  box-shadow: 0 0 0 3px var(--color-primary-soft, rgba(46,125,71,.15)); }
.login-field.has-toggle { position: relative; }
.login-field.has-toggle .login-input { padding-right: 4.5rem; }
.login-pw-toggle { position: absolute; right: var(--space-2, .5rem); bottom: .45rem; min-height: 1.9rem;
  padding: 0 var(--space-2, .5rem); cursor: pointer; font-family: inherit; font-size: var(--text-xs, .75rem);
  font-weight: 600; color: var(--color-text-muted, #6b7684); background: none; border: none;
  border-radius: var(--radius-sm, .375rem); }
.login-pw-toggle:hover { color: var(--mock-primary-ink, #2e7d47); }
.login-pw-toggle:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.login-error { margin-bottom: var(--space-4, 1rem); padding: var(--space-3, .75rem);
  font-size: var(--text-sm, .875rem); color: var(--color-danger, #b42318);
  background: var(--color-danger-soft, rgba(180,35,24,.08)); border: 1px solid var(--color-danger, #b42318);
  border-radius: var(--radius-md, .5rem); }
.persona-logout-form { display: inline-flex; margin: 0; }
.persona-dashboard { display: inline-flex; align-items: center; text-decoration: none; }

/* De inlogpagina (`/login`): de kaart op een rustig vlak tussen header en footer, iets boven het
   optische midden. Merk, titel en uitleg gecentreerd; de velden links uitgelijnd, want een
   gecentreerd label leest slecht. */
.login-page { display: flex; flex-direction: column; align-items: center;
  min-height: calc(100vh - 16rem); padding: clamp(2rem, 8vh, 5rem) 0; }
.login-page .login-card { box-shadow: var(--shadow-md, 0 4px 16px rgba(20,30,45,.08)); }
.login-alt { margin: var(--space-5, 1.25rem) 0 0; padding-top: var(--space-5, 1.25rem);
  border-top: 1px solid var(--color-border, #d7dce2);
  font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684); }
.login-alt a { color: var(--mock-primary-ink, #2e7d47); font-weight: 600; text-underline-offset: 3px; }
.login-alt a:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; border-radius: var(--radius-sm, .375rem); }
.login-card .login-form { text-align: left; }
.login-card .login-submit { margin-top: var(--space-2, .5rem); min-height: 2.75rem; }
.login-notice { margin: 0 0 var(--space-5, 1.5rem); padding: var(--space-3, .75rem); text-align: left;
  font-size: var(--text-sm, .875rem); color: var(--color-success, #2e7d47);
  background: var(--color-success-bg, rgba(46,125,71,.08)); border: 1px solid var(--color-success, #2e7d47);
  border-radius: var(--radius-md, .5rem); }
@media (max-width: 480px) {
  .login-page { padding: var(--space-6, 1.5rem) var(--space-4, 1rem); }
  .login-card { padding: var(--space-6, 1.5rem) var(--space-5, 1.25rem); }
}

/* Geen-toegang: als je ingelogd een pagina buiten je rol opent. */
.no-access { display: flex; flex-direction: column; align-items: center; text-align: center;
  padding: var(--space-16, 4rem) var(--space-6, 2rem); gap: var(--space-3, .75rem); }
.no-access-glyph { width: 3rem; height: 3rem; display: inline-grid; place-items: center; border-radius: 999px;
  background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666); }
.no-access-glyph svg { width: 1.4rem; height: 1.4rem; }
.no-access-title { font-family: var(--font-heading, inherit); font-size: var(--text-2xl, 1.5rem); color: var(--color-text-heading, #1a2230); margin: 0; }
.no-access-text { font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684); margin: 0; max-width: 24rem; }
.no-access-actions { display: flex; gap: var(--space-3, .75rem); margin-top: var(--space-4, 1rem); }
.no-access-btn { cursor: pointer; font-family: inherit; font-weight: 600; font-size: var(--text-sm, .875rem);
  padding: var(--space-2, .5rem) var(--space-4, 1rem); border-radius: var(--radius-md, .5rem);
  border: none; background: var(--color-primary, #2e7d47); color: var(--color-text-on-primary, #fff); transition: background .12s; }
.no-access-btn.ghost { background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #d7dce2); color: var(--color-text-secondary, #4b5563); }
.no-access-btn:hover { background: var(--color-primary-bright, #2e7d47); }
.no-access-btn.ghost:hover { background: var(--color-bg-surface-hover, #f4f6f8); }
.no-access-btn:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 2px; }

/* ═══ Pagina-indeling — het overzicht-paneel (plan B Fase 1). Editor-only drawer, DS-tokens. ═══ */
.mpc-body { flex: 1; overflow-y: auto; padding: var(--space-4, 1rem); display: flex; flex-direction: column; gap: var(--space-3, .75rem); }
.mpc-lock { margin-left: auto; font-size: .75rem; font-weight: 600; white-space: nowrap;
  color: var(--color-text-secondary, #4b5563); background: var(--color-bg-muted, #eef1f4);
  border-radius: var(--radius-pill, 999px); padding: 1px var(--space-2, .5rem); }
.mpc-lock.open { color: var(--color-success, #16a34a); background: var(--color-success-bg, rgba(22,163,74,.12)); }
.mpc-chips { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); }
.mpc-chip { display: inline-flex; align-items: center; gap: var(--space-2, .5rem);
  padding: var(--space-1, .25rem) var(--space-3, .625rem); border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--color-border, #dfe4ec); background: var(--color-bg-surface, #fff);
  font-size: var(--text-sm, .8125rem); font-weight: 600; color: var(--color-text, #1a2230); }
.mpc-chip-dot { width: .5rem; height: .5rem; border-radius: 50%; flex: none; background: var(--color-text-muted, #9aa4b1); }
.mpc-chip.k-worklist .mpc-chip-dot { background: var(--color-primary, #2e7d47); }
.mpc-chip.k-drill .mpc-chip-dot { background: #d97706; }
.mpc-chip.k-flow .mpc-chip-dot { background: #2563eb; }
.mpc-empty { font-size: var(--text-sm, .8125rem); color: var(--color-text-muted, #9aa4b1); font-style: italic; }
.mpc-chip { padding-right: var(--space-1, .25rem); }
.mpc-move { margin-left: var(--space-1, .25rem); border: none; background: none; cursor: pointer;
  color: var(--color-text-muted, #6b7684); font-size: .75rem; line-height: 1; padding: 3px 5px;
  border-radius: var(--radius-sm, .375rem); transition: background .12s, color .12s; }
.mpc-move:hover { background: var(--color-bg-surface-hover, #eef1f4); color: var(--mock-primary-ink, #2e7d47); }
.mpc-move:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.mpc-move-menu { z-index: 80; }
.mpc-move-menu .mpc-mm-arrow { color: var(--mock-primary-ink, #2e7d47); font-weight: 700; }
.row-menu-empty { padding: var(--space-2, .5rem) var(--space-3, .75rem); font-size: var(--text-sm, .8125rem); color: var(--color-text-muted, #9aa4b1); font-style: italic; }
.row-menu-sep { height: 1px; margin: var(--space-1, .25rem) 0; background: var(--color-border, #dfe4ec); }
.mpc-move-menu .row-menu-item.danger { color: var(--color-error, #c0392b); }
.mpc-move-menu .row-menu-item.danger:hover { background: var(--color-error-bg, rgba(192,57,43,.08)); }

/* ═══ 24-09 — het laatje opent op de huidige pagina: stapel (herschikken) + toevoegen + alle pagina's ingeklapt ═══ */
.mpc-sub-kop { margin: var(--space-3, .75rem) 0 var(--space-2, .5rem); font-size: .75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-muted, #6b7684); }
.mpc-chips.is-stapel { flex-direction: column; flex-wrap: nowrap; }
.mpc-chips.is-stapel .mpc-chip { border-radius: var(--radius-md, .5rem); padding-top: var(--space-2, .5rem); padding-bottom: var(--space-2, .5rem); }
.mpc-chips.is-stapel .mpc-chip-name { flex: 1; }
/* Hetzelfde component op meer pagina's (08-10): zeg waar nog meer, klein en rustig. */
.mpc-chip-ook { font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684);
  white-space: nowrap; margin-left: var(--space-1, .25rem); }
.mpc-chips.is-stapel .mpc-drop-caret { width: auto; height: 3px; min-height: 0; margin: -1px 0; align-self: stretch; }
.mpc-hint-regel { margin: var(--space-2, .5rem) 0 0; font-size: .75rem; color: var(--color-text-muted, #6b7684); line-height: var(--leading-snug, 1.4); }
.mpc-toevoeg { display: flex; flex-direction: column; gap: var(--space-1, .25rem); }
.mpc-toevoeg-rij { display: flex; align-items: center; gap: var(--space-2, .5rem); width: 100%; text-align: left; cursor: pointer;
  font-family: inherit; font-size: var(--text-sm, .8125rem); padding: var(--space-2, .5rem) var(--space-3, .625rem);
  border: 1px dashed var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230); }
.mpc-toevoeg-rij:hover { border-style: solid; border-color: var(--color-primary, #2e7d47); background: var(--color-primary-soft, rgba(46,125,71,.06)); }
.mpc-toevoeg-rij:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.mpc-toevoeg-plus { font-weight: 700; color: var(--mock-primary-ink, #2e7d47); }
.mpc-toevoeg-rij.k-worklist .mpc-chip-dot { background: var(--color-primary, #2e7d47); }
.mpc-toevoeg-rij.k-drill .mpc-chip-dot { background: #d97706; }
.mpc-toevoeg-rij.k-flow .mpc-chip-dot { background: #2563eb; }
.mpc-toevoeg-n { font-weight: 600; flex: 1; min-width: 0; }
.mpc-toevoeg-w { font-size: .75rem; color: var(--color-text-muted, #6b7684); white-space: nowrap; }
.mpc-toevoeg-w.is-elders { color: #b45309; }

/* ═══ Fase 2 (07-19) — slepen: affordance, sleep-staat, drop-doel + caret ═══ */
.mpc-draggable { cursor: grab; }
.mpc-draggable:active { cursor: grabbing; }
.mpc-chip.dragging { opacity: .4; }
.mpc-chips { min-height: 1.9rem; border-radius: var(--radius-sm, .375rem); padding: 2px; transition: background .12s, box-shadow .12s;
  align-content: flex-start; }
.mpc-chips.drop-active { background: var(--color-primary-soft, rgba(46,125,71,.08));
  box-shadow: inset 0 0 0 2px var(--color-primary, #2e7d47); }
.mpc-drop-caret { flex: none; width: 3px; align-self: stretch; min-height: 1.4rem; margin: 0 -1px;
  border-radius: 2px; background: var(--color-primary, #2e7d47); animation: mpc-caret .6s ease-in-out infinite alternate; }
@keyframes mpc-caret { from { opacity: .45; } to { opacity: 1; } }
/* RBAC-plaats-guard (Fase 5): doel dat niet mag → rood, niet-toegestaan. */
.mpc-chips.drop-deny { cursor: not-allowed; background: var(--color-error-bg, rgba(192,57,43,.07));
  box-shadow: inset 0 0 0 2px var(--color-error, #c0392b); }
.row-menu-item.is-denied { color: var(--color-text-muted, #9aa4b1); cursor: not-allowed; }
.row-menu-item.is-denied .mpc-mm-arrow { color: var(--color-text-muted, #9aa4b1); font-weight: 400; }

/* ═══ Fase 2 (07-19) — hover-preview: event-model-kaart (wireframe) + mini mock-render ═══ */
.mpc-preview { position: absolute; z-index: 90; width: 22rem; max-width: calc(100vw - 1rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-lg, .75rem); box-shadow: var(--shadow-lg, 0 12px 32px rgba(16,24,40,.16));
  padding: var(--space-3, .75rem); display: none; pointer-events: auto; }
.mpc-preview.open { display: block; animation: mc-in .14s ease; }
.mpc-pv-head { display: flex; align-items: center; gap: var(--space-2, .5rem); font-weight: 700;
  font-size: var(--text-sm, .875rem); color: var(--color-text-heading, #1a2230); margin-bottom: var(--space-2, .5rem); }
.mpc-pv-head .mpc-chip-dot.k-worklist { background: var(--color-primary, #2e7d47); }
.mpc-pv-head .mpc-chip-dot.k-drill { background: #d97706; }
.mpc-pv-panes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2, .5rem); }
.mpc-pv-pane { min-width: 0; display: flex; flex-direction: column; gap: var(--space-1, .25rem); }
.mpc-pv-label { font-size: .6875rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
  color: var(--color-text-muted, #6b7684); }
.mpc-pv-empty { font-size: var(--text-sm, .8125rem); color: var(--color-text-muted, #9aa4b1); font-style: italic; padding: var(--space-2, .5rem); }
/* wireframe — schematisch skelet */
.mpc-wf { border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-muted, #f6f8fa); padding: var(--space-2, .5rem); font-size: .6875rem; overflow: hidden; }
.mpc-wf-bar { display: flex; align-items: center; gap: var(--space-1, .25rem); margin-bottom: var(--space-1, .25rem); }
.mpc-wf-kind { font-size: .5625rem; font-weight: 700; letter-spacing: .04em; padding: 1px 5px; border-radius: 999px;
  color: var(--color-text-on-primary, #fff); background: var(--color-primary, #2e7d47); }
.mpc-wf-title { font-weight: 700; color: var(--color-text-heading, #1a2230); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mpc-wf-row { display: flex; gap: 3px; margin-top: 3px; }
.mpc-wf-head .mpc-wf-cell { font-weight: 600; color: var(--color-text-muted, #6b7684); background: none; height: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mpc-wf-cell { flex: 1; min-width: 0; }
.mpc-wf-skel { height: 7px; border-radius: 3px; background: var(--color-border, #dfe4ec); }
.mpc-wf-actions { display: flex; flex-wrap: wrap; gap: 3px; margin-top: var(--space-2, .5rem); }
.mpc-wf-btn { font-size: .625rem; font-weight: 600; padding: 2px 6px; border-radius: var(--radius-sm, .375rem);
  color: var(--color-text-on-primary, #fff); background: var(--color-primary, #2e7d47); }
.mpc-wf-btn.ghost { color: var(--mock-primary-ink, #2e7d47); background: none; border: 1px solid var(--color-primary-soft, #cfe3d6); }
.mpc-wf-kind.form { background: #2563eb; }
.mpc-wf-field { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.mpc-wf-flabel { font-size: .625rem; color: var(--color-text-muted, #6b7684); }
.mpc-wf-input { height: 12px; border-radius: 3px; background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec); }
/* mini mock-render — schaal de echte render weg in een vast venster */
.mpc-pv-mockclip { border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  height: 8.5rem; overflow: hidden; background: var(--color-bg-surface, #fff); position: relative; }
.mpc-pv-mock { transform: scale(.62); transform-origin: top left; width: 161%; pointer-events: none; padding: var(--space-2, .5rem); }

/* ═══ Fase 5 (07-19) — per-pagina rol-toekenning: klikbaar slot + multi-select rol-menu ═══ */
.mpc-lock-btn { margin-left: auto; display: inline-flex; align-items: center; gap: 2px; cursor: pointer;
  font: inherit; font-size: .75rem; font-weight: 600; white-space: nowrap; border: 1px solid transparent;
  padding: 2px 7px; border-radius: 999px; color: var(--color-text-muted, #6b7684);
  background: var(--color-bg-muted, #f1f4f8); transition: background .12s, border-color .12s, color .12s; }
.mpc-lock-btn.open { color: var(--color-success, #16a34a); background: var(--color-success-bg, rgba(22,163,74,.12)); }
.mpc-lock-btn.is-explicit { border-color: var(--color-primary, #2e7d47); }
.mpc-lock-btn:hover { background: var(--color-bg-surface-hover, #e6ebf1); color: var(--color-text, #1a2230); }
.mpc-lock-btn.open:hover { color: var(--color-success, #16a34a); }
.mpc-lock-btn:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.mpc-lock-caret { font-size: .625rem; opacity: .7; }
.mpc-role-menu { z-index: 90; min-width: 12rem; padding: var(--space-1, .25rem); }
.mpc-role-hint { padding: var(--space-1, .25rem) var(--space-2, .5rem) var(--space-2, .5rem);
  font-size: .6875rem; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--color-text-muted, #9aa4b1); }
.mpc-role-opt { display: flex; align-items: center; gap: var(--space-2, .5rem); }
.mpc-role-opt.on { color: var(--mock-primary-ink, #2e7d47); font-weight: 600; }
.mpc-role-check { display: inline-flex; align-items: center; justify-content: center; width: 1rem; height: 1rem; flex: none;
  border: 1.5px solid var(--color-border, #cdd5df); border-radius: var(--radius-sm, .3rem); font-size: .7rem; line-height: 1; }
.mpc-role-opt.on .mpc-role-check { background: var(--color-primary, #2e7d47); border-color: var(--color-primary, #2e7d47); color: #fff; }
.mpc-role-reset { color: var(--color-text-muted, #6b7684); font-size: var(--text-sm, .8125rem); }

/* ═══ Fase 4 — inline form (registratie boven de vouw, in de composeerbare landing). ═══ */
.inline-form { max-width: 30rem; margin: var(--space-6, 2rem) 0; padding: var(--space-6, 2rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-lg, .875rem); box-shadow: var(--shadow-md, 0 6px 18px rgba(20,30,45,.08)); }
.inline-form-title { font-family: var(--font-heading, inherit); font-size: var(--text-lg, 1.25rem);
  color: var(--color-text-heading, #1a2230); margin: 0 0 var(--space-4, 1rem); }
/* `.form-wrapper` is een flex-kolom MET gap; een marge eronder komt daar bovenop en gaf dubbele
   tussenruimte (32px tussen velden, 40px voor de knop) — ongelijk ritme in één kaart. */
.inline-form .form-group { margin-bottom: 0; }
/* De velden van een OMGEZET formulier. Eén kolom, met dezelfde tussenruimte als de generieke
   render — een omzetting verandert het design, niet de indeling. (Stond op `.form-grid`, de grid
   van de formulieren-hub: kaarten van 260px, dus tegelden de velden in kolommen.) */
.form-fields { display: flex; flex-direction: column; gap: var(--space-4, 1rem); }
.form-fields > [data-bind-field] { display: flex; flex-direction: column; }
/* Een formulier BINNEN een kaart is geen tweede kaart. Sommige design-systemen stylen een kale
   `form` als oppervlak (rand + schaduw); binnen `.inline-form` levert dat een doos in een doos op
   — het eerste wat je ziet op een detail- of registratiescherm (gemeten 21-09). */
.inline-form .form-wrapper { border: 0; box-shadow: none; background: none; padding: 0; }
/* De knoppenrij is een RIJ. Twee knoppen onder elkaar over de volle breedte lezen als twee even
   zware hoofdhandelingen; naast elkaar leest de hiërarchie (destructief krimpt, hoofdknop groeit). */
.inline-form-foot { margin-top: var(--space-5, 1.5rem); display: flex; gap: var(--space-3, .75rem); flex-wrap: wrap; }
.inline-form-foot .btn { flex: 1 1 auto; justify-content: center; }
.inline-form-foot .btn.is-danger { flex: 0 1 auto; }
/* `.form-wrapper` heeft zelf al een gap; de marge van de voet kwam daar bovenop en gaf een gat
   van ~80px tussen het laatste veld en de knop. */
.inline-form .form-wrapper > .inline-form-foot { margin-top: var(--space-2, .5rem); }
.inline-form-missing { max-width: 30rem; margin: var(--space-6, 2rem) 0; padding: var(--space-4, 1rem);
  border: 1px dashed var(--color-error, #c0392b); border-radius: var(--radius-md, .5rem); color: var(--color-error, #c0392b); text-align: center; }

/* ══ MOBIEL — de invarianten van de GENERIEKE laag ═══════════════════════════
   Tot 2026-09-02 leefde het stapelen van een worklist ALLEEN in de per-project
   `components.css`. 9 van de 22 design-systemen in dit repo hadden die regel niet:
   daar was de lijst op 390px **636px breed in een 340px kolom** — status én rij-acties
   achter een onaangekondigde swipe. En zelfs mét een stapelend DS lekte de `nowrap` +
   `min-width:max-content` hierboven erdoorheen (gemeten: 367px kaart in een 340px wrap,
   27px afgeknipt zodra een rij drie acties had).

   Mobiel-fatsoen hoort een GARANTIE van de codegen te zijn, niet een eigenschap van
   het toevallige design-systeem — zelfde lat als "niets in de codegen kent een
   projectnaam". Het DS mag dit hierna nog mooier maken; het mag het niet langer
   *mogelijk* maken.

   Meting + achtergrond: docs/plan-2026-09-02-mobiel-en-native.md
   ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 48rem) {

  /* ── 1. Worklist: van tabel naar kaartjes ────────────────────────────────
     `display:block` op de TABEL zelf is de kern. Zonder dat blijft het
     table-layout-algoritme actief en bepaalt de breedste rij (de actie-rij) de
     min-content-breedte — dan stapelen de cellen wél, maar puilt de kaart alsnog
     buiten de container. Dát was het 27px-lek. */
  .table-wrap { overflow-x: visible; border: 0; background: none; box-shadow: none; border-radius: 0; }
  .data-table { display: block; width: 100%; }
  .data-table thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .data-table tbody { display: block; }
  .data-table tbody tr {
    display: block; width: 100%;
    padding: var(--space-2, .5rem) var(--space-4, 1rem);
    margin-bottom: var(--space-3, .75rem);
    background: var(--color-bg-surface, #fff);
    border: 1px solid var(--color-border, #dfe4ec);
    border-radius: var(--radius-lg, 12px);
    box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.04));
  }
  .data-table tbody tr:last-child { margin-bottom: 0; }
  .data-table tbody td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--space-4, 1rem);
    width: auto; min-width: 0; padding: var(--space-2, .5rem) 0;
    white-space: normal; overflow-wrap: anywhere;
    border-bottom: 1px solid var(--color-border-subtle, #eef1f6);
  }
  /* Het kolomlabel dat in de thead stond. De renderer zet `data-label` al op elke
     cel (renderTable) — dit is dus puur CSS. */
  .data-table tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto; margin-right: auto;
    font-size: var(--text-xs, .75rem); font-weight: 700; letter-spacing: .02em;
    text-transform: uppercase; color: var(--color-text-muted, #6b7684);
  }
  /* De eerste kolom is de IDENTITEIT van de rij — op een kaart is dat de titel, niet een waarde
     achter een label. "NAAM · Sanne de Jong" rechts uitgelijnd leest als een veld; "Sanne de Jong"
     als kop leest als een kaart. Canon §2: één stabiele linker-scan-rand. */
  .data-table tbody td.cell-primary {
    display: block; font-size: var(--text-lg, 1.0625rem); font-weight: 650;
    color: var(--color-text-heading, inherit);
    padding-top: var(--space-3, .75rem); padding-bottom: var(--space-2, .5rem);
  }
  .data-table tbody td.cell-primary::before { content: none; }
  /* Een design-systeem dat cellen rechts zet (`td { text-align: right }`) zette ook de KOP van het
     kaartje rechts. De kop is de linker-scan-rand. */
  .data-table tbody td.cell-primary { text-align: left; }
  /* Eén kolom (en geen acties): een gewone lijst, geen stapel kaartjes. "Beheerder" en
     "Gebruiker" als twee losse kaarten in een paneel las als kaart-in-kaart (23-09). */
  .data-table tbody tr:has(> td:only-child) {
    background: none; border: 0; border-radius: 0; box-shadow: none; margin: 0; padding: 0;
    border-bottom: 1px solid var(--color-border-subtle, #eef1f6);
  }
  .data-table tbody tr:has(> td:only-child):last-child { border-bottom: 0; }
  .data-table tbody tr:has(> td:only-child) > td.cell-primary {
    font-size: var(--text-base, 1rem); font-weight: 500; border-bottom: 0;
    padding: var(--space-3, .75rem) var(--space-4, 1rem);
  }

  /* ── 2. Rij-acties: eigen regel, volle breedte, mogen afbreken ──────────
     Op desktop krimpt de actie-kolom tot z'n inhoud en mogen de knoppen niet
     krimpen (zie de overlap-bug hierboven). In een gestapelde kaart is precies
     dat de bodem die de kaart te breed maakt — hier dus het omgekeerde. */
  .data-table td.cell-actions, .data-table th.th-actions {
    width: auto; min-width: 0; text-align: left; white-space: normal;
    border-bottom: 0; padding-top: var(--space-3, .75rem);
  }
  .data-table td.cell-actions::before { content: none; }
  .row-actions { display: flex; flex-wrap: wrap; width: 100%; justify-content: stretch; }
  .row-actions .btn { flex: 1 1 8rem; justify-content: center; }
  /* De "Openen"-knop is in een gestapelde kaart de primaire actie — geef 'm z'n naam terug
     (op desktop blijft het een chevron in de actie-kolom). */
  .row-actions .btn-ghost[data-open] { gap: .4rem; }
  .row-actions .btn-ghost[data-open]::after { content: attr(data-open); }

  /* ── 3. Aanraakdoelen (WCAG 2.2 AA 2.5.8) ───────────────────────────────
     Gemeten vóór deze regel: chips 25px, breadcrumbs 22px, knoppen 32–37px,
     invoervelden 34px — axe meldde 18 target-size-schendingen op één lijstpagina. */
  .btn, .btn-sm { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
  .chip { min-height: 40px; display: inline-flex; align-items: center; }
  .crumb { min-height: 36px; display: inline-flex; align-items: center; }
  .search-clear, .drawer-close, .pw-toggle { min-width: 40px; min-height: 40px;
    display: inline-flex; align-items: center; justify-content: center; }
  .persona-login, .persona-logout { min-height: 44px; display: inline-flex; align-items: center; }
  /* Chip + uitloggen op ÉÉN regel. `flex-wrap: nowrap` + overal `min-width: 0` is wat een
     flex-kind laat krimpen; zonder die nul duwt de langste tekst (een gebruikersnaam, of de
     rollenlijst in de ontwerp-stand) de knop naar een eigen regel — en dat kost op een telefoon
     een hele koprij. De naam kapt af; de titel draagt 'm voluit. */
  .persona-bar { flex: 1 1 100%; margin-left: 0; justify-content: space-between; flex-wrap: nowrap; }
  /* Alleen een inlog-knop (de bezoeker) is geen hele regel waard: die past naast het merk. */
  .persona-bar:not(:has(.persona-chip)) { flex: 0 0 auto; margin-left: auto; }
  .persona-chip { flex: 0 1 auto; min-width: 0; overflow: hidden; }
  .account-menu { flex: 0 1 auto; min-width: 0; margin-left: auto; }
  /* "Ingelogd als" verdwijnt op een klein scherm: de groene stip zegt hetzelfde en de naam heeft
     de ruimte harder nodig. Liet 'm eerst staan mét krimp — toen liep de tekst over de naam heen,
     want een gekrompen inline-element kapt niet vanzelf af. */
  .persona-label { display: none; }
  .persona-dot { flex: 0 0 auto; }
  .persona-name, .persona-roles {
    flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .persona-roles { max-width: 8rem; }
  /* In de echte-auth-tak zit de uitlog-knop in een <form> — DAT is het flex-kind, niet de knop.
     Zonder deze regel krimpt de chip niet en valt "Uitloggen" alsnog op een eigen regel. */
  .persona-login, .persona-logout, .persona-logout-form { flex: 0 0 auto; }
  /* Het zoekveld ZELF vullen: de doos was al 44px hoog, maar het kale input erin 18px — tikken
     naast de tekst deed dan niets. */
  .search-box .search-input { align-self: stretch; }

  /* ── 4. Invoer: 16px ondergrens ──────────────────────────────────────────
     Onder 16px zoomt iOS Safari in zodra een veld focus krijgt en verspringt de
     hele pagina. Gold vóór deze regel voor élk formulier (13,6px). */
  .form-control, .search-input, .mc-input,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea {
    font-size: max(16px, var(--text-sm, .875rem));
  }
  .form-control, .search-box { min-height: 44px; }
  textarea.form-control { min-height: 5.5rem; }

  /* ── 5. Chrome: minder scherm opeten ─────────────────────────────────────
     De sticky header was 170px van 844px — een vijfde van het scherm, permanent. */
  .app-header-inner { padding: var(--space-3, .75rem) var(--space-4, 1rem); gap: var(--space-3, .75rem); }
  .tagline { display: none; }
  .app-shell { padding: var(--space-4, 1rem); }
  .hub-nav { padding: 0 var(--space-4, 1rem); scroll-snap-type: x proximity; }
  .hub-tab { scroll-snap-align: start; padding-left: var(--space-3, .75rem); padding-right: var(--space-3, .75rem); }
  /* Scroll-affordance: de rechterrand vervaagt, zodat zichtbaar is dat er meer
     tabs zijn. Zonder dit is de nav een STILLE scroller — 13 items, 4 in beeld. */
  .hub-nav {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
  }

  /* ── 6. Detail-inzage: label boven waarde i.p.v. twee kolommen ───────────*/
  .detail-row { grid-template-columns: 1fr; gap: var(--space-1, .25rem); }
}

/* ══════════════════════════════════════════════════════════════════════════
   VERRIJKTE SCHERM-COMPONENTEN + WIDGET-CATALOGUS (Component Studio)
   --------------------------------------------------------------------------
   Structuur, geen smaak: het artefact brengt z'n eigen opmaak mee (design-systeem-
   tokens), deze regels zorgen alleen dat de door de RENDERER geplaatste onderdelen
   (widgets, ingevulde slots, de terugval-velden) er verzorgd bij staan.
   ══════════════════════════════════════════════════════════════════════════ */
.screen-artifact { display: block; }
/* Niet-gebonden verplichte velden vallen nooit stil weg — ze staan hier, zichtbaar apart. */
.artifact-rest {
  display: grid; gap: var(--space-4, 1rem);
  margin-top: var(--space-5, 1.25rem); padding-top: var(--space-4, 1rem);
  border-top: 1px dashed var(--color-border, #d8dee6);
}

/* ── slider ─────────────────────────────────────────────────────────────── */
.slider-row { display: flex; align-items: center; gap: var(--space-3, .75rem); }
.slider-input { flex: 1 1 auto; padding: 0; height: 1.5rem; accent-color: var(--color-primary, #3a7ca5); }
.slider-value {
  flex: 0 0 auto; min-width: 3.5rem; text-align: right;
  font-family: var(--font-mono, ui-monospace, monospace); font-size: var(--text-sm, .875rem);
  color: var(--color-text-secondary, #4a5568);
}

/* ── stepper ────────────────────────────────────────────────────────────── */
.stepper-row { display: flex; align-items: center; gap: var(--space-2, .5rem); }
.stepper-row .stepper-input { flex: 1 1 auto; text-align: center; }

/* ── segmented (keuzeknoppen i.p.v. dropdown) ───────────────────────────── */
.segmented { display: inline-flex; flex-wrap: wrap; gap: 0; border: 1px solid var(--color-border, #d8dee6); border-radius: var(--radius-md, .5rem); overflow: hidden; }
.seg-btn {
  appearance: none; border: 0; cursor: pointer;
  padding: var(--space-2, .5rem) var(--space-4, 1rem);
  font: inherit; font-size: var(--text-sm, .875rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1a202c);
  border-right: 1px solid var(--color-border-subtle, #edf1f5);
}
.seg-btn:last-child { border-right: 0; }
.seg-btn:hover { background: var(--color-bg-surface-hover, #f4f7fa); }
.seg-btn.is-on { background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); }

/* ── switch ─────────────────────────────────────────────────────────────── */
.switch { display: inline-flex; align-items: center; cursor: pointer; }
.switch .switch-input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 2.75rem; height: 1.5rem; border-radius: var(--radius-pill, 999px);
  background: var(--color-border-strong, #b9c4d0); position: relative; transition: background .15s ease;
}
.switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 1.25rem; height: 1.25rem;
  border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.15));
  transition: transform .15s ease;
}
.switch .switch-input:checked + .switch-track { background: var(--color-primary, #3a7ca5); }
.switch .switch-input:checked + .switch-track::after { transform: translateX(1.25rem); }
.switch .switch-input:focus-visible + .switch-track { outline: 2px solid var(--color-border-focus, #3a7ca5); outline-offset: 2px; }

/* ── rating ─────────────────────────────────────────────────────────────── */
.rating { display: inline-flex; gap: var(--space-1, .25rem); }
.rating-star {
  appearance: none; border: 0; background: none; cursor: pointer; padding: 0 .1rem;
  font-size: var(--text-xl, 1.25rem); line-height: 1; color: var(--color-border-strong, #b9c4d0);
}
.rating-star.is-on { color: var(--mock-primary-ink, #3a7ca5); }

/* ── chips (multiselect) ────────────────────────────────────────────────── */
.chip-set { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); }
.tag-veld { display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.tag-set:empty { display: none; }
.chip.tag { display: inline-flex; align-items: center; gap: 4px; cursor: default; }
.tag-weg { border: 0; background: transparent; color: inherit; font: inherit; font-size: 1.1em; line-height: 1; padding: 0 2px; cursor: pointer; opacity: .8; }
.tag-weg:hover, .tag-weg:focus-visible { opacity: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   COMPONENT STUDIO + MODEL-VENSTER (bouw-chrome — alleen editor-geserveerd)
   --------------------------------------------------------------------------
   Reist wél mee in app.css, maar wordt in de crate nooit zichtbaar: de knoppen
   en panelen worden alleen aangemaakt als `__MOCK_EDIT__` er is.
   ══════════════════════════════════════════════════════════════════════════ */
body.studio-open { overflow: hidden; }

/* ── het "verrijk dit scherm"-knopje op een component (Bewerken-modus) ───── */
/* DRIE SOORTEN, drie signalen. Een component uit het event-model krijgt een eigen RANDVORM
   (blokjes, niet de streepjes van een tekstblok) plus het ◆-teken op z'n knop: je ziet zonder
   klikken dat dit een ander soort aanpassing is — de inhoud komt uit het model, alleen de vorm
   is van jou. */
/* De legenda in de bewerk-balk: drie benoemde ingangen in plaats van één algemene uitnodiging. */
/* De balk zelf vangt geen muis (hij zweeft over de pagina), de KNOPPEN erin wél. Stond dit er niet,
   dan was elke ingang in de legenda dood — inclusief de onderstreepte link, die er klikbaar uitzag. */

/* Aandacht-puls: de legenda-knop wijst z'n eigen soort op de pagina aan. */
@keyframes eb-flits-puls {
  0%, 100% { box-shadow: 0 0 0 0 rgba(58,124,165,0); }
  25%, 75% { box-shadow: 0 0 0 5px var(--color-primary-soft, #cfe3ee); }
}
.eb-flits { animation: eb-flits-puls 1.5s ease-in-out; border-radius: var(--radius-lg, .75rem); }
@media (prefers-reduced-motion: reduce) { .eb-flits { animation: none; outline: 3px solid var(--color-primary, #3a7ca5); } }

/* BEWERKBARE TEKST LAAT ZICH ZIEN. Een contenteditable kop zag er exact zo uit als een vaste kop —
   de enige manier om te ontdekken dat je erin kon typen was erop klikken. Nu draagt 'ie in de
   bewerk-modus dezelfde streepjeslijn als het staaltje in de balk. */
body.cms-editing .cms-editable {
  cursor: text; border-radius: var(--radius-sm, 6px);
  outline: 1px dashed var(--color-border, #c6cedb); outline-offset: 4px;
}
body.cms-editing .cms-editable:hover { outline-color: var(--color-primary, #3a7ca5); background: var(--color-primary-soft, #eef5f9); }
body.cms-editing .cms-editable:focus { outline: 2px solid var(--color-primary, #3a7ca5); background: transparent; }

/* De eigen-tekst-zone van een pagina: een benoemde plek in plaats van een losse "+"-balk. */
.page-cms-zone { margin-top: var(--space-6, 1.5rem); }
body.cms-editing .page-cms-zone {
  border-top: 1px dashed var(--color-border, #dfe4ec);
  padding-top: var(--space-4, 1rem);
}
.cms-zone-kop {
  display: flex; align-items: center; gap: .45rem; margin: 0 0 var(--space-3, .75rem);
  color: var(--color-text-muted, #6b7684); font-size: var(--text-xs, .75rem); font-weight: 600;
  text-transform: uppercase; letter-spacing: .04em;
}
/* De pagina-kaart in het indeling-paneel: voor wie is 'ie, wat voor soort, en de opmaak-knop. */
/* Geen rol = de mock toont 'm aan iedereen. Dat is een gat, geen derde publiek — dus opvallend. */
/* De pagina waar je NU staat is de enige die je kunt laten opmaken — die springt eruit. */
/* Het opmaak-gesprek van deze pagina. */
.mpc-compose { margin: .5rem 0 .25rem; display: flex; flex-direction: column; gap: .4rem; }
.mpc-log { display: flex; flex-direction: column; gap: .25rem; max-height: 150px; overflow: auto; }
.mpc-log-r { margin: 0; font-size: var(--text-xs, .75rem); line-height: 1.45; padding: .3rem .5rem; border-radius: var(--radius-md, 10px); }
.mpc-log-r.is-jij { background: var(--color-bg-muted, #eef2f7); color: var(--color-text-secondary, #4a5666); }
.mpc-log-r.is-tool { background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec); }
.mpc-log-r.is-fout { background: var(--color-error-soft, #fdecea); color: var(--color-error, #c0392b); }
.mpc-input {
  width: 100%; font: inherit; font-size: var(--text-sm, .875rem); resize: vertical;
  padding: .45rem .6rem; border-radius: var(--radius-md, 10px);
  border: 1px solid var(--color-border, #dfe4ec); background: var(--color-bg-surface, #fff);
  color: var(--color-text, #24303f);
}
.mpc-input:focus { outline: 2px solid var(--color-primary, #3a7ca5); outline-offset: 1px; }
.mpc-compose-voet { display: flex; align-items: center; gap: .5rem; }
.mpc-hint { font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684); }
.mpc-mooi {
  margin-left: auto; appearance: none; cursor: pointer; font: inherit;
  font-size: var(--text-xs, .75rem); font-weight: 600; padding: .2rem .65rem;
  border-radius: var(--radius-pill, 999px); border: 1px solid var(--color-primary, #3a7ca5);
  background: transparent; color: var(--mock-primary-ink, #3a7ca5);
}
.mpc-mooi:hover { background: var(--color-primary-soft, #eef5f9); }
.mpc-mooi[disabled] { opacity: .6; cursor: progress; }

/* ── de Studio-overlay ──────────────────────────────────────────────────── */
.studio, .model-view {
  position: fixed; inset: 2.5vh 2.5vw; z-index: 60;
  display: none; flex-direction: column;
  background: var(--color-bg, #f7f9fb); color: var(--color-text, #1a202c);
  border: 1px solid var(--color-border, #d8dee6); border-radius: var(--radius-lg, .75rem);
  box-shadow: var(--shadow-xl, 0 24px 64px rgba(16, 24, 40, .28)); overflow: hidden;
}
.studio.open, .model-view.open { display: flex; }
.studio-head, .mv-head {
  display: flex; align-items: center; gap: var(--space-3, .75rem);
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-bottom: 1px solid var(--color-border, #d8dee6);
  background: var(--color-bg-surface, #fff);
}
.studio-title { display: flex; align-items: baseline; gap: var(--space-2, .5rem); flex: 1 1 auto; min-width: 0; }
.studio-head > .btn { flex: 0 0 auto; }
.studio-title h2, .mv-head h2 { margin: 0; font-size: var(--text-lg, 1.125rem); color: var(--color-text-heading, #16202c); }
.studio-kind, .mv-sub {
  font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684);
  text-transform: uppercase; letter-spacing: .04em;
}
.mv-sub { flex: 1 1 auto; text-transform: none; letter-spacing: 0; }
.mv-link { font-size: var(--text-sm, .875rem); color: var(--mock-primary-ink, #3a7ca5); }
.studio-toggle { display: inline-flex; border: 1px solid var(--color-border, #d8dee6); border-radius: var(--radius-md, .5rem); overflow: hidden; }
.studio-toggle .seg-btn:disabled { opacity: .45; cursor: not-allowed; }
.studio-close, .studio-del {
  appearance: none; border: 0; background: none; cursor: pointer;
  font-size: var(--text-lg, 1.125rem); line-height: 1; padding: .25rem .4rem;
  color: var(--color-text-muted, #6b7684);
}
.studio-close:hover, .studio-del:hover { color: var(--color-text, #1a202c); }

/* Drie kolommen: waar je mee ontwerpt · wat je maakt · het gesprek. De chat stond eerst als balk
   ónder het geheel, en groeide dus mee met elk antwoord — dan schuift de preview weg terwijl je
   zit te wachten. Als kolom over de volle hoogte staat alles stil en lees je het gesprek als een
   gesprek. */
.studio-body { flex: 1 1 auto; display: grid; grid-template-columns: 19rem minmax(0, 1fr) 21rem; min-height: 0; }
.studio-contract {
  border-right: 1px solid var(--color-border, #d8dee6);
  background: var(--color-bg-surface, #fff);
  padding: var(--space-4, 1rem); overflow-y: auto; overflow-x: hidden; min-width: 0;
}
.studio-hint { margin: 0 0 var(--space-4, 1rem); font-size: var(--text-sm, .875rem); color: var(--color-text-secondary, #4a5568); }
.studio-group { margin-bottom: var(--space-5, 1.25rem); }
.studio-group h3 {
  margin: 0 0 var(--space-2, .5rem); font-size: var(--text-xs, .75rem);
  text-transform: uppercase; letter-spacing: .06em; color: var(--color-text-muted, #6b7684);
}
.studio-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .15rem; }
.studio-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2, .5rem); font-size: var(--text-sm, .875rem); }
.studio-mark { flex: 0 0 1rem; color: var(--color-text-muted, #6b7684); }
.studio-list li.is-ok .studio-mark { color: var(--color-success, #2f855a); }
.studio-list li.is-off .studio-mark { color: var(--color-error, #c53030); }
.studio-label { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.studio-meta { flex: 0 1 auto; font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684); text-align: right; overflow-wrap: anywhere; }
.studio-empty { margin: 0; font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684); }
.studio-warn {
  margin: var(--space-3, .75rem) 0 0; padding: var(--space-2, .5rem) var(--space-3, .75rem);
  font-size: var(--text-sm, .875rem); color: var(--color-text, #1a202c);
  background: var(--color-error-bg, #fdecec); border-radius: var(--radius-sm, .25rem);
}
.studio-preview { display: flex; flex-direction: column; min-width: 0; overflow: auto; background: var(--color-bg, #f7f9fb); }
.studio-stage-head {
  padding: var(--space-2, .5rem) var(--space-4, 1rem);
  font-size: var(--text-xs, .75rem); text-transform: uppercase; letter-spacing: .06em;
  color: var(--color-text-muted, #6b7684); border-bottom: 1px solid var(--color-border-subtle, #edf1f5);
}
/* Het scherm staat op een vloer, gecentreerd en met ruimte eromheen: zo beoordeel je het zoals een
   gebruiker het ziet, niet als een blok tegen een paneelrand. */
.studio-stage {
  flex: 1 1 auto; padding: var(--space-6, 1.5rem);
  display: flex; justify-content: center; align-items: flex-start;
}
/* Alleen breedte en midden: het component tekent z'n eigen kaart al, en een kaart in een kaart
   leest als een fout. */
.studio-stage > * { width: 100%; max-width: 60rem; }

.studio-chat {
  border-left: 1px solid var(--color-border, #d8dee6); background: var(--color-bg-surface, #fff);
  display: flex; flex-direction: column; min-height: 0; min-width: 0;
}
/* Het gesprek vult wat er over is en scrollt; de invoer blijft onderaan staan. */
.studio-chat-log {
  flex: 1 1 auto; min-height: 0; overflow: auto;
  display: flex; flex-direction: column; gap: var(--space-2, .5rem);
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
}
.studio-chat-row {
  display: flex; flex-direction: column; gap: var(--space-2, .5rem);
  padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-top: 1px solid var(--color-border-subtle, #edf1f5);
}
.studio-chat-row .mc-input { width: 100%; }
.studio-chat-row .btn { justify-content: center; }

/* ── het model-venster ──────────────────────────────────────────────────── */
.mv-frame { flex: 1 1 auto; width: 100%; border: 0; background: #fff; }

@media (max-width: 1100px) {
  /* Te smal voor drie kolommen: de chat gaat terug naar onderen, maar houdt z'n eigen hoogte. */
  .studio-body { grid-template-columns: 17rem minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) 14rem; }
  .studio-chat { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--color-border, #d8dee6); }
}
@media (max-width: 860px) {
  .studio-body { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) 14rem; }
  .studio-contract { border-right: 0; border-bottom: 1px solid var(--color-border, #d8dee6); max-height: 40vh; }
}

/* ── "alleen dit component" (…/mock/screen-preview) ──────────────────────────
   Het scherm zonder chrome, om ingebed te worden (bv. op een SCREEN-sticky in het
   model-venster). Alles wat om het component heen zit valt weg; het component zelf
   blijft exact zoals de mock 'm tekent. */
/* Een knop wees naar een component op DEZE pagina: even oplichten zodat je ziet waar 'ie staat. */
.component-aangewezen { outline: 2px solid var(--color-primary, #2e7d47); outline-offset: 4px;
  border-radius: var(--radius-md, .5rem); }

/* ══ DE PAGINA-INDELER (…/mock/pages) ═══════════════════════════════════════
   Dezelfde handelingen als het ▤-laatje, maar paginavullend: indelen is een ruimtelijke
   taak (pagina's naast componenten, plek om te slepen). Twee kolommen op een breed scherm,
   onder elkaar op een smal. Tokens met fallback, zoals de rest van app.css. */
body.pages-mode .app-header,
body.pages-mode .hub-nav,
body.pages-mode .app-footer,
body.pages-mode .mode-toggle,
body.pages-mode .persona-bar,
body.pages-mode .edit-bar { display: none !important; }
body.pages-mode .app-shell { max-width: 1400px; padding: var(--space-4, 1rem); }
.pgc-head { display: flex; flex-direction: column; gap: var(--space-2, .5rem);
  padding-bottom: var(--space-4, 1rem); border-bottom: 1px solid var(--color-border, #dfe4ec); }
.pgc-head-l { display: flex; align-items: baseline; gap: var(--space-4, 1rem); flex-wrap: wrap; }
.pgc-back { font-size: var(--text-sm, .8125rem); font-weight: 600; text-decoration: none;
  color: var(--color-text-secondary, #4b5563); min-height: 44px; display: inline-flex; align-items: center; }
.pgc-back:hover { color: var(--mock-primary-ink, #2e7d47); }
.pgc-title { margin: 0; font-size: var(--text-xl, 1.25rem); }
.pgc-count { font-size: var(--text-sm, .8125rem); font-weight: 600; padding: 2px var(--space-3, .625rem);
  border-radius: var(--radius-pill, 999px); color: var(--color-success, #16a34a);
  background: var(--color-success-bg, rgba(22,163,74,.12)); }
.pgc-count.is-open { color: var(--color-warning, #b45309); background: var(--color-bg-muted, #f3f5f7); }
/* De schakelaar: aan = de tool maakt de pagina's, uit = jij deelt in. Een knop met een stand,
   geen vinkje — de tekst zegt wat er NU geldt. */
.pgc-auto { margin-left: auto; min-height: 36px; padding: 0 var(--space-3, .625rem); cursor: pointer;
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-pill, 999px);
  background: var(--color-bg-surface, #fff); font: inherit; font-size: var(--text-xs, .75rem);
  font-weight: 600; color: var(--color-text-secondary, #4b5563); }
.pgc-auto::before { content: "\2699"; margin-right: .4rem; }
.pgc-auto.is-on { color: var(--mock-primary-ink, #2e7d47); border-color: var(--color-primary, #2e7d47); }
.pgc-auto:hover { background: var(--color-bg-surface-hover, #eef1f4); }
.pgc-auto:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.pgc-hot { margin: 0; font-size: var(--text-sm, .8125rem); color: var(--color-text-muted, #6b7684); }
.pgc-body { display: grid; grid-template-columns: minmax(260px, 340px) 1fr;
  gap: var(--space-5, 1.5rem); padding-top: var(--space-4, 1rem); align-items: start; }
/* Een grid-kind krimpt pas onder z'n min-content als je het zegt; zonder deze nul duwden de
   zoek- en naam-velden de hele pagina breder dan het scherm (gemeten op 420px). */
.pgc-col { min-width: 0; }
.pgc-col-head { display: flex; align-items: center; gap: var(--space-3, .625rem);
  flex-wrap: wrap; margin-bottom: var(--space-3, .625rem); }
.pgc-col-head h2 { margin: 0; font-size: var(--text-base, .9375rem); }
/* Eigen regel: naast de kop bleef er te weinig over en las de placeholder als "Zoek een com". */
.pgc-zoek { flex: 1 1 100%; min-width: 0; min-height: 40px; padding: 0 var(--space-3, .625rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); color: inherit; font: inherit; font-size: var(--text-sm, .8125rem); }
.pgc-groep { margin-bottom: var(--space-4, 1rem); }
.pgc-groep-n { margin: 0 0 var(--space-2, .5rem); font-size: var(--text-xs, .75rem);
  text-transform: uppercase; letter-spacing: .04em; color: var(--color-text-muted, #6b7684); }
.pgc-item { display: flex; align-items: center; gap: var(--space-2, .5rem); width: 100%;
  padding: var(--space-2, .5rem) var(--space-3, .625rem); min-height: 44px;
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); margin-bottom: var(--space-2, .5rem); cursor: grab; }
.pgc-item.dragging { opacity: .5; }
.pgc-item:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.pgc-item.k-worklist .mpc-chip-dot { background: var(--color-primary, #2e7d47); }
.pgc-item.k-drill .mpc-chip-dot { background: #d97706; }
.pgc-item.k-flow .mpc-chip-dot { background: #2563eb; }
.pgc-item.k-singletonDetail .mpc-chip-dot { background: #7c3aed; }
/* Naam bóven, bijschrift eronder. Op één regel vochten ze om dezelfde ruimte en kapte de naam
   af — het enige dat je leest. De title-tooltip draagt alles voluit. */
.pgc-item-tekst { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pgc-item-n { font-weight: 600; font-size: var(--text-sm, .8125rem);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pgc-item-sub { display: flex; gap: var(--space-2, .5rem); min-width: 0;
  font-size: var(--text-xs, .75rem); color: var(--color-text-muted, #6b7684); }
.pgc-item-s { flex: 0 0 auto; }
.pgc-item-p { flex: 0 1 auto; min-width: 0; margin-left: auto;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: var(--font-mono, ui-monospace, monospace); }
/* Niet geplaatst = het werk. Eén zichtbare rand, geen kleurenfeest. */
.pgc-item.is-los { border-color: var(--color-warning, #d97706); }
.pgc-item.is-los .pgc-item-p { color: var(--color-warning, #b45309); font-weight: 600;
  font-family: inherit; }
/* "op de lijst X" is geen waarschuwing maar een plek: gewone bijschrift-kleur, geen mono. */
.pgc-item-p.is-aan { font-family: inherit; }
/* Een scherm dat AAN een component hangt (add-form achter +, detail achter een rij-knop):
   zichtbaar zodat je weet dat de tool 'm kent, maar niet sleepbaar — hij heeft geen eigen plek. */
.pgc-sub { display: flex; align-items: baseline; gap: var(--space-2, .5rem);
  margin: -2px 0 var(--space-2, .5rem) var(--space-5, 1.5rem); font-size: var(--text-xs, .75rem);
  color: var(--color-text-muted, #6b7684); }
.pgc-sub-pijl { flex: none; }
.pgc-sub-n { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pgc-sub-h { margin-left: auto; white-space: nowrap; }
.pgc-addp { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); margin-left: auto;
  flex: 1 1 14rem; min-width: 0; max-width: 26rem; }
.pgc-addp-input { flex: 1 1 8rem; min-height: 40px; min-width: 0; padding: 0 var(--space-3, .625rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); color: inherit; font: inherit; font-size: var(--text-sm, .8125rem); }
.pgc-addp-input.is-leeg { border-color: var(--color-danger, #c0392b);
  box-shadow: 0 0 0 3px var(--color-danger-soft, rgba(192,57,43,.15)); }
.pgc-addp-btn { min-height: 40px; padding: 0 var(--space-3, .625rem); cursor: pointer;
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); font: inherit; font-size: var(--text-sm, .8125rem); font-weight: 600; }
.pgc-addp-btn:hover { border-color: var(--color-primary, #2e7d47); color: var(--mock-primary-ink, #2e7d47); }
.pgc-page { border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-lg, .75rem);
  background: var(--color-bg-surface, #fff); padding: var(--space-3, .625rem) var(--space-4, 1rem);
  margin-bottom: var(--space-3, .625rem); }
.pgc-page.is-landing { border-color: var(--color-primary, #2e7d47); }
/* Net toegevoegd: even oplichten, zodat je ziet WAAR 'ie landde. */
.pgc-page.is-nieuw { border-color: var(--color-primary, #2e7d47);
  box-shadow: 0 0 0 3px var(--color-primary-soft, rgba(46,125,71,.18)); }
@media (prefers-reduced-motion: no-preference) {
  .pgc-page.is-nieuw { transition: box-shadow .2s, border-color .2s; }
}
.pgc-page-head { display: flex; align-items: center; gap: var(--space-2, .5rem);
  flex-wrap: wrap; margin-bottom: var(--space-2, .5rem); }
.pgc-page-n { font-weight: 700; font-size: var(--text-sm, .8125rem); }
.pgc-page-r { font-family: var(--font-mono, ui-monospace, monospace); font-size: var(--text-xs, .75rem);
  color: var(--color-text-muted, #6b7684); }
/* De route is te wijzigen: klik erop (01-10). Secondary i.p.v. muted, want 'm lezen is nu een taak. */
.pgc-route-knop { min-height: 44px; padding: 0 var(--space-2, .5rem); border: 1px dashed transparent; background: none;
  border-radius: var(--radius-md, .5rem); color: var(--color-text-secondary, #4a5563); cursor: text; }
.pgc-route-knop:hover, .pgc-route-knop:focus-visible { border-color: var(--color-border, #dfe4ec); }
.pgc-route-vak { display: inline-flex; flex-direction: column; gap: 2px; }
.pgc-route-invoer { min-height: 44px; min-width: 16rem; padding: 0 var(--space-2, .5rem); font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-sm, .875rem); border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); color: inherit; }
.pgc-route-invoer[aria-invalid="true"] { border-color: var(--color-danger, #c0392b); }
.pgc-route-melding { font-size: var(--text-xs, .75rem); color: var(--color-danger, #c0392b); max-width: 22rem; }
.pgc-route-melding:empty { display: none; }
/* De sleutel van een pagina die bij één ding hoort (08-10): de variabele achter de route + de keuze. */
.pgc-sleutel-vak { display: inline-flex; align-items: center; gap: var(--space-1, .25rem); }
.pgc-route-sleutel { margin-left: calc(-1 * var(--space-2, .5rem)); }
.pgc-sleutel { min-height: 44px; padding: 0 var(--space-2, .5rem); font-size: var(--text-xs, .75rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text-secondary, #4a5563); }
.pgc-landing { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius-md, .5rem);
  background: none; color: var(--color-text-muted, #9aa4b1); font-size: 1rem; }
.pgc-landing:hover { border-color: var(--color-border, #dfe4ec); color: var(--mock-primary-ink, #2e7d47); }
.pgc-landing.is-on { color: var(--mock-primary-ink, #2e7d47); cursor: default; }
.pgc-landing:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
/* ⇥ start na inloggen — zelfde knop-vorm als ⌂, maar aan/uit: nog een klik zet 'm terug. */
.pgc-start { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center;
  justify-content: center; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius-md, .5rem);
  background: none; color: var(--color-text-muted, #9aa4b1); font-size: 1rem; }
.pgc-start:hover { border-color: var(--color-border, #dfe4ec); color: var(--mock-primary-ink, #2e7d47); }
.pgc-start.is-on { color: var(--mock-primary-ink, #2e7d47); }
.pgc-start:focus-visible { outline: 2px solid var(--color-border-focus, #2e7d47); outline-offset: 1px; }
.pgc-menu.is-uit { text-decoration: line-through; }
.pgc-account svg { width: 18px; height: 18px; }
.pgc-account:not(.is-on) { color: var(--color-text-muted, #9aa4b1); }
.pgc-volgorde-paar { display: inline-flex; flex-direction: column; }
.pgc-volgorde-paar .pgc-volgorde { min-width: 32px; min-height: 22px; padding: 0; line-height: 1; }
.pgc-volgorde:disabled { opacity: .35; cursor: default; border-color: transparent; }
.pgc-delp { margin-left: auto; min-width: 44px; min-height: 44px; cursor: pointer;
  border: none; background: none; color: var(--color-text-muted, #9aa4b1); border-radius: var(--radius-md, .5rem); }
.pgc-delp:hover { color: var(--color-danger, #c0392b); background: var(--color-bg-surface-hover, #eef1f4); }
.pgc-chips { min-height: 44px; align-content: center; padding: var(--space-2, .5rem);
  border: 1px dashed var(--color-border, #dfe4ec); border-radius: var(--radius-md, .5rem); }
.pgc-los { border-style: dashed; background: none; }
/* Startpagina per rol (plan 2026-10-01, F6): per rol één keuze, naam links, pagina rechts. */
.pgc-startrol { display: flex; flex-direction: column; gap: var(--space-2, .5rem); padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-lg, .75rem); background: var(--color-bg-surface, #fff); }
.pgc-startrol-kop { margin: 0; font-size: var(--text-base, 1rem); }
.pgc-startrol-uitleg { margin: 0; font-size: var(--text-sm, .875rem); color: var(--color-text-secondary, #4a5563); }
.pgc-startrol-lijst { display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.pgc-startrol-rij { display: grid; grid-template-columns: minmax(8rem, 1fr) minmax(10rem, 1.4fr); gap: var(--space-3, .75rem); align-items: center; }
.pgc-startrol-naam { display: flex; flex-direction: column; font-weight: 600; }
.pgc-startrol-hint { font-weight: 400; font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5563); }
.pgc-startrol-keuze { min-height: 44px; padding: 0 var(--space-2, .5rem); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, .5rem); background: var(--color-bg-surface, #fff); color: inherit; font: inherit; }
.pgc-startrol-keuze:focus-visible { outline: 2px solid var(--mock-primary-ink, #2e7d47); outline-offset: 2px; }
.pgc-startrol-vast { color: var(--color-text-secondary, #4a5563); }
@media (max-width: 40rem) { .pgc-startrol-rij { grid-template-columns: 1fr; } }
@media (max-width: 60rem) {
  .pgc-body { grid-template-columns: 1fr; }
}

body.only-screen .app-header,
body.only-screen .hub-nav,
body.only-screen .app-footer,
body.only-screen .mode-toggle,
body.only-screen .edit-bar { display: none !important; }
body.only-screen { background: var(--color-bg-surface, #fff); }
body.only-screen .app-shell { padding: var(--space-3, .75rem); max-width: none; }

/* ══════════════════════════════════════════════════════════════════════════
   BOUW-CHROME — de steiger, niet het gebouw (alleen editor-geserveerd)
   --------------------------------------------------------------------------
   Zeven gelijkwaardige pillen in de app-header wrapten op 1440px naar twee rijen en op 390px naar
   vijf — ~30% van het scherm voordat je één woord van de app zag. Nu: een eigen, stille strip
   bóven de app, met twee knoppen zichtbaar en de rest onder ⋯. De strip is bewust saai: hij mag
   niet concurreren met het product dat je erin beoordeelt.
   ══════════════════════════════════════════════════════════════════════════ */
.bouw-strip {
  background: var(--color-bg-muted, #eef2f7);
  border-bottom: 1px solid var(--color-border, #dfe4ec);
  padding: 4px var(--space-4, 1rem);
}
.bouw-chrome { display: flex; align-items: center; gap: var(--space-2, .5rem); flex-wrap: nowrap; position: relative; }
.bouw-chrome .mode-toggle {
  font-size: var(--text-xs, .75rem); padding: 3px var(--space-3, .75rem);
  background: transparent; border-color: transparent; color: var(--mock-muted);
}
.bouw-chrome .mode-toggle:hover { background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230); }
.bouw-chrome .mode-toggle.is-on { background: var(--color-bg-surface, #fff); color: var(--mock-primary-ink, #3a7ca5); }
.chrome-more { margin-left: auto; letter-spacing: .08em; }
.chrome-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 90; min-width: 190px;
  padding: var(--space-1, .25rem); display: flex; flex-direction: column; gap: 1px;
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 10px); box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.16));
}
.chrome-menu[aria-hidden="true"] { display: none; }
.chrome-menu .chrome-menu-item {
  width: 100%; justify-content: flex-start; text-align: left; border: 0; background: none;
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-sm, 7px);
  font-size: var(--text-sm, .875rem); color: var(--color-text, #1c2530);
}
.chrome-menu .chrome-menu-item:hover { background: var(--color-bg-surface-hover, #f2f5f9); }
/* De bouw-strip is chrome: bij het printen en in de productie-preview hoort 'ie er niet te zijn. */
@media print { .bouw-strip { display: none; } }

/* Kolom-discipline: wat we uit de tabel lieten, zeggen we eronder — stil weglaten is liegen. */
.kolom-noot {
  margin: var(--space-3, .75rem) 0 0; font-size: var(--text-xs, .75rem);
  color: var(--mock-muted);
}

/* ══════════════════════════════════════════════════════════════════════════
   DONKER — één palet-omkering, alle 18 design-systemen tegelijk
   --------------------------------------------------------------------------
   De mock had geen donkere modus (0× `prefers-color-scheme`), terwijl de tool-chrome die wel heeft
   en de mock straks de ECHTE app is. Wachten tot elk design-systeem z'n eigen donkere palet
   meebrengt zou betekenen: achttien systemen bijwerken vóór er één donker scherm bestaat.

   Daarom keert de renderer de STRUCTURELE tokens om (grond, vlak, rand, tekst) en laat 'ie de
   MERK-tokens staan — die worden alleen opgelicht zodat ze op een donkere grond hun contrast halen
   (`color-mix`, met de kleur zelf als terugval). Zo is elk project meteen donker-waardig zonder
   z'n identiteit te verliezen.

   Een design-systeem dat het beter weet, wint: zet je eigen donkere blok in `style-guide.css` op
   `:root:root` (of `html:root`) — dat is specifieker dan het `:root` hieronder en overrulet 't,
   ook al laadt jouw bestand eerder.

   Drie standen, zoals de artefact-conventie: `data-theme="dark"` en `data-theme="light"` zijn een
   expliciete keuze, geen attribuut = volg het systeem. */
/* ── Afgeleide, gegarandeerd leesbare tinten ────────────────────────────────
   Veel design-systemen kiezen een `--color-text-muted` die er mooi uitziet en 3,2:1 haalt. Voor
   decoratie is dat prima, voor tekst die je moet LEZEN (kolomkoppen, tellingen, de voettekst) niet:
   WCAG eist 4,5:1. In plaats van achttien systemen te corrigeren, leidt de renderer z'n eigen stille
   grijs af uit de tekstkleur die het systeem al heeft — dat blijft dus op-merk, maar het haalt de
   norm. `--mock-*` is renderer-intern: een design-systeem hoeft het niet te kennen (het DS-contract
   slaat dit voorvoegsel over). */
:root {
  --mock-muted: color-mix(in srgb, var(--color-text, #1a2230) 80%, var(--color-bg, #fff));
  --mock-muted-op-vlak: color-mix(in srgb, var(--color-text, #1a2230) 80%, var(--color-bg-subtle, var(--color-bg-surface, #fff)));
}
:root { color-scheme: light; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --color-bg: #12161c;
    --color-bg-subtle: #171c24;
    --color-bg-muted: #1d2430;
    --color-bg-surface: #181e26;
    --color-bg-surface-hover: #212a35;
    --color-surface-2: #1d2430;
    --color-border: #2b3440;
    --color-border-subtle: #232b36;
    --color-border-strong: #3a4553;
    --color-text: #e6eaf0;
    --color-text-heading: #f3f6fa;
    --color-text-secondary: #b8c1cd;
    --color-text-muted: #8b96a5;
    /* Merk-tokens: dezelfde kleur, opgelicht tot ze op donker leesbaar zijn. */
    --color-primary: color-mix(in srgb, var(--color-primary-bright, #3a7ca5) 72%, #ffffff);
    --color-primary-soft: color-mix(in srgb, var(--color-primary-bright, #3a7ca5) 22%, #12161c);
    /* Semantische kleuren krijgen in donker VASTE waarden. Ze afleiden uit de lichte token gaat
       niet: `--color-danger: color-mix(… var(--color-danger) …)` verwijst naar zichzelf, en dan valt
       de hele declaratie terug op de lichte waarde — donkerrood op bijna-zwart, 2,56:1. Het hoeft
       ook niet: rood-is-gevaar is een conventie, geen merk-eigenschap. Het MERK (primary) wordt wél
       uit het palet afgeleid, want dát is wat van het project is. */
    --color-success: #5fd08a;
    --color-success-bg: color-mix(in srgb, var(--color-success, #2e7d47) 24%, #12161c);
    --color-error: #ff7a6e;
    --color-error-bg: color-mix(in srgb, var(--color-error, #c0392b) 24%, #12161c);
    --color-danger: #ff7a6e;
    --color-danger-soft: color-mix(in srgb, var(--color-danger, #c0392b) 24%, #12161c);
    --color-warning: #efc05f;
    --color-warning-bg: color-mix(in srgb, var(--color-warning, #b8791a) 24%, #12161c);
    --shadow-sm: 0 1px 2px rgba(0,0,0,.5);
    --shadow-md: 0 4px 12px rgba(0,0,0,.5);
    --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
    --shadow-xl: 0 24px 64px rgba(0,0,0,.6);
  }
}
/* De expliciete keuze — dezelfde waarden, maar los van wat het systeem wil. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --color-bg: #12161c;
  --color-bg-subtle: #171c24;
  --color-bg-muted: #1d2430;
  --color-bg-surface: #181e26;
  --color-bg-surface-hover: #212a35;
  --color-surface-2: #1d2430;
  --color-border: #2b3440;
  --color-border-subtle: #232b36;
  --color-border-strong: #3a4553;
  --color-text: #e6eaf0;
  --color-text-heading: #f3f6fa;
  --color-text-secondary: #b8c1cd;
  --color-text-muted: #8b96a5;
  --color-primary: color-mix(in srgb, var(--color-primary-bright, #3a7ca5) 72%, #ffffff);
  --color-primary-soft: color-mix(in srgb, var(--color-primary-bright, #3a7ca5) 22%, #12161c);
  --color-success: #5fd08a;
  --color-success-bg: color-mix(in srgb, var(--color-success, #2e7d47) 24%, #12161c);
  --color-error: #ff7a6e;
  --color-error-bg: color-mix(in srgb, var(--color-error, #c0392b) 24%, #12161c);
  --color-danger: #ff7a6e;
  --color-danger-soft: color-mix(in srgb, var(--color-danger, #c0392b) 24%, #12161c);
  --color-warning: #efc05f;
  --color-warning-bg: color-mix(in srgb, var(--color-warning, #b8791a) 24%, #12161c);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.5);
  --shadow-md: 0 4px 12px rgba(0,0,0,.5);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.55);
  --shadow-xl: 0 24px 64px rgba(0,0,0,.6);
}
/* Beeld en logo's zijn voor licht ontworpen; op donker temperen we ze een tik. */
:root[data-theme="dark"] img, :root[data-theme="dark"] .brand-mark svg { filter: brightness(.92); }

/* De dag/nacht-schakelaar — PRODUCT-chrome (de eindgebruiker wil 'm ook), dus in de app-header
   en niet in de bouw-strip. */
.theme-toggle {
  appearance: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; padding: 0; border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--color-border, #dfe4ec); background: var(--color-bg-surface, #fff);
  color: var(--color-text-secondary, #4a5666); font-size: var(--text-sm, .875rem); line-height: 1;
}
.theme-toggle:hover { border-color: var(--color-border-strong, #c2cad6); color: var(--color-text, #1a2230); }

/* ── Donker: de renderer neemt z'n eigen componenten terug ──────────────────
   De token-omkering hierboven werkt voor alles wat een token LEEST. Maar een design-systeem dat
   z'n nav-tabs of chips met een letterlijke kleur opmaakt (`color: #4b5563`) volgt niet mee — en
   dan staat er donkergrijs op bijna-zwart. Deze regels zijn specifieker dan een kale class-regel
   uit het DS, dus in donker wint de renderer op de hooks die van hem zijn. Alleen op renderer-
   eigen classes; de vrije CMS-laag en de landing blijven van de auteur.

   Merk je hier iets missen: dat is een DS dat z'n kleuren hardcodeert. De echte oplossing is dat
   dát systeem tokens gebruikt — dit is het vangnet, niet de norm. */
:root[data-theme="dark"] .hub-tab,
:root[data-theme="dark"] .crumb,
:root[data-theme="dark"] .vh-count,
:root[data-theme="dark"] .search-input,
:root[data-theme="dark"] .form-label { color: var(--color-text-secondary); }
:root[data-theme="dark"] .hub-tab[aria-selected="true"] { color: var(--mock-primary-ink); }
:root[data-theme="dark"] .view-head h1,
:root[data-theme="dark"] .drawer h2,
:root[data-theme="dark"] .wordmark,
:root[data-theme="dark"] .inline-form-title,
:root[data-theme="dark"] h1, :root[data-theme="dark"] h2, :root[data-theme="dark"] h3 { color: var(--color-text-heading); }
:root[data-theme="dark"] .data-table thead th { color: var(--color-text-muted); background: var(--color-bg-subtle); }
:root[data-theme="dark"] .cell-primary { color: var(--color-text-heading); }
:root[data-theme="dark"] .chip { background: var(--color-bg-muted); color: var(--color-text-secondary); border-color: var(--color-border); }
:root[data-theme="dark"] .chip.is-active { background: var(--color-primary); color: #10151b; border-color: transparent; }
:root[data-theme="dark"] .btn-primary { background: var(--color-primary); color: #10151b; }
:root[data-theme="dark"] .btn-secondary { background: var(--color-bg-surface); color: var(--color-text); border-color: var(--color-border); }
:root[data-theme="dark"] .form-control { background: var(--color-bg-surface); color: var(--color-text); border-color: var(--color-border); }
:root[data-theme="dark"] .table-wrap, :root[data-theme="dark"] .drawer,
:root[data-theme="dark"] .form-card { background: var(--color-bg-surface); border-color: var(--color-border); }
:root[data-theme="dark"] body, :root[data-theme="dark"] .app-shell { background: var(--color-bg); color: var(--color-text); }
/* Een sfeerlaag onder de pagina (`body::before` met een verloop) schildert het DS met z'n LICHTE
   palet (`--cyan-50` e.d.): die tokens keert niemand om, dus in donker stond er een lichte baan
   langs de rand (de `.app-shell` hierboven dekt de rest af, dus alleen de marge liet 'm zien).
   In donker vervalt die laag: de grond is de sfeer. */
:root[data-theme="dark"] body::before { background: none; }
/* Dezelfde terugname wanneer de bezoeker het systeem volgt i.p.v. expliciet te kiezen. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hub-tab,
  :root:not([data-theme="light"]) .crumb,
  :root:not([data-theme="light"]) .vh-count,
  :root:not([data-theme="light"]) .search-input,
  :root:not([data-theme="light"]) .form-label { color: var(--color-text-secondary); }
  :root:not([data-theme="light"]) .hub-tab[aria-selected="true"] { color: var(--mock-primary-ink); }
  :root:not([data-theme="light"]) .view-head h1,
  :root:not([data-theme="light"]) .drawer h2,
  :root:not([data-theme="light"]) .wordmark,
  :root:not([data-theme="light"]) .inline-form-title,
  :root:not([data-theme="light"]) h1, :root:not([data-theme="light"]) h2, :root:not([data-theme="light"]) h3 { color: var(--color-text-heading); }
  :root:not([data-theme="light"]) .data-table thead th { color: var(--color-text-muted); background: var(--color-bg-subtle); }
  :root:not([data-theme="light"]) .cell-primary { color: var(--color-text-heading); }
  :root:not([data-theme="light"]) .chip { background: var(--color-bg-muted); color: var(--color-text-secondary); border-color: var(--color-border); }
  :root:not([data-theme="light"]) .chip.is-active { background: var(--color-primary); color: #10151b; border-color: transparent; }
  :root:not([data-theme="light"]) .btn-primary { background: var(--color-primary); color: #10151b; }
  :root:not([data-theme="light"]) .btn-secondary { background: var(--color-bg-surface); color: var(--color-text); border-color: var(--color-border); }
  :root:not([data-theme="light"]) .form-control { background: var(--color-bg-surface); color: var(--color-text); border-color: var(--color-border); }
  :root:not([data-theme="light"]) .table-wrap, :root:not([data-theme="light"]) .drawer,
  :root:not([data-theme="light"]) .form-card { background: var(--color-bg-surface); border-color: var(--color-border); }
  :root:not([data-theme="light"]) body, :root:not([data-theme="light"]) .app-shell { background: var(--color-bg); color: var(--color-text); }
  :root:not([data-theme="light"]) body::before { background: none; }
}

/* De kruimel op het eerste niveau zegt hetzelfde als de H1 eronder — `hidden` moet daar dan ook
   écht verbergen; `.crumbs { display:flex }` won anders van `[hidden]`. */
.crumbs[hidden] { display: none; }

/* ── De start (route `/` voor wie ingelogd is) ──────────────────────────────
   Oriëntatie boven overtuiging: waar ben ik, wat is er, wat is de volgende stap. Geen nieuwe
   componenten — de pagina's die deze rol tóch al mag zien, met hun eigen telling. */
.start-head { margin-bottom: var(--space-6, 1.5rem); }
.start-head h1 { margin: 0 0 var(--space-2, .5rem); }
.start-sub { margin: 0; color: var(--color-text-secondary, #4a5666); }
.start-grid {
  display: grid; gap: var(--space-4, 1rem);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
/* `/start` — een tab per rol (plan 2026-10-01, F5). Alleen design-systeem-tokens: elk project krijgt
   de tabs in z'n eigen look. Op smalle schermen scrollen de tabs horizontaal in plaats van te breken. */
.start-tabs-pagina { display: flex; flex-direction: column; gap: var(--space-6); }
.start-tabs {
  display: flex; gap: var(--space-1); overflow-x: auto; scrollbar-width: thin;
  border-bottom: 1px solid var(--color-border-subtle, var(--color-border));
}
.start-tab {
  flex: none; padding: var(--space-3) var(--space-4); min-height: 44px;
  background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px;
  font: inherit; font-weight: 600; color: var(--color-text-secondary); cursor: pointer;
}
.start-tab:hover { color: var(--color-text-heading, var(--color-text)); }
.start-tab.is-actief { color: var(--color-primary); border-bottom-color: var(--color-primary); }
.start-tab:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: var(--radius-sm, 4px); }
.start-tab-paneel:focus-visible { outline: none; }
.start-tab-admin { display: flex; flex-direction: column; gap: var(--space-4); align-items: flex-start; max-width: 40rem; }
.start-tab-admin p { margin: 0; color: var(--color-text-secondary); }

.start-kaart {
  appearance: none; cursor: pointer; text-align: left; font: inherit;
  display: flex; align-items: baseline; gap: var(--space-2, .5rem);
  padding: var(--space-4, 1rem) var(--space-5, 1.25rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-lg, 12px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.04));
}
.start-kaart:hover { border-color: var(--color-primary, #3a7ca5); }
.start-kaart:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 2px; }
.sk-naam { font-weight: 650; color: var(--color-text-heading, inherit); }
.sk-telling { font-size: var(--text-sm, .875rem); color: var(--color-text-muted, #6b7684); }
.sk-pijl { margin-left: auto; color: var(--color-text-muted, #6b7684); display: inline-flex; }
.sk-pijl svg { width: 16px; height: 16px; }
.start-kop {
  margin: var(--space-8, 2rem) 0 var(--space-3, .75rem); font-size: var(--text-sm, .875rem);
  text-transform: uppercase; letter-spacing: .06em; color: var(--color-text-muted, #6b7684);
}
.start-taken { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); }

/* De deterministische eerste stap in de Studio: vertalen kost geen AI. */
.studio-start { margin: 0 0 var(--space-5, 1.25rem); }
.studio-start-uitleg { margin: var(--space-2, .5rem) 0 0; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
/* Wat je op dít veld kunt vragen — stil, onder het veld, alleen waar er iets te kiezen valt. */
.studio-kan {
  flex: 1 0 100%; padding-left: 1.5rem; margin-top: .1rem;
  font-size: var(--text-xs, .75rem); color: var(--mock-muted); line-height: 1.4;
  overflow-wrap: anywhere;
}
/* Een noot in het contract-paneel: context die geen lijst is (welk drill-niveau, de lege staat). */
.studio-noot {
  margin: var(--space-3, .75rem) 0 var(--space-5, 1.25rem);
  font-size: var(--text-xs, .75rem); color: var(--mock-muted); line-height: 1.5;
}
/* Wat de renderer al doet, en waar de grens van de Studio ligt: twee noten die je één keer leest en
   daarna herkent aan hun streep. Stiller dan een lijst, luider dan niets. */
.studio-doet, .studio-grens {
  padding-left: var(--space-3, .75rem);
  border-left: 2px solid var(--color-border-subtle, #edf1f5);
}

/* Naslag hoort niet als muur in beeld te staan. Eén regel die je openklapt als je 'm nodig hebt. */
.studio-vouw { margin-top: var(--space-3, .75rem); font-size: var(--text-xs, .75rem); }
.studio-vouw > summary {
  cursor: pointer; color: var(--mock-muted); list-style: none;
  padding: .2rem 0; user-select: none;
}
.studio-vouw > summary::-webkit-details-marker { display: none; }
.studio-vouw > summary::before { content: '▸ '; }
.studio-vouw[open] > summary::before { content: '▾ '; }
.studio-vouw > summary:hover { color: var(--color-text, #1a202c); }
.studio-vouw p {
  margin: var(--space-2, .5rem) 0 0; padding-left: var(--space-3, .75rem);
  border-left: 2px solid var(--color-border-subtle, #edf1f5);
  color: var(--mock-muted); line-height: 1.5;
}

/* Eigen opmaak is onzichtbaar in de markup — deze regel is de enige plek waar je 'm ziet staan. */
.studio-opmaak { margin-bottom: var(--space-3, .75rem); }
.studio-opmaak-weg {
  appearance: none; border: 0; background: none; padding: 0; font: inherit; cursor: pointer;
  color: var(--mock-primary-ink, #3a7ca5); text-decoration: underline;
}

/* De chat vóór het eerste woord: zeggen wat hier gebeurt is beter dan een leeg vlak. */
.studio-leeg {
  margin: 0; font-size: var(--text-sm, .875rem); color: var(--mock-muted); line-height: 1.5;
}

/* Een bijgevoegde schermafbeelding, tot je 'm verstuurt. */
.studio-bijlage:empty { display: none; }
.studio-bijlage {
  display: flex; align-items: center; gap: var(--space-2, .5rem);
  padding: var(--space-2, .5rem) var(--space-4, 1rem);
  font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5568);
}
.studio-bijlage-mini {
  width: 2.25rem; height: 2.25rem; object-fit: cover; border-radius: var(--radius-sm, .25rem);
  border: 1px solid var(--color-border, #d8dee6);
}
.studio-bijlage-naam { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.studio-bijlage-weg {
  appearance: none; border: 0; background: none; cursor: pointer; font: inherit;
  color: var(--mock-muted); padding: 0 .25rem;
}
.studio-bijlage-weg:hover { color: var(--color-error, #c53030); }
.studio-chat.is-drop { outline: 2px dashed var(--color-primary, #3a7ca5); outline-offset: -4px; }
.studio-chat-knoppen { display: flex; gap: var(--space-2, .5rem); }
.studio-chat-knoppen .btn { flex: 1 1 auto; }
.studio-chat-knoppen .studio-clip { flex: 0 0 auto; padding-inline: var(--space-3, .75rem); }

/* De voorstellen onder de chat: klikken vult het invoerveld, versturen doe je zelf. */
.studio-chips {
  display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem);
  padding: var(--space-3, .75rem) var(--space-4, 1rem) 0;
}
.studio-chip {
  padding: .3rem var(--space-3, .75rem);
  font: inherit; font-size: var(--text-xs, .75rem); line-height: 1.3;
  color: var(--color-text-secondary, #4a5568); background: var(--color-bg, #f7f9fb);
  border: 1px solid var(--color-border, #d8dee6); border-radius: 999px;
  cursor: pointer; text-align: left;
}
.studio-chip:hover {
  color: var(--color-text, #1a202c); border-color: var(--color-primary, #3a7ca5);
  background: var(--color-bg-surface, #fff);
}
.studio-chip:focus-visible { outline: 2px solid var(--color-primary, #3a7ca5); outline-offset: 2px; }

/* ── Opmaak-werkplek (…/mock/opmaak) ─────────────────────────────────────────────
   Twee werelden. Het WERKSTUK (de pagina) ligt als canvas op een neutrale vloer, in de stijl van
   het design-systeem. Het GEREEDSCHAP (bovenbalk + zijbalk) heeft een eigen, vaste neutrale stijl
   — de stijl van de hub, niet van het project — zodat nooit twijfel is wat bij de pagina hoort.
   Daarom vaste waarden en géén custom properties: alles wat var(--…) leest, is contract met het
   design-systeem (DesignSystemContractDriftTest), en dit hoort daar juist niet bij. */
body.opmaak-mode .bouw-strip, body.opmaak-mode .cms-editbar { display: none; }
body.opmaak-mode { background: #e8ebef; background-image: none; }
body.opmaak-mode main.app-shell { max-width: none; margin: 0; padding: 0; }
.opm { display: flex; flex-direction: column; height: 100vh; }
.opm-bar { flex: 0 0 auto; display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 20px;
  background: #fff; border-bottom: 1px solid #dde1e6; font: 14px/1.4 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; }
.opm-terug { color: #667281; text-decoration: none; }
.opm-terug:hover { color: #3a7ca5; }
.opm-sep { width: 1px; height: 20px; background: #dde1e6; }
.opm-titel { margin: 0; font: 600 15px/1.2 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; }
.opm-pub, .opm-stand { font-size: 12px; color: #667281; border: 1px solid #dde1e6; border-radius: 999px; padding: 1px 9px; }
.opm-stand.is-af { color: #2e7d52; border-color: #b9dcc7; }
.opm-wissel { display: inline-flex; border: 1px solid #dde1e6; border-radius: 999px; overflow: hidden; }
.opm-wissel-k { padding: 3px 12px; font-size: 12.5px; text-decoration: none; color: #667281; }
.opm-wissel-k.is-on { background: #1c2530; color: #fff; }
.opm-open { margin-left: auto; color: #3a7ca5; text-decoration: none; }
.opm-open:hover { text-decoration: underline; }
.opm-body { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 380px; }
.opm-vloer { overflow: auto; padding: 28px 32px 48px; background: #e8ebef; }
.opm-canvas { max-width: 1200px; margin: 0 auto; background: var(--color-bg, #f6f8fb); border-radius: 10px;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 28px rgba(16, 24, 40, .10); overflow: hidden; }
.opm-canvas-inhoud { padding: 28px 32px 40px; }
/* De kopbalk van de app hoort bij het werkstuk: in het canvas, niet vastgeplakt aan het venster. */
.opm-canvas .app-header { position: static; top: auto; }
/* De paginakiezer ís de titel van de balk: één naam, niet twee. */
.opm-kiezer.opm-titel { font: 600 15px/1.2 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; padding: 6px 28px 6px 10px; }
/* Bewerkbare tekst wijst zichzelf aan bij hover, niet de hele tijd — anders is het canvas onrustig. */
body.opmaak-mode.cms-editing .opm-canvas .cms-editable:not(:hover):not(:focus) { outline-color: transparent; }
/* De achtergrond-tint alleen weg bij tekst: een knop (de hero-CTA) verloor anders z'n eigen kleur en
   stond wit-op-wit in de werkplek. */
body.opmaak-mode.cms-editing .opm-canvas .cms-editable:not(:hover):not(:focus):not(.btn):not(button):not(a) { background: none; }
.opm-kiezer { font: 13px -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; background: #fff; border: 1px solid #dde1e6;
  border-radius: 8px; padding: 5px 8px; max-width: 240px; }
.opm-zij { overflow: auto; background: #fff; border-left: 1px solid #dde1e6; padding: 20px 20px 28px;
  font: 14px/1.5 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; }
.opm-zij-kop { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 18px; }
.opm-zij-ic { flex: 0 0 34px; height: 34px; display: grid; place-items: center; border-radius: 9px; background: #eef4f9; font-size: 16px; }
.opm-zij-t { margin: 0 0 2px; font: 600 16px/1.3 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; }
.opm-zij-i { margin: 0; font-size: 13px; color: #667281; }
.opm-zij-k { margin: 0 0 8px; font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; color: #667281; }
.opm-sug { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.opm-sug-k { text-align: left; font: 13px/1.4 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; background: #f5f7f9;
  border: 1px solid #dde1e6; border-radius: 8px; padding: 8px 10px; cursor: pointer; }
.opm-sug-k:hover { border-color: #3a7ca5; background: #eef4f9; }
.opm-zij-voet { margin: 18px 0 0; font-size: 12.5px; color: #667281; }
/* Het gesprek (composePaneel) in de gereedschapsstijl — niet in die van het project. */
.opm-zij .mpc-compose { margin: 0; gap: 10px; }
.opm-zij .mpc-log { max-height: 260px; gap: 6px; }
.opm-zij .mpc-log-r { font: 13px/1.45 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; border-radius: 8px; padding: 7px 10px; }
.opm-zij .mpc-log-r.is-jij { background: #eef4f9; color: #1c2530; }
.opm-zij .mpc-log-r.is-tool { background: #fff; border: 1px solid #dde1e6; color: #1c2530; }
.opm-zij .mpc-input { width: 100%; box-sizing: border-box; min-height: 120px; resize: vertical; font: 14px/1.5 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
  color: #1c2530; background: #fff; border: 1px solid #c9d0d8; border-radius: 8px; padding: 10px 12px; }
.opm-zij .mpc-input:focus { outline: 2px solid #3a7ca5; outline-offset: 0; border-color: #3a7ca5; }
.opm-zij .mpc-compose-voet { justify-content: space-between; }
.opm-zij .mpc-hint { font: 12px -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #667281; }
.opm-zij .mpc-mooi { font: 600 14px/1 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #fff; background: #3a7ca5; border: 0;
  border-radius: 8px; padding: 10px 16px; cursor: pointer; }
.opm-zij .mpc-mooi:hover { background: #2f6486; }
.opm-zij .mpc-mooi:disabled { opacity: .6; cursor: wait; }
/* Opmaken per component (24-09): elk geplaatst component is op het canvas aan te klikken. De omlijning
   staat BUITEN het component (outline-offset) zodat 'ie de vorm die je beoordeelt niet raakt. */
.opm-canvas .mock-component[data-screen] { position: relative; cursor: pointer; outline: 2px solid transparent; outline-offset: 6px;
  border-radius: 4px; transition: outline-color .12s; }
.opm-canvas .mock-component[data-screen] * { cursor: pointer; }
.opm-canvas .mock-component[data-screen]:hover { outline: 2px dashed #3a7ca5; }
.opm-canvas .mock-component[data-screen].is-opm-gekozen { outline: 2px solid #3a7ca5; }
.opm-canvas .mock-component[data-screen]::before { content: attr(data-opm-naam); position: absolute; z-index: 5; left: -6px; top: -30px;
  font: 600 11.5px/1 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #fff; background: #3a7ca5;
  border-radius: 6px 6px 6px 0; padding: 5px 8px; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity .12s; }
.opm-canvas .mock-component[data-screen]:hover::before,
.opm-canvas .mock-component[data-screen].is-opm-gekozen::before { opacity: 1; }
/* Een component in een component (bv. een formulier op een lijst): alleen de binnenste lijnt op bij hover. */
.opm-canvas .mock-component[data-screen]:has(.mock-component[data-screen]:hover) { outline-color: transparent; }
.opm-canvas .mock-component[data-screen]:has(.mock-component[data-screen]:hover)::before { opacity: 0; }
.opm-kruimel { display: flex; align-items: center; gap: 6px; margin: -4px 0 14px; font-size: 13px; }
.opm-kruimel-terug { font: 13px -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #3a7ca5; background: none; border: 0;
  padding: 2px 0; cursor: pointer; }
.opm-kruimel-terug:hover { text-decoration: underline; }
.opm-kruimel-sep { color: #9aa4b1; }
.opm-kruimel-hier { font-weight: 600; color: #1c2530; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.opm-comp-stand { margin: 0 0 6px; font-size: 13px; color: #1c2530; }
.opm-comp-stand.is-eigen b { color: #3a7ca5; }
.opm-comp-scope { margin: 0 0 16px; font-size: 12.5px; color: #667281; }
.opm-zij .mpc-log-r.is-fout { border-color: #e2b4ae; color: #a4332a; }
.opm-zij .mpc-log-r.is-bezig { color: #667281; font-style: italic; }
.opm-zij .opm-sug-k:disabled { opacity: .55; cursor: default; }
.opm-comp-acties { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; padding-top: 14px; border-top: 1px solid #eef0f3; }
.opm-comp-actie { font: 13px -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; background: #fff;
  border: 1px solid #dde1e6; border-radius: 8px; padding: 6px 10px; cursor: pointer; }
.opm-comp-actie:hover { border-color: #3a7ca5; color: #3a7ca5; }
.opm-comp-actie:disabled { opacity: .55; cursor: default; }
/* Stap 3: de "Op deze pagina"-lijst in het zijpaneel, in de gereedschapsstijl. */
.opm-lijst { margin-top: 22px; padding-top: 6px; border-top: 1px solid #eef0f3; }
.opm-lijst .mpc-sub-kop { font: 600 11.5px/1.3 -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; letter-spacing: .04em; color: #667281; }
.opm-lijst .mpc-chip, .opm-lijst .mpc-toevoeg-rij { font-family: -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; }
.opm-lijst .mpc-chips.is-stapel .mpc-chip { cursor: pointer; }
.opm-lijst .mpc-chips.is-stapel .mpc-chip:hover { border-color: #3a7ca5; }
.opm-lijst .mpc-hint-regel { font-size: 12px; color: #667281; }
/* Stap 4: overal of alleen op deze pagina. */
.opm-scope { margin: 0 0 16px; }
.opm-scope-seg { display: inline-flex; border: 1px solid #dde1e6; border-radius: 8px; overflow: hidden; margin-bottom: 8px; }
.opm-scope-k { font: 13px -apple-system, "Segoe UI", Roboto, system-ui, sans-serif; color: #1c2530; background: #fff; border: 0;
  padding: 6px 12px; cursor: pointer; }
.opm-scope-k + .opm-scope-k { border-left: 1px solid #dde1e6; }
.opm-scope-k.is-on { background: #3a7ca5; color: #fff; cursor: default; }
.opm-scope-k:not(.is-on):hover { background: #eef4f9; }
.opm-scope-k:disabled { opacity: .55; cursor: default; }
.opm-scope .opm-comp-scope { margin: 0 0 8px; }
.opm-comp-stand.is-variant b { color: #b45309; }
.opm-zij .studio-bijlage { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: #667281; }

@media (max-width: 1000px) {
  .opm { height: auto; }
  .opm-body { grid-template-columns: 1fr; }
  .opm-zij { border-left: 0; border-top: 1px solid #dde1e6; }
}
.pgc-opmaak { font-size: .8rem; text-decoration: none; color: var(--mock-primary-ink, #2e7d47);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: 999px; padding: 2px 10px; white-space: nowrap; }
.pgc-opmaak:hover { border-color: var(--color-primary, #2e7d47); }
.pgc-opmaak.is-af { color: var(--color-text-muted, #5b6675); }
.pgc-bekijk { font-size: .8rem; text-decoration: none; color: var(--color-text-muted, #5b6675); padding: 2px 6px; white-space: nowrap; }
.pgc-bekijk:hover { color: var(--mock-primary-ink, #2e7d47); text-decoration: underline; }

/* ══════════════════════════════════════════════════════════════════════════
   KAART — LOCATION-velden en -kolommen (Leaflet + PDOK; gedrag in app.js, blok KAART)
   Alleen bestaande tokens: een design-systeem hoeft voor de kaart niets nieuws te leveren. De
   tegelstijl kiest het DS met `--map-tiles` (grijs · pastel · standaard · water) — die leest app.js,
   niet deze CSS, dus hij telt niet mee in het token-contract.
   Tinten: pinnen kleuren per soort (status/categorie) uit vijf tokens die elk DS al heeft.
   ══════════════════════════════════════════════════════════════════════════ */
.geo-kaart {
  position: relative; width: 100%; overflow: hidden; isolation: isolate;
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-lg, 12px);
  background: var(--color-bg-muted, #eef2f7); font-family: inherit;
}
.geo-kaart:focus-visible { outline: 3px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 2px; }
.geo-kaart-kiezer { height: clamp(220px, 38svh, 320px); }
.geo-kaart-lijst { height: clamp(260px, 46svh, 440px); }
.geo-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Leaflet-chrome in de taal van het DS. */
.geo-kaart .leaflet-bar { border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px); box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.08)); overflow: hidden; }
.geo-kaart .leaflet-bar a { background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230); border-bottom-color: var(--color-border, #dfe4ec); }
.geo-kaart .leaflet-bar a:hover { background: var(--color-bg-surface-hover, #f7f9fc); }
.geo-kaart .leaflet-control-attribution { font-size: 10px; background: color-mix(in srgb, var(--color-bg-surface, #fff) 80%, transparent); color: var(--color-text-secondary, #4a5666); }
.geo-kaart .leaflet-control-attribution a { color: inherit; }
/* Duimvriendelijk: op touch zijn de zoomknoppen een echt tikdoel (WCAG 2.5.8, NN/g 44px). */
@media (pointer: coarse) {
  .geo-kaart .leaflet-bar a { width: 44px; height: 44px; line-height: 44px; font-size: 22px; }
}
/* De twee-vingers-hint: verschijnt alleen als je met één vinger over de kaart sleept. */
.geo-gebaar {
  position: absolute; inset: 0; z-index: 1000; display: grid; place-items: center; padding: var(--space-6, 1.5rem);
  background: rgba(15, 23, 35, .55); color: #fff; font-weight: 600; font-size: var(--text-sm, .875rem); text-align: center;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.geo-gebaar.is-zichtbaar { opacity: 1; }

/* ── Het form-veld ── */
.geo-veld { gap: var(--space-2, .5rem); }
.geo-zoek { position: relative; }
.geo-zoek-ico { position: absolute; left: var(--space-3, .75rem); top: 50%; transform: translateY(-50%); display: inline-flex; color: var(--mock-muted); pointer-events: none; }
.geo-zoek-ico svg { width: 16px; height: 16px; }
.geo-zoek-input { width: 100%; padding-left: calc(var(--space-3, .75rem) + 22px); }
.geo-zoek-input { padding-right: 44px; }
/* De native webkit-X is blauw en niet te stylen; we hebben een eigen wis-knop. */
.geo-zoek-input::-webkit-search-cancel-button, .geo-zoek-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.geo-zoek-wis {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; cursor: pointer;
  border-radius: var(--radius-pill, 999px); background: none; color: var(--mock-muted);
}
.geo-zoek-wis:hover { background: var(--color-bg-muted, #eef2f7); color: var(--color-text, #1a2230); }
.geo-zoek-wis:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 1px; }
.geo-zoek-wis svg { width: 16px; height: 16px; }
.geo-zoek-wis[hidden] { display: none; }
.geo-opties {
  position: absolute; z-index: 1100; left: 0; right: 0; top: calc(100% + 4px); margin: 0; padding: var(--space-1, .25rem);
  list-style: none; max-height: min(50svh, 320px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-md, 10px); box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.14));
}
.geo-optie {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3, .75rem);
  min-height: 44px; padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-sm, 6px);
  cursor: pointer; font-size: var(--text-sm, .875rem); color: var(--color-text, #1a2230);
}
.geo-optie:hover, .geo-optie[aria-selected="true"] { background: var(--color-primary-soft, #e3eef5); }
.geo-optie[aria-selected="true"] { box-shadow: inset 3px 0 0 var(--color-primary, #3a7ca5); }
.geo-optie-naam { min-width: 0; overflow-wrap: anywhere; }
.geo-optie-soort { flex: none; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.geo-hint { margin: 0; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.geo-voet { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2, .5rem) var(--space-3, .75rem); }
.geo-coord-label { font-size: var(--text-xs, .75rem); font-weight: 600; color: var(--color-text-secondary, #4a5666); }
.geo-coord { flex: 0 1 13.5rem; min-width: 0; font-family: var(--font-mono, ui-monospace, monospace); font-size: var(--text-xs, .8rem); font-variant-numeric: tabular-nums; }
.geo-plek { flex: 1 1 12rem; min-width: 0; font-size: var(--text-xs, .75rem); color: var(--mock-muted); overflow-wrap: anywhere; }
.geo-plek:empty { display: none; }
.geo-mijn { margin-left: auto; }
.geo-mijn[aria-busy="true"] { opacity: .6; cursor: progress; }
.geo-status { margin: 0; font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5666); min-height: 1em; }
.geo-status:empty { min-height: 0; }
@media (pointer: coarse) { .geo-mijn { min-height: 44px; } }

/* De kiespin: een druppel in de merkkleur, 44×44 tikdoel, de punt op de plek. */
.geo-kiespin-host { background: none; border: 0; }
.geo-kiespin {
  position: absolute; left: 50%; top: 4px; width: 28px; height: 28px; margin-left: -14px; box-sizing: border-box;
  border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
  background: var(--color-primary, #3a7ca5); border: 3px solid var(--color-bg-surface, #fff);
  box-shadow: var(--shadow-md, 0 4px 12px rgba(0,0,0,.25));
}
.geo-kiespin::after { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--color-bg-surface, #fff); }
.leaflet-dragging .geo-kiespin { box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.3)); }

/* ── De lijst met kaart ── */
.geo-lijst { display: grid; gap: var(--space-4, 1rem); }
.geo-lijst-kaart { display: flex; flex-direction: column; gap: var(--space-2, .5rem); min-width: 0; }
.geo-lijst-tabel { min-width: 0; }
.geo-lijst .geo-kolom-weg { display: none; }
.geo-noot { margin: 0; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.geo-legenda { display: flex; flex-wrap: wrap; gap: var(--space-1, .25rem) var(--space-3, .75rem); margin: 0; padding: 0; list-style: none; font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5666); }
.geo-legenda li { display: inline-flex; align-items: center; gap: 6px; }
.geo-stip { width: 10px; height: 10px; border-radius: 50%; background: var(--mock-geo-tint); }
@media (min-width: 60rem) {
  .geo-lijst { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); align-items: start; }
  .geo-lijst-kaart { order: 2; position: sticky; top: var(--space-4, 1rem); }
  .geo-kaart-lijst { height: min(70vh, 620px); }
}
.data-table tbody tr.is-geo-actief { background: var(--color-primary-soft, #e3eef5); }
.data-table tbody tr.is-geo-actief .cell-primary { box-shadow: inset 3px 0 0 var(--color-primary, #3a7ca5); }
@media (max-width: 48rem) {
  .data-table tbody tr.is-geo-actief { border-color: var(--color-primary, #3a7ca5); }
  .data-table tbody tr.is-geo-actief .cell-primary { box-shadow: none; }
}
.geo-cel { font-size: var(--text-xs, .8rem); white-space: nowrap; }
/* Een map-cel: per sleutel een regel, de sleutel als klein opschrift ervoor ("crm: beheerder, lezer"). */
.map-cel { display: inline-flex; flex-direction: column; gap: var(--space-1, .125rem); }
.map-regel { white-space: nowrap; }
.map-sleutel { font-weight: 600; color: var(--color-text-secondary); margin-right: var(--space-1, .25rem); }
.map-sleutel::after { content: ':'; }

/* Tinten per soort — vijf tokens die elk DS heeft. `--mock-*` = renderer-intern (buiten het DS-contract). */
.geo-tint-0 { --mock-geo-tint: var(--color-primary, #3a7ca5); }
.geo-tint-1 { --mock-geo-tint: var(--color-warning, #b8791a); }
.geo-tint-2 { --mock-geo-tint: var(--color-success, #2e7d47); }
.geo-tint-3 { --mock-geo-tint: var(--color-primary-bright, #5a9cc5); }
.geo-tint-4 { --mock-geo-tint: var(--color-text-secondary, #4a5666); }

/* De pin van een rij: een compacte bubbel met de naam, een rand in de tint van z'n soort en een
   punt eronder op de exacte plek. Geen standaard-marker: de plek zelf is de inhoud. */
.geo-pin-host { background: none; border: 0; overflow: visible; }
.geo-pin-host:focus { outline: none; }
.geo-pin {
  position: absolute; left: 0; top: 0; transform: translate(-50%, calc(-100% - 9px));
  display: inline-flex; align-items: center; min-height: 32px; max-width: 12rem; padding: 0 var(--space-3, .75rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text-heading, #1a2230);
  border: 2px solid var(--mock-geo-tint); border-radius: var(--radius-pill, 999px);
  box-shadow: var(--shadow-md, 0 4px 12px rgba(0,0,0,.18));
  font: 700 var(--text-xs, .75rem)/1.1 var(--font-heading, inherit); white-space: nowrap; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease;
}
/* Onzichtbare rand: het tikdoel is groter dan wat je ziet. */
.geo-pin::before { content: ""; position: absolute; inset: -6px; }
/* Het puntje onder de bubbel + de stip op de plek. */
.geo-pin::after {
  content: ""; position: absolute; left: 50%; bottom: -9px; width: 10px; height: 10px; margin-left: -5px;
  border-radius: 50%; background: var(--mock-geo-tint); border: 2px solid var(--color-bg-surface, #fff);
  box-shadow: 0 1px 3px rgba(0,0,0,.3);
}
.geo-pin-label { overflow: hidden; text-overflow: ellipsis; }
.geo-pin-host.is-actief .geo-pin, .geo-pin-host:hover .geo-pin, .geo-pin-host:focus-visible .geo-pin {
  transform: translate(-50%, calc(-100% - 9px)) scale(1.08);
  background: var(--mock-geo-tint); color: var(--color-text-on-primary, #fff); box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.25));
}
.geo-pin-host:focus-visible .geo-pin { outline: 3px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 2px; }
/* Veel pinnen: alleen de stip; het label komt bij aanwijzen/focus/actief. */
.geo-pin.is-compact { min-height: 0; padding: 0; border: 0; background: none; box-shadow: none; transform: translate(-50%, -50%); }
.geo-pin.is-compact .geo-pin-label { display: none; }
.geo-pin.is-compact::after { position: static; display: block; width: 16px; height: 16px; margin: 0; }
.geo-pin.is-compact::before { inset: -14px; }
.geo-pin-host.is-actief .geo-pin.is-compact, .geo-pin-host:hover .geo-pin.is-compact, .geo-pin-host:focus-visible .geo-pin.is-compact {
  min-height: 32px; padding: 0 var(--space-3, .75rem); border: 2px solid var(--mock-geo-tint); transform: translate(-50%, calc(-100% - 9px));
}
.geo-pin-host.is-actief .geo-pin.is-compact .geo-pin-label, .geo-pin-host:hover .geo-pin.is-compact .geo-pin-label,
.geo-pin-host:focus-visible .geo-pin.is-compact .geo-pin-label { display: inline; }
.geo-pin-host.is-actief .geo-pin.is-compact::after, .geo-pin-host:hover .geo-pin.is-compact::after,
.geo-pin-host:focus-visible .geo-pin.is-compact::after { position: absolute; width: 10px; height: 10px; margin-left: -5px; }
@media (prefers-reduced-motion: reduce) { .geo-pin { transition: none; } }

/* De popup: een kaartje in het DS, niet Leaflet's standaardballon. */
.geo-popup-host .leaflet-popup-content-wrapper {
  padding: 0; overflow: hidden; border-radius: var(--radius-lg, 12px);
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230); box-shadow: var(--shadow-lg, 0 12px 32px rgba(0,0,0,.2));
}
.geo-popup-host .leaflet-popup-tip { background: var(--color-bg-surface, #fff); }
.geo-popup-host .leaflet-popup-content { margin: 0; font-family: inherit; font-size: var(--text-sm, .875rem); line-height: 1.4; }
.geo-popup-host a.leaflet-popup-close-button { width: 32px; height: 32px; font-size: 22px; line-height: 30px; color: var(--color-text-secondary, #4a5666); }
.geo-popup { display: flex; flex-direction: column; gap: var(--space-2, .5rem); padding: var(--space-4, 1rem); }
.geo-popup-foto { display: block; width: calc(100% + 2 * var(--space-4, 1rem)); max-width: none; height: 132px; object-fit: cover; margin: calc(-1 * var(--space-4, 1rem)) calc(-1 * var(--space-4, 1rem)) 0; }
.geo-popup-titel { margin: 0; padding-right: var(--space-6, 1.5rem); font: 700 var(--text-base, 1rem)/1.25 var(--font-heading, inherit); color: var(--color-text-heading, inherit); }
.geo-popup-velden { display: grid; gap: 2px; margin: 0; font-size: var(--text-xs, .8rem); }
.geo-popup-velden > div { display: flex; gap: var(--space-2, .5rem); }
.geo-popup-velden dt { flex: none; min-width: 5.5rem; color: var(--mock-muted); }
.geo-popup-velden dd { margin: 0; min-width: 0; overflow-wrap: anywhere; color: var(--color-text, #1a2230); }
.geo-popup-meer { align-self: flex-start; margin-top: var(--space-1, .25rem); }
@media (max-width: 48rem) { .geo-popup-foto { height: 88px; } }
@media (pointer: coarse) { .geo-popup-meer { min-height: 44px; } }

/* Foto-miniatuur in een cel (IMAGE-kolom). */
.cel-thumb { display: block; width: 40px; height: 40px; object-fit: cover; border-radius: var(--radius-sm, 6px); background: var(--color-bg-muted, #eef2f7); }
.cel-thumbs { display: inline-flex; align-items: center; gap: 6px; }
.cel-thumb-meer { font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.detail-row dd .cel-thumb { width: 96px; height: 72px; }

/* Donker: de gedempte kaart omgekeerd, zodat de kaart niet het felste vlak van het scherm is. */
:root[data-theme="dark"] .geo-kaart .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.85) contrast(.9); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .geo-kaart .leaflet-tile-pane { filter: invert(1) hue-rotate(180deg) brightness(.85) contrast(.9); }
}

/* ══════════════════════════════════════════════════════════════════════════
   FOTO'S, ENUM-CHIPS, LEGE BEELDEN (gedrag in app.js, blokken FOTO'S / Beelden / Enums)
   ══════════════════════════════════════════════════════════════════════════ */
/* Een lege beeldplek: een rustige tegel met een beeld-icoon — nooit een bestandsnaam. */
.beeld-leeg {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  background: repeating-linear-gradient(135deg, var(--color-bg-muted, #eef2f7) 0 8px, var(--color-bg-subtle, #f4f6f9) 8px 16px);
  color: var(--mock-muted); border: 1px solid var(--color-border-subtle, #eef1f6);
}
.beeld-leeg svg { width: 45%; height: 45%; max-width: 28px; max-height: 28px; opacity: .7; }
.geo-popup-foto.beeld-leeg { display: flex; height: 72px; }
.detail-foto.beeld-leeg { width: 96px; height: 72px; border-radius: var(--radius-md, 10px); }
.detail-fotos { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); justify-content: flex-end; }
.detail-fotos .detail-foto { width: 96px; height: 72px; object-fit: cover; border-radius: var(--radius-md, 10px); background: var(--color-bg-muted, #eef2f7); }
.detail-fotos .detail-foto:first-child:not(:only-child) { width: 100%; height: auto; aspect-ratio: 16 / 9; }

/* Enum-lijst als chips; de stip draagt de kleur van de waarde (`--cat-<code>` of de rotatie). */
.cat-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; justify-content: inherit; }
.cat-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px 2px 8px; white-space: nowrap;
  border-radius: var(--radius-pill, 999px); border: 1px solid var(--color-border, #dfe4ec);
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230);
  font-size: var(--text-xs, .75rem); font-weight: 600; line-height: 1.5;
}
.cat-chip::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--mock-geo-tint); }

/* Foto-cel in de tabel: een vierkante duimnagel, de kolom zo smal als de foto. */
.data-table td.cell-image { width: 1%; padding-top: var(--space-2, .5rem); padding-bottom: var(--space-2, .5rem); }
.data-table td.cell-image .cel-thumb { width: 48px; height: 48px; }
@media (max-width: 48rem) {
  /* Op een telefoon is de foto de kop-afbeelding van het kaartje, bovenaan en van rand tot rand. */
  .data-table tbody tr:has(> td.cell-image) { display: flex; flex-direction: column; overflow: hidden; padding-top: 0; }
  .data-table tbody td.cell-image {
    order: -1; display: block; width: auto; padding: 0; border-bottom: 0;
    margin: 0 calc(-1 * var(--space-4, 1rem)) var(--space-1, .25rem);
  }
  .data-table tbody td.cell-image::before { content: none; }
  .data-table tbody td.cell-image .cel-thumb, .data-table tbody td.cell-image .cel-thumbs {
    display: flex; width: 100%; height: auto; aspect-ratio: 16 / 9; border-radius: 0; object-fit: cover; border: 0;
  }
  .data-table tbody td.cell-image .cel-thumbs { position: relative; }
  .data-table tbody td.cell-image .cel-thumbs .cel-thumb { width: 100%; height: 100%; aspect-ratio: auto; }
  .data-table tbody td.cell-image .cel-thumb-meer {
    position: absolute; right: var(--space-3, .75rem); bottom: var(--space-3, .75rem); padding: 2px 8px;
    border-radius: var(--radius-pill, 999px); background: rgba(15, 23, 35, .6); color: #fff; font-weight: 600;
  }
  .data-table tbody td.cell-image .beeld-leeg { aspect-ratio: 16 / 7; border: 0; }
  .data-table tbody td .cat-chips { justify-content: flex-end; }
}

/* ── Het foto-veld ── */
.foto-hint { margin: 0; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.foto-invoer { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.foto-tegels {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--space-2, .5rem);
  margin: 0; padding: 0; list-style: none; border-radius: var(--radius-lg, 12px);
}
.foto-tegels.is-doel { outline: 2px dashed var(--color-primary, #3a7ca5); outline-offset: 4px; }
.foto-tegel {
  position: relative; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-md, 10px);
  background: var(--color-bg-muted, #eef2f7); border: 1px solid var(--color-border, #dfe4ec);
}
.foto-tegels.is-multi .foto-tegel.is-omslag { grid-column: span 2; grid-row: span 2; }
.foto-tegel img { display: block; width: 100%; height: 100%; object-fit: cover; }
.foto-tegel[draggable="true"] { cursor: grab; }
.foto-tegel.is-slepend { opacity: .45; }
.foto-tegel.is-doel { outline: 3px solid var(--color-primary, #3a7ca5); outline-offset: -3px; }
.foto-omslag {
  position: absolute; left: var(--space-2, .5rem); top: var(--space-2, .5rem); padding: 2px 8px;
  border-radius: var(--radius-pill, 999px); background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff);
  font-size: var(--text-xs, .75rem); font-weight: 700; letter-spacing: .02em;
}
.foto-knop {
  display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: var(--radius-pill, 999px); cursor: pointer;
  background: rgba(15, 23, 35, .62); color: #fff; backdrop-filter: blur(4px);
}
.foto-knop svg { width: 16px; height: 16px; }
.foto-knop:hover { background: rgba(15, 23, 35, .82); }
.foto-knop:focus-visible { outline: 3px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 1px; }
.foto-knop:disabled { opacity: .35; cursor: default; }
.foto-knop::before { content: ""; position: absolute; inset: -6px; }
.foto-knop { position: relative; }
.foto-weg { position: absolute; right: 6px; top: 6px; }
.foto-volgorde { position: absolute; left: 6px; right: 6px; bottom: 6px; display: flex; justify-content: space-between; }
.foto-tegel.is-bezig { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2, .5rem);
  font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5666); }
.foto-spinner { width: 22px; height: 22px; border-radius: 50%; border: 3px solid var(--color-border, #dfe4ec); border-top-color: var(--color-primary, #3a7ca5); animation: foto-draai .8s linear infinite; }
@keyframes foto-draai { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .foto-spinner { animation-duration: 2.4s; } }
.foto-plus { border-style: dashed; background: var(--color-bg-surface, #fff); }
.foto-toevoegen {
  width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  padding: var(--space-2, .5rem); border: 0; background: none; cursor: pointer; font: inherit;
  font-size: var(--text-xs, .75rem); font-weight: 600; color: var(--mock-primary-ink, #3a7ca5); text-align: center;
}
.foto-toevoegen:hover { background: var(--color-primary-soft, #e3eef5); }
.foto-toevoegen:focus-visible { outline: 3px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: -3px; }
.foto-toevoegen[aria-invalid="true"] { box-shadow: inset 0 0 0 2px var(--color-error, #c0392b); }
.foto-toevoegen-ico svg { width: 28px; height: 28px; }
.foto-status { margin: 0; font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5666); }
.foto-status:empty { display: none; }

/* Ronde 2 (09-30), mobiel-polish rond kaart, foto's en de lade. */
.geo-lijst { margin-top: var(--space-3, .75rem); }
.geo-popup-foto.beeld-leeg { height: 56px; }
/* In de lade IS de lade de kaart — een formulier-kaart daarbinnen is kaart-in-kaart en kost op een
   telefoon twee keer de binnenmarge (zelfde regel als `.inline-form .form-wrapper`). */
.drawer .form-wrapper { border: 0; box-shadow: none; background: none; padding: 0; }
@media (max-width: 48rem) {
  .drawer-body { padding: var(--space-4, 1rem); }
  .drawer-foot { padding-bottom: max(var(--space-4, 1rem), env(safe-area-inset-bottom)); }
  /* Een lege foto is op een kaartje een smalle band, geen halve scherm-hoogte grijs. */
  .data-table tbody td.cell-image .beeld-leeg { aspect-ratio: auto; height: 56px; }
  .geo-pin { max-width: 9.5rem; }
}
@media (max-width: 48rem) {
  /* Naast een kaart zegt een coördinaat op een kaartje niets wat de pin niet beter zegt. */
  .geo-lijst .data-table tbody td:has(> .geo-cel) { display: none; }
}

/* ── Foto-upload (app): voortgang en fout op de tegel ─────────────────────────────────────
   In de gegenereerde app gaat elke foto meteen naar `POST /upload`; zolang dat loopt of mislukt
   staat hij als tegel met een balk of een melding + "Opnieuw" (app.js, renderFotoVeld → stuur). */
.foto-tegel.is-upload img { opacity: .6; }
.foto-voortgang { position: absolute; left: 8px; right: 8px; bottom: 8px; height: 6px; border-radius: 3px;
  background: color-mix(in srgb, var(--color-bg-surface, #fff) 80%, transparent); overflow: hidden; }
.foto-voortgang > span { display: block; height: 100%; width: 0; background: var(--color-primary, #3a7ca5); transition: width .2s ease; }
.foto-tegel.is-fout { outline: 2px solid var(--color-error, #b3261e); outline-offset: -2px; }
.foto-uploadfout { position: absolute; inset: auto 6px 6px 6px; display: flex; flex-direction: column; gap: 4px;
  padding: 6px; border-radius: var(--radius-sm, 6px); font-size: var(--text-xs, .75rem); line-height: 1.3;
  background: var(--color-bg-surface, #fff); color: var(--color-error, #b3261e); }
@media (prefers-reduced-motion: reduce) { .foto-voortgang > span { transition: none; } }

/* ── KAART-LIJST: naast een kaart is de lijst een medialijst ──────────────────────────────
   Naast de kaart is er de ruimte niet voor een tabel: een foto-, naam-, sporten- en ondergrond-
   kolom in een halve breedte gaf een horizontale scrollbalk, en informatie achter een scroll is
   informatie die je niet ziet (gebruiker, 30-09). Dus op élke breedte: per plek één regel met
   een vierkante foto links en daarnaast naam, chips en de rest — zoals je het van een
   kaart-app kent. De thead blijft voor schermlezers in de DOM.
   Alles hangt onder `.geo-lijst .geo-lijst-tabel`: de mobiele kaartjes-regels hierboven
   (`.data-table tbody tr:has(> td.cell-image)`) wegen anders zwaarder en winnen. */
.geo-lijst .geo-lijst-tabel .table-wrap { overflow: visible; border: 0; background: none; box-shadow: none; border-radius: 0; }
.geo-lijst .geo-lijst-tabel .data-table { display: block; width: 100%; border: 0; background: none; }
.geo-lijst .geo-lijst-tabel .data-table thead {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.geo-lijst .geo-lijst-tabel .data-table tbody { display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.geo-lijst .geo-lijst-tabel .data-table tbody tr {
  display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--space-4, 1rem); row-gap: 4px;
  align-content: start; margin: 0; padding: var(--space-3, .75rem);
  background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border-subtle, #eef1f6);
  border-radius: var(--radius-lg, 12px); box-shadow: none; overflow: visible;
  transition: border-color .15s, box-shadow .15s;
}
.geo-lijst .geo-lijst-tabel .data-table tbody tr:has(> td.cell-image) { grid-template-columns: 72px minmax(0, 1fr); }
.geo-lijst .geo-lijst-tabel .data-table tbody tr.row-clickable { cursor: pointer; }
.geo-lijst .geo-lijst-tabel .data-table tbody tr.row-clickable:hover,
.geo-lijst .geo-lijst-tabel .data-table tbody tr.is-geo-actief { border-color: var(--color-primary, #3a7ca5); box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.06)); }
.geo-lijst .geo-lijst-tabel .data-table tbody td {
  display: block; grid-column: -2; width: auto; min-width: 0; margin: 0; padding: 0; border: 0;
  text-align: left; white-space: normal; overflow-wrap: anywhere; background: none;
  font-size: var(--text-sm, .875rem); color: var(--color-text-secondary, #4a5666);
}
.geo-lijst .geo-lijst-tabel .data-table tbody td::before {
  content: attr(data-label) " "; display: inline; margin: 0; font-size: inherit; font-weight: 600;
  letter-spacing: 0; text-transform: none; color: var(--color-text-muted, #6b7684);
}
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-primary,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-actions,
.geo-lijst .geo-lijst-tabel .data-table tbody td:has(.cat-chips) { font-size: inherit; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-primary::before,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image::before,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-actions::before,
.geo-lijst .geo-lijst-tabel .data-table tbody td:has(.cat-chips)::before { content: none; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-primary {
  font-size: var(--text-base, 1rem); font-weight: 650; line-height: var(--leading-snug, 1.3);
  color: var(--color-text-heading, var(--color-text, #1a2230));
}
.geo-lijst .geo-lijst-tabel .data-table tbody td .cat-chips { justify-content: flex-start; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image { grid-column: 1; grid-row: 1 / span 4; align-self: start; order: 0; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .cel-thumb,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .cel-thumbs,
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .beeld-leeg {
  display: block; position: relative; width: 72px; height: 72px; aspect-ratio: 1; margin: 0;
  border-radius: var(--radius-md, 10px); object-fit: cover; overflow: hidden; border: 0;
}
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .cel-thumbs .cel-thumb { width: 100%; height: 100%; border-radius: 0; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .cel-thumb-meer {
  position: absolute; right: 4px; bottom: 4px; padding: 0 6px; font-size: var(--text-xs, .75rem); font-weight: 700;
  border-radius: var(--radius-pill, 999px); background: rgba(15, 23, 35, .65); color: #fff;
}
/* De coördinatenkolom naast de kaart (renderKaartLijst zet `geo-kolom-weg`) — zwaarder dan de
   td-regel hierboven, anders toont die 'm weer. */
.geo-lijst .geo-lijst-tabel .data-table tr > .geo-kolom-weg { display: none; }
.geo-lijst .geo-lijst-tabel .data-table tbody td.cell-image .beeld-leeg { display: grid; place-items: center; }

/* ══ QUERY — de filterbalk uit het model (gedrag in app.js, blok QUERY) ══════════════════════════
   Een lijst die haar readmodel bevraagt: chips (enum), een segment (vaste keuzes), een zoekveld
   (zoektIn) en de locatie-knoppen. Mobiel eerst: één horizontaal scrollbare rij die onder de kop
   blijft plakken terwijl je door kaart en lijst scrollt; elk doel minstens 44px hoog.
   Alleen tokens die de renderer al leest (plus eigen --mock-*): een design-systeem hoeft voor
   filters niets nieuws te leveren. ─────────────────────────────────────────────────────────── */
.q-plakt {
  position: sticky; top: var(--mock-kop-hoogte, 0px); z-index: 15;
  background: var(--color-bg, #f6f8fb);
}
.toolbar.q-plakt { padding-top: var(--space-2, .5rem); padding-bottom: var(--space-2, .5rem); }
.toolbar > .q-balk { flex: 1 1 100%; min-width: 0; margin-bottom: 0; }
.q-balk {
  display: flex; flex-direction: column; gap: var(--space-2, .5rem);
  padding: var(--space-2, .5rem) 0; margin-bottom: var(--space-3, .75rem); min-width: 0;
}
.q-rij {
  display: flex; align-items: center; gap: var(--space-3, .75rem);
  overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
  /* Ruimte voor de focusring: een scrollende rij knipt anders de buitenkant van de ring af. */
  padding: 4px; margin: -4px;
}
.q-rij::-webkit-scrollbar { display: none; }
/* Er staat nog meer rechts: de rand vervaagt tot je aan het eind bent (app.js zet `is-eind`). */
.q-rij:not(.is-eind) { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent); }
.q-groep { display: flex; align-items: center; gap: var(--space-2, .5rem); flex: none; margin: 0; }
.q-groep + .q-groep { padding-left: var(--space-3, .75rem); border-left: 1px solid var(--color-border-subtle, #eef1f6); }
/* De locatie-regel scrollt niet en vervaagt niet: twee knoppen passen altijd. */
.q-rij-locatie { overflow: visible; }
.q-rij-locatie:not(.is-eind) { -webkit-mask-image: none; mask-image: none; }
.q-label {
  font-size: var(--text-xs, .75rem); font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
  color: var(--color-text-muted, #6b7684); white-space: nowrap;
}
.q-chips { flex-wrap: nowrap; }
.q-balk .chip { min-height: 44px; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px; }
.q-balk .chip[aria-busy="true"] { opacity: .7; cursor: progress; }
.q-balk .chip:focus-visible,
.q-seg:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 2px; }
.q-ico { display: inline-flex; }
.q-ico svg { width: 16px; height: 16px; }
.q-segment {
  display: inline-flex; gap: 2px; padding: 2px;
  background: var(--color-bg-muted, #eef2f7); border: 1px solid var(--color-border, #dfe4ec);
  border-radius: var(--radius-pill, 999px);
}
.q-seg {
  min-height: 44px; min-width: 44px; padding: 0 var(--space-3, .75rem);
  border: 0; border-radius: var(--radius-pill, 999px); background: none; cursor: pointer;
  font: inherit; font-size: var(--text-sm, .875rem); font-weight: 600; white-space: nowrap;
  color: var(--color-text-secondary, #4a5666); font-variant-numeric: tabular-nums;
}
.q-seg:hover { color: var(--color-text, #1a2230); }
.q-seg.is-active {
  background: var(--color-bg-surface, #fff); color: var(--mock-primary-ink, #3a7ca5);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(0,0,0,.08));
}
.q-zoek { flex: 0 1 16rem; min-width: 12rem; min-height: 44px; }
.q-keuze { min-height: 44px; width: auto; }
.q-sub { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1, .25rem) var(--space-3, .75rem); }
.q-adres { flex: 1 1 100%; max-width: 32rem; }
.q-adres .geo-zoek-input { min-height: 44px; }
.q-noot { margin: 0; flex: 1 1 16rem; font-size: var(--text-xs, .75rem); color: var(--mock-muted); }
.q-noot.is-let-op { color: var(--color-text-secondary, #4a5666); font-weight: 600; }
.q-status:empty { display: none; }
.q-telling {
  margin: 0 0 0 auto; font-size: var(--text-sm, .875rem); font-weight: 600; white-space: nowrap;
  color: var(--color-text-secondary, #4a5666); font-variant-numeric: tabular-nums;
}
/* De afstand bij de naam ("0,2 km"): het antwoord op de vraag waarom deze plek hier staat. */
.q-berekend {
  display: inline-block; margin-left: var(--space-2, .5rem);
  font-size: var(--text-sm, .875rem); font-weight: 600; white-space: nowrap;
  color: var(--mock-primary-ink, #3a7ca5); font-variant-numeric: tabular-nums;
}
.q-berekend-cel { white-space: nowrap; color: var(--mock-primary-ink, #3a7ca5); font-weight: 600; }
/* De straal op de kaart: een rustig vlak met een stippelrand, en "hier ben jij" in het midden. */
.q-straal {
  fill: var(--color-primary, #3a7ca5); fill-opacity: .08;
  stroke: var(--color-primary, #3a7ca5); stroke-opacity: .55; stroke-width: 2; stroke-dasharray: 6 6;
}
.q-hier-host { background: none; border: 0; }
.q-hier {
  display: block; width: 22px; height: 22px; border-radius: 50%;
  background: var(--color-primary, #3a7ca5); border: 3px solid var(--color-bg-surface, #fff);
  box-shadow: 0 0 0 6px var(--color-primary-glow, rgba(58,124,165,.2)), var(--shadow-md, 0 4px 12px rgba(0,0,0,.2));
}
/* Breed genoeg: de filters mogen afbreken in plaats van te scrollen. */
@media (min-width: 60rem) {
  .q-rij { flex-wrap: wrap; overflow: visible; }
  .q-rij:not(.is-eind) { -webkit-mask-image: none; mask-image: none; }
  /* Afgebroken regels beginnen anders met een scheidingslijn. */
  .q-groep + .q-groep { padding-left: 0; border-left: 0; }
}

/* Een straal zonder positie: zichtbaar, maar uit (de query filtert dan niet op afstand). */
.q-groep.is-uit { opacity: .45; }
.q-groep.is-uit .q-seg.is-active { background: transparent; box-shadow: none; }

/* "Filters wissen": een stille tekstknop naast de telling. */
.q-wis {
  border: 0; background: none; padding: 0 var(--space-1, .25rem); min-height: 44px; cursor: pointer;
  font: inherit; font-size: var(--text-sm, .875rem); font-weight: 600; color: var(--mock-primary-ink, #3a7ca5);
  text-decoration: underline; text-underline-offset: 2px;
}
.q-wis:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 2px; }
/* Het beheer (pagina's onder /admin) is altijd donker; de dag/nacht-keuze geldt in de app. */
.beheer-schil .theme-toggle { display: none; }

/* ── Een knop per item (ScreenButton.perItemVan): chips in een lijst-cel ─────────────────── */
.item-chips { display: flex; flex-wrap: wrap; gap: var(--space-1, .25rem); }
.item-chip {
  display: inline-flex; align-items: center; gap: 4px; min-height: 28px;
  padding: 2px var(--space-2, .5rem); border-radius: var(--radius-pill, 999px);
  font: inherit; font-size: var(--text-xs, .75rem); cursor: pointer;
  border: 1px solid var(--color-border, #d5dbe3); background: var(--color-bg-surface, #fff); color: var(--color-text, #1a2230);
  transition: background .15s ease, border-color .15s ease;
}
.item-chip:hover { background: var(--color-bg-surface-hover, #f3f6f9); border-color: var(--color-border-strong, #b7c0cc); }
.item-chip:focus-visible { outline: 2px solid var(--color-border-focus, #3a7ca5); outline-offset: 2px; }
.item-chip.is-weg { background: var(--color-primary-soft, #e3eef5); border-color: transparent; }
.item-chip.is-weg:hover { background: var(--color-danger-soft, #fde8e8); color: var(--color-danger, #b42318); }
.item-chip.is-erbij { border-style: dashed; color: var(--color-text-secondary, #4a5566); }
.item-chip.is-erbij:hover { border-style: solid; color: var(--mock-primary-ink, #3a7ca5); }
.item-chip-teken { font-weight: 700; line-height: 1; }

/* De kop van een DETAIL_LIST-niveau: de velden van de aangeklikte ouder, boven de tabel. */
.detail-list.drill-kop { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1, .25rem) var(--space-6, 1.5rem);
  margin: 0 0 var(--space-4, 1rem); font-size: var(--text-sm, .875rem); }
.detail-list.drill-kop dt { color: var(--color-text-muted, #6b7380); }
.detail-list.drill-kop dd { margin: 0; color: var(--color-text-heading, inherit); font-weight: 500; }

/* Dode interne link in vrije pagina-HTML (alleen in de editor-mock, zie `dodeLinks`). */
.mock-landing-artifact .mock-dode-link { outline: 2px dashed var(--color-danger, var(--color-error, #b3261e)); outline-offset: 3px; }
.mock-landing-artifact .mock-dode-links {
  margin: var(--space-4, 1rem) 0; padding: var(--space-3, .75rem) var(--space-4, 1rem);
  border-left: 4px solid var(--color-danger, var(--color-error, #b3261e)); background: var(--color-bg-surface, #fff);
  color: var(--color-text, inherit); font-size: .9rem;
}

/* ── De bouwstraat op deze pagina (editor-only) ─────────────────────────────
   Knop in de bouw-chrome + paneel: wat er gebouwd is, indeling goedkeuren, pagina afkeuren. */
.bouw-pagina-paneel {
  position: fixed; z-index: 96; width: min(24rem, calc(100vw - 16px));
  padding: var(--space-4, 1rem); display: flex; flex-direction: column; gap: var(--space-3, .75rem);
  background: var(--color-bg-surface, #fff); color: var(--color-text, inherit);
  border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-md, 10px);
  box-shadow: var(--shadow-md, 0 6px 20px rgba(0,0,0,.12)); font-size: var(--text-sm, .875rem);
}
.bouw-pagina-kop { font-weight: 700; }
.bouw-pagina-slices { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2, .5rem); }
.bouw-pagina-slices li { display: flex; justify-content: space-between; gap: var(--space-3, .75rem); }
.bouw-pagina-fase { color: var(--color-text-muted, #6b7280); white-space: nowrap; }
.bouw-pagina-fase.fase-goedgekeurd { color: var(--color-success, #16a34a); }
.bouw-pagina-fase.fase-mock-opnieuw { color: var(--color-warning, #b45309); }
.bouw-pagina-reden {
  width: 100%; box-sizing: border-box; font: inherit; resize: vertical;
  padding: var(--space-2, .5rem); border: 1px solid var(--color-border, #dfe4ec); border-radius: var(--radius-sm, 6px);
  background: var(--color-bg, #fff); color: inherit;
}
.bouw-pagina-knoppen { display: flex; flex-wrap: wrap; gap: var(--space-2, .5rem); justify-content: flex-end; }
.bouw-pagina-knop {
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-sm, 6px); font: inherit; cursor: pointer;
  border: 1px solid var(--color-border, #dfe4ec); background: var(--color-bg-subtle, #f3f5f9); color: inherit;
}
.bouw-pagina-knop.goed { border-color: var(--color-success, #16a34a); color: var(--color-success, #16a34a); }
.bouw-pagina-knop.af { border-color: var(--color-warning, #b45309); color: var(--color-warning, #b45309); }
.bouw-pagina-knop:hover, .bouw-pagina-knop:focus-visible { background: var(--color-bg-surface, #fff); outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 1px; }
.bouw-pagina-leeg { margin: 0; color: var(--color-text-muted, #6b7280); }

/* ══════════════════════════════════════════════════════════════════════════
   UX-ronde 08-10 (journey-review buurtsporten): generieke renderer-defaults
   ══════════════════════════════════════════════════════════════════════════ */
/* Een datum is tekst om te lezen ("do 9 okt · 19:00"), geen code: de letter van de pagina, wel
   cijfers van gelijke breedte zodat tijden onder elkaar lijnen (P14). */
time.datum { font-family: inherit; font-variant-numeric: tabular-nums; }

/* Een pin met meer rijen op één plek: de popup noemt ze allemaal (P22). */
.geo-pin-aantal { flex: none; display: inline-grid; place-items: center; min-width: 1.25rem; height: 1.25rem;
  margin-left: var(--space-2, .5rem); margin-right: calc(-1 * var(--space-1, .25rem)); padding: 0 4px; border-radius: 999px;
  background: var(--mock-geo-tint); color: var(--color-text-on-primary, #fff); font-size: .6875rem; }
.geo-pin.is-compact .geo-pin-aantal { display: none; }
.geo-popup-lijst { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1, .25rem); }
.geo-popup-lijst .geo-popup-meer { width: 100%; justify-content: flex-start; text-align: left; margin-top: 0; }

/* Breed: het menu blijft de tabrij; icoon, "Meer", avatar en menukop zijn er alleen op de telefoon. */
.ht-icoon, .hub-meer, .persona-avatar, .account-menu-kop { display: none; }
.account-menu-kop { flex-direction: column; gap: 2px; padding: var(--space-2, .5rem) var(--space-3, .75rem);
  border-bottom: 1px solid var(--color-border, #d7dce2); margin-bottom: var(--space-1, .25rem); }
.account-menu-naam { font-weight: 600; color: var(--color-text-heading, #1a2230); overflow-wrap: anywhere; }
.account-menu-rol { font-size: var(--text-xs, .75rem); color: var(--color-text-secondary, #4a5666); }

@media (max-width: 48rem) {
  /* ── Het hoofdmenu als onderbalk (P7) ── */
  .hub-nav.is-onderbalk {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; max-width: none; margin: 0;
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0;
    padding: 0 0 env(safe-area-inset-bottom); overflow: visible; scroll-snap-type: none;
    background: var(--color-bg-surface, #fff); border-top: 1px solid var(--color-border, #dfe4ec);
    box-shadow: 0 -2px 10px rgba(16, 24, 40, .06);
    -webkit-mask-image: none; mask-image: none;
  }
  .hub-nav.is-onderbalk.heeft-meer { right: 20%; }
  .hub-nav.is-onderbalk .hub-tab, .hub-meer-knop {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    min-width: 0; min-height: 56px; padding: 6px 2px; margin: 0;
    font-family: inherit; font-size: .6875rem; font-weight: 600; line-height: 1.15; text-align: center; white-space: normal; text-decoration: none;
    color: var(--color-text-secondary, #4a5666); background: none; border: 0;
    border-top: 2px solid transparent; border-bottom: 0; cursor: pointer;
  }
  .hub-nav.is-onderbalk .ht-label, .hub-meer-knop .ht-label {
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
    max-width: 100%; overflow-wrap: anywhere;
  }
  .hub-nav.is-onderbalk .ht-icoon, .hub-meer-knop .ht-icoon { display: inline-flex; width: 22px; height: 22px; }
  .ht-icoon svg { width: 100%; height: 100%; }
  .hub-nav.is-onderbalk .hub-tab[aria-selected="true"], .hub-meer.is-actief .hub-meer-knop {
    color: var(--mock-primary-ink, #3a7ca5); border-top-color: var(--color-primary, #3a7ca5);
  }
  .hub-nav.is-onderbalk .hub-indicator, .hub-nav.is-onderbalk .hub-tab.is-over { display: none; }
  .hub-meer { display: block; position: fixed; right: 0; bottom: 0; width: 20%; z-index: 30;
    padding-bottom: env(safe-area-inset-bottom); background: var(--color-bg-surface, #fff);
    border-top: 1px solid var(--color-border, #dfe4ec); }
  .hub-meer-knop { width: 100%; }
  .hub-meer-lijst { position: absolute; right: var(--space-2, .5rem); bottom: calc(100% + var(--space-2, .5rem));
    min-width: 12rem; max-width: calc(100vw - 1rem); padding: var(--space-1, .25rem); display: flex; flex-direction: column;
    background: var(--color-bg-surface, #fff); border: 1px solid var(--color-border, #d7dce2);
    border-radius: var(--radius-md, .5rem); box-shadow: var(--shadow-md, 0 8px 24px rgba(16,24,40,.12)); }
  .hub-meer-lijst[hidden] { display: none; }
  .hub-meer-item { display: flex; align-items: center; gap: var(--space-3, .75rem); min-height: 44px;
    padding: var(--space-2, .5rem) var(--space-3, .75rem); border: 0; border-radius: var(--radius-sm, .375rem);
    background: none; font-family: inherit; font-size: var(--text-sm, .875rem); font-weight: 500; color: var(--color-text, #1a2230);
    text-align: left; text-decoration: none; cursor: pointer; }
  .hub-meer-item .ht-icoon { display: inline-flex; width: 20px; height: 20px; }
  .hub-meer-item:hover, .hub-meer-item:focus-visible { background: var(--color-bg-surface-hover, #f4f6f8); }
  /* De inhoud houdt z'n onderkant vrij van de balk; toasts staan erboven. */
  body:has(.hub-nav.is-onderbalk) { padding-bottom: calc(57px + env(safe-area-inset-bottom)); }
  body:has(.hub-nav.is-onderbalk) .toast-stack { bottom: calc(57px + var(--space-4, 1rem) + env(safe-area-inset-bottom)); }

  /* ── Het accountmenu als rondje (P7) ── */
  .persona-bar { flex: 0 0 auto; margin-left: auto; }
  .account-menu-knop { padding: 2px; gap: 0; background: none; }
  .account-menu-knop .persona-dot, .account-menu-knop .persona-label, .account-menu-knop .persona-name,
  .account-menu-knop .persona-roles, .account-menu-knop .account-menu-pijl { display: none; }
  .persona-avatar { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 50%;
    background: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff);
    font: 700 var(--text-sm, .875rem)/1 var(--font-heading, inherit); letter-spacing: .02em; }
  .account-menu-kop { display: flex; }

  /* ── De kaart naast een lijst: lager, zodat het eerste item boven de vouw staat (P22) ── */
  .geo-kaart-lijst { height: clamp(170px, 26svh, 240px); }
}

/* ── Tijdkiezer (P8, 09-10): dagknoppen + tijd per kwartier boven het tekstveld ───────────────── */
.tijdkiezer { display: flex; flex-direction: column; gap: var(--space-2, .5rem); min-width: 0; }
/* Eén rij die horizontaal schuift: veertien dagen passen niet naast elkaar, en op een telefoon veeg je. */
.tk-dagen {
  display: flex; gap: var(--space-2, .5rem); overflow-x: auto; scroll-snap-type: x proximity;
  padding-bottom: var(--space-1, .25rem); scrollbar-width: thin;
}
.tk-dag {
  flex: 0 0 auto; scroll-snap-align: start; min-width: 4.5rem; min-height: 44px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: var(--space-2, .5rem) var(--space-3, .75rem); border-radius: var(--radius-md, .5rem); cursor: pointer;
  background: var(--color-bg-surface, #fff); color: var(--color-text, #1e2530);
  border: 1px solid var(--color-border, #dfe4ec); font: inherit; line-height: 1.15;
}
.tk-dag:hover { border-color: var(--color-border-strong, #c2cad6); }
.tk-dag:focus-visible { outline: 2px solid var(--color-border-focus, var(--color-primary, #3a7ca5)); outline-offset: 1px; }
.tk-dag-naam { font-size: var(--text-xs, .75rem); font-weight: 700; text-transform: lowercase; color: var(--color-text-secondary, #4a5666); }
.tk-dag-datum { font-size: var(--text-sm, .875rem); font-weight: 600; white-space: nowrap; }
.tk-dag[aria-pressed="true"] { background: var(--color-primary, #3a7ca5); border-color: var(--color-primary, #3a7ca5); color: var(--color-text-on-primary, #fff); }
.tk-dag[aria-pressed="true"] .tk-dag-naam { color: inherit; }
.tk-onder { display: grid; grid-template-columns: minmax(6.5rem, 8rem) minmax(0, 1fr); gap: var(--space-2, .5rem); align-items: center; }
