/* ===================== TOKENS ===================== */
:root {
  /* Gedeelde rollen volgens conventions.md §3/§8; donkere waarden hieronder.
     Ouderkleuren, status en datavisualisatie blijven aparte betekenissen. */
  --color-bg: #fcfcfc;
  --color-surface: #ffffff;
  --color-card: #e8e8e8;
  --color-card-pressed: #e0e0e0;
  --color-status-leeg: #c9c9c9;
  --color-schakel-uit: #c9c9c9;
  --color-radio-ring: var(--color-control-border);
  --color-selected: #ededed;
  --color-drawer: #fcfcfc;
  --color-scrim: rgba(0, 0, 0, 0.40);
  --color-control-border: #808080;
  --color-sidebar-bg: #fcfcfc;
  --color-hover: rgba(25, 25, 25, 0.06);
  --color-druk: rgba(13, 13, 13, 0.08);
  --color-surface-own: rgba(204, 120, 92, 0.08);
  --color-text: #0d0d0d;
  --color-text-muted: #5d5d5d;
  --color-border: #cfcfcf;
  --color-accent: #895f44;
  --color-accent-hover: #835b41;
  --color-custody: #79766d;
  --color-focus: var(--color-text);
  --color-error: #b23a2a;
  --color-neutraal-zacht: #e9e9e9;
  --color-faint: #686868;
  --color-line: #dcdcdc;
  --color-panel: #e9e9e9;
  --color-btn: #0d0d0d;
  --color-on-btn: #ffffff;
  --shadow-knop: none;
  --color-hair: #dedede;
  --color-coparent: #6b5f92;
  --color-coparent-soft: #eceaf3;
  --color-ouder-een: #8a6045;
  /* Donker genoeg voor witte tekst op een gevulde dagtegel (zorgverdeling; Jerry 2026-10-09). */
  --color-ouder-twee: #6d62a8;
  --color-amber: #926023;
  --color-amber-soft: #f7ead5;
  --color-green: #34784c;
  --color-green-soft: #e4efe6;
  --color-mark: #fff1b8;
  --color-assistant: #2f5f8c;
  --color-assistant-soft: #e7eff6;
  --color-assistant-line: #c3d7e8;
  --color-now-line: #e0492b;
  --color-amber-deep: #8a5a1e;
  --color-amber-border: #ead6b8;
  --color-green-deep: #245c3b;
  --color-green-border: #cfe6d5;
  --color-coparent-deep: #4b426e;
  --color-coparent-border: #d8d4e4;
  --color-error-soft: #f7e2dd;
  --color-error-border: #ead0ca;
  --color-error-deep: #8a3324;
  --color-soft-border: #eedbcf;
  --color-file-pdf: #b83d29;
  --color-file-pdf-soft: #f7e2dd;
  --color-file-doc: #2b5cc0;
  --color-file-doc-soft: #dee7f9;
  --color-file-sheet: #28794c;
  --color-file-sheet-soft: #e4efe6;
  --color-holiday-soft: #dbeafe;
  --color-holiday-deep: #1e40af;
  --color-on-accent: #ffffff;
  --color-on-dark: #ffffff;
  --color-muted-warm: #5d5d5d;
  --gradient-accent: linear-gradient(140deg, #bb5a3a, var(--color-accent-hover));
  --gradient-coparent: linear-gradient(140deg, #7860e8, #5942c9);
  --color-chat-bg: var(--color-bg);
  --color-chat-bubble-other: var(--color-card);
  --color-chat-text: var(--color-text);
  --color-chat-border: var(--color-border);
  --color-chat-accent: var(--color-accent);
  --color-chat-accent-hover: var(--color-accent-hover);
  --color-chat-surface-own: rgba(204, 120, 92, 0.08);
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --page-gutter: 18px;
  --uur-hoogte: 45px;
  --tijd-kolom: 20px;
  --page-top: calc(8px + env(safe-area-inset-top, 0px));
  --page-bottom: 24px;
  --page-max: 520px;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-body: "Hanken Grotesk", var(--font-sans);
  --font-display: var(--font-body);
  --text-10: 0.625rem;
  --text-11: 0.6875rem;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-15: 0.9375rem;
  --text-base: 1rem;
  --text-17: 1.0625rem;
  --text-lg: 1.125rem;
  --text-20: 1.25rem;
  --text-22: 1.375rem;
  --text-24: 1.5rem;
  --text-26: 1.625rem;
  --text-28: 1.75rem;
  --text-30: 1.875rem;
  --text-32: 2rem;
  --text-40: 2.5rem;
  --text-56: 3.5rem;
  --weight-medium: 500;
  --leading-kop: 1.2;
  --leading-rij: 1.3;
  --leading-sub: 1.4;
  --leading: 1.45;
  --leading-lees: 1.55;
  --select-chevron: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 4.5 6 8l3.5-3.5" stroke="rgb(91,95,102)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>');
  --radius: 8px;
  --radius-ballon: 20px;
  --radius-xs: 4px;
  --greep: 38px;
  --radius-binnen: 6px;
  --radius-veld-plan: 14px;
  --radius-sheet-rij: 18px;
  --radius-textarea: 24px;
  --radius-rooster-dag: 20px;
  --avatar-sm: 28px;
  --avatar: 40px;
  --avatar-lg: 84px;
  --radius-groep: 26px;
  --radius-groep-sheet: 22px;
  --radius-sheet: 28px;
  --radius-pill: 999px;
  --veld-focus-ring: none;
  --icon-xs: 16px;
  --icon-sm: 18px;
  --icon: 21px;
  --icon-lg: 22px;
  --sidebar-width: 264px;
  --shadow-vlak: none;
  --shadow-pil: 0 1px 2px rgba(0, 0, 0, 0.04), 0 6px 20px rgba(0, 0, 0, 0.06);
  --shadow-rond: 0 8px 32px rgba(0, 0, 0, 0.06);
  --shadow-fab: 0 2px 6px rgba(0, 0, 0, 0.14), 0 12px 28px rgba(0, 0, 0, 0.26);
  --shadow-16: 0 8px 16px rgba(0, 0, 0, 0.12), 0 0 2px rgba(0, 0, 0, 0.06);
  --curve-decel: cubic-bezier(0.1, 0.9, 0.2, 1);
  --dur-fast: 120ms;
  --dur-normal: 200ms;
  --druk-in: 70ms;
  --druk-uit: 240ms;
  --druk-schuif: 2px;
  --slate-dark: #191919;
  --slate-medium: #262625;
  --slate-light: #40403e;
  --cloud-dark: #666663;
  --cloud-medium: #91918d;
  --cloud-light: #bfbfba;
  --ivory-dark: #e5e4df;
  --ivory-medium: #f0f0eb;
  --ivory-light: #fafaf7;
  --book-cloth: #cc785c;
  --kraft: #d4a27f;
  --manilla: #ebdbbc;
  --logo-ink: #0d0d0d;
  --logo-inverse-accent: #6ea3e8;
  --color-dataviz-line: var(--cloud-dark);
  --color-dataviz-muted: var(--cloud-light);
  --color-dataviz-axis: var(--color-border);
  --color-dataviz-text: var(--color-text-muted);
  --color-dataviz-cat-1: var(--book-cloth);
  --color-dataviz-cat-2: var(--cloud-dark);
  --color-dataviz-cat-3: var(--kraft);
  --color-dataviz-cat-4: var(--slate-light);
  --color-barometer-track: var(--color-chat-border);
  --color-barometer-calm-fill: #b8b3a7;
  --color-barometer-warming-fill: var(--kraft);
  --color-barometer-hot-fill: var(--book-cloth);
  --color-barometer-cooldown-bg: rgba(204, 120, 92, 0.08);
  color-scheme: light dark;
}

/* ===================== DONKER THEMA ===================== */
/* Donker-thema-handoff (2026-08-07). Het ontwerp is een
   dónkere rendition van exact dezelfde schermen — zelfde tokennamen, andere waarden.
   Gestuurd door `data-theme` op <html>, niet door `prefers-color-scheme`: sinds de
   gebruiker in Instellingen licht/donker/systeem kan kiezen, moet een expliciete keuze
   de telefoon kunnen overrulen. Bij "systeem" zet een inline script in de <head> het
   attribuut alsnog vanuit `matchMedia` — vóór de eerste paint, dus zonder flits. Eén
   bron voor de donkere waarden; geen tweede, bijna-identiek blok voor de media-query.
   Zestien waarden komen letterlijk uit de handoff (bg/card/ink/muted/faint/line/accent/
   soft/softer/purple(+soft)/amber(+soft)/green(+soft)/shadow); de "deep"-tekstkleuren en
   de gradients zijn eveneens uit het ontwerp geplukt. De afgeleiden (randen, bestands-
   tinten, chat, dataviz) zijn per groep beredeneerd — het ontwerp toont ze niet
   allemaal, maar ze moeten wél in dezelfde familie blijven.
   Alle waarden zijn getoetst op WCAG-AA; zie test/lint/contrast_test.rb. */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* — Grond & inkt (letterlijk uit de handoff) — */
  --color-bg: hsl(30 10% 8%);
  --color-surface: #211c18;
  /* Donker volgt het design system nog niet (besluit 2026-09-26): de nieuwe rollen
     krijgen hier de oude donkere waarden, zodat donker er hetzelfde uitziet als vóór. */
  --color-card: #211c18;
  --color-card-pressed: #2a241f;
  --color-status-leeg: #4a423b;
  --color-schakel-uit: #4a423b;
  --color-radio-ring: var(--color-control-border);
  --color-selected: #2a241f;
  --color-drawer: #211c18;
  --color-control-border: #968a7e;
  --color-scrim: rgba(30, 18, 10, 0.45);
  --veld-focus-ring: none;
  --shadow-fab: 0 2px 6px rgba(0, 0, 0, 0.14), 0 12px 28px rgba(0, 0, 0, 0.26);
  --shadow-pil: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 20px rgba(0, 0, 0, 0.35);
  --shadow-rond: 0 1px 3px rgba(0, 0, 0, 0.4);
  /* Licht: de sidebar is een tint DONKERDER dan de bg zodat de rail zich aftekent.
     Donker keert dat om — hoger = lichter is de conventie voor elevatie. */
  --color-sidebar-bg: #26201b;
  /* De waas moet altijd lichter zijn dan de ondergrond i.p.v. donkerder. */
  --color-hover: rgba(255, 255, 255, 0.07);
  --color-druk: rgba(255, 255, 255, 0.10);
  --color-surface-own: rgba(209, 128, 87, 0.16);
  --color-text: #f2ece4;
  --color-text-muted: #a79b8e;
  --color-faint: #968a7e;
  --color-line: #332c26;
  --color-border: #3a332c;

  /* — Accent — de handoff licht 'm op zodat hij op donker
       evenveel spreekt; hover gaat dan ook omhóóg i.p.v. omlaag. */
  --color-accent: #d18057;
  --color-accent-hover: #dd8c62;
  --color-custody: #9a9488;
  --color-focus: var(--color-text);
  --color-error: #e47c6a;      /* opgelicht; #b23a2a verdrinkt op donker */

  /* — Zacht-vlakken (letterlijk) — */
  --color-soft-border: #4a352a;

  /* — Statusfamilies. Kleur + zacht-vlak komen uit de handoff; "deep" (de tekst
       ÓP dat vlak) draait om — op donker is dat juist de lichtste tint. De randen
       zitten tussen soft en deep in. — */
  --color-coparent: #9381ef;
  --color-ouder-een: #d18057;
  --color-ouder-twee: #b3a9e6;
  --color-coparent-soft: #2b2450;
  --color-coparent-deep: #aca2d7;
  --color-coparent-border: #392f66;
  --color-panel: #2a241f;
  --color-btn: #ede5da;
  --color-on-btn: #1b1410;
  --shadow-knop: none;
  --color-hair: #322b25;
  --color-amber: #dca34e;
  --color-amber-soft: #3a2c16;
  --color-amber-deep: #e7c192;
  --color-amber-border: #4d3c1f;
  --color-green: #5fbc81;
  --color-green-soft: #1e3527;
  --color-mark: #5b4c12;
  --color-green-deep: #a1d8b5;
  --color-green-border: #2a4a35;
  /* Assistent-familie: op donker licht het blauw op (het handoff-blauw verdrinkt), het
     zacht-vlak wordt juist diep — zelfde omslag als de statusfamilies hierboven. */
  --color-assistant: #7fb2dd;
  --color-assistant-soft: #1b2b39;
  --color-assistant-line: #2f4a61;
  --color-error-soft: #422d28;
  --color-error-deep: #e69d94;
  --color-error-border: #56362f;
  --color-now-line: #ef6a4d;

  /* — Bestandstype-tinten: zelfde rol (typering, geen status), dus zelfde
       omkering — hue vast, kleur op, vlak diep. — */
  --color-file-pdf: #e37d6b;
  --color-file-pdf-soft: #422d28;
  --color-file-doc: #7aa2f0;
  --color-file-doc-soft: #22304d;
  --color-file-sheet: #5fbc81;
  --color-file-sheet-soft: #1e3527;
  /* Vakantie blijft bewust de enige koele familie. */
  --color-holiday-soft: #1e2f4d;
  --color-holiday-deep: #9dbcf5;

  /* Omslag naar inkt: op de opgelichte vullingen (accent #d18057, paars #9381ef,
     error #e47c6a, groen, amber) haalt wit 3,1-3,5:1 en inkt 5,0-7,9:1. --color-on-dark
     blijft wit voor de vlakken die óók in donker donker zijn (gradients, viewer). */
  --color-on-accent: #191919;
  --color-muted-warm: #a79b8e;

  /* — Gradients: beide letterlijk uit de handoff. De paarse is daar bewust vlak
       (#352d5d ↔ #352d5d) — op donker leest een verloop als een render-fout. — */
  --gradient-accent: linear-gradient(140deg, #5c3d2d, #a0512e);
  --gradient-coparent: linear-gradient(140deg, #352d5d, #352d5d);

  /* — Chat: de manilla eigen-bubbel wordt een warme donkere tint met lichte tekst;
       de bubbel van de ander volgt --color-surface. — */
  --color-neutraal-zacht: #262523;
  --color-chat-bubble-other: var(--color-card);
  --color-chat-surface-own: rgba(209, 128, 87, 0.16);

  /* — Schaduw: op donker doet een inkt-getinte schaduw niets; de handoff gaat naar
       diep zwart met veel meer dekking. — */
  --shadow-vlak: none;
  /* Gloed onder een gevuld blok: op donker draagt de kleur zelf minder, dus dieper
     en met meer dekking — anders verdwijnt hij in de achtergrond. */
  --shadow-16: 0 6px 14px rgba(0, 0, 0, 0.55), 0 14px 30px rgba(0, 0, 0, 0.45);

  /* — Woordmerk: de handoff zet "blin" op var(--ink) en "Co" op var(--accent);
       het donkerblauwe merk-ink zou anders wegvallen in de grond. — */
  --logo-ink: #f2ece4;

  /* — Dataviz + barometer: de warme niet-alarm-doctrine geldt onverkort, alleen
       opgelicht zodat de tinten niet in de grond zakken. — */
  --color-dataviz-cat-2: #a79b8e;
  --color-dataviz-cat-4: #8f8a80;
  --color-barometer-calm-fill: #6f695e;
  --color-barometer-cooldown-bg: rgba(209, 128, 87, 0.16);

  /* Chevron van élke select: het grijs uit de lichte variant is op donker niet meer
     te zien — zelfde pijl, muted-tint van dit thema. */
  --select-chevron: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 4.5 6 8l3.5-3.5" stroke="rgb(167,155,142)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>');
}

/* De kalender-chrome draagt eigen, gescopete tokens (--agenda-cell/-hour-lines).
   Die staan NIET hier maar direct onder hun lichte tegenhanger bij .agenda-week ?
   een tweede .agenda-week-regel hier zou verliezen van de latere originele regel
   (gelijke specificiteit, bronvolgorde beslist). Zoek op "agenda-cell". */

/* ===================== BASE (mobile-first) ===================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
/* Formuliercontrols erven het app-font niet vanzelf — zonder deze regel rendert een
   <button>/<input> in Arial 13.33px, de browser-default. Dat viel niet op bij icoon-knoppen
   maar wél bij de datum-/tijdkiezer en de Opslaan-knop (sweep 2026-07-27). Eén baseline
   i.p.v. `font: inherit` per component — die stond al 30× los in dit bestand. */
button, input, select, textarea { font-family: inherit; }

html {
  -webkit-text-size-adjust: 100%;
  height: 100dvh;
  overflow: hidden;
}

body {
  height: 100%;
  overflow: hidden;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: var(--leading);
  color: var(--color-text);
  background: var(--color-bg);
}

/* ── Druk-taal: één antwoord op een vinger, app-breed (2026-09-12) ─────────────────────
   Tot vandaag had de app er drie: een terracotta vlak (--color-softer, 45×), een grijze waas
   (--color-hover, 15×) en her en der een handgeschreven rgba. De terracotta was de lichtste
   accent-tint en las daardoor als "hoort bij de andere ouder" in plaats van als "je drukt".
   Nu één taal, en die is een handeling, geen kleurwissel:
   · indrukken gaat meteen (--druk-in), loslaten dooft rustig weg (--druk-uit) — die
     asymmetrie maakt het verschil tussen "er gebeurt iets" en een hover;
   · de kleur is een inkt-waas (--color-druk), geen vaste tint: werkt op de grond, op een
     wit vlak en in het donkere thema zonder aparte regels;
   · een rij schuift z'n inhoud twee pixels mee (--druk-schuif); het vlak zelf blijft staan.
   Twee lijsten: RIJEN (waas + schuif) en VLAKKEN (alleen de waas — knoppen, cellen, kiezers:
   daar is schuiven een tic). Nieuw tikbaar? Zet 'm hier bij, niet in een eigen :active-regel
   met een eigen kleur — dat is precies hoe er drie talen ontstonden. Wat op :active juist
   níets mag doen (.setrow--static, .vakanties__row--locked) staat in het eigen bestand en zet
   daar ook de schuif uit. Android's eigen grijze tikflits gaat uit: die vecht met de fade. */
.agenda-form__optsummary,
.lade__row,
.pick-row,
.folderlist__link,
.doclist__link,
.movelist__item,
.infofilter__opt,
.sheetmenu__item,
.samen__linkbtn,
.contacts__link,
.contacts__call,
.contact-detail__field-link,
.agenda-list__item,
.agenda-day__context,
button.radiorow,
.coach-actions__item,
.setrow,
.avsheet__rij,
.mail-drawer__edit,
.mail-drawer__sessie,
.home__task--flush,
.home__invite-solo,
.plan-choice,
.coach-sheet__q,
.coach-bar,
.kasboek__row,
.mail-drawer__folder,
.mail-actions__item,
.meldingen__item,
.plan-topic,
.vakanties__row,
button.timewheel__display,
button.datecal__display,
.datecal__yearbtn,
.datecal__monthbtn,
.datecal__navbtn,
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input,
.screen-head__pick,
.infocard__act,
.agenda-mobile__strook-weekcel,
.agenda-month__cell,
.knowledge-btn,
.agenda-form__delete,
.app-topbar__menu,
.app-topbar__bell,
.sheet__kop-save,
.confirm__ok,
.confirm__cancel,
.vnav__action,
.doclist__kebab,
.kaart__menu,
.vnav__back,
.vac-period__del,
.agenda-mobile__strook-num {
  transition: background var(--druk-uit) ease-out;
  -webkit-tap-highlight-color: transparent;
}
.agenda-form__optsummary:active,
.lade__row:active,
.pick-row:active,
.folderlist__link:active,
.doclist__link:active,
.movelist__item:active,
.infofilter__opt:active,
.sheetmenu__item:active,
.samen__linkbtn:active,
.contacts__link:active,
.contacts__call:active,
.contact-detail__field-link:active,
.agenda-list__item:active,
.agenda-day__context:active,
button.radiorow:active,
.coach-actions__item:active,
.setrow:active,
.avsheet__rij:active,
.mail-drawer__edit:active,
.mail-drawer__sessie:active,
.home__task--flush:active,
.home__invite-solo:active,
.plan-choice:active,
.coach-sheet__q:active,
.coach-bar:active,
.kasboek__row:active,
.mail-drawer__folder:active,
.mail-actions__item:active,
.meldingen__item:active,
.plan-topic:active,
.vakanties__row:active,
button.timewheel__display:active,
button.datecal__display:active,
.datecal__yearbtn:active,
.datecal__monthbtn:active,
.datecal__navbtn:active,
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input:active,
.screen-head__pick:active,
.infocard__act:active,
.agenda-mobile__strook-weekcel:active,
.agenda-month__cell:active,
.knowledge-btn:active,
.agenda-form__delete:active,
.app-topbar__menu:active,
.app-topbar__bell:active,
.sheet__kop-save:active,
.confirm__ok:active,
.confirm__cancel:active,
.vnav__action:active,
.doclist__kebab:active,
.kaart__menu:active,
.vnav__back:active,
.vac-period__del:active,
.agenda-mobile__strook-cel:active .agenda-mobile__strook-num {
  background: var(--color-druk);
  transition-duration: var(--druk-in);
}
.agenda-form__optsummary > *,
.lade__row > *,
.pick-row > *,
.folderlist__link > *,
.doclist__link > *,
.movelist__item > *,
.infofilter__opt > *,
.sheetmenu__item > *,
.samen__linkbtn > *,
.agenda-list__item > *,
.agenda-day__context > *,
button.radiorow > *,
.coach-actions__item > *,
.setrow > *,
.avsheet__rij > *,
.mail-drawer__edit > *,
.mail-drawer__sessie > *,
.home__task--flush > *,
.home__invite-solo > *,
.plan-choice > *,
.coach-sheet__q > *,
.coach-bar > *,
.kasboek__row > *,
.mail-drawer__folder > *,
.mail-actions__item > *,
.meldingen__item > *,
.plan-topic > *,
.vakanties__row > * { transition: transform var(--druk-uit) ease-out; }
.agenda-form__optsummary:active > *,
.lade__row:active > *,
.pick-row:active > *,
.folderlist__link:active > *,
.doclist__link:active > *,
.movelist__item:active > *,
.infofilter__opt:active > *,
.sheetmenu__item:active > *,
.samen__linkbtn:active > *,
.agenda-list__item:active > *,
.agenda-day__context:active > *,
button.radiorow:active > *,
.coach-actions__item:active > *,
.setrow:active > *,
.avsheet__rij:active > *,
.mail-drawer__edit:active > *,
.mail-drawer__sessie:active > *,
.home__task--flush:active > *,
.home__invite-solo:active > *,
.plan-choice:active > *,
.coach-sheet__q:active > *,
.coach-bar:active > *,
.kasboek__row:active > *,
.mail-drawer__folder:active > *,
.mail-actions__item:active > *,
.meldingen__item:active > *,
.plan-topic:active > *,
.vakanties__row:active > * {
  transform: translateX(var(--druk-schuif));
  transition-duration: var(--druk-in);
}
@media (prefers-reduced-motion: reduce) {
  .agenda-form__optsummary:active > *,
.lade__row:active > *,
.pick-row:active > *,
.folderlist__link:active > *,
.doclist__link:active > *,
.movelist__item:active > *,
.infofilter__opt:active > *,
.sheetmenu__item:active > *,
.samen__linkbtn:active > *,
.agenda-list__item:active > *,
.agenda-day__context:active > *,
button.radiorow:active > *,
.coach-actions__item:active > *,
.setrow:active > *,
.avsheet__rij:active > *,
.mail-drawer__edit:active > *,
.mail-drawer__sessie:active > *,
.home__task--flush:active > *,
.home__invite-solo:active > *,
.plan-choice:active > *,
.coach-sheet__q:active > *,
.coach-bar:active > *,
.kasboek__row:active > *,
.mail-drawer__folder:active > *,
.mail-actions__item:active > *,
.meldingen__item:active > *,
.plan-topic:active > *,
.vakanties__row:active > * { transform: none; }
}

/* Eén letter (design system 2026-09-26): koppen zijn Hanken Grotesk; het gewicht maakt de kop. */

/* Een link is accent-tekst zónder onderstreping (contact-opdracht 2026-09-03 §6). Zonder
   deze regel viel elk <a> zonder eigen class terug op de browserstandaard — onderstreept
   en in de blauw-achtige erfkleur — wat op de Assistent-pane zichtbaar was. */
a { color: var(--color-accent); text-decoration: none; }
a:hover { color: var(--color-accent-hover); }

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

.container {
  width: 100%;
  max-width: 640px;
  margin-inline: auto;
  padding: var(--space-4);
}

/* ===================== PAGINACONTAINER (.page) ===================== */
/* Eén schermpadding voor álle full-bleed ouder-schermen (audit 2026-08-06 §3):
   18px zijkant, 8px + safe-area boven, 24px onder (de bottom-nav-clearance komt
   app-breed uit .app__body, zie bottom_nav.css), max 520px gecentreerd.
   Nieuwe schermen dragen .page; de legacy container-classes hieronder delen de
   regel tot hun views .page dragen. Varianten via de custom properties
   (--page-gutter/-top/-bottom/-max), nooit via een eigen padding-regel. */
.page,
.home, .gezin-section, .contacts, .contact-detail, .kinddetail,
.noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
.account, .account-section, .backup-pw, .plan {
  /* width:100% want deze containers hangen in een flex-RIJ (.app__body). Zonder breedte
     krimpt een flex-item naar zijn inhoud: een scherm met smalle inhoud — de mail-opsteller —
     stond daardoor 33px van beide randen af in plaats van op de schermpadding
     (feedback 2026-09-10). max-width blijft de bovengrens op een breed scherm. */
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding: var(--page-top) var(--page-gutter) var(--page-bottom);
  color: var(--color-text);
}
/* De gedeelde app-topbar (direct kind) draagt de safe-area zelf — dan hierboven
   niet nóg eens. Vervangt de oude handmatige reset-lijst per container, waar
   .contact-detail en .fotoboek net niet in stonden (dubbele safe-area). */
:is(.page, .home, .gezin-section, .contacts, .contact-detail, .kinddetail,
    .noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
    .account, .account-section, .backup-pw, .plan):has(> .app-topbar) {
  padding-top: 0;
}

/* Idem voor de V9-terugkop: die centreert zichzelf op 16px, dus de pagina eronder houdt
   exact dezelfde inzet — één maat voor kop, vlakken en tekst. (Stond eerst op 0 met een
   eigen marge per vlak; dat werd per scherm bijplakken, zie 2026-08-29.) */
:is(.page, .home, .gezin-section, .contacts, .contact-detail, .kinddetail,
    .noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
    .account, .account-section, .backup-pw, .plan):has(> .vnav) {
  /* 16 -> 18px (prototype-maat 2026-09-02): de schermpadding is app-breed 18. */
  --page-gutter: 18px;
  padding-top: 0;
}
/* De kop-familie draagt zijn eigen zijinzet (zodat hij ook los van een container klopt —
   het toevoeg-scherm rendert hem naast de sectie). Zit hij ín een container die al padding
   heeft, dan telde dat op: de terug-link en de schermnaam stonden 34-36px in terwijl het
   scherm eronder op 18 staat (gemeld met schermafdruk, 2026-09-03). Hier dus geen eigen
   inzet meer; de ‹-knop trekt zijn eigen 8px aanraakvlak terug zodat het pijltje precies
   op de tekstlijn eronder uitkomt. */
:is(.page, .home, .gezin-section, .contacts, .contact-detail, .kinddetail,
    .noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
    .account, .account-section, .backup-pw, .plan):has(> .vnav) > .vnav {
  padding-inline: 0;
  margin-inline: -8px;
}
:is(.page, .home, .gezin-section, .contacts, .contact-detail, .kinddetail,
    .noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
    .account, .account-section, .backup-pw, .plan):has(> .vnav) > :is(.vnav__pagetitle, .vnav__pagesub) {
  padding-inline: 0;
}
/* Idem onder de titelrij van een bestemming (vnav in de topniveau-stand): de container
   draagt de gutter al, dus de subregel niet nóg eens. */
:is(.page, .home, .gezin-section, .contacts, .contact-detail, .kinddetail,
    .noodkaart, .fotoboek, .fotoboek-detail, .fotoboek-invitescreen, .meldingen,
    .account, .account-section, .backup-pw, .plan):has(> .app-topbar) > .vnav__pagesub {
  padding-inline: 0;
}

@media (min-width: 640px) {
  .container { padding: var(--space-6); }
}

/* ===================== COMPONENTEN ===================== */
.card {
  background: var(--color-card);
  border-radius: var(--radius);
  padding: var(--space-4);
  box-shadow: var(--shadow-vlak);
}

@media (min-width: 640px) {
  .card { padding: var(--space-6); }
}

.card__title {
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}

.card__meta {
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ===================== CHAT (DP2) ===================== */
/* Eén gespreksstroom in het Claude-palet: volle-breedte warme achtergrond, content
   (berichten + composer) gecentreerd. Eigen bericht rechts (warm-grijs), de ander
   links (wit) — WhatsApp-indeling. De chat vult de viewport onder de nav (body =
   flex-kolom); de stroom scrollt, de composer staat vast onderaan. */
.chat {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--color-chat-bg);
  color: var(--color-chat-text);
}

.chat__stream {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Zijpadding = app-brede scherm-padding (was 16px — het enige scherm dat afweek). */
  padding: var(--space-4) var(--page-gutter);
  display: flex;
  flex-direction: column;
}
/* Berichten vastgeankerd onderaan (WhatsApp-stijl): bij weinig berichten staan ze
   onderin, nieuwste onderaan; bij overflow collapst de marge en scroll je omhoog
   naar oudere berichten. */
.chat__stream .messages { margin-top: auto; }
/* Kop en opsteller zweven over het gesprek (ChatGPT-stijl, Jerry 2026-10-09): de stroom loopt
   van boven tot onder door en krijgt de hoogte van kop en opsteller als ruimte (composer-hoogte-
   controller). De kop is licht doorschijnend; het gesprek schuift er wazig onderdoor. */
.chat__stream {
  padding-top: calc(var(--kop-h, 120px) + var(--space-4));
  padding-bottom: calc(var(--composer-h, 88px) + var(--space-2));
}
.chat__kop, .coach-sheet__head {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 3;
  background: color-mix(in srgb, var(--color-chat-bg) 84%, transparent);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
}

/* Systeemmelding bij een verstuurpoging tijdens een Samen-terugval (T5):
   alleen de afzender ziet dit, geen opgeslagen Message. */
.chat-error { color: var(--color-error); font-size: var(--text-sm); line-height: var(--leading); margin: 8px 0; }

.messages {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  /* 760px: chat-breedte — ruimer dan de 640px-container voor niet-chat-pagina's */
  max-width: 760px;
  margin-inline: auto;
}

/* Rij = bubbel + status-vinkjes. De ander links, eigen rechts (class door de
   own-message-controller). Kant + afgeplatte bubbelhoek = twee signalen naast
   kleur (WCAG 1.4.1). */
.message-row {
  /* Zelfde reden als bij .mail-swipe: de veeg naar rechts (antwoorden) is van ons, alleen
     verticaal scrollen is van de browser. */
  touch-action: pan-y;
  position: relative;
  display: flex;
  flex-direction: column;
  align-self: flex-start;
  align-items: flex-start;
  gap: 2px;
  max-width: 80%;
  transition: transform 0.18s ease;
}
/* Tijdens het slepen volgt de rij de vinger (geen transitie); bij loslaten veert
   'ie terug via de transitie hierboven. */
.message-row--swiping { transition: none; }

.message-row--own {
  align-self: flex-end;
  align-items: flex-end;
}

/* De ander: wit met de gewone haarlijn (was een warme accent-rand, 2026-09-12). */
/* ChatGPT-stijl (prototype CHAT 2026-09-28): de tekst op 17, 13/16 binnenruimte. */
.message {
  padding: 13px 16px;
  font-size: var(--text-17);
  background: var(--color-chat-bubble-other);
  border: 0;
  border-radius: var(--radius-ballon);
}

/* Eigen bericht: hetzelfde neutrale, ruime vlak als in de assistent (2026-09-12, model: de
   Claude-app). Stond hier als manilla bubbel met bruine tekst en een afgeplatte hoek; die
   kleur zei niets en de chat en de assistent zagen er als twee apps uit. */
.message-row--own .message {
  background: var(--color-btn);
  color: var(--color-on-btn);
  border: 0;
  border-radius: var(--radius-ballon);
  padding: 13px 16px;
}
.message-row--own .message__body { font-size: var(--text-17); line-height: var(--leading-lees); }
.message-row--own .message__meta,
.message-row--own .message :is(.message__quote-author, .message__quote-body, .message__quote-body--veiled, a) { color: var(--color-on-btn); }
.message-row--own .message__quote { border-left-color: var(--color-on-btn); }

/* Geciteerd bericht (reply): klein quote-blokje bovenin de bubbel. */
.message__quote {
  display: block;
  margin-bottom: 4px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, 0.04);
  border-left: 3px solid var(--color-chat-accent);
  border-radius: var(--radius-binnen);
  font-size: var(--text-xs);
  line-height: var(--leading);
}
.message__quote-author { display: block; font-weight: 500; color: var(--color-chat-accent); }
.message__quote-body { display: block; color: var(--color-text-muted); overflow-wrap: anywhere; }

/* Reply-knop (desktop): verschijnt op hover, net buiten de bubbel aan de binnenkant.
   Op touch verborgen — daar is de swipe de manier. */
.message__reply {
  position: absolute;
  top: 50%;
  right: -34px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-binnen);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.message-row--own .message__reply { right: auto; left: -34px; }
.message-row:hover .message__reply { opacity: 1; }
.message__reply-icon { width: var(--icon-sm); height: var(--icon-sm); }
@media (hover: none) {
  .message__reply { display: none; }
}

/* Crisis-bubbel — alléén de coach-ruimte. "De warme vloor": een zacht, warm
   vasthoudend vlak, NOOIT een alarm (geen rood, geen schreeuw). Zelfde bubbel-
   anatomie als .message (DRY); alleen warmer getint — zacht clay-vlak + gedempte
   clay-rand. Coach = links, dus de afgeplatte linkeronderhoek blijft staan. */
.message--crisis {
  background: var(--color-chat-surface-own);
  border-color: rgba(196, 115, 74, 0.35);
}

.message__body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Typ-indicator (assistent denkt na / andere ouder typt): drie bolletjes die om de
   beurt omhoog wippen — bewust GEEN bubbel-chrome (geen achtergrond/rand/schaduw),
   puur de bewegende stippen in de gespreksstroom. Vluchtig client-side element —
   nooit gepersisteerd. */
.message--typing {
  background: none;
  border: none;
  border-radius: 0;
  padding: var(--space-2) var(--space-3);
}
.typing-dots { display: inline-flex; align-items: center; gap: 6px; }
.typing-dots span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cloud-medium);
  animation: typing-bounce 1s ease-in-out infinite;
}
.typing-dots span:nth-child(2) { animation-delay: 0.16s; }
.typing-dots span:nth-child(3) { animation-delay: 0.32s; }
@keyframes typing-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
  40% { transform: translateY(-7px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .typing-dots span { animation: none; opacity: 0.6; }
}

/* Assistent-actieknoppen onder een coach-bubbel (prefill; efemeer op de verse beurt). */
.message__actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 0 4px; }
.message__action-btn {
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}
.message__action-btn:hover { background: var(--color-panel); }

/* Afzender-naam: in een 1-op-1-chat zegt de kant al wie het stuurde — visueel
   verborgen, maar in de DOM voor schermlezers. */
.message__author {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Tijd + vinkjes rechtsonder ín de bubbel (WhatsApp-stijl). */
.message__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
  margin-top: 2px;
  font-size: var(--text-sm);
  line-height: 1;
  color: var(--color-text-muted);
}

.message__time {
  font-variant-numeric: tabular-nums;
}

/* Status (vinkjes): ✓ verzonden, ✓✓ afgeleverd — own-only (controller toont 'm). */
.message__status {
  display: inline-flex;
  align-items: center;
}

.message__tick {
  letter-spacing: -0.15em;
}

/* Inkomend-berichtenfilter: de sluier is een compacte, laag-contrast weergave — geen
   aandacht-trekkende kaart. De labels blijven rauw en onverzacht (veiligheidsdragend). */
.message--veiled {
  background: var(--color-surface);
  border: 1px dashed var(--color-border);
}

.veil__summary {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
}

.veil__summary-label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-text-muted);
  margin-bottom: 2px;
}

.veil__note {
  margin: 0 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.veil__labels {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0 0 var(--space-2);
}

.veil__label,
.veil__topic {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: 1px 8px;
}

.veil__reveal {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--text-sm);
  color: var(--color-accent);
  text-decoration: underline;
  cursor: pointer;
}

/* Na onthullen: permanent beschikbaar, maar ingeklapt bij terugscrollen (native details). */
.veil-details__summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  cursor: pointer;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.veil-details__status { }

.veil-details[open] .veil-details__summary {
  margin-bottom: var(--space-2);
}

/* Verzamel-regel boven de stroom: stil — geen badge, geen kleur, alleen tekst. */
.veil-collect {
  align-self: center;
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
}

.veil-collect__link {
  color: var(--color-text-muted);
  text-decoration: underline;
}

/* Contextuele aanbieding van het filter: discreet regeltje boven de compose-zone. */
.veil-offer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.veil-offer__link {
  color: var(--color-accent);
}

.veil-offer__dismiss {
  background: none;
  border: none;
  padding: 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-decoration: underline;
  cursor: pointer;
}

/* Gate-hint in de review-kaart (§3.3): informatief, ondergeschikt aan de acties. */
.review-card__filter-hint {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.message__quote-body--veiled {
  font-style: italic;
  color: var(--color-text-muted);
}

/* Dag-scheiding: Fluent-divider — een fijne lijn met een gecentreerd caption-label
   (luchtiger dan een pil), gespannen over de berichten-kolom. */
.day-separator {
  align-self: stretch;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.day-separator::before,
.day-separator::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-line);
}

/* Export-markering: zelfde rustige toon als de dagscheider hierboven (geen
   waarschuwing) — hergebruikt diens tokens voor kleur en tekstgrootte. */
.chat-export-marker {
  margin: var(--space-4) 0 var(--space-2);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

/* Fluent-entree: berichten zakken zacht naar hun plek (rise + fade) met de
   decelerate-curve. Eén keer per render; bij een nieuw broadcast-bericht
   animeert alleen die ene rij. Respecteert prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  .message-row {
    animation: message-in var(--dur-normal) var(--curve-decel) both;
  }
}
@keyframes message-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Naam-label (anti-misverzend) zit als aria-label op de knop; visueel verborgen
   zodat alleen het vliegtuig-icoon toont. */
.compose__send-name {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Composer: vast onderaan, wit afgerond veld + koraal-verzendknop (Claude-look). */
/* Alleen-lezen gearchiveerd gesprek: waar anders het opstelveld staat. */
.chat__gearchiveerd { margin: 0; padding: 14px var(--page-gutter); text-align: center; font-size: var(--text-sm); color: var(--color-faint); }

.chat__composer {
  flex-shrink: 0;
  /* Zonder bottom-nav vangt de composer zelf de home-indicator op. */
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: var(--space-3) var(--page-gutter) calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  background: transparent;
  pointer-events: none;
}
.chat__composer > * { pointer-events: auto; }
/* Het veld zelf is een tikje doorschijnend, met de berichten wazig erachter; geen inktrand bij
   focus (de cursor zegt al dat je typt, zoals in ChatGPT). */
.chat__composer .compose:focus-within, .coach-sheet__composer .compose:focus-within { border-color: transparent; }
.chat__composer .compose, .coach-sheet__composer .compose {
  background: color-mix(in srgb, var(--color-surface) 86%, transparent);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
/* Mét bottom-nav (chat en assistent sinds 2026-09-12) draagt de balk de home-indicator al
   en zit de composer er direct boven: dan geen dubbele veilige zone. */
.app__main:has(> .bottom-nav) .chat__composer { padding-bottom: var(--space-1); }
/* Mobiel met de menubalk: het gesprek loopt door tot de onderrand, achter de balk langs (zoals
   overal in de app, Jerry 2026-10-09); de opsteller zweeft er net boven. */
@media (max-width: 767px) {
  .app__main:has(> .bottom-nav) .app__body:has(> .chat) { padding-bottom: 0; }
  .app__main:has(> .bottom-nav) .chat__composer { padding-bottom: calc(var(--bottom-nav-h) - 10px + env(safe-area-inset-bottom, 0px)); }
}

/* Reply/quote ín de pill (WhatsApp-stijl): grijs blokje boven het tekstveld. */
.compose__reply {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: rgba(0, 0, 0, 0.05);
  border-left: 3px solid var(--color-chat-accent);
  border-radius: var(--radius-groep);
}
.compose__reply[hidden] { display: none; } /* [hidden] moet de flex hierboven verslaan */
.compose__reply-quote { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.compose__reply-author { font-size: var(--text-xs); font-weight: 500; color: var(--color-chat-accent); }
.compose__reply-snippet {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
.compose__reply-cancel {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--color-text-muted);
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.compose__reply-cancel:hover { color: var(--color-text); }

/* Composer = los tekstveld (eigen pill) + losse ronde verzendknop ernaast
   (WhatsApp-stijl). Volle-breedte achtergrond eromheen; content gecentreerd. */
/* Eén blok waarin je typt, met de knoppen eronder (feedback 2026-09-11). Het was een pill
   met drie dingen erin — tekst, paperclip, camera — en een losse verzendknop ernaast; het
   veld werd daardoor smal terwijl er ruimte zat. Nu draagt het blok de vorm en is het veld
   kaal: je typt over de volle breedte en de acties staan op hun eigen regel. */
/* Eén opsteller voor chat en assistent (2026-09-12, model: de Claude-app): het veld en de
   verzendknop zijn één wit vlak met een fijne rand — de knop zit ín het vlak, rechtsonder,
   rond en in inkt. De chat had een eigen variant met een terracotta rand, een bijlage- en
   een fotoknop en een losse actierij; die is opgegaan in deze ene. */
.compose {
  position: relative;
  display: block;
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
  padding: 8px 8px 8px 6px;
  background: var(--color-surface);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-pil);
  transition: border-color var(--dur-fast) var(--curve-decel);
}
.compose:focus-within { border-color: var(--color-text); }

/* Kaal binnen het blok: de vorm en de focus-rand zitten op .compose (2026-09-11). */
.compose__field {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 0 56px 0 0; /* ruimte voor de verzendknop in het vlak */
}

.compose__field-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-1);
}

/* Het tekstveld is de opsteller zelf, geen vak erin: geen grond, geen rand — en ook geen
   lift, radius of focusring, want die krijgt élk veld van de gedeelde veldbasis
   (`:where(input, select, textarea)`) en dat gaf een kader-in-een-kader zodra je typte
   (feedback 2026-09-12). */
.compose__body {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  max-height: 160px;
  padding: 11px 12px;
  border-radius: 0;
  box-shadow: none;
  font: inherit;
  font-size: var(--text-17);
  line-height: var(--leading);
  color: var(--color-chat-text);
  background: transparent;
  border: 0;
  resize: none;
}

.compose__body:focus,
.compose__body:focus-visible {
  outline: none;
  border: 0;
  box-shadow: none;
}

/* Chat en assistent delen hun controlvorm; afzender en context blijven in de bestaande labels. */
.chat__leeg { padding: 0 2px 6px; }

/* Verzendknop: rond, in inkt, rechtsonder ín het opstelvlak (36px — kleiner dan de
   44px van eerst, feedback 2026-09-12). De "Stuur naar <naam>"-tekst (anti-misverzend)
   zit als aria-label op de knop en is visueel verborgen (zie .compose__send-name). */
.compose__submit {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  /* Inkt, geen accent (2026-09-12): verzenden is dé primaire actie, en die is app-breed
     --color-btn — zoals "Opslaan" en "Selecteer". Het accent-bolletje was het laatste
     terracotta vlak in het gesprek; --color-chat-accent blijft voor de citaat-streep. */
  color: var(--color-on-btn);
  background: var(--color-btn);
  border: 0;
  /* Rond, niet vierkant (2026-09-11): een verzendknop is één handeling, geen vlak. */
  border-radius: 50%;
  cursor: pointer;
  overflow: hidden;
  transition: background var(--dur-fast) var(--curve-decel),
              transform var(--dur-fast) var(--curve-decel);
}

.compose__submit:hover {
  background: var(--color-text);
}

.compose__submit:active {
  transform: translateY(0.5px);
}

.compose__send-icon {
  width: var(--icon);
  height: var(--icon);
  transition: opacity 0.15s;
}

/* Subtiele spinner: dun wit ringetje dat ronddraait; icoon verdwijnt zacht. */
/* Transparante wrapper zodat de flex-layout van .compose onveranderd blijft. */
/* Bijlage en foto links, verzenden rechts. */

/* Generieke laad-spinner-op-knop (submit-spinner-controller, DRY): verbergt de knop-
   inhoud (tekst óf icoon, ongeacht opmaak — via > * i.p.v. een element-specifieke regel)
   en draait er een wit ringetje overheen. Herbruikbaar op elke knop met een actie die
   even duurt (versturen, uploaden, toon-analyse, …) — app-breed één stijl i.p.v. losse
   per-knop-implementaties. */
.is-loading { position: relative; cursor: default; pointer-events: none; }
/* Een knop die zelf al gepositioneerd is (de verzendknop: absolute, rechts) houdt die plek. */
.compose__submit.is-loading { position: absolute; }
.is-loading > * { visibility: hidden; }
.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: var(--color-on-accent);
  border-radius: 50%;
  animation: spin 0.65s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Info-/fail-melding boven het veld (rustig informatief, geen alarm). */
.compose__notice {
  flex-basis: 100%;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ===================== COACH-RUIMTE (Claude-stijl) ===================== */
/* De coach-ruimte deelt de chat-shell (.chat / .message-row / .message / .compose)
   maar volgt het assistent-paradigma i.p.v. WhatsApp: de coach "praat" als platte
   donkere tekst direct op de achtergrond (géén bubbel), de ouder houdt een lichte
   bubbel rechts. Alle bubbel-anatomie komt nog uit .message (DRY) — hier alléén de
   afwijkingen, gescoped onder .coach. */

/* Ouder-bubbel: erft de warme zand-bubbel van de chat (DRY) — geen eigen coach-tint meer. */

/* Coach-beurt: geen bubbel. Sterretje-glyph + platte tekst op de achtergrond, volle
   leesbreedte. De crisis-vloer blijft wél een (warme) bubbel — bewust vasthoudend. */
.coach .message-row:not(.message-row--own) {
  flex-direction: row;
  gap: 11px;
  align-items: flex-start;
  max-width: 100%;
}
.coach .message-row:not(.message-row--own) .message:not(.message--crisis) {
  padding-inline: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.coach .message-row:not(.message-row--own) .message__body { line-height: var(--leading-lees); }

/* De coach-rij staat op row (bubbel + acties naast elkaar door de regel hierboven) —
   wrap zodat de actieknoppen op een eigen regel ONDER de bubbel vallen i.p.v.
   ernaast; flex-basis: 100% dwingt bij .message__actions de nieuwe regel af. */
.coach .message-row:not(.message-row--own) { flex-wrap: wrap; }
.coach .message-row:not(.message-row--own) .message__actions { flex-basis: 100%; }

/* Ruimte tussen het eigen bericht en het antwoord van de assistent. */
/* De eigen bubbel van de assistent is sinds 2026-09-12 de basis voor élke eigen bubbel
   (zie .message-row--own .message hierboven); hier geen eigen regel meer. */

.coach .messages {
  gap: var(--space-4);
}

/* Coach-kop: sessie-la + titel + ⋯, op de paginagrond. Dit was een tweede witte balk
   onder de app-header — twee chrome-balken met elk een hamburger boven elkaar
   (feedback 2026-09-10). De app-header blijft (de lade is de navigatie), maar deze rij
   is nu gewoon de titelregel van het gesprek. */
.coach-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 2px var(--page-gutter) 12px;
  background: transparent;
}
.coach-head__title {
  flex: 1;
  min-width: 0;
  font-size: var(--text-lg);
  font-weight: 500;
  overflow-wrap: break-word;
}
.coach-head .button_to { margin: 0; }
/* De chat-kop (prototype 29 sep): terug links, de naam met "Andere ouder" eronder in het
   midden, het ⋯ rechts. */
.coach-head__terug { flex: none; margin: 0; }
.coach-head__naam { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; text-align: center; }
.coach-head__naam .coach-head__title { flex: none; max-width: 100%; font-size: var(--text-17); }
.coach-head__sub { margin-top: 1px; font-size: var(--text-15); color: var(--color-text-muted); }
/* In de assistent staat de titel links, naast de knop Gesprekken. */
.coach-head__naam--links { align-items: flex-start; text-align: left; }

/* Kebab in de coach-kop: opent de sessie-acties (zelfde plek en vorm als de kebab in
   de mail-draad, design "Mail - UX ontwerp" scherm 10). */
.coach-head__menu {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  color: var(--color-text);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.coach-head__menu svg { width: var(--icon-lg); height: var(--icon-lg); }
/* Sessie-acties-sheet (⋯ in de kop): verticale opbouw — een hernoem-rij bóven een
   menu-lijst met tikbare rijen. Bewust NIET de horizontale .sheet-actions (die propt
   de drie forms op één regel: afgeknelde input + afgekapte acties). */
.coach-actions { display: flex; flex-direction: column; }

/* De chat en assistent delen de actierijstijl met sheetmenu en mail-actions. */
.coach-actions__menu { display: flex; flex-direction: column; gap: 3px; }
.coach-actions__menu > form { margin: 0; }

/* ===================== DE-ESCALATIE (DP3) ===================== */
/* Een gefluisterde alternatieve formulering bóven het invoerveld — géén dominante
   kaart en géén alarmerende blokkade. De kaart vervangt de verzendknop en wordt via
   flex (order/flex-basis) bovenop het veld geplaatst, zodat de suggestie verschijnt
   wáár je typt en niet ernaast. Een frosted, translucent warm vlak; het voorstel is
   een pull-quote (géén veld-look), de acties staan in één compacte rij. */
/* Suggestie-kaart in de eigen regio (#deescalation-review) boven de bar — vervangt
   NIET meer de verzendknop/het veld. Zacht warm vlak, géén rand. */
.review-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-chat-surface-own);
  border: 0;
  border-radius: calc(var(--radius) + var(--radius-xs));
  animation: review-card-in 0.28s cubic-bezier(0.25, 0.1, 0.25, 1);
}

@keyframes review-card-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

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

/* Kop: kleine, rustige label-regel met een zacht koraal-puntje als markering. */
.review-card__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--color-text-muted);
}

.review-card__heading::before {
  content: "";
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-chat-accent);
  opacity: 0.7;
}

/* Het voorstel: rechte tekst met een rustig koraal-lijntje links — een callout,
   géén box/rand/wit en géén cursief, dus niet te verwarren met een invoerveld. */
.review-card__suggestion {
  margin: 0;
  padding-left: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading);
  color: var(--color-chat-text);
  background: none;
  border: 0;
  border-left: 2px solid var(--color-chat-accent);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Eén actie-rij: hoofdacties links, de uitweg rechts (margin-left:auto). */
.review-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

.review-card__action {
  margin: 0;
}

/* Compact: icoon + kort label op inhoudsbreedte. */
.review-card__submit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 0 var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  border-radius: var(--radius);
  cursor: pointer;
}
.review-card__icon { width: var(--icon-sm); height: var(--icon-sm); flex-shrink: 0; }

/* Primair: gevuld accent, compact, met een subtiele lift. */
.review-card__submit--primary {
  color: var(--color-on-accent);
  background: var(--color-chat-accent);
  border: 0;
  box-shadow: 0 1px 2px rgba(179, 97, 63, 0.25);
}

.review-card__submit--primary:hover {
  background: var(--color-chat-accent-hover);
}

/* Secundair: pure ghost-knop (geen vlak/rand) — ondergeschikt aan primair. */
.review-card__submit--secondary {
  color: var(--color-chat-text);
  background: transparent;
  border: 0;
}

.review-card__submit--secondary:hover {
  background: var(--color-hover);
}

/* "Tóch ongewijzigd versturen": meest ondergeschikt — kleine link, rechts in de rij. */
.review-card__action--muted {
  margin-left: auto;
}

.review-card__link {
  padding: var(--space-1) 0;
  font: inherit;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
  background: none;
  border: 0;
  cursor: pointer;
}

.review-card__link:hover {
  color: var(--color-chat-text);
}

/* Hard-modus: melding dat rustige formulering vereist is — rechts in de rij. */
.review-card__enforced {
  margin: 0 0 0 auto;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* ===================== BAROMETER (DP3) ===================== */
/* Cijferloze, perifere gespreks-richting-meter bovenaan de chat. Ontworpen om de
   arousal te VERLAGEN, niet om de "richting" zo scherp mogelijk te schreeuwen: een
   rustige rand-indicator, geen focaal element (anders gaan ouders "presteren voor de
   meter"). De track-container heeft in ELKE zone dezelfde footprint — alleen de
   fill-breedte + tint binnen die vaste track verschuift (thermometer, geen alarm).
   Geen border/shadow/groei die in de hot-zone aanzwelt (zou de meter laten schreeuwen,
   ongeacht de tint). */

/* Placeholder-staat (te weinig beurten): de lege #barometer blijft als Turbo-replace-
   target in de DOM maar neemt geen layout-ruimte in (geen opgedrongen witruimte). */
#barometer:not(.barometer) {
  display: contents;
}

/* Puur-visuele temperatuur-indicator bovenaan de compose-zone: een dunne getinte
   lijn + een rustig info-icoon met tooltip. Geen vaste tekstregels meer — de
   betekenis blijft als tekst beschikbaar via aria-label + tooltip (kleur is nooit
   de enige drager; de vullengte per zone is het tweede visuele kanaal). */
.barometer {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  max-width: 760px; /* zelfde kolom-as als .messages / .compose */
  margin: 0 auto var(--space-1);
  padding: 0 var(--space-2);
}

/* Meter-rij: de lijn groeit, het info-icoon staat rustig aan het eind. */
.barometer__meter {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* Temperatuur-lijn: dun (4px), perifere rand-indicator net boven het invoerveld. */
.barometer__track {
  flex: 1;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--color-barometer-track);
  overflow: hidden;
}

/* Vulling links→rechts. Breedte + tint per zone; nooit 100% (= max-uitslag, alarm).
   Startwaarden, te tunen met de drempel-kalibratie. */
.barometer__fill {
  height: 100%;
  width: 28%;
  background: var(--color-barometer-calm-fill);
}

.barometer--calm .barometer__fill {
  width: 28%;
  background: var(--color-barometer-calm-fill);
}

.barometer--warming .barometer__fill {
  width: 58%;
  background: var(--color-barometer-warming-fill);
}

.barometer--hot .barometer__fill {
  width: 88%;
  background: var(--color-barometer-hot-fill);
}

/* Rustige overgang — load-bearing voor de de-escalatie ÉN de asymmetrie-bescherming:
   een trage, continue vervloeiing voorkomt een toerekenbare visuele sprong na één
   bericht (zou de dyade-meter de facto per-persoon maken — §8a.2). Pas actief ná de
   ready-haak, zodat de eerste render geen flash van de beginstand toont. */
.barometer--ready .barometer__fill {
  transition: width 1.2s cubic-bezier(0.25, 0.1, 0.25, 1), background-color 1.8s ease;
}

@media (prefers-reduced-motion: reduce) {
  .barometer--ready .barometer__fill {
    transition: none;
  }
}

/* Richting-tekst: primaire betekenis-drager (kleur is nooit de enige drager), maar
   bewust niet zwaarder dan een bericht. */
/* Rustig info-icoon ("i", geen alarm-"!") aan het eind van de lijn. */
.barometer__info {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  background: none;
  border: 0;
  cursor: help;
}

.barometer__info-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--icon-xs);
  height: var(--icon-xs);
  font-size: var(--text-10);
  font-weight: 500;
  font-style: normal;
  line-height: 1;
  color: var(--color-text-muted);
  border: 1px solid currentColor;
  border-radius: 50%;
}

.barometer__info:hover .barometer__info-icon,
.barometer__info:focus-visible .barometer__info-icon {
  color: var(--color-chat-text);
}

/* Tooltip: verschijnt boven het icoon op hover én focus (tap = focus → werkt op
   touch). Donkere bubbel met lichte tekst; opent linksboven vanaf het icoon. */
.barometer__tooltip {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  z-index: 5;
  width: max-content;
  max-width: 240px;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs);
  font-weight: 400;
  line-height: var(--leading);
  text-align: left;
  color: var(--color-chat-bg);
  background: var(--color-chat-text);
  border-radius: var(--radius);
  box-shadow: var(--shadow-16);
  opacity: 0;
  visibility: hidden;
  transform: translateY(3px);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s;
  pointer-events: none;
}

.barometer__info:hover .barometer__tooltip,
.barometer__info:focus .barometer__tooltip {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Afkoel-prompt: een zachte uitnodiging met agency, geen waarschuwing. Lichter dan
   de berichten eromheen (geen border/shadow → niet urgenter ogen dan de review-kaart).
   Niet-blokkerend, naast de stroom. */
.barometer__cooldown {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-top: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  background: var(--color-barometer-cooldown-bg);
}

/* [hidden] moet de display:flex hierboven verslaan — anders blijft de cooldown
   zichtbaar nadat de Sluit-knop hem op hidden zet (was de "Sluit werkt niet"-bug). */
.barometer__cooldown[hidden] {
  display: none;
}

.barometer__cooldown-text {
  flex: 1;
  min-width: 0;
}

.barometer__cooldown-title {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-chat-text);
}

.barometer__cooldown-body {
  margin: 2px 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* Sluiten: een rustige × rechtsboven — makkelijke, ondergeschikte uitweg. */
.barometer__cooldown-dismiss {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin: -2px -4px 0 0;
  padding: 0;
  color: var(--color-text-muted);
  background: none;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}

.barometer__cooldown-dismiss:hover {
  color: var(--color-chat-text);
  background: rgba(0, 0, 0, 0.04);
}

/* ===================== METINGEN (DP6) ===================== */
/* Brede dashboard-pagina: vult de volledige breedte naast de sidebar (géén
   max-width), met ruime padding. Bewust niet de smalle .container (640px). */
.dashboard-page { width: 100%; padding: var(--space-6); }
@media (min-width: 768px) {
  .dashboard-page { padding: var(--space-8); }
}

.dashboard { --stack-gap: var(--space-6); }
.dashboard__title { font-size: var(--text-lg); font-weight: var(--weight-medium); }

/* Panelen-grid: tegels vloeien responsief in kolommen (M365-achtig). Laag-banden
   (toon/agenda, DEF-7) spannen de volle breedte zodat ze niet als gelijke tegel
   lezen maar als aparte meetlaag. */
.dashboard__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}
@media (min-width: 640px) {
  .dashboard__grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1200px) {
  .dashboard__grid { grid-template-columns: repeat(4, 1fr); }
}
.dashboard__band { grid-column: 1 / -1; }

/* Agenda-sub-panelen tegelen net als de andere widgets (volume/lock/revert/self). */
.agenda-panel__sub-panels {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}
@media (min-width: 640px) {
  .agenda-panel__sub-panels { grid-template-columns: repeat(2, 1fr); }
}

.dashboard__band-heading {
  margin: 0 0 var(--space-3);
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}

/* Sub-grid binnen een band: splitst een overvolle meetlaag in losse widgets
   (bv. de toon-trend + een indicatoren-widget per ouder), die tegelen. */
.dashboard__subgrid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}
@media (min-width: 640px) {
  .dashboard__subgrid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1200px) {
  .dashboard__subgrid { grid-template-columns: repeat(3, 1fr); }
}

/* Inklapbaar uitleg-panel: bundelt meet-kanttekeningen onder een band, rustig
   en standaard dicht. Chevron rechts die meedraait. */
.explain {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.explain__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  list-style: none;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.explain__summary::-webkit-details-marker { display: none; }
.explain__summary::after {
  content: "›";
  margin-left: auto;
  font-size: var(--text-base);
  line-height: 1;
  transition: transform 0.15s ease;
}
.explain[open] .explain__summary::after { transform: rotate(90deg); }
.explain__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.explain__body p {
  margin: 0;
  font-size: var(--text-xs);
  line-height: var(--leading);
  color: var(--color-text-muted);
}
.dashboard__panel { /* CardComponent verzorgt de border/padding */
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.measurements__pending {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6) 0;
}
.measurements__pending-title { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.measurements__pending-body { color: var(--color-text-muted); }
.measurements__pending-status { font-size: var(--text-sm); color: var(--color-text-muted); }

/* Meetlaag-sectie (LayerSectionComponent): kop + kaarten-stapel + grens-noot.
   Had géén CSS — de kaarten stonden op 0px van elkaar (audit 2026-08-06 B6).
   De body is een .stack in de template; hier alleen kop/voet-afstanden. */
.measurement-layer__header { margin-bottom: var(--space-3); }
.measurement-layer__subheading { color: var(--color-text-muted); font-size: var(--text-sm); }
.measurement-layer__footer { margin-top: var(--space-3); }
.measurement-layer__boundary { color: var(--color-text-muted); font-size: var(--text-sm); }

.dataviz { display: flex; flex-direction: column; gap: var(--space-2); }
.dataviz__label { font-size: var(--text-sm); color: var(--color-dataviz-text); }
.dataviz__svg { display: block; width: 100%; height: auto; max-height: 56px; }
.dataviz__stats-row { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.dataviz__stat { display: flex; align-items: baseline; gap: var(--space-2); }
.dataviz__stat-value { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.dataviz__stat-n { font-size: var(--text-sm); color: var(--color-dataviz-text); }
.dataviz__too-few {
  font-size: var(--text-sm);
  color: var(--color-dataviz-text);
  font-style: italic;
}

/* Lineaire %-meter (Claude-stijl): één dimensie als 0–100%-balk. */
.meter { display: flex; flex-direction: column; gap: 5px; }
.meter__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.meter__label { font-size: var(--text-sm); color: var(--color-text); }
.meter__value {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  font-variant-numeric: tabular-nums;
}
.meter__percent { font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-text); }
.meter__caption { font-size: var(--text-xs); color: var(--color-text-muted); }
.meter__value--muted { font-size: var(--text-sm); color: var(--color-text-muted); font-style: italic; }
.meter__track {
  height: 8px;
  background: var(--color-dataviz-muted);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.meter__fill { height: 100%; background: var(--color-dataviz-line); border-radius: var(--radius-pill); }

/* Stat-groep: een paar meters/stats onder een sub-label (bv. per ouder). */
.dashboard__stat-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

/* Vergelijkingsbalken: per partij één balk op gedeelde schaal (voor duren e.d.,
   géén aandeel). Rij zonder waarde toont alleen tekst (te weinig data). */
.compare-bars {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.compare-bars__row {
  display: grid;
  grid-template-columns: 7rem 1fr auto;
  align-items: center;
  gap: var(--space-2);
}
.compare-bars__label { font-size: var(--text-sm); color: var(--color-text); }
.compare-bars__track {
  height: 8px;
  background: var(--color-dataviz-muted);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.compare-bars__fill { height: 100%; border-radius: var(--radius-pill); }
.compare-bars__value {
  font-size: var(--text-sm);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.compare-bars__value--muted {
  grid-column: 2 / -1;
  color: var(--color-text-muted);
  font-style: italic;
}

/* Donut: ring met neutrale segmenten + totaal in het midden, legenda ernaast. */
.donut {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.donut__chart {
  position: relative;
  flex-shrink: 0;
  width: 132px;
  height: 132px;
}

.donut__svg { display: block; width: 100%; height: 100%; }

.donut__track { fill: none; stroke: var(--color-dataviz-muted); }

.donut__seg {
  fill: none;
  stroke-linecap: butt;
  transition: stroke-dasharray 0.6s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.donut__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.donut__center-value {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  line-height: 1;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.donut__center-label { font-size: var(--text-xs); color: var(--color-text-muted); }

.donut__legend {
  flex: 1;
  min-width: 150px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.donut__legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
}
.donut__legend-dot {
  flex-shrink: 0;
  width: 10px;
  height: 10px;
  border-radius: var(--radius-xs);
}
.donut__legend-label { color: var(--color-text); }
.donut__legend-value {
  margin-left: auto;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.dataviz__bars { display: flex; flex-direction: column; gap: var(--space-2); }
/* Mobile-first: label vol-breed boven de track; vanaf 480px naast elkaar
   in drie kolommen. Voorkomt overflow op 320–360px schermen. */
.dataviz__bar-row {
  display: grid;
  grid-template-columns: 1fr 2.5rem;
  grid-template-rows: auto auto;
  align-items: center;
  gap: var(--space-1) var(--space-2);
}
.dataviz__bar-label {
  grid-column: 1 / -1;
  font-size: var(--text-sm);
  color: var(--color-dataviz-text);
}
.dataviz__bar-track { background: var(--color-dataviz-muted); border-radius: var(--radius-pill); height: 8px; overflow: hidden; }
.dataviz__bar-fill { background: var(--color-dataviz-line); height: 100%; }
.dataviz__bar-value { font-size: var(--text-sm); color: var(--color-text); text-align: right; }

@media (min-width: 480px) {
  .dataviz__bar-row {
    grid-template-columns: 8rem 1fr 2.5rem;
    grid-template-rows: auto;
  }
  .dataviz__bar-label { grid-column: auto; }
}

/* ===================== APP-SHELL + SIDEBAR (mobile-first) ===================== */
/* Links een sidebar-paneel, vast op desktop (≥768px). Op mobiel staat 'ie buiten
   beeld (translateX): daar navigeer je via de bottom-nav + het kebab-menu — de oude
   off-canvas-drawer (hamburger/.app--menu-open/backdrop) is opgeruimd (audit
   2026-08-06 U3). De chat vult de viewport; content-pagina's groeien gewoon mee. */
.app { height: 100%; display: flex; }

.sidebar {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 50; /* boven de mobiele bottom-nav (40): de open drawer dekt ook de tabbalk */
  display: flex;
  flex-direction: column;
  width: var(--sidebar-width);
  max-width: 85vw;
  padding: var(--space-4);
  background: var(--color-sidebar-bg);
  border-right: 1px solid var(--color-border);
  transform: translateX(-100%);
  transition: transform 0.2s ease;
  overflow: hidden;
}

/* Mobiele header (WhatsApp-stijl): vaste balk bovenaan .app__main; de body eronder
   scrollt. Verborgen op desktop (de sidebar staat dan in de flow). */
.app__topbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* Safe-area (notch) bovenop de vaste 56px — deze legacy-balk miste 'm, waardoor
     Mijn gezinnen/Dashboard/admin onder de notch doken (audit 2026-08-06 B5). */
  height: calc(56px + env(safe-area-inset-top, 0px));
  /* Horizontale padding gelijk aan de content-container (--space-4) zodat de
     topbar-titel én de kebab uitlijnen met de kaarten eronder (niet 8px te ver links). */
  padding: env(safe-area-inset-top, 0px) var(--space-4) 0;
  /* De paginagrond, niet wit (2026-09-02): deze balk raakt de statusbalk van het toestel,
     en die staat op --color-bg (theme-color). Wit gaf daar een zichtbare naad. De V9-topbar
     op de vier landingen heeft nooit een eigen achtergrond gehad en sloot dus al aan. */
  background: var(--color-bg);
  /* Onderrand neemt de gezinskleur over wanneer een pagina die zet (chat); anders een
     haarlijn — dit is chrome dat zich van de pagina afzet, dus --color-line. */
  border-bottom: 1px solid var(--gezin-color, var(--color-line));
}

.app__topbar-title {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  /* Lange namen (de andere ouder) lopen door op een volgende regel; nooit afkappen (§3.4). */
  min-width: 0;
  flex: 1;
  overflow-wrap: break-word;
}

/* Menu-knop: gewone knop ín de topbar (niet meer zwevend over de inhoud). */
.app__menu-toggle {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: var(--color-text);
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.app__menu-toggle:hover { background: var(--color-hover); }

/* Dev-toggle: knop rechtsboven bínnen de main-container (absolute t.o.v. .app__main),
   klapt de dev-drawer in/uit (alleen development). Bij een open paneel schuift hij
   mee naar de nieuwe rechterrand van main, pal naast het paneel. */
.app__dev-toggle {
  position: absolute;
  top: var(--space-2);
  /* Links van de kebab (die rechts in de topbar hangt) zodat ze niet overlappen. */
  right: 96px;
  /* Boven alle pagina-chrome (max z-30, incl. agenda-modal), maar onder de
     dev-drawer-overlay (39/40) op mobiel — zo dekt de backdrop hem daar af. */
  z-index: 38;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 50%;
  box-shadow: var(--shadow-16);
  cursor: pointer;
  transition: background var(--dur-fast) var(--curve-decel),
              color var(--dur-fast) var(--curve-decel),
              border-color var(--dur-fast) var(--curve-decel);
}
.app__dev-toggle:hover { background: var(--color-hover); color: var(--color-text); }

/* Aan-staat: paneel open → de toggle staat 'ingedrukt' (accent-vlak, witte icoon),
   zodat het zichtbaar een echte aan/uit-toggle is. */
.app.dev-panel-open .app__dev-toggle {
  color: var(--color-on-btn);
  background: var(--color-btn);
  border-color: var(--color-text);
}
.app.dev-panel-open .app__dev-toggle:hover {
  color: var(--color-on-accent);
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.app__menu-icon { width: var(--icon-lg); height: var(--icon-lg); }

/* Generiek dropdown-menu: topbar-kebab (opent naar beneden) en sidebar-footer-account
   (opent naar boven, --up). Eén bron voor de paneel- en item-stijl (DRY). Eigen blok
   `.dropdown` — NIET `.menu` (dat is het admin-beheer-menu, met eigen margin-top). */
.dropdown { position: relative; flex-shrink: 0; }
.dropdown__panel {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 12rem;
  padding: var(--space-1);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-16);
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Opent naar boven, links uitgelijnd (sidebar-footer). */
.dropdown__panel--up { top: auto; right: auto; left: 0; bottom: calc(100% + 4px); }
.dropdown__panel[hidden] { display: none; }
.dropdown__panel .button_to { width: 100%; margin: 0; }
.dropdown__item {
  display: block;
  width: 100%;
  min-height: 44px;
  overflow-wrap: anywhere;
  padding: var(--space-3);
  /* Expliciet de app-tekstfont (knoppen erven die niet vanzelf). */
  font-family: var(--font-body);
  font-size: var(--text-17);
  font-weight: var(--weight-normal, 400);
  line-height: var(--leading);
  text-align: left;
  color: var(--color-text);
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: var(--radius-sheet-rij);
  cursor: pointer;
}
.dropdown__item:hover { background: var(--color-hover); }
.dropdown__item:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
/* Placeholder-item (nog niet functioneel): ziet er app-native uit, maar is niet
   klikbaar (cursor-signaal). */
.dropdown__item--placeholder { cursor: default; }

/* De kebab hangt altijd rechts in de topbar, ongeacht de titel-breedte. */
.app__topbar .dropdown { margin-left: auto; }

/* .app__main = kolom: topbar (vast) + body (scrollt). Position: relative zodat de
   dev-toggle er absoluut in verankert (rechtsboven). */
.app__main {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Scrollende inhoud onder de topbar. Voor gewone pagina's scrollt de body zelf;
   voor chat-/coach-pagina's wordt de body een flex-kolom zodat de chat via flex:1
   exact vult en intern scrollt — de body zelf scrollt dan NIET (composer blijft
   vast onderin). :has() is veilig — de app dwingt moderne browsers af. */
.app__body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}
.app__body:has(> .chat),
.app__body:has(> .mail-compose),
.app__body:has(> .agenda-layout) {
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.app__body:has(> .chat) > .chat {
  flex: 1;
  min-height: 0;
  height: auto;
}

/* Samen-banner (SamenBannerComponent): één regel bovenaan de scrollende body, boven de
   flash. `flex: none` omdat de body op chat-/agenda-schermen een flex-kolom is — zonder
   dat zou de banner meekrimpen met de chat. Amber = persoonlijk respijt (er loopt een
   klok), neutraal-op-surface = de gezinsbrede terugval (een toestand, geen alarm). */
.samen-banner {
  display: flex;
  flex: none;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  font-size: var(--text-sm);
}
/* Amber = er loopt een klok (respijt), met of zonder terugval eronder. */
.samen-banner--respijt,
.samen-banner--respijt_terugval {
  background: var(--color-amber-soft);
  color: var(--color-amber-deep);
  border-bottom: 1px solid var(--color-amber-border);
}
.samen-banner--terugval_betalend,
.samen-banner--proef_voorbij {
  background: var(--color-surface);
  color: var(--color-text);
  border-bottom: 1px solid var(--color-line);
}
.samen-banner__text { flex: 1; line-height: var(--leading); }
.samen-banner__cta {
  flex: none;
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  font-weight: 500;
  text-decoration: underline;
  cursor: pointer;
}
/* button_to wikkelt de knop in een form; die is dan het flex-item (geen eigen marge). */
.samen-banner__cta-form { flex: none; margin: 0; }

.sidebar__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.sidebar__brand {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--color-chat-text);
  text-decoration: none;
}

/* Compacte merk-tegel (favicon): alleen zichtbaar in de ingeklapte balk. */
.sidebar__brand-mark { display: none; }

.icon { width: var(--icon); height: var(--icon); flex-shrink: 0; }

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.sidebar__link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-3);
  font: inherit;
  color: var(--color-chat-text);
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: var(--radius-veld-plan);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast) var(--curve-decel),
              color var(--dur-fast) var(--curve-decel);
}
.sidebar__link .icon { transition: color var(--dur-fast) var(--curve-decel); }

.sidebar__link:hover { background: var(--color-hover); }

/* Fluent v9-selectie: subtiel koraal-vlak + afgeronde accent-rail links +
   accent-icoon — dezelfde nav-taal als de instellingen. */
.sidebar__link--active {
  background: var(--color-surface-own);
  font-weight: var(--weight-medium);
}
.sidebar__link--active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 20px;
  transform: translateY(-50%);
  border-radius: var(--radius-pill);
  background: var(--color-btn);
}
.sidebar__link--active .icon { color: var(--color-text); }

/* Gesprek-groep: kop + per-gezin sublinks (ingeklapt → flyout, zie collapsed-blok) */
.sidebar__group { display: flex; flex-direction: column; position: relative; }
.sidebar__flyout { display: flex; flex-direction: column; }
.sidebar__flyout-title { display: none; }
.sidebar__group-label { display: flex; align-items: center; gap: 0.625rem; padding: 0.625rem 0.75rem 0.25rem; color: var(--color-text-muted); font: inherit; }
.sidebar__sublink { padding-left: 2.25rem; }
.sidebar__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gezin-color, var(--color-accent)); flex: none; }
.sidebar__badge-slot { margin-left: auto; display: inline-flex; align-items: center; }
/* Groepsscheiding in de desktop-sidebar (dezelfde vier groepen als de lade). */
.sidebar__badge { min-width: 1.25rem; padding: 0 0.375rem; border-radius: var(--radius-groep); background: var(--gezin-color, var(--color-accent)); color: var(--color-on-accent); font-size: 0.6875rem; line-height: 1.25rem; text-align: center; }

/* Toasts — één vorm in de hele app (testronde 2026-09-30, C2): compact, donker, rechthoekig met
   ronde hoeken, onderin gecentreerd boven de tabbalk — dezelfde als de flash-melding (.flash).
   Verschijnen op elke pagina via de per-ouder Turbo-stream (#toasts); de container vangt zelf
   geen klikken. */
.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  width: max-content;
  max-width: min(22rem, 88vw);
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 11px 18px;
  background: var(--slate-dark);
  color: var(--color-on-accent);
  border-radius: var(--radius-groep);
  box-shadow: var(--shadow-16);
  cursor: pointer;
  animation: toast-in 0.22s cubic-bezier(0.25, 0.1, 0.25, 1);
}
.toast--leaving { opacity: 0; transform: translateX(8px); transition: opacity 0.2s ease, transform 0.2s ease; }
.toast__icon { color: var(--color-on-accent); flex: none; display: inline-flex; }
.toast__content { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.toast__title { font-size: var(--text-sm); color: var(--color-on-accent); font-weight: 500; }
.toast__body { font-size: var(--text-sm); color: var(--color-on-accent); opacity: .8; overflow-wrap: break-word; }
.toast__close { flex: none; display: inline-flex; padding: 2px; border: 0; background: transparent; color: var(--color-on-accent); opacity: .7; cursor: pointer; border-radius: var(--radius); }
.toast__close:hover { opacity: 1; }
@keyframes toast-in { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: translateX(0); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } .toast--leaving { transition: none; } }

.sidebar__footer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

.sidebar__signout {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-3);
  font: inherit;
  color: var(--color-text-muted);
  background: var(--color-chat-bubble-other);
  border: 1px solid var(--color-chat-border);
  border-radius: var(--radius);
  cursor: pointer;
}

.sidebar__signout:hover { color: var(--color-chat-text); }

.sidebar__collapse { display: flex; align-items: center; gap: var(--space-2); min-height: 44px; padding: 0 var(--space-3); background: none; border: 0; border-radius: var(--radius); cursor: pointer; color: var(--color-text-muted); }
.sidebar__collapse:hover { background: var(--color-hover); border-radius: var(--radius); }

/* Account-blok onderin de footer: placeholder-avatar (initialen) + oudernaam +
   gezinsnaam, klikt door naar de instellingen. */
.sidebar__account {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 48px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
  font: inherit;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
}
.sidebar__account:hover { background: var(--color-hover); }
.sidebar__avatar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--color-btn);
  color: var(--color-on-accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
}
.sidebar__account-text { display: flex; flex-direction: column; min-width: 0; line-height: var(--leading-kop); }
.sidebar__account-name {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  overflow-wrap: break-word;
}
.sidebar__account-gezin {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  overflow-wrap: break-word;
}

@media (min-width: 768px) {
  /* Sidebar in de echte flex-flow (geen fixed + margin-truc): flexbox reserveert
     de breedte fysiek, dus de chat kan er nooit achter verdwijnen en in-/uitklappen
     schuift de chat vanzelf mee. */
  .sidebar { position: relative; transform: none; flex-shrink: 0; }
  .app__topbar { display: none; } /* geen mobiele header op desktop */
  .app__menu-toggle { display: none; }
  .sidebar { transition: width 0.15s ease; }
  /* Ingeklapt (alleen desktop): icoon-only rail. Labels worden tooltips bij hover;
     de gespreksgroep krijgt een flyout-submenu naast de balk (M365-stijl). Overflow
     zichtbaar zodat tooltip/flyout naast de smalle balk mogen uitsteken. */
  /* Top-padding gelijk aan de uitgeklapte balk (var(--space-4)) zodat merk-tegel én
     nav-items op dezelfde hoogte staan; zijkanten smal zodat de iconen breed blijven. */
  .app--sidebar-collapsed .sidebar { width: 72px; padding: var(--space-4) var(--space-2) var(--space-2); overflow: visible; }
  .app--sidebar-collapsed .sidebar__nav { overflow: visible; }
  /* Woordmerk wijkt voor de compacte merk-tegel, op exact de woordmerk-hoogte
     (1.35rem) zodat de header even hoog blijft en de nav-items niet verspringen. */
  .app--sidebar-collapsed .sidebar__header { justify-content: center; }
  .app--sidebar-collapsed .sidebar__brand { display: flex; align-items: center; justify-content: center; }
  .app--sidebar-collapsed .sidebar__brand-wordmark { display: none; }
  .app--sidebar-collapsed .sidebar__brand-mark { display: block; width: 1.35rem; height: 1.35rem; }

  /* Iconen gecentreerd; geen accent-rail (de gevulde tegel markeert "actief"). */
  .app--sidebar-collapsed .sidebar__link,
  .app--sidebar-collapsed .sidebar__group-label,
  .app--sidebar-collapsed .sidebar__collapse,
  .app--sidebar-collapsed .sidebar__signout,
  .app--sidebar-collapsed .sidebar__account {
    justify-content: center;
    gap: 0;
    padding: 0;
    min-height: 44px;
    position: relative;
  }
  /* Ingeklapt: alleen de avatar tonen (initialen), naam/gezin wijken. */
  .app--sidebar-collapsed .sidebar__account-text { display: none; }
  .app--sidebar-collapsed .sidebar__link--active::before { display: none; }
  .app--sidebar-collapsed .sidebar__collapse .icon { transform: rotate(180deg); }

  /* Ongelezen-teller als hoekindicator i.p.v. in de flex-flow — anders duwt de
     auto-margin het icoon uit het midden (alleen top-level links, niet de flyout). */
  .app--sidebar-collapsed .sidebar__nav > .sidebar__link > .sidebar__badge-slot {
    position: absolute;
    top: 4px;
    right: 4px;
    margin: 0;
  }

  /* Tooltip = het (anders verborgen) label, zwevend rechts van het icoon. */
  .app--sidebar-collapsed .sidebar__nav > .sidebar__link > .sidebar__label,
  .app--sidebar-collapsed .sidebar__footer .sidebar__label {
    position: absolute;
    left: calc(100% + 0.625rem);
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
    padding: 0.3rem 0.55rem;
    white-space: nowrap;
    background: var(--color-chat-text);
    color: var(--color-on-accent);
    font-size: var(--text-sm);
    border-radius: var(--radius-veld-plan);
    box-shadow: var(--shadow-16);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--curve-decel);
    z-index: 50;
  }
  .app--sidebar-collapsed .sidebar__group-label > .sidebar__label { display: none; }
  .app--sidebar-collapsed .sidebar__nav > .sidebar__link:hover > .sidebar__label,
  .app--sidebar-collapsed .sidebar__nav > .sidebar__link:focus-visible > .sidebar__label,
  .app--sidebar-collapsed .sidebar__collapse:hover .sidebar__label,
  .app--sidebar-collapsed .sidebar__collapse:focus-visible .sidebar__label,
  .app--sidebar-collapsed .sidebar__signout:hover .sidebar__label,
  .app--sidebar-collapsed .sidebar__signout:focus-visible .sidebar__label {
    opacity: 1;
    visibility: visible;
  }

  /* Gespreksgroep: flyout-submenu naast de balk bij hover/focus. */
  .app--sidebar-collapsed .sidebar__flyout {
    position: absolute;
    left: calc(100% + 0.625rem);
    top: 0;
    min-width: 190px;
    padding: var(--space-1);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-16);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-fast) var(--curve-decel);
    z-index: 50;
  }
  .app--sidebar-collapsed .sidebar__group:hover .sidebar__flyout,
  .app--sidebar-collapsed .sidebar__group:focus-within .sidebar__flyout {
    opacity: 1;
    visibility: visible;
  }
  .app--sidebar-collapsed .sidebar__flyout-title {
    display: block;
    padding: 0.25rem 0.5rem 0.375rem;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
  }
  .app--sidebar-collapsed .sidebar__flyout .sidebar__sublink {
    justify-content: flex-start;
    gap: var(--space-2);
    padding-left: var(--space-3);
    min-height: 40px;
  }
}

/* ===================== LANDING-DASHBOARD (DP1) ===================== */
.dashboard-landing { --stack-gap: var(--space-3); }
.dashboard-landing__title { font-size: var(--text-lg); font-weight: var(--weight-medium); }
.dashboard-landing__welcome { color: var(--color-text-muted); }

/* Beheer-menu (coördinator/admin): kaarten met label + omschrijving. */
.menu {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: 0;
  list-style: none;
}

.menu__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-height: 44px;
  padding: var(--space-4);
  background: var(--color-card);
  border-radius: var(--radius);
  text-decoration: none;
  box-shadow: var(--shadow-vlak);
}

.menu__link:hover { border-color: var(--color-text); }
.menu__label { font-weight: var(--weight-medium); color: var(--color-text); }
.menu__description { font-size: var(--text-sm); color: var(--color-text-muted); }

/* Dossier-werklijst (ouder/casemanager): label + status + acties. */
.dossier-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: 0;
  list-style: none;
}

.dossier-list__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-vlak);
}

.dossier-list__info { display: flex; flex-direction: column; gap: var(--space-1); }
.dossier-list__label { font-weight: var(--weight-medium); }
.dossier-list__status { font-size: var(--text-sm); color: var(--color-text-muted); }

.dossier-list__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.dossier-list__action {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-accent);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-decoration: none;
}

.dossier-list__action:hover { border-color: var(--color-text); }

.dossier-list__action--primary {
  color: var(--color-bg);
  background: var(--color-btn);
  border-color: var(--color-btn);
  box-shadow: var(--shadow-knop);
}

.dossier-list__action--primary:hover { background: var(--color-accent-hover); }

@media (min-width: 640px) {
  .dossier-list__item {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
  .dossier-list__actions { flex-shrink: 0; }
}

/* ===================== UITNODIGINGEN-BEHEER (DP1) ===================== */
/* Mobile-first: elke uitnodiging is een kaart-rij met info boven de acties;
   vanaf 640px info links en acties rechts. Hergebruikt door portal + backoffice. */
.invitations {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding: 0;
  list-style: none;
}

.invitation {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-card);
  border-radius: var(--radius);
  box-shadow: var(--shadow-vlak);
}

.invitation__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.invitation__email {
  overflow-wrap: anywhere;
}

.invitation__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.invitation__status {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.invitation__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.invitation__action {
  min-height: 44px;
  padding: 0 var(--space-4);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--color-text);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  cursor: pointer;
}

.invitation__action:hover {
  border-color: var(--color-text);
}

/* Intrekken is destructief: tekst-accent zonder rood alarm (rustige huisstijl). */
.invitation__action--danger {
  color: var(--color-text-muted);
}

@media (min-width: 640px) {
  .invitation {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
  .invitation__actions { flex-shrink: 0; }
}

/* ===================== PROFESSIONAL — DOSSIERS-INDEX ===================== */
/* Kaarten-lijst: elke kaart = info-blok + acties. Mobile-first (gestapeld);
   vanaf 640px info links, acties rechts op dezelfde rij. */
.pro-dossiers__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  margin-bottom: var(--space-4);
}

.pro-dossier-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 0;
  list-style: none;
}

.pro-dossier-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-card);
  border-radius: var(--radius);
  transition: border-color 0.15s;
  box-shadow: var(--shadow-vlak);
}

.pro-dossier-card:hover { border-color: var(--color-text); }

.pro-dossier-card__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.pro-dossier-card__name {
  font-weight: var(--weight-medium);
  color: var(--color-text);
  text-decoration: none;
}

.pro-dossier-card__name:hover { color: var(--color-accent); }

.pro-dossier-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.pro-dossier-card__meta > * + *::before {
  content: "·";
  margin-right: var(--space-2);
}

.pro-dossier-card__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.pro-dossier-card__assign-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.pro-dossier-card__select {
  flex: 1;
  min-width: 0;
  min-height: 36px;
  padding: 0 34px 0 var(--space-2);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--color-text);
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--color-surface);
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.pro-dossier-card__submit {
  min-height: 36px;
  padding: 0 var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-bg);
  background: var(--color-btn);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  white-space: nowrap;
  box-shadow: var(--shadow-knop);
}

.pro-dossier-card__submit:hover { background: var(--color-accent-hover); }

.pro-dossier-card__enforcement {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.pro-dossier-card__enforced-label {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* Collapsible agenda-lock-sectie: summary als klikbaar label (inline-flex),
   het formulier erin als card-achtige sectie. */
.lock-agenda {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}

.lock-agenda__summary {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  cursor: pointer;
  list-style: none;
}

.lock-agenda__summary::-webkit-details-marker { display: none; }

.lock-agenda__summary::after {
  content: "▸";
  margin-left: auto;
  color: var(--color-text-muted);
  transition: transform 0.15s;
}

.lock-agenda[open] .lock-agenda__summary::after { transform: rotate(90deg); }

.lock-agenda__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.lock-agenda__hint {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.lock-agenda__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.lock-agenda__textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-size: var(--text-17);
  color: var(--color-text);
  background: var(--color-card);
  border: 1px solid transparent;
  border-radius: var(--radius-textarea);
  resize: vertical;
}

.lock-agenda__textarea:focus-visible {
  outline: none;
  border-color: var(--color-text);
  box-shadow: var(--veld-focus-ring);
}

.lock-agenda__submit {
  align-self: flex-start;
  min-height: 36px;
  padding: 0 var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-bg);
  background: var(--color-btn);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  box-shadow: var(--shadow-knop);
}

.lock-agenda__submit:hover { background: var(--color-accent-hover); }

@media (min-width: 640px) {
  .pro-dossier-card {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
  }

  .pro-dossier-card__info { flex: 1; min-width: 0; }

  .pro-dossier-card__actions {
    flex-shrink: 0;
    align-items: flex-end;
  }
}

/* ===================== PROFESSIONAL — METINGEN-DASHBOARD ===================== */
/* Dossier-context boven de panelen: naam van het dossier als oriëntatie. */
.dashboard-header {
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.dashboard-header__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--color-text);
}

/* Periode-filter: pill-tabs-rij boven de meetpanelen. */
.dashboard-filter {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.dashboard-filter__label {
  display: none;
}

.dashboard-filter__option {
  padding: var(--space-1) var(--space-3);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-pill);
  text-decoration: none;
  cursor: pointer;
}

.dashboard-filter__option:hover {
  background: var(--color-border);
  color: var(--color-text);
}

.dashboard-filter__option--active {
  background: var(--color-text);
  color: var(--color-surface);
  border-color: var(--color-text);
}

/* AGENDA (DP4-4b) — week-grid + event-kaartjes */

.agenda-filter__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gezin-color, var(--color-accent)); }

/* Event-wrapper voor absolute positionering; --lane/--lanes verdelen
   overlappende afspraken naast elkaar binnen de kolom (AgendaHelper). */
.agenda-week__event {
  position: absolute;
  --lane: 0;
  --lanes: 1;
  left: calc(2px + (100% - 4px) * var(--lane) / var(--lanes));
  width: calc((100% - 4px) / var(--lanes) - 1px);
  top: calc(var(--top) / 60 * var(--hour-height));
  height: calc(var(--height) / 60 * var(--hour-height));
  min-height: 2.5rem;
  z-index: 1;
}

/* Eigen afspraken: versleepbaar (tijd/dag) + resize-handle onderaan.
   -webkit-user-drag voorkomt de native link-drag (Safari) die de
   pointer-gesture zou kapen. */
.agenda-week__event--draggable {
  cursor: grab;
  -webkit-touch-callout: none;
  user-select: none;
}

.agenda-week__event--draggable .agenda-event,
.agenda-week__event--draggable .agenda-event * {
  -webkit-user-drag: none;
}

.agenda-week__event--dragging {
  z-index: 5;
  opacity: 0.9;
  box-shadow: var(--shadow-16);
  cursor: grabbing;
}

.agenda-week--dragging,
.agenda-week--dragging * {
  cursor: grabbing;
  user-select: none;
}

.agenda-week__resize {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 10px;
  cursor: ns-resize;
  touch-action: none;
  z-index: 2;
}

/* Inline-selectie op lege grid-ruimte; na loslaten wordt dit blok de
   klikbare "+"-placeholder (--armed) die de afspraak-modal opent. */
.agenda-week__select {
  position: absolute;
  left: 2px;
  right: 2px;
  top: calc(var(--top, 0) / 60 * var(--hour-height));
  height: calc(var(--height, 60) / 60 * var(--hour-height));
  padding: 0;
  font: inherit;
  background: color-mix(in srgb, var(--color-chat-accent) 14%, transparent);
  border: 1px dashed var(--color-chat-accent);
  border-radius: var(--radius);
  pointer-events: none;
}

.agenda-week__select--armed {
  pointer-events: auto;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: var(--weight-medium);
  color: var(--color-chat-accent);
  border-style: solid;
  z-index: 2;
}

/* Agendakleur-instelling (account): swatch-radio's uit het vaste palet */
.agenda-color {
  border: none;
  padding: 0;
  margin: 0;
}

.agenda-color__swatches {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

.agenda-color__swatch {
  cursor: pointer;
}

.agenda-color__swatch input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.agenda-color__chip {
  display: block;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--swatch, var(--color-surface));
  border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

.agenda-color__swatch input:checked + .agenda-color__chip {
  border-color: var(--color-text);
}

/* Al in de andere groep gekozen kleur: niet nogmaals te kiezen (gedimd). */
.agenda-color__swatch--disabled {
  cursor: not-allowed;
}
.agenda-color__swatch--disabled .agenda-color__chip {
  opacity: 0.28;
}

.agenda-color__swatch input:focus-visible + .agenda-color__chip {
  outline: 2px solid var(--color-chat-accent);
  outline-offset: 2px;
}

.agenda-color__hint {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Bijnaam-veld alleen bij weergave "Anders" — class wint van .form__row-display (dat
   het [hidden]-attribuut zou overschrijven). */
.child-name__custom.is-hidden { display: none; }

/* Maand: "+"-placeholder in een dag-cel */
/* Event-kaartje */
.agenda-event {
  display: flex;
  flex-direction: column;
  gap: 2px;
  height: 100%;
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  /* Zacht getint blok in de gezin-kleur (ontwerp), met een warme hairline i.p.v.
     het koude grijs. De dikkere linkerrand draagt de kleur het sterkst. */
  background: color-mix(in srgb, var(--event-color, var(--color-accent)) 8%, var(--color-surface));
  border: 1px solid var(--color-line);
  border-left: 3px solid var(--event-color, var(--color-text-muted));
  border-radius: var(--radius);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}

/* Fix 2: eigen-accent subtieler — alleen de linkerrand onderscheidt;
   geen extra achtergrond zodat eigen en andermans even leesbaar zijn. */
.agenda-event--own {
  border-left-color: var(--event-color, var(--color-chat-accent));
}

.agenda-event__time {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.agenda-event__title {
  font-weight: var(--weight-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Kind-dot vóór de titel (ook zichtbaar in compacte maand-cellen) */
.agenda-event--child .agenda-event__title::before {
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 4px;
  border-radius: 50%;
  background: var(--event-color, var(--color-text-muted));
  vertical-align: baseline;
}

/* Kind-naam: eigen regel in het week-grid */
.agenda-event__child {
  font-size: var(--text-xs);
  color: var(--event-color, var(--color-text-muted));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Herhaal-indicator vóór de titel */
.agenda-event__recurring {
  color: var(--color-text-muted);
  font-weight: normal;
}

/* Voorstel-afspraak: gestippelde rand tot de andere ouder bevestigt */
.agenda-event--proposed {
  border-style: dashed;
}

.agenda-event__badge {
  font-size: var(--text-xs);
  font-style: italic;
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* V9.2: "bevestigd" is een rustende stand — gedempt, niet groen. */
.agenda-event__badge--confirmed {
  font-style: normal;
  color: var(--color-text-muted);
}

/* Maker-naam: altijd zichtbaar, muted, compact */
.agenda-event__creator {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ===================== INFO-KAART + SHEET-ACTIES (generiek, DRY) =====================
   Herbruikbaar detail-blok: een witte kaart met icoon-rijen (label boven, waarde
   eronder) + een actie-rij met twee knoppen. Gebruikt in het afspraak-detail; klaar
   voor hergebruik in andere detail-sheets. Kleur-accent via --event-color. */

/* Afspraak-detail: kleurbalk vóór de titel in de sheet-kop + eigenaar-pill. */
.event-sheet .sheet__title { display: inline-flex; align-items: center; min-width: 0; }

/* Info-kaart: witte kaart, icoon-rijen met haarlijn ertussen. */
/* Feiten op één kaart met rijen — dezelfde vorm als het afspraakformulier (feedback
   2026-09-10). Ze lagen een dag lang plat op de paginagrond; met ruimte als enige scheiding
   dreven de rijen uit elkaar en werd elk scherm langer dan het hoefde. Een kaart houdt ze
   bij elkaar, en een haarlijn zegt waar de ene stopt en de volgende begint. Maten en vorm
   staan in de gedeelde .kaart-regel hieronder. */
/* ChatGPT-stijl (prototype ZORGPERIODE/AFSPRAAK DETAIL 2026-09-28): elke feitrij is een eigen
   grijs vlak in de groep (3px ertussen, 26px buitenhoek), het label 15 muted boven de waarde
   op 17. Een tikbare rij (de herinnering) is een gewone .setrow in dezelfde groep. */
.info-card__row {
  display: flex;
  align-items: center;
  gap: 13px;
  min-height: 60px;
  padding: 13px 20px;
}
.info-card > * { background: var(--color-card); border-radius: var(--radius-binnen); }
.info-card__row--top { align-items: flex-start; }
.info-card__icon {
  flex: none;
  display: flex;
  color: var(--color-faint);
}
.info-card__row--top .info-card__icon { margin-top: 2px; }
.info-card__icon svg { width: var(--icon); height: var(--icon); }
.info-card__text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Het label is een bijschrift, geen fijndruk: 14 in muted tegenover de waarde op 16 in de
   inkt (feedback 2026-09-10). Stond op 12/500 in faint en woog daarmee even zwaar als de
   waarde eronder, alleen kleiner en grijzer - twee stijlen zonder verschil in betekenis. */
.info-card__label { font-size: var(--text-15); font-weight: 400; color: var(--color-text-muted); }
.info-card__value { font-size: var(--text-17); font-weight: 400; color: var(--color-text); margin-top: 1px; }
.info-card__value--multiline { font-weight: 400; white-space: pre-wrap; line-height: var(--leading); }

/* Status-banner (wacht op akkoord / bevestigd) onder de kaart. */
/* Wacht op akkoord: een amber blok (bron agenda §8); bevestigd is een rustende stand —
   gedempt, niet groen (V9.2). In de .stack: geen eigen marge. */
.event-detail__status {
  display: flex; align-items: center; gap: 9px;
  margin: 0; padding: 12px 14px; border-radius: var(--radius-groep);
  font-size: var(--text-sm);
  /* Neutraal vlak, geen amber (feedback 2026-09-10). Amber leest als een waarschuwing terwijl
     er niets mis is: er staat alleen iets nog niet vast. En het was de laatste plek op dit
     scherm waar een vlak een accentkleur droeg, terwijl accent bij ons een tekstsignaal is.
     Het vlak zelf blijft — dit is een stand van de afspraak, geen feit ernaast, en dat mag je
     zien. Wachtend staat in de inkt, bevestigd is een rustende stand en dus gedempt. */
  background: var(--color-neutraal-zacht); color: var(--color-text);
}
.event-detail__status--confirmed { color: var(--color-text-muted); }

/* Gezin-keuze in de modal (2+ gezinnen): knoppen boven het eigenlijke formulier */
.agenda-modal__chooser { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.75rem; }
.agenda-modal__chooser-label { margin: 0 0 var(--space-1); font-size: var(--text-sm); color: var(--color-text-muted); }
.agenda-modal__choose { display: flex; align-items: center; gap: 0.5rem; width: 100%; min-height: 44px; padding: 0.5rem 0.75rem; background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); font: inherit; cursor: pointer; text-align: left; }
.agenda-modal__choose:hover { border-color: var(--color-text); background: var(--color-hover); }

/* De afspraak-sheets (nieuw/detail/bewerken) delen nu de app-brede .sheet-chrome
   (zie "BOTTOM-SHEET (generiek, DRY)"). Alleen de formulier-specifieke styling
   binnen de sheet staat hier. */

/* Formulier binnen de sheet (bron agenda §5, checklist 2026-09-09): volle breedte, en één
   verticaal ritme — elk blok 18px onder het vorige (de .stack-marge), géén flex-gap erbovenop:
   gap + marge gaf ~40px tussen Titel, Hele dag, Datum en de kaart. */
:is(.sheet, .agenda-form-pagina) .agenda-form {
  max-width: none;
  gap: 0;
  --stack-gap: 18px;
}

/* De afspraak-sheet staat op de paginagrond, net als de mail-opsteller (feedback
   2026-09-09: witte vakken met lift op een lichte sheet lazen grof en rommelig). Elke regel
   is een rij met een haarlijn eronder in plaats van een eigen vlak; wat je invult is de
   inhoud, niet een verzameling doosjes. De velden ín een open tekstrij (Plaats, Notities)
   houden hun vak: dat is een eigen sheet bovenop deze en daar IS het veld het onderwerp.
   Bij focus kleurt de haarlijn accent — dezelfde taal als .mail-compose__row. */
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input,
:is(.sheet, .agenda-form-pagina) .agenda-form__field--title input[type="text"] {
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
:is(.sheet, .agenda-form-pagina) .agenda-form select,
:is(.sheet, .agenda-form-pagina) .agenda-form__optpanel input[type="text"],
:is(.sheet, .agenda-form-pagina) .agenda-form__optpanel textarea {
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  box-shadow: none;
}
:is(.sheet, .agenda-form-pagina) .agenda-form__optpanel textarea { border-radius: var(--radius-textarea); }
:is(.sheet, .agenda-form-pagina) .agenda-form__optpanel input[type="text"]:focus-visible,
:is(.sheet, .agenda-form-pagina) .agenda-form__optpanel textarea:focus-visible { border-color: var(--color-text); box-shadow: var(--veld-focus-ring); }

/* Titelveld (lichte stijl, bron NIEUWE AFSPRAAK): een witte pil met rand, tekst 17 — de
   gedeelde veldvorm. */
:is(.sheet, .agenda-form-pagina) .agenda-form__field--title input[type="text"] {
  min-height: 52px;
  padding: 15px 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  font-size: var(--text-17);
  font-weight: 400;
}
/* Bij focus kleurt alléén de haarlijn. De gedeelde focus-ring is een schaduw rondom en
   tekende hier een vierkante doos om een veld dat juist géén doos is (feedback 2026-09-10). */
:is(.sheet, .agenda-form-pagina) .agenda-form__field--title input[type="text"]:focus,
:is(.sheet, .agenda-form-pagina) .agenda-form__field--title input[type="text"]:focus-visible {
  outline: none; box-shadow: var(--veld-focus-ring); border-color: var(--color-text);
}
:is(.sheet, .agenda-form-pagina) .agenda-form__field--title input[type="text"]::placeholder { color: var(--color-faint); font-weight: 400; }
/* Inhoud-regel (Overige info, 2026-09-13): dezelfde kale regel als de titel, in gewoon
   type — het wachtwoord is de kern van zo'n item en staat meteen in beeld, geen paneel. */
:is(.sheet, .agenda-form-pagina) .agenda-form__field--inhoud textarea {
  display: block; width: 100%; min-height: 0; padding: 15px 20px;
  border: 0; border: 1px solid transparent; border-radius: var(--radius-textarea); background: var(--color-card); box-shadow: none;
  font: inherit; font-size: var(--text-17); line-height: var(--leading); color: var(--color-text); resize: none;
  /* Het veld groeit mee (autogrow-controller), dus het krijgt nooit een eigen schuifbalk:
     bij een lange tekst scrollt de sheet, niet het vakje (2026-09-16). */
  overflow-y: hidden;
}
:is(.sheet, .agenda-form-pagina) .agenda-form__field--inhoud textarea:focus,
:is(.sheet, .agenda-form-pagina) .agenda-form__field--inhoud textarea:focus-visible { outline: none; box-shadow: none; border-color: var(--color-text); }
:is(.sheet, .agenda-form-pagina) .agenda-form__field--inhoud textarea::placeholder { color: var(--color-faint); }
:is(.sheet, .agenda-form-pagina) .agenda-form__when { padding: 11px 0; }
/* Datum en tijd links uitgelijnd (feedback 2026-09-10) — behalve in de van/tot-kolommen,
   waar datum en tijd gecentreerd onder elkaar staan (2026-09-11, zie .agenda-form__when-kolom). */
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input,
:is(.sheet, .agenda-form-pagina) button.timewheel__display,
:is(.sheet, .agenda-form-pagina) button.datecal__display { text-align: left; }
:is(.sheet, .agenda-form-pagina) .agenda-form__when-kolom .agenda-form__when-input { text-align: center; }
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input { padding: 2px 6px; font-size: var(--text-base); box-shadow: none; }
/* Geen focus-ring (de rij is geen doos, zelfde reden als de titelregel hierboven) — maar
   wél een merkteken: dezelfde grond als bij een tik. Zonder dat tekende focus hier niets
   en liep je met het toetsenbord blind door de datum/tijd-rijen (gevonden 2026-09-12,
   toen de veld-focus-guard weer echt keek). Grond i.p.v. rand: de kolom verspringt niet.
   Alléén bij :focus-visible: na een tik houdt de knop de focus als de kiezer-sheet weer
   dicht is, en dan bleef de grond als grijze balk staan (toestel, 2026-09-13). */
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input:focus { outline: none; box-shadow: none; }
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input:focus-visible { outline: none; box-shadow: none; background: var(--color-hover); border-radius: var(--radius-xs); }
:is(.sheet, .agenda-form-pagina) .agenda-form__when-input:active { border-radius: var(--radius-xs); }
/* De keuzerijen in een sheet of op een formulierpagina: een groep rijen zoals overal
   (conventions §3.5, 3px ertussen). De groep zelf draagt geen vlak — dat verborg de 3px — en
   knipt niet af (een rij opent zijn paneel), dus de buitenhoeken zitten op de eerste en
   laatste rij. */
:is(.sheet, .agenda-form-pagina) .agenda-form__optcard { box-shadow: none; overflow: visible; }
:is(.sheet, .agenda-form-pagina) .agenda-form__optcard > :first-child { border-top-left-radius: var(--radius-groep); border-top-right-radius: var(--radius-groep); }
:is(.sheet, .agenda-form-pagina) .agenda-form__optcard > :last-child { border-bottom-left-radius: var(--radius-groep); border-bottom-right-radius: var(--radius-groep); }
/* Elke rij in een sheet ligt op de kantlijn van de pagina: de zijpadding zat op de rij zelf,
   maar de sheet draagt die al. Gold alleen binnen .agenda-form__optcard, waardoor de rijen
   van het zorgwissel-formulier 16px inspringden t.o.v. de tekst erboven (feedback
   2026-09-11). */
:is(.sheet, .agenda-form-pagina) .agenda-form__velden .agenda-form__optsummary { padding: 13px 0; }
:is(.sheet, .agenda-form-pagina) .agenda-form__optcard .agenda-form__optsummary { padding: 14px 16px; }
/* Kind-select in de afspraak-sheet: eigen chevron mét rechter-padding (i.p.v. de
   native pijl tegen de rand) — DRY via --select-chevron. */
:is(.sheet, .agenda-form-pagina) .agenda-form select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 12px;
}

/* Compacte keuzerijen (ontwerp "1a"): herhaling + herinnering dichtgeklapt tot één
   rij met hun waarde; een tik klapt open met chips. Eén rij tegelijk (accordeon). */
/* ---- Het afspraakformulier is één kaart met rijen (feedback 2026-09-10) ----------------
   Elk onderdeel stond als los blok in de .stack-ritmiek: 20px stapelmarge bovenop de eigen
   padding van elke rij, en het scherm werd daarmee bijna twee keer zo lang als nodig. Nu
   dragen de rijen alleen hun eigen hoogte en scheidt een haarlijn ze — de vorm die elke
   agenda-app gebruikt. De kaart draagt de zijmarge, dus de rijen erin hebben er geen.
   Een formulier is bij uitstek "iets te doen", dus hier hoort een vlak wél (conventions §3).
   De zwevende actiebalk staat er bewust búiten: die hoort onder de kaart te zweven. */
/* Eén vorm voor elke kaart met rijen: het afspraakformulier, de feitenlijst van een
   detailscherm, het zorgwissel-formulier. 6px boven en onder zodat de eerste rij niet tegen
   de rand plakt; de rijen brengen hun eigen hoogte mee. */
/* Plat op de paginagrond, net als het afspraakformulier en de mail (feedback 2026-09-11).
   Een detailscherm gaat al helemaal over dat ene onderwerp en een formulier is het scherm
   zelf; een vlak eromheen bakent dan niets af. Wat wél een vlak houdt is een blok dat zich
   van de rest van het scherm moet onderscheiden: een statusmelding, een beslisblok.
   De rijen houden hun hoogte en de haarlijn ertussen — dat is de structuur. */
.info-card {
  display: flex;
  flex-direction: column;
}
/* Lichte stijl (2026-09-26, opdracht stap 2): de feitenkaart is weer een grijs vlak met
   rijen en haarlijnen — het zorgwissel-formulier blijft plat. */
.info-card { gap: 3px; border-radius: var(--radius-groep); overflow: hidden; }
/* Het afspraakformulier ligt plat op de paginagrond, zoals de mail-opsteller (2026-09-11):
   met sluiten en opslaan in de kop is het hele scherm het formulier, en dan markeert een vlak
   eromheen niets meer. Alleen de rijen en hun haarlijnen blijven over; de sheet-marge draagt
   de zijkant. */
.agenda-form__velden { display: flex; flex-direction: column; }
/* Eén scheiding: een haarlijn bóven elke volgende rij. De rijen dragen die niet zelf — anders
   staat er onder de laatste een lijn naar niets, en tussen twee blokken twee lijnen op elkaar.
   De titel houdt zijn eigen onderstreping (die kleurt bij focus), dus de rij erna krijgt geen. */
.agenda-form__velden > * + * { border-top: 1px solid var(--color-hair); }
.agenda-form__velden > .agenda-form__field--title { padding-bottom: 16px; }
.agenda-form__velden > .agenda-form__field--title + * { border-top: 0; }
/* Een grijs vlak met keuzerijen (lichte stijl) is zelf de scheiding: geen haarlijn erboven of
   eronder, wel 12px lucht naar wat ervoor en erna staat (feedback Jerry 2026-09-26: de vlakken
   plakten aan elkaar en aan het voorleg-vinkje, met een grijze rand eromheen). */
.agenda-form__velden > .agenda-form__optcard { border-top: 0; margin-top: 12px; }
/* Wat erna komt (het voorleg-vinkje) heeft zelf 13px padding: alleen de haarlijn moet weg. */
.agenda-form__velden > .agenda-form__optcard + * { border-top: 0; }
/* Het voorleg-vinkje is binnen de kaart een rij als alle andere. */
.agenda-form__velden > .agenda-form__field--inline { padding: 13px 0; }

/* ChatGPT-stijl (prototype 2026-09-28): een groep rijen — elke rij een eigen grijs vlak, 3px
   ertussen, 26px buitenhoek (22 in een sheet, waar de rijen op de paginagrond liggen). De
   haarlijn tussen de rijen (.agenda-form__opthr) is daarmee overbodig. */
.agenda-form__optcard {
  display: flex;
  flex-direction: column;
  gap: 3px;
  border-radius: var(--radius-groep);
  overflow: hidden;
}
.agenda-form__optcard > :not(.agenda-form__opthr, .veld-fout) { background: var(--color-card); border-radius: var(--radius-binnen); }
.sheet .agenda-form__optcard > :not(.agenda-form__opthr, .veld-fout) { background: var(--color-card); }

.agenda-form__opthr { display: none; }

.agenda-form__optsummary {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  background: none;
  border: none;
  font: inherit;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
}

/* Rij-icoon in muted (bron §5: geen accent op een icoon), op de ladder-maat boven de
   19px van de bron; zo staat het op één lijn met de tekst. */
/* Het icoon staat altijd in de gewone kleur, ook naast een gedempte rijnaam (2026-09-12). */
.agenda-form__opticon { display: inline-flex; flex: none; color: var(--color-text); }
.agenda-form__opticon svg { width: var(--icon); height: var(--icon); }
.agenda-form__optname { font-size: var(--text-base); font-weight: 400; flex: none; }
/* Een rij met een kiezer erin (de verjaardag in het contactformulier, 2026-09-12): de
   samenvatting is dan geen knop maar een rij met de kiezer-knop als tekst — dezelfde maat
   en kleur als .agenda-form__optvalue, leeg gedempt (is-empty), zonder eigen vak. */
/* Een rij die ergens heen gaat (e-mail op het profiel → bevestigingsflow): een link in
   dezelfde vorm, met een chevron rechts. */
a.agenda-form__optsummary { text-decoration: none; }
a.agenda-form__optsummary .setrow__chevron { margin-left: auto; }
.agenda-form-pagina { margin-top: var(--space-2); }
.agenda-form__optsummary--kiezer { cursor: default; }
.agenda-form__optsummary--kiezer .datecal__display {
  flex: 1 1 auto; min-width: 0; min-height: 0; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; text-align: left;
  font-size: var(--text-base); font-weight: 400; color: var(--color-text);
}
/* Inline tekstrij (agenda/_veld_row, 2026-09-14): het veld zelf staat óp de rij, kaal — geen
   paneel voor één woord. De placeholder is de rijnaam, in de gedempte kleur zoals elke lege
   rij. Bij focus geen ring: de rij is geen doos (zelfde motivering als de titelregel). Een
   veldfout kleurt het icoon en zet zijn regel ónder de rij, ingesprongen tot de tekst. */
.agenda-form__optsummary--veld { cursor: text; }
.agenda-form__optsummary--veld .agenda-form__veldinput {
  flex: 1 1 auto; min-width: 0; min-height: 0; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; font: inherit; font-size: var(--text-17); font-weight: 400; color: var(--color-text);
}
.agenda-form__optsummary--veld .agenda-form__veldinput::placeholder { color: var(--color-text-muted); }
.agenda-form__optsummary--veld .agenda-form__veldinput:focus,
.agenda-form__optsummary--veld .agenda-form__veldinput:focus-visible { outline: none; box-shadow: none; }
.agenda-form__optsummary.is-fout .agenda-form__opticon,
.agenda-form__optsummary.is-fout .agenda-form__optvalue { color: var(--color-error); }
.agenda-form__optsummary--veld + .veld-fout { margin: -6px 16px 12px calc(16px + var(--icon) + 12px); }
/* Eén tekst per rij (2026-09-12, naar de agenda van het toestel): leeg staat de rijnaam in
   de gedempte kleur ("Plaats", "Niet herhalen"), gevuld staat de waarde ervoor in de plaats,
   in de gewone kleur. Geen "Toevoegen" in accent en geen chevron meer — de rij is de knop.
   Daarvóór: naam links, waarde rechts, chevron. */
.agenda-form__optvalue {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--text-base); font-weight: 400; color: var(--color-text);
  overflow-wrap: break-word;
}
.agenda-form__optvalue--empty { color: var(--color-text-muted); }
/* Een rij die altijd een waarde heeft houdt zijn naam ervoor: "Heen · Jij haalt op".
   Het scheidingsteken staat er als echt teken, niet als CSS-escape. Als escape (\00B7) stond hier
   een tijdlang een NUL-byte gevolgd door "B7" -- de backslash sneuvelde bij het schrijven,
   en de gebruiker las "Heen ?B7 Jij haalt op" (2026-09-12). Een NUL maakt het bestand
   bovendien binair voor git: geen regel-einde-normalisatie meer, en elke bewerking geeft
   dan een diff van 9.000 regels. */
.agenda-form__optname + .agenda-form__optvalue::before { content: "· "; color: var(--color-text-muted); }
/* Gelabelde rij (vast: true, 2026-09-13): leeg staat alleen de naam, gedempt; gevuld
   "Naam · waarde". De controller zet --empty, en daar volgt de naam op. */
.agenda-form__optsummary:has(.agenda-form__optvalue--empty) .agenda-form__optname { display: none; }
.agenda-form__optname + .agenda-form__optvalue--empty::before { content: none; }

/* Invoerveld binnen een open tekstrij (plaats/notitie). */
.agenda-form__fieldinput {
  width: 100%;
  padding: 15px 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  box-shadow: none;
  font: inherit;
  font-size: var(--text-17);
  color: var(--color-text);
  outline: none;
}
.agenda-form__fieldinput::placeholder { color: var(--color-faint); }
.agenda-form__fieldinput:focus-visible { outline: none; border-color: var(--color-text); box-shadow: var(--veld-focus-ring); }
textarea.agenda-form__fieldinput { min-height: 76px; resize: vertical; border-radius: var(--radius-textarea); }

/* Paneel van een keuzerij/tekstrij (§5): een bottom-sheet-laag bínnen de afspraak-sheet —
   geen tweede <dialog> (die zet de hele pagina inert), wel dezelfde vorm: --radius-sheet
   bovenhoeken, lift, en een scrim over de rest (::before op de open rij, zelfde tint als
   de sheet-backdrop). De kop (naam · Klaar) sluit 'm. */
.agenda-form__optrow.is-open::before { content: ""; position: fixed; inset: 0; z-index: 2; background: var(--color-scrim); }
/* Zo hoog als zijn inhoud, tot aan de bovenrand — en pas dán scrollt hij (feedback
   2026-09-11: op 80vh scrolde de overdracht-sheet terwijl er boven nog ruimte over was). */
.agenda-form__optpanel {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 3;
  max-height: 100vh; max-height: calc(100dvh - env(safe-area-inset-top, 0px)); overflow-y: auto;
  padding: 0 22px calc(26px + env(safe-area-inset-bottom, 0px));
  background: var(--color-surface); /* een sheet-laag is wit (lichte stijl) */
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  box-shadow: var(--shadow-16);
  scrollbar-width: none;
}
.agenda-form__optpanel::-webkit-scrollbar { display: none; }
.agenda-form__optpanel[hidden] { display: none; }
/* Op een pagina (geen <dialog>, dus geen top layer) moet het paneel én zijn scrim boven de
   tabbalk (z-index 40) uitkomen — anders viel de onderste keuze erachter (2026-09-15). */
.agenda-form-pagina .agenda-form__optrow.is-open::before,
.plan .agenda-form__optrow.is-open::before,
.agenda-form__optrow--veld.is-open::before { z-index: 41; }
.agenda-form-pagina .agenda-form__optpanel,
.plan .agenda-form__optpanel,
.agenda-form__optrow--veld > .agenda-form__optpanel { z-index: 42; }
/* De kop loopt tot de paneelranden (de 22px zijpadding zit al in .sheet__head). */
.agenda-form__optpanel > .sheet__head { margin: 0 -22px 10px; }
/* Klaar: één pilknop onderaan die het paneel sluit (bron, scherm "Notities"). */
.agenda-form__optklaar { margin-top: 20px; }
/* De veldblokken van een overdrachtsmoment: de stack deelt de ruimte ertussen uit
   (--space-5), hetzelfde als de marge vóór Klaar — één ritme (feedback 2026-09-11: labels
   stonden nu eens tegen een veld, dan weer een centimeter ervan). */
.agenda-form__optvelden { margin-top: 8px; }

/* Chips — alleen nog de eenheid-/duur-chips in de Aangepast-secties (§5: de keuzes zelf
   zijn een radiolijst in .sheetmenu). Eén maat, dus geen --sm/--units-modifiers meer. */
.agenda-form__chips { display: flex; flex-wrap: wrap; gap: 7px; }
/* Suggestie-chips onder een tekstveld (Plaats): tussen het veld en de Klaar-knop. */
.agenda-form__fieldchips { margin-top: 12px; }
.agenda-form__chip {
  padding: 8px 11px;
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text-muted);
  border: 1px solid var(--color-line);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--curve-decel);
}
.agenda-form__chip:active { transform: scale(0.95); }
.agenda-form__chip.is-selected { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }

/* Stepper (− N +) + eenheid-chips op één rij */
.agenda-form__stepper-row { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-top: 13px; }
.agenda-form__stepper-label { font-size: var(--text-sm); font-weight: 500; color: var(--color-text-muted); }
.agenda-form__stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-groep);
  overflow: hidden;
}
.agenda-form__step {
  padding: 8px 13px;
  background: none;
  border: none;
  font: inherit;
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-accent);
  cursor: pointer;
}
.agenda-form__step-n {
  min-width: 26px;
  padding: 8px 6px;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: 500;
  border-left: 1px solid var(--color-line);
  border-right: 1px solid var(--color-line);
}

/* Duur (achter Aangepast): altijd / N keer / tot */
.agenda-form__duur { margin-top: 14px; padding-top: 13px; border-top: 1px dashed var(--color-line); }
.agenda-form__duur-label {
  margin: 0 0 8px;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.agenda-form__duur-detail { display: flex; align-items: center; gap: 8px; margin-top: 10px; font-size: var(--text-sm); }
.agenda-form__duur-detail[hidden] { display: none; }
.agenda-form__duur-detail .agenda-form__number { margin: 0; }
:is(.sheet, .agenda-form-pagina) .agenda-form__duur-detail input[type="date"] {
  min-height: 40px;
  padding: 9px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  font: inherit;
  font-size: var(--text-17);
}

/* -- formulier-onderdelen (Samsung-stijl) -- */

/* Begindag → einddag (+ tijden) */
/* Van → tot als twee kolommen met de pijl ertussen (2026-09-11, zoals de agenda van het
   toestel): in elke kolom de datum en daaronder de tijd; bij een hele-dag-afspraak vallen de
   tijden weg en blijft één regel met de twee dagen over. De pijl staat verticaal in het
   midden van wat er staat. Daarvóór: twee losse rijen (datums, tijden), elk met een pijl. */
.agenda-form__when {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.agenda-form__when-kolom {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: stretch;
}
/* Hele dag uit: de tijd schuift open en alles onder het tijdstip schuift mee naar beneden
   (feedback 2026-09-11: de tijd popte ineens midden in het veld). Grid-rijen van 0fr naar
   1fr animeren de hoogte zonder de inhoud te hoeven meten; de marge boven de tijd doet mee,
   anders bleef er dicht een gaatje over. Dicht is ook onzichtbaar en niet tabbaar
   (visibility), maar pas ná de beweging. */
.agenda-form__when-tijd {
  display: grid; grid-template-rows: 1fr; margin-top: 6px;
  transition: grid-template-rows var(--dur-normal) var(--curve-decel), margin-top var(--dur-normal) var(--curve-decel),
              opacity var(--dur-normal) var(--curve-decel), visibility 0s;
}
.agenda-form__when-tijd > * { min-height: 0; overflow: hidden; }
.agenda-form__when-tijd.is-dicht {
  grid-template-rows: 0fr; margin-top: 0; opacity: 0; visibility: hidden;
  transition-delay: 0s, 0s, 0s, var(--dur-normal);
}
@media (prefers-reduced-motion: reduce) {
  .agenda-form__when-tijd { transition: none; }
}

/* De datum-/tijdknop draagt de gedeelde veldvorm (zie DÉ veldstijl); hier alleen de
   flex-verdeling binnen een van/tot-rij. */
.agenda-form__when-input { flex: 1 1 0; min-width: 0; }
.agenda-form__when-kolom .agenda-form__when-input { flex: none; width: 100%; }

.agenda-form__when-arrow {
  flex: none;
  font-size: var(--text-sm);
  color: var(--color-faint);
}

/* Eén regel onder de grote tijd (prototype TIJDKIEZER 2026-09-28). */
.picker__hint { margin: 0 0 6px; font-size: var(--text-15); line-height: var(--leading); color: var(--color-text-muted); text-align: center; }
/* ── Tijd- & datumkiezer (pickers-handoff, 2026-07-15) ────────────────
   Twee herbruikbare bottom sheets: gedeelde chrome (.picker__*) + eigen body.
   Maten/kleuren 1-op-1 uit het ontwerp; kleuren via de app-tokens (zelfde palet). */
.timewheel, .datecal { flex: 1 1 0; min-width: 0; display: flex; }
button.timewheel__display, button.datecal__display { font-weight: 500; cursor: pointer; }
button.timewheel__display { text-align: center; }
/* Datum leest app-breed als een gewoon veld: links uitgelijnd (gebruikersfeedback
   2026-08-06); leeg = placeholder-behandeling via .is-empty hieronder. */
button.datecal__display { text-align: left; }
/* Eén placeholder-taal (2026-07-27): een lege kiezer toont "Kies datum"/"--:--" gedempt en
   normaal gewicht — zelfde behandeling als ::placeholder op de tekstvelden ernaast, in
   béíde varianten (agenda-gecentreerd én --plain). Gekozen waarde = donker. De controllers
   halen .is-empty weg zodra er bevestigd is. */
button.datecal__display.is-empty,
button.timewheel__display.is-empty { color: var(--color-text-muted); font-weight: 400; }
/* Plat formulierveld-variant (Documenten "Geldig tot", design-feedback 2026-07-19): links-
   uitgelijnd en normaal gewicht, zoals de andere velden in dezelfde sheet — i.p.v. de grote
   gecentreerde/vette weergave die bij een agenda-datumkiezer hoort. Dubbele class-selector
   voor hogere specificiteit dan de basisregel hierboven (die wint anders ondanks bronvolgorde). */
button.datecal__display.datecal__display--plain,
button.timewheel__display.timewheel__display--plain { text-align: left; font-weight: 400; }

/* Gedeelde sheet-chrome */
/* Kennisbank (shared/_knowledge, DRY app-breed): vraagteken naast een kop, opent een sheet
   met verdieping. Klein en stil — het is een aanbod, geen aandachttrekker. */
/* Handout planbuilder 2026-09-28: 28×28 met een vraagteken van 18 in muted, aanraakstand
   de ingedrukte kaartkleur. */
.knowledge-btn {
  appearance: none; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border: 0; background: none;
  color: var(--color-text-muted); cursor: pointer; border-radius: 50%;
}
.knowledge-btn:active { background: var(--color-card-pressed); }
.knowledge-btn svg { width: var(--icon-sm); height: var(--icon-sm); }
/* Een lede met het vraagteken ernaast (Derden, 2026-09-14): de zin links, de knop rechts —
   de uitleg zelf staat in de kennisbank-sheet, niet als alinea's op de pagina. */
.lede:has(> .knowledge-btn) { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
/* Info-sheet (handout 2026-09-28): tekst 17 op leesregelhoogte, tussenkopjes 15/500 muted,
   onderaan de knop Begrepen. */
.knowledge-body { --stack-gap: var(--space-3); font-size: var(--text-17); line-height: var(--leading-lees); color: var(--color-text); }
.knowledge-body > p { margin: 0; }
.knowledge-body h4 { margin: 6px 0 -6px; font-size: var(--text-15); font-weight: 500; color: var(--color-text-muted); }
.knowledge-foot { padding-top: 14px; }
/* Kop in de sheet erft het display-font al van de globale h1..h6-regel; alleen maat + gewicht. */
.knowledge-heading { font-size: var(--text-base); font-weight: 500; margin: var(--space-1) 0 0; }
.knowledge-source { font-size: var(--text-xs); color: var(--color-faint); }

.picker { background: var(--color-bg); }
/* De picker schakelt z'n onderdelen met het [hidden]-attribuut (JS: static/typed, dag- vs
   jaar-/maand-modus, de rechterhelft van de maandregel). Class-selectors met display
   (inline-flex/grid/contents) verslaan de UA-regel voor [hidden], waardoor verborgen delen
   tóch ruimte innamen — de lege jaar-grid (264px hoog) duwde zo de snelkeuzes + Opslaan uit
   de sheet. Eén regel op picker-scope i.p.v. per element (zelfde aanpak als .school-form). */
.picker [hidden] { display: none !important; }
/* ---- Sleepgreep: een streepje voor de hele app ----------------------------------------
   Elke laag die je naar beneden kunt duwen draagt dezelfde greep: de bottom sheets, de tijd-
   en datumkiezer, het coach-paneel en de weekstrook in de agenda. Die weekstrook stond op
   --color-faint en was daarmee een stuk donkerder en grover dan de rest (feedback
   2026-09-10) - de zachte lijnkleur van de sheets wint, want een greep is een aanwijzing,
   geen scheiding. Maten en kleur staan hier een keer; de plekken zelf zetten alleen nog hun
   eigen marge. */
.sheet__grip,
.coach-sheet__grabber,
.agenda-mobile__grip {
  width: var(--greep); height: 4px; border-radius: var(--radius-xs); background: var(--color-line);
}
/* De kop van een kiezer is dezelfde als van elke andere sheet (.sheet__grip/.sheet__head/
   .sheet__title/.sheet__close, 2026-09-12): titel en kruis stonden een stuk dieper en de
   titel in de display-letter, terwijl een kiezer gewoon een sheet is. */

/* Grote waarde: tik om te typen */
/* De gekozen waarde staat vrij op de sheet — géén vlak eromheen (feedback 2026-09-12).
   Het witte vlak van 2026-09-12 loste de ene rommel op en maakte een andere: het lag met
   z-index óver het wiel, dus de rij eronder werd door een kaarsrechte rand doormidden
   gesneden, en de fade lag eronder en deed aan de bovenkant niets. Drie vlakken over
   elkaar (sheet · wit vlak · gevulde band) waren er twee te veel. Nu draagt de sheet één
   kleur, staat de waarde er als tekst op, en lossen de wielcijfers op via een mask
   (zie .timewheel__col). Geldt voor béíde kiezers: de kalender had het vlak alleen maar
   geërfd, hij had er nooit een overlap-probleem mee. */
.picker__value { flex: none; text-align: center; padding: 2px 0 10px; }
.picker__typed { display: inline-flex; align-items: center; gap: 2px; }
.picker__typedcolon { font-family: var(--font-display); font-size: var(--text-32); font-weight: 500; color: var(--color-text); padding: 0 2px; }
.picker__typedinput {
  width: 64px; text-align: center; font-family: var(--font-display); font-size: var(--text-32); font-weight: 500;
  color: var(--color-text); background: var(--color-panel); border: 2px solid var(--color-text);
  border-radius: var(--radius-pill); padding: 2px 0; outline: none;
}
.picker__typedinput--date { width: 190px; font-size: var(--text-20); padding: 6px 0; }
.picker__static { display: inline-flex; align-items: center; border: 0; background: none; padding: 0; cursor: text; }
.picker__static:active { opacity: .6; }
/* Zonder vlak eromheen moet de waarde zichzelf dragen: een maat groter. De datum blijft een
   stap kleiner dan de tijd — "12 september 2026" is vier keer zo lang als "14:30" en zou op
   een smal toestel omvallen. */
.picker__bigtime { font-family: var(--font-display); font-size: var(--text-32); font-weight: 500; letter-spacing: -0.01em; color: var(--color-text); font-variant-numeric: tabular-nums; }
.picker__bigdate { font-family: var(--font-display); font-size: var(--text-24); font-weight: 500; color: var(--color-text); }

/* Snelkeuzes */
.picker__presets { padding: 4px 20px; flex: none; }
/* Een label boven een veld staat in de inkt op leesmaat — het hoort bij wat je invult,
   het is geen bijschrift (rust-plan 2026-09-09; stond op 11px in muted grijs). */
.vlabel,
.plan-label,
.plan-inf__sublabel {
  display: block;
  margin-bottom: 5px;
  font-size: var(--text-base);
  font-weight: 400;
  color: var(--color-text);
  letter-spacing: normal;
}

.picker__presets-label { display: block; font-size: var(--text-xs); font-weight: 500; color: var(--color-faint); margin-bottom: 8px; }
.picker__chips { display: flex; gap: 8px; flex-wrap: wrap; }
.picker__chip {
  padding: 9px 14px; border-radius: var(--radius-pill); font: inherit; font-size: var(--text-sm); font-weight: 500; cursor: pointer;
  background: var(--color-surface); color: var(--color-text-muted); border: 1px solid var(--color-line);
}
.picker__chip:active { transform: scale(.96); }
.picker__chip.is-active { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }

/* Primaire bevestiging */
.picker__confirm { padding: 16px 20px 30px; flex: none; }
.picker__cta {
  display: block; width: 100%; background: var(--color-btn); color: var(--color-on-btn); text-align: center;
  border: 0; border-radius: var(--radius-pill); padding: 16px; font: inherit; font-size: var(--text-base); font-weight: 500; cursor: pointer;
  box-shadow: var(--shadow-knop);
}
.picker__cta:active { transform: scale(.99); background: var(--color-accent-hover); }

/* Tijd-wiel: gecentreerde rij = keuze (46px per rij) */
.timewheel__wheels { position: relative; display: flex; justify-content: center; gap: 6px; padding: 0 0 8px; flex: none; }
/* Het venster is twee haarlijnen, geen gevuld vlak (feedback 2026-09-12): een gevulde band
   is een derde tint in een sheet die het met één toe kan, en dezelfde lijn markeert overal
   in de app een scheiding. */
.timewheel__band {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 214px; height: 46px; pointer-events: none;
  border-top: 1px solid var(--color-line); border-bottom: 1px solid var(--color-line);
}
/* De cijfers lossen op in plaats van af te kappen. Dat gebeurt met een mask op de kolom zelf,
   niet met twee gradient-lagen erboven: een laag vervaagt alleen naar de kleur die je erin
   hardcodeert, en botst dus met elke bodem waar het wiel op staat (dat was precies wat er
   misging toen het witte vlak erboven kwam). Een mask maakt de pixels écht doorzichtig en is
   daarmee ongevoelig voor de achtergrond — ook in het donkere thema. `black` is hier geen
   kleur maar volle dekking: een mask kijkt alleen naar alpha, dus het thema raakt 'm niet. */
.timewheel__col {
  position: relative; height: 184px; width: 86px; padding: 69px 0; /* (184-46)/2 → rand-items centreren */
  overflow-y: scroll; scroll-snap-type: y mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(transparent 0, black 30%, black 70%, transparent 100%);
  mask-image: linear-gradient(transparent 0, black 30%, black 70%, transparent 100%);
}
.timewheel__col::-webkit-scrollbar { display: none; }
.timewheel__col--hours { text-align: right; }
.timewheel__col--minutes { text-align: left; }
.timewheel__item {
  height: 46px; line-height: 46px; scroll-snap-align: center; font-size: var(--text-20); font-weight: 500;
  color: var(--color-faint); font-variant-numeric: tabular-nums;
}
.timewheel__col--hours .timewheel__item { padding-right: 14px; }
.timewheel__col--minutes .timewheel__item { padding-left: 14px; }
.timewheel__item.is-active { font-weight: 500; color: var(--color-text); }
/* position: relative — anders tekent de absolute band eroverheen. */
.timewheel__colon { position: relative; align-self: center; font-size: var(--text-20); font-weight: 500; color: var(--color-text); padding-bottom: 2px; }

/* Datumkiezer — maandregel: jaar links (tikbaar → jaar-grid) · maandnaam (tikbaar → maand-grid) · pijlen */
.datecal__nav { display: flex; align-items: center; justify-content: space-between; padding: 6px 20px 10px; flex: none; }
.datecal__yearbtn {
  display: flex; align-items: center; gap: 6px; border: 0; background: none; cursor: pointer;
  padding: 4px 10px; margin-left: -10px; border-radius: var(--radius-groep);
}
.datecal__caret { display: inline-flex; flex: none; transition: transform .2s; }
.datecal__caret-icon { width: var(--icon-sm); height: var(--icon-sm); color: var(--color-text); }
.datecal__navright { display: contents; }
.datecal__monthpick { flex: 1; display: flex; justify-content: center; }
.datecal__monthbtn {
  display: flex; align-items: center; gap: 5px; border: 0; background: none; cursor: pointer;
  padding: 4px 10px; border-radius: var(--radius-groep); font-size: var(--text-base);
  font-weight: 500; color: var(--color-text);
}
.datecal__monthbtn svg { width: var(--icon-sm); height: var(--icon-sm); color: var(--color-text); flex: none; }
.datecal__arrows { display: flex; gap: 10px; }
.datecal__navbtn {
  width: 34px; height: 34px; border-radius: 50%; background: var(--color-surface); border: 1px solid var(--color-line);
  display: flex; align-items: center; justify-content: center; color: var(--color-text); cursor: pointer; flex: none;
}
.datecal__navbtn svg { width: var(--icon-sm); height: var(--icon-sm); }
.datecal__month { font-size: var(--text-base); font-weight: 500; color: var(--color-text); }

/* Jaar- en maand-modus: chips van 3 breed (jaar scrollt) */
.datecal__chipgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 0 18px 8px; flex: none; }
.datecal__chipgrid--years { height: 264px; overflow-y: auto; align-content: start; scrollbar-width: none; }
.datecal__chipgrid--years::-webkit-scrollbar { display: none; }
.datecal__chip {
  border: 0; background: transparent; font: inherit; font-size: var(--text-base); font-weight: 500;
  color: var(--color-text); cursor: pointer; text-align: center;
}
.datecal__chip:active { transform: scale(.96); }
.datecal__chip--year { padding: 12px 0; border-radius: var(--radius-pill); }
.datecal__chip--month { padding: 13px 0; border-radius: var(--radius-pill); font-size: var(--text-sm); background: var(--color-surface); border: 1px solid var(--color-line); }
.datecal__chip.is-active { font-weight: 500; color: var(--color-on-btn); background: var(--color-btn); border-color: var(--color-btn); }
.datecal__dows { display: grid; grid-template-columns: repeat(7, 1fr); padding: 0 16px 4px; flex: none; }
.datecal__dow { text-align: center; font-size: var(--text-xs); font-weight: 500; color: var(--color-faint); }
.datecal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; padding: 0 16px 6px; flex: none; }
.datecal__day {
  aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  border: 0; background: transparent; border-radius: var(--radius-binnen); font: inherit; font-size: var(--text-base);
  color: var(--color-text); cursor: pointer; font-weight: 500;
}
.datecal__day:active { transform: scale(.94); }
.datecal__dot { width: 4px; height: 4px; border-radius: 50%; margin-top: 2px; background: transparent; }
/* Aangrenzende maanddagen: zichtbaar + tikbaar (vervangt de lege lead-cellen) */
.datecal__day.is-outside { color: var(--color-faint); }
/* Onder de ondergrens (vooruitkijkende velden): zichtbaar maar niet kiesbaar — je ziet de
   maand nog kloppen, je kunt er alleen niet in terug. */
.datecal__day.is-disabled { color: var(--color-faint); opacity: .45; cursor: default; }
.datecal__day.is-disabled:active { transform: none; }
.datecal__day.is-outside.is-today { background: transparent; }
.datecal__day.is-today { font-weight: 500; color: var(--color-accent); background: var(--color-panel); }
.datecal__day.is-today .datecal__dot { background: var(--color-btn); }
.datecal__day.is-selected { font-weight: 500; color: var(--color-on-btn); background: var(--color-btn); }
.datecal__day.is-selected .datecal__dot { background: transparent; }

.agenda-form__number {
  width: 4.25rem;
  min-height: 36px;
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  text-align: center;
}

/* Afspraak-formulier (new/edit) — mobile-first, labels boven inputs,
   44px touch-targets, tokens uit :root. */
/* De verticale ritmiek komt van .stack (conventions §3) — hier alleen nog de breedte. */
.agenda-form { max-width: 480px; }

/* Opslaan onderaan: vol-breed accent-knop (ontwerp), met de annuleer-link eronder. */
/* Verwijderen onderaan het bewerkscherm: een kale rij op de paginagrond, apart van de kaart
   met de velden — het hoort niet bij invullen, het maakt er een eind aan (2026-09-11).
   Gecentreerd en in --error, zonder vlak: rood is hier de betekenis, geen alarm. */
.agenda-form__delete {
  display: block; margin: var(--space-4) 0 0; padding: 8px 16px;
  text-align: center; font-size: var(--text-sm); font-weight: 500;
  color: var(--color-error); text-decoration: none; border-radius: var(--radius-pill);
}
/* Dezelfde regel als button_to (contact, overdracht, kasboek, kind, club — 2026-09-15): app-breed
   één verwijderen in de letter van "Gezin verlaten" (.vset__logout) — geen roze vlak, geen
   ghost-knop, geen icoonknop. */
button.agenda-form__delete { width: 100%; background: none; border: 0; font: inherit; font-size: var(--text-sm); font-weight: 500; cursor: pointer; }
.agenda-form__delete-form { margin: 0; }

.agenda-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Inline variant (voorleg-vinkje, bron §5): vinkje + label naast elkaar, bovenaan uitgelijnd
   zodat een lange zin onder zichzelf doorloopt; binnen de 22px-marge van de sheet. */
.agenda-form__field--inline {
  flex-direction: row;
  align-items: flex-start;
  gap: 11px;
  padding: 2px 4px 4px;
}
/* Uitgeschakeld (solo: geen co-ouder om aan voor te leggen) — gedimd, hint eronder. */
.agenda-form__field--disabled { opacity: 0.45; flex-wrap: wrap; }
/* Het (lange) label blijft náást de checkbox en tekst-wrapt intern — zonder flex:1
   duwt de max-content-breedte het als geheel naar de volgende flex-regel. */
.agenda-form__field--inline label { flex: 1; min-width: 0; }

.agenda-form__field label {
  font-size: var(--text-15);
  font-weight: var(--weight-medium);
  line-height: var(--leading);
  color: var(--color-text);
}

.agenda-form__field input[type="text"],
.agenda-form__field input[type="datetime-local"],
.agenda-form__field select,
.agenda-form__field textarea {
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  font: inherit;
  font-size: var(--text-17);
  color: var(--color-text);
  background: var(--color-card);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);

  border-radius: var(--radius-textarea);
}

/* Veldmodel (2026-09-01): zelfde focus-taal als .form__input — rand + ring. */
.agenda-form__field input[type="text"]:focus-visible,
.agenda-form__field input[type="datetime-local"]:focus-visible,
.agenda-form__field select:focus-visible,
.agenda-form__field textarea:focus-visible {
  outline: none;
  border-color: var(--color-text);
  box-shadow: var(--veld-focus-ring);
}

.agenda-form__field textarea {
  resize: vertical;
  min-height: 80px;

  border-radius: var(--radius-textarea);
}

/* Vinkje (bron: 22px, radius 7, rand 2px faint; aangevinkt = inkt met wit vinkje — accent is
   nooit een gevuld vlak). Eigen tekening i.p.v. accent-color, zodat maat en vorm kloppen. */
.agenda-form__field input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin: 0;
  display: grid;
  place-items: center;
  border: 2px solid var(--color-faint);
  border-radius: var(--radius-binnen);
  background: transparent;
  cursor: pointer;
}
.agenda-form__field input[type="checkbox"]:checked { background: var(--color-btn); border-color: var(--color-btn); }
.agenda-form__field input[type="checkbox"]:checked::after {
  content: ""; width: 11px; height: 6px; margin-top: -2px;
  border: solid var(--color-on-btn); border-width: 0 0 2.5px 2.5px; transform: rotate(-45deg);
}
.agenda-form__field input[type="checkbox"]:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* Maand-grid — 7 kolommen, mobiel horizontaal scrollbaar */
/* Verjaardag (read-time uit de gezinsinfo, geen event): compact pill-item
   met de gezin-kleur als linksaccent; past in maand-cel én all-day-rij. */
.agenda-birthday {
  display: block;
  font-size: var(--text-xs);
  padding: 1px var(--space-2);
  margin-bottom: 2px;
  border-radius: var(--radius);
  background: var(--color-surface-own);
  border-left: 3px solid var(--event-color, var(--color-accent));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Omgangs-custody-band: wie heeft de kinderen op deze dag (read-time via Agenda::Custody).
   Eén vaste neutrale kleur (--color-custody) voor béíde ouders — dit gaat over wáár de
   kinderen zijn, geen persoon, dus geen persoons-kleur (en buiten het kiesbare palet). */
.agenda-custody { display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px; }
.agenda-custody__band {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px;
  font-size: var(--text-xs);
  padding: 1px var(--space-2);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--color-custody) 14%, var(--color-surface));
  border-left: 3px solid var(--color-custody);
}
.agenda-custody__label { color: var(--color-text); }
/* Aantikbare band → zorgperiode-scherm. Geen onderstreping of accentkleur: 'ie moet een
   rustige informatieband blijven, alleen mét een tik-doel. */
a.agenda-custody__band--link { text-decoration: none; color: inherit; cursor: pointer; }
a.agenda-custody__band--link:active { background: color-mix(in srgb, var(--color-custody) 26%, var(--color-surface)); }

/* Wisselvoorstel-overlay: náást de custody-band, muteert 'm niet (design 2026-07-13
   §2/§4). Amber = dezelfde "wacht op akkoord"-taal als elders in de app (afspraak-
   card__wait, plan-status--wacht); gestippelde rand spiegelt .agenda-event--proposed
   (nog niet bevestigd). */
.swap-overlay {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-bottom: 2px;
  padding: 3px var(--space-2);
  font-size: var(--text-xs);
  border-radius: var(--radius);
  background: var(--color-amber-soft);
  border: 1px dashed color-mix(in srgb, var(--color-amber) 45%, var(--color-amber-soft));
}
.swap-overlay__status { color: var(--color-text-muted); }
/* Veld-groepje dat als geheel verschijnt/verdwijnt (Tot en met, het contextuele reden-veld
   en de generieke Notitie) — de Stimulus-controller zet alleen [hidden]. */
.zw-field[hidden] { display: none; }
.swap-overlay__summary { margin: 0; color: var(--color-text); }
.swap-overlay__moment,
.swap-overlay__reason,
.swap-overlay__note,
.swap-overlay__standby { margin: 0; color: var(--color-text-muted); }

/* Voorstel-kaart (conventions §3.9b): grijze kaart, herkomst 15 muted, wat 17 op 1,4, de
   overdrachtsmomenten en de reden 15 muted, twee even brede knoppen — Akkoord inkt, Dat lukt
   niet wit. De vrager ziet i.p.v. de knoppen de tekstactie Intrekken. */
.swap-overlay--full {
  display: flex; flex-direction: column; gap: 6px;
  padding: 22px 20px;
  background: var(--color-card);
  border-radius: var(--radius-groep);
  font-size: var(--text-15);
}
.swap-overlay--full .swap-overlay__status { font-size: var(--text-15); }
.swap-overlay--full .swap-overlay__summary { font-size: var(--text-17); line-height: var(--leading); }
.swap-overlay--full .swap-overlay__moment,
.swap-overlay--full .swap-overlay__reason,
.swap-overlay--full .swap-overlay__note,
.swap-overlay--full .swap-overlay__standby { font-size: var(--text-15); line-height: var(--leading); }
.swap-overlay--full .swap-overlay__standby { margin-top: 4px; }
/* Bij een wijziging: de oude waarde doorgestreept in muted, dan de pijl en de nieuwe in inkt. */
.swap-overlay__oud { color: var(--color-text-muted); }
.swap-overlay__actions { display: flex; gap: 10px; margin-top: 12px; }
.swap-overlay__actions .button_to { flex: 1; margin: 0; }
.swap-overlay__accept,
.swap-overlay__decline,
.swap-overlay__withdraw {
  width: 100%; min-height: 48px; padding: 12px 16px;
  font: inherit; font-size: var(--text-17); font-weight: 500;
  border-radius: var(--radius-pill); cursor: pointer;
}
.swap-overlay__accept { background: var(--color-btn); color: var(--color-on-btn); border: none; }
.swap-overlay__decline { background: var(--color-surface); color: var(--color-text); border: 1px solid var(--color-line); }
.swap-overlay__withdraw { background: none; color: var(--color-text-muted); border: none; }

/* ===================== AGENDA — LIJST-VIEW (mobiel-eerste) =====================
   Komende afspraken gegroepeerd per dag: dag-kop + een kaart met rijen
   (tijd+duur · gekleurde custody-balk · titel/sub · wacht-op-akkoord-badge). */
/* Losse dag-kaarten onder elkaar. Het scrollen gebeurt één niveau hoger, op
   .agenda-page__grid--padded — twee geneste scrollers zouden de rijen samenpersen. */
/* Eén-regel-badge voor een openstaand wijzigingsverzoek ("Wijziging aangevraagd") — in het
   rooster en de lijst. Tik opent het panel met het volle voorstel; het beslisblok zelf
   staat nooit in de agenda (te groot, zie design-feedback 2026-07-26). Amber = dezelfde
   wacht-op-akkoord-familie als de overlay. */
.pending-badge {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  margin: 2px 0; padding: 3px 9px; border-radius: var(--radius-pill);
  border: 1px dashed var(--color-amber); background: var(--color-amber-soft);
  color: var(--color-amber-deep); font-size: var(--text-xs); font-weight: 500;
  font-family: inherit; cursor: pointer; text-align: left;
}
.pending-badge__dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--color-amber); }
.pending-badge__text { overflow-wrap: break-word; }

/* Verjaardag in een lijst-kaart: hoort bij de hele dag, niet bij een rij — uitlijnen met
   de binnenmarge van de rijen eronder zodat de kaart één kolom leest. */
.agenda-list__card > .agenda-birthday { margin: 0; }

/* Openstaand wisselvoorstel als rij in de lijst: dezelfde kolommen als een afspraak-rij,
   dus het staat ín de dag — maar amber, zodat je ziet dat het nog niet vaststaat. Het is
   een <button> (opent het panel) en geen <a>, dus de knop-defaults terugzetten. De 3px
   accentrand komt van de padding af, anders schuift de rij uit de lijn. */
.agenda-list__item--pending {
  width: calc(100% - 32px);
  margin: 4px 16px 6px;
  border: 0;
  border-radius: var(--radius);
  padding: 11px 14px;
  background: var(--color-amber-soft);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* ===================== OVERDRACHT-DETAIL (eigen scherm, geen modal) ===================== */
/* Gekleurd staafje vóór de scherm-titel, in de kleur van de ouder die het moment aangaat. */
/* "Tot nu → Vanaf nu": de kern van het scherm, dus als eerste blok en symmetrisch —
   geen van beide ouders krijgt visueel voorrang. */
/* Zelfde rijhoogte als de feitrijen eronder; de lijn komt van de kaart (2026-09-10). */
.overdracht-flow {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
}
.overdracht-flow__side {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  text-align: center;
}
.overdracht-flow__label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-muted);
}
/* De naam per kant als gekleurde tekst, geen vlakje (bron: signaalnaam = tekst). */
.overdracht-flow__chip {
  font-size: var(--text-sm);
  font-weight: 500;
  /* Zelfde terugval-fout als .agenda-list__whodot: de code geeft de placeholder bewust
     geen kleur, dus de chip moet neutraal zijn en niet de kleur van de kijker lenen. */
  color: var(--chip-color, var(--color-text-muted));
}
.overdracht-flow__arrow { flex: none; color: var(--color-text); }
.overdracht-flow__arrow svg { width: var(--icon); height: var(--icon); }
/* Kind-avatars rechts op de "Kinderen"-regel: zelfde initiaal-in-cirkel als de gezin-hub. */
.overdracht-kids { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; }
.overdracht-kids__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--kid-color, var(--color-accent));
  color: var(--color-on-accent);
  font-size: var(--text-xs);
  font-weight: 500;
}
/* Herinnering-rij: een button_to (geen checkbox) { margin-top: 14px; }

/* ===================== AGENDA-CHROME (Outlook-stijl) ===================== */
/* Eén werkbalk over de volle breedte; daaronder de zijbalk (mini-kalender +
   bron-checkboxes) links en het rooster rechts. De uren-as + dag-koppen wit,
   de cellen grijzig (Fluent, strak, minimale schaduw). */
.agenda-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  /* Geen top-padding: de gedeelde .app-topbar (eerste kind) draagt de safe-area-top.
     Zijpadding 18px = app-brede scherm-padding (gelijk aan Home/Gezin/Gesprek). */
  padding: 0 18px var(--space-4);
  min-width: 0;
  /* Vult de hoogte van het werkvlak; alleen het rooster scrollt (zie .agenda-week). */
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

/* Zijbalk (mini + bronnen) links, rooster rechts — op gelijke hoogte, samen de
   resthoogte vullend onder de werkbalk. */
.agenda-body {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: var(--space-4);
  align-items: stretch;
  min-width: 0;
  flex: 1;
  min-height: 0;
}

.agenda-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  /* Vult de resthoogte: zo eindigt ook een kort raster (maand) tegen de tabbalk. */
  flex: 1;
  min-height: 0;
}

/* De grid-wrapper geeft het rooster de resthoogte; het rooster scrollt intern. */
.agenda-page__grid {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
/* Maand & lijst krijgen de normale schermpadding aan weerszijden (kaart-achtig);
   het tijd-rooster blijft full-bleed. */
/* En ze dragen hun eigen verticale scroller: de agenda-shell (.agenda-layout, .app__body)
   staat op overflow:hidden omdat in de tijd-weergaven alléén .agenda-week intern scrollt.
   Maand en lijst hebben zo'n binnen-scroller niet, dus zonder deze regel wordt een lijst
   die langer is dan het scherm gewoon afgekapt in plaats van scrollbaar. */
.agenda-page__grid--padded {
  padding-inline: var(--page-gutter);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* "Mijn agenda's" — bron-checkboxes (welke gezinnen tonen); geen kaart, sluit
   aan op de transparante zijbalk. */
.agenda-sources {
  border: none;
  padding: var(--space-2) 0 0;
  margin: 0;
}
.agenda-sources__legend {
  padding: 0 var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.agenda-sources__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 40px;
  cursor: pointer;
  font-size: var(--text-sm);
}
/* Teller rechts in een filterrij (bron): het aantal in het huidige venster, gedempt. */
.agenda-sources__count { margin-left: auto; font-size: var(--text-xs); font-weight: 400; color: var(--color-faint); }
.agenda-sources__box {
  width: 18px;
  height: 18px;
  accent-color: var(--gezin-color, var(--color-btn));
  cursor: pointer;
  flex: 0 0 auto;
}

.agenda-chrome__picker {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  border: 0;
}

/* ---- Mobiele agenda-chrome: de desktop-werkbalk + zijbalk wijken voor een
   compacte dag-strip (Outlook-mobiel-stijl). Standaard verborgen. ---- */
.agenda-mobile { display: none; }

@media (min-width: 0px) {
  /* Full-bleed rooster (design): de layout draagt géén zij-/onderpadding meer — het
     grid loopt tot de schermranden en tot de bottom-nav. De chrome (topbar + dag-
     strip) houdt de 18px scherm-padding zelf. */
  .agenda-layout { padding: 0; gap: var(--space-2); align-self: center; width: 100%; max-width: 460px; }
  .agenda-layout > .app-topbar,
  .agenda-layout > .agenda-mobile { padding-inline: var(--page-gutter); }
  /* .agenda-layout is een gap-container, dus de 8px gap komt bóvenop de 18px marge van
     de topbar. Hier dus 10px, zodat de dag-strip op dezelfde 18px onder het logo staat
     als de titel op Home, Contact en Gezin (feedback Jerry 2026-09-03). */
  .agenda-layout > .app-topbar { margin-bottom: 10px; }
  /* Een vaste laag op --bg: de lijst schuift eronder door (§1); z-index boven de lijst
     zodat de maandoverlay (stap 2) er straks óver kan hangen. */
  .agenda-mobile { display: block; position: relative; z-index: 3; background: var(--color-bg); }
  /* Body = alleen het rooster (zijbalk verborgen); vult de resthoogte. */
  .agenda-body { display: flex; flex-direction: column; gap: 0; }
  /* Geen gap onder het rooster (het lege modal-frame telde als flex-kind mee):
     het grid loopt door tot de bottom-nav. */
  .agenda-main { gap: 0; }

  .agenda-mobile__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding-bottom: var(--space-2);
  }
  /* Maand-navigator (‹ juni 2026 ›) links + Jij/co-legenda rechts. */
  .agenda-mobile__nav { display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; }
  .agenda-mobile__navstep {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    color: var(--color-text-muted);
  }
  .agenda-mobile__navstep svg { width: var(--icon-lg); height: var(--icon-lg); }
  .agenda-mobile__actions { display: inline-flex; gap: var(--space-1); }

  /* Datum/tijd-velden mogen krimpen i.p.v. overlopen. */
  .agenda-form__when-input { min-width: 0; flex: 1; }
}

/* Zoekresultaten (?q=): telling + venster-hint boven de dag-kaarten. Bewust rustig —
   het gaat om de treffers eronder, niet om de meta-regels. */
.agenda-search__count { font-size: var(--text-sm); color: var(--color-text); margin: 0 2px 10px; }

/* ── Agenda-kop (design scherm 5): 3 icoonknoppen + zoekbalk + weergave-sheet ── */
.agenda-mobile__actions { display: inline-flex; align-items: center; gap: 7px; }
/* Zoekveld ín de kop (§3): zichtbaar vervangt het de hele rij — navigatie en knoppen wijken. */
.agenda-mobile__head > .agenda-mobile__searchbar { flex: 1; min-width: 0; }
.agenda-mobile__head:has(> .agenda-mobile__searchbar:not([hidden])) > :not(.agenda-mobile__searchbar) { display: none; }
.agenda-mobile__searchbar {
  display: flex; align-items: center; gap: 10px; margin: 0;
  background: var(--color-card); border: 1px solid transparent;
  border-radius: var(--radius-pill); padding: 10px 13px;
}
/* De zoekbalk is dicht tot het zoek-icoon 'm toont; [hidden] moet de display winnen. */
.agenda-mobile__searchbar[hidden] { display: none; }
.agenda-mobile__searchbar svg { flex: none; width: var(--icon); height: var(--icon); color: var(--color-faint); }
.agenda-mobile__searchbar input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: none;
  font-family: inherit; font-size: var(--text-17); color: var(--color-text);
}
.agenda-mobile__searchclear { appearance: none; -webkit-appearance: none; flex: none; display: inline-flex; padding: 0; border: 0; background: none; color: var(--color-faint); cursor: pointer; }

/* ===================== INLOG (auth) ===================== */
/* Rustige, warme "doorway": gecentreerde kaart op een zachte warme gloed. Mobile-
   first; inputs 16px (geen iOS-zoom) en 48px hoog (touch). */
.auth {
  /* De auth-schermen vallen buiten .app__body (de scroll-container van de app-shell) en
     staan dus direct in een body met overflow:hidden. Zonder eigen scroll viel alles
     onder de vouw weg zodra het scherm korter was dan de inhoud — op een telefoon mét
     browserbalken dus meteen (2026-09-02). */
  height: 100dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Links uitgelijnd en van bovenaf (ontwerp 2026-09-02): het woordmerk staat linksboven
     als afzender, de vraag eronder. Gecentreerd las het als een los inlogvenster. */
  justify-content: flex-start;
  /* Eigen chrome (geen .app__body): safe-area zelf opvangen; zijpadding = app-breed. */
  padding: calc(var(--space-6) + env(safe-area-inset-top, 0px)) var(--page-gutter) var(--space-6);
  /* Egaal de paginagrond, geen gloed (2026-09-02). Er lag een terracotta radial-gradient
     van 10% precies bovenaan, waardoor de bovenste rand ~#F4EBE7 werd in plaats van
     #F8F8F6 — de statusbalk (theme-color = --color-bg) sloot daardoor zichtbaar niet aan.
     De ingelogde app had die gloed niet, dus het was ook een inconsistentie; en
     decoratieve kleur is precies wat de kleurdelta eruit haalde. */
  background: var(--color-bg);
}

.auth__card {
  width: 100%;
  max-width: 400px;
  /* Geen kaart-chrome (ontwerp 2026-09-02): het formulier staat op de doorlopende grond,
     zoals elk ander scherm. De witte velden zetten zichzelf al genoeg af. */
  animation: auth-in 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes auth-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .auth__card { animation: none; }
}

/* Woordmerk LINKSBOVEN als afzender (ontwerp 2026-09-02), niet als gecentreerde titel.
   Zelfde breedte als de rest van de kolom, zodat het met de velden uitlijnt. */
.auth__brand {
  display: flex;
  justify-content: flex-start;
  width: 100%;
  max-width: 400px;
  margin-bottom: 2px;
}

.auth__heading {
  margin-bottom: var(--space-6);
  font-size: 1.6rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text);
}
.auth__heading:has(+ .auth__lede) { margin-bottom: var(--space-2); }

/* Intro-regel onder de kop (bv. op de wachtwoord-vergeten-pagina). */
.auth__lede {
  margin: 0 0 var(--space-6);
  font-size: var(--text-sm);
  line-height: var(--leading);
  color: var(--color-text-muted);
}
/* Volgt er nog een kleine noot (uitleg-scherm), dan hoort die bij de lede: de ruimte
   onder de lede vervalt, de eigen bovenmarge van de noot doet het werk. */
.auth__lede:has(+ .auth__codenote) { margin-bottom: 0; }

/* .auth__form gebruikt de gedeelde ritmiek (.stack, 16px); hier niets eigens meer. */
.auth__form { --stack-gap: var(--space-4); }
.auth__field { display: flex; flex-direction: column; gap: 6px; }
.auth__label { font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }

/* Het adres in de lede: de kern van de zin ("klopt dit adres?"), dus donkerder. */
.auth__lede b { color: var(--color-text); }

/* Zelfde veldmodel als .form__input (2026-09-01): randloos in rust, rand + ring op focus. */
.auth__input {
  width: 100%;
  min-height: 52px;
  padding: 15px 20px;
  font-size: var(--text-17); /* 16px → geen iOS-zoom */
  color: var(--color-text);
  background: var(--color-card);
  /* Lichte stijl (bron LOGIN): een zichtbare rand, focus in inkt. */
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.auth__input::placeholder { color: var(--color-faint); }
.auth__input:focus {
  outline: none;
  border-color: var(--color-text);
  box-shadow: var(--veld-focus-ring);
}
.auth__input--password { padding-right: 48px; }

.auth__input-wrap { position: relative; }
.auth__reveal {
  position: absolute;
  top: 0;
  right: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  color: var(--color-text-muted);
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.auth__reveal:hover { color: var(--color-text); }
.auth__eye { width: 20px; height: 20px; }
/* Eén icoon zichtbaar: standaard het oog (tonen); na onthullen het doorgestreepte. */
.auth__eye--off { display: none; }
.auth__field.is-revealed .auth__eye--on { display: none; }
.auth__field.is-revealed .auth__eye--off { display: inline-block; }

/* Wachtwoord-sterkte-indicatie (alleen visueel). Track + groeiende balk + label.
   Kleur per niveau: zwak = error-rood, matig = kraft (tan), sterk = accent. */
.auth__strength { display: flex; align-items: center; gap: var(--space-2); margin-top: 6px; }
.auth__strength-track {
  flex: 1;
  height: 6px;
  background: var(--color-border);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.auth__strength-bar {
  display: block;
  width: 0;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--color-border);
  transition: width 0.2s ease, background-color 0.2s ease;
}
.auth__strength-bar[data-level="1"] { background: var(--color-error); }
.auth__strength-bar[data-level="2"] { background: var(--kraft); }
.auth__strength-bar[data-level="3"] { background: var(--color-btn); }
.auth__strength-label {
  min-width: 3.5em;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* De passkey-knop volgt op het formulier; zonder deze regel plakte hij tegen de
   hoofdknop (de "of"-streep die daar stond gaf die ruimte eerder). */
.auth__form + .button--block { margin-top: var(--space-3); }
.auth__submit {
  margin-top: var(--space-2);
  width: 100%;
  height: 48px;
  font-size: 1rem;
  font-weight: 500;
  color: var(--color-on-btn);
  background: var(--color-btn);
  border: 0;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.15s ease, transform 0.05s ease;
  box-shadow: var(--shadow-knop);
}
.auth__submit:hover { background: var(--color-accent-hover); }
.auth__submit:active { transform: translateY(1px); }

.auth__alert {
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading);
  color: var(--color-error);
  background: rgba(192, 54, 44, 0.08);
  border: 1px solid rgba(192, 54, 44, 0.3);
  border-radius: var(--radius);
}

/* Notice (info/bevestiging, bv. "we hebben je een e-mail gestuurd"). */
.auth__notice {
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading);
  color: var(--color-text);
  background: var(--color-chat-surface-own);
  border-radius: var(--radius);
}

/* Alternatieve actie onder de card (bv. "Nog geen account? Maak er een aan"). */
.auth__alt {
  width: 100%;
  max-width: 400px;
  margin-top: var(--space-4);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.auth__alt-link {
  margin-left: 4px;
  color: var(--color-accent);
  font-weight: 500;
  text-decoration: none;
}
.auth__alt-link:hover { text-decoration: underline; }

/* Mobiel: geen card-chrome (het formulier staat los op de warme achtergrond),
   maar het merk blijft erboven en de link eronder staan. */
@media (max-width: 767px) {
  .auth__card {
    max-width: none;
    width: 100%;
    padding: var(--space-6) 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    animation: none;
  }
}

/* ── Wachtwoordloze aanmeld-/inlogflow (e-mail → code → voornaam → Face ID) ── */
/* Tagline onder het woordmerk. */
.auth__tagline {
  width: 100%;
  max-width: 400px;
  margin: 0 0 var(--space-8);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
/* De andere wegen naar binnen staan ONDERAAN en zonder kaart (ontwerp 2026-09-02): op de
   grond, gescheiden door haarlijnen. Een kaart zou ze evenveel gewicht geven als de
   code-flow hierboven, en dat zijn ze niet. margin-top:auto duwt ze naar de onderkant,
   zodat de ruimte ertussen meeademt met het scherm. */
/* Terug-link bóven de kop op een uitleg-scherm (ontwerp 2026-09-02) — zelfde vorm als de
   vnav-terugweg binnen de app, maar de auth-schermen dragen geen vnav. */
/* Losse tekstblokken direct in .auth (uitleg-schermen zonder kaart) krijgen dezelfde
   kolombreedte als de rest; zonder dat krimpen ze tot hun inhoud en centreert de
   flex-container ze (2026-09-02). */
.auth > .auth__heading,
.auth > .auth__lede { width: 100%; max-width: 400px; }
.auth__terug { display: inline-flex; align-items: center; gap: 4px; width: 100%; max-width: 400px; margin-bottom: var(--space-4); color: var(--color-accent); font-size: var(--text-sm); font-weight: 500; text-decoration: none; }
.auth__terug .icon { width: var(--icon-sm); height: var(--icon-sm); }
/* "Geen e-mail gevonden?" — een aparte hulp-sectie onder de stappen, afgezet met een
   haarlijn zodat hij niet als vierde stap leest. */
.auth__hulp { width: 100%; max-width: 400px; margin-top: var(--space-8); padding-top: var(--space-6); border-top: 1px solid var(--color-hair); }
.auth__hulp h2 { margin: 0; font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.auth__hulp .settings__hint { margin-top: var(--space-3); }
/* De actie staat onderaan vast: dit scherm is uitleg, de enige stap die je hier zelf kunt
   zetten staat los van de tekst. */
.auth__foot { width: 100%; max-width: 400px; margin: auto auto 0; padding-top: var(--space-5); }
.auth__routes {
  width: 100%;
  max-width: 400px;
  margin: auto auto 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* Label alleen voor schermlezers: het veld heeft een placeholder en staat alleen. */
.auth__srlabel {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
/* Code-veld (OTP): gecentreerd, ruime letter-spacing. */
.auth__input--code {
  text-align: center;
  font-size: 1.6rem;
  font-weight: 500;
}
/* "Code niet ontvangen? / Opnieuw sturen" staat bóven de knop (ontwerp 2026-09-02): het is
   een uitweg bij het veld, geen naschrift onder de actie. */
.auth__coderow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.auth__codehint { font-size: var(--text-sm); color: var(--color-text-muted); }
/* Waar je nog meer kunt kijken als de mail niet aankomt — één regel, onder de resend-rij. */
.auth__codenote {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* button_to-acties (opnieuw sturen / terug / overslaan / Face ID inschakelen) doen mee
   in de flow alsof het de knop/link zelf is (geen form-wrapper-layout). */
.auth__card form.button_to { display: contents; }
button.auth__alt-link {
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
}
/* "Opnieuw sturen" leest even groot als "Code niet ontvangen?" ernaast (feedback
   2026-08-07) — zonder deze regel wint `font: inherit` hierboven met de grotere
   kaart-tekstmaat (button.auth__alt-link heeft hogere specificiteit dan .auth__resend
   alleen, dus de override moet als element+class meekomen). */
button.auth__resend { font-size: var(--text-sm); }
/* Tijdens de cooldown (otp-controller) leest de knop als tekst, niet als actie. */
button.auth__resend[disabled] { color: var(--color-text-muted); cursor: default; }
.auth__back, .auth__skip {
  display: block;
  width: 100%;
  margin-top: var(--space-3);
  text-align: center;
}

/* Accept-modus: paarse co-ouder-uitnodig-banner. */
.auth__invite {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
  padding: 13px 15px;
  background: var(--color-coparent-soft);
  border-radius: var(--radius-groep);
}
.auth__invite-avatar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--color-coparent);
  color: var(--color-on-accent);
  font-weight: 500;
}
.auth__invite-text { display: flex; flex-direction: column; gap: 1px; }
.auth__invite-title { font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.auth__invite-sub { font-size: 0.78rem; color: var(--color-text-muted); }

/* Face ID-stap: gecentreerd, met terracotta icoon-tegel. */
.auth__card--center { text-align: center; }
.auth__lockicon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 84px;
  margin: 0 auto var(--space-5);
  border-radius: var(--radius-groep);
  background: rgba(204, 120, 92, 0.12);
  color: var(--color-text);
}
.auth__lockicon svg { width: 40px; height: 40px; }

/* ===================== DEV-TOOLING (env-gated, alleen local) =====================
   Split-view + dev-paneel + reset-knoppen. Bewust een eigen, donker
   "developer-console"-palet (hardcoded, los van de tokens) zodat dev-tooling
   visueel onmiskenbaar verschilt van de echte ouder-/pro-UI. Alles hieronder
   verschijnt alleen in dev/test (env-guarded in de layout + controllers). */

/* Dev-paneel als off-canvas drawer (rechts), geopend via het dev-icoon in de
   header (alleen development). De gescopete --dev-*-tokens (GitHub-dark-achtig)
   staan hier zodat .dev-panel en .dev-reset binnen de drawer ze erven. */
.dev-drawer {
  --dev-bg: #0d1117;
  --dev-surface: #161b22;
  --dev-elev: #1f2733;
  --dev-border: #283041;
  --dev-text: #e6edf3;
  --dev-muted: #8b949e;
  --dev-accent: #58a6ff;
  --dev-accent-hover: #79b8ff;
  --dev-info: #a5d6ff;
  --dev-warn: #e3b341;
  --dev-border-hover: #3a455c;
  --dev-ok: #3fb950;
  --dev-warn: #d29922;
  --dev-danger: #f85149;

  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  width: 360px;
  max-width: 90vw;
  overflow-y: auto;
  background: var(--dev-bg);
  color: var(--dev-text);
  border-left: 1px solid var(--dev-border);
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  transform: translateX(100%);
  transition: transform 0.2s ease;
}
.app.dev-panel-open .dev-drawer { transform: translateX(0); }

.dev-drawer__backdrop {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: rgba(0, 0, 0, 0.4);
  display: none;
}
.app.dev-panel-open .dev-drawer__backdrop { display: block; }

/* Desktop (≥768px): het dev-paneel staat in de flex-flow rechts — net als de
   sidebar links. Geen overlay/backdrop: dicht = breedte 0, open = 360px, dus
   .app__main (flex: 1) krimpt fysiek mee. De open-staat blijft staan (de
   controller bewaart 'm in localStorage en herstelt bij connect). z-index: auto
   zodat het zwevende dev-icoon (z-38) erboven blijft en kan toggelen. */
@media (min-width: 768px) {
  .dev-drawer {
    position: relative;
    top: auto;
    bottom: auto;
    z-index: auto;
    flex-shrink: 0;
    width: 0;
    max-width: none;
    overflow: hidden;
    border-left: 0;
    transform: none;
    transition: width 0.15s ease;
  }
  .app.dev-panel-open .dev-drawer {
    width: 360px;
    overflow-y: auto;
    border-left: 1px solid var(--dev-border);
  }
  .dev-drawer__backdrop { display: none !important; }
}

.dev-panel {
  padding: var(--space-3);
  font-size: var(--text-xs);
  line-height: var(--leading);
}

/* Sticky header met env-badge: altijd zichtbaar dat dit dev-tooling is. */
.dev-panel__header {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) var(--space-3);
  padding: var(--space-3);
  background: var(--dev-bg);
  border-bottom: 1px solid var(--dev-border);
}

.dev-panel__badge {
  padding: 2px 6px;
  font-size: var(--text-10);
  font-weight: 500;
  color: var(--dev-warn);
  border: 1px solid var(--dev-warn);
  border-radius: var(--radius-xs);
}

.dev-panel__title {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--dev-text);
}

/* Secties als subtiele kaarten — duidelijke groepering i.p.v. losse regels. */
.dev-panel__section {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  background: var(--dev-surface);
  border: 1px solid var(--dev-border);
  border-radius: var(--radius);
}

.dev-panel__section-title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-10);
  font-weight: 500;
  color: var(--dev-muted);
}

/* Inklapbare secties (<details>): de titel is de summary, met een chevron rechts
   die meedraait. Standaard open (open-attribuut in de HAML). */
.dev-panel__section--collapsible > summary {
  display: flex;
  align-items: center;
  margin: 0;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.dev-panel__section--collapsible > summary::-webkit-details-marker { display: none; }
.dev-panel__section--collapsible[open] > summary { margin-bottom: var(--space-2); }
.dev-panel__section--collapsible > summary::after {
  content: "›";
  margin-left: auto;
  font-size: var(--text-base);
  line-height: 1;
  color: var(--dev-muted);
  transition: transform 0.15s ease;
}
.dev-panel__section--collapsible[open] > summary::after { transform: rotate(90deg); }
.dev-panel__section--collapsible > summary:hover::after { color: var(--dev-text); }

.dev-panel__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  padding: 5px 0;
}
.dev-panel__row + .dev-panel__row { border-top: 1px solid rgba(255, 255, 255, 0.04); }

.dev-panel__label { color: var(--dev-muted); }
.dev-panel__value {
  color: var(--dev-text);
  font-weight: 500;
  text-align: right;
  word-break: break-word;
}

.dev-panel__empty { padding: var(--space-3); color: var(--dev-muted); font-style: italic; }
.dev-panel__empty-inline { color: var(--dev-muted); font-style: italic; }

/* Status-pills (dot + label) voor backend, uitkomst, hard mode. */
.dev-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 9px;
  font-size: var(--text-xs);
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
}
.dev-pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.dev-pill--ok      { color: var(--dev-ok); }
.dev-pill--warn    { color: var(--dev-warn); }
.dev-pill--accent  { color: var(--dev-accent); }
.dev-pill--muted   { color: var(--dev-muted); }
.dev-pill--neutral { color: var(--dev-text); border-color: var(--dev-border); }
.dev-pill--neutral::before { display: none; }

/* Meetscores als stat-chips: de score groot (hero), uitkomst + hard mode ernaast. */
.dev-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}
.dev-stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: var(--space-2) var(--space-3);
  background: var(--dev-bg);
  border: 1px solid var(--dev-border);
  border-radius: var(--radius-binnen);
}
.dev-stat--wide { grid-column: 1 / -1; }
.dev-stat__label {
  font-size: var(--text-10);
  color: var(--dev-muted);
}
.dev-stat__value {
  font-size: var(--text-22);
  font-weight: 500;
  line-height: 1;
  color: var(--dev-text);
  font-variant-numeric: tabular-nums;
}

.dev-details summary {
  cursor: pointer;
  color: var(--dev-accent);
  font-size: var(--text-xs);
}

.dev-panel__json {
  margin: var(--space-2) 0 0;
  padding: var(--space-3);
  background: var(--dev-bg);
  border: 1px solid var(--dev-border);
  border-radius: var(--radius-binnen);
  font-size: var(--text-xs);
  color: var(--dev-info);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

.dev-input {
  width: 100%;
  margin-bottom: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--dev-bg);
  border: 1px solid var(--dev-border);
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: var(--text-xs);
  color: var(--dev-text);
  resize: vertical;
}
.dev-input::placeholder { color: var(--dev-muted); }
.dev-input:focus-visible { outline: 2px solid var(--dev-accent); outline-offset: 1px; }

.dev-btn {
  width: 100%;
  padding: 8px 10px;
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--dev-text);
  background: var(--dev-bg);
  border: 1px solid var(--dev-border);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.dev-btn:hover { background: var(--dev-elev); border-color: var(--dev-border-hover); }
.dev-btn--primary {
  color: var(--dev-bg);
  background: var(--dev-accent);
  border-color: var(--dev-accent);
}
.dev-btn--primary:hover { background: var(--dev-accent-hover); border-color: var(--dev-accent-hover); }

.dev-panel__warning {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: rgba(210, 153, 34, 0.12);
  border: 1px solid rgba(210, 153, 34, 0.5);
  border-left: 3px solid var(--dev-warn);
  border-radius: var(--radius-binnen);
  font-size: var(--text-xs);
  line-height: var(--leading);
  color: var(--dev-warn);
}
.dev-panel__warning-icon { flex-shrink: 0; }

.dev-reset {
  padding: var(--space-3);
  border-top: 1px solid var(--dev-border);
}
.dev-reset__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-10);
  font-weight: 500;
  color: var(--dev-muted);
}
.dev-reset form.button_to { display: block; margin: 0 0 var(--space-2); }
.dev-reset__btn {
  width: 100%;
  padding: 8px 10px;
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 500;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(248, 81, 73, 0.5);
  background: transparent;
  color: var(--dev-danger);
  cursor: pointer;
  transition: background 0.12s ease;
}
.dev-reset__btn:hover { background: rgba(248, 81, 73, 0.12); }

.form__row { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.form--inline { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2, .5rem); }
/* In een inline-form groeit het veld mee maar laat het de knop ernaast staan
   (i.p.v. de width:100% van de gedeelde veldbasis, die zou laten wrappen). */
.form--inline .form__input { width: auto; flex: 1 1 16rem; min-width: 0; }

/* ===================== SCHOOL/OPVANG-TOEVOEGFORMULIER ===================== */
/* Plat (2026-09-13): het formulier staat in het afspraak-idioom (titelregel + rijen); de
   besturingselementen (type-segment, dagpillen, tijden) staan eronder, elk in een blok
   onder een gedempte kop. */
.school-form { display: flex; flex-direction: column; }
/* [hidden] moet winnen van de display:flex-regels hieronder, anders blijven
   verborgen tijd-/soort-blokken zichtbaar (Stimulus zet .hidden, CSS overschreef). */
.school-form [hidden] { display: none !important; }
/* Een blok met besturingselementen (segment, chips, pillen) onder een gedempte kop — de
   gedeelde vorm voor wat geen rij is (school-, clubformulier). */
.agenda-form__blok { display: flex; flex-direction: column; }
.agenda-form__blokkop { display: block; margin: 0 2px 8px; font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.school-form__opvangtype { margin-top: 14px; }
.form__label-opt { color: var(--color-faint); font-weight: 500; margin-left: 4px; }
/* Veldmodel (2026-09-01): verplicht wordt NIET meer gemarkeerd — bijna alles is
   verplicht, dus een sterretje overal zegt niets. Gemarkeerd wordt wat optioneel
   is: .form__label-opt + t("shared.optioneel"). De --req-class blijft in de views
   als semantische haak (welke velden verplicht zijn); [required] + de form-gate
   doen het echte werk.
/* Uitleg-regel binnen een formulier (bv. de keuze uitnodigen-vs-alleen-opslaan): zelfde
   gedempte toon als .settings__hint, maar boven de knoppen i.p.v. onder een veld. */
.form__hint { margin: 0 0 var(--space-3); color: var(--color-text-muted); font-size: var(--text-sm); line-height: var(--leading); }

/* Type-toggle (school / opvang) */
.school-form__toggle { display: flex; gap: 8px; }
.school-form__toggle-btn { flex: 1; padding: 11px; border: 1px solid var(--color-border); border-radius: var(--radius-pill); background: var(--color-surface); color: var(--color-text); font-weight: 500; font-size: var(--text-sm); cursor: pointer; transition: transform .12s ease; }
.school-form__toggle-btn:active { transform: scale(.97); }
.school-form__toggle-btn.is-active { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }

/* Schooldagen-pills (verborgen checkbox + label) */
.school-form__days { display: flex; gap: 8px; }
.daypill { flex: 1; position: relative; }
.daypill__input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.daypill__label { display: block; text-align: center; padding: 12px 0; border: 1px solid var(--color-border); border-radius: var(--radius-pill); background: var(--color-surface); color: var(--color-text); font-weight: 500; font-size: var(--text-sm); cursor: pointer; }
.daypill.is-active .daypill__label { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
/* Als radio (terugkerende uitzondering: één dag) kiest de browser zelf; geen JS nodig. */
.daypill:has(.daypill__input:checked) .daypill__label { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
.daypill__input:focus-visible + .daypill__label { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* "Elke dag dezelfde tijd" — een rij met de schakelaar rechts, tussen haarlijnen. */
.school-form__same { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; padding: 12px 2px; border-top: 1px solid var(--color-line); border-bottom: 1px solid var(--color-line); font-size: var(--text-base); cursor: pointer; }

/* Tijden — uniform paar en per-dag-rijen */
.school-form__times { display: flex; gap: 12px; margin-top: 14px; }
.school-form__time { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.school-form__time-label { font-size: var(--text-xs); color: var(--color-faint); font-weight: 500; }
.school-form__perday { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.school-form__perday-row { display: flex; align-items: center; gap: 8px; }
.school-form__perday-day { flex: none; width: 28px; font-size: var(--text-sm); color: var(--color-text-muted); }
.school-form__perday-row .form__input { flex: 1; min-width: 0; }
.school-form__perday-sep { color: var(--color-faint); }

/* ===================== FORMULIER-VELDEN (gedeeld, Fluent v9) ===================== */

/* Zero-specificity baseline: élke bare input/select/textarea in de app krijgt een
   nette Fluent-doos, óók zónder class. `:where()` heeft specificiteit 0, dus elke
   class-regel hieronder (.form__*, .auth__input, .agenda-form__field, .compose__body)
   wint moeiteloos en blijft intact. Voorkomt losse systeemvelden. */
:where(
  input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"], [type="color"], [type="submit"], [type="button"], [type="reset"]),
  select,
  textarea
) {
  min-height: 44px;
  padding: 15px 20px;
  font: inherit;
  font-size: var(--text-17);
  color: var(--color-text);
  background-color: var(--color-card);
  /* Transparante rustgrens reserveert ruimte voor focus en fout. */
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  box-shadow: none;
  transition: border-color var(--dur-fast) var(--curve-decel), box-shadow var(--dur-fast) var(--curve-decel);
}
:where(
  input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"], [type="color"], [type="submit"], [type="button"], [type="reset"]):focus,
  select:focus,
  textarea:focus
) {
  outline: none;
  border-color: var(--color-text);
  box-shadow: var(--veld-focus-ring);
}

/* Veldlabel in zinsvorm (veldmodel 2026-09-01): muted 13px — uppercase is de taal
   van een sectiekop, en een veldlabel is dat niet. */
/* Veldlabel (ontwerp 2026-09-26): boven het veld, 15/500 in inkt; tussen label en veld 8px.
   Het label begint op de lijn van de tekst in de pil (20px), niet op de rand — op 4px stak
   het uit (feedback Jerry 2026-09-26). */
.form__label,
.field__label { padding: 0 20px; font-size: var(--text-15); font-weight: 500; color: var(--color-text); }

/* Gedeelde invoer: grijs, 17px, transparante rustgrens; inkt bij focus, rood bij fout. */
.form__input,
.form__input--textarea,
.plan-field,
.plan-textarea,
.agenda-form__when-input {
  width: 100%;
  min-height: 52px;
  box-sizing: border-box;
  padding: 15px 20px;
  font: inherit;
  font-size: var(--text-17);
  color: var(--color-text);
  background-color: var(--color-card);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  box-shadow: none;
  transition: border-color var(--dur-fast) var(--curve-decel),
              box-shadow var(--dur-fast) var(--curve-decel);
}

.form__input::placeholder,
.form__input--textarea::placeholder,
.plan-field::placeholder,
.plan-textarea::placeholder { color: var(--color-faint); }

.form__input:focus,
.form__input--textarea:focus,
.plan-field:focus,
.plan-textarea:focus,
.agenda-form__when-input:focus-visible {
  outline: none;
  border-color: var(--color-text);
  box-shadow: var(--veld-focus-ring);
}

/* Het label staat boven het veld, ook in een sheet (ontwerp 2026-09-26; vervangt het label in
   de rand). Bij een fout blijft het label inkt: de rode rand en de regel eronder zeggen genoeg. */
textarea.form__input, textarea.plan-textarea { border-radius: var(--radius-textarea); }
/* Een datumkiezer onder een veldlabel is gewoon een veld: dezelfde witte pil als de
   tekstvelden (Ouders & kinderen, contactformulier). De tijd van een wisselmoment ook
   (prototype: "Hoe laat" als veld). */
.form__row button.datecal__display.datecal__display--plain {
  width: 100%; min-height: 52px; padding: 15px 20px;
  background: var(--color-card); border: 1px solid transparent; border-radius: var(--radius-pill);
  font-size: var(--text-17);
}

/* Fout: de enige rand die een veld in rust draagt. Staat als .is-fout op het veld zelf en
   niet als .form__input--modifier, want élke veldvorm kan fout staan — een kiezer-knop en
   een .plan-field net zo goed als een .form__input (veldfout.js + BlincoFormBuilder zetten
   hem, en die kennen de vorm niet). */
.is-fout,
.is-fout:focus { border-color: var(--color-error); box-shadow: none; }
/* flex-basis 100%: valt de regel binnen een flex-rij (een veld met een €-teken ernaast),
   dan zakt hij naar zijn eigen regel in plaats van naast het veld te gaan staan. Buiten een
   flex-container doet de declaratie niets. */
.veld-fout { margin: 6px 2px 0; font-size: var(--text-sm); color: var(--color-error); line-height: var(--leading); flex: 1 0 100%; }
.veld-hint { margin: 6px 2px 0; font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); }
/* Wat géén veld heeft, staat bovenaan het formulier: fouten op het geheel (:base) en
   fouten van een record dat hier geen invulveld kent. Alles wat wél een veld heeft staat
   ónder dat veld (.veld-fout) — een samenvatting daarvan zou dezelfde fout twee keer tonen.
   Verving .account-section__alert, .form__errors, .mail-compose__errors en
   .agenda-form__errors (2026-09-12): vier vormen voor één melding. */
.form-fouten {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-groep);
  background: var(--color-error-soft);
  color: var(--color-error-deep);
  font-size: var(--text-sm);
  line-height: var(--leading);
}
.form-fouten p { margin: 0; }
.form-fouten p + p { margin-top: 4px; }
/* Staat er een kennisbank-vraagteken aan het eind van de hint, dan hangt het aan de tekst
   (dezelfde uitlijning als naast een kop — zie .plan-ouders__vraag). */
.veld-hint .knowledge-btn { vertical-align: middle; margin-left: 2px; }

.form__input--select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  cursor: pointer;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 20px center;
  background-size: 12px 12px;
}

/* Textarea: hoger, verticaal schaalbaar; geen pil maar 24px rond. */
.form__input--textarea {
  min-height: 88px;
  padding: 16px 20px;
  border-radius: var(--radius-textarea);
  line-height: var(--leading);
  resize: vertical;
}

/* Veld dat geen veld is maar een doorgang (profiel → e-mail wijzigen, 2026-09-03):
   een <a> die de gedeelde veldvorm draagt. Dezelfde witte vorm en hoogte als de velden
   eromheen, zodat de kolom niet verspringt, met de gedeelde .setrow__chevron als enige
   verschil — die zegt "hier gaat het verder". Geen eigen class: het element zélf is het
   onderscheid, net als bij button.datecal__display--plain. */
a.form__input {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  color: var(--color-text);
  text-decoration: none;
}
a.form__input > span { overflow-wrap: break-word; }

/* Twee velden op één regel (postcode + plaats). Een adres opknippen uit één vrije regel
   is raden; twee echte velden naast elkaar kosten geen regel extra en raden niets. */
.form__paar { display: flex; gap: 10px; }
.form__paar > :first-child { flex: 0 0 128px; }
.form__paar > :last-child { flex: 1; min-width: 0; }

.form__input--small { min-height: 44px; }

.form__input:disabled,
.form__input--select:disabled { opacity: 0.6; cursor: not-allowed; }

/* ===================== MIJN GEZINNEN-HUB ===================== */
/* Overzicht van de gezinnen van de ingelogde ouder: paginakop met "nieuw gezin",
   daaronder klikbare gezin-kaarten (BeNice-achtig: icoon · naam/status · chevron,
   met leden + uitnodig-badge). Zelfde content-breedte als de instellingen-hub. */
.container.gezinnen { max-width: 880px; }

.gezinnen__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}

.gezinnen__title {
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text);
}

.gezinnen__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* De kaart is één grote link: hele rij klikbaar, hover als zachte lift. */
.gezin-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color var(--dur-fast) var(--curve-decel),
              box-shadow var(--dur-fast) var(--curve-decel);
}
.gezin-card:hover {
  border-color: var(--color-text);
  box-shadow: none;
}

.gezin-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.gezin-card__head > .icon {
  flex: none;
  width: 28px;
  height: 28px;
  color: var(--color-text);
}
.gezin-card__titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}
.gezin-card__name { font-weight: var(--weight-medium); }
.gezin-card__status { font-size: var(--text-sm); color: var(--color-text-muted); }
.gezin-card__chevron {
  flex: none;
  width: var(--icon);
  height: var(--icon);
  color: var(--color-text-muted);
  transform: rotate(180deg); /* chevrons-icoon wijst links; hier vooruit */
}

.gezin-card__members {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.gezin-card__member {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  background: var(--color-hover);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
}
/* Status-pill (BeNice-achtig warm geel → bij ons Manilla): uitnodiging onderweg /
   actie nodig. De action-variant kleurt accent zodat hij als uitnodiging-CTA leest. */
.gezin-card__badge {
  font-size: var(--text-sm);
  background: var(--color-panel);
  color: var(--color-text);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
}
.gezin-card__badge--action {
  background: var(--color-surface-own);
  color: var(--color-accent);
  font-weight: var(--weight-medium);
}

/* ===================== SCHERMKOP (full-bleed top-level schermen) =====================
   In-body kop die de app-topbar vervangt op de full-bleed schermen: serif-titel links,
   kebab (Instellingen/Uitloggen) rechts. Ontwerp: elke pagina draagt zijn eigen kop. */
.screen-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-top: calc(8px + env(safe-area-inset-top, 0px));
  margin-bottom: 12px;
  /* Vaste hoogte, ook zonder actieknop of avatar (feedback 2026-09-04): de rij werd
     anders zo hoog als de titel (31px) i.p.v. de 44px-knop, en dan stonden titel én
     tabbalk op de Assistent-tab hoger dan op Chat en Mail. De maat is de padding plus de
     44px-knop; min-height rekent binnen de border-box, dus de padding telt mee. */
  min-height: calc(8px + 44px + env(safe-area-inset-top, 0px));
}
.screen-head__title {
  /* Neemt de ruimte die de acties overlaten (flex: 1) en mag krimpen (min-width: 0):
     zo krijgt de titelknop (.screen-head__pick, max-width: 100%) een echte maat en kapt
     hij pas af als de naam écht niet past — niet al bij "Postvak IN" (2026-09-05). */
  flex: 1;
  min-width: 0;
  padding-left: 4px;
  /* Paginatitel (lichte stijl): 30/600, -0,6px — dezelfde als .vnav__pagetitle. */
  font-size: var(--text-30);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: var(--leading-kop);
  color: var(--color-text);
}
.screen-head__actions { display: flex; align-items: center; gap: 8px; }
/* Titel als keuze (navigatie-opdracht 2026-09-05, stap 4): "Postvak IN ▾" opent de
   postvak-sheet. Knop erft de titelopmaak; alleen bij aanraken een zacht vlak. */
.screen-head__pick {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 100%;
  margin-left: -2px;
  padding: 2px 8px 2px 2px;
  border: 0;
  border-radius: var(--radius-groep);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.screen-head__pick > span { overflow-wrap: break-word; }
.screen-head__pick-icon { flex: none; width: var(--icon-sm); height: var(--icon-sm); margin-top: 3px; color: var(--color-faint); }
/* De kebab is mobiel; op desktop verzorgt de sidebar instellingen/uitloggen. */
@media (min-width: 768px) { .screen-head .dropdown:not(.dropdown--keuze) { display: none; } }

/* De Gesprekken-home is de Contact-hub geworden (contact.css) — die draagt .page en
   zet zijn eigen --page-max. */
.app-topbar + .screen-head { padding-top: 0; }

/* ===================== APP-HEADER (navigatie-opdracht 2026-09-05) ===================== */
/* Hamburger links (opent de lade), woordmerk ernaast, bel rechts. Staat op élke
   bestemming uit de lade — topniveau, geen terug-pijl. De avatar is verdwenen: je account
   staat onderin de lade. Bij meer dan één gezin komt de gezinsnaam naast het logo. */
.app-topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  align-self: stretch;
  width: 100%;
  /* 8px van de bovenrand (feedback 2026-09-15: de bel zat er tegenaan). */
  padding-top: calc(8px + env(safe-area-inset-top, 0px));
  /* 18px tussen de kop-rij en wat eronder komt — één waarde, één plek, zodat élke
     bestemming hetzelfde ritme heeft (feedback Jerry 2026-09-03). */
  margin-bottom: 18px;
}
/* De safe-area-verdeling (topbar vs. container) loopt via de :has()-regel bij .page
   bovenin dit bestand — geen handmatige reset-lijst per container meer. */
/* Rooster van een clublidmaatschap (2026-09-19): één blok per moment — de weekdag als
   strip van zeven, daaronder Van → Tot naast elkaar (.agenda-form__when, gedeeld met het
   afspraakformulier). Meerdere blokken, want een kind traint vaak twee of drie keer per
   week; de vorige versie had één dag en zette Van en Tot onder elkaar. */
.lidmoment { display: flex; flex-direction: column; gap: var(--space-2); }
.lidmoment__rij {
  padding: 8px 12px;
  background: var(--color-panel);
  border-radius: var(--radius-groep);
}
/* De tijden staan al in een eigen blok; de royale agenda-padding maakt het hier hol. */
.lidmoment__rij .agenda-form__when { padding: 2px 0 0; }
/* Medicatie/allergie-rijen dragen tekstvelden i.p.v. tijden: die moeten binnen het blok
   blijven (border-box, anders duwt de eigen padding ze eruit) en onder elkaar lucht houden. */
.lidmoment__rij .agenda-form__fieldinput {
  width: 100%;
  box-sizing: border-box;
  margin-top: 6px;
}
.lidmoment__kop .lidmoment__naam { flex: 1; min-width: 0; margin-top: 0; font-weight: 500; }
.lidmoment__kop { display: flex; align-items: center; gap: 8px; }
.lidmoment__dagen { flex: 1; min-width: 0; display: flex; gap: 4px; }
.lidmoment__dag {
  flex: 1 1 0;
  min-width: 0;
  min-height: 32px;
  padding: 0 2px;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 500;
  cursor: pointer;
}
.lidmoment__dag.is-selected { background: var(--color-btn); color: var(--color-on-btn); }
.lidmoment__weg {
  flex: none;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--color-faint);
  cursor: pointer;
}
.lidmoment__weg .icon { width: var(--icon-sm); height: var(--icon-sm); }
.lidmoment__toevoegen {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--color-accent);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
}
.lidmoment__toevoegen .icon { width: var(--icon-sm); height: var(--icon-sm); }

/* Kop-knoppen (lichte stijl, `Blinco mobiel - licht.dc.html`, 2026-09-26): een witte cirkel
   van 48px met het icoon in inkt — ook het noodkaart-schild. Wit is de laag "erboven" op de
   grijze grond. Geen terugtrek-marge meer: de cirkel is zelf de vorm. */
.app-topbar__menu, .app-topbar__bell {
  position: relative;
  flex: none;
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;

  box-shadow: var(--shadow-rond);
}
.app-topbar__menu .icon { width: var(--icon-lg); height: var(--icon-lg); }
.app-topbar__bell svg { width: var(--icon); height: var(--icon); }
.app-topbar__brand { flex: 1; min-width: 0; display: flex; align-items: center; gap: 11px; }
.app-topbar__nood { margin-right: -2px; } /* 8px tussen schild en bel (gap 10) */
/* Woordmerk in de kop: 22px (lichte stijl). */
.app-topbar__brand .blinco-logo { flex: none; font-size: var(--text-22); }
.app-topbar__divider { flex: none; width: 1px; height: 16px; background: var(--color-line); }
.app-topbar__gezin {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-muted);
  overflow-wrap: break-word;
}
/* Ongelezen-stip rechtsboven op de bel: 9px inkt met een 2px rand in de paginakleur.
   De hamburger draagt dezelfde stip als er ongelezen post of chat in de lade zit
   (2026-09-18) — de lade is altijd dicht, dus de teller op die rijen was onzichtbaar. */
.app-topbar__bell--unread::after,
.app-topbar__menu--unread::after {
  content: "";
  position: absolute;
  top: 12px;
  right: 13px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-btn);
  border: 2px solid var(--color-surface);
}
/* Desktop: de vaste sidebar staat in de flow, de lade bestaat daar niet. */
@media (min-width: 768px) { .app-topbar__menu { display: none; } }
/* Scherm-acties in de titelrij van een bestemming (shared/_vnav, topniveau): dezelfde
   knop als in een terug-kop, maar hier 44px borderloos in de inkt — de titelrij staat
   naast de app-header en volgt die knopvorm (zoeken, ⋯), niet de 36px-cirkel van een
   subscherm. */
.screen-head__actions .vnav__action:last-child { margin-right: -8px; }
/* De assistent-chat is een flex-kolom zonder zijinzet: de app-header krijgt daar zijn
   eigen gutter en geen ondermarge (de sessiekop sluit er direct op aan). */
.coach-top { flex: none; padding: 0 var(--page-gutter); }
.coach-top > .app-topbar { margin-bottom: 0; }

/* ===================== LADE (navigatie-opdracht 2026-09-05) ===================== */
/* De ene navigatielaag: 304px van links, scrim erachter, --color-surface als ondergrond.
   Kop in --color-panel met woordmerk + gezinsnaam; scrollende lijst van rijen (≥48px) in
   vier groepen gescheiden door --color-hair; vast onderin Ons gezin en je account. */
.lade { position: fixed; inset: 0; z-index: 60; }
.lade[hidden] { display: none; }
.lade__scrim {
  position: absolute;
  inset: 0;
  background: var(--color-scrim);
  opacity: 0;
  transition: opacity 0.2s ease;
}
/* Lichte stijl (2026-09-26, bron `Blinco mobiel - licht.dc.html`, LADE): 84% breed tot 330px,
   ondergrond --color-drawer, geen schaduw — de scrim zet het paneel af. */
.lade__panel {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 84%;
  max-width: 330px;
  display: flex;
  flex-direction: column;
  background: var(--color-drawer);
  transform: translateX(-100%);
  transition: transform 0.26s cubic-bezier(0.2, 0.8, 0.25, 1);
}
.lade--open .lade__scrim { opacity: 1; }
.lade--open .lade__panel { transform: translateX(0); }
.lade__head {
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: calc(22px + env(safe-area-inset-top, 0px)) 20px 10px 26px;
}
/* Woordmerk op 30px met -1px, gezinsnaam eronder op 15 in muted. */
.lade__brand .blinco-logo { font-size: var(--text-30); letter-spacing: -0.033em; }
.lade__gezin {
  font-size: var(--text-15);
  color: var(--color-text-muted);
  overflow-wrap: break-word;
}
.lade__list { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 12px; }
/* Boven en onder vervagen de rijen zacht in plaats van hard af te snijden (Jerry 2026-10-09). */
.lade__list {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--space-5), #000 calc(100% - var(--space-5)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--space-5), #000 calc(100% - var(--space-5)), transparent 100%);
}
/* Potlood rechtsboven naast het logo; in bewerkstand "Klaar" in de merkkleur. */
.lade__aanpassen {
  position: absolute;
  top: calc(14px + env(safe-area-inset-top, 0px));
  right: 12px;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  border: 0;
  border-radius: var(--radius-pill);
  background: none;
  color: var(--color-text);
  font-size: var(--text-15);
  font-weight: 500;
  cursor: pointer;
}
.lade__aanpassen-icon { width: var(--icon); height: var(--icon); }
.lade__aanpassen-klaar { display: none; color: var(--color-accent); }
.lade--bewerken .lade__aanpassen-icon { display: none; }
.lade--bewerken .lade__aanpassen-klaar { display: inline; }
/* Rij: 52px hoog, 14px rond, icoon 22 in inkt, label 18/500. Actief = een vlak in
   --color-selected; het gewicht verandert niet. */
.lade__row {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 52px;
  padding: 0 14px;
  border-radius: var(--radius-veld-plan);
  color: var(--color-text);
  font-size: var(--text-lg);
  font-weight: 500;
  letter-spacing: -0.01em;
  text-decoration: none;
}
.lade__row:active,
.lade__row--active { background: var(--color-selected); }
.lade__icon { flex: none; width: var(--icon-lg); height: var(--icon-lg); color: var(--color-text); }
.lade__label { flex: 1; min-width: 0; overflow-wrap: break-word; }
/* Volgorde aanpassen (E2, 2026-09-18). De greep hangt in elke rij maar is er alleen in de
   bewerkstand; `touch-action: none` houdt het slepen bij de vinger in plaats van bij de
   scroller. Home heeft geen greep — die rij staat vast. */
.lade__greep {
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin-right: -8px;
  border: 0;
  background: none;
  color: var(--color-faint);
  cursor: grab;
  touch-action: none;
}
.lade__greep-icon { width: var(--icon-sm); height: var(--icon-sm); }
.lade--bewerken .lade__greep { display: inline-flex; }
/* Tijdens het slepen: de rij licht op en volgt de vinger, de rest schuift eronder door. */
.lade--bewerken .lade__row--pakt {
  background: var(--color-surface);
  box-shadow: var(--shadow-rond);
  cursor: grabbing;
}
/* In bewerkstand is een rij geen bestemming meer: geen actief-vlak dat een plek belooft. */
.lade--bewerken .lade__row--active { background: none; }
/* Herstellen onder de lijst, alleen in bewerkstand, in de merkkleur. */
.lade__bewerkbalk { display: none; }
.lade--bewerken .lade__bewerkbalk { display: flex; align-items: center; justify-content: space-between; padding: 0 12px; }
.lade__bewerkknop {
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  background: none;
  color: var(--color-text-muted);
  font-size: var(--text-15);
  text-align: left;
  cursor: pointer;
}
.lade__bewerkknop--herstel { display: none; }
.lade--bewerken .lade__bewerkknop { color: var(--color-accent); font-weight: 500; }
.lade--bewerken .lade__bewerkknop--herstel { display: inline-flex; align-items: center; }
/* Ongelezen: een stip van 9px in het accent, rechts in de rij. */
.lade__stip { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--color-accent); }
/* Onderaan: "Ons gezin" vast (nooit onder de vouw) en daaronder je account als rij: avatar
   op de plek van het icoon, dan je naam (testronde B1). */
.lade__foot {
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px calc(24px + env(safe-area-inset-bottom, 0px));
}
.lade__avatar {
  flex: none;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-btn);
  color: var(--color-on-btn);
  font-size: var(--text-sm);
  font-weight: 500;
  overflow: hidden;
}
/* De avatar is breder dan een icoon: trek hem iets naar links zodat de naam gelijk staat. */
.lade__row--account { padding-left: 10px; gap: 10px; }
@media (min-width: 768px) { .lade { display: none; } }

/* Zoekveld (placeholder) bovenaan — zacht afgeronde rechthoek (ontwerp): 16px radius,
   warme hairline. Gedeeld door de Gesprekken- en Gezin-zoekbalk (DRY). */
/* Eén rij in één vlak (bron 2026-09-03): het veld erin is naakt, het vlak draagt de
   vorm. Stond eerder als veld-in-een-veld met een eigen rand en kaartradius, en
   bóven de tabs — hij hoort eronder, waar hij de lijst filtert die hij doorzoekt. */
.conversation-search {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
  padding: 11px 14px;
  background: var(--color-card);
  border: 0;
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-vlak);
}
/* Het hidden-attribuut moet de display:flex hierboven kunnen overrulen (class+attribuut
   wint van de class-only regel) — anders blijft de zoekbalk altijd zichtbaar. */
.conversation-search[hidden] { display: none; }
.conversation-search__icon { flex: none; color: var(--color-text-muted); display: grid; place-items: center; }
.conversation-search__icon .icon { width: var(--icon); height: var(--icon); }
/* Naakt veld IN een vlak: het vlak draagt de vorm, het veld niets. `border: 0` en
   `background: none` alleen zijn niet genoeg — de gedeelde veldbasis
   (`:where(input, select, textarea)`) geeft élk veld ook een lift en een radius, en die
   blijven staan als je ze niet expliciet uitzet. Dat gaf hier een veld-in-een-veld
   (bron 2026-09-03), en eerder al een zwevend schaduwplaatje in een rij. */
.conversation-search__input {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
  font-family: var(--font-body);
  font-size: var(--text-17);
  color: var(--color-text);
}
.conversation-search__input::placeholder { color: var(--color-text-muted); }
.conversation-search__input:focus { outline: none; }
/* Sluiten als tekst: een native zoekveld kan al een kruisje voor wissen tonen.
   De bestaande classnaam blijft behouden; deze actie sluit de zoekmodus. */
.conversation-search__clear {
  flex: none;
  display: grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text-muted);
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: var(--leading);
  white-space: nowrap;
  cursor: pointer;
}

/* De gesprekkenlijst zelf (feed, sectielabel, gezin-/coach-/invite-rij) is verhuisd naar
   contact.css: sinds de Contact-hub (handoff "Mail - UX ontwerp" 2026-08-16) zijn dat
   .listrow / .contact-section / .contact-invite binnen een .contact-card. Alleen de
   zoekbalk hierboven bleef staan. */

/* ===================== GEZINSINFO (DP9) ===================== */
/* Tegel-pagina voor praktische gezinsinformatie: kinderen + categorie-tegels +
   mutatie-log. Tegel-grid: 2 kolommen mobiel { max-width: 640px; }

/* Agreement-specialisaties (reis-/medische toestemming): één gedeeld blok.
   Disclaimer = prominente kanttekening (onderlinge afspraak, geen officieel
   document) — zacht koraal-vlak + accentlijn links, bij lijst én formulier. */
.consents__disclaimer {
  margin: 16px 0 18px;
  padding: 13px 15px;
  font-size: var(--text-15);
  line-height: var(--leading);
  color: var(--color-text);
  background: var(--color-card);
  border-radius: var(--radius-groep);
}

/* ChatGPT-stijl (2026-09-29): de toestemmingen als groep rijen — elk een grijs vlak, 3px
   ertussen, 26px buitenhoek. */
.consents {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  border-radius: var(--radius-groep);
  overflow: hidden;
}

.consents__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: 14px 20px;
  border-radius: var(--radius-binnen);
  background: var(--color-card);
}

.consents__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

.consents__primary { font-size: var(--text-17); }
.consents__secondary { font-size: var(--text-15); color: var(--color-text-muted); }

.consents__meta,
.consents__status {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-15);
  color: var(--color-text-muted);
}

/* Vervaldatum op een document: pill alleen als het urgent is (verlopen /
   verloopt binnenkort); een verre datum staat rustig in de meta-regel. */
.doclist__expiry {
  font-size: var(--text-sm);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}

.doclist__expiry--soon {
  background: var(--color-surface-own);
  color: var(--color-accent);
  font-weight: var(--weight-medium);
}

.doclist__expiry--expired {
  background: rgba(191, 77, 67, 0.12); /* --color-error op 12% */
  color: var(--color-error);
  font-weight: var(--weight-medium);
}

/* ===================== NOODKAART ===================== */
/* ChatGPT-stijl (prototype NOODKAART 2026-09-28): een gewone pagina met sectiekoppen en rijen
   (family/children/_waarde_rij). Eigen zijn alleen de soort boven de naam, de allergie-melding,
   112 en de voetregel. Bij printen verdwijnen de app-chrome en de knoppen (@media print). */
/* De kaart (I3, variant A): één vlak met een kop in inkt; de onderdelen erin. */
.noodkaart__kaart { margin-top: var(--space-2); border-radius: var(--radius-groep); background: var(--color-surface); overflow: hidden; box-shadow: var(--shadow-vlak); }
.noodkaart__kop { padding: 16px 18px 18px; background: var(--color-text); color: var(--color-bg); -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.noodkaart__kop-boven { display: flex; align-items: center; justify-content: space-between; }
.noodkaart__soort { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-sm); font-weight: 500; }
.noodkaart__soort svg { width: var(--icon-sm); height: var(--icon-sm); }
.noodkaart__merk .blinco-logo, .noodkaart__merk .blinco-logo__accent { color: var(--color-bg); font-size: var(--text-base); }
.noodkaart__held { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.noodkaart__avatar { flex: none; width: 54px; height: 54px; display: grid; place-items: center; border-radius: 50%; background: color-mix(in srgb, var(--color-bg) 18%, transparent); font-size: var(--text-22); font-weight: 500; }
.noodkaart__naam { margin: 0; font-size: var(--text-24); font-weight: 500; line-height: var(--leading-kop); }
.noodkaart__meta { margin: 3px 0 0; font-size: var(--text-sm); opacity: .8; }
.noodkaart__inhoud { padding: 2px 14px 14px; }
.noodkaart__allergie { display: flex; align-items: flex-start; gap: 12px; margin-top: 16px; padding: 14px 16px; border-radius: var(--radius-groep); background: var(--color-error-soft); }
.noodkaart__allergie > svg { flex: none; width: var(--icon); height: var(--icon); margin-top: 2px; color: var(--color-error); }
.noodkaart__allergie strong { display: block; font-size: var(--text-15); font-weight: 500; color: var(--color-error); }
.noodkaart__allergie span { font-size: var(--text-17); color: var(--color-error-deep); }
.noodkaart__112 { display: flex; align-items: center; min-height: 60px; margin: 24px 0 0; padding: 12px 20px; border-radius: var(--radius-groep); background: var(--color-error-soft); font-size: var(--text-17); font-weight: 500; color: var(--color-error); }
.noodkaart__gemaakt { margin: 12px 18px 0; font-size: var(--text-15); line-height: var(--leading); color: var(--color-text-muted); }

/* Printen: alleen de inhoud; app-chrome, knoppen en scroll-kaders weg. */
@media print {
  .sidebar, .app__topbar, .app-topbar, .flash,
  .dev-drawer, .dev-drawer__backdrop, .app__dev-toggle, .bottom-nav,
  .noodkaart .vnav, .noodkaart .setrow__bel, .noodkaart__beheer { display: none !important; }
  .app, .app__main, .app__body {
    display: block;
    height: auto;
    overflow: visible;
  }
  .noodkaart { padding: 0; }
  .noodkaart .vset__rows { break-inside: avoid; }
}

/* Fluent page-load — gedoseerde reveal van de instellingen-panels. */
@media (prefers-reduced-motion: no-preference) {
  .settings__panel {
    animation: settings-rise var(--dur-normal) var(--curve-decel) both;
    animation-delay: 100ms;
  }
}

@keyframes settings-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Sidebar: één Instellingen-doel per viewport — mobiel = hub-lijst. */
@media (max-width: 767px) {
  .sidebar__link--desktop-only { display: none; }
  /* Chat · Coach · Agenda staan mobiel in de bottom-nav; verberg ze hier zodat de
     off-canvas-sidebar het rustige 'meer'-menu blijft (Gezin + Instellingen). */
  .sidebar__group--desktop-only { display: none; }
  /* "Inklappen" is een desktop-functie (collapse werkt alleen ≥768px); op mobiel
     zinloos. Uitloggen blijft als enige in de (vastgezette) footer staan. */
  .sidebar__collapse { display: none; }
}

/* Paneel-inhoud — Fluent-surface: zachte elevatie i.p.v. alleen een platte rand,
   met een hairline-rand die de schaduw afzet tegen de warme bg. */
.settings__panel {
  border-color: var(--color-border);
  box-shadow: var(--shadow-vlak);
}
.settings-omgang .plan-afspraken { margin-top: 28px; }

/* ===================== ZORGVERDELING-HUB (instellingen/gezin/omgang, taak 3) =====
   Regeling-kaart + rijen-vensters i.p.v. acht blokken boven één knop (design 2026-07-23
   §1) — copy/vorm 1-op-1 uit de zorgverdeling-hub-mockup. Eigen kaart-
   recept (18px radius/warme schaduw) in een eigen naamruimte (los aanpasbaar); kleuren komen
   uit de bestaande tokens
   (--color-accent = mockup --accent, --color-coparent = --co, enz.) — geen nieuwe hexen. */
/* consistentie-sweep 2026-08-10: amber = wacht (status-kleurenfamilie, conventions §3) —
   was paars (co-ouder-kleur), een derde statusfamilie die de norm juist verbiedt. */
.omgang-hub__status { display: flex; justify-content: flex-end; margin: 6px 0 10px; }
/* Ingang-schakelaar (prototype 29 sep): uit = alleen de schakelrij (met alle hoeken rond),
   aan = de toevoeg-rij eronder in dezelfde groep. */
.omgang-hub__ingang > .omgang-hub__ingang-body { display: none; }
.omgang-hub__ingang:has(.omgang-hub__ingang-input:checked) .omgang-hub__ingang-body { display: flex; }
.omgang-hub__ingang:not(:has(.omgang-hub__ingang-input:checked)) > .setrow:first-child:has(.omgang-hub__ingang-input) {
  border-bottom-left-radius: var(--radius-groep); border-bottom-right-radius: var(--radius-groep);
}

/* ChatGPT-stijl (planbuilder-handout 2026-09-28): een grijs vlak met de ronde groepshoeken,
   geen schaduw — zelfde vorm als een groep rijen. */
.omgang-hub__card { background: var(--color-card); border-radius: var(--radius-groep); }
/* Rooster (prototype 29 sep): één grijze kaart, per kalenderweek een kop en zeven ronde dagen in
   de kleur van de ouder (jij = accent, de ander = inkt; rolkleur is data, conventions §3.3); een
   wisseldag is een halve cirkel van → naar. Haarlijn tussen de weken. */
.omgang-hub__reg { --stack-gap: 14px; padding: 16px 18px; cursor: pointer; }
.omgang-hub__reg--locked { cursor: default; }
.omgang-hub__week:not(:first-child) { padding-top: 14px; border-top: 1px solid var(--color-hair); }
.omgang-hub__week-kop { margin: 0 0 10px; font-size: var(--text-17); color: var(--color-text); }
.omgang-hub__week-datums { margin-left: 6px; font-size: var(--text-15); color: var(--color-text-muted); }
.omgang-hub__strip { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
/* Overdracht per wisselmoment: stip in de kleur van de ouder bij wie de kinderen komen. */
.omgang-hub__stip { flex: none; width: 10px; height: 10px; border-radius: 50%; }
.omgang-hub__stip--jij { background: var(--color-ouder-een); }
.omgang-hub__stip--co { background: var(--color-ouder-twee); }
.omgang-hub__naar { margin-left: 4px; color: var(--color-text-muted); }
.omgang-hub__legend { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin: 0 16px 10px; font-size: var(--text-15); color: var(--color-text); }
.omgang-hub__legend > span { display: inline-flex; align-items: center; }
.omgang-hub__legend-swatch { display: inline-block; width: 12px; height: 12px; border-radius: var(--radius-xs); margin-right: 6px; }
.omgang-hub__legend-swatch--jij { background: var(--color-accent); }
.omgang-hub__legend-swatch--co { background: var(--color-btn); }
.omgang-hub__legend-swatch--wissel { background: linear-gradient(90deg, var(--color-accent) 50%, var(--color-btn) 50%); }

.omgang-hub__refer {
  display: flex; gap: 12px; align-items: center; padding: 13px 14px; border-radius: var(--radius-groep); margin-bottom: 14px;
  background: var(--color-panel); border: 1px solid var(--color-line);
}
.omgang-hub__refer-icon { flex: none; width: var(--icon); height: var(--icon); color: var(--color-text-muted); font-size: var(--text-lg); }
.omgang-hub__refer-text { flex: 1; min-width: 0; }
.omgang-hub__refer p { font-size: var(--text-xs); line-height: var(--leading); color: var(--color-text-muted); }
.omgang-hub__refer a { flex: none; color: var(--color-accent); font-weight: 500; text-decoration: none; white-space: nowrap; font-size: var(--text-xs); }

/* Ritme-sheet: EditPatternFormComponent brengt zijn éigen <form> mee (render_submit:
   false), dus geen shared/_sheet form-variant (dat zou een tweede <form> nesten) — de
   knop staat aan het eind van de scrollende body, zelfde idioom als .sheet__save
   (StructuralExceptionFormComponent e.a.), form-attribuut-gekoppeld aan FORM_ID. */
.omgang-hub__ritme-save { margin-top: 16px; }
/* Eigen afspraken pas na de regeling (Jerry 2026-10-09): [hidden] moet de flex van .vset__rows verslaan. */
.omgang-hub__na-regeling[hidden] { display: none; }


/* Sectiekopje binnen een wijzigingsverzoek (design 2026-07-25 §2): bundelt wat bij elkaar
   hoort, zodat de tijd niet losgezongen naast de datum staat maar zichtbaar bij de
   overdracht. Lijn erachter i.p.v. een kader — het scheidt, het omsluit niet. */
/* Uitleg-regel onder de contextregel: die zegt wát je hier doet, de context zegt wáárover —
   dus kleiner en rustiger dan de context zelf. */
/* Verstuurknop uit zolang er niets is gewijzigd (agenda_overdracht_controller);
   de disabled-stijl komt van de .button-primitive. */

/* Samenvatting: de zin die de ander straks te lezen krijgt, apart gezet zodat je 'm vóór
   het versturen echt leest en niet tussen de velden kwijtraakt. Gedeeld door het
   overdracht- en het zorgformulier (Agenda::RequestSummaryComponent). */
.req-summary {
  margin: 4px 0 6px; padding: 13px 14px; border-radius: var(--radius-groep);
  background: var(--color-panel); /* het zachte vlak zonder rand (--soft in het ontwerp, §6) */
}
.req-summary__intro { margin: 0 0 8px; font-size: var(--text-xs); color: var(--color-text-muted); line-height: var(--leading); }
.req-summary__zin { margin: 0; font-size: var(--text-base); line-height: var(--leading); }
.req-summary__zin b { color: var(--color-accent); }
/* Nog-in-te-vullen deel van de zin: dezelfde rustige placeholder-taal als een lege kiezer
   (.is-empty) — muted en normaal gewicht, geen italic/semibold (design-feedback 2026-07-27). */
.req-summary__gap { color: var(--color-text-muted); font-weight: 400; font-size: var(--text-sm); }
.req-summary__note { margin: 7px 0 0; font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); }
.req-summary__note[hidden] { display: none; }

/* "Welke overdracht?" — kieslijst van komende wisselmomenten (design 2026-07-25 §9).
   Rij-vorm i.p.v. de .plan-choice-tegels: dit zijn geen soorten om uit te kiezen maar
   concrete momenten, dus datum en tijd voorop. */
/* Kieslijst van wisselmomenten (design-feedback 2026-07-27): rijen met een datum-tegel
   (dag-afkorting + dagnummer, zoals een kalendercel) i.p.v. een tekst-kolom met losse
   oranje tijd — tijd en plek staan samen in de subregel. Kaart blijft vlak (conventions). */
/* Rijen rechtstreeks op de sheet met een haarlijn — geen witte kaart met lift meer in een
   sheet (vlak-op-vlak, 2026-09-12); dezelfde vorm als .plan-choice. */
.pick-list { margin-bottom: 6px; }
.pick-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 2px;
  border-bottom: 1px solid var(--color-line); text-decoration: none; color: var(--color-text);
}
.pick-row:last-child { border-bottom: 0; }
/* Datumkolom van 42px zonder vlak (bron): dagnaam muted, dagnummer inkt — geen tegel, geen
   accent (accent is een tekstsignaal voor acties, geen datum of tijd). */
.pick-row__date {
  flex: none; width: 42px;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
}
.pick-row__dow { font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.pick-row__num { font-size: var(--text-base); font-weight: 500; line-height: var(--leading-kop); }
.pick-row__t { flex: 1; min-width: 0; }
.pick-row__who { display: block; font-size: var(--text-sm); font-weight: 500; }
.pick-row__sub { display: block; margin-top: 2px; font-size: var(--text-sm); color: var(--color-text-muted); }
.pick-row__chev { flex: none; width: var(--icon-sm); height: var(--icon-sm); color: var(--color-faint); }

/* Herinnering-keuzerij op het overdracht-detailscherm (design 2026-07-24 §7): dezelfde
   presets als de afspraak-editor, maar app-breed — de subregel zegt dat er expliciet bij. */
/* Herinnering-keuze op het overdracht-detail: leeft in de gedeelde keuzerij
   (shared/_keuzerij, agenda-form__opt*-chrome) — hier alleen nog de vorm-vrije delen. */

/* Historie — rustige, standaard-ingeklapte mutatie-log onderaan de zorg-editor. Bewust
   low-profile (niet prominent); open toont een compacte tijdlijn met avatar-initialen. */
/* Historie (prototype 29 sep): een rij "Wijzigingen" in een groep; open = de tijdlijn als
   tweede vlak in dezelfde groep. */
.histlog__summary { list-style: none; cursor: pointer; }
.histlog__summary::-webkit-details-marker { display: none; }
.histlog__summary::marker { content: ""; }
.histlog__chevron { transition: transform 0.2s var(--curve-decel, ease); }
.histlog[open] .histlog__chevron { transform: rotate(180deg); }
.histlog > .histlog__list { background: var(--color-card); border-radius: var(--radius-binnen) var(--radius-binnen) var(--radius-groep) var(--radius-groep); padding: 6px 20px; }
.histlog[open] > .histlog__summary { border-bottom-left-radius: var(--radius-binnen); border-bottom-right-radius: var(--radius-binnen); }
.histlog__list { list-style: none; margin: 0 0 10px; padding: 2px 0 0; display: flex; flex-direction: column; }
.histlog__entry { display: flex; align-items: flex-start; gap: 11px; padding: 9px 2px; }
.histlog__entry + .histlog__entry { border-top: 1px solid var(--color-border); }
.histlog__avatar {
  flex: none; width: 26px; height: 26px; margin-top: 1px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-panel); color: var(--color-text-muted, var(--cloud-dark));
  font-size: var(--text-xs); font-weight: 500;
}
.histlog__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.histlog__text { font-size: var(--text-sm); line-height: var(--leading); color: var(--color-text); }
.histlog__badge {
  display: inline-block; margin-left: 6px; vertical-align: 1px; color: var(--color-text-muted, var(--cloud-dark));
  font-size: var(--text-xs); font-weight: 500;
}
.histlog__meta { font-size: var(--text-xs); color: var(--color-faint, var(--cloud-medium)); }
/* Alleen de tussenruimte vóór de hint eronder — de titel zelf volgt de gewone
   .card__title-stijl, gelijk aan de kaarttitels van de andere twee secties op dit scherm. */
.settings__panel .card__title { margin-bottom: var(--space-4); }

/* Intro-/hint-tekst boven een instellingen-paneel + lege-staat. */
.settings__hint { color: var(--color-text-muted); font-size: var(--text-sm); margin: 0 0 var(--space-3); }

/* Zorgrooster: direct dagen wisselen, met een ouderstreepje en overdrachtsrijen eronder. */
.pattern-form { display: flex; flex-direction: column; }
/* De pattern-form-body erft de generieke .stack-ritmiek; de koppen zijn gewone sectiekoppen. */
/* Per kind (zorg-mockup v163): de kindkeuze als pillen — gekozen inkt (conventions §3.6, chips voor
   kindkeuze). [hidden] moet de display:flex van de pillen en van .stack (het rooster tot de keuze
   gemaakt is) verslaan. */
.pattern-form__tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.pattern-form__body :is(.pattern-form__tabs, .stack)[hidden] { display: none; }
/* Een groep in de editor knipt zijn eigen buitenhoeken (zoals in .plan-stack): een verborgen laatste
   rij (Eerste wisseldag) laat de rij erboven anders hoekig. Het keuzemenu staat in de top layer. */
.pattern-form .vset__rows { border-radius: var(--radius-groep); overflow: hidden; }
.pattern-form__tab {
  font: inherit; font-size: var(--text-15); font-weight: 500; min-height: 44px; overflow-wrap: anywhere;
  padding: 11px 18px; border-radius: var(--radius-pill); cursor: pointer;
  background: var(--color-card); color: var(--color-text); border: 1px solid transparent;
}
.pattern-form__tab--on { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
/* Schema als keuzerij, legenda buiten de kaart, weken met witte afgeronde dagtegels.
   De compacte leesweergave (.omgang-hub__day) behoudt haar eigen cirkels. */
.pattern-form__card { background: var(--color-card); border-radius: var(--radius-groep); padding: 22px 20px; }
/* De goedgekeurde zorgrooster-uitvoering: legenda + witte dagtegels met een ouderstreepje. */
.pattern-form__legend-item--jij, .pattern-form__legend-item--co { display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow-wrap: anywhere; font-size: var(--text-15); color: var(--color-text-muted); }
.pattern-form__legend-dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }
.pattern-form__legend-item--jij .pattern-form__legend-dot { background: var(--color-ouder-een); }
.pattern-form__legend-item--co .pattern-form__legend-dot { background: var(--color-ouder-twee); }
.pattern-form__hint { margin: 16px 0 0; font-size: var(--text-15); color: var(--color-text-muted); line-height: var(--leading); }
.pattern-form__weeks { --stack-gap: 28px; }
.pattern-form__week { padding: 0; border: 0; }
.pattern-form__week-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.pattern-form__week-nr { font-size: var(--text-17); color: var(--color-text); }
.pattern-form__week-dates { margin: 2px 0 16px; font-size: var(--text-15); color: var(--color-text-muted); }
.pattern-form__week-del {
  margin-left: auto; font: inherit; font-size: var(--text-15);
  color: var(--color-text-muted); background: none; border: none; padding: 0; min-height: 44px; cursor: pointer;
}
/* De week blijft één rij, ook op smalle telefoons; dagknoppen delen de beschikbare breedte. */
.pattern-form__week-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 3px; margin-inline: -14px; touch-action: auto; }
.omgang-hub__day {
  aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; padding: 0;
  font: inherit; font-size: var(--text-15); font-weight: 500; color: var(--color-on-btn); border: 0;
}
.pattern-form__day { container-type: inline-size; min-width: 0; min-height: 64px; padding: 10px 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; background: var(--color-surface); color: var(--color-text); border: 0; border-radius: var(--radius-rooster-dag); font-size: var(--text-15); font-weight: 400; cursor: pointer; }
/* Dagafkortingen schalen mee tot de beschikbare tegelbreedte; de rest van de tekst is onbegrensd. */
.pattern-form__day > span:first-child { font-size: min(var(--text-15), 75cqi); }
.pattern-form__day:active { background: var(--color-card-pressed); }
.pattern-form__day .pattern-form__legend-dot { width: 24px; height: 4px; border-radius: var(--radius-xs); }
.pattern-form__day--jij .pattern-form__legend-dot { background: var(--color-ouder-een); }
.pattern-form__day--co .pattern-form__legend-dot { background: var(--color-ouder-twee); }
.pattern-form__day--leeg .pattern-form__legend-dot { background: var(--color-line); }
.omgang-hub__day--jij { background: var(--color-ouder-een); }
.omgang-hub__day--co { background: var(--color-btn); }
.omgang-hub__day--wissel-jij-co { background: linear-gradient(90deg, var(--color-ouder-een) 50%, var(--color-btn) 50%); }
.omgang-hub__day--wissel-co-jij { background: linear-gradient(90deg, var(--color-btn) 50%, var(--color-ouder-een) 50%); }
/* Toevoegactie binnen de grijze roosterkaart: witte pil met tekst in inkt. */
.pattern-form__add-week {
  width: 100%; margin-top: 14px; padding: 14px;
  font: inherit; font-size: var(--text-17); color: var(--color-text);
  background: var(--color-surface); border: 0; border-radius: var(--radius-pill); cursor: pointer;
}
.pattern-form__add-week:disabled { color: var(--color-faint); cursor: default; }
.pattern-form__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pattern-form__chip {
  padding: 7px 12px; font: inherit; font-size: var(--text-sm); font-weight: 500;
  border: 1px solid var(--color-border); border-radius: var(--radius-pill);
  background: var(--color-surface); color: var(--color-text-muted); cursor: pointer;
}
.pattern-form__chip--on { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
.pattern__deviations { font-size: var(--text-sm); color: var(--color-text-muted); margin: var(--space-2) 0 0; }

/* Generieke radio-chip (DRY): "Voor wie"/"Wat verandert er"/"Die dag bij" delen deze
   recipe — een verborgen radio + has()-selector voor de geselecteerde staat. */
.chip-radio-group { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
/* In een veldblok (label + chips) draagt de groep geen eigen ondermarge: de container
   (.stack) deelt de ruimte uit, net als bij elk ander veld (2026-09-11). */
.zw-field > .chip-radio-group { margin-bottom: 0; }
/* Segment (Duur, wie brengt): pillen; de gekozen stand is inkt met witte tekst, de andere
   --card met --muted (Design 2026-09-08 — accent is nooit een gevuld vlak). */
.chip-radio { position: relative; font-size: var(--text-15); font-weight: 500; color: var(--color-text-muted); background: var(--color-card); border: 1px solid transparent; border-radius: var(--radius-pill); padding: 11px 14px; cursor: pointer; }
.chip-radio__input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip-radio:has(.chip-radio__input:checked),
.chip-radio[aria-current="true"] { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
/* Als link (kind-pillen in de agenda, M1): geen onderstreping. */
a.chip-radio { text-decoration: none; }
.chip-radio:has(.chip-radio__input:focus-visible) { outline: 2px solid var(--color-focus); outline-offset: 2px; }
/* Generieke inline tekst-link-knop (DRY): "Bewerken", "… toevoegen"-triggers. */
.link-edit { font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--color-accent); background: none; border: none; padding: 0; cursor: pointer; }

/* ── Eenmalige uitzonderingen (design "Uitzonderingen → Eenmalig") ── */
.exceptions { margin-top: 22px; }
/* Sub-kop van een uitzonderingen-blok ("Structureel" / "Eenmalig") — één gedeelde stijl
   (DRY, design: 14px/800), niet het display-font. */
.exceptions__title { font-size: var(--text-base); font-weight: 500; margin: 0 2px 4px; }
.exceptions__list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.exceptions__item {
  background: var(--color-card);
  border-radius: var(--radius-groep); padding: 12px 14px;
  box-shadow: var(--shadow-vlak);
}
.exceptions__label { display: block; font-size: var(--text-sm); font-weight: 500; }
.exceptions__note { display: block; font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 1px; }
.exceptions__actions { display: flex; align-items: center; gap: 14px; margin-top: 8px; }
.exceptions__delete {
  font: inherit; font-size: var(--text-sm); font-weight: 500; color: var(--color-error);
  background: none; border: none; padding: 0; cursor: pointer;
}
.exceptions__history { margin-top: 8px; font-size: var(--text-sm); color: var(--color-text-muted); }
.exceptions__history summary { cursor: pointer; }

/* Form (toevoegen/bewerken eenmalige uitzondering) — op de gedeelde sheet-primitives. */
.exception-form { display: flex; flex-direction: column; }

/* Knop-primitive — `.btn` (instellingen) en `.button` (gezinsprofiel)
   delen één definitie (DRY: zelfde primitive, twee historisch gegroeide namen). */
.btn,
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 var(--space-4);
  font: inherit;
  font-weight: var(--weight-medium);
  color: var(--color-on-btn);
  background: var(--color-btn);
  border: 1px solid transparent;
  /* Pil + eigen lift (kleurdelta V9.3 §3). Geen accent-gevulde knop meer: terracotta zat
     op vlakken, iconen, knoppen én tekst tegelijk en betekende daardoor niets meer. */
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-knop);
  text-decoration: none;
  cursor: pointer;
  appearance: none;
  transition: background var(--dur-fast) var(--curve-decel),
              border-color var(--dur-fast) var(--curve-decel),
              transform var(--dur-fast) var(--curve-decel);
}
.btn:hover, .button:hover { background: var(--color-text); }
/* Lichte stijl: indrukken = even kleiner (bron: scale .97). */
.btn:active, .button:active {
  transform: scale(0.97);
}
/* Zichtbaar disabled (bijv. "Foto's toevoegen" tot er iets gekozen is) — anders
   oogt een gevulde accent-knop bruikbaar terwijl hij dat niet is. */
.btn:disabled, .button:disabled {
  background: var(--color-faint);
  border-color: var(--color-faint);
  cursor: not-allowed;
}
/* Secundaire actie: grijze pil, inkt; gekozen/primaire actie blijft inkt gevuld. */
.button--secondary {
  color: var(--color-text);
  background: var(--color-card);
  border-color: transparent;
  box-shadow: none;
}
.button--secondary:hover { background: var(--color-card-pressed); }
:is(dialog.sheet, .confirm__box, .setrow--identity) .button--secondary { border-color: transparent; }
/* Kleurdelta V9.3 §5: de paarse knop is vervallen (class weg uit alle drie de views) —
   een gevulde knop is de primaire actie en die is warm zwart, ongeacht wie 'm aanbiedt.
   Groen blijft: akkoord geven is een handeling met een eigen betekenis. */
.button--green { background: var(--color-green); border-color: var(--color-green); }
.button--green:hover { background: var(--color-green); border-color: var(--color-green); opacity: 0.92; }
/* Compacte variant voor inline-acties (kind-rijen, snelkoppelingen). */
.button--small {
  min-height: 44px;
  padding: 0 var(--space-3);
  font-size: var(--text-15);
}
/* Terughoudende variant voor destructieve/zeldzame acties (kind verwijderen). */
.button--ghost {
  color: var(--color-text-muted);
  background: transparent;
  border-color: transparent;
  border-radius: var(--radius-pill);
  box-shadow: none;
}
.button--ghost:hover { background: var(--color-hover); color: var(--color-text); }
/* Destructieve tekstknop onder een formulier (kind verwijderen, club uitschrijven,
   2026-09-14): dezelfde rood als elke andere rode actie in de app (.sheetmenu__item--danger,
   .sheetmenu__item--danger, .vset__logout). De klasse stond al in de views, maar had geen regel — de
   knop was grijs. */
.button--ghost.button--danger, .button--ghost.button--danger svg { color: var(--color-error); }
.button--ghost.button--danger:hover { color: var(--color-error); }
/* Toevoeg-actie in een lijst-context ("+ Periode toevoegen", "+ Week toevoegen"): dashed
   kader + accent-tekst. Bestond 3× als feature-eigen variant met nét andere randkleuren
   (consistentie-sweep 2026-08-10) — dít is de ene primitive; zie /dev/stijlgids. */
.button--dashed {
  gap: 6px;
  color: var(--color-text);
  background: var(--color-card);
  border: 0;
  border-radius: var(--radius-pill);
  box-shadow: none;
}
.button--dashed:hover { background: var(--color-card-pressed); border-color: var(--color-line); color: var(--color-text); }
.button--dashed:disabled { background: transparent; color: var(--color-faint); border-color: var(--color-line); }

.alert {
  padding: var(--space-3);
  border-radius: var(--radius);
  background: rgba(191, 77, 67, 0.08);
  color: var(--color-error);
  font-size: var(--text-sm);
}

/* ===================== INFOBOX =====================
   Dé uitleg-/let-op-box van de app. Vervangt acht bijna-identieke feature-eigen
   varianten (backup-pw__note, noodkaart__hint, sheetmenu__info, fotoboek-privatehint,
   fotoboek-form__note, consent-sign__note, afspraak-form__note, plan-intake__hint) die
   in twee verschillende neutrale tinten én twee keer in paars stonden.

   Kleur draagt betekenis, dus er zijn maar drie varianten:
   - standaard = neutrale uitleg (zacht zand, de accent-tint van de app);
   - --warning = pas op, dit kan tegen je werken (amber, de "actie nodig"-familie);
   - --coparent = dit gaat over de ándere ouder (paars). Paars is voor niets anders;
     een generieke uitleg in paars leest als co-ouder-informatie en dat is 'ie niet.
   Rood blijft .alert (een fout, geen uitleg). */
.infobox {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: var(--space-4) 0;
  padding: 22px 20px;
  border-radius: var(--radius-groep);
  background: var(--color-card);
  color: var(--color-text-muted);
  font-size: var(--text-base);
  line-height: var(--leading);
}
/* Het icoon mag als kale svg meekomen (shared/_icon zonder klass) of met .infobox__icon. */
/* .infobox__icon vooraan: de icoon-maat-guardrail (style_consistency_test) matcht op regelbegin. */
.infobox__icon, .infobox > svg { flex: none; width: var(--icon); height: var(--icon); margin-top: 1px; }
.infobox p { margin: 0; }
.infobox--warning { background: var(--color-amber-soft); color: var(--color-amber-deep); }
.infobox--coparent { background: var(--color-coparent-soft); color: var(--color-coparent-deep); }
/* --geregeld = jullie zijn het hierover eens (groen, planbuilder-handout 2026-09-28): het vinkje
   in een groene cirkel, de titel in groen, eventueel een gedempte regel eronder. */
.infobox--geregeld { gap: 11px; padding: 13px 15px; border-radius: var(--radius-groep); background: var(--color-green-soft); }
.infobox--geregeld > svg { box-sizing: border-box; width: var(--space-6); height: var(--space-6); padding: 5px; border-radius: 50%; background: var(--color-green); color: var(--color-on-accent); }
.infobox--geregeld strong { display: block; margin-bottom: 2px; font-size: var(--text-15); font-weight: 500; color: var(--color-green-deep); }
/* Binnen een sheet-menu of direct onder een veld staat de box strak tegen z'n context aan. */
.infobox--tight { margin: 4px 0 0; }

/* ===================== BLINCO WOORDMERK ===================== */
/* Self-hosted letters (AVG: NIET via Google's CDN — dat lekt het bezoeker-IP). De woff2's
   staan in app/assets/fonts/; Propshaft herschrijft de url() naar het gedigeste /assets-pad.
   Beide onder de SIL Open Font License, latin-subset.

   Hanken Grotesk is één variabel bestand met de hele gewichtsas. Het is de enige letter
   (design system 2026-09-26): koppen onderscheiden zich door gewicht en letterspatiëring. */
@font-face {
  font-family: "Hanken Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/hankengrotesk-var-19e35a88.woff2") format("woff2");
}

/* Woordmerk "blinCo" via één shared/_logo-partial: gezette tekst, geen beeldmerk. "blin" in
   inkt, "Co" in accent, 600 met -0,5px op 22px (design system 2026-09-26). */
.blinco-logo {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.023em;
  color: var(--logo-ink);
  line-height: 1;
  font-size: 1.75rem;
  white-space: nowrap;
  user-select: none;
}
.blinco-logo__accent { color: var(--color-accent); }
.blinco-logo--inverse { color: var(--color-on-accent); }
.blinco-logo--inverse .blinco-logo__accent { color: var(--logo-inverse-accent); }

/* Formaat per plek (alles schaalt mee met font-size). */
.sidebar__brand .blinco-logo { font-size: 1.35rem; }
.app__topbar-title .blinco-logo { font-size: 1.3rem; }
.auth__brand .blinco-logo { font-size: 1.5rem; }

/* ===================== CONTACTEN (scherm 10/11) =====================
   Full-bleed naar het ontwerp: eigen kop (terug ‹ Gezin · titel · "+"), witte zoek-pill,
   gekleurde categorie-groepen, per-rij bel-knop, doorklik naar het contactdetail. */
/* .contacts/.contact-detail: paginageometrie via de gedeelde .page-regel. */

/* ChatGPT-stijl (prototype CONTACTEN 2026-09-28): de zoekregel is een grijze pil van 52px. */
.contacts__search {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 52px;
  background: var(--color-card);
  border-radius: var(--radius-pill);
  padding: 0 18px;
}
.contacts__search-icon { width: var(--icon); height: var(--icon); color: var(--color-faint); flex: none; }
.contacts__search-input { flex: 1; min-width: 0; border: none; outline: none; background: none; font: inherit; font-size: var(--text-17); color: var(--color-text); }

/* ===================== BOTTOM-SHEET (generiek, DRY) =====================
   Native <dialog> die van onderen opkomt met ronde bovenkant. Hergebruikt voor
   "Nieuw contact", "Nieuwe afspraak", … (shared/_sheet + sheet-controller). */
dialog.sheet {
  /* Onderaan vastgeplakt via position:fixed — betrouwbaarder dan `margin:auto auto 0`,
     dat op sommige mobiele browsers (Samsung Internet) de modal toch centreert. */
  position: fixed;
  inset: auto 0 0 0;
  margin: 0 auto;
  width: 100%;
  max-width: 520px;
  max-height: 92vh;           /* fallback; content-hoog → de body scrollt */
  max-height: 88dvh;          /* dynamische viewport + topmarge: kop niet achter de mobiele browserbalk */
  padding: 0;
  border: none;
  border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
  /* Lichte stijl (2026-09-26): een sheet ligt bovenop de pagina en is dus wit; de scrim
     zet hem af, een schaduw is niet nodig. */
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: none;
  overflow: hidden;
}
/* Alleen geopend zichtbaar — een gesloten <dialog> blijft via de UA-default display:none.
   (display NIET op de basisregel zetten, anders staat de sheet altijd open.) */
dialog.sheet[open] {
  display: flex;
  flex-direction: column;
  animation: sheet-up 0.34s cubic-bezier(0.32, 0.72, 0, 1);
}
dialog.sheet::backdrop { background: var(--color-scrim); }
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* Geen lijn onder de titel (2026-09-10): de kop is geen balk maar de aanhef van wat eronder
   staat. Sommige sheets hadden 'm wel en andere niet. */
.sheet__head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 22px 8px;
}
/* min-width:0 + overflow:hidden: een flex-item krimpt standaard niet onder z'n inhoud
   (min-width:auto). Een lange bestandsnaam zonder spaties duwde de kop daardoor breder
   dan de sheet; met justify-content:space-between liep die overloop naar de START-kant
   en knipte overflow:hidden de linkerhelft van de sheet weg. Een titel MET spaties breekt
   nu gewoon af over twee regels (feedback 2026-09-09: een lange vraag liep tegen het kruis
   aan en verloor zijn staart); alleen een onbreekbare reeks wordt nog hard gebroken. */
.sheet__head { gap: 14px; align-items: flex-start; }
/* De sheet-titel is een label boven wat eronder staat, geen schermkop (feedback
   2026-09-10). Op 22px in de display-letter nam hij de plek van een kop in terwijl een sheet
   maar één ding vraagt — en die regel plus zijn marges duwden het invoerveld een centimeter
   naar beneden. Nu leesmaat in de broodletter, zoals elk veldlabel; de display-letter begint
   pas bij 20px (conventions §"De letter"), dus die valt vanzelf weg. Geldt voor élke sheet. */
/* Dikgedrukt (feedback 2026-09-12): op gewicht 500 was de titel niet te onderscheiden van
   de rijen eronder, die ook 500 dragen. */
/* Lichte stijl (2026-09-26, opdracht stap 7): de titel staat weer op 22/500. */
.sheet__title { font-size: var(--text-22); font-weight: 500; line-height: var(--leading-kop);
  min-width: 0; overflow: hidden; overflow-wrap: anywhere; }
.sheet__close { margin-top: -2px; }
/* Sheet met greep i.p.v. kop (Design 2026-09-08): greep 38×4 in --line, kleine titel eronder.
   Greep en kop zijn ook het handvat waarmee je de sheet naar beneden duwt (sheet-controller);
   touch-action houdt dat gebaar bij de sheet i.p.v. bij de pagina-scroll. Het greep-vlak is
   groter dan de streep zelf — 4px is niet te raken. */
/* Krap boven: greepmarge, kopmarge en paneelmarge telden op tot ruim 50px vóór de titel
   (feedback 2026-09-10). Het raakvlak (de padding hieronder) draagt de lucht al. */
/* Kop van een schrijf-sheet: kruis links om te sluiten, de handeling rechts (2026-09-11,
   zoals de mail-opsteller). Geen titel ertussen — het formulier eronder zegt al waar je bent.
   De veilige zone zit hier, want deze kop is het eerste wat het scherm raakt. */
.sheet__kop {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  padding: calc(8px + env(safe-area-inset-top, 0px)) 14px 6px;
}
.sheet__kop-save {
  appearance: none; border: 0; background: none; font: inherit;
  font-size: var(--text-base); font-weight: 500; color: var(--color-text);
  padding: 8px 10px; border-radius: var(--radius-pill); cursor: pointer;
}
.sheet__sub { margin: 2px 0 0; font-size: var(--text-15); color: var(--color-text-muted); }
.sheet__sub:empty { display: none; }
.sheet__kop-save[disabled] { color: var(--color-faint); cursor: default; }
/* Een sheet mét deze kop draagt de veilige zone daar al. */
.sheet--koploos:has(> .sheet__kop) > .sheet__body { padding-top: 0; }
/* De losse new/edit-pagina heeft geen kop met acties, dus daar blijft een knop onderaan. */
.agenda-form__paginaknop { margin-top: var(--space-5); }

.sheet__grip { margin: 4px auto 0; }
/* Het raakvlak is groter dan de streep zelf: 4px is met een duim niet te raken, en dan doet
   slepen niets. Gold alleen bínnen een <dialog>; de uitklap-panelen van het afspraakformulier
   zijn géén dialog en misten het dus (feedback 2026-09-10). Nu draagt elke greep het.
   content-box + background-clip: de padding vergroot het raakvlak zonder de streep te
   verdikken. */
.sheet__grip, .coach-sheet__grabber {
  box-sizing: content-box; padding: 10px 40px; background-clip: content-box;
}
/* Het greep-vlak is groter dan de streep zelf — 4px is niet te raken. Full-screen sheets
   krijgen geen greep: die zijn een scherm, geen laatje dat je wegduwt. */
dialog.sheet--full > .sheet__grip { display: none; }
dialog.sheet:not(.sheet--full) > .sheet__grip,
dialog.sheet:not(.sheet--full) > .sheet__head { touch-action: none; }
.sheet__close { flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; background: none; border: none; color: var(--color-text); cursor: pointer; }
.sheet__close:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; border-radius: var(--radius-pill); }
.sheet__close svg { width: var(--icon-lg); height: var(--icon-lg); }
.sheet__body { flex: 1; overflow-y: auto; padding: 14px 22px 26px; }
/* De inhoud scrolt zonder zichtbare balk (bron/checklist §5); op desktop stond er een rechterbalk. */
.sheet__body { scrollbar-width: none; }
.sheet__body::-webkit-scrollbar { display: none; }
/* Form-variant (schrijf-sheets): ✕ | titel | opslaan-submit; het formulier wrapt
   kop + body zodat de submit in de kop kan leven. Kop zonder lijn (design). */
.sheet__form { display: flex; flex-direction: column; min-height: 0; max-height: inherit; }
/* Opslaan-footer van de form-variant (conventions §Opslag-model): volle-breedte knop
   onderaan; in de sheet--full-flex blijft hij als flex:none altijd in beeld terwijl
   alleen .sheet__body scrollt. De knop zelf is de .button-primitive. */

/* Intro-regel direct onder de kop (home-plan-sheet e.a.). */
/* Korte uitleg bovenin (design-feedback 2026-07-27): dé lede. Eén stijl voor de intro-regel
   bovenaan een sheet, formulier of scherm — verving 18 bijna-identieke *__intro/__lede/
   __uitleg-klassen (lint-guard bewaakt dat er geen nieuwe bijkomen). De 6px boven sluit
   aan op een kop erboven; staat 'ie bovenaan een sheet-body, dan valt dat weg in de
   padding. Hero-landingsschermen (auth/paywall/samen) houden bewust hun grotere variant. */
/* Eén regel onder de paginatitel: 17 muted (ChatGPT-stijl, prototype 2026-09-28); in een sheet
   is het de aanloop naar de vraag en staat hij op 15. */
.lede { font-size: var(--text-17); color: var(--color-text-muted); line-height: var(--leading); margin: 6px 0 var(--space-4); }
.sheet .lede { font-size: var(--text-15); }
.lede--sub { font-size: var(--text-15); margin-top: -10px; }

/* Volledige-modal-variant (UX-besluit 2026-07-20): grote formulieren — zoals "Kind
   toevoegen" — worden full-screen i.p.v. een bottom-sheet die tegen zijn eigen hoogte-
   limiet aan schuurt en dan intern gaat scrollen. Zelfde <dialog>/sheet-controller-
   mechaniek (open/close/backdrop ongewijzigd) — alleen de chrome verandert: edge-to-edge
   zoals .viewer, fade i.p.v. slide-up (leest als een eigen scherm, niet als een sheet). */
dialog.sheet--full {
  inset: 0;
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  border-radius: 0;
  box-shadow: none;
  /* Géén display hier: dat zit al op dialog.sheet[open] (flex kolom). Op de basisregel
     zou het de UA-default display:none van een gesloten <dialog> overrulen — de sheet
     ligt dan permanent over de pagina en lijkt niet meer te sluiten. */
}
/* Kop blijft staan; alleen de body scrollt. Beide layout-varianten (met en zonder
   form-kop) delen dit: .sheet__form is de flex-drager als hij er is. */
dialog.sheet--full .sheet__form { display: flex; flex-direction: column; flex: 1; min-height: 0; }
dialog.sheet--full .sheet__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
dialog.sheet--full[open] { animation: sheet-full-in 0.22s ease both; }
@keyframes sheet-full-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
/* Een bottom-sheet clearet de statusbalk vanzelf (onderaan-anchored); een fullscreen-
   dialoog begint bovenaan het scherm en heeft de notch-marge zelf nodig (zelfde recept
   als .viewer__bar). */
/* Alleen de eigen kop van de full-screen sheet (directe dochter): een paneel dat vanuit zo'n
   sheet opent (de overdrachtsmomenten van een zorgwissel) heeft óók een .sheet__head, en die
   erfde deze 18px mee — daardoor stond zijn kruis lager dan in elke andere bottom sheet
   (feedback 2026-09-11). */
.sheet--full > .sheet__head { padding-top: calc(18px + env(safe-area-inset-top, 0px)); }
/* Een sheet zonder kop (het afspraakformulier): de body draagt de veilige zone die de kop
   anders droeg, anders begint de eerste rij onder de statusbalk. */
.sheet--koploos > .sheet__body { padding-top: calc(14px + env(safe-area-inset-top, 0px)); }

/* ===================== COACH-INGANGEN (plan-onderwerp, design 'planTopicQ') ===================== */
/* Rendert als <button> (opent de coach-sheet) óf als <a> (coach_cta met
   naar:) — vandaar de link-reset, zelfde idioom als .conversation-invite. */
/* Zelfstandige actierij: het gedeelde grijze vlak blijft zichtbaar op de paginagrond. */
.coach-bar { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; background: var(--color-card); border: 0; border-radius: var(--radius-pill); padding: 10px 18px 10px 10px; margin-bottom: 16px; cursor: pointer; text-align: left; font: inherit; text-decoration: none; color: var(--color-text); }
.coach-bar__icon { flex: none; width: 32px; height: 32px; border-radius: 50%; background: var(--color-accent); color: var(--color-on-accent); display: flex; align-items: center; justify-content: center; }
.coach-bar__icon svg { width: var(--icon-sm); height: var(--icon-sm); }
.coach-bar__title { flex: 1; min-width: 0; font-size: var(--text-17); font-weight: 400; color: var(--color-text); }
.coach-bar__chevron { flex: none; width: var(--icon-sm); height: var(--icon-sm); color: var(--color-text-muted); }

/* Coach-sheet: hoger dan de standaard sheet (design: vanaf 70px onder de top), eigen kop
   + picker/gesprek + composer. De bubbels hergebruiken de chat-styling (.message-row). */
dialog.sheet--coach { height: calc(100dvh - 70px); max-height: calc(100dvh - 70px); }
/* In combinatie met sheet--full wint full: de coach leest dan als een eigen scherm,
   edge-to-edge — de losse sheet--coach-hoogte (met 70px lucht) blijft voor de
   bottom-sheet-variant elders. */
dialog.sheet--coach.sheet--full { height: 100dvh; max-height: 100dvh; }
.coach-sheet { display: flex; flex-direction: column; height: 100%; min-height: 0; box-sizing: border-box; padding: calc(18px + env(safe-area-inset-top, 0px)) 20px calc(22px + env(safe-area-inset-bottom, 0px)); background: var(--color-bg); }
.coach-sheet__grabber { flex: none; margin: 6px auto 14px; }
.coach-sheet__head { flex: none; display: flex; align-items: flex-start; gap: 12px; }
.coach-sheet__titles { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.coach-sheet__title { font-family: var(--font-display); font-size: var(--text-22); font-weight: 500; overflow-wrap: anywhere; }
.coach-sheet__about { font-size: var(--text-15); color: var(--color-text-muted); margin-top: 1px; }
.coach-sheet__close { flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; background: none; border: none; color: var(--color-text); cursor: pointer; }
.coach-sheet__close svg { width: var(--icon-lg); height: var(--icon-lg); }
.coach-sheet__stream { flex: 1; overflow-y: auto; margin-top: 12px; padding-bottom: 2px; }
.coach-sheet__privacy { font-size: var(--text-15); color: var(--color-text-muted); line-height: var(--leading); margin: 0 2px 14px; }
/* Vragen als haarlijn-rijen — waren witte kaarten met lift en een paars pijl-tegeltje
   (2026-09-12). De pijl staat kaal in faint, zoals elk chevron op een rij. */
.coach-sheet__qs { display: flex; flex-direction: column; }
.coach-sheet__q { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; background: none; border: 0; border-bottom: 1px solid var(--color-line); padding: 13px 2px; cursor: pointer; text-align: left; font: inherit; }
.coach-sheet__q:last-child { border-bottom: 0; }
.coach-sheet__q-text { font-size: var(--text-base); color: var(--color-text); line-height: var(--leading); }
.coach-sheet__q-arrow { flex: none; display: flex; color: var(--color-faint); }
.coach-sheet__q-arrow svg { width: var(--icon-sm); height: var(--icon-sm); }
.coach-sheet__composer { flex: none; margin-top: 14px; }
/* Ook hier zweven kop en opsteller over het gesprek, zoals in de assistent (Jerry 2026-10-09). */
.coach-sheet { position: relative; padding-top: 0; padding-bottom: 0; }
.coach-sheet__head { padding: calc(18px + env(safe-area-inset-top, 0px)) 20px 12px; }
.coach-sheet__stream {
  margin-top: 0;
  padding-top: calc(var(--kop-h, 90px) + var(--space-3));
  padding-bottom: calc(var(--composer-h, 88px) + var(--space-2));
}
.coach-sheet__composer {
  position: absolute;
  inset: auto 20px 0 20px;
  z-index: 2;
  margin: 0;
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
}
.coach-sheet__composer > * { pointer-events: auto; }
.coach-sheet__composer .compose__submit { background: var(--color-btn); }

/* ===================== ABONNEMENT "BLINCO SAMEN" (design paywall/abo/mollie) ===================== */
.paywall { max-width: 480px; margin: 0 auto; padding: 0 24px 34px; }
.paywall__topbar { display: flex; justify-content: flex-end; padding: 16px 0 0; }
.paywall__close { width: 34px; height: 34px; border-radius: 50%; background: var(--color-surface); border: 1px solid var(--color-line); display: flex; align-items: center; justify-content: center; color: var(--color-text); }
.paywall__close svg { width: var(--icon-sm); height: var(--icon-sm); }
/* Paywall als bottom-sheet-modal (frame-dialog): de body scrollt binnen de sheet, de
   X-topbar blijft plakken. dialog.sheet is al flex-kolom + overflow:hidden. */
.paywall-sheet .paywall { flex: 1; min-height: 0; max-width: none; overflow-y: auto; -webkit-overflow-scrolling: touch; }
/* De sheet is wit (lichte stijl), dus de plakkende kop ook — anders stond er een grijze balk. */
.paywall-sheet .paywall__topbar { position: sticky; top: 0; z-index: 1; padding-top: 12px; background: var(--color-surface); }
/* Full-screen (.sheet--full, feedback 2026-08-07): de topbar begint bovenaan het
   scherm en heeft de notch-marge zelf nodig — zelfde recept als .sheet--full .sheet__head. */
.sheet--full.paywall-sheet .paywall__topbar { padding-top: calc(16px + env(safe-area-inset-top, 0px)); }
.paywall__hero { font-family: var(--font-display); font-size: var(--text-32); font-weight: 500; line-height: var(--leading-kop); letter-spacing: -0.01em; margin: 2px 0 0; }
.paywall__lede { font-size: var(--text-base); color: var(--color-text-muted); margin: 11px 0 0; line-height: var(--leading); }
/* Het kernblok ("wat Blinco je geeft") staat op het papier onder een haarlijn — was een
   paarse gradient-kaart met gloed (tot 2026-09-12). Conventie: accent alleen op tekst-signalen,
   geen gradients op een tegel; de paarse rolkleur betekent hier niets. */
.paywall__core { margin-top: var(--space-5); padding: var(--space-4) 2px 0; border-top: 1px solid var(--color-line); color: var(--color-text); }
.paywall__core-head { display: flex; align-items: center; gap: 13px; }
.paywall__core-icon { flex: none; display: flex; color: var(--color-text-muted); }
.paywall__core-icon svg { width: var(--icon-lg); height: var(--icon-lg); }
.paywall__core-titles { flex: 1; display: flex; flex-direction: column; }
.paywall__core-eyebrow { font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.paywall__core-title { font-size: var(--text-lg); font-weight: 500; margin-top: 2px; }
.paywall__core-text { font-size: var(--text-sm); color: var(--color-text-muted); margin: 12px 0 0; line-height: var(--leading); }
.paywall__section { font-size: var(--text-xs); font-weight: 500; color: var(--color-faint); margin: var(--space-6) 4px var(--space-3); }
/* Rijen op het papier met haarlijnen (was een witte kaart met lift, 2026-09-12). */
.paywall__row { display: grid; grid-template-columns: 1fr 32px; align-items: center; padding: 14px 2px; border-bottom: 1px solid var(--color-line); }
.paywall__row:last-child { border-bottom: none; }
.paywall__feature { font-size: var(--text-sm); }
.paywall__col { display: flex; justify-content: center; }
.paywall__check { width: 16px; height: 16px; color: var(--color-green); }
/* Keuze-rijen met de radio-stip, gescheiden door een haarlijn — waren omrande kaartjes die bij
   keuze een zandvlak kregen (2026-09-12). Gekozen = de stip, zoals elke radiorij. */
.paywall__plan { position: relative; display: flex; align-items: center; gap: 13px; padding: 14px 2px; border-bottom: 1px solid var(--color-line); cursor: pointer; }
/* De keuze-rijen staan in een .stack (de form) zonder tussenruimte: de haarlijn scheidt. */
.paywall__form { --stack-gap: 0; }
.paywall__plan.is-active { }
.paywall__plan-radio { position: absolute; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.paywall__plan-dot { flex: none; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--color-line); display: flex; align-items: center; justify-content: center; }
.paywall__plan.is-active .paywall__plan-dot { border-color: var(--color-text); }
.paywall__plan.is-active .paywall__plan-dot::after { content: ""; width: 11px; height: 11px; border-radius: 50%; background: var(--color-btn); }
.paywall__plan-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.paywall__plan-name { font-size: var(--text-base); font-weight: 500; }
.paywall__plan-sub { font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 1px; }
.paywall__plan-price { font-size: var(--text-base); font-weight: 500; }
.paywall__plan-permonth { font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.paywall__plan-note { font-size: var(--text-sm); color: var(--color-text-muted); margin: 11px 4px 0; line-height: var(--leading); }
.paywall__cta { display: block; width: 100%; text-align: center; background: var(--color-btn); color: var(--color-on-btn); font-weight: 500; font-size: var(--text-base); padding: 16px; border: none; border-radius: var(--radius-pill); margin-top: 20px; cursor: pointer; font-family: inherit; transition: transform .12s ease;
  box-shadow: var(--shadow-knop);
}
.paywall__cta:active { transform: scale(.98); }
.paywall__cta-note { text-align: center; font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 10px; line-height: var(--leading); }
.paywall__privacy { display: flex; gap: 10px; align-items: flex-start; margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--color-hair); font-size: var(--text-xs); color: var(--color-faint); line-height: var(--leading); }
.paywall__privacy svg { flex: none; width: var(--icon-sm); height: var(--icon-sm); margin-top: 1px; }

/* Proef/actief/bevroren: statuskaart met badge. */
/* Stand van het abonnement: tekst op het papier; alleen een amber/groene stand houdt zijn
   toon-vlak (dat is status, V9.2). */
.abo-statecard { padding: var(--space-4) 2px; border-top: 1px solid var(--color-line); }
.abo-statecard--amber, .abo-statecard--green { padding: var(--space-5); border-top: 0; border-radius: var(--radius-groep); }
.abo-statecard--amber { background: var(--color-amber-soft); border-color: var(--color-amber-border); }
.abo-statecard--green { background: var(--color-green-soft); border-color: var(--color-green-border); }
.abo-statecard__title { font-family: var(--font-display); font-size: var(--text-22); font-weight: 500; color: var(--color-text); margin: 11px 0 0; }
.abo-statecard__text { font-size: var(--text-sm); color: var(--color-text); opacity: 0.82; margin: 6px 0 0; line-height: var(--leading); }

/* Prijs/volgende-betaling-rijen onder een statuskaart. */

/* Gedekt door de ander. */
.abo-covered { padding: var(--space-4) 2px; border-top: 1px solid var(--color-line); }
.abo-covered__head { display: flex; align-items: center; gap: 13px; }
.abo-covered__avatar { flex: none; display: grid; place-items: center; width: 46px; height: 46px; border-radius: var(--radius-groep); background: var(--color-coparent-soft); color: var(--color-coparent); font-weight: 500; font-size: var(--text-lg); }
.abo-covered__title { flex: 1; font-size: var(--text-base); font-weight: 500; line-height: var(--leading-kop); }
.abo-covered__text { font-size: var(--text-sm); color: var(--color-text-muted); margin: 12px 0 0; line-height: var(--leading); }

/* Info-noot (halen-brengen-stijl): icoon + tekst. Variant --green voor de proef-noot. */
.abo-note { display: flex; gap: 11px; align-items: flex-start; padding: 6px 2px; margin-top: 12px; font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); }
.abo-note svg { flex: none; width: var(--icon); height: var(--icon); margin-top: 1px; color: var(--color-text-muted); }
.abo-note--green { background: var(--color-green-soft); border-radius: var(--radius-groep); padding: 12px 14px; color: var(--color-green-deep); }
.abo-note--green svg { color: var(--color-green-deep); }

.abo__cta { width: 100%; margin-top: 16px; }
.abo__cta-form { margin-top: 0; }
.abo__ghost { display: block; width: 100%; text-align: center; background: none; border: none; color: var(--color-text-muted); font-weight: 500; font-size: var(--text-sm); padding: 15px; cursor: pointer; font-family: inherit; }
/* Secundaire actie onder de primaire: 12px — niet er tegenaan (audit 2026-08-06 §4.2). */
.abo__ghost-form { margin-top: var(--space-3); }

/* Mollie-checkout */
.mollie__heading { font-family: var(--font-display); font-size: var(--text-24); font-weight: 500; margin: 6px 0 0; }
.mollie__explain { font-size: var(--text-sm); color: var(--color-faint); line-height: var(--leading); margin: 12px 0; }
.mollie__confirm { width: 100%; }

/* Flash-melding als toast onderaan (auto-fade) i.p.v. ruwe tekst bovenaan de pagina. */
.flash {
  position: fixed;
  left: 50%;
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 60;
  max-width: 88%;
  text-align: center;
  background: var(--slate-dark);
  color: var(--color-on-accent);
  font-size: var(--text-sm);
  line-height: var(--leading);
  padding: 11px 18px;
  border-radius: var(--radius-groep);
  box-shadow: var(--shadow-16);
  animation: flash-toast 4.2s ease forwards;
}
.flash[data-flash-type="alert"] { background: var(--color-error); }
@keyframes flash-toast {
  0% { opacity: 0; transform: translate(-50%, 12px); }
  7% { opacity: 1; transform: translate(-50%, 0); }
  86% { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, 8px); pointer-events: none; }
}

/* Bestand-kiezen-veld netter: gestylede ::file-selector-button. */
.form__input[type="file"] { padding: 9px 12px; line-height: var(--leading); }
.form__input[type="file"]::file-selector-button {
  margin-right: 12px;
  padding: 8px 14px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--color-panel);
  color: var(--color-accent);
  font-weight: 500;
  font-size: var(--text-sm);
  cursor: pointer;
}

/* Herbruikbare bevestigings-modal (DRY, app-breed) — een lage balk onderaan.
   Was een gecentreerde modal met een prullenbak in een roze vlak en een rode knop op volle
   breedte: dat nam het hele scherm over voor een vraag van één regel, en las als een alarm
   (feedback 2026-09-10, "te heftig"). Nu verschijnt de vraag onderin, waar je duim al is,
   met de acties als tekst naast elkaar. De backdrop dempt in plaats van te verduisteren:
   je blijft zien waar je vandaan komt. */
dialog.confirm {
  margin: auto auto 0; padding: 0 12px calc(12px + env(safe-area-inset-bottom, 0px));
  border: none; background: transparent; width: 100%; max-width: 460px;
}
dialog.confirm::backdrop { background: rgba(30, 18, 10, 0.28); }
dialog.confirm[open] { animation: confirm-op 0.22s cubic-bezier(.32, .72, 0, 1); }
@keyframes confirm-op { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
.confirm__box {
  background: var(--color-surface); border-radius: var(--radius-groep);
  padding: 14px 4px 4px; box-shadow: var(--shadow-16);
}
.confirm__message { font-size: var(--text-sm); line-height: var(--leading); margin: 0 0 10px; padding: 0 14px; color: var(--color-text); }
/* De acties als tekst naast elkaar, gescheiden door één haarlijn — de vorm van de
   acties in de kop van een schrijf-sheet, zodat een keuze er overal hetzelfde uitziet. */
.confirm__acties { display: flex; }
.confirm__ok, .confirm__cancel {
  flex: 1; appearance: none; border: 0; background: none; font: inherit;
  font-size: var(--text-base); font-weight: 500; padding: 12px 10px; cursor: pointer;
  border-radius: var(--radius-pill);
}
.confirm__cancel { color: var(--color-text-muted); }
/* Destructief is rood in de tekst, niet als vlak: het is de uitkomst die telt, niet het
   alarm eromheen (conventions §3 — rood alléén hier, nooit los op een pagina). */
.confirm__ok { color: var(--color-error); }
.confirm__cancel + .confirm__ok { border-left: 1px solid var(--color-line); border-radius: 0 var(--radius-pill) var(--radius-pill) 0; }
/* Neutrale toon: een vraag die niets kapotmaakt hoort er niet uit te zien alsof dat wel
   zo is (feedback 2026-09-02). Dan staat de actie in de inkt in plaats van in rood. */
.confirm--neutraal .confirm__ok { color: var(--color-text); }

/* De transparantie-regel in de export-sheet (fix-ronde 1, taak 8) is de kern van de
   afspraak met de gebruiker, niet de twee neutrale info-regels erboven — een zacht
   accent-vlak laat 'm opvallen zonder amber/rood (dit is een mededeling, geen
   waarschuwing). */
.sheet__nadruk { margin-top: var(--space-3); padding: 12px 14px; background: var(--color-panel); border-radius: var(--radius-groep); font-size: var(--text-sm); font-weight: 500; line-height: var(--leading); color: var(--color-accent); }

/* Sectiekop in een sheet: 13/500 in muted (Design 2026-09-08); een <label> boven een
   invoerveld houdt de inkt — dat is een veldlabel, geen sectiekop. */
.sheet__label { display: block; font-size: var(--text-15); font-weight: 500; margin-bottom: 8px; color: var(--color-text-muted); }
label.sheet__label { color: var(--color-text); }
.sheet__field {
  width: 100%;
  border: 1px solid transparent;
  background: var(--color-card);
  border-radius: var(--radius-pill);
  min-height: 52px;
  padding: 15px 20px;
  font-size: var(--text-17);
  font-family: inherit;
  color: var(--color-text);
  outline: none;
  /* Geen eigen ondermarge — de .stack deelt de ruimte uit (conventions §3). */
}
select.sheet__field {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 40px;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px 12px;
}
/* Kleur én marge zonder iets anders te
   betekenen. Geen eigen marges: de .stack-container deelt die uit. Is de uitleg langer dan
   één regel,
dan hoort 'ie in de kennisbank-sheet (conventions §3),
niet hier.
   .hint--inline: binnen een flex-rij (bv. naast een schakelaar) op een eigen regel. */
.hint { font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); margin: 0; }
.hint--inline { flex-basis: 100%; }
/* Opslaan in sheets = de gedeelde .button--block-primitive (fase 5, audit 2026-08-06);
   .sheet__save is opgeheven — er bestonden twee Opslaan-hoogtes binnen één sheet-familie. */

/* ===================== GEZIN-SUBSCHERM (full-bleed, design) =====================
   Gedeelde container + kop voor de full-bleed gezin-sub-schermen (Scholen, Documenten,
   Ouderschapsplan, Toestemmingen) — zelfde idioom als Contacten (shared/_section_head). */
/* .gezin-section: paginageometrie via de gedeelde .page-regel (bovenin dit bestand). */
/* Kop-knop (Design 2026-09-08, app-breed): 44×44, --radius-icon, kaal — geen vulling, geen
   accent; alleen bij aanraken een zacht vlak. Dé kop-knop-primitive: scherm-acties, zoeken,
   de weergavekiezer en de plus in de agenda. Rond (50%) is voor avatars en de bel. */
.vnav__action {
  width: 44px;
  height: 44px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--color-text);
  text-decoration: none;
  cursor: pointer;
  transition: transform .12s ease;
}
.vnav__action svg { width: var(--icon); height: var(--icon); }
/* De primaire kop-actie ("+"): in --btn met de knop-lift, krimpt naar .9 bij aanraken. */
.vnav__action--primair { background: var(--color-btn); color: var(--color-on-btn); box-shadow: var(--shadow-knop); }
.vnav__action--primair:active { background: var(--color-btn); transform: scale(.9); }

/* ChatGPT-stijl (prototype CONTACTEN 2026-09-28): per categorie een label (17 muted) en
   daaronder een groep rijen — elk contact een eigen grijs vlak, 3px ertussen, 26px buitenhoek. */
.contacts__group { margin-top: var(--space-5); }
.contacts__group-label {
  display: block;
  margin: 0 4px 10px;
  font-size: var(--text-17);
  font-weight: 400;
  color: var(--color-text-muted);
}
.contacts__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; border-radius: var(--radius-groep); overflow: hidden; }
.contacts__row { display: flex; align-items: center; min-height: 68px; padding-right: 12px; border-radius: var(--radius-binnen); background: var(--color-card); }
.contacts__link {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 0 12px 16px;
  text-decoration: none;
  color: var(--color-text);
}
.contacts__row:has(.contacts__link:active) { background: var(--color-card-pressed); }
/* Het initiaal in een rondje met alleen een haarlijn: herkenning zonder tegeltje. */
.contacts__avatar {
  flex: none;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-surface);
  font-weight: 500;
  font-size: var(--text-15);
  color: var(--color-text);
}
.contacts__body { min-width: 0; display: flex; flex-direction: column; }
.contacts__name { font-size: var(--text-17); font-weight: 400; overflow-wrap: break-word; }
.contacts__role { font-size: var(--text-15); color: var(--color-text-muted); margin-top: 2px; }
/* Belknop kaal en gedempt (geen tegel, geen accent op een icoon). */
.contacts__call {
  flex: none;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--color-text-muted);
}
.contacts__call svg { width: var(--icon); height: var(--icon); }

/* Alleen een noodcontact draagt kleur — dat is betekenis (kleur alleen met betekenis). De
   andere categorieën lees je aan het groepslabel; hun tint (2026-08-19) is vervallen. */
.contacts__avatar--noodcontact { border-color: transparent; background: var(--color-error-soft); color: var(--color-error); }

/* ----- Contactdetail (scherm 10) ----- */
/* Plat (2026-09-13, "zelfde stijl als het formulier"): de kop links — het initiaal uit de
   lijst naast de naam, rol en categorie eronder — en de velden als rijen met een icoon op
   het papier, precies het contactformulier maar dan lezend. Telefoon, e-mail en adres zijn
   zélf de actie (bellen, mailen, route): accent op de tekst, geen actietegels meer.
   Het potlood staat in de nav-rij (.contact-detail__nav) samen met de terug-link. */
/* ChatGPT-stijl (prototype CONTACT DETAIL 2026-09-28): de kop gecentreerd (initiaal van 72px,
   naam 24/500, rol en categorie 15 muted) en de gegevens als groep rijen: icoon, het label
   boven de waarde. Een rij die zelf de actie is (bellen, mailen, route) is de hele rij. */
.contact-detail__head { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 4px 0 24px; }
.contact-detail__headtext { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; }
.contact-detail__avatar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  margin-bottom: 14px;
  border-radius: 50%;
  background: var(--color-card);
  font-size: var(--text-28);
  font-weight: 500;
  color: var(--color-text);
}
.contact-detail__name { font-size: var(--text-24); font-weight: 500; letter-spacing: -0.01em; margin: 0; }
.contact-detail__role { font-size: var(--text-15); line-height: var(--leading); color: var(--color-text-muted); }
.contact-detail__fields { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; border-radius: var(--radius-groep); overflow: hidden; }
.contact-detail__field { display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 12px 20px; border-radius: var(--radius-binnen); background: var(--color-card); }
.contact-detail__field--actie { padding: 0; }
.contact-detail__field-link { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 12px 20px; color: inherit; text-decoration: none; }
.contact-detail__field-icon { display: inline-flex; flex: none; color: var(--color-text); }
.contact-detail__field-icon svg { width: var(--icon); height: var(--icon); }
.contact-detail__field-text { min-width: 0; display: flex; flex-direction: column; }
.contact-detail__field-label { font-size: var(--text-15); line-height: var(--leading); color: var(--color-text-muted); }
.contact-detail__field-value { min-width: 0; font-size: var(--text-17); line-height: var(--leading); color: var(--color-text); overflow-wrap: anywhere; }
/* De schakelaars onder het contactformulier: één groep rijen. De noodkaart-rij kan verborgen
   zijn, dus de groep knipt zelf zijn hoeken af (de eerste zichtbare rij is dan geen :first-child). */
.contact-form__schakelaars { margin: var(--space-5) 0 0; border-radius: var(--radius-groep); overflow: hidden; }
.contact-form__schakelaars:not(:has(> .setrow:not([hidden]))) { display: none; }
.contact-detail__added { display: flex; align-items: center; gap: 8px; margin: 14px 4px 0; font-size: var(--text-15); color: var(--color-text-muted); }

/* ===================== DOCUMENTEN (design-handoff "Documenten") ===================== */
/* Dropbox-achtig: geen kaarten maar een platte lijst met fijne scheidingslijnen, per rij
   een bestandstype-tegel links en een kebab rechts. Mappen boven, losse documenten
   eronder. Zelfde rij-anatomie voor mappen, documenten en verplaats-doelen. */
/* Plat (2026-09-13): de groepskop staat op de lijn van de rijen (2px), gedempt — de
   16px van .vset__group hoort bij een kaart, en die is hier weg. */
.documenten .vset__group, .afspraken .vset__group { margin: var(--space-5) 2px 2px; color: var(--color-text-muted); }
.afspraken .vset__group { margin: 22px 4px 10px; font-size: var(--text-17); }
/* Documenten (ChatGPT-stijl, prototype DOCUMENTEN 2026-09-28): "Mappen" en "Losse documenten"
   op 17 muted boven de platte lijst. */
.documenten .vset__group { margin: 20px 2px 10px; font-size: var(--text-17); }
.documenten__loosehead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.documenten__loosehead .vset__group { margin: 0; }
.documenten__sorthead { display: flex; justify-content: flex-end; margin: 18px 2px 6px; }
.documenten__foldermeta { display: flex; align-items: center; gap: 8px; margin: 8px 2px 0; }
.documenten__ownernote { font-size: var(--text-15); color: var(--color-text-muted); }
.documenten__readonly { display: flex; align-items: flex-start; gap: 9px; background: var(--color-amber-soft); border-radius: var(--radius-groep); padding: 10px 13px; margin-top: 12px; font-size: var(--text-xs); color: var(--color-amber-deep); line-height: var(--leading); }
.documenten__readonly svg { flex: none; width: var(--icon-sm); height: var(--icon-sm); margin-top: 1px; color: var(--color-amber); }

/* Toegang van een map: gekleurde tekst, geen pil (ChatGPT-stijl, prototype DOCUMENTEN
   2026-09-28) — faint (privé), amber (kan bekijken), groen (kan bewerken). De kleur is hier
   betekenis. */
.accessbadge { flex: none; font-size: var(--text-15); font-weight: 400; color: var(--color-faint); }
.accessbadge--lezen { color: var(--color-amber); }
.accessbadge--bewerken { color: var(--color-green); }

/* Bestandstype-tegel, afgeleid van de extensie. Afbeeldingen krijgen het foto-icoon,
   de rest een extensielabel - elk met een eigen tint (design "Bestandstype-iconen"). */
/* Naakt stroke-icoon in een rij, geen gevulde tegel (ontwerpregel §4, app-breed
   doorgevoerd 2026-09-03). Een cirkel of vierkant achter een icoon is voorbehouden aan
   een avatar met een initiaal erin. */
.filetile { flex: none; display: flex; align-items: center; justify-content: center; margin: 0 3px; color: var(--color-text-muted); }
.filetile svg { width: var(--icon-lg); height: var(--icon-lg); }
.filetile__ext { font-size: 0.625rem; font-weight: 500; }
/* Geen tint per bestandstype meer (2026-09-13): het extensielabel zegt het al. De
   --filetile--pdf/doc/sheet/image-modifiers blijven als data-haak (tests, viewer). */
/* Echte duimnagel: de afbeelding vult de tegel, geen gekleurd vlak eromheen. */
.filetile--thumb { width: 40px; height: 40px; border-radius: var(--radius-binnen); background: var(--color-panel); overflow: hidden; }
.filetile__img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── Groep rijen (conventions §3.5, 2026-10-01) — één bron voor lijsten met een eigen klasse ──
   Elk item een eigen grijs vlak, 3px ertussen, 26px buiten- en 6px binnenhoek, geen haarlijnen.
   Een nieuwe lijst krijgt .vset__rows + .setrow; deze lijsten dragen nog hun eigen klassen en
   delen hier de vorm. :where() houdt de specificiteit op nul, zodat een rij-modifier (nieuw,
   afgehandeld, vergrendeld) gewoon wint. */
:where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) { display: flex; flex-direction: column; gap: 3px; }
:where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > * { background: var(--color-card); border-radius: var(--radius-binnen); overflow: hidden; }
:where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > :first-child { border-top-left-radius: var(--radius-groep); border-top-right-radius: var(--radius-groep); }
:where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > :last-child { border-bottom-left-radius: var(--radius-groep); border-bottom-right-radius: var(--radius-groep); }
/* In een witte sheet: grijze rijen en de gedeelde sheet-groephoek (§3.5). */
:where(.sheet) :where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > * { background: var(--color-card); }
:where(.sheet) :where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > :first-child { border-top-left-radius: var(--radius-groep-sheet); border-top-right-radius: var(--radius-groep-sheet); }
:where(.sheet) :where(.folderlist, .doclist, .meldingen__group, .kasboek-detail__fields, .kasboek-gate__points, .vastpost-detail__tijdlijn, .jaaroverzicht__card, .ov__lijst, .ov-detail__timeline, .vakanties__card, .plan-topics, .plan-sign__topics, .plan-choices) > :last-child { border-bottom-left-radius: var(--radius-groep-sheet); border-bottom-right-radius: var(--radius-groep-sheet); }

/* ----- Mappenlijst ----- */
/* Groep rijen: de vorm komt uit de gedeelde regel hierboven. */
.folderlist, .doclist { list-style: none; margin: 0 0 var(--space-4); padding: 0; }
.movelist { display: flex; flex-direction: column; gap: 3px; list-style: none; margin: 0; padding: 0; }
.folderlist__item, .doclist__item { display: flex; align-items: center; min-height: 64px; padding-right: 6px; }
.folderlist__link { flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; padding: 12px 12px 12px 16px; text-decoration: none; color: var(--color-text); }
/* Icoon in een kaart staat in een witte cirkel van 44px (§3.5). */
.folderlist__tile { flex: none; width: 44px; height: 44px; border-radius: 50%; background: var(--color-surface); display: flex; align-items: center; justify-content: center; color: var(--color-text); }
.folderlist__tile svg { width: var(--icon); height: var(--icon); }
.folderlist__body { flex: 1; min-width: 0; }
.folderlist__naam { display: block; font-size: var(--text-17); font-weight: 400; overflow-wrap: anywhere; }
.folderlist__meta { display: flex; align-items: center; gap: 7px; margin-top: 2px; }
.folderlist__count { font-size: var(--text-15); color: var(--color-text-muted); }
.folderlist__chevron { flex: none; width: var(--icon); height: var(--icon); color: var(--color-faint); }

/* ----- Documentenlijst ----- */
/* De rij is óf een link (download) óf een knop (afbeelding → viewer). De knop-variant
   moet de browserstijl kwijt — anders krijgt-ie een eigen kader, achtergrond, centrering
   en systeemfont, en wijkt de afbeeldingsrij zichtbaar af van de rest. */
.doclist__link {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px; padding: 12px 12px 12px 16px;
  text-decoration: none; color: var(--color-text);
  appearance: none; -webkit-appearance: none;
  background: none; border: none; border-radius: 0;
  font: inherit; text-align: left; cursor: pointer;
}
.doclist__body { flex: 1; min-width: 0; }
.doclist__naam { display: block; font-size: var(--text-17); font-weight: 400; overflow-wrap: anywhere; }
.doclist__meta { display: block; font-size: var(--text-15); color: var(--color-text-muted); margin-top: 2px; }
.doclist__kebab { flex: none; width: 44px; height: 44px; border: none; border-radius: 50%; background: none; color: var(--color-faint); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.doclist__kebab svg { width: var(--icon); height: var(--icon); }
.doclist__expiry { display: inline-block; margin-left: 8px; font-size: var(--text-xs); padding: 1px 7px; border-radius: var(--radius-binnen); }
/* Voorstellen ("Samen afgesproken"): titel-only tot de ander akkoord geeft. */
.doclist--voorstellen { margin-bottom: 14px; }
.doclist__item--voorstel { justify-content: space-between; gap: 12px; padding: 12px 18px 12px 16px; }
.doclist__item--voorstel .doclist__body { flex: 1; min-width: 0; }
.doclist__wacht { flex: none; font-size: var(--text-15); color: var(--color-faint); }
.doclist__voorstel-acties { flex: none; display: flex; gap: 8px; }

/* Sorteer-toggle (Naam <-> Datum). */
/* Twee losse tapdoelen: label = sorteerveld, pijltje = richting. Beide krijgen wat
   padding zodat ze op een telefoon los aantikbaar blijven. */
.docsort { display: flex; align-items: center; gap: 2px; }
.docsort__field, .docsort__dir { display: inline-flex; align-items: center; padding: 4px 3px; text-decoration: none; }
.docsort__field:active, .docsort__dir:active { opacity: 0.6; }
.docsort__label { font-size: var(--text-17); font-weight: 400; color: var(--color-text-muted); }
.docsort__icon { width: var(--icon-xs); height: var(--icon-xs); color: var(--color-text-muted); }

/* ----- Bestandschip in de gegevens-sheet (upload-eerst) ----- */
.visually-hidden-input { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; z-index: -1; }
/* Plat (2026-09-13): de eerste rij van het formulier, met een haarlijn eronder. */
.filechip { display: flex; align-items: center; gap: 12px; padding: 10px 2px 12px; border-bottom: 1px solid var(--color-hair); }
.filechip .filetile { width: 42px; height: 42px; }
.filechip .filetile svg { width: var(--icon); height: var(--icon); }
.filechip__body { flex: 1; min-width: 0; }
.filechip__naam { display: block; font-size: var(--text-sm); font-weight: 500; overflow-wrap: anywhere; }
.filechip__meta { display: block; font-size: var(--text-xs); color: var(--color-text-muted); margin-top: 1px; }
.filechip__replace { flex: none; font-size: var(--text-xs); font-weight: 500; color: var(--color-accent); cursor: pointer; padding: 6px 8px; }
.filechip__replace:active { opacity: 0.6; }

/* ----- Sheet-menus: rijke rijen (toevoeg-menu), inforegel, divider, deel-badge ----- */
.sheetmenu__label { flex: 1; }
/* Zelfde menu, zelfde maat als de basis-rij (audit 2026-08-06 §5.5) — --rich regelt
   alleen de rijkere inhoud (icoon-tegel + subtekst), niet een eigen padding. */
.sheetmenu__item.sheetmenu__item--rich { align-items: flex-start; }
.sheetmenu__tile { flex: none; margin-top: 2px; color: var(--color-text); display: flex; align-items: center; justify-content: center; }
.sheetmenu__tile svg { width: var(--icon-lg); height: var(--icon-lg); }
.sheetmenu__rich { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sheetmenu__divider { height: 1px; background: var(--color-line); margin: 8px 12px; }
/* Aantal rechts in een keuze-rij (de postvak-sheet): een stand, dus gedempt. */
.sheetmenu__count { flex: none; font-size: var(--text-sm); font-weight: 400; color: var(--color-text-muted); }
.sheetmenu__note { font-size: var(--text-15); color: var(--color-faint); text-align: center; margin: 8px 0 0; line-height: var(--leading); }
.sharebadge { flex: none; font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); background: var(--color-panel); border-radius: var(--radius); padding: 4px 10px; }
/* V9.2: "gedeeld" is een rustende stand, geen momentane bevestiging — dus gedempt. */
.sharebadge--on { color: var(--color-text-muted); }

/* Kop van het document-kebab-menu: tegel + meta onder de sheet-titel. */
.sheetfilehead { display: flex; align-items: center; gap: 13px; padding: 0 0 14px; margin-bottom: 6px; border-bottom: 1px solid var(--color-hair); }
.sheetfilehead__meta { font-size: var(--text-xs); color: var(--color-text-muted); }

/* ----- Verplaatsen: doelenlijst + zichtbaarheidsbevestiging ----- */
.movelist__form { margin: 0; width: 100%; }
.movelist__tile { flex: none; color: var(--color-text); display: flex; align-items: center; justify-content: center; }
.movelist__tile svg { width: var(--icon-lg); height: var(--icon-lg); }
.movelist__body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.movelist__chevron { flex: none; width: var(--icon); height: var(--icon); color: var(--color-faint); }

/* Deel-markering op een bestand-/maptegel: klein poppetje rechtsonder (Dropbox-idioom).
   Vervangt de losse "gedeeld met …"-regel boven de lijst. */
.filetile, .folderlist__tile { position: relative; }
.sharemark {
  position: absolute; right: -3px; bottom: -3px;
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--color-coparent); color: var(--color-on-accent);
  border: 2px solid var(--color-surface);
}
.sharemark svg { width: var(--icon-xs); height: var(--icon-xs); }

/* Mapnaam met mapicoon op een regel (mapweergave). */

/* Dé primaire actie onderaan (mobiel): volle breedte en ruimer dan de inline-knop.
   48px verving de drie feature-kopieën van ~52-54px (.sheet__save/.plan-btn/…, fase 5).
   display: flex (niet block) zodat de basis-centrering van de primitive blijft werken. */
/* Volle breedte (bron: 18/500, padding 17): de hoofdknop onder een formulier of in een sheet. */
.button--block { display: flex; width: 100%; text-align: center; min-height: 56px; font-size: var(--text-lg); }

/* ----- Scholen en opvang / Sport en hobby: één locatie is een groep rijen (ChatGPT-stijl,
   2026-09-29; .setrow + family/children/_waarde_rij). Hieronder alleen nog de no-JS-
   bewerkweergave (?bewerk). ----- */
.school-card__edit-title { font-size: var(--text-base); font-weight: 500; margin: 18px 0 10px; }
.school-card__edit-actions { display: flex; gap: 8px; align-items: center; }
.school-card__enroll-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; font-size: var(--text-sm); }

/* ── Inklapbare sectie (shared/_collapse, 2026-09-17) ──────────────────────────
   Native <details>. De kop leest als een sectiekop (ChatGPT-stijl 2026-09-29: 15 muted,
   16px ingesprongen, dezelfde maat als .vkop), met rechts de samenvatting en de chevron;
   open draait de chevron. Eén vorm, zodat een volgende inklap-plek niet wéér zijn eigen
   marker-reset meebrengt. */
.collapse { display: block; }
.collapse__kop {
  display: flex; align-items: center; gap: 8px; min-height: 28px; margin: 28px 16px 10px;
  list-style: none; cursor: pointer;
}
.collapse__kop::-webkit-details-marker { display: none; }
.collapse__titel { flex: none; font-size: var(--text-15); font-weight: 400; color: var(--color-text-muted); }
.collapse__sub { margin-left: auto; min-width: 0; font-size: var(--text-15); color: var(--color-faint); overflow-wrap: break-word; }
/* Open staan de rijen er zelf onder: de samenvatting zou alleen herhalen. */
.collapse[open] > .collapse__kop .collapse__sub { visibility: hidden; }
.collapse__chevron { flex: none; display: grid; place-items: center; color: var(--color-faint); }
.collapse__chevron svg { width: var(--icon); height: var(--icon); transition: transform var(--dur-fast) var(--curve-decel); }
/* Zonder een sub duwt de chevron zichzelf naar rechts. */
.collapse__kop > .collapse__chevron:nth-child(2) { margin-left: auto; }
/* De actie staat na de chevron: de chevron hoort bij de kop, de knop is een eigen doel. */
.collapse__actie { flex: none; display: inline-flex; margin-right: -8px; }
.collapse[open] > .collapse__kop .collapse__chevron svg { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .collapse__chevron svg { transition: none; }
}

/* Kaart-kebab (scholen, afspraken, overige info — 2026-09-15): één maat en kleur voor het
   menu rechts in een kaart, dezelfde vorm als de kale plus in een sectiekop. */
.kaart__menu { appearance: none; -webkit-appearance: none; flex: none; margin-left: auto; margin-right: -8px; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--color-text-muted); cursor: pointer; }
.kaart__menu svg { width: var(--icon); height: var(--icon); }

/* ===================== GEZINSINSTELLINGEN-LANDING (scherm 20) ===================== */
/* V9 (2026-08-19): dezelfde 16px-zijmarge en onderstand als de kaarten/vlakken
   eronder (.vset__card/.vset__rows) — anders oogt de band niet als deel van
   dezelfde kolom. Top-marge zodat hij niet tegen de sticky vnav-balk aan plakt
   (zelfde 16px als .vset__intro direct onder de balk). Feedback 2026-08-19. */
/* Solo-variant: zacht-zand i.p.v. paars ("je gebruikt Blinco alleen"). */
.gsettings__card { background: var(--color-card); border-radius: var(--radius-groep); overflow: hidden;   box-shadow: var(--shadow-vlak);
 }
.gsettings__row { display: flex; align-items: center; gap: 13px; padding: 14px 16px; border-bottom: 1px solid var(--color-hair); text-decoration: none; color: var(--color-text); }
.gsettings__row--last, .gsettings__row:last-child { border-bottom: none; }
.gsettings__row-icon { flex: none; width: var(--icon); height: var(--icon); color: var(--color-text-muted); }
.gsettings__row-icon svg { width: var(--icon); height: var(--icon); }
.gsettings__row-icon--amber { color: var(--color-text-muted); }
.gsettings__row-icon--danger { color: var(--color-text-muted); }
.gsettings__row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.gsettings__row-title { font-size: var(--text-base); font-weight: 500; }
.gsettings__row-title--danger { color: var(--color-error); }
.gsettings__row-sub { font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 1px; }
.gsettings__hint { font-size: var(--text-xs); color: var(--color-faint); margin: 8px 4px 0; }

/* Archiveren/Verlaten als button_to (form>button) — de knop is de hele rij */
.gsettings__card--actions form { margin: 0; }
.gsettings__row--action {
  width: 100%; border: none; border-bottom: 1px solid var(--color-line);
  background: none; text-align: left; cursor: pointer; font: inherit;
}
.gsettings__card--actions form:last-child .gsettings__row--action { border-bottom: none; }

/* Overzicht-grid (S1) */
.fotoboek__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.fotoboek-card { position: relative; background: var(--color-card); border: 0; border-radius: var(--radius-groep); overflow: hidden; }
.fotoboek-card__body { display: block; text-decoration: none; color: var(--color-text); transition: transform var(--dur-fast) var(--curve-decel); }
.fotoboek-card__body:active { transform: scale(0.97); }
.fotoboek-card__cover {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 1fr;
  gap: 2px;
  aspect-ratio: 1.15;
  background: var(--color-panel);
}
.fotoboek-card__cell { background-size: cover; background-position: center; background-color: rgba(0, 0, 0, 0.04); }
/* Lege vakjes: één neutraal vlak, geen pastelkleur per album meer (testronde J9). */
.fotoboek-card__cell--empty { background-color: var(--color-panel); }
.fotoboek-card__count { position: absolute; right: 7px; bottom: 7px; background: rgba(0, 0, 0, 0.55); color: var(--color-on-accent); font-size: var(--text-10); padding: 2px 7px; border-radius: var(--radius-binnen); }
.fotoboek-card__info { padding: 14px 16px; display: flex; flex-direction: column; }
.fotoboek-card__title { font-size: var(--text-17); font-weight: 400; line-height: var(--leading-kop); }
.fotoboek-card__meta { font-size: var(--text-15); color: var(--color-text-muted); margin-top: 2px; }
.fotoboek-card__status { font-size: var(--text-sm); margin-top: 2px; }
.fotoboek-card__status--amber { color: var(--color-amber); }
.fotoboek-card__status--faint { color: var(--color-faint); }
/* Tikdoel 44px, zichtbaar een rondje van 30px (de gradient) — een vlak van 44 was te zwaar op de cover. */
.fotoboek-card__menu { position: absolute; right: 0; top: 0; width: 44px; height: 44px; border-radius: 50%; background: radial-gradient(circle, rgba(0, 0, 0, 0.45) 15px, transparent 15.5px); border: none; display: grid; place-items: center; cursor: pointer; color: var(--color-on-accent); }
.fotoboek-card__menu svg { width: var(--icon-sm); height: var(--icon-sm); }

/* Album-opties-sheet (kaart-⋯) + content-hoge sheet-variant */
.sheet--compact { height: auto; max-height: 92vh; }
/* ── Fotoboek — album-detail naar ontwerp (S3/S6) ──────────────────────────── */
/* Stroke-stippen i.p.v. dikke gevulde cirkels, voor een pagina-kop-kebab. */

/* Foto-tegel: wrapper + media + overlays + opmerking */
.fotoboek-photo { display: flex; flex-direction: column; padding: 0; border: none; background: none; border-radius: 0; overflow: visible; }
/* Meerdere foto's selecteren (J2, vorm 2026-10-01). In de selectiestand toont elke foto een leeg
   rondje; een gekozen foto wordt donkerder met een wit vinkje op inkt — geen rand. */
.fotoboek-detail.is-selecteren .fotoboek-photo__btn { -webkit-touch-callout: none; user-select: none; }
.fotoboek-photo__btn { position: relative; }
.fotoboek-detail.is-selecteren .fotoboek-photo__btn::after {
  content: ""; position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid var(--color-on-dark); background: rgba(0, 0, 0, 0.2);
  display: grid; place-items: center; color: var(--color-on-btn); font-size: var(--text-sm); font-weight: 500;
}
.fotoboek-photo__btn.is-gekozen::before { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, 0.38); }
.fotoboek-detail.is-selecteren .fotoboek-photo__btn.is-gekozen::after { content: "✓"; background: var(--color-btn); }
/* De selectiebalk is de tabbalk zelf (zelfde .bottom-nav-pil en -tabs); zolang hij staat, is de
   echte tabbalk weg. Op desktop (geen tabbalk) staat hij er ook. */
body:has(.fotoboek-detail.is-selecteren) #bottom-nav { display: none; }
.fotoboek-detail__selectiebalk[hidden],
.fotoboek-detail__selectiebalk .bottom-nav__item[hidden] { display: none; }
.fotoboek-detail__selectiebalk .bottom-nav__item { border: 0; background: none; font-family: inherit; color: var(--color-text); cursor: pointer; }
@media (min-width: 768px) { .fotoboek-detail__selectiebalk:not([hidden]) { display: block; } }
/* Bovenin tijdens het selecteren: een rondje met het aantal erachter (op de plek van de
   feitenregel). Tik = alles, nog een tik = niets; is alles gekozen, dan is het rondje gevuld. */
.fotoboek-detail.is-selecteren .vnav__pagesub { display: none; }
.fotoboek-detail__alles { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; margin: 0 0 8px; padding: 0; border: 0; background: none; font-family: inherit; font-size: var(--text-17); font-weight: 500; color: var(--color-text); cursor: pointer; }
.fotoboek-detail__alles[hidden] { display: none; }
.fotoboek-detail__allesrond { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--color-text); display: grid; place-items: center; color: var(--color-on-btn); font-size: var(--text-sm); }
.fotoboek-detail__alles.is-alles .fotoboek-detail__allesrond { background: var(--color-btn); border-color: var(--color-btn); }
.fotoboek-detail__alles.is-alles .fotoboek-detail__allesrond::after { content: "✓"; }
.fotoboek-photo__media { position: relative; border-radius: var(--radius-groep); overflow: hidden; }
.fotoboek-photo__btn { display: block; width: 100%; padding: 0; border: none; background: none; cursor: pointer; }
.fotoboek-photo__img { display: block; width: 100%; aspect-ratio: 1; background-size: cover; background-position: center; background-color: var(--color-panel); }
/* Voorstel (derden-upload): de duimnagel is het "wat" van de voorstel-kaart. */
.fotoboek-photo__img--voorstel { width: 96px; height: 96px; aspect-ratio: auto; border-radius: var(--radius-binnen); }
.swap-overlay__summary .fotoboek-photo__img--voorstel { margin-top: 4px; }
.fotoboek-photo__cobadge { position: absolute; left: 7px; top: 7px; width: 15px; height: 15px; border-radius: 50%; background: var(--color-coparent); border: 2px solid var(--color-surface); }
.fotoboek-photo__emotion { position: absolute; right: 7px; top: 7px; width: 24px; height: 24px; border-radius: 50%; background: rgba(255, 255, 255, 0.92); display: grid; place-items: center; color: var(--color-text); box-shadow: none; }
.fotoboek-photo__emotion svg { width: var(--icon-xs); height: var(--icon-xs); }
.fotoboek-photo__hiddenform { margin: 0; }
.fotoboek-photo__hidden { position: absolute; inset: 0; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; background: var(--color-panel); border: none; cursor: pointer; color: var(--color-text-muted); }
.fotoboek-photo__hidden svg { width: var(--icon); height: var(--icon); }
.fotoboek-photo__hidden-label { font-size: var(--text-xs); font-weight: 500; }
.fotoboek-photo__hidden-show { font-size: var(--text-xs); font-weight: 500; color: var(--color-accent); }
.fotoboek-photo__comment { font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); margin-top: 5px; padding: 0 2px; }

/* Aanmaak-form (S2) */

.fotoboek-detail__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.fotoboek-photo { padding: 0; border: none; background: none; cursor: pointer; border-radius: var(--radius-groep); overflow: hidden; }
.fotoboek-photo__img { display: block; width: 100%; aspect-ratio: 1; background-size: cover; background-position: center; background-color: var(--color-panel); border-radius: var(--radius-groep); }

/* Fullscreen foto-viewer */
.viewer { margin: 0; padding: 0; border: none; width: 100vw; height: 100dvh; max-width: 100vw; max-height: 100dvh; background: var(--slate-dark); color: var(--color-on-dark); }
.viewer::backdrop { background: rgba(0, 0, 0, 0.85); }
.viewer[open] { display: flex; flex-direction: column; }
.viewer__bar { display: flex; align-items: center; justify-content: space-between; padding: calc(10px + env(safe-area-inset-top, 0px)) 14px 10px; }
.viewer__icon { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: rgba(255, 255, 255, 0.12); color: var(--color-on-dark); border: none; cursor: pointer; }
.viewer__icon svg { width: var(--icon-lg); height: var(--icon-lg); }
.viewer__image { flex: 1; min-height: 0; width: 100%; object-fit: contain; }
.viewer__foot { padding: 12px 18px calc(16px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: 2px; }
/* PDF-frame: zelfde plek als de afbeelding, maar wit — een PDF op een donkere vloer
   leest slecht en de browserlezer tekent z'n eigen chrome. */
.viewer__frame { flex: 1; min-height: 0; width: 100%; border: none; background: var(--color-surface); }
.viewer__fallback { font-size: var(--text-sm); color: var(--color-on-dark); text-decoration: underline; }
/* CSV-tabel: witte leesvloer, horizontaal scrollbaar (een kostenoverzicht is breder dan
   een telefoon) en een plakkende kopregel zodat je bij het scrollen ziet wat wat is. */
.viewer__csvwrap { flex: 1; min-height: 0; overflow: auto; background: var(--color-surface); color: var(--color-text); }
.viewer__csv { border-collapse: collapse; width: max-content; min-width: 100%; font-size: var(--text-sm); }
.viewer__csv th, .viewer__csv td { border: 1px solid var(--color-line); padding: 7px 10px; text-align: left; white-space: nowrap; }
.viewer__csv th { position: sticky; top: 0; background: var(--color-panel); font-weight: 500; }
.viewer__csv tr:nth-child(even) td { background: var(--color-panel); }
.viewer__csv-note, .viewer__csv-error { font-size: var(--text-sm); color: var(--color-text-muted); padding: 12px; margin: 0; }
/* Docx-tekst: leesbare kolom op een witte vloer. Geen opmaak uit het bestand — alleen
   de tekst — dus we geven 'm hier zelf een prettige ritmiek. */
.viewer__doc { padding: 18px 16px; max-width: 62ch; margin: 0 auto; }
.viewer__doc p { font-size: var(--text-base); line-height: var(--leading-lees); margin: 0 0 12px; }
.viewer__caption { font-size: var(--text-base); }
.viewer__by { font-size: var(--text-sm); color: rgba(255, 255, 255, 0.6); }
/* Strook miniaturen onder de foto (J10): horizontaal scrollen binnen de strook, de huidige foto
   met een witte rand; de rest gedempt. */
.viewer__strip { display: flex; gap: 6px; overflow-x: auto; padding: 10px 14px 0; scrollbar-width: none; }
.viewer__strip[hidden] { display: none; }
.viewer__strip::-webkit-scrollbar { display: none; }
.viewer__thumb { flex: none; width: 48px; height: 48px; padding: 0; border: 2px solid transparent; border-radius: var(--radius-binnen); background: center / cover no-repeat; opacity: .55; cursor: pointer; }
.viewer__thumb.is-actief { border-color: var(--color-on-dark); opacity: 1; }

/* Lege staat (S1) — witte kaart met icoon-tegel + kop + subtekst + full-width knop. */
/* Gedeelde lege-staat-placeholder (design "Lege-staat-patroon"): card-loos, gecentreerd —
   zacht icoon-vlak + kop + uitleg + optionele accent-knop. Eén bron voor alle lijst-/
   sectie-schermen (EmptyStateComponent). */
/* Lege staat, app-breed op de ontwerpvorm gezet (§5, 2026-09-03): links uitgelijnd en
   klein, geen icoon en geen centrering. Stond als gecentreerde illustratie met een
   icoontegel van 64px — daarmee was "er is niets" het zwaarste element op het scherm,
   terwijl het een terzijde is. */
.empty-state { display: flex; flex-direction: column; align-items: flex-start; text-align: left; padding: 6px 2px 0; }
/* ChatGPT-stijl (prototype 2026-09-28, "Nog geen …"): titel 17/500, tekst 15 muted, de knop zwart. */
.empty-state__title { margin: 0; font-size: var(--text-17); font-weight: var(--weight-medium); color: var(--color-text); }
.empty-state__text { max-width: 320px; margin: 6px 0 0; font-size: var(--text-15); line-height: var(--leading); color: var(--color-text-muted); text-wrap: pretty; }
.empty-state__btn { display: inline-flex; align-items: center; gap: 8px; margin-top: 20px; padding: 12px 24px; border: none; border-radius: var(--radius-pill); background: var(--color-btn); color: var(--color-on-btn); font-family: inherit; font-weight: 500; font-size: var(--text-base); text-decoration: none; white-space: nowrap; cursor: pointer; transition: transform var(--dur-fast) var(--curve-decel);
  box-shadow: var(--shadow-knop);
}
.empty-state__btn:active { transform: scale(0.97); }
/* Kaart-variant (afspraken-idioom): dezelfde staat op een warme kaart. */
.empty-state--card {
  background: var(--color-card);
  border-radius: var(--radius-groep);
  padding: 16px;
  margin-top: 10px;
  box-shadow: var(--shadow-vlak);
}
.empty-state__btn-icon { width: var(--icon); height: var(--icon); }

/* Deel-modus-keuze (S4a deel-sheet) */

.fotoboek-emotion-remove { margin: 10px 0 0; }
.fotoboek-emotion-remove .button { width: 100%; }

/* ===================== OVERIGE INFO-KLUIS ===================== */
/* Plat (2026-09-13): per soort een gedempte sectiekop en daaronder rijen op het papier met
   haarlijnen — geen kaarten, geen categorie-kleuren (de soort staat al boven de groep), de
   waarde als gewone regel met het oog en kopiëren als kale knoppen. */
.infovault__none { padding: 30px 4px; text-align: center; color: var(--color-text-muted); font-size: var(--text-sm); }

/* Categorie-filter: een keuze-sheet (geopend via het filter-icoon rechtsboven naast "+"). */
.filtersheet { display: flex; flex-direction: column; gap: 3px; }
/* Een filter met meer soorten keuzes (kasboek: periode, categorie, kind) krijgt een kop per blok. */
.filtersheet__kop { margin: 18px 2px 4px; font-size: var(--text-15); font-weight: 400; color: var(--color-text-muted); }
.filtersheet__kop:first-child { margin-top: 0; }
/* Actief filter: klein bolletje (unread-stip-stijl) op het filter-icoon rechtsboven. */
.vnav__action { position: relative; }
.vnav__action--active::after { content: ""; position: absolute; top: 5px; right: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--color-coparent); border: 1.5px solid var(--color-panel); }
/* Rijen; de gekozen stand in inkt met een vinkje (gekozen = inkt, geen accent-vlak). */
.infofilter__opt--active { background: var(--color-selected); }
.infofilter__opticon { display: inline-flex; flex: none; color: var(--color-text); }
.infofilter__opticon svg { width: var(--icon); height: var(--icon); }
.infofilter__optlabel { flex: 1; min-width: 0; }
.infofilter__check { flex: none; width: 18px; height: 18px; color: var(--color-text); }

/* Sectiekop per soort: gedempt, met het kale soort-icoon. */
.infosection { margin-top: 0; }

/* Kluis-rij. */
/* Lichte stijl (2026-09-26, bron OVERIGE INFO): elk item is een grijze kaart. */
/* ChatGPT-stijl (prototype OVERIGE INFO 2026-09-28): een kaart van 26px met de titel op 17 in
   gewoon gewicht en de waarde op 17; de knoppen oog en kopiëren zijn witte cirkels. */
.infocard { padding: 16px 12px 14px 20px; margin-bottom: 10px; background: var(--color-card); border-radius: var(--radius-groep); }
.infocard__head { display: flex; align-items: center; gap: 12px; }
.infocard__headtext { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.infocard__title { font-size: var(--text-17); font-weight: 400; display: flex; align-items: center; gap: 8px; min-width: 0; }
.infocard__kid { flex: none; padding: 2px 8px; border-radius: var(--radius); background: var(--color-card-pressed); color: var(--color-text-muted); font-size: var(--text-15); }
/* De waarde: een gewone regel, het oog en kopiëren kaal en gedempt ernaast. */
.infocard__secret { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.infocard__value { flex: 0 1 auto; min-width: 0; font-size: var(--text-17); color: var(--color-text); overflow-wrap: anywhere; }
.infocard__acts { flex: none; margin-left: auto; display: flex; align-items: center; gap: 8px; }
.infocard__act { appearance: none; -webkit-appearance: none; flex: none; display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: none; border-radius: 50%; background: var(--color-surface); color: var(--color-text); cursor: pointer; }
.infocard__act svg { width: var(--icon); height: var(--icon); }
.infocard__act.is-revealed { color: var(--color-text); }
.infocard__act.is-copied { color: var(--color-text); }
.infocard__shared { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: var(--text-15); color: var(--color-text-muted); }
.infocard__shared svg { flex: none; width: var(--icon-sm); height: var(--icon-sm); }
.infocard__shared--private { color: var(--color-faint); }

/* Actie-sheet (kebab → Bewerken/Verwijderen): rustige rijen, géén knop-look. De X in de
   sheet-kop sluit 'm (geen aparte Annuleren-knop). appearance:none zodat mobiele browsers
   de kale <button> niet als grijze knop tonen. */
.sheetmenu { display: flex; flex-direction: column; gap: 3px; }
.sheetmenu__form { margin: 0; width: 100%; }
/* Eén rijcontract voor de bestaande menu-families; geen wijziging van hun bediening. */
:is(.sheetmenu__item, .mail-actions__item, .coach-actions__item, .movelist__item, .infofilter__opt) {
  appearance: none; -webkit-appearance: none; display: flex; align-items: center; gap: 14px;
  width: 100%; min-height: 56px; padding: 16px 18px;
  border: 1px solid transparent; border-radius: var(--radius-sheet-rij);
  background: var(--color-card); color: var(--color-text);
  font: inherit; font-size: var(--text-17); font-weight: 400; line-height: var(--leading-rij);
  text-align: left; text-decoration: none; overflow-wrap: anywhere; cursor: pointer;
}
.coach-actions__item-icon,
:is(.sheetmenu__item, .mail-actions__item, .coach-actions__item, .movelist__item, .infofilter__opt) svg {
  flex: none; width: var(--icon-lg); height: var(--icon-lg); color: currentColor;
}
:is(.sheetmenu__label, .sheetmenu__rich, .mail-actions__body) { min-width: 0; }
:is(.sheetmenu__richtitle, .plan-choice__title, .mail-actions__label, .movelist__naam) {
  font-size: var(--text-17); font-weight: 400; line-height: var(--leading-rij); overflow-wrap: anywhere;
}
:is(.sheetmenu__richsub, .plan-choice__sub, .mail-actions__hint, .movelist__sub) {
  font-size: var(--text-15); font-weight: 400; line-height: var(--leading-sub);
  color: var(--color-text-muted); overflow-wrap: anywhere;
}
:is(.sheetmenu__item, .mail-actions__item, .coach-actions__item, .movelist__item, .infofilter__opt, .plan-choice):focus-visible {
  outline: 2px solid var(--color-focus); outline-offset: -2px;
}
:is(.sheetmenu__item, .mail-actions__item, .coach-actions__item, .movelist__item, .infofilter__opt, .plan-choice):active { background: var(--color-card-pressed); }
:is(.sheetmenu__item--danger, .mail-actions__item--danger, .coach-actions__item--danger) {
  background: var(--color-error-soft); border-color: var(--color-error-border); color: var(--color-error);
}
:is(.sheetmenu__item--danger, .mail-actions__item--danger, .coach-actions__item--danger):active { background: var(--color-error-soft); }
/* Actieve stand — ook de radiolijst in het afspraakformulier (is-selected, agenda-form). */
.sheetmenu__item--active, .sheetmenu__item.is-selected, .infofilter__opt.infofilter__opt--active { background: var(--color-selected); color: var(--color-text); }
/* Keuze blijft zichtbaar via inktvinkje en neutraal selectievlak; rijmaten blijven gelijk. */
.sheetmenu--vink .sheetmenu__item { font-weight: 400; }
.sheetmenu--vink .sheetmenu__item--active { background: var(--color-selected); color: var(--color-text); }
.sheetmenu__check { margin-left: auto; width: var(--icon); height: var(--icon); }
/* Keuzesheet van een keuzerij (plan-keuze): het vinkje staat in élke rij, alleen zichtbaar bij de gekozen. */
.sheetmenu--vink .sheetmenu__item:not(.sheetmenu__item--active) .sheetmenu__check { visibility: hidden; }
/* Teller en vinkje als vaste kolommen aan de rechterkant: de teller rechts uitgelijnd in
   een eigen breedte, het vinkje altijd even breed — ook zonder vinkje. Zonder die vaste
   plekken verspringt het getal per rij (feedback 2026-09-10). */
.sheetmenu__count { margin-left: auto; min-width: 1.6em; text-align: right; }
.sheetmenu__checkslot { flex: none; width: var(--icon); height: var(--icon); margin-left: 12px; }
/* Meerkeuze-lijst (kinderen, 2026-09-11): dezelfde vink-rijen als de weergavekiezer, maar
   een checkbox i.p.v. een link — aantikken zet een vinkje achter de naam, nog eens tikken
   haalt het weg. De input zelf is onzichtbaar; de rij is het raakvlak. */
.sheetmenu--kies .sheetmenu__item { position: relative; cursor: pointer; }
.sheetmenu__box { position: absolute; opacity: 0; width: 0; height: 0; }
.sheetmenu--kies .sheetmenu__check { visibility: hidden; }
.sheetmenu--kies .sheetmenu__item:has(.sheetmenu__box:checked) { color: var(--color-text); background: var(--color-selected); }
.sheetmenu--kies .sheetmenu__item:has(.sheetmenu__box:checked) .sheetmenu__check { visibility: visible; }
.sheetmenu--kies .sheetmenu__item:has(.sheetmenu__box:focus-visible) { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.sheetmenu__checkslot .sheetmenu__check { margin: 0; }

/* ===================== ONDERTEKEN-SHEET (design consentSign) ===================== */
.consent-sign { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 4px 2px 2px; }
.consent-sign__icon { color: var(--color-text-muted); display: flex; margin-bottom: 14px; }
.consent-sign__icon svg { width: var(--icon-lg); height: var(--icon-lg); }
.consent-sign__body { font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); margin: 0 4px 18px; }
.consent-sign__submit { width: 100%; }

/* ===================== AFSPRAKEN-SCHERM (design 'afspraken') ===================== */
/* Plat (2026-09-13): de vastleg-actie is een tekstactie in accent (zoals "+ Toevoegen" op het
   kind-scherm), geen vlak; elke afspraak is een blok op het papier met een haarlijn eronder. */

/* ChatGPT-stijl (prototype AFSPRAKEN 2026-09-28): elke afspraak een grijze kaart van 26px,
   10px ertussen; de groepskop (Voorstellen, Vastgelegd, Archief) 17 muted. */
.afspraak-card { margin-bottom: 10px; padding: 14px 16px 15px; border-radius: var(--radius-groep); background: var(--color-card); }
.afspraak-card--flush { padding: 14px 16px 15px; }
.afspraak-card--archived { opacity: .82; }
.afspraak-card__row { display: flex; gap: 12px; }
/* Het vinkje kaal in groen (akkoord = betekenis), zonder tegeltje. */
.afspraak-card__check { flex: none; display: flex; align-items: center; justify-content: center; color: var(--color-green); margin-top: 1px; }
.afspraak-card__check svg { width: var(--icon); height: var(--icon); }
.afspraak-card__body { flex: 1; min-width: 0; }
.afspraak-card__topic { display: inline-block; font-size: var(--text-15); font-weight: 500; color: var(--color-text-muted); background: var(--color-panel); padding: 4px 9px; border-radius: var(--radius-binnen); margin-bottom: 8px; }
.afspraak-card__topic--pending { color: var(--color-amber); background: var(--color-amber-soft); }
.afspraak-card__summary { font-size: var(--text-17); font-weight: 400; line-height: var(--leading); color: var(--color-text); margin: 0; }
.afspraak-card__meta { display: block; font-size: var(--text-15); color: var(--color-faint); margin-top: 7px; }

/* Pending: bevestigen/afwijzen (ontvanger) of wacht + bewerken/intrekken (voorsteller). */
.afspraak-card__actions { display: flex; gap: 9px; margin-top: 12px; }
.afspraak-card__actionform { margin: 0; }
.afspraak-card__actionform--grow { flex: 1; }
.afspraak-card__confirm { width: 100%; text-align: center; background: var(--color-btn); color: var(--color-on-btn); font: inherit; font-weight: 500; font-size: var(--text-sm); padding: 11px; border: none; border-radius: var(--radius-pill); cursor: pointer; transition: transform .12s ease;
  box-shadow: var(--shadow-knop);
}
.afspraak-card__confirm:active { transform: scale(.97); }
.afspraak-card__decline { text-align: center; background: var(--color-surface); color: var(--color-text-muted); font: inherit; font-weight: 500; font-size: var(--text-sm); padding: 11px 16px; border: 1px solid var(--color-line); border-radius: var(--radius-groep); cursor: pointer; }
.afspraak-card__waitrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--color-hair); }
.afspraak-card__wait { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-15); color: var(--color-amber); }
.afspraak-card__wait svg { width: var(--icon-xs); height: var(--icon-xs); }
.afspraak-card__ownactions { display: flex; gap: 14px; align-items: center; }
.afspraak-card__linkbtn { background: none; border: none; padding: 0; font: inherit; font-size: var(--text-15); font-weight: 500; color: var(--color-accent); cursor: pointer; }
.afspraak-card__linkbtn--faint { color: var(--color-faint); }
.afspraak-card__linkform, .afspraak-card__restoreform { margin: 0; display: inline; align-self: center; flex: none; }

/* Vervolg-voorstel-blokken (wijziging=amber, beëindigen=rood, herstellen=groen). */
.afspraak-card__proposal { margin-top: 10px; padding: 10px 12px; border-radius: var(--radius-groep); }
.afspraak-card__proposal--edit { background: var(--color-amber-soft); border-top-color: var(--color-amber-border); }
.afspraak-card__proposal--end { background: var(--color-error-soft); border-top-color: var(--color-error-border); }
.afspraak-card__proposal--restore { background: var(--color-green-soft); border-top-color: var(--color-green-border); }
.afspraak-card__proposal-label { display: block; font-size: var(--text-xs); font-weight: 500; margin-bottom: 6px; }
.afspraak-card__proposal--edit .afspraak-card__proposal-label { color: var(--color-amber); }
.afspraak-card__proposal--end .afspraak-card__proposal-label { color: var(--color-error); }
.afspraak-card__proposal--restore .afspraak-card__proposal-label { color: var(--color-text); }
.afspraak-card__proposal-text { font-size: var(--text-15); line-height: var(--leading); margin: 0; }
.afspraak-card__proposal--edit .afspraak-card__proposal-text { color: var(--color-amber-deep); }
.afspraak-card__proposal--end .afspraak-card__proposal-text { color: var(--color-error-deep); font-weight: 400; }
.afspraak-card__proposal--restore .afspraak-card__proposal-text { color: var(--color-text); font-weight: 400; }
.afspraak-card__proposal-actions { display: flex; gap: 9px; margin-top: 11px; }
.afspraak-card__proposal-confirm { width: 100%; text-align: center; color: var(--color-on-accent); font: inherit; font-weight: 500; font-size: var(--text-sm); padding: 10px; border: none; border-radius: var(--radius-groep); cursor: pointer; }
.afspraak-card__proposal-confirm--edit { background: var(--color-amber); }
.afspraak-card__proposal-confirm--end { background: var(--color-error); }
.afspraak-card__proposal-confirm--restore { background: var(--color-green); }
.afspraak-card__proposal-decline { text-align: center; background: var(--color-surface); font: inherit; font-weight: 500; font-size: var(--text-sm); padding: 10px 14px; border: none; border-radius: var(--radius-groep); cursor: pointer; }
.afspraak-card__proposal-decline--edit { color: var(--color-amber); }
.afspraak-card__proposal-decline--end { color: var(--color-error); }
.afspraak-card__proposal-decline--restore { color: var(--color-text); }
.afspraak-card__proposal-waitrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.afspraak-card__proposal-wait { font-size: var(--text-xs); font-weight: 500; }
.afspraak-card__proposal--edit .afspraak-card__proposal-wait { color: var(--color-amber); }
.afspraak-card__proposal--end .afspraak-card__proposal-wait { color: var(--color-error); }
.afspraak-card__proposal--restore .afspraak-card__proposal-wait { color: var(--color-text); }

/* Lege staten + voetnoot. */
/* Lege staat: shared EmptyStateComponent met card: true — geen eigen defs meer. */
.afspraken__nomatch { display: flex; flex-direction: column; align-items: center; text-align: center; padding: 34px 24px; }
.afspraken__nomatch-title { font-size: var(--text-17); font-weight: 500; }
.afspraken__nomatch-link { margin-top: 12px; font-size: var(--text-15); font-weight: 500; color: var(--color-accent); }

/* Vastleg-sheet: onderwerp-chips (radio-pills). */
.afspraak-form__chips { display: flex; flex-wrap: wrap; gap: 7px; margin: 4px 0 6px; }
.afspraak-form__chip { position: relative; }
.afspraak-form__chip-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.afspraak-form__chip-label { display: inline-block; padding: 8px 14px; border-radius: var(--radius-pill); font-size: var(--text-sm); font-weight: 500; cursor: pointer; background: var(--color-surface); color: var(--color-text-muted); border: 1px solid var(--color-line); transition: transform .12s ease; }
.afspraak-form__chip-label:active { transform: scale(.95); }
.afspraak-form__chip-input:checked + .afspraak-form__chip-label { background: var(--color-btn); color: var(--color-on-btn); border-color: var(--color-btn); }
.afspraak-form__chip-input:focus-visible + .afspraak-form__chip-label { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* ── Kind toevoegen-sheet: herindeling + 2-staps-wizard ─────────────────────── */
/* Kind toevoegen én bewerken staan sinds 2026-09-14 in het afspraak-idioom (één formulier,
   rijen met een paneel of een veld óp de rij); de eigen naam-/uitklapper-/ouderkaart-regels
   en de detail-hub (kindhub) zijn daarmee vervallen. Wat rest: de gezag-kop in het
   rol-paneel, het figuurtje boven de velden en verwijderen eronder. */
.kindf__figuur-rij { display: flex; padding: 4px 2px 12px; }
.kindf__figuur { flex: none; overflow: hidden; width: 56px; height: 56px; border-radius: var(--radius-groep); background: var(--kid-color, var(--color-panel)); color: var(--color-on-accent); display: grid; place-items: center; font-family: var(--font-display); font-weight: 500; font-size: var(--text-24); }

/* ===================== UTILITIES ===================== */
/* Verticale ritmiek (DRY): één vaste maat tussen gestapelde blokken via de aangrenzende-
   sibling-selector — geen losse margins per kind. Nul de eigen verticale marges van directe
   kinderen zodat component-margins de ritmiek niet doorbreken. Override de maat met
   --stack-gap (bv. style="--stack-gap: 12px"). Staat laat in het bestand zodat de
   margin-reset component-regels wint. */
/* Dubbele class = specificiteit (0,2,0): de margin-reset moet ook winnen van feature-CSS
   die NÁ application.css laadt (kasboek, parenting_plan, home…). Met één class bleven de
   eigen marges van componenten staan en was de ritmiek per scherm anders — precies wat
   .stack moet oplossen (gevonden bij de sweep 2026-07-27). */
.stack { display: flex; flex-direction: column; }
.stack.stack > * { margin-block: 0; }
.stack.stack > * + * { margin-top: var(--stack-gap, var(--space-5)); }
/* Een stapel LOSSE kaarten staat dichter op elkaar dan losse blokken: de kaart zet zich
   al af met zijn eigen vlak, dus 12px is genoeg. Stond als eigen --stack-gap-regel per
   feature (noodkaart, gezin-hub); dit is dezelfde maat, één keer. */
.stack--kaart { --stack-gap: var(--space-3); }
/* Formulier-ritmiek binnen een stack (2026-07-27): een label hoort strak op z'n control,
   en de primaire actie krijgt méér lucht dan de blok-maat. Velden dragen binnen een stack
   geen eigen ondermarge — de container deelt uit, het element niet. Zelfde regel als de
   plan-editor-ritmiek (parenting_plan.css), andere container. */
.stack > :is(.sheet__label, .form__label) + * { margin-top: var(--space-2); }
.stack .zw-field > .sheet__label { margin-bottom: var(--space-2); }
.stack > :is([type="submit"], .button--block) { margin-top: var(--space-6); }

/* Ja/nee/akkoord/niet akkoord/intrekken op de huidige verdeling (_voorstel_acties). */
.omgang__status-acties { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-2); }

/* ═══════════ /dev/stijlgids (alleen local — Dev::StyleguidesController) ═══════════
   Chrome van de primitive-catalogus. Bewust minimaal: de getoonde primitives dragen hun
   eigen echte classes; .sg-* is alleen de lijst eromheen. */
.sg { max-width: 640px; margin: 0 auto; padding: var(--space-6) var(--space-4) 80px; }
.sg__title { font-size: var(--text-22); font-weight: 500; margin: 0; }
.sg__lede { font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading); margin: 6px 0 0; }
.sg__section { margin-top: 34px; }
.sg__h { font-size: var(--text-base); font-weight: 500; margin: 0 0 4px; }
.sg__note { font-size: var(--text-xs); color: var(--color-text-muted); line-height: var(--leading); margin: 0 0 12px; }
.sg__row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-start; margin-top: var(--space-3); }
.sg__demo { --stack-gap: var(--space-3); margin-top: var(--space-3); }
.sg__name { font-size: var(--text-xs); color: var(--color-faint); word-break: break-all; }
.sg__radius, .sg__shadow {
  display: flex; flex-direction: column; gap: 2px; padding: var(--space-3);
  background: var(--color-surface); border: 1px solid var(--color-line);
  font-size: var(--text-xs); color: var(--color-text-muted);
}
.sg__shadow { border-radius: var(--radius-groep); border-color: transparent; }
.sg__shadow-note { color: var(--color-faint); }
.sg__h3 { margin: var(--space-5) 0 4px; font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.sg__accent-demo { flex: 1; min-width: 220px; }
.sg__accent-label { display: block; margin-bottom: 6px; font-size: var(--text-xs); color: var(--color-green); }
.sg__accent-label--fout { color: var(--color-error); }
.sg__accent-demo .vset__card { margin: 0; }
.sg__radius code, .sg__shadow code { font-weight: 500; color: var(--color-text); }
.sg__type { margin: 0; }
.sg__iconsample { width: 100%; height: 100%; }
.sg__rules { margin: var(--space-3) 0 0; padding-left: 18px; font-size: var(--text-sm); color: var(--color-text-muted); line-height: var(--leading-lees); }
.sg__rules li { margin-bottom: 6px; }

/* Contactdetail V9: nav-rij (terug + potlood) en de rustige "mag ophalen"-pil. */
.contact-detail__pill {
  margin-top: 4px;
  padding: 5px 12px;
  border-radius: var(--radius-pill);
  background: var(--color-hover);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* ===================== AGENDA (bron `Agenda - bron.dc.html`, herzien 2026-09-09) =====================
   Kop + weekstrook, de vier weergaven (lijst · dag · week · maand), de zwevende plus en de
   detailschermen (Kinderen bij jou, afspraak). Maten en kleuren komen uit tokens.css; waar
   een maat geen token heeft staat 'ie hier als getal, zoals in de bron. */

/* ---- Weekstrook (§2): dagkoppen 10px muted (vandaag accent), cijfers 15px in een cirkel
   van 28 — de gekozen dag inkt/wit. Geen stipjes. ---- */
.agenda-mobile__dow--today { color: var(--color-accent); }
.agenda-mobile__strook { display: flex; gap: 4px; }
.agenda-mobile__strook-cel {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 34px; padding: 3px 0; text-decoration: none; color: var(--color-text);
}
/* Afgerond vierkant, geen cirkel (feedback 2026-09-10): de zwevende plus rechtsonder is een
   gevulde cirkel, en twee gevulde rondjes op één scherm lezen als twee knoppen. Dezelfde vorm
   als de vandaag-knop in de kop. line-height op de volle hoogte + tabular-nums, anders hangt
   het cijfer net boven het midden van zijn vlak. */
.agenda-mobile__strook-cel .agenda-mobile__strook-num {
  width: 28px; height: 28px; border-radius: var(--radius);
  display: flex; align-items: center; justify-content: center;
  /* line-height: 1 - met een line-height van 28px (de volle hoogte) verdeelt de browser de
     overgebleven ruimte naar de ascender en de descender van het lettertype, en die zijn niet
     gelijk: het cijfer kwam daardoor scheef in zijn vlak te staan (feedback 2026-09-10). Met
     een strak lijnvak centreert flexbox de cijferbox zelf. */
  font-size: var(--text-base); font-weight: 500; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.agenda-mobile__strook-cel--sel .agenda-mobile__strook-num { background: var(--color-btn); color: var(--color-on-btn); }
/* Stip op een dag met een afspraak (2026-09-17). Neutraal, want hij zegt "hier staat iets",
   niet van wie — de ouder-tint ging er op 2026-09-10 juist uit. 4px, met een vaste regel
   eronder zodat een dag zónder stip even hoog blijft en de rij niet gaat hobbelen.
   Op de gekozen dag (inkt-vlak) zou een gedempte stip wegvallen: die krijgt de inkt-tekst. */
/* Agenda-lijn in de weekstrook (M1): 4px onder het cijfer, over de volle breedte van de dag. */
.agenda-mobile__lijn { align-self: stretch; height: 4px; margin: 3px -2px 0; background: var(--lijn, none); }
.agenda-mobile__stip {
  display: block; width: 4px; height: 4px; margin-top: 3px;
  border-radius: 50%; background: var(--color-text-muted);
}
.agenda-mobile__strook-cel, .agenda-mobile__strook-weekcel { padding-bottom: 0; }
.agenda-mobile__strook-cel::after, .agenda-mobile__strook-weekcel::after {
  content: ""; display: block; width: 4px; height: 7px;
}
.agenda-mobile__strook-cel:has(.agenda-mobile__stip)::after,
.agenda-mobile__strook-weekcel:has(.agenda-mobile__stip)::after { display: none; }
.agenda-mobile__strook-cel--sel .agenda-mobile__stip { background: var(--color-on-btn); }
/* Kader om vandaag: één vlak over de kolom, zie .agenda-mobile__vandaagkader. */
/* De vier volgende weken: dicht = hoogte 0; de controller (agenda-mobile) schuift ze open
   (.34s cubic-bezier(.32,.72,0,1)) en de agenda zakt mee. Cellen 14px op radius 12; dagen
   bij de andere ouder in de co-ouder-tint (bron). */
.agenda-mobile__strook-meer { height: 0; overflow: hidden; padding-top: 4px; }
.agenda-mobile__strook-rij { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px 4px; padding-bottom: 2px; }
.agenda-mobile__strook-weekcel {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 34px; padding: 3px 0;
  border-radius: var(--radius-binnen); text-decoration: none; color: var(--color-text);
  font-size: var(--text-sm); font-weight: 500; line-height: 1;
}
/* Géén ouder-tint op een weekcel: bij een week-om-week-ritme kleurt elke tweede rij
   volledig mee en wordt de uitgeklapte maand een gestreepte tabel (feedback 2026-09-10 —
   zelfde reden als in het maandraster op 2026-09-09). Sinds M1 (2026-10-01) staat bij wie de
   kinderen zijn als lijn onder het nummer (.agenda-mobile__lijn). */
/* Greep (34×4, faint) met chevron; staat onder de uitgeklapte weken. Open = chevron om. */
.agenda-mobile__expander {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; padding: 9px 0 4px; margin: 0; border: 0; background: none; cursor: pointer;
}
.agenda-mobile__expander:active { opacity: .5; }
/* De greep is het hele signaal: geen chevron ernaast — de streep zegt al dat je kunt
   trekken, en open/dicht blijkt uit wat je ziet. */
.agenda-mobile__grip { flex: none; }
/* Vandaag-knop in de kop (Outlook-voorbeeld 2026-09-09): het dagnummer van vandaag in een
   vierkantje; tik brengt je terug naar vandaag in de weergave waar je in staat. */
.agenda-mobile__vandaagnum {
  display: grid; place-items: center; width: 26px; height: 26px;
  border: 1.5px solid var(--color-text); border-radius: var(--radius-binnen);
  font-size: var(--text-xs); font-weight: 500; line-height: 1; font-variant-numeric: tabular-nums;
}

/* Maand-label in de kop: tikbaar (opent de datumkiezer), geen dropdown-caret. */
.agenda-mobile__monthwrap { position: relative; display: inline-flex; }
.agenda-mobile__monthlabel {
  font-size: var(--text-base); font-weight: 500; min-width: 104px; text-align: center; text-transform: capitalize;
  border: 0; background: none; color: inherit; font-family: inherit; padding: 4px 2px; cursor: pointer;
}
/* In de WEEKweergave staan de zeven dagen recht boven de zeven kolommen van het rooster.
   Die kolommen beginnen ná de tijdkolom (.agenda-week__cols), terwijl de strook over de volle
   breedte liep — een afspraak op woensdag stond daardoor niet onder "wo" (feedback
   2026-09-10). In dag, lijst en maand blijft de strook vol: daar is niets om onder te vallen. */
.agenda-mobile__dows,
.agenda-mobile__strook,
.agenda-mobile__strook-rij { padding-left: var(--tijd-kolom); }
/* Weeknummer in die inspringing (feedback 2026-09-10, Samsung-/Outlook-voorbeeld): de ruimte
   is er toch, want de strook moet boven de kolommen van het rooster uitkomen. Alleen in de
   weekweergave - elders springt de strook niet in en is er geen plek. Kaal getal, zoals de
   weeknummerkolom in het maandraster; "Week 37" staat in het aria-label. Absoluut geplaatst,
   zodat de zeven dagen niet opschuiven en het kader om vandaag blijft kloppen. */
.agenda-mobile__strook,
.agenda-mobile__strook-rij { position: relative; }
.agenda-mobile__weeknr {
  position: absolute; left: 0; top: 0; bottom: 0; width: var(--tijd-kolom);
  display: grid; place-items: center;
  font-size: var(--text-10); font-weight: 500; color: var(--color-faint);
  font-variant-numeric: tabular-nums;
}

/* Kader om vandaag (feedback 2026-09-10, Google-voorbeeld). Eén absoluut vlak over de
   weekdag-kolom in plaats van een randje per cel: dicht is het één cel hoog, en zodra de
   strook openschuift groeit het mee naar beneden over alle dagen van die weekdag. Losse
   randjes per cel zouden bij het openen een stapel doosjes met gaten worden.
   De breedte is één van zeven kolommen met 4px ertussen; --inset is de tijdkolom waarmee de
   strook in de weekweergave inspringt. */
.agenda-mobile__kolommen { position: relative; --inset: var(--tijd-kolom); }
.agenda-mobile__vandaagkader {
  --kolombreedte: calc((100% - var(--inset) - 24px) / 7);
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--inset) + (var(--kolombreedte) + 4px) * var(--vandaag-kolom));
  width: var(--kolombreedte);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  pointer-events: none;
}
.agenda-weekwrap--week .agenda-week__allday { margin-left: var(--tijd-kolom); }
.agenda-mobile__week { margin-bottom: 2px; }
.agenda-mobile__dows { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 2px; }
.agenda-mobile__dow { text-align: center; font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.agenda-mobile__dow--today { color: var(--color-accent); }
/* De strook staat vast op --bg; een fluister-schaduw op de onderrand laat het witte
   agendadeel eronder doorschuiven (bron). */
.agenda-mobile { box-shadow: 0 7px 9px -7px rgba(60, 33, 18, .20); }

/* ---- Zwevende plus (§1): .contact-fab uit Contact/Mail; hier een <button>. Weg zodra
   een sheet openstaat. ---- */
.agenda-layout:has(dialog[open]) .contact-fab { display: none; }

/* ---- Rooster-scroller: lijst en maand scrollen zelf (de agenda-shell staat op
   overflow:hidden omdat dag/week bínnen .agenda-week scrollen). ---- */
.agenda-page__grid--scroll { overflow-y: auto; overscroll-behavior: contain; }

/* Slotmelding: het antwoord op een vergrendelde rij, midden onder de duim en boven de
   tabbalk. Deze regels verdwenen per ongeluk mee toen de gezinshub werd opgeheven
   (a0931d0c) — de controller en het slotknop-helper bleven wél in gebruik, dus elk slotje
   in de app zei sindsdien niets zichtbaars (gevonden 2026-09-16). Bewust géén
   Turbo-toast-container: die hoort rechtsonder bij de berichten. */
.slotmelding {
  position: fixed;
  left: 50%;
  bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom, 0px) + var(--space-3));
  transform: translateX(-50%);
  z-index: 1100;
  max-width: min(30rem, calc(100vw - 2 * var(--space-4)));
  padding: 11px var(--space-4);
  background: var(--color-btn);
  color: var(--color-on-btn);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-16);
  font-size: var(--text-sm);
  line-height: var(--leading);
  text-align: center;
  animation: slotmelding-in 0.18s var(--curve-decel) both;
}
/* De uitweg: een vergrendelde rij mag niet alleen "nee" zeggen maar wijst waar het wél
   kan (2026-09-16). Onderstreept, want op een gevuld vlak is kleur geen verschil. */
.slotmelding__weg { color: inherit; text-decoration: underline; white-space: nowrap; margin-left: 6px; }
@keyframes slotmelding-in {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) { .slotmelding { animation: none; } }
/* Lege lijst: de lege staat leunt op de kantlijn van zijn container, maar de lijstweergave
   loopt bewust full-bleed (geen --padded). Daardoor plakte "Nog geen afspraken" tegen de
   linkerrand en hing het strak onder de weekstrook (2026-09-16). Hier dus zelf de
   paginakantlijn en lucht; bij zoeken staat de kantlijn al op de container. */
.agenda-page__grid:not(.agenda-page__grid--padded) > .empty-state { padding: 24px var(--page-gutter) 0; }
.agenda-page__grid--padded { padding-inline: var(--page-gutter); }

/* ---- Lijst (§3, herzien 2026-09-09): één doorlopende stroom i.p.v. een kaartje per dag.
   Een lijst hoort door te lopen; zes zwevende kaartjes onder elkaar knippen dat ritme op en
   laten de dag die je leest wegschuiven. De dagkop plakt daarom bovenin tot de volgende dag
   hem wegduwt — LET OP: géén overflow op .agenda-list, want een overflow-doos wordt zélf de
   scrollport en dan doet position:sticky niets meer. Tijdkolom 60px met hairline, 76px lucht
   onderaan (de zwevende plus). ---- */
/* Lichte stijl (2026-09-26, bron AGENDA lijst): elke dag is een grijze kaart op de grijze
   grond, met de dagkop bovenin en een haarlijn boven elke afspraak. */
.agenda-list { background: var(--color-bg); padding: 12px var(--page-gutter) 76px; }
/* Eén dag = een kop en daaronder een groep rijen (conventions §3.5, 2026-10-01): elke afspraak,
   wissel of voorstel een eigen grijs vlak, 3px ertussen, 26px buiten- en 6px binnenhoek, geen
   haarlijnen. De kop staat er los boven, zoals een sectiekop. */
.agenda-list__card { display: flex; flex-direction: column; gap: 3px; }
.agenda-list__card > :not(.agenda-list__cardhead) { background: var(--color-card); border-radius: var(--radius-binnen); }
.agenda-list__card > .agenda-list__cardhead + * { border-top-left-radius: var(--radius-groep); border-top-right-radius: var(--radius-groep); }
.agenda-list__card > :last-child { border-bottom-left-radius: var(--radius-groep); border-bottom-right-radius: var(--radius-groep); }
.agenda-list, .agenda-list__blok { --stack-gap: 14px; }
/* Is er een vangnet, dan IS dat de vrije ruimte onder de lijst — anders kwam die 76px er
   nog een keer bovenop en zweefde het laadringetje halverwege een leeg vlak
   (feedback 2026-09-10). */
.agenda-list:has(.agenda-list__meer) { padding-bottom: 0; }
/* De dagkop schuift gewoon mee onder de weekstrook door (feedback 2026-09-10). Hij plakte
   bovenin, maar een dag zonder afspraken is niet hoger dan zijn eigen kop: die bleef dan nul
   pixels plakken en werd meteen door de volgende overschreven — een harde wissel in plaats
   van een beweging. Wélke dag je bekijkt staat al in de weekstrook en het maandlabel, die
   allebei meelopen met de bovenste dag (agenda-list-controller). De haarlijn blijft: hij
   scheidt de kop van zijn rijen. */
.agenda-list__cardhead { display: flex; align-items: baseline; gap: 8px; padding: 2px 16px 7px; }
/* Lucht tussen twee dagen — genoeg om de dagen te scheiden, niet zoveel dat er een halve
   dag minder op het scherm past (feedback 2026-09-12: de lijst mocht compacter). De dagkop
   zelf en de rijen gaven elk ook een paar pixels terug. */
/* Vangnet onderaan de lijst: normaal geen hoogte, alleen een plek die in beeld kan komen.
   Terwijl het volgende venster onderweg is groeit hij tot een ringetje, zodat je ziet dat
   er iets gebeurt in plaats van tegen een lege onderrand te kijken (feedback 2026-09-10). */
/* Het vangnet draagt de vrije ruimte voor de zwevende plus, en het ringetje staat onderin
   die ruimte — niet erboven, want dan blijft er een half scherm wit onder staan. */
.agenda-list__meer {
  box-sizing: border-box;
  height: 76px;
  display: grid;
  place-items: end center;
  padding-bottom: 18px;
}
.agenda-list__meer--laden::after {
  content: "";
  width: 16px;
  height: 16px;
  border: 2px solid var(--color-line);
  border-top-color: var(--color-text-muted);
  border-radius: 50%;
  animation: spin 0.65s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .agenda-list__meer--laden::after { animation: none; border-top-color: var(--color-line); }
}
.agenda-list__dayname { margin: 0; font-size: var(--text-sm); font-weight: 500; color: var(--color-text); }
.agenda-list__dayname--today { color: var(--color-accent); }
.agenda-list__daydate { font-size: var(--text-xs); font-weight: 500; color: var(--color-faint); }
/* "bij jou" rechts in de kop met een stip in de kleur van die ouder; tikbaar naar
   Kinderen bij jou. */
.agenda-list__who {
  margin-left: auto; display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); text-decoration: none;
}
/* Geen kleur = de solo-placeholder (Agenda::ParentColors#for geeft bewust nil voor de
   andere ouder zonder account). De terugval was --color-accent: precies de kleur van de
   kijker zelf, dus "bij jou" en "bij de andere ouder" kregen hetzelfde bolletje
   (testsessie 2026-09-16). Zonder persoonskleur hoort neutraal, niet die van jou. */
/* De lijn als sleutel vóór "bij jou" (M1, 2026-10-01): dezelfde lijn als onder het dagnummer. */
.agenda-list__whodot { flex: none; width: 14px; height: 4px; background: var(--lijn, var(--dot-color, var(--color-text-muted))); }
/* Rijen dragen geen lijnen: niet tussen elkaar en niet naast de tijd. Een tijdkolom die
   uitlijnt IS al een kolom — daar hoeft geen streep bij. Top-uitgelijnd, zodat de tijd op de
   titel staat en niet halverwege een rij van drie regels hangt. */
.agenda-list__item {
  display: flex; align-items: flex-start; gap: 12px; padding: 14px 18px 14px 16px;
  text-decoration: none; color: var(--color-text);
}
a.agenda-list__item:active { background: var(--color-card-pressed); }
.agenda-list__time { flex: none; width: 56px; padding-top: 1px; font-variant-numeric: tabular-nums; }
/* De tijd is de kolom náást de titel, niet de titel zelf: een trede lager houdt de
   rangorde zichtbaar (de titel leidt). */
.agenda-list__hour { display: block; font-size: var(--text-sm); font-weight: 500; line-height: var(--leading); white-space: nowrap; color: var(--color-text-muted); }
/* Overdracht: kaal wisselicoon 17px in muted tussen tijd en titel — geen tegel. */
.agenda-list__swapicon { flex: none; margin-top: 2px; width: var(--icon-sm); height: var(--icon-sm); color: var(--color-text-muted); }
.agenda-list__body { flex: 1; min-width: 0; }
.agenda-list__title { display: block; font-size: var(--text-base); font-weight: 500; }
.agenda-list__sub { display: block; margin-top: 1px; font-size: var(--text-sm); color: var(--color-text-muted); }
/* "Wacht op akkoord" onder een rij: amber tekst, geen pil (signaal = gekleurde tekst). */
.agenda-list__wacht { display: inline-block; margin-top: 3px; font-size: var(--text-sm); color: var(--color-amber); }
/* Lege dag in een kaart ("Geen afspraken op deze dag"). */
.agenda-list__empty { margin: 0; padding: 14px 16px 18px; font-size: var(--text-15); color: var(--color-text-muted); }
/* Verjaardag in een kaart: hoort bij de hele dag, niet bij een rij. */

/* ---- Dag & week (§3): vaste band (balk + linten) boven een raster van 45px per uur op
   --card met de uurlabels ín het raster; geen verticale lijnen, geen urenkolom. ---- */
/* Het rooster is één wit vlak dat direct onder de weekstrook begint. De gaten in de layout
   lieten daar een band paginagrond zien, precies onder de schaduw van de strook
   (feedback 2026-09-10). */
.agenda-weekwrap { display: flex; flex-direction: column; flex: 1; min-height: 0; background: var(--color-surface); }
.agenda-week__fixed { flex: none; padding: 6px var(--page-gutter) 0; }
.agenda-layout:has(.agenda-weekwrap),
.agenda-layout:has(.agenda-list) { gap: 0; }
.agenda-layout:has(.agenda-weekwrap) .agenda-main,
.agenda-layout:has(.agenda-weekwrap) .agenda-body,
.agenda-layout:has(.agenda-list) .agenda-main,
.agenda-layout:has(.agenda-list) .agenda-body { gap: 0; }
/* De scroller zelf draagt het wit: anders zie je onder de schaduw van de weekstrook een
   bandje paginagrond zodra de lijst korter is dan het scherm (feedback 2026-09-10). */
.agenda-page__grid--scroll:has(.agenda-list) { background: var(--color-bg); }
/* Balk "Kinderen bij X": vlak in de zachte kleur van die ouder, tekst 13px/500 in de
   ouderkleur, chevron 15px — opent Kinderen bij jou. */
/* Balk "Kinderen bij X": wit, compact, en hij begint waar de uurlijnen beginnen — hij hoort
   bij het rooster, niet boven de tijdkolom (feedback 2026-09-10). Het vlak was een getinte
   pil over de volle breedte; nu draagt alleen de tekst de ouderkleur, zoals overal in de app
   (conventions: accent is een tekstsignaal, nooit een gevuld vlak). */
/* Begint aan de linkerrand, net als het hele-dag-lint eronder — niet ingesprongen tot de
   uurlijnen (feedback 2026-09-10). Zonder stip en op dezelfde maat als een afspraak: het is
   een regel die zegt bij wie de dag speelt, geen kop. */
.agenda-day__context {
  display: flex; align-items: center; gap: 6px;
  margin: 2px 0 4px; padding: 4px 2px;
  background: var(--color-surface);
  color: var(--event-color, var(--color-accent)); text-decoration: none;
}
.agenda-day__context:active { border-radius: var(--radius); }
.agenda-day__context-text { flex: 1; min-width: 0; font-size: var(--text-xs); }
.agenda-day__context-chev { flex: none; width: var(--icon-xs); height: var(--icon-xs); }
/* Hele-dag-linten: dag één kolom, week zeven (zelfde steek als de strook, 4px ertussen). */
.agenda-week__allday { display: flex; gap: 4px; margin: 4px 0 8px; }
.agenda-week__allday-cell { flex: 1; min-width: 0; min-height: 18px; display: flex; flex-direction: column; gap: 2px; }
.agenda-weekwrap .agenda-week__allday-cell .agenda-event,
.agenda-weekwrap .agenda-week__allday-cell .agenda-birthday {
  display: block; height: auto; min-height: 0; margin: 0; padding: 2px 4px;
  border: 0; border-radius: var(--radius-xs);
  background: color-mix(in srgb, var(--event-color, var(--color-accent)) 11%, var(--color-surface));
  color: var(--event-color, var(--color-accent));
  font-size: var(--text-10); font-weight: 500; line-height: var(--leading);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agenda-weekwrap--day .agenda-week__allday-cell .agenda-event,
.agenda-weekwrap--day .agenda-week__allday-cell .agenda-birthday { padding: 4px 10px; border-radius: var(--radius-binnen); font-size: var(--text-xs); }
.agenda-weekwrap .agenda-week__allday-cell .agenda-event__title { display: inline; font-size: inherit; font-weight: inherit; white-space: inherit; }
.agenda-weekwrap .agenda-week__allday-cell .agenda-event__sub { display: none; }
/* De scroller: vult de resthoogte tot de tabbalk, wit, 18px zijpadding (het raster loopt
   full-bleed, de inhoud niet). */
.agenda-week {
  --hour-height: var(--uur-hoogte);
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 var(--page-gutter); background: var(--color-surface);
}
.agenda-week__canvas {
  position: relative;
  height: calc((var(--end-hour) - var(--start-hour)) * var(--hour-height));
  /* Uurlijn vol, halfuurlijn fijner — dezelfde tweedeling als vóór de canvas-herbouw en
     als in Outlook/Google. Twee lagen, want ze beginnen niet op dezelfde plek: de uurlijn
     loopt onder het uurlabel door (dat label dekt hem af met zijn eigen achtergrond), de
     halfuurlijn heeft daar niets staan en zou dus tot de rand doorlopen. Die springt in
     over de breedte van de labelkolom, zodat beide lijnen op dezelfde x beginnen. */
  background-image:
    repeating-linear-gradient(to bottom, var(--color-hair) 0 1px, transparent 1px var(--hour-height)),
    repeating-linear-gradient(to bottom,
      transparent 0 calc(var(--hour-height) / 2),
      color-mix(in srgb, var(--color-hair) 55%, transparent) calc(var(--hour-height) / 2) calc(var(--hour-height) / 2 + 1px),
      transparent calc(var(--hour-height) / 2 + 1px) var(--hour-height));
  background-position: 0 0, var(--tijd-kolom) 0;
  background-size: 100% 100%, calc(100% - var(--tijd-kolom)) 100%;
  background-repeat: repeat, repeat-y;
}
/* Uurlabel ÓP zijn lijn (het eerste eronder, anders valt het buiten beeld). */
.agenda-week__hour {
  position: absolute; left: 0; width: var(--tijd-kolom); top: calc(var(--row) * var(--hour-height));
  transform: translateY(-50%); padding: 0 4px 0 0; background: var(--color-surface);
  /* Rechts uitgelijnd, tegen de kolommen aan (feedback 2026-09-10). Links uitgelijnd bleef een
     gat van bijna twee cijferbreedtes tussen het getal en het raster staan - ruimte die er als
     padding uitzag. Zelfde keuze als Outlook en Google. De kolom kon daarna van 30 naar 20px:
     "23" is bij deze maat 11,2px breed, plus 4px lucht. Die 10px gaat naar de zeven kolommen,
     want alles wat de kolommen inspringt hangt aan --tijd-kolom. */
  text-align: right;
  font-size: var(--text-10); line-height: var(--leading-kop); color: var(--color-faint); z-index: 1;
}
.agenda-week__hour:first-child { transform: none; }
/* De kolommen beginnen ná de labelkolom — ook in de weekweergave. De bron tekent daar
   kolommen over de volle breedte met de uurlabels eroverheen, maar dan botst een afspraak
   op een heel uur met het label van dat uur (feedback 2026-09-09). Outlook en Google
   houden om dezelfde reden een smalle strook vrij. */
.agenda-week__cols { position: absolute; inset: 0 0 0 var(--tijd-kolom); display: flex; gap: 4px; }
.agenda-week__col { position: relative; flex: 1; min-width: 0; }
/* Afspraak-blok: zachte kleur van de ouder, titel in de ouderkleur; dag ruim (13px + subregel
   11px muted), week compact (9.5px, één regel). */
/* Hoog genoeg voor een titel mét subregel: een kort blok kapte zijn tweede regel halverwege
   af (feedback 2026-09-10). overflow:hidden is het vangnet voor blokken die nóg korter zijn. */
.agenda-weekwrap .agenda-week__event { min-height: 22px; }
.agenda-weekwrap--day .agenda-week__event { min-height: 52px; }
.agenda-weekwrap .agenda-week__col .agenda-event { overflow: hidden; }
.agenda-weekwrap .agenda-week__col .agenda-event {
  gap: 0; padding: 6px 10px; border: 0; border-radius: var(--radius);
  background: color-mix(in srgb, var(--event-color, var(--color-accent)) 11%, var(--color-surface));
  color: var(--event-color, var(--color-accent));
}
.agenda-weekwrap .agenda-event__time,
.agenda-weekwrap .agenda-event__child,
.agenda-weekwrap .agenda-event__creator,
.agenda-weekwrap .agenda-event__owner,
.agenda-weekwrap .agenda-event__badge { display: none; }
.agenda-weekwrap .agenda-event__title { font-size: var(--text-sm); font-weight: 500; line-height: var(--leading); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agenda-weekwrap .agenda-event__sub { display: block; font-size: var(--text-11); line-height: var(--leading); color: var(--color-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agenda-weekwrap .agenda-event--child .agenda-event__title::before { content: none; }
.agenda-weekwrap .agenda-event--proposed { outline: 1px dashed var(--color-amber); outline-offset: -1px; }
.agenda-weekwrap--week .agenda-week__col .agenda-event { padding: 4px 5px; border-radius: var(--radius-binnen); }
.agenda-weekwrap--week .agenda-event__title { font-size: var(--text-10); line-height: var(--leading); }
.agenda-weekwrap--week .agenda-event__sub { display: none; }
/* Overdracht in het raster: blok van 22px op de wisseltijd, zachte kleur van de ontvangende
   ouder. Tik → Kinderen bij jou. */
.agenda-week__handover {
  position: absolute; left: 0; right: 0; top: calc(var(--top) / 60 * var(--hour-height)); z-index: 2;
  display: flex; align-items: center; height: 22px; padding: 0 5px;
  border-radius: var(--radius-binnen); text-decoration: none;
  background: color-mix(in srgb, var(--event-color, var(--color-accent)) 11%, var(--color-surface));
  color: var(--event-color, var(--color-accent));
  font-size: var(--text-10); font-weight: 500; line-height: 1;
}
.agenda-weekwrap--day .agenda-week__handover { padding: 0 10px; font-size: var(--text-xs); border-radius: var(--radius); }
.agenda-week__handover-text { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.agenda-week__handover:active { filter: brightness(.96); }
/* Openstaand wijzigingsverzoek: gestippelde amber rand — nog niet vast. */
.agenda-week__handover--pending { outline: 1px dashed var(--color-amber); outline-offset: -1px; }
/* Nu-tijd (#E0492B): het tijdlabel links ín het raster, de lijn alleen in de kolom van
   vandaag — over zeven dagen zou hij niets zeggen. Met een stip aan het begin, zodat de
   lijn ook tussen de afspraken herkenbaar blijft. Alleen zichtbaar zolang "nu" in het
   uurvenster valt (--has-now via Stimulus). */
.agenda-week__now {
  display: none; position: absolute; left: 0; right: 0;
  top: calc(var(--now-top, 0) / 60 * var(--hour-height));
  height: 1.5px; background: var(--color-now-line); z-index: 3; pointer-events: none;
}
.agenda-week__now::before {
  content: ""; position: absolute; left: -3px; top: 50%; transform: translateY(-50%);
  width: 7px; height: 7px; border-radius: 50%; background: var(--color-now-line);
}
.agenda-week--has-now .agenda-week__now { display: block; }
.agenda-week__now-label {
  display: none; position: absolute; left: calc(var(--tijd-kolom) - 4px); z-index: 3;
  top: calc(var(--now-top, 0) / 60 * var(--hour-height));
  /* Rechterrand gelijk aan de uurlabels; het label groeit naar links de paginamarge in
     (--page-gutter, 18px) in plaats van over de eerste kolom heen. "14:32" is 24,8px breed en
     past daar (2026-09-10). */
  transform: translate(-100%, -50%);
  padding: 0 0 0 3px; background: var(--color-surface);
  /* Roostermaat: "14:31" moet in de smallere labelkolom (30px) passen — op 12px liep de
     laatste cijfer onder de nu-lijn door (2026-09-10). */
  font-size: var(--text-10); font-weight: 500; line-height: var(--leading-kop); color: var(--color-now-line); white-space: nowrap;
}
.agenda-week--has-now .agenda-week__now-label { display: block; }

/* ---- Maand (§3): 7×6 vol-breed op --card, cel ≥ 78px met hairline onder; nummer 12.5px in
   een cirkel van 22 (vandaag panel/accent, gekozen inkt/wit); afspraken als labeltje in de
   zachte kleur van de ouder; "+N"; andere-ouder-dagen in de co-ouder-tint; buiten de maand
   45%. Het raster eindigt tegen de tabbalk, zonder band. ---- */
/* Het raster vult de resthoogte tot de tabbalk (wit tot onder), de dagnamen erboven op --bg. */
.agenda-month { display: flex; flex-direction: column; flex: 1; min-height: 100%; }
/* Acht kolommen: een smalle weeknummer-kolom (Outlook-voorbeeld 2026-09-09) en zeven
   dagen. Die kolom is meteen de linkermarge — de maandag stond eerder tegen de rand. */
.agenda-month { --weeknr-kolom: 30px; }
.agenda-month__daynames { display: grid; grid-template-columns: var(--weeknr-kolom) repeat(7, 1fr); margin-top: 2px; padding: 0 8px 0 0; }
.agenda-month__dayname { text-align: center; padding-bottom: 5px; font-size: var(--text-xs); font-weight: 500; color: var(--color-text-muted); }
.agenda-month__grid { display: grid; grid-template-columns: var(--weeknr-kolom) repeat(7, 1fr); align-content: start; flex: 1; background: var(--color-surface); }
/* Weeknummer: gedempt cijfer op de paginagrond, zodat de kolom als kantlijn leest en
   niet als achtste dag. */
.agenda-month__weeknr {
  display: flex; align-items: flex-start; justify-content: center; padding: 7px 0 0;
  background: var(--color-bg); border-bottom: 1px solid var(--color-hair);
  font-size: var(--text-xs); font-weight: 500; color: var(--color-faint);
}
.agenda-month__cell {
  display: block; min-height: 78px; padding: 2px 3px 3px; overflow: hidden;
  /* Lijn onder én links: zo blijft een reeks dagen bij dezelfde ouder een rij losse
     cellen in plaats van één gekleurde band over de week. */
  border-bottom: 1px solid var(--color-hair); border-left: 1px solid var(--color-hair);
  text-decoration: none; color: var(--color-text);
}
.agenda-month__cell--out { opacity: .45; }
/* Geen ouder-tint op een maandcel: bij een week-om-week-ritme kleurt de hele rij mee en
   wordt het raster een gestreepte tabel. Bij wie de kinderen zijn staat sinds M1 (2026-10-01)
   als lijn van 4px onder het nummer (.agenda-month__lijn) — een lijn, geen vlak. */
.agenda-month__num {
  width: 22px; height: 22px; margin: 0 auto; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--text-sm); font-weight: 500; line-height: 1;
}
/* Alleen vandaag krijgt een cirkel. Er was ook een "gekozen" dag, maar in een maandraster
   bestaat die niet: blader je naar de volgende maand, dan houdt het anker dezelfde dag van de
   maand en stond de 9e in élke maand aangevinkt (feedback 2026-09-09). Bladeren is per maand,
   dus de maand zelf is de keuze. */
.agenda-month__cell--today .agenda-month__num { background: var(--color-btn); color: var(--color-on-btn); }
.agenda-month__label {
  display: block; margin-bottom: 2px; padding: 1px 3px; border-radius: var(--radius-xs);
  background: var(--label-bg, var(--color-panel)); color: var(--label-color, var(--color-text-muted));
  font-size: var(--text-10); font-weight: 500; line-height: var(--leading);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Agenda-lijn (M1, 2026-10-01; conventions §3.3): bij wie de kinderen zijn, 4px direct onder het
   nummer (2px eronder, 3px boven de labels) — een lijn, geen tint op de cel. Leeg = geen lijn,
   de ruimte blijft zodat de rijen niet hobbelen. */
.agenda-month__lijn { display: block; height: 4px; margin: 2px -3px 3px; background: var(--lijn, none); }
.agenda-month__more { display: block; padding-left: 3px; font-size: var(--text-10); font-weight: 500; color: var(--color-text-muted); }

/* Kind-pillen in de agenda-kop (M1): wrappen, nooit horizontaal scrollen. */
.agenda-mobile__kinderen { margin: 2px 0 10px; }
/* Sleutel bij de agenda-lijn (M1), alleen in de maand: 14 muted, 16px ingesprongen. */
.agenda-lijn-legenda { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 0 16px 10px; font-size: var(--text-sm); color: var(--color-text-muted); }
.agenda-lijn-legenda__item { display: inline-flex; align-items: center; gap: 6px; }
.agenda-lijn-legenda__lijn { flex: none; width: 16px; height: 4px; background: var(--lijn); }
.agenda-lijn-legenda__leeg { margin: 0; padding: 0 16px 10px; font-size: var(--text-sm); color: var(--color-text-muted); }

/* ---- Detailschermen (§8/§9): feitrijen, gekleurde eigenaar-regel, acties. ---- */
/* Feitrij zonder icoon (Kinderen bij jou, afspraak-detail): dezelfde kaart-rij, alleen
   platter — label, waarde, optionele subregel onder elkaar. */
.info-card__sub { margin-top: 1px; font-size: var(--text-15); color: var(--color-text-muted); }
/* Herinnering-rij (Kinderen bij jou, overdracht-detail): een <button> in de setrow-vorm die
   de radiolijst opent — zonder de browser-knopvorm. */
/* Kleuren staan hier expliciet, niet op `inherit` (feedback 2026-09-10: de rij kwam in
   terracotta op het scherm terwijl een rijtitel overal elders in de inkt staat en accent
   voorbehouden is aan links en betekenisdragende kleur). Een gedeelde rij die zijn kleur
   uit zijn omgeving haalt, verandert mee met elk scherm waarin hij belandt - deze staat in
   twee schermen. Zelfde ladder als elke andere setrow: titel inkt, waarde muted. */
button.reminder-row { width: 100%; appearance: none; border: 0; font: inherit; font-size: var(--text-17); color: var(--color-text); text-align: left; cursor: pointer; }
button.reminder-row .setrow__title { flex: 1; min-width: 0; color: var(--color-text); }
button.reminder-row .setrow__value { color: var(--color-text-muted); }

/* Radiolijst (blinco-ui.css §6 "radiolijst en vinkje"): rijen van 11px 2px met een ring van
   19px (2px faint); de gekozen rij een accent-ring met een stip van 9px, tekst 15px in de inkt.
   Twee bedieningen, één vorm: een <label> met een native radio erin (herinnering bij
   overdrachten — toetsenbord + autosubmit), of een <button> die z'n stand in aria-checked /
   .is-selected draagt (de keuzerijen in het afspraakformulier, gestuurd door agenda-form).
   Geen gevuld vlak achter de gekozen rij: accent is een tekstsignaal, de ring draagt de stand. */
.radiolist { display: flex; flex-direction: column; margin: 0; gap: 3px; border-radius: var(--radius-groep); overflow: hidden; }
.radiorow { display: flex; align-items: center; gap: 14px; min-height: 60px; padding: 14px 20px; background: var(--color-card); border-radius: var(--radius-binnen); cursor: pointer; }
button.radiorow { width: 100%; appearance: none; -webkit-appearance: none; border: 0; background: var(--color-card); font: inherit; color: inherit; text-align: left; }
button.radiorow:active { background: var(--color-card-pressed); }
.radiorow__input { position: absolute; opacity: 0; width: 0; height: 0; }
.radiorow__ring {
  flex: none; width: 19px; height: 19px; border-radius: 50%; border: 2px solid var(--color-control-border);
  display: flex; align-items: center; justify-content: center;
}
.radiorow:has(.radiorow__input:checked) .radiorow__ring,
.radiorow.is-selected .radiorow__ring,
.radiorow[aria-checked="true"] .radiorow__ring { border-color: var(--color-text); }
.radiorow:has(.radiorow__input:checked) .radiorow__ring::after,
.radiorow.is-selected .radiorow__ring::after,
.radiorow[aria-checked="true"] .radiorow__ring::after { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--color-btn); }
.radiorow:has(.radiorow__input:focus-visible) .radiorow__ring,
button.radiorow:focus-visible .radiorow__ring { outline: 2px solid var(--color-focus); outline-offset: 2px; }
button.radiorow:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
.radiorow__label { font-size: var(--text-17); color: var(--color-text); }
/* Toelichting onder een optie ("Alleen jij ziet deze map"), gedempt (2026-09-13). */
.radiorow__sub { display: block; margin-top: 2px; font-size: var(--text-15); color: var(--color-text-muted); }
/* "Bij jou" / "Bij Sophie" onder de titel: gekleurde tekst 13px/500, geen pil. */
.event-detail__who { margin: -8px 0 16px; font-size: var(--text-sm); font-weight: 500; color: var(--event-color, var(--color-accent)); }
/* Bronregel op Kinderen bij jou ("Kerstvakantie"): 13px/500 in de kleur van de ouder. */
.overdracht-detail__bron { margin: -8px 0 16px; font-size: var(--text-sm); color: var(--event-color, var(--color-text-muted)); }
/* Bewerken als pilknop op volle breedte, Verwijderen als tekstlink in --danger eronder. */
.event-detail__actions { --stack-gap: 14px; align-items: center; margin-top: 8px; }
.event-detail__actions > form { width: 100%; margin: 0; }
.event-detail__actions > form:has(> .event-detail__textlink) { width: auto; }
.event-detail__textlink {
  appearance: none; border: 0; background: none; padding: 6px 12px; font: inherit;
  font-size: var(--text-sm); font-weight: 500; color: var(--color-accent); cursor: pointer;
}
.event-detail__textlink--danger { color: var(--color-error); }

/* ---- Nieuwe afspraak in de lichte stijl (bron NIEUWE AFSPRAAK, 2026-09-27) --------------
   Kop: titel links, kruis rechts, haarlijn eronder. Geen haarlijnen tussen de bovenste
   regels; de datums zijn witte pillen naast elkaar, de tijden grijze vakjes eronder. De
   keuzerijen tonen hun naam links, de waarde rechts (gedempt; leeg "Toevoegen" in accent) en
   een chevron. Opslaan staat onderaan als zwarte knop. */
/* Een full-screen sheet draagt een haarlijn onder zijn kop (lichte stijl, bron NIEUWE AFSPRAAK
   en ALBUM AANMAKEN): het is een eigen scherm, de kop staat vast boven wat scrolt. */
.sheet--full > .sheet__head { padding-bottom: 12px; border-bottom: 1px solid var(--color-hair); }
.agenda-form__velden--afspraak > * + * { border-top: 0; }
/* De wanneer-groep: de tijdrijen kunnen dicht staan, dus de groep knipt zelf zijn hoeken af. */
.agenda-form__wanneer { margin: 14px 0 0; border-radius: var(--radius-groep); overflow: hidden; }
.agenda-form__velden--afspraak > .agenda-form__optcard { margin-top: 16px; }
.agenda-form__velden--afspraak > .agenda-form__field--inline { padding: 18px 4px 4px; }
.agenda-form__voorleg-hint { margin: 4px 4px 0 37px; }
.agenda-form__optsummary--labelrij .agenda-form__opticon { color: var(--color-text-muted); }
.agenda-form__optsummary--labelrij .agenda-form__optname { flex: 1 1 auto; min-width: 0; font-size: var(--text-17); font-weight: 400; }
.agenda-form__optsummary--labelrij .agenda-form__optvalue {
  flex: 0 1 auto; max-width: 50%; font-size: var(--text-15); color: var(--color-text-muted);
}
.agenda-form__optsummary--labelrij .agenda-form__optname + .agenda-form__optvalue::before { content: none; }
.agenda-form__optsummary--labelrij:has(.agenda-form__optvalue--empty) .agenda-form__optname { display: block; }
.agenda-form__optsummary--toevoegen .agenda-form__optvalue--empty { color: var(--color-accent); }
.event-sheet .agenda-form__paginaknop { margin-top: 22px; }

/* Afspraak-detail in de lichte stijl (bron AFSPRAAK DETAIL, 2026-09-27): Bewerken als grijze
   pil op de grijze grond (de kaartkleur), het herinneringsicoon in inkt. */
.event-detail__actions .event-detail__bewerk { background: var(--color-card); }
.info-card__icon--inkt { color: var(--color-text); }

/* Album aanmaken (bron ALBUM AANMAKEN, 2026-09-27): twee even brede velden naast elkaar, de
   kinderen als chips onder een vraag met een hint. */
.form__paar--gelijk > :first-child,
.form__paar--gelijk > :last-child { flex: 1 1 0; min-width: 0; }
.form__row > .chip-radio-group { margin-bottom: 0; }

/* Een datum weer leegmaken (optioneel veld, 2026-09-27): een tekstknop onder Opslaan. */
.picker__wis {
  display: block; width: 100%; margin-top: 8px; padding: 12px;
  appearance: none; border: 0; background: none; font: inherit;
  font-size: var(--text-base); font-weight: 500; color: var(--color-text-muted); cursor: pointer;
  border-radius: var(--radius-pill);
}
/* Een veldfout onder een rij in een grijs keuzevlak: ingesprongen tot de tekst. */
.agenda-form__optcard .veld-fout { margin: -6px 16px 12px calc(16px + var(--icon) + 12px); }
.agenda-form__optsummary--kiezer .datecal__display.is-fout { color: var(--color-error); }

/* Titel en toelichting: één eigenaar voor de 4px tussenruimte. */
.screen-head:has(+ .vnav__pagesub),
.screen-head:has(+ .vset > :is(.vset__intro, .lede):first-child) { margin-bottom: 4px; }
.screen-head + .vset > :is(.vset__intro, .lede):first-child { padding-top: 0; padding-bottom: 0; }
.screen-head + .vset > :is(.vset__intro, .lede):first-child + .vset__group { margin-top: 22px; }
/* Focus/druk op een rij krijgt inkt; oudermarkeringen houden hun eigen kleurrol. */
.setrow--actie:active, .setrow:active .setrow__title--accent { color: var(--color-text); }
.message-row--own .message a:focus-visible { outline-color: var(--color-on-btn); }
.contacts__search:focus-within, .conversation-search:focus-within,
.agenda-mobile__searchbar:focus-within, .contact-picker__search:focus-within {
  outline: 1px solid var(--color-text); outline-offset: -1px;
}
/* Losse tekstarea's behouden hun meerregelige vorm, ook zonder formulierklasse. */
:where(textarea) { border-radius: var(--radius-textarea); }
/* Bestaande checkbox/radio-invoer blijft bedienbaar; alleen de rijvorm wordt gedeeld. */
.sheet .radiorow { min-height: 56px; }
/* Compacte zelfstandige instelling: grijze rij, wit keuzemenu in de native top layer (§3.8). */
.dropdown--keuze > .setrow { width: 100%; border: 0; text-align: left; }
.dropdown--keuze [data-menu-target][hidden] { display: none; }
.dropdown--heading { flex: 1; min-width: 0; }
.dropdown--row { container-type: inline-size; }
/* Op een smalle rij krijgt de waarde een eigen regel; geen geplette titelkolom. */
@container (max-width: 20rem) {
  .dropdown--keuze > .setrow {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 12px;
  }
  .dropdown--keuze > .setrow > .setrow__text { grid-column: 1; }
  .dropdown--keuze > .setrow > .setrow__value { grid-column: 1; max-width: none; text-align: left; }
  .dropdown--keuze > .setrow > .setrow__chevron { grid-column: 2; grid-row: 1 / 3; }
}
.dropdown--keuze .dropdown__trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-card);
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-17);
  text-align: left;
  cursor: pointer;
}
.dropdown--keuze .dropdown__fallback { min-width: 0; }
.dropdown--keuze .dropdown__label { flex: 1; min-width: 0; }
.dropdown--keuze .dropdown__option > svg, .dropdown--keuze .dropdown__count { flex: none; }
.dropdown--keuze .dropdown__count { font-size: var(--text-15); color: var(--color-text-muted); }
.dropdown--keuze .dropdown__footer { padding: 0 20px 8px; background: var(--color-card); }
.dropdown--keuze .dropdown__footer .vsubject__follow { min-height: 44px; }
.vset__rows > .dropdown--keuze:has(.dropdown__footer):last-child > .setrow { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.vset__rows > .dropdown--keuze:last-child > .dropdown__footer { border-radius: 0 0 var(--radius-groep) var(--radius-groep); }
.dropdown--keuze [aria-expanded="true"] .setrow__chevron { transform: rotate(180deg); }
.dropdown--keuze .dropdown__panel {
  display: none;
  position: fixed;
  inset: auto;
  margin: 0;
  width: max-content;
  min-width: min(280px, calc(100vw - 24px));
  padding: 8px;
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-groep);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-16);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.dropdown--keuze .dropdown__panel:popover-open { display: block; }
.dropdown--keuze .dropdown__form { margin: 0; }
.dropdown--keuze .dropdown__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 14px 16px;
  border: 0;
  border-radius: var(--radius-sheet-rij);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-17);
  font-weight: 400;
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
  text-decoration: none;
}
.dropdown--keuze .dropdown__option:hover, .dropdown--keuze .dropdown__option:active { background: var(--color-card); }
.dropdown--keuze .dropdown__option:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; }
.dropdown--keuze .dropdown__panel .dropdown__option:not([aria-checked="true"]) .setrow__check { visibility: hidden; }
.dropdown--keuze .setrow__check { color: var(--color-text); }

/* Assistent: gedeelde actie- en gespreksrollen uit conventions §3/§8. */
.coach-head__menu:focus-visible, .coach-sheet__close:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -2px; border-radius: var(--radius-pill); }
.coach [data-coach-target="latest"] { display: block; margin: 0 auto 10px; min-height: 44px; }
.coach [data-coach-target="latest"][hidden] { display: none; }

/* Korte bereik-/weergavekeuze naast de bestaande uitgebreide filters. */
.agenda-mobile__keuzes { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.kasboek__periode { display: flex; margin-bottom: 12px; }
