/* Self-hosted webfonts (latin) — body Inter, koppen Manrope. Offline via SW-cache. */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/inter-latin-400-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/inter-latin-500-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/inter-latin-600-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/inter-latin-700-normal.woff2') format('woff2'); }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/manrope-latin-700-normal.woff2') format('woff2'); }

/* ============================================================
   LETTERGROOTTES STAAN IN `rem`, NOOIT IN px (UX-audit A7, 14-09-2026).
   Knijpzoom staat bewust uit (`user-scalable=no`), dus wie grotere letters
   nodig heeft, heeft alleen de lettergrootte-instelling van zijn browser —
   en die raakt `px` niet. 1rem = de gekozen standaardgrootte (meestal 16px),
   dus 13px werd 0.8125rem. Wat tekst omsluit (rijhoogtes, chips, knoppen)
   staat daarom óók in rem of heeft geen vaste hoogte; randen, radii,
   schaduwen en icoonmaten blijven px — die hoeven niet mee te groeien.
   ============================================================ */

/* ============================================================
   Apple HIG — flat, opaque, fast.
   No backdrop-filter, no ambient effects, no transforms.
   iOS Inset Grouped List aesthetic.
   ============================================================ */

:root {
  color-scheme: dark;

  /* Surfaces (dark default — 'Petrol': diep teal-marine) */
  --bg:           #08151b;
  --bg-grouped:   #061116;
  --surface:      #102530;
  --surface-2:    #173341;
  --surface-3:    #214656;

  /* Hairlines */
  --separator:           rgba(96, 160, 180, 0.26);
  --separator-opaque:    #214656;

  /* Text */
  --label:           #e7f1f4;
  /* Contrast (13-09-2026). --label-tertiary stond op 0.32 en haalde daarmee ~2,2:1 — ver onder
     de 4,5:1 die tekst van deze grootte hoort te halen, en in de praktijk waren datums en
     km-standen onder een kostenpost slecht te lezen (in de browser gezien, vooral in het lichte
     thema). Opgetrokken naar 4,5:1.

     Secondary ging mee omhoog, en dat moest ook: op 0.60 zou tertiary er ineens dónkerder
     uitzien dan secondary en klopt de rangorde niet meer. De volgorde label > secondary >
     tertiary > quaternary blijft dus staan, alleen minder ver uit elkaar.

     Quaternary blijft bewust laag: die wordt niet voor leestekst gebruikt maar voor streepjes,
     lege-staat-iconen en scheidingspunten. */
  --label-secondary: rgba(190, 218, 224, 0.80);
  --label-tertiary:  rgba(190, 218, 224, 0.63);
  --label-quaternary:rgba(190, 218, 224, 0.18);
  /* #74c (Audit 2, M5): --label-tertiary faalt WCAG (~2,3:1) op *primaire veldlabels*
     (bv. "KM-STAND"), niet alleen decoratieve bijschriften — apart, donkerder token
     specifiek voor .field label, richting 4,5:1 (gemeten ~6,7:1 hier). */
  --label-tertiary-strong: rgba(190, 218, 224, 0.75);

  /* Accenten ('Petrol' — rijk cyaan/teal i.p.v. iOS-systeemkleuren) */
  --systemBlue:   #3fb0dc;
  /* Knopvulling apart van --systemBlue. Die laatste is óók tekstkleur (actieve tab,
     links) en moet licht blijven: #3fb0dc als tekst op --surface-2 haalt 5,30:1,
     #1c6e93 zou daar 2,37:1 halen. Andersom haalde wit op #3fb0dc maar 2,48:1 als
     knopvulling (UX-audit A2, WCAG AA vraagt 4,5:1). Wit op #1c6e93 = 5,6:1.
     Gebruik dit token overal waar wit op blauw staat. */
  --btn-primary-bg: #1c6e93;
  /* #138-4 — knopvulling als eigen token. In het donkere thema is dat gewoon --surface-2/-3
     (ongewijzigd); in het lichte thema lag --surface-2 (#f3f0e9) zó dicht tegen de
     paginakleur (--bg-grouped #f1eee6) dat een knop als "Schema" nauwelijks als knop te zien
     was. Elke knop die op de achtergrond of op een kaart staat gebruikt dít token, zodat er
     één plek is waar de knopkleur vandaan komt. */
  --btn-bg:       #173341;
  --btn-bg-hover: #214656;
  --systemGreen:  #36c9a3;
  --systemOrange: #eaa84c;
  --systemRed:    #f26e60;

  /* #153 — de inkt van een geschat bedrag. Verzoek Gilles: "ik wil een elegantere manier om
     geschatte bedragen weer te geven i.p.v. ~; liever met kleur onderscheiden van vaste
     bedragen." De app zei dat al op twee plekken in blauw — de pil `.est-tag` ("schatting")
     en het bedrag van de vastgepinde schattingsregel in de kostenlijst — dus dít is de kleur
     die "dit getal is geschat" in CarDB al betekende; nieuw is alleen dat élk geschat bedrag
     hem nu draagt en dat het tilde-teken kan vervallen. Eén token, dus één regel om hem te
     wisselen als hij te veel op een link gaat lijken. */
  --est-ink: var(--systemBlue);

  /* Tinted fills for status pills (accent w/ low alpha) */
  --tint-blue:   rgba(63, 176, 220, 0.16);
  --tint-green:  rgba(54, 201, 163, 0.18);
  --tint-orange: rgba(234, 168, 76, 0.20);
  --tint-red:    rgba(242, 110, 96, 0.20);

  /* Continuous corners — semantische radius-schaal.
     REGEL: gebruik ALTIJD een --r-* token voor border-radius, nooit een kale px-waarde.
     Zo schakelt de UI-stijl 'Scherp' automatisch overal mee, óók op nieuwe schermen
     (geen losse :root[data-radius="sharp"]-uitzondering per element meer nodig).
     Uitzonderingen die bewust px blijven: echte cirkels (50%) en haarlijn-bars/-dots,
     plus de stijl-preview-thumbnails (.rw--rounded/.rw--sharp) die juist vast moeten zijn. */
  --r-xl:      18px;   /* modals, login-card */
  --r-card:    16px;   /* kaarten, panelen */
  --r-lg:      14px;   /* middelgrote kaarten/thumbs */
  --r-control: 12px;   /* inputs, knoppen, rijen */
  --r-icon:    11px;   /* icoontegels */
  --r-md:      10px;   /* kleine tegels/chips-containers */
  --r-sm:      8px;    /* kleine elementen */
  --r-xs:      6px;    /* badges, mini-knoppen, checkboxes */
  --r-2xs:     4px;    /* zeer klein / dunne bars */
  --r-pill:    999px;  /* pill-vormen */

  /* Type — Inter body, Manrope koppen (system fallback) */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text",
          "Helvetica Neue", system-ui, sans-serif;
  --font-head: "Manrope", "Inter", -apple-system, BlinkMacSystemFont,
          "Helvetica Neue", system-ui, sans-serif;

  /* ---------------------------------------------------------------
     #146 — de vijf schalen. Zie docs/UI-SYSTEEM.md voor de regels en
     scripts/check-ui-tokens.mjs, dat ze afdwingt in `npm run predeploy`.

     Tekstschaal — 7 maten. Alles eronder (0,6875 / 0,625 / 0,5625 /
     0,5 rem) is vervallen: dat was 11 px en kleiner, vaak ook nog in
     kapitalen, en juist op de plekken die inhoud dragen.
     --fs-input is met opzet 16 px: onder die maat zoomt iOS Safari in
     zodra je in een veld tikt. Dat is geen smaak maar een harde regel,
     dus elk invoerveld gebruikt dít token. */
  --fs-display: 2.125rem;   /* 34 — paginatitel, hoofdveld in stapmodus */
  --fs-title:   1.375rem;   /* 22 — h2.section, KPI-waarde */
  --fs-heading: 1.0625rem;  /* 17 — venstertitel, kaarttitel */
  --fs-input:   1rem;       /* 16 — élk invoerveld (iOS-zoomgrens) */
  --fs-body:    0.9375rem;  /* 15 — rijtitel, knoptekst, lopende tekst */
  --fs-sub:     0.8125rem;  /* 13 — onderregel, veldlabel, lege staat */
  --fs-meta:    0.75rem;    /* 12 — bijschrift, teller, eenheid */

  /* Ruimteschaal — 4 px. Padding van een container is --sp-3/--sp-4,
     gap is --sp-1 t/m --sp-3. Optische correcties van 1–2 px mogen
     los blijven; die vormen geen ritme en horen niet in de schaal. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;

  /* Hoogte van iets dat je aanraakt. Eén knophoogte, één veldhoogte. */
  --ctl-h:    40px;   /* knop, segment, select */
  --ctl-h-lg: 44px;   /* invoerveld, rij met raakdoel */

  /* Pictogramschaal — 3 maten (verzoek Gilles 19-09-2026: "alle icoontjes zijn
     te klein op mobiel"). Een pictogram stond tot nu toe óf in vaste px (zestien
     losse waarden tussen 13 en 30), óf het erfde zijn maat van de tekst ernaast
     via font-size. Allebei leverden op de telefoon hetzelfde op: het pictogram
     was er even groot als op een bureaublad, terwijl het scherm verder weg staat
     en het pictogram daar vaak het enige herkenningspunt van een rij is.

     De schaal schuift daarom één stap op onder 700 px — zie het blok onderaan
     dit bestand. Een pictogram dat ín een tekstregel meeloopt (badge, teller)
     blijft 1em en hoort hier niet bij. */
  --ic-sm: 16px;   /* in een knop, chip, zoekbalk */
  --ic-md: 18px;   /* rij- en menupictogram — de meest voorkomende */
  --ic-lg: 22px;   /* onderbalk, tegel, presetkaart */

  /* Schaduw — 3 niveaus. Hoger niveau = verder van de pagina af. */
  --shadow-1: 0 1px 3px rgba(0, 0, 0, 0.16);     /* kaart, popover */
  --shadow-2: 0 8px 24px rgba(0, 0, 0, 0.22);    /* menu, FAB */
  --shadow-3: 0 20px 50px rgba(0, 0, 0, 0.35);   /* venster */

  /* Lagen. Elke fixed/sticky laag kiest hieruit; losse getallen (en
     style.zIndex in JS) zijn vervallen. De volgorde is de stapeling:
     een bevestiging hoort bóven het venster waar hij over gaat, en een
     melding boven allebei. */
  --z-sticky:    10;  /* sticky kop binnen de pagina, zijbalk, offline-banner */
  --z-menu:      30;  /* dropdown, popover, filtermenu */
  --z-nav:       70;  /* FAB, onderbalk (backdrop op --z-nav minus 1) */
  --z-header:   100;  /* paginakop */
  --z-takeover: 150;  /* paginaovername: de voertuighub */
  --z-drawer:   180;  /* zijmenu + hamburger (backdrop op --z-drawer minus 1) */
  --z-window:   200;  /* venster: modal, verkoopdocument, login */
  --z-window-2: 250;  /* een venster dat vanúít een venster opent */
  --z-confirm:  300;  /* bevestiging — boven het venster waar hij bij hoort */
  --z-toast:    400;  /* melding — boven alles */

  /* Categoriepalet — zes tinten. Dit is de énige categorische kleurbron in de
     app: kostencategorieën, de kleur per voertuig op de vloot-tijdlijn én de
     labels op taken putten er alle drie uit.

     Hiervóór waren dat drie losse systemen: negen vaste hexen voor de
     categorieën (die níét meeschakelden met het lichte thema), vijf
     ongewijzigde iOS-systeemkleuren voor de voertuigen, en een hash van de
     labeltekst naar een hue van 0 tot 359 — onbegrensd, dus elk nieuw label
     kon elke kleur krijgen, inclusief kleuren die botsten met de statuskleuren.

     Zes omdat negen naast elkaar in de uitsplitsingsbalk op Kosten niet uit
     elkaar te houden waren. Categorieën die een tint delen (brandstof/laden,
     wegenbelasting/verzekering, lease/overig) houden hun eigen pictogram en
     hun eigen naam. */
  --cat-1: #3fb0dc;   /* onderhoud */
  --cat-2: #36c9a3;   /* reparatie */
  --cat-3: #eaa84c;   /* brandstof, laden */
  --cat-4: #f26e60;   /* wegenbelasting, verzekering */
  --cat-5: #8c7ade;   /* banden */
  --cat-6: #6fa8bd;   /* lease, overig */

  /* Tekst óp een gekleurd vlak: een oranje banner, een groen vinkje, een foto met
     een donkere sluier eroverheen. Die tekst hoort niet met het thema mee te
     draaien — hij moet leesbaar blijven op díé kleur. Twee tokens in plaats van
     zes losse hexen (#1a1100, #1a1208, #06210f, #dfeef3 …). */
  --on-accent:  #1a1208;                 /* donkere tekst op een lichte accentvulling */
  --on-photo:   #dfeef3;                 /* lichte tekst op een foto-sluier */
  --scrim:      rgba(6, 17, 22, 0.62);   /* de sluier zelf */
  --scrim-soft: rgba(6, 17, 22, 0.35);
}

/* UI-stijl → 'Scherp': strakkere hoeken. Eén plek — alleen de tokens flippen,
   en omdat álle componenten via var(--r-*) renderen werkt dit overal automatisch
   door (ook op nieuwe schermen). Geen per-element-uitzonderingen meer nodig. */
:root[data-radius="sharp"] {
  --r-xl:      9px;
  --r-card:    8px;
  --r-lg:      7px;
  --r-control: 6px;
  --r-icon:    6px;
  --r-md:      5px;
  --r-sm:      4px;
  --r-xs:      3px;
  --r-2xs:     2px;
  --r-pill:    6px;
}

/* Light-palet — toegepast wanneer de effectieve thema-keuze 'light' is.
   JS zet data-theme="light"|"dark" op <html> (auto wordt opgelost o.b.v. systeem). */
:root[data-theme="light"] {
  color-scheme: light;

  /* 'Linnen' — helder, koel licht greige met leisteen-indigo accent */
  --bg:         #f8f6f1;
  --bg-grouped: #f1eee6;
  --surface:    #fffefb;
  --surface-2:  #f3f0e9;
  --surface-3:  #e8e4da;

  --separator:        rgba(60, 58, 50, 0.22);
  --separator-opaque: #e3dfd4;

  --label:           #29271f;
  /* Hogere dekking dan in het donkere thema voor dezelfde leesbaarheid: donkere tekst op een
     bijna-witte ondergrond verliest sneller contrast dan lichte tekst op een donkere. */
  --label-secondary: rgba(58, 55, 46, 0.84);
  --label-tertiary:  rgba(58, 55, 46, 0.71);
  --label-quaternary:rgba(58, 55, 46, 0.18);
  --label-tertiary-strong: rgba(58, 55, 46, 0.75);

  --systemBlue:   #3a5a7d;
  --btn-primary-bg: #3a5a7d;    /* licht thema haalde met wit al 7,15:1 — ongewijzigd */
  /* #138-4 — knoppen moeten zich van de pagina (#f1eee6) én van een kaart (#fffefb) losmaken;
     --surface-2 deed dat met 1 % verschil niet. Deze twee zijn de enige knopkleuren. */
  --btn-bg:       #e2dcce;
  --btn-bg-hover: #d5ceba;
  --systemGreen:  #4f7a5e;
  --systemOrange: #bd7a38;
  --systemRed:    #a8463d;

  --tint-blue:   rgba(58, 90, 125, 0.12);
  --tint-green:  rgba(79, 122, 94, 0.14);
  --tint-orange: rgba(189, 122, 56, 0.16);
  --tint-red:    rgba(168, 70, 61, 0.16);

  /* #146 — schaduw in het lichte thema. Zwart op een bijna-witte ondergrond
     wordt snel vuil; dit is dezelfde vorm in de warme grijstint van Linnen,
     en zachter, want op licht valt een schaduw eerder op. */
  --shadow-1: 0 1px 3px rgba(70, 64, 50, 0.10);
  --shadow-2: 0 8px 24px rgba(70, 64, 50, 0.13);
  --shadow-3: 0 20px 50px rgba(70, 64, 50, 0.15);

  /* Hetzelfde palet, donkerder: op een bijna-witte ondergrond moet een tint
     zelf de contrastdrager zijn, terwijl hij op Petrol juist licht moet oplichten. */
  --cat-1: #3a5a7d;
  --cat-2: #4f7a5e;
  --cat-3: #bd7a38;
  --cat-4: #a8463d;
  --cat-5: #6a5bb0;
  --cat-6: #4d7385;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
/* [hidden] moet écht verbergen. De standaardregel van de browser is `display: none` met
   specificiteit 0,0,1 — elke klasse die zelf `display: flex/grid/block` zet, wint daarvan.
   Zo bleef de schattingskaart als leeg vlak staan bij een nieuwe auto (UX-audit V2), en
   negen andere klassen in dit bestand hebben precies hetzelfde patroon. Eén regel voorkomt
   dat het opnieuw gebeurt. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  overscroll-behavior-y: none;
  /* #86 — de ruimte voor de schuifbalk altijd reserveren. Dashboard en Taken passen op één
     scherm, Onderhoud/Kosten/Brandstof niet; zonder deze regel is het venster op de ene tab
     15 px breder dan op de andere (gemeten: clientWidth 1440 vs 1425) en schuift de
     gecentreerde inhoud ~7 px opzij bij élke tabwissel. */
  scrollbar-gutter: stable;
  /* Ook op <html> zodat de safe-area's (achter de iOS-statusbalk in een PWA met
     black-translucent) én een eventuele overscroll-/cold-start-rand de app-kleur
     tonen i.p.v. wit/zwart. Volgt het thema via --bg-grouped. */
  background: var(--bg-grouped);
}

body {
  background: var(--bg-grouped);
  color: var(--label);
  font-family: var(--font);
  font-size: var(--fs-heading);          /* iOS body */
  line-height: 1.35;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;   /* cijfers (km, bedragen) lijnen overal uit */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
}

/* Koppen — Manrope 700. Alle overige tekst is Inter (400/500/600/700).
   Bewust géén uppercase micro-labels hierin (die blijven Inter).
   #146 — .carhub-top-title is hieruit weg: de titel van een venster staat nu
   overal in .modal-topbar, en die is Inter 600. Een venstertitel is navigatie,
   geen kop. .card-title/.task-group-title/.qhead-t bestonden niet meer (ronde B). */
.title h1,
.mc-name,
.carhub-hero-name,
.etitle-in {
  font-family: var(--font-head);
  font-weight: 700;
}

.container {
  max-width: 980px;
  margin: 0 auto;
  padding: 32px 20px max(56px, env(safe-area-inset-bottom)) 20px;
}

/* ============ Header ============ */
header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 24px;
}

.title h1 {
  font-size: var(--fs-display);          /* iOS Large Title */
  font-weight: 700;
  letter-spacing: -0.022em;
  line-height: 1.05;
  cursor: pointer;          /* klikbaar → auto-bewerkscherm */
}
.title .sub {
  margin-top: 6px;
  color: var(--label-secondary);
  font-size: var(--fs-body);          /* iOS Subheadline */
  letter-spacing: -0.005em;
}

/* Modal section heading (e.g. Aankoop in km-modal) */
.modal-section {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
  margin: 16px 0 8px;
  padding-top: 12px;
  border-top: 0.5px solid var(--separator);
}
.field-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
}
@media (max-width: 480px) {
  .field-row { grid-template-columns: minmax(0, 1fr); }
}/* ============================================================
   #155 — het bewerkscherm van een voertuig: kaart + secties

   Optie A uit [de schets](../schetsen-log-onderhoud-en-voertuig.html) §2. De kaart bovenaan
   is dezelfde `--surface`-vorm als elke andere kaart; de secties eronder zijn `<details>`
   met de gedeelde `.disc-chev` — geen nieuw component, alleen een eigen rij-indeling met
   een onderregel die zegt wát erin staat.
   ============================================================ */
.car-ident {
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--surface); border-radius: var(--r-card);
  padding: var(--sp-3); margin-bottom: var(--sp-2);
}
.car-ident-plate { flex: none; display: flex; }
.car-ident-plate[hidden] { display: none; }
.car-ident-plate .plate-svg { width: 104px; }
.car-ident-plate .plate-na { width: 64px; }
.car-ident-tx { min-width: 0; flex: 1 1 auto; }
.car-ident-nm {
  display: block; font-family: var(--font-head); font-weight: 700;
  font-size: var(--fs-heading); letter-spacing: -0.02em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.car-ident-sub {
  display: block; font-size: var(--fs-sub); color: var(--label-secondary); margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.car-sec { border-top: 0.5px solid var(--separator); }
.car-sec:first-child { border-top: 0; }
.car-sec > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-1);
  min-height: var(--ctl-h-lg);
}
.car-sec > summary::-webkit-details-marker { display: none; }
.car-sec > summary:hover { background: var(--surface-2); border-radius: var(--r-control); }
.car-sec .cs-ic { display: inline-flex; align-items: center; color: var(--label-secondary); flex: none; }
.car-sec .cs-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.car-sec .cs-nm { font-size: var(--fs-body); font-weight: 600; }
.car-sec .cs-sub {
  font-size: var(--fs-meta); color: var(--label-tertiary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.car-sec .car-sec-body { padding: 0 var(--sp-1) var(--sp-2); }
/* De laatste rij van een open sectie mag geen dubbele lucht onder zich krijgen. */
.car-sec .car-sec-body > .field:last-child,
.car-sec .car-sec-body > .field-row:last-child { margin-bottom: 0; }
/* Een sectie die niet van toepassing is (het schema van een ánder voertuig) verdwijnt
   helemaal — inclusief zijn scheidingslijn. */
.car-sec[hidden] { display: none; }

/* ============ Section title ============ */
h2.section {
  font-size: var(--fs-title);          /* iOS Title 2 */
  font-weight: 700;
  letter-spacing: -0.018em;
  margin: 32px 0 12px;
  padding-left: 4px;
}
h2.section .section-sub {
  font-weight: 500;
  font-size: var(--fs-sub);
  color: var(--label-tertiary);
  letter-spacing: -0.005em;
  margin-left: 8px;
}
/* #153 — verzoek Gilles: "op het dashboard mogen de verschillende items van de verschillende
   pagina's wat strakker tegen elkaar — de ruimte tussen de laatste tegel en de volgende
   heading." Het dashboard is de enige pagina waar vijf van deze koppen ónder elkaar staan,
   elk met 32 px erboven; op de tabbladen zelf staat er meestal één en is die lucht juist de
   scheiding tussen de tegels en de lijst. Daarom hier en niet in `h2.section` zelf. */
#tabpanel-dashboard h2.section { margin-top: 20px; }

/* ============ Dashboard-tegelrijen ============
   Dit was de "Aankomend onderhoud"-lijst; die is met #95 vervangen door de tijdlijn. De vorm
   zelf blijft: Gilles wilde de taken in dezelfde tegelstijl (#94), dus de stijl is hernoemd in
   plaats van gekopieerd. Eén vorm, één plek om te wijzigen. */
.dash-rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
  margin-bottom: 8px;
}
/* #verbeterpunten-dashboard-17 — reparatietegels mogen op desktop precies twee kolommen zijn
   (breder dan de taken-auto-fill hierboven zou geven), zodat de twee nieuwe meta's per tegel
   niet krap komen te staan. */
@media (min-width: 861px) { #dash-repairs .dash-rows, #dash-fleet-repairs .dash-rows { grid-template-columns: 1fr 1fr; } }
.dash-row {
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: var(--r-control);
  display: flex;
  gap: 12px;
  align-items: center;
  overflow: hidden;
  transition: background-color 0.12s linear, border-color 0.12s linear;
}
.dash-row:hover { background: var(--surface-2); }
.dash-row.done { opacity: 0.55; }
/* De rij bestaat uit twee knoppen náást elkaar (afvinken, openen) — een knop ín een knop
   bestaat niet in HTML en wordt door de browser uit elkaar getrokken. */
.dash-row-main {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 12px 12px 12px 0;
  display: flex;
  gap: 12px;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  cursor: pointer;
  font-family: inherit;
  color: var(--label);
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.dash-row-check {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 12px 4px 12px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  -webkit-tap-highlight-color: transparent;
  flex: 0 0 auto;
}
.dash-row-check span {
  width: 1.125rem;
  height: 1.125rem;
  border-radius: var(--r-xs);
  border: 1.5px solid var(--label-tertiary);
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  font-size: var(--fs-meta);
  font-weight: 700;
}
.dash-row-check:hover span { border-color: var(--systemBlue); }
.dash-row-check[aria-checked="true"] span {
  background: var(--btn-primary-bg);
  border-color: var(--btn-primary-bg);
  color: #fff;
}
.dash-row-ic { flex: none; font-size: var(--fs-heading); color: var(--label-tertiary); display: flex; }
/* #146 — dezelfde kostenpost stond op Kosten in 16 px/700 en op het dashboard in
   13 px/600. Eén maat voor het bedrag rechts in een rij, waar die rij ook staat. */
.dash-row-amount { flex: none; font-size: var(--fs-body); font-weight: 700; color: var(--label);
  font-variant-numeric: tabular-nums; text-align: right; }
.dash-row-amount .sub { font-size: var(--fs-meta); font-weight: 500; color: var(--label-tertiary); }
.dash-row--rep .dash-row-main { padding-top: 12px; padding-bottom: 12px; }
/* #138-6 — de linkermarge van een tegel komt normaal van de afvinkknop ernaast
   (.dash-row-check heeft padding-left:14px). Een reparatietegel heeft die knop niet, dus
   stond het icoon tegen de rand. Eerste kind = geen knop ervoor = zelf de marge dragen. */
.dash-row-main:first-child { padding-left: 12px; }
.dash-row-body { min-width: 0; flex: 1; }
/* #140 — naam en onderregel zijn <span>'s; zonder display:block lopen ze in elkaar door zodra
   de naam kort is ("Check the wipers VW Golf TDI" op één regel). Ze stonden alleen onder elkaar
   omdat de naam meestal de hele regel vulde — dat is geen opmaak, dat is toeval. */
.dash-row-name {
  display: block;
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-row-sub {
  display: block;
  font-size: var(--fs-meta);
  color: var(--label-secondary);
  margin-top: 2px;
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dash-row-more {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--systemBlue);
  font-family: inherit;
  font-size: var(--fs-sub);
  padding: 8px 4px;
  cursor: pointer;
  text-align: left;
}

/* #67 — tegel met totale ~kosteninschatting + DIY/garage-schakelaar op de Onderhoud-tab. */
/* 6A — uitleg boven de onderhoudslijst zolang er van geen enkel punt een datum bekend is. */

/* Bandentracker (#79, uitgebreid 09-07-2026) — onderaan Onderhoud (boven het Logboek), één
   kaart per set (tag). Duidelijke scheiding t.o.v. de onderhoudskaarten erboven, zelfde
   ritme als `h2.section` (32px marge). */
#tireTrackerCard:not([hidden]) {
  margin-top: 32px;
  padding-top: 16px;
  border-top: 0.5px solid var(--separator);
}
.tire-tracker-head {
  font-size: var(--fs-sub); font-weight: 700;
  color: var(--label-tertiary); margin-bottom: 10px; padding-left: 4px;
}
.tire-tracker-grid {
  display: grid;
  /* #83 — `auto-fill` maakte áltijd drie sporen van 300 px in een kolom van 940: met één
     bandenset stond er een kaart van 307 px naast twee lege sporen (alleen zichtbaar op een
     breed scherm, want smal past er toch maar één kolom). `auto-fit` vouwt de lege sporen op;
     de bovengrens houdt één set op een bewuste maat in plaats van 940 px leegte. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 470px));
  gap: 8px;
}
.tire-card {
  background: var(--surface);
  border-radius: var(--r-card);
  overflow: hidden;
}
.tire-card-head {
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  width: 100%;
  appearance: none;
  background: transparent;
  border: 0;
  padding: 12px 12px;
  cursor: pointer;
  font-family: inherit;
  color: var(--label);
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.tire-card-head:hover  { background: var(--surface-2); }
.tire-card-head:active { background: var(--surface-3); }
.tire-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px; border-top: 0.5px solid var(--separator);
}
.tire-rot-status { display: flex; align-items: center; gap: 4px; font-size: var(--fs-meta); color: var(--label-tertiary); }

/* #114 — Reparaties-kaart: zelfde kop/voet-opbouw als de bandentracker-kaart hierboven
   (.tire-card*), los gehouden onder een eigen naam — een reparatie is geen band. */
.rep-card { background: var(--surface); border-radius: var(--r-card); overflow: hidden; margin-bottom: 8px; }
/* #verbeterpunten-repairs-2 — twee kolommen op medium/grote schermen, zelfde breekpunt als de
   reparatiekaarten op het dashboard (#dash-repairs .dash-rows hierboven). Alleen de lijstweergave:
   het beeldbord (.rep-board-view) heeft al zijn eigen raster via .task-board. */
@media (min-width: 861px) {
  #reparaties-board:not(.rep-board-view) { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: start; }
  #reparaties-board:not(.rep-board-view) .rep-card { margin-bottom: 0; }
}
/* #verbeterpunten-2-repairs-3 — de Log-knop stond op een eigen voetregel onder de kaart, met
   een uitlegzin ernaast. Nu staat hij náást het item op dezelfde regel, over de volle hoogte
   van die regel (align-items: stretch), zodat de kaart één regel is in plaats van twee. */
.rep-card-line { display: flex; align-items: stretch; }
.rep-card-head {
  flex: 1 1 auto; min-width: 0;
  display: grid; grid-template-columns: 36px 1fr auto; gap: 12px; align-items: center;
  appearance: none; background: transparent; border: 0; padding: 12px 12px;
  cursor: pointer; font-family: inherit; color: var(--label); text-align: left;
  -webkit-tap-highlight-color: transparent; transition: background-color 0.12s linear;
}
/* Verzoek Gilles (19-09-2026): "hover over reparatie item maakt maar een klein deel in
   hover kleur, vreemd". De kaart bestaat uit drie stukken — de aanklikbare kop, de
   Klaar-knop ernaast en de metaregel (onderdelen + notitie) eronder — en alleen het
   eerste kleurde mee. Je zweefde dus over één kaart en zag een blokje oplichten.
   Nu kleurt de kaart als geheel zodra je over het aanklikbare deel gaat; de knop houdt
   zijn eigen hover, want die doet iets anders. */
.rep-card { transition: background-color 0.12s linear; }
.rep-card:has(.rep-card-head:hover)  { background: var(--surface-2); }
.rep-card:has(.rep-card-head:active) { background: var(--surface-3); }
.rep-card-head:hover, .rep-card-head:active { background: transparent; }
/* #140 — de knop is weer een gewone pil (verzoek Gilles): dezelfde vorm als elke andere
   `.btn primary` in de app. Hij staat nog steeds op dezelfde regel als het item, maar
   verticaal gecentreerd in plaats van over de volle hoogte uitgerekt — een pil van 60 px hoog
   is geen pil meer. */
.rep-card-line .rep-log-btn {
  flex: 0 0 auto; align-self: center;
  margin: 0 12px 0 4px;
}
/* #verbeterpunten-2-repairs-4 — alles wat aan de reparatie hangt staat op de kaart zelf:
   de deelbedragen met hun prijs en de notitie. Onder de regel, over de volle breedte —
   anders zou de Log-knop met die inhoud meegroeien. */
.rep-card-meta {
  padding: 0 12px 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.rep-meta-parts { display: flex; flex-wrap: wrap; gap: 4px; }
.rep-meta-part {
  display: inline-flex; align-items: baseline; gap: 8px;
  background: var(--surface-2); border-radius: var(--r-control);
  padding: 4px 8px; font-size: var(--fs-meta); min-width: 0;
}
.rep-meta-part .rmp-n { color: var(--label-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-meta-part .rmp-c { color: var(--label); font-weight: 600; font-variant-numeric: tabular-nums; flex: none; }
.rep-meta-note {
  font-size: var(--fs-meta); color: var(--label-tertiary); line-height: 1.45;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.rep-card.done .item-title { color: var(--label-tertiary); text-decoration: line-through; }
/* #84 — "3.200 km sinds rotatie (12-05-2026)" was één zin met een datum tussen haakjes, terwijl
   de rest van de pagina met een klein label en een waarde eronder werkt (zoals de km-teller in
   de kop van dezelfde kaart). De datum staat in het venster dat deze knop opent. */
.tire-rot-status.done { align-items: baseline; gap: 8px; color: var(--label-tertiary); }
.tire-rot-status .trs-k { font-weight: 600; }
/* Verzoek Gilles (19-09-2026): "sinds rotatie bij bandentracker heeft hele grote font".
   De waarde stond op --fs-body (15 px) in een voetregel die verder uit --fs-meta bestaat,
   en de echte uitschieter zat in de knop hieronder. Nu --fs-sub: één stap boven het label
   ernaast, zoals elke andere onderregel in de app. */
.tire-rot-status .trs-v { font-size: var(--fs-sub); color: var(--label); font-variant-numeric: tabular-nums; }
.tire-rot-status .licon { width: var(--ic-sm); height: var(--ic-sm); align-self: center; }
/* .done is een knop (opent de rotatie-bewerken-modal) — .none blijft een niet-klikbare span.

   Hier stond `font: inherit`, en dat is precies waarom deze regel er zo groot uitzag: de
   korte vorm zet álle font-eigenschappen, dus óók de font-size uit .tire-rot-status
   hierboven (--fs-meta, 12 px). De knop erfde daardoor de body-maat en werd 16 px, terwijl
   dezelfde regel zónder rotatie (.none is een span, geen knop) wél 12 px bleef — twee maten
   voor één ding, in dezelfde voetregel. `font-family` is wat een knop echt nodig heeft. */
button.tire-rot-status.done {
  appearance: none; background: transparent; border: 0; padding: 2px 4px 2px 0;
  font-family: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent;
  border-radius: var(--r-xs);
}
button.tire-rot-status.done:hover { background: var(--surface-2); }
button.tire-rot-status.done:active { background: var(--surface-3); }

/* ============ Logboek ============ */
.logbook-details { margin-bottom: 12px; }
.logbook-details > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 24px 0 0;          /* zelfde afstand erboven als 'Alle onderhoudspunten' */
  padding-left: 4px;
  -webkit-tap-highlight-color: transparent;
}
.logbook-details > summary::-webkit-details-marker { display: none; }
/* Zelfde kop-stijl als 'Alle onderhoudspunten' */
.logbook-summary > span:first-child { font-size: var(--fs-heading); font-weight: 700; letter-spacing: -0.01em; }
.logbook-summary .section-sub { font-weight: 500; font-size: var(--fs-meta); color: var(--label-tertiary); }
.logbook-list {
  display: grid;
  gap: 4px;
  margin-top: 12px;
  margin-bottom: 12px;
}
.log-row {
  appearance: none;
  background: var(--surface);
  border: 0;
  border-radius: var(--r-control);
  padding: 12px 12px;
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  font-family: inherit;
  color: var(--label);
  text-align: left;
  width: 100%;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
}
.log-row:hover  { background: var(--surface-2); }
.log-row:active { background: var(--surface-3); }
.log-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--r-icon);
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-heading);
}
.log-body { min-width: 0; overflow: hidden; }
.log-name {
  display: block;
  min-width: 0;
  max-width: 100%;
  font-size: var(--fs-body);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.log-date {
  font-size: var(--fs-meta);
  color: var(--label-secondary);
  margin-top: 2px;
}
.log-row.undated .log-date { color: var(--label-tertiary); font-style: italic; }
.log-km {
  font-size: var(--fs-body);
  color: var(--label-secondary);
  font-weight: 500;
  text-align: right;
  white-space: nowrap;
}

/* ============ Grid + card ============ */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 12px;
}.card {
  background: var(--surface);
  border: 1px solid transparent;
  border-radius: var(--r-card);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  container-type: inline-size;
  transition: border-color 0.12s linear;
}
.card.overdue { border-color: var(--systemRed); }
.card.soon    { border-color: var(--systemOrange); }
.card.flash, .mrow-wrap.flash > .mrow, .item-row.flash { animation: cardFlash 0.9s ease; }
@keyframes cardFlash {
  0%, 100% { background: var(--surface); }
  30%      { background: var(--surface-3); }
}

:root[data-theme="light"] .card.overdue { border-color: rgba(168, 70, 61, 0.55); }
:root[data-theme="light"] .card.soon    { border-color: rgba(189, 122, 56, 0.55); }

.card-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}/* Bars */
.bars { display: flex; flex-direction: column; gap: 8px; }
.bar-row { display: flex; flex-direction: column; gap: 4px; }
.bar-label {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-sub);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
  gap: 8px;
}
.bar-label .key {
  color: var(--label-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bar-label .val { color: var(--label); font-weight: 600; white-space: nowrap; }
.bar-label .val.over { color: var(--systemRed); }

.bar {
  height: 6px;
  background: var(--surface-2);
  border-radius: var(--r-pill);
  overflow: hidden;
  position: relative;
}
.bar-fill {
  height: 100%;
  background: var(--systemGreen);
  border-radius: inherit;
  /* No transition: avoid layout work on first paint; only updates on user action */
}
.bar-fill.soon    { background: var(--systemOrange); }
.bar-fill.overdue { background: var(--systemRed); }
.bar-fill.unknown { background: var(--label-quaternary); width: 100% !important; }
.bar-mid {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--surface);
  transform: translateX(-50%);
  pointer-events: none;
}

/* Includes (collapsible via <details>) */
.includes {
  border-top: 0.5px solid var(--separator);
  padding-top: 12px;
}
.includes > summary {
  list-style: none;          /* verberg de native marker */
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.includes > summary::-webkit-details-marker { display: none; }
.includes-head {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
  margin-bottom: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  align-items: center;
}
.includes[open] .includes-head { margin-bottom: 10px; }
.includes-head .legend {
  font-weight: 500;
  text-transform: none;
  letter-spacing: -0.005em;
  color: var(--label-tertiary);
  font-size: var(--fs-meta);
}
.includes-head .legend .ic { color: var(--systemBlue); font-weight: 700; }

.includes ul {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px 16px;
  font-size: var(--fs-sub);
  color: var(--label-secondary);
  letter-spacing: -0.005em;
}
@container (min-width: 540px) {
  .includes ul { grid-template-columns: 1fr 1fr; }
}
.includes li {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  line-height: 1.4;
}
.includes li .marker {
  flex-shrink: 0;
  width: 14px;
  text-align: center;
  font-weight: 700;
  color: var(--label-tertiary);
}
.includes li.replace { color: var(--label); }
.includes li.replace .marker { color: var(--systemBlue); }

/* Card footer */
.card-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding-top: 12px;
  border-top: 0.5px solid var(--separator);
}
.last {
  font-size: var(--fs-sub);
  color: var(--label-secondary);
  flex: 1;
  min-width: 0;
  letter-spacing: -0.005em;
}
.last strong { color: var(--label); font-weight: 600; }
button.last {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.12s linear;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
button.last:hover strong { color: var(--systemBlue); }
button.last::after {
  content: '›';
  color: var(--label-tertiary);
  font-weight: 700;
  font-size: var(--fs-body);
  line-height: 1;
}
button.last:hover::after { color: var(--systemBlue); }

/* History modal list */
.history-list {
  display: grid;
  gap: 4px;
  margin: 12px 0 4px;
  max-height: 50vh;
  overflow-y: auto;
}
.history-list .log-row { background: var(--surface-2); }
.history-list .log-row:hover { background: var(--surface-3); }
.history-list .log-row .log-icon { background: var(--surface-3); }
.history-list .log-row:hover .log-icon { background: var(--surface); }

/* ============ Uitklap-chevron ============
   #152 — élke plek die iets ópenklapt gebruikt hetzelfde teken: de › van de
   onderhoudsregel, die bij openen een kwartslag naar beneden draait. Daarvóór stonden er
   zes varianten naast elkaar (▾ met rotate(180deg), ▾/▴ als ::after-paar, een
   losse SVG, en de › van de onderhoudsregel zelf) in vier verschillende maten.

   De maat is die van de navigatiechevron (--fs-heading): daarmee heeft de app nog
   één chevronmaat, en is hij overal iets groter dan de oude --fs-sub/--fs-meta.

   Het open-gedrag hangt aan de <details> of aan aria-expanded van de knop eromheen,
   niet aan een klasse per plek — een nieuwe uitklapper hoeft dus alleen de span. */
.disc-chev {
  flex: none;
  /* Ook in een rij die op baseline uitlijnt (de bakjes op Onderhoud, het logboek, "Meer"
     in de item-editor) hoort de chevron optisch in het midden, niet op de schrijflijn. */
  align-self: center;
  margin-left: auto;
  color: var(--label-tertiary);
  font-size: var(--fs-heading);
  line-height: 1;
  transition: transform 0.15s ease;
}
details[open] > summary .disc-chev,
[aria-expanded="true"] > .disc-chev,
[aria-expanded="true"] .disc-chev { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .disc-chev { transition: none; }
}
/* De knop om een kostenpost uit te vouwen is zelf zo groot als de chevron; daar duwt
   margin-left:auto niets meer opzij. */
.cost-breakdown-toggle .disc-chev { margin-left: 0; }

/* Buttons */
/* ============ Knop ============
   #146 — één knop: vier varianten (primair · standaard · rustig · destructief)
   en twee maten (--ctl-h en .small). Hiervóór stonden er zestien losse
   knopcomponenten naast elkaar met veertien verschillende paddings.

   De vorm is --r-control, niet --r-pill (keuze van 19-09): knop, veld, rij en
   kaart delen daarmee één hoek. De pil blijft bestaan voor chips en badges,
   die dan juist herkenbaar géén knop zijn. In de UI-stijl "Scherp" schakelt
   dit automatisch mee, want het is een token. */
.btn {
  appearance: none;
  background: var(--btn-bg);
  border: 0;
  color: var(--label);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  /* Hoogte i.p.v. verticale padding: zo zijn twee knoppen naast elkaar altijd
     even hoog, ook als de een een pictogram draagt en de ander niet. */
  min-height: var(--ctl-h);
  padding: 0 var(--sp-4);
  border-radius: var(--r-control);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  letter-spacing: -0.005em;
  white-space: nowrap;
  transition: background-color 0.12s linear, opacity 0.12s linear;
}
.btn:hover  { background: var(--btn-bg-hover); }
.btn:active { opacity: 0.7; }

/* V8 — één focusring voor alles. Velden en de auto-pill hadden al een eigen ring in
   --systemBlue; knoppen en links hadden niets en kregen de standaardring van de browser,
   die er per browser anders uitziet. :where() geeft specificiteit 0, dus elke bestaande
   regel wint hier nog steeds van. :focus-visible zodat een muisklik geen ring oplevert.
   Outline i.p.v. box-shadow: die wordt niet afgekapt door een ouder met overflow:hidden,
   en dat komt in de lijsten en het plusmenu voor. */
:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--systemBlue);
  outline-offset: 2px;
}

.btn.primary {
  background: var(--btn-primary-bg);
  color: white;
}
.btn.primary:hover { background: var(--btn-primary-bg); filter: brightness(1.12); }

/* Rustig: geen vulling. Gebruikt voor de destructieve knop linksonder in een
   venster — die mag zichtbaar zijn maar niet om aandacht vragen. De rode hover
   is een bestaand besluit (13-09-2026) en blijft. */
.btn.ghost {
  background: transparent;
  color: var(--label-secondary);
}
.btn.ghost:hover { background: var(--tint-red); color: var(--systemRed); }

/* Empty state */
/* ============ Lege staat ============
   #146 — er waren er elf, allemaal dezelfde tekstmaat met een andere padding, en
   twee ervan waren een hele kaart (de een met een doorlopende, de ander met een
   gestippelde rand). Eén regel voor de gewone variant; alleen de "nog geen
   voertuig"-kaart blijft apart, want dat is het eerste scherm dat iemand ziet. */
.empty-section,
.task-empty,
.tl-empty,
.kpi-pop-empty,
.plate-empty,
.attachment-empty {
  color: var(--label-tertiary);
  font-size: var(--fs-sub);
  padding: var(--sp-3) var(--sp-1);
  text-align: center;
}
/* #154 — de eerste stap ónder een lege lijst: "Importeren met AI" op Kosten, Tanken en Laden
   (verzoek Gilles). Gecentreerd en niet op volle breedte: het is een aanbod, geen
   hoofdknop — de plus rechtsonder blijft de gewone weg om iets toe te voegen. */
.empty-import { display: flex; margin: 0 auto var(--sp-4); }

/* ============ Modal ============ */
.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: var(--z-window);
  opacity: 0;
  /* visibility hoort hier expliciet bij: met alleen opacity:0 blijven alle knoppen
     en velden in een gesloten venster gewoon focusbaar. Op het dashboard leverde dat
     112 onzichtbare tabstops op — twaalf dichte vensters plus het plusmenu (UX-audit
     A1). visibility is animeerbaar en blijft tijdens het uitfaden op `visible`, dus
     de overgang verandert niet. */
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s linear, visibility 0.18s linear;
}
:root[data-theme="light"] .modal-bg { background: rgba(0, 0, 0, 0.25); }
.modal-bg.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
/* ============================================================
   #154 — een venster dat uit de plusknop groeit

   Verzoek Gilles: "voeg ook zo'n groei-animatie toe als je daar een item kiest, dus naar het
   volgende scherm. Geen fade." `laatGroeien()` in fab.js zet het middelpunt van de aangetikte
   menuregel als `--grow-x`/`--grow-y` op het paneel en hangt deze klasse erop; hij haalt hem
   er bij `animationend` weer af, zodat een venster dat langs een andere weg opent zijn
   gewone overgang houdt.

   `transition: none` op de mat is de "geen fade" uit het verzoek: de sluier staat er meteen,
   het paneel doet het werk. `will-change` niet nodig — het is één korte transform.
   ============================================================ */
.modal-bg.grows { transition: none; }
.modal-bg.grows > .modal {
  transform-origin: var(--grow-x, 50%) var(--grow-y, 50%);
  animation: modal-grow 0.24s cubic-bezier(0.2, 0.9, 0.25, 1);
}
@keyframes modal-grow {
  from { transform: scale(0.24); opacity: 0.4; }
  to   { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .modal-bg.grows > .modal { animation: none; }
}
/* Zolang er een modal/overlay open is: achtergrondpagina niet laten scrollen. Anders
   flitst op iOS de scroll-indicator van het scherm erachter over de sheet heen (terwijl
   er in de sheet niets te scrollen valt). De sheet scrollt zelf via .modal-scroll. */
body:has(.modal-bg.show),
body:has(.carhub-bg:not([hidden])) { overflow: hidden; }
.modal {
  background: var(--surface);
  border-radius: var(--r-xl);
  padding: 20px;
  max-width: 460px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.35);
}
.modal h3 {
  font-size: var(--fs-heading);
  font-weight: 700;
  letter-spacing: -0.018em;
  margin-bottom: 4px;
}
.modal-sub {
  color: var(--label-secondary);
  font-size: var(--fs-body);
  margin-bottom: 16px;
}

/* ============================================================
   13B — tanken/laden in drie stappen (UX-audit M2)
   Eén stap tegelijk, het veld van die stap groot genoeg om staand bij de pomp met
   één hand te raken. Geen apart scherm: dezelfde modal, dezelfde velden — alleen
   de stappen die niet aan de beurt zijn staan op `hidden`.
   ============================================================ */
.step-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -4px 0 16px;
}
.step-dots { display: flex; gap: 4px; }
.step-dots .sd {
  width: 26px;
  height: 4px;
  border-radius: var(--r-2xs);
  background: var(--separator-opaque);
}
.step-dots .sd.done { background: var(--label-tertiary); }
.step-dots .sd.now  { background: var(--btn-primary-bg); }
.step-lab { font-size: var(--fs-meta); color: var(--label-tertiary); font-weight: 600; }

/* Het hoofdveld van de actieve stap: groot getal, ruime raakzone. De 2.25rem schaalt
   mee met de lettergrootte-instelling (A7), de 56px hoogte is een minimum. */
.modal-bg.stepped .field[data-fstep-main] input {
  font-size: var(--fs-display);
  font-weight: 700;
  min-height: 56px;
  padding: 8px 12px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.modal-bg.stepped .field[data-fstep-main] label { text-align: center; font-size: var(--fs-sub); }
/* De datum staat in stap 1 naast de km-stand; die hoeft niet groot. */
.modal-bg.stepped .field-row { flex-wrap: wrap; }
/* De ondertitel beschrijft het hele formulier; in stapmodus zegt de stapbalk het al. */
.modal-bg.stepped .modal-sub { display: none; }
/* De spinnertjes van een number-veld zijn op 2.25rem een klont pijltjes naast het getal. */
.modal-bg.stepped .field[data-fstep-main] input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
.modal-bg.stepped .field[data-fstep-main] input[type="number"]::-webkit-outer-spin-button,
.modal-bg.stepped .field[data-fstep-main] input[type="number"]::-webkit-inner-spin-button { appearance: none; -webkit-appearance: none; margin: 0; }
/* #155 — het hoofdveld van stap 1 bij onderhoud is geen invoerveld maar de chipwolk. Die
   hoeft niet groot, maar wel gecentreerd zoals de rest van de stap, en hij mag de hoogte
   van het scherm gebruiken in plaats van een eigen scrollgebied te openen. */
.modal-bg.stepped #eventServicesField > label { text-align: center; font-size: var(--fs-sub); }
.modal-bg.stepped #eventServicesField .svc-picker { max-height: none; }

/* ============================================================
   #155 — "wat kostte het" staat groot, ook buiten de stapmodus

   Uit [de schets](../schetsen-log-onderhoud-en-voertuig.html) §1, optie A: het bedrag is het
   tweede dat je intypt, en op een formulier van acht gelijke velden viel het nergens op. Eén
   variant op `.field`, geen nieuw component; de maat blijft binnen de tekstschaal.
   ============================================================ */
.field--big input {
  font-size: var(--fs-title);
  font-weight: 700;
  min-height: var(--ctl-h-lg);
  font-variant-numeric: tabular-nums;
}
/* In stapmodus wint de --fs-display van het hoofdveld hierboven; deze regel mag hem niet
   terugzetten, dus hij staat hier en niet erna. */
.modal-bg.stepped .field--big[data-fstep-main] input { font-size: var(--fs-display); }
/* "Niets geselecteerd" hoort bij het gecentreerde label van de stap, niet links ernaast. */
.modal-bg.stepped .svc-selected { justify-content: center; }
/* #155 — in stapmodus staan er vier knoppen onderin (Vorige · Annuleren · Volgende ·
   Opslaan) en op 390 px valt "Opslaan" dan van het scherm. "Annuleren" gaat eruit: de ‹ in
   de kopbalk doet precies dat, en die staat er op elk venster. Hij blijft in de DOM, zodat
   die ‹ hem kan aanklikken (zie dismissModal in modal-chrome.js). */
.modal-bg.stepped .modal-actions .right > [data-action$="Cancel"] { display: none; }

.field { margin-bottom: 12px; min-width: 0; }
/* #146 — veldlabels stonden in kapitalen op 11 px: de kleinste tekst in de app,
   in de moeilijkst leesbare vorm ervan, uitgerekend op het label dat zegt wát je
   invult. Lange labels braken daardoor ook sneller over twee regels, en in zeven
   talen is dat vaker dan je denkt. Nu zinsvorm op --fs-sub (keuze 3 van 19-09).
   Kapitalen blijven bestaan voor korte, vaste labels (een statuspil, een teller),
   maar niet meer voor tekst die inhoud draagt. */
.field label {
  display: block;
  font-size: var(--fs-sub);
  font-weight: 500;
  color: var(--label-secondary);
  margin-bottom: 4px;
}
/* Het "(optioneel)" of een eenheidshint achter een labeltekst. Stond drie keer met
   de hand in index.html — één keer mét text-transform:none, één keer zonder (en
   dus in kapitalen) en één keer op een andere grootte. Dit is roadmappunt V9. */
.field label .fhint {
  font-weight: 400;
  color: var(--label-tertiary);
  font-size: var(--fs-meta);
}
/* Het eenheidssymbool hoefde alleen beschermd te worden tegen de kapitalen
   hierboven; die zijn weg, dus dit is nu alleen nog een haakje in settings.js. */
.unit-lit { font-variant-numeric: normal; }
/* #146 — één veld. Hiervóór stonden er acht varianten naast elkaar met vijf
   hoogtes (10/11/12 px verticale padding, of helemaal geen) en drie tekstmaten.
   Nu: --ctl-h-lg hoog, --surface-2 als vulling, --r-control als hoek en
   --fs-input (16 px) als tekst — die laatste is een harde grens, want daaronder
   zoomt iOS Safari in zodra je in een veld tikt.
   De losse varianten (.login-card input, .part-add input, .cat-new input,
   .danger-box input, .settings-pw input, .list-search-input)
   delen deze regel nu, of houden alleen nog wat écht afwijkt.

   #149 — `.totp-box input` stond er niet bij en was daarmee het enige invoerveld in de app
   zonder vorm: het vak voor de 2FA-code en het wachtwoordvak bij het uitzetten van 2FA
   kregen wat de browser van een <input> vindt, midden in een scherm vol velden die wél
   44 px hoog zijn ("bij 2fa is wachtwoord invulveld niet in stijl" — Gilles). Dat het
   erbuiten viel is logisch: dit blok wordt door renderTotpSection() in JS opgebouwd en niet
   uit index.html, dus het kwam bij de zoekvervanging van #146 niet langs. */
.field input,
.field select,
.field textarea,
.login-card input,
.settings-pw input,
.totp-box input,
.part-add input,
.cat-new input,
.danger-box input {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  background: var(--surface-2);
  border: 0;
  color: var(--label);
  min-height: var(--ctl-h-lg);
  padding: 0 12px;
  border-radius: var(--r-control);
  font-size: var(--fs-input);
  font-family: inherit;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  transition: background-color 0.12s linear, box-shadow 0.12s linear;
}
/* Een textarea groeit met zijn regels, dus daar is de padding verticaal. */
.field textarea { min-height: 0; padding: 12px 12px; line-height: 1.4; }
/* Een notitieveld dat met zijn regels meegroeit (autoGrow() in ui-shared.js zet de
   hoogte). `resize: none` omdat de greep van de browser en het meegroeien elkaar
   tegenwerken: sleep je hem kleiner, dan springt hij bij de volgende toetsaanslag
   terug. De bovengrens houdt het venster bruikbaar — daarboven scrollt het veld weer
   gewoon, zoals elke andere textarea. */
.field textarea[data-autogrow] { resize: none; overflow-y: auto; max-height: 40vh; }
/* iOS Safari geeft type=date een intrinsieke min-breedte op basis van de
   native picker. Reset de native styling zodat het veld netjes meekrimpt
   en geen horizontale scroll veroorzaakt op smalle viewports.

   #142 — met alleen die reset bepaalt iOS de maat van het veld verder zélf: het kromp mee
   tot de breedte van de datumtekst en kreeg een eigen regelhoogte, waardoor het naast het
   tekstveld in dezelfde rij opvallend smaller én lager stond. `width` en `min-height` staan
   daarom expliciet hier — `.field input` zette `width: 100%` al, maar alleen als iOS geen
   eigen intrinsieke maat oplegt. De hoogte volgt de tekst (`1.2em` + 2 × 11 px padding), dus
   hij blijft kloppen bij een grotere systeemletter. */
.field input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  /* Verzoek Gilles (19-09-2026): "in alle datumvelden staat de datum te hoog".
     Dat kwam door `display: block` hierboven. De browser geeft een datumveld van
     zichzelf `display: inline-flex; align-items: center` — dát is wat de datum
     verticaal midden in het vak houdt. `block` zette die flexcontext uit, waarna
     de datumtekst als gewoon blok bovenaan het 44 px hoge vak bleef plakken; bij
     een leeg veld gold hetzelfde voor "dd-mm-jjjj".
     `flex` doet wat `block` hier moest doen (een blokniveau-vak dat width: 100 %
     aanneemt, zodat de #142-correctie voor iOS overeind blijft) én herstelt het
     midden. */
  display: flex;
  align-items: center;
  line-height: 1.2;
  min-height: var(--ctl-h-lg);
}
/* Het binnenvak van de datumtekst vult de hoogte niet vanzelf; zonder dit blijft
   er in Chrome een halve pixel speling over waar de tekst weer omhoog van kruipt. */
.field input[type="date"]::-webkit-datetime-edit { display: flex; align-items: center; }
.field input[type="date"]::-webkit-date-and-time-value { text-align: left; }
.field input:focus,
.field select:focus,
.field textarea:focus,
.login-card input:focus,
.settings-pw input:focus,
.totp-box input:focus,
.part-add input:focus,
.cat-new input:focus,
.danger-box input:focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--systemBlue);
}
/* ============ Wisknop bij een veld (#149) ============
   "Alle reset x bij invulvelden mogen groter" (Gilles, 19-09-2026). Het waren er zes, elk
   met zijn eigen maat: 24, 26, 26, 30 px en twee die helemaal geen maat hadden maar wat
   padding. Het teken zelf stond op 12 tot 15 px. Naast een veld van 44 px is dat een doelwit
   dat je op een telefoon met je duim moet zoeken.

   Nu één maat voor alle zes: 32 px raakvlak met het teken op --fs-heading. Dat is dezelfde
   kleine-knopmaat die het UI-systeem kent voor "een knop ín een rij" (§3), en het teken staat
   één stap onder de veldtekst — groot genoeg om te zien, klein genoeg om niet met het veld te
   concurreren. Wat per plek écht anders is (kleur bij hover, positie in het veld) blijft in de
   regel van die plek staan. */
.date-clear,
.part-del,
.subtask-del,
.mt-pt-x,
.harow .harow-rm,
.attachment-row .att-delete {
  flex: 0 0 auto;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  width: 32px;
  height: 32px;
  border-radius: var(--r-xs);
  font-family: inherit;
  font-size: var(--fs-heading);
  line-height: 1;
  color: var(--label-tertiary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
}

/* #146 — vaste knopplaatsing. Dit stond op `justify-content: space-between` met
   een `.right`-groep ernaast. Was de destructieve knop verborgen (een níéuwe
   kostenpost heeft niets te verwijderen), dan was `.right` het enige kind en
   schoof "Annuleren / Opslaan" naar links; bij bewerken stond dezelfde knop
   rechts. De hoofdknop had dus geen vaste plek.
   Nu: `.right` duwt zichzelf naar rechts met `margin-left: auto`, dus primair
   staat altíjd rechtsonder — met of zonder destructieve knop ernaast. */
.modal-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  /* Niet sticky: een sticky footer met negatieve marge liet content eronder
     doorlekken en kapte het laatste item af. Nu staat de footer netjes onderaan
     de scrollbare modal. */
  margin: 16px -20px -20px;                 /* span de modal-padding */
  padding: 14px 20px calc(16px + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 0.5px solid var(--separator);
}
.modal-actions .right { display: flex; gap: var(--sp-2); margin-left: auto; }

/* ---- Uniform sheet-patroon: vaste kopbalk + scrollend midden + sticky footer ---- */
.modal--sheet {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  max-height: 90vh;
}
.modal-topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  /* Eigen achtergrond: de balk kleurt zo ook de safe-area (onder de iOS-statusbalk) in,
     i.p.v. een donkere "afgesneden" band erboven. */
  background: var(--surface);
  border-bottom: 0.5px solid var(--separator);
}
/* #146 — de titel van een venster. `h3` blijft werken voor de vensters die hun
   kop uit index.html halen; `.modal-topbar-title` is dezelfde regel voor de
   vensters die hun kop in JS opbouwen (onderhoudsschema, back-up, verkoop).
   Hiervóór hadden die twee hun eigen maten: 17/600, Manrope 700 en 15/700. */
.modal-topbar h3,
.modal-topbar-title {
  grid-column: 2;
  margin: 0;
  text-align: center;
  font-size: var(--fs-heading);
  font-weight: 600;
  letter-spacing: -0.01em;
  font-family: var(--font);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* U1 — plaatsvervanger voor de terug-knop in vensters die er geen hebben, zodat de
   titel gecentreerd blijft. */
.modal-back-spacer { display: inline-block; width: 60px; flex: none; }
.modal-back {
  grid-column: 1;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 0;
  color: var(--systemBlue);
  font-family: inherit;
  font-size: var(--fs-input);
  letter-spacing: -0.01em;
  padding: 4px 4px;
  margin: 0;
  cursor: pointer;
}
/* #152 — de ‹ stond optisch een haartje te laag naast het woord (het teken zit rond de
   x-hoogte, de kapitaal ernaast reikt hoger) en plakte er bovendien tegenaan. Een 4 px-gap
   en 1 px extra omhoog; de kleur komt nu van de knop zelf (blauw) in plaats van van het
   gelijknamige bakjes-chevrontje op Onderhoud, dat er per ongeluk overheen viel. */
.modal-back .mback-chev { font-size: var(--fs-title); line-height: 0.7; margin-top: -2px; }
.mt-topbar-right { grid-column: 3; justify-self: end; display: inline-flex; align-items: center; }
.mt-topbar-right .task-detail-del { margin: 0; }
.modal-scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Scroll-bounce binnen de sheet niet laten doorlekken naar de pagina/achtergrond
     erachter (anders komt er bij het scrollen van de velden een stukje van
     daaronder zichtbaar). */
  overscroll-behavior: contain;
  padding: 16px 20px 8px;
}
.modal--sheet .modal-sub { margin-bottom: 14px; }
.modal--sheet .modal-actions {
  margin: 0;
  flex: 0 0 auto;
}

/* ---- "Meer opties": niet-essentiele velden inklapbaar ---- */
.more-options {
  border: 0.5px solid var(--separator);
  border-radius: var(--r-control);
  margin: 4px 0 12px;
  overflow: hidden;
}
.more-options > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 12px;
  font-size: var(--fs-body);
  font-weight: 500;
  color: var(--label-secondary);
}
.more-options > summary::-webkit-details-marker { display: none; }
.more-options[open] > summary { border-bottom: 0.5px solid var(--separator); }
.more-options-body { padding: 12px 12px 2px; }
.more-options-body > .field:last-child,
.more-options-body > .field-row:last-child { margin-bottom: 2px; }

/* ---- Mobiel: elk invulvenster vult het hele scherm (geen scherm-over-scherm) ---- */
@media (max-width: 600px) {
  .modal-bg { padding: 0; align-items: stretch; justify-content: stretch; }
  .modal {
    max-width: none;
    width: 100%;
    border-radius: 0;
    max-height: 100vh;
    max-height: 100dvh;
  }
  .modal--sheet { height: 100vh; height: 100dvh; }
  /* Full-screen sheet loopt onder de iOS-statusbalk/notch door (viewport-fit=cover).
     Kopbalk-padding volgt de safe-area aan álle kanten + een extra marge boven, zodat
     de terug-knop + titel rúim onder het dynamic island vallen (niet er tegenaan). De
     strook achter het island krijgt de app-achtergrondkleur, zodat het naadloos meekleurt
     met de rest van de app i.p.v. het lichtere sheet-grijs. */
  .modal--sheet .modal-topbar {
    padding-top: max(18px, calc(env(safe-area-inset-top, 0px) + 12px));
    padding-left: max(12px, env(safe-area-inset-left));
    padding-right: max(12px, env(safe-area-inset-right));
    background: var(--bg-grouped);
  }
  /* Footer-knoppen ook vrij van de home-indicator/onderrand houden. */
  .modal--sheet .modal-actions {
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }
  /* Niet-sheet modals worden ook full-screen, maar hebben geen eigen kopbalk → geef hun
     bovenkant safe-area zodat de inhoud niet onder de statusbalk/notch begint.

     #142 — en dezelfde extra marge als de kopbalk van een sheet hierboven (+12 px). Met kaal
     `env(safe-area-inset-top)` begint de inhoud précies op de onderrand van het dynamic
     island: technisch niet erónder, maar er tegenaan. Dat viel op bij het bewerkscherm van een
     reparatie, dat als enige geen `.modal-actions` heeft en daardoor door enhanceModals()
     (modal-chrome.js) niet tot sheet wordt omgebouwd — het begint dus meteen met een invoerveld
     zonder kopbalk ertussen. */
  .modal:not(.modal--sheet) {
    padding-top: max(22px, calc(env(safe-area-inset-top, 0px) + 12px));
    /* Ook de andere drie randen: dit venster is full-screen, dus de onderste knoppen mogen
       niet achter de home-indicator vallen en in landschap niet onder de notch. Zonder
       safe-area (desktop, Android zonder inkeping) blijft het gewoon de 22 px van `.modal`. */
    padding-bottom: max(22px, calc(env(safe-area-inset-bottom, 0px) + 12px));
    padding-left: max(22px, env(safe-area-inset-left, 0px));
    padding-right: max(22px, env(safe-area-inset-right, 0px));
  }
  /* De item-editor had hier vijf knoppen in zijn voet en paste daarmee op geen enkel
     scherm. Sinds 19-09-2026 zijn het er twee (zie .mt-more-wrap verderop); ze delen de
     breedte, zodat ze op 375 px allebei een fatsoenlijk raakdoel blijven. */
  #maintItemModal .modal-actions .right { width: 100%; }
  #maintItemModal .modal-actions .right .btn { flex: 1 1 0; }
}

/* Footer */
.foot {
  margin-top: 32px;
  text-align: center;
  color: var(--label-tertiary);
  font-size: var(--fs-sub);
}
.foot strong { color: var(--label-secondary); font-weight: 600; }
.foot-version {
  margin-top: 6px;
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
/* Draait de browser oude JS achter een verse index.html, dan zegt de footer dat zelf. Bewust
   opvallend: dit is precies het geval waarin iets "gewoon niet werkt" zonder foutmelding. */
.foot-version--stale { color: var(--systemOrange); }
.foot-stale-btn {
  appearance: none;
  background: var(--tint-orange, transparent);
  border: 0.5px solid var(--systemOrange);
  color: var(--systemOrange);
  font-family: inherit;
  font-size: var(--fs-meta);
  font-weight: 600;
  min-height: 32px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-control);
  cursor: pointer;
}

/* ============ App-shell + zijbalk-navigatie ============ */
.app-shell {
  display: flex;
  align-items: flex-start;
  min-height: 100vh;
}
/* De content-kolom houdt zelf zijn max-width + centrering (.container).
   Op desktop scrollt het venster; op mobiel wordt #mainContent een vaste interne
   scroller (zie media-query onderaan) zodat de onderbalk niet meescrolt. */
#mainContent { flex: 1 1 auto; min-width: 0; }

.sidebar {
  flex: 0 0 236px;
  width: 236px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  background: var(--surface);
  border-right: 0.5px solid var(--separator);
  padding: 20px 14px max(20px, env(safe-area-inset-bottom)) 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  z-index: var(--z-sticky);
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px 16px;
  font-size: var(--fs-heading);
  font-weight: 700;
  letter-spacing: -0.02em;
}
.sidebar-brand .brand-icon { font-size: var(--fs-title); line-height: 1; }

.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-tab {
  appearance: none;
  background: transparent;
  border: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--label-secondary);
  cursor: pointer;
  text-align: left;
  letter-spacing: -0.01em;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.side-tab:hover { background: var(--surface-2); color: var(--label); }
.side-tab.active { background: var(--tint-blue); color: var(--systemBlue); }
.side-tab .side-ic { font-size: var(--fs-heading); width: 22px; text-align: center; flex: 0 0 auto; }

/* ============================================================
   14A — inhoud van de la (alleen smalle schermen)
   ============================================================ */
/* #89 — het autoblok staat sinds 14-09-2026 óók in de zijbalk op desktop: wisselen is één
   klik, op elk scherm. Alleen de databestanden blijven de la voorbehouden (op desktop staan
   die in Instellingen). Zie schetsen-garage.html. */
.drawer-extra { display: block; }
.drawer-only { display: none; }
.side-more {
  color: var(--systemBlue);
  justify-content: space-between;
  gap: 8px;
}
.side-more .settings-chev { color: inherit; }
/* Het label duwt het aantal en de chevron naar rechts; die twee horen bij elkaar. Het
   aantal verschijnt alleen als er auto's buiten beeld vallen (zie fitSidebarCars). */
.side-more > span:first-child { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-more-n {
  flex: 0 0 auto;
  font-size: var(--fs-meta);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--label-tertiary);
  background: var(--surface-2);
  border-radius: var(--r-pill);
  padding: 1px 8px;
}
.drawer-head {
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
  padding: 12px 12px 4px;
}
.drawer-cars { display: flex; flex-direction: column; gap: 2px; }
.drawer-car {
  appearance: none;
  background: transparent;
  border: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--r-md);
  font-family: inherit;
  color: var(--label-secondary);
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.drawer-car:active { background: var(--surface-2); }
.drawer-car.active { background: var(--tint-blue); color: var(--systemBlue); }
.drawer-car .dw-body { flex: 1 1 auto; min-width: 0; }
.drawer-car .dw-name {
  display: block;
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* #verbeterpunten-2-garage-2 — staat "kenteken" ingesteld, dan komt hier de plaat zelf te
   staan in plaats van de letters ervan (verzoek Gilles). Klein gehouden: de la is 265 px breed
   en er staat een km-stand + "volgende beurt" onder. De oude tekstvariant (.dw-plate) is
   daarmee vervallen. */
.drawer-car .dw-plate-svg { display: block; margin-bottom: 3px; }
.drawer-car .dw-plate-svg .plate-svg {
  height: 21px; width: auto; max-width: 100%;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.22));
}
.drawer-car .dw-plate-svg .plate-na { height: 34px; }   /* #150 — zie .car-row-plate */
.drawer-car .dw-sub {
  display: block;
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.drawer-car .dw-check { flex: 0 0 auto; font-weight: 700; }
/* De "volgende beurt" in de onderregel draagt zijn urgentie als kleur — dezelfde drie
   niveaus als .car-row-next in de garage, zodat één auto niet in de zijbalk rood is en in
   de garage grijs. Alleen het woord "over 3 mnd" kleurt: de naam van het punt is geen
   waarschuwing. */
.drawer-car .dw-next { display: flex; align-items: baseline; gap: 4px; }
.drawer-car .dwn-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.drawer-car .dwn-when { flex: none; font-variant-numeric: tabular-nums; }
.drawer-car .dw-next.overdue .dwn-when { color: var(--systemRed); font-weight: 600; }
.drawer-car .dw-next.soon .dwn-when { color: var(--systemOrange); font-weight: 600; }
.drawer-car.active .dw-sub { color: var(--label-secondary); }

/* #3 (wensenlijst 14-09-2026) — "Auto toevoegen" plakte tegen de laatste auto en las
   daardoor als een derde auto in de lijst. De autolijst is één groep (inclusief de
   "Alle auto's"-regel, dat is de overloop ván die lijst); toevoegen begint iets nieuws en
   krijgt daarom lucht erboven. */
#drawerAddCar { margin-top: 12px; }

.sidebar-actions {
  margin-top: auto;
  padding-top: 12px;
  border-top: 0.5px solid var(--separator);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.side-action {
  appearance: none;
  background: transparent;
  border: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 var(--sp-3);
  min-height: var(--ctl-h);
  border-radius: var(--r-control);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--label-secondary);
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.side-action:hover { background: var(--surface-2); color: var(--label); }
.side-action .glyph { color: var(--label-tertiary); font-size: var(--fs-body); width: 22px; text-align: center; flex: 0 0 auto; }

/* Hamburger — standaard verborgen (desktop), zichtbaar op smalle schermen */
.hamburger {
  display: none;
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 12px);   /* niet onder de iOS-klok in PWA */
  left: calc(env(safe-area-inset-left, 0px) + 12px);
  z-index: var(--z-drawer);
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: var(--r-icon);
  background: var(--surface);
  color: var(--label);
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2);
}
.hb-bar { display: block; width: 18px; height: 2px; border-radius: var(--r-2xs); background: var(--label); }
/* Hamburger nooit bovenop een open invulvenster: hij zweeft anders (z-index 1100)
   over de sheet-kopbalk/terug-knop en de invulvelden heen. */
body:has(.modal-bg.show) .hamburger { display: none; }

.sidebar-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  z-index: calc(var(--z-drawer) - 1);
}

/* ============ Mobiele onderbalk (hoofdtabs) ============ */
/* Standaard verborgen — alleen op smalle schermen getoond. */
.bottom-nav { display: none; }

/* Smalle schermen: zijbalk wordt een uitschuifbaar drawer-menu */
@media (max-width: 860px) {
  /* #46 — compacte topbalk: hamburger · paginatitel · auto-switcher op één lijn.
     De header wordt een sticky balk en de hamburger staat er inline in (niet meer
     zwevend). Scheelt de oude ~60px dode ruimte erboven en oogt strakker. */
  .hamburger {
    display: flex;
    position: static;
    top: auto; left: auto;
    width: 44px; height: 44px;    /* 44 i.p.v. 38 — app-bij-de-pomp (UX-audit A9) */
    margin-left: -9px;            /* icoon optisch op de 20px-tekstmarge */
    background: transparent;
    box-shadow: none;
    border-radius: var(--r-sm);
    flex: 0 0 auto;
    z-index: auto;
  }
  .hamburger:active { background: var(--surface-2); }
  header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    /* GEEN negatieve marge: die stak buiten de contentkolom → horizontale scroll.
       De gutter toont al dezelfde --bg-grouped-kleur, dus dit dekt visueel net zo. */
    margin: 0 0 12px;
    padding: calc(env(safe-area-inset-top, 0px) + 8px) 0 8px;
    background: var(--bg-grouped);
  }
  header .title { flex: 1 1 auto; min-width: 0; }
  /* line-height 1.05 (de algemene regel) is krap: mét overflow:hidden erbij sneed dat bij
     150 % tekst de onderkant van de letters af. 1.25 geeft de staarten ruimte. */
  header .title h1 { font-size: var(--fs-title); line-height: 1.25; overflow: hidden; text-overflow: ellipsis; }
  /* De auto-switcher mag niet wegduwen: hij houdt zijn eigen breedte rechts.
     De plaat zit bovenin de pill → optisch wat te hoog; een paar px omlaag laat
     plaat+naam beter uitlijnen met de hamburger en de titeltekst. */
  header .car-pill { flex: 0 0 auto; }
  header .car-pill.has-plate { transform: translateY(2px); }
  /* iOS PWA scroll-architectuur: het document scrollt NIET. De app-shell is een vaste
     kolom (100dvh) met onderaan de onderbalk als echte flex-footer (niet position:fixed,
     dus die kan per definitie niet meescrollen) en daarboven #mainContent als de enige
     scroller. Zo verspringt de viewport nooit en blijft de balk gegarandeerd onderaan.

     LET OP bij een losse pagina die dit bestand meeleest voor zijn tokens (privacy.html,
     en wat er later bij komt): die heeft géén .app-shell en dus géén scroller, en staat
     met deze regel muurvast in een geïnstalleerde PWA. Zet er dan
     `html, body { height: auto; min-height: 100%; overflow: visible; }` tegenover, ná de
     <link> — zie de uitleg bovenin privacy.html. */
  html, body { overflow: hidden; }
  /* Hoogte-eenheid is hier de valkuil (zie iOS-PWA-research):
       - height:100%   → breekt viewport-fit=cover + black-translucent.
       - height:100dvh → fout bij PWA cold-start tot je roteert → zwarte strook onder de balk.
       - height:100vh  → enige die meteen klopt in een standalone PWA.
     Daarom: browser krijgt 100dvh (volgt de dynamische balk netjes), de geïnstalleerde PWA
     krijgt 100vh via de display-mode:standalone-override hieronder. min-height:0 overruled de
     globale min-height:100vh die het document anders hoger maakt. GEEN position:fixed op body. */
  body { height: 100dvh; min-height: 0; }
  .app-shell {
    flex-direction: column;
    align-items: stretch;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }
  #mainContent {
    flex: 1 1 auto;
    min-height: 0;          /* ESSENTIEEL: zonder dit groeit het flex-item i.p.v. te scrollen */
    width: auto;
    max-width: none;
    margin: 0;
    overflow-y: scroll;     /* scroll, NIET auto: iOS pakt 'auto' soms geen scroll-container → "paar mm" */
    overflow-x: hidden;     /* nooit horizontaal scrollen (vangnet tegen te brede kinderen) */
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding-top: 0;   /* de sticky topbalk (header) levert nu zelf de bovenruimte (#46) */
    /* Onderlucht ruim genoeg dat het laatste lijst-item vrij van de zwevende FAB
       komt (FAB zit ~72px boven de onderrand en is ~56px hoog → ~70px intrek). */
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 96px);
  }
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    height: 100%;
    width: 270px;
    max-width: 82vw;
    flex-basis: auto;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    /* Schaduw alleen wanneer het menu open is — anders lekt de 40px-blur van de
       dichtgeschoven drawer over de linkerrand (zichtbaar op het lichte palet). */
    box-shadow: none;
    z-index: var(--z-drawer);
    padding-top: calc(env(safe-area-inset-top, 0px) + 22px);
  }
  .app-shell.sidebar-open .sidebar { transform: translateX(0); box-shadow: 0 0 40px rgba(0, 0, 0, 0.45); }
  /* (Fade-strook vervallen met #46: de sticky topbalk dekt nu zelf de bovenrand af.) */
  /* Hoofdtabs niet in de zijbalk op mobiel — die staan onderin. */
  .side-nav { display: none; }
  /* 14A — en dáárom staat de rest hier: op desktop staat de zijbalk al vol met de tabs. */
  .drawer-only { display: block; }
  /* Footer-caption verbergen op mobiel: stak onder de vaste onderbalk uit (gap). */
  .foot { display: none; }
  /* #154 — "Voertuig toevoegen" stond in de la twee keer: #drawerAddCar bovenin (alleen
     mobiel) en #addCarBtn onderin (die verschijnt bij hooguit één voertuig). Onderin is de
     desktop-ingang, want daar bestaat .drawer-only niet; op een telefoon is het een
     dubbeling. */
  #addCarBtn { display: none !important; }
  /* FAB volledig BOVEN de onderbalk (op hoogte, niet via z-index): onderbalk is
     58px hoog + safe-area, FAB krijgt 14px lucht erboven.
     #fabWrap (id) wint qua specificiteit van de basis-.fab-wrap regel verderop. */
  /* #153 — verzoek Gilles: "blauwe plus mag een klein stukje hoger". Was 72 px (14 px lucht
     boven de 58 px onderbalk); nu 84 px, zodat hij ook op een toestel met een gebarenbalk
     vrij van de onderbalk staat en de duim er onderlangs bij kan. */
  #fabWrap { bottom: calc(env(safe-area-inset-bottom, 0px) + 84px); }
  /* Onderbalk = echte footer-flex-child onderaan de kolom (NIET position:fixed). */
  .bottom-nav {
    display: grid;
    /* #114 — zesde tab (Reparaties) erbij; laden vervangt brandstof's kolom bij een PHEV
       i.p.v. een zevende kolom te vragen, dus dit blijft altijd zes zichtbare tegels. */
    grid-template-columns: repeat(6, 1fr);
    gap: 2px;
    align-items: stretch;   /* knoppen vullen de hoogte → tegels hoger/vierkanter */
    box-sizing: border-box;
    flex: 0 0 auto;
    height: calc(64px + env(safe-area-inset-bottom, 0px));
    z-index: var(--z-nav);
    background: var(--surface);
    border-top: 0.5px solid var(--separator);
    padding: 0 6px env(safe-area-inset-bottom, 0px);
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.18);
  }
}
/* Geïnstalleerde PWA (iOS én Android): 100dvh klopt op iOS niet bij cold-start (zwarte
   strook onder de onderbalk) → forceer 100vh, dat is in standalone de volledige schermhoogte
   en meteen correct. Geldt alleen in standalone, dus de browser houdt zijn nette 100dvh.

   #140 (20-09-2026) — deze regel hoort bij de statusbalk-meta in index.html; verander je de
   één, loop dan de ander na. Toen die meta even op `default` stond was de webview ~59 pt
   korter dan het scherm en klopte 100vh niet meer, en de twee alternatieven bleken allebei
   hun eigen val te hebben:
     - 100%   → juiste hoogte, maar hangt aan het initial containing block en dat her-resolvet
       iOS na een rotatie héén en terug niet: de onderbalk bleef op de oude hoogte hangen.
     - 100dvh → herberekent netjes bij elke resize, maar dat is precies de eenheid die in #24i
       bij cold-start omviel.
   De meta is teruggedraaid, dus 100vh klopt weer. Niet "opruimen" naar 100% of 100dvh: alle
   drie zijn geprobeerd en alleen deze werkt bij deze meta. */
@media (max-width: 860px) and (display-mode: standalone) {
  body, .app-shell { height: 100vh; }
}
@media (min-width: 861px) {
  /* Op desktop staat de zijbalk vast; backdrop nooit tonen */
  .sidebar-backdrop { display: none !important; }
}

.bottom-tab {
  appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  margin: 4px 4px;          /* hoger + smaller → tegel richting vierkant */
  padding: 4px;
  border-radius: var(--r-lg);
  min-width: 0;
  color: var(--label-secondary);
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.bottom-tab .bt-ic { font-size: var(--fs-title); line-height: 1; }   /* alleen iconen onderaan */
/* Labels onderaan visueel weg (alleen iconen), maar wél in de DOM voor screenreaders.
   De tekst-labels blijven wél staan in het bovenmenu (zijbalk, .side-label). */
.bottom-tab .bt-label {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* Ingedrukt / actief: donkere, mooi afgeronde tegel — zoals in het zijmenu. */
.bottom-tab:active { background: var(--surface-3); }
.bottom-tab.active { background: var(--surface-2); color: var(--systemBlue); }

.tab-section { display: none; }
.tab-section.active { display: block; }

/* ============ Klussen / to-do bord ============ */
.tasks-board {
  display: flex;
  flex-direction: column;
  gap: 16px;
}.task-title {
  flex: 1 1 auto;
  min-width: 0;
  appearance: none;
  background: transparent;
  border: 0;
  outline: 0;
  font-family: inherit;
  font-size: var(--fs-body);
  color: var(--label);
  padding: 4px 4px;
  border-radius: var(--r-sm);
  letter-spacing: -0.01em;
}
.task-title:focus { background: var(--surface-2); }/* Touch-apparaten: geen hover, dus verwijderknop altijd subtiel zichtbaar */
.task-empty {
  font-style: italic;
}

/* #1 — Taken-tab: strakkere aansluiting bovenaan (minder marge tot eerste groep) */
[data-tab-content="taken"] .page-actions { margin-bottom: 12px; }/* ====== Taak-detail modal: subtaken + notitie ====== */
.task-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.task-detail-del {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--label-tertiary);
  font-size: var(--fs-input);
  cursor: pointer;
  width: 34px;
  height: 34px;
  border-radius: var(--r-control);
  -webkit-tap-highlight-color: transparent;
  transition: color 0.12s linear, background-color 0.12s linear;
}
.task-detail-del:hover { color: var(--systemRed); background: var(--tint-red); }
.field textarea {
  line-height: 1.4;
  resize: vertical;
}
.field textarea:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }.subtask-list { display: flex; flex-direction: column; margin-bottom: 8px; }
.subtask-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}
.subtask-check {
  flex: 0 0 auto;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: var(--r-xs);
  border: 1.5px solid var(--separator-opaque);
  background: transparent;
  color: #fff;
  font-size: var(--fs-meta);
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, border-color 0.12s linear;
}
.subtask-row.done .subtask-check { background: var(--systemGreen); border-color: var(--systemGreen); }
.subtask-title {
  flex: 1 1 auto;
  min-width: 0;
  appearance: none;
  background: transparent;
  border: 0;
  outline: 0;
  font-family: inherit;
  font-size: var(--fs-body);
  color: var(--label);
  padding: 4px 4px;
  border-radius: var(--r-sm);
  letter-spacing: -0.01em;
}
.subtask-title:focus { background: var(--surface-2); }
.subtask-row.done .subtask-title { color: var(--label-tertiary); text-decoration: line-through; }
.subtask-del {
  opacity: 0.55;
  transition: opacity 0.12s linear, color 0.12s linear, background-color 0.12s linear;
}
.subtask-del:hover { opacity: 1; color: var(--systemRed); background: var(--tint-red); }/* Subtaak toevoegen — rustige ghost-regel "＋ Subtaak" (geen invoervak-look) */
.subtask-add { display: flex; align-items: center; gap: 8px; padding: 3px 0 2px; }
.subtask-add .sa-plus { color: var(--systemBlue); font-size: var(--fs-heading); font-weight: 500; flex: none; line-height: 1; }
/* #146 — inline invoer in een rij: geen vak, wel dezelfde tekstmaat. Twee
   plekken (zoeken in een lijst, een subtaak toevoegen) delen deze regel. */
.subtask-add input, .list-search-input {
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--label);
  padding: 4px 2px;
  font-size: var(--fs-body);
  font-family: inherit;
}
.subtask-add input::placeholder { color: var(--systemBlue); opacity: 0.85; }
.subtask-add input:focus { outline: none; }/* Detail: onderdelen (besteld/binnen + kosten) */
.parts-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 9px; }
#eventBreakdownList { margin-top: 8px; margin-bottom: 0; }
.part-row { display: flex; align-items: center; gap: 8px; background: var(--surface-2); border-radius: var(--r-control); padding: 8px 12px; }
.part-row .pn { flex: 1 1 auto; min-width: 0; font-size: var(--fs-body); color: var(--label); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.part-row .pc { font-size: var(--fs-sub); font-weight: 600; color: var(--label-secondary); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.part-del:hover { color: var(--systemRed); background: var(--tint-red); }
.part-add { display: flex; gap: 8px; }
.part-add input#taskDetailPartName, .part-add input.part-name-input { flex: 1 1 auto; }
.part-add input.part-cost-input { flex: 0 0 88px; text-align: right; }
.part-add input:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }/* ====== Settings: account- en auto-rijen ====== */
.settings-rows { display: flex; flex-direction: column; gap: 4px; }
.settings-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  appearance: none;
  background: var(--surface-2);
  border: 0;
  color: var(--label);
  font-family: inherit;
  font-size: var(--fs-body);
  text-align: left;
  padding: 12px 12px;
  border-radius: var(--r-control);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
/* #77: de privacylink is een <a> i.p.v. een <button> (echte navigatie, opent in een nieuw
   tabblad) — dezelfde rij-stijl, maar zonder browser-onderstreping. */
.settings-link { text-decoration: none; }
.settings-link:hover:not(:disabled) { background: var(--surface-3); }
.settings-link:disabled { cursor: default; color: var(--label-secondary); }
.settings-link-label { letter-spacing: -0.01em; }
.settings-badge {
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--label-tertiary);
  background: var(--surface);
}
.settings-chev { color: var(--label-tertiary); font-size: var(--fs-heading); line-height: 1; }
.settings-badge-ok { color: var(--systemGreen); background: var(--tint-green); }

/* ====== #77 (K3): account verwijderen — onomkeerbare zone ====== */
/* Hergebruikt bewust de .totp-box-vorm (zelfde soort inline-bevestigingsblok binnen
   Instellingen), maar in rood: dit is de enige actie in de app die data definitief wist. */
.danger-box { display: flex; flex-direction: column; gap: 8px; background: var(--tint-red); border: 1px solid var(--systemRed); border-radius: var(--r-control); padding: 12px 12px; margin-top: 6px; }
.danger-box p { margin: 0; font-size: var(--fs-sub); line-height: 1.5; color: var(--label); }
.danger-box .danger-warn { font-weight: 600; }
.danger-box .danger-hint { color: var(--label-secondary); }

.danger-box input:focus { outline: none; box-shadow: 0 0 0 2px var(--systemRed); }
.danger-actions { display: flex; gap: 8px; }
.danger-actions .btn { flex: 1; }
.settings-link.settings-link-danger .settings-link-label { color: var(--systemRed); }

/* ====== #15b: 2FA (TOTP) instellingen ====== */
.totp-box { display: flex; flex-direction: column; gap: 8px; background: var(--surface-2); border-radius: var(--r-control); padding: 12px 12px; margin-top: 6px; }
.totp-hint { font-size: var(--fs-sub); color: var(--label-secondary); line-height: 1.5; margin: 0; }
.totp-hint.totp-warn { color: var(--systemOrange); font-weight: 600; }
.totp-secret {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-body);
  letter-spacing: 0.04em;
  word-break: break-all;
  background: var(--surface);
  border-radius: var(--r-sm);
  padding: 8px 12px;
  user-select: all;
}
/* Het blok zelf staat al op --surface-2, dus een veld in diezelfde tint zou erin oplossen.
   Binnen dit blok is --surface de "inhoud"-laag — precies wat .totp-secret hierboven ook doet. */
.totp-box input { background: var(--surface); }
.totp-actions { display: flex; gap: 8px; }
.totp-actions .btn { flex: 1; }
.totp-backup-codes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px;
}
.totp-backup-codes code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-body);
  background: var(--surface);
  border-radius: var(--r-sm);
  padding: 8px 8px;
  text-align: center;
}
.settings-hint {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  margin: 8px 2px 2px;
  letter-spacing: -0.005em;
}
.settings-hint .settings-hint-lbl { color: var(--label-tertiary); }
/* ============ Drijvende toevoeg-knop (FAB) + iOS-stijl keuzemenu ============ */
.fab-wrap {
  position: fixed;
  right: max(20px, env(safe-area-inset-right));
  bottom: max(20px, env(safe-area-inset-bottom));
  z-index: var(--z-nav);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  /* De wrap omvat óók de (gesloten, onzichtbare) .fab-menu → mag GEEN touches opvangen,
     anders blokkeert hij scrollen in de hele rechteronderhoek. Alleen de knop/het open
     menu zijn interactief. */
  pointer-events: none;
}
.fab {
  appearance: none;
  position: relative;
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 60px;
  height: 60px;
  min-width: 60px;
  min-height: 60px;
  padding: 0;
  aspect-ratio: 1 / 1;
  border: 0;
  border-radius: 50%;
  background: var(--btn-primary-bg);
  color: #fff;
  font-size: 0;                 /* tekst-"+" verbergen; plus wordt getekend (zie ::before/::after) */
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  pointer-events: auto;        /* knop blijft klikbaar, ook al is de wrap touch-transparant */
  transition: transform 0.16s ease, filter 0.12s linear;
}
/* Getekend plusje — exact gecentreerd, los van font-metrics */
.fab::before,
.fab::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: #fff;
  border-radius: var(--r-2xs);
}
.fab::before { width: 24px; height: 3px; transform: translate(-50%, -50%); }   /* horizontale balk */
.fab::after  { width: 3px;  height: 24px; transform: translate(-50%, -50%); }  /* verticale balk */
.fab:hover { filter: brightness(1.07); }
.fab:active { transform: scale(0.92); }
.fab-wrap.open .fab { transform: rotate(45deg); }   /* + draait naar × */

.fab-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-nav) - 1);
  background: rgba(0, 0, 0, 0.16);
}

.fab-menu {
  min-width: 210px;
  background: var(--surface);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: 0 12px 44px rgba(0, 0, 0, 0.38);
  transform-origin: bottom right;
  transform: scale(0.82);
  opacity: 0;
  visibility: hidden;            /* zie .modal-bg — anders vier onzichtbare tabstops (A1) */
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s linear;
}
.fab-wrap.open .fab-menu { transform: scale(1); opacity: 1; visibility: visible; pointer-events: auto; }
.fab-menu-title {
  padding: 8px 16px 4px;
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
}
.fab-menu-item {
  appearance: none;
  background: transparent;
  border: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  font-family: inherit;
  font-size: var(--fs-input);
  font-weight: 500;
  color: var(--label);
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.fab-menu-item + .fab-menu-item { border-top: 0.5px solid var(--separator); }
.fab-menu-item:hover  { background: var(--surface-2); }
.fab-menu-item:active { background: var(--surface-3); }
.fab-mi-ic { font-size: var(--fs-heading); width: 24px; text-align: center; flex: 0 0 auto; }
.fab-menu-item.current { color: var(--systemBlue); font-weight: 600; }

/* ============ Instellingen — thema-kiezer (visuele previews) ============ */
.theme-options { display: flex; gap: 10px; }
.theme-opt {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  -webkit-tap-highlight-color: transparent;
}
.theme-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 14 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #20242e;
  box-shadow: 0 0 0 1.5px var(--separator-opaque);
  transition: box-shadow 0.15s ease;
}
.theme-opt:hover .theme-thumb { box-shadow: 0 0 0 1.5px var(--label-tertiary); }
.theme-opt.selected .theme-thumb { box-shadow: 0 0 0 3px var(--systemBlue); }
.theme-opt-label {
  font-size: var(--fs-meta);
  font-weight: 500;
  color: var(--label-secondary);
  letter-spacing: -0.005em;
}
.theme-opt.selected .theme-opt-label { color: var(--label); font-weight: 600; }

/* Mini desktop-mockup binnen een thumbnail */
.tw { position: absolute; inset: 0; }
.tw--light { background: linear-gradient(135deg, #f8f6f1 0%, #e8e4da 100%); }
.tw--dark  { background: linear-gradient(135deg, #173341 0%, #08151b 100%); }
.tw--clip  { clip-path: inset(0 0 0 50%); }            /* rechterhelft → 'auto' split */
.tw-menu {
  position: absolute;
  top: 16%; left: 12%;
  width: 44%; height: 12%;
  border-radius: var(--r-2xs);
  background: var(--systemBlue);
}
.tw-win {
  position: absolute;
  left: 12%; right: 12%; bottom: 0;
  height: 52%;
  border-radius: 7px 7px 0 0;
}
.tw--light .tw-win { background: #fffefb; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06); }
.tw--dark  .tw-win { background: #102530; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06); }
.tw-dots { position: absolute; top: 13%; left: 9%; display: flex; gap: 3px; }
.tw-dots i { display: block; width: 5px; height: 5px; border-radius: 50%; }
.tw-dots i:nth-child(1) { background: #ff5f57; }
.tw-dots i:nth-child(2) { background: #febc2e; }
.tw-dots i:nth-child(3) { background: #28c840; }

/* Hoeken-thumbnail: kaartje met de betreffende corner radius op een donkere achtergrond */
.radius-options { display: flex; gap: 10px; }
.radius-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 14 / 9;
  border-radius: var(--r-md);
  overflow: hidden;
  background: linear-gradient(135deg, #46506e 0%, #1f2435 100%);
  box-shadow: 0 0 0 1.5px var(--separator-opaque);
  transition: box-shadow 0.15s ease;
}
/* De thema-thumbs hiernaast tonen bewust hun eigen thema (dat is hun onderwerp). Deze twee
   gaan over hoekradius, niet over kleur — die hoorden dus gewoon het huidige thema te volgen,
   maar stonden altijd donkerblauw en vielen in het lichte thema uit de toon (V8). Literale
   kleuren, net als bij .tw--light / .tw--dark, want dit is een miniatuur en geen echt paneel. */
:root[data-theme="light"] .radius-thumb { background: linear-gradient(135deg, #dfe3ee 0%, #b4bcd2 100%); }
.theme-opt:hover .radius-thumb { box-shadow: 0 0 0 1.5px var(--label-tertiary); }
.theme-opt.selected .radius-thumb { box-shadow: 0 0 0 3px var(--systemBlue); }
.rw {
  position: absolute;
  inset: 24% 18%;
  background: #fcfcfe;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.10);
}
.rw::before {
  content: "";
  position: absolute;
  top: 16%; left: 14%;
  width: 30%; height: 16%;
  border-radius: inherit;
  background: var(--systemBlue);
}
/* Stijl-preview-thumbnails: bewust vaste radii zodat ze de twee opties tónen,
   onafhankelijk van de actieve UI-stijl. Niet tokeniseren. */
.rw--rounded { border-radius: 11px; }
.rw--sharp   { border-radius: var(--r-2xs); }

/* ============ Instellingen — data-knoppen rij ============ */
/* Tussenkopje binnen een instellingen-sectie. Lichter dan .modal-section (dat trekt een lijn
   en begint een nieuw blok); dit deelt een blok alleen onder. Gebruikt om de databestanden te
   scheiden op wat je ermee kunt: terugzetten of alleen bekijken. */
.settings-subhead {
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--label-secondary);
  margin: 16px 2px 2px;
}
.settings-subhead:first-of-type { margin-top: 10px; }

.settings-data-row { display: flex; gap: 8px; margin: 8px 0 4px; }
.settings-data-row .btn { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 4px; }
.settings-data-row .glyph { color: var(--label-tertiary); font-size: var(--fs-sub); }

/* ============================================================
   Instellingen — zes groepen (14-09-2026, schetsen-instellingen.html)
   Eén lijst van 1755 px werd zes groepen in twee vormen: onder 860 px is `.set-nav` een hub
   (tik een groep aan, het paneel neemt het scherm over), daarboven staat diezelfde nav vast
   als zijbalk naast het paneel. In beide gevallen dezelfde panelen.
   ============================================================ */
.set-nav { display: flex; flex-direction: column; gap: 4px; }
.set-navitem {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  appearance: none;
  background: var(--surface-2);
  border: 0;
  color: var(--label);
  font-family: inherit;
  font-size: var(--fs-body);
  text-align: left;
  padding: 12px 12px;
  border-radius: var(--r-control);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.set-navitem:hover { background: var(--surface-3); }
.set-navic {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: var(--r-icon);
  background: var(--tint-blue);
  color: var(--systemBlue);
  display: flex;
  align-items: center;
  justify-content: center;
}
.set-navic .licon { width: var(--ic-md); height: var(--ic-md); }
.set-navtxt { flex: 1 1 auto; min-width: 0; }
.set-navt { display: block; letter-spacing: -0.01em; }
/* De onderregel is de reden dat deze vorm werkt: wat er ingesteld staat, zonder te openen. */
.set-navs { display: block; font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 1px; }
.set-navs:empty { display: none; }
.set-chev { flex: 0 0 auto; color: var(--label-tertiary); font-size: var(--fs-heading); line-height: 1; }
.set-pane { min-width: 0; }
/* Binnen een paneel staan de tussenkopjes dichter op elkaar dan in de oude lange lijst; iets
   meer lucht eromheen, anders plakt "Volgt uit je regio" aan het veldlabel eronder vast. */
.set-pane .settings-subhead { margin: 16px 2px 4px; }
.set-pane .settings-subhead:first-child { margin-top: 2px; }

/* Smal: de hub verdwijnt zodra er een paneel openstaat (terug via de kopbalk), en de
   Sluiten-knop is overbodig — instellingen worden meteen opgeslagen en de kopbalk sluit. */
@media (max-width: 860px) {
  .modal-bg.pane-open .set-nav { display: none; }
  .modal--settings > .modal-actions { display: none; }
}

/* Breed: navigatiekolom naast het paneel. De kolom toont alleen de namen — de waarden staan
   in het paneel zelf, dat hier altijd openstaat. */
@media (min-width: 861px) {
  .modal--settings { max-width: 760px; }
  .modal--settings .modal-scroll { display: flex; padding: 0; overflow: hidden; }
  .modal--settings .set-shell {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
  }
  .modal--settings .set-nav {
    gap: 3px;
    padding: 12px 8px;
    border-right: 0.5px solid var(--separator);
    overflow-y: auto;
  }
  .modal--settings .set-navitem { background: transparent; }
  .modal--settings .set-navitem:hover { background: var(--surface-2); }
  .modal--settings .set-navitem.active { background: var(--surface-2); font-weight: 600; }
  /* De zijbalk toont alleen de namen — de waarden staan in het paneel zelf. Let op de scope:
     `.set-nav`, niet de hele modal, anders verdwijnt ook de 2FA-badge in het Account-paneel. */
  .modal--settings .set-nav .set-navs,
  .modal--settings .set-nav .set-chev,
  .modal--settings .set-nav .settings-badge { display: none; }
  /* #85 — elk paneel was zo hoog als zijn eigen inhoud (gemeten: 464 tot 569 px), dus het
     venster wipte tot 105 px op en neer bij het wisselen van groep en verschoof de
     Sluiten-knop mee. De bodem ligt nu bij het hoogste paneel (Data & privacy). In `rem`,
     niet in px: bij 150 % tekst groeit dat paneel mee en zou een vaste hoogte gaan afkappen.
     Komt er een instelling bij, kijk dan of dit getal nog klopt. */
  .modal--settings .set-panes { padding: 16px 20px 20px; overflow-y: auto; min-height: 29rem; }
}

/* Rijen met een icoontegel en een onderregel (Account-paneel, schets §7). `.settings-link` blijft
   de basisvorm; dit voegt alleen de twee onderdelen toe die zo'n rij extra heeft. */
.set-rowic {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: var(--r-icon);
  background: var(--tint-blue);
  color: var(--systemBlue);
  display: flex;
  align-items: center;
  justify-content: center;
}
.set-rowic .licon { width: var(--ic-md); height: var(--ic-md); }
.set-rowic.danger { background: var(--tint-red); color: var(--systemRed); }
.settings-link-txt { flex: 1 1 auto; min-width: 0; text-align: left; }
.settings-link-sub { display: block; font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 1px; }
/* De chevron van een rij die iets ópenklapt draait mee, zodat hij niet navigatie belooft. */
.settings-link[aria-expanded] .settings-chev { transition: transform 0.15s ease; }
.settings-link[aria-expanded="true"] .settings-chev { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .settings-link[aria-expanded] .settings-chev { transition: none; }
}

/* Identiteitsrij bovenaan het Account-paneel: naam boven, e-mailadres eronder. */
.settings-idrow {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface-2);
  border-radius: var(--r-control);
  padding: 12px 12px;
  margin-bottom: 2px;
}
.settings-idtxt { min-width: 0; }
.settings-idname { display: block; font-size: var(--fs-body); color: var(--label); letter-spacing: -0.01em; }
.settings-idmail { display: block; font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 1px; word-break: break-all; }

/* Aan/uit-regel in Instellingen (13B). Bewust géén `.field`: `.field label` heeft
   specificiteit 0,1,1 en wint van elke klasse op het label zelf — het vinkje stond daardoor
   als blok-element bóven een bijschrift in kapitalen, en `.field input { width: 100% }` rekte
   het op tot 401 px (14-09-2026 in de browser gemeten). Een schakelaar is geen invoerveld met
   een label erboven, dus hij hoort ook niet in die vorm te staan. */
.set-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface-2);
  border-radius: var(--r-control);
  padding: 12px 12px;
  cursor: pointer;
}
.set-toggle-txt { min-width: 0; }
.set-toggle-t { display: block; font-size: var(--fs-body); color: var(--label); letter-spacing: -0.01em; }
.set-toggle-s { display: block; font-size: var(--fs-sub); color: var(--label-secondary); line-height: 1.45; margin-top: 3px; }
/* De schakelaar zelf staat bij de knoppen; hier alleen de bewegingsvoorkeur. */
@media (prefers-reduced-motion: reduce) {
  .toggle, .toggle::after, .set-switch, .set-switch::after { transition: none; }
}

/* ============================================================
   Garage (#89–#92) — álle auto's, als lijst of als bord.
   Eén component, drie plekken: compact in de zijbalk/la, rijk in de garage en de auto-hub.
   ============================================================ */
.modal--garage { max-width: 720px; }
/* #150 — de balk bovenin de garage (.garage-bar) is vervallen: de schakelaar staat nu in de
   kop van de wisselaar (.carhub-switchbar), onder de huidige auto. Zonder auto is die kop
   het eerste in het venster en hoort hij niet op 24 px van de titel te beginnen. */
#garageBody > .carhub-switchbar:first-child .carhub-section { margin-top: 0; }
.garage-count {
  margin-left: 6px;
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
}
.garage-view .gv {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--label-secondary);
  padding: 0 var(--sp-3);
  min-height: 30px;
  border-radius: calc(var(--r-control) - 3px);
  cursor: pointer;
  line-height: 0;
}
.garage-view .gv .licon { width: var(--ic-sm); height: var(--ic-sm); }

.car-rows { display: flex; flex-direction: column; gap: 8px; }
/* #verbeterpunten-2-garage-1 — de rij en de potloodknop ernaast. De knop stáát ernaast en zit
   er niet in: een knop in een knop bestaat niet in HTML. */
.car-row-wrap { display: flex; align-items: stretch; gap: 8px; min-width: 0; }
.car-row-wrap > .car-row { flex: 1 1 auto; min-width: 0; }
.car-row-edit {
  flex: 0 0 auto;
  appearance: none; border: 0; cursor: pointer;
  width: 44px; border-radius: var(--r-control);
  background: var(--surface-2); color: var(--label-secondary);
  display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.car-row-edit:hover { background: var(--surface-3); color: var(--label); }
.car-row-edit:active { opacity: 0.7; }
.car-row-edit .licon { width: var(--ic-md); height: var(--ic-md); }
.car-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  appearance: none;
  background: var(--surface-2);
  border: 0;
  color: var(--label);
  font-family: inherit;
  text-align: left;
  padding: 12px 12px;
  border-radius: var(--r-control);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.car-row:hover { background: var(--surface-3); }
.car-row.active { background: var(--tint-blue); }
.car-row-ic {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: var(--r-icon);
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
}
.car-row-ic .licon { width: var(--ic-md); height: var(--ic-md); }
.car-row-body { flex: 1 1 auto; min-width: 0; }
.car-row-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.car-row-name { font-size: var(--fs-body); letter-spacing: -0.01em; }
/* De plaat wordt als SVG getekend (Calc.renderPlateSVG); hier alleen op maat gebracht. */
.car-row-plate svg, .car-card-plate svg { height: 18px; width: auto; display: block; }
/* #150 — een Noord-Amerikaanse plaat is 300 × 150 en een Europese 520 × 110. Op dezelfde
   hoogte is de Amerikaanse dus ruim twee keer zo smal en wordt hij een postzegel waar je
   niets meer op leest. Hij mag hoger (verzoek Gilles), en is daarmee ook groter. Dezelfde
   uitzondering staat bij de pill in de kop en bij de rij in het menu. */
.car-row-plate .plate-na, .car-card-plate .plate-na { height: 30px; }
.car-row-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
}
.car-row-check { flex: 0 0 auto; color: var(--systemBlue); font-weight: 700; }

/* Bord: de foto als heldplaatje, met het kenteken erop. */
.car-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 8px;
}
.car-card {
  position: relative;
  background: var(--surface-2);
  border-radius: var(--r-card);
  overflow: hidden;
}
.car-card-main {
  appearance: none;
  border: 0;
  padding: 0;
  margin: 0;
  background: transparent;
  width: 100%;
  display: block;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
/* De fotoknop ligt óver de kaart, maar staat er in de HTML náást: een knop in een knop
   bestaat niet, en de browser trekt zo'n constructie uit elkaar. */
/* #1 — sinds de foto achteraf bijgesneden kan worden staan er twee knoppen: bijsnijden en
   vervangen. Ze zitten in één balkje zodat ze samen op- en afdimmen (en de tweede niet
   halverwege de kaart hangt). */
.car-card-tools {
  position: absolute;
  right: 6px;
  top: 6px;
  display: flex;
  gap: 4px;
  z-index: 1;
}
.car-card-photo {
  appearance: none;
  border: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--scrim);
  color: var(--on-photo);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s linear;
}
.car-card-photo .licon { width: var(--ic-sm); height: var(--ic-sm); }
.car-card:hover .car-card-photo,
.car-card-photo:focus-visible { opacity: 1; }
/* Op een aanraakscherm bestaat hover niet — daar staat de knop gewoon altijd aan. */
@media (hover: none) {
  .car-card-photo { opacity: 1; }
}
.car-card.active { outline: 2px solid var(--systemBlue); outline-offset: -2px; }
.car-card-check { z-index: 1; }
.car-card-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 10;
  max-width: 100%;
  background: var(--surface-3);
  background-size: cover;
  background-position: center;
}
.car-card-hero.has-photo { background-color: var(--surface); }
.car-card-ic .licon { width: 30px; height: 30px; color: var(--label-tertiary); }
.car-card-plate { position: absolute; right: 7px; bottom: 7px; }
.car-card-check {
  position: absolute; left: 7px; top: 7px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--btn-primary-bg); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-meta); font-weight: 700;
}
.car-card-body { display: block; padding: 8px 12px 12px; }
.car-card-name { display: block; color: var(--label); font-size: var(--fs-body); letter-spacing: -0.01em; }
.car-card-facts { display: block; color: var(--label-tertiary); font-size: var(--fs-meta); margin-top: 3px; font-variant-numeric: tabular-nums; }

/* "Auto toevoegen" hoort in de garage, niet meer in de zijbalk op desktop. */
.car-add {
  appearance: none;
  background: transparent;
  border: 1px dashed var(--separator-opaque);
  color: var(--systemBlue);
  font-family: inherit;
  font-size: var(--fs-body);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  border-radius: var(--r-control);
  cursor: pointer;
  width: 100%;
}
.car-board .car-add { min-height: 6rem; }
.car-add:hover { background: var(--surface-2); }
.car-add-ic { font-size: var(--fs-heading); line-height: 1; }

/* De hub deelt de garage-component; alleen de kopregel met de schakelaar is van hem. */
.carhub-switchbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.carhub-switchbar .carhub-section { margin-bottom: 0; }
.carhub-switchbar .garage-view .glyph { line-height: 0; }

/* ============================================================
   #97 — onderhoudstijdlijn. Eén component, twee plekken: compact bovenaan het dashboard
   (#95, besluit Gilles 14-09-2026) en wat uitgebreider boven de onderhoudslijst.
   ============================================================ */
.tl-card {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 14px 16px 12px;
  margin-bottom: 12px;
}
.tl-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
}
.tl-title {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
}
.tl-head-right { display: flex; align-items: center; gap: 10px; flex: none; }
/* #104 — het bedrag staat er áltijd bij, ook als er iets over tijd is. Tot 14-09-2026
   verdrong "2 over tijd" het bedrag, en dan blijft de halve vraag onbeantwoord. Het zijn
   twee antwoorden op twee verschillende vragen, dus ze staan naast elkaar. */
.tl-overdue { font-size: var(--fs-sub); font-weight: 600; color: var(--systemRed); }
.tl-cost { font-size: var(--fs-sub); color: var(--label-secondary); font-variant-numeric: tabular-nums; }
/* Dezelfde schakelaar als in de garage (.garage-view/.gv): hetzelfde soort keuze hoort er
   hetzelfde uit te zien. Alleen wat kleiner, want hij staat in een kopregel. */
.tl-switch .gv { padding: 4px 8px; }
.tl-switch .gv .licon { width: var(--ic-sm); height: var(--ic-sm); }

/* ---------- variant A: de maandstrook ---------- */
.tl-strip { display: flex; align-items: stretch; gap: 6px; }
/* Achterstallig hoort niet ín de kalender — het is geen maand die nog komt. Eigen blok
   ervóór, zodat "twee maanden te laat" en "anderhalf jaar te laat" niet op dezelfde plek
   belanden zoals ze op de oude as deden. */
.tl-now {
  flex: none;
  min-width: 3.5rem;
  background: var(--tint-red);
  border-radius: var(--r-md);
  padding: 6px 8px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
}
.tl-now-lab {
  font-size: var(--fs-meta); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--systemRed);
}
.tl-now-n { font-size: var(--fs-heading); font-weight: 700; line-height: 1; color: var(--systemRed); }
.tl-now-sub { font-size: var(--fs-meta); color: var(--label-tertiary); line-height: 1.2; }

.tl-cells {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 3px;
}
.tl-cell {
  background: var(--surface-2);
  border-radius: var(--r-sm);
  min-height: 3.25rem;
  padding: 4px 2px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2px;
  min-width: 0;
}
/* Een maand zonder iets is niet leeg maar rustig: hij vertelt dat er dán niets hoeft. */
.tl-cell:not(.on) { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.tl-cell-m {
  font-size: var(--fs-meta);
  text-align: center;
  color: var(--label-quaternary);
  overflow: hidden;
  white-space: nowrap;
}
.tl-cell.on .tl-cell-m { color: var(--label-secondary); font-weight: 600; }
.tl-chip {
  display: block;
  height: 0.4375rem;
  margin: 0 3px;
  border-radius: var(--r-pill);
  background: var(--systemGreen);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.tl-chip.soon { background: var(--systemOrange); }
.tl-chip.overdue { background: var(--systemRed); }
/* Een datum die uit kilometers is afgeleid is een voorspelling, geen afspraak — dus opener. */
.tl-chip.est { opacity: 0.55; }
.tl-chip-more { display: block; height: 0.4375rem; margin: 0 3px; font-size: var(--fs-meta);
  line-height: 0.4375rem; text-align: center; color: var(--label-quaternary); font-weight: 700; }

/* #verbeterpunten-dashboard-4 — kalender op "all vehicles": een auto-kleur bovenop de
   urgentiekleur (rand i.p.v. vulling, want de vulling is al bezet door soon/overdue/ok) en
   een kopje per auto in de legenda eronder. */
/* #146 — de kleur per voertuig kwam uit vijf ongewijzigde iOS-systeemkleuren die
   buiten het palet vielen en niet met het thema meeschakelden. Nu dezelfde zes. */
.tl-chip.fc-0 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-1) 70%, transparent); }
.tl-chip.fc-1 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-2) 70%, transparent); }
.tl-chip.fc-2 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-3) 70%, transparent); }
.tl-chip.fc-3 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-4) 70%, transparent); }
.tl-chip.fc-4 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-5) 70%, transparent); }
.tl-chip.fc-5 { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--cat-6) 70%, transparent); }
.tl-fleet-group + .tl-fleet-group { margin-top: 10px; padding-top: 10px; border-top: 0.5px solid var(--separator); }
.tl-fleet-car { display: block; width: 100%; text-align: left; background: transparent; border: 0;
  font-family: inherit; cursor: pointer; padding: 4px 6px 2px; font-size: var(--fs-meta); font-weight: 700;
  color: var(--label-secondary); }
.tl-fleet-car::before { content: ''; display: inline-block; width: 7px; height: 7px; border-radius: var(--r-pill);
  margin-right: 6px; background: var(--label-quaternary); }
.tl-fleet-car.fc-0::before { background: var(--cat-1); }
.tl-fleet-car.fc-1::before { background: var(--cat-2); }
.tl-fleet-car.fc-2::before { background: var(--cat-3); }
.tl-fleet-car.fc-3::before { background: var(--cat-4); }
.tl-fleet-car.fc-4::before { background: var(--cat-5); }
.tl-fleet-car.fc-5::before { background: var(--cat-6); }

/* ---------- de legenda onder de strook ---------- */
.tl-rows { display: flex; flex-direction: column; margin-top: 10px; }
.tl-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  appearance: none;
  background: transparent;
  border: 0;
  padding: 4px 6px;
  border-radius: var(--r-sm);
  font-family: inherit;
  font-size: var(--fs-sub);
  color: var(--label-secondary);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tl-row-when {
  flex: none;
  width: 2.5rem;
  font-weight: 600;
  color: var(--systemGreen);
  font-variant-numeric: tabular-nums;
}
.tl-row.soon .tl-row-when { color: var(--systemOrange); }
.tl-row.overdue .tl-row-when { color: var(--systemRed); }
.tl-row.est .tl-row-when { opacity: 0.7; }
.tl-row-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--label); }
.tl-row-cost { flex: none; color: var(--label-tertiary); font-variant-numeric: tabular-nums; }
.tl-later { margin-top: 6px; padding: 0 6px; font-size: var(--fs-meta); color: var(--label-quaternary); }

/* #104 — aanwijzen koppelt blokje en regel aan elkaar. Dat is wat een tooltip níét kan op een
   aanraakscherm, en de reden dat een stip met alleen een kleur geen informatie is. */
.tl-row:hover, .tl-row.hl { background: var(--surface-2); }
/* #149 — stond op `scale(1.2, 2)`. Twee ongelijke factoren rekken ook de hoeken mee: een
   blokje van 7 px met `--r-pill` (dus rond) werd een afgeplatte ovaal van 14 px hoog en maar
   1,2× zo breed. De vorm veránderde bij het aanwijzen in plaats van dichterbij te komen
   ("bij hover klik op pil shape in calendar evenredig schalen. Want nu veranderd de vorm en
   dat is lelijk" — Gilles). Eén factor houdt de pil een pil.

   Die factor kan niet groot zijn: een blokje vult zijn maandhokje bijna helemaal, dus alles
   boven ~1,15 schuift over de buren heen (de 3 px marge plus de 3 px rastergap is alle ruimte
   die er is). De zichtbaarheid komt daarom van de ring, die daarvoor een stap dikker wordt —
   dat is wat de tweede schaalfactor in de praktijk deed. */
.tl-chip:hover, .tl-chip.hl { transform: scale(1.15); box-shadow: 0 0 0 2px var(--label-quaternary); }
.tl-row:focus-visible, .tl-item:focus-visible { outline: 2px solid var(--systemBlue); outline-offset: -2px; }

/* ---------- variant B: de agendalijst ---------- */
.tl-list { display: flex; flex-direction: column; }
.tl-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 0.5px solid var(--separator);
  padding: 8px 4px;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tl-item:last-child { border-bottom: 0; }
.tl-item:hover, .tl-item.hl { background: var(--surface-2); }
.tl-item-when { flex: none; width: 3.75rem; text-align: center; }
.tl-item-when .tiw-big {
  display: block; font-size: var(--fs-input); font-weight: 700; line-height: 1.15;
  letter-spacing: -0.01em; color: var(--label);
}
.tl-item-when .tiw-small {
  display: block; font-size: var(--fs-sub); color: var(--label-tertiary);
}
.tl-item.overdue .tiw-big, .tl-item.overdue .tiw-small { color: var(--systemRed); }
.tl-item-bar { flex: none; align-self: stretch; width: 3px; border-radius: var(--r-2xs); background: var(--systemGreen); }
.tl-item.soon .tl-item-bar { background: var(--systemOrange); }
.tl-item.overdue .tl-item-bar { background: var(--systemRed); }
.tl-item-body { flex: 1 1 auto; min-width: 0; }
.tl-item-name {
  display: block; font-size: var(--fs-body); color: var(--label); letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tl-item-sub { display: block; font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 1px; }
.tl-item-cost { flex: none; font-size: var(--fs-sub); color: var(--label-secondary); font-variant-numeric: tabular-nums; }

.tl-empty { line-height: 1.5; }

/* ============================================================
   #87 — verdelingsbalk op de kostenpagina.
   Eigen kleurenreeks: de categoriepillen delen kleuren (onderhoud en reparatie zijn allebei
   oranje), en in een gestapelde balk zouden twee buurvakken dan in elkaar overlopen. Elke
   categorie heeft hier dus een eigen tint — mét de naam ernaast, want kleur alleen is geen
   informatie voor wie kleuren slecht onderscheidt.
   ============================================================ */
.split-card {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 12px 16px 12px;
  margin-bottom: 16px;
}
.split-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 10px;
}
.split-title {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
}
.split-total { font-size: var(--fs-body); font-weight: 700; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
/* De periode hoort bij de kop maar is geen kop: zonder hoofdletters en zonder vetgedrukt,
   zodat "AFGELOPEN 12 MAANDEN" niet even hard roept als de titel zelf. */
.split-period {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-meta);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--label-quaternary);
}
.split-bar {
  display: flex;
  height: 1rem;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--surface-2);
}
.split-seg { display: block; height: 100%; transition: opacity 0.12s ease; }
.split-seg + .split-seg { box-shadow: inset 1px 0 0 var(--scrim-soft); }
/* Aanwijzen koppelt vak en regel aan elkaar, net als de maandkalender van #104. De overige
   vakken doven in plaats van dat het aangewezen vak een randje krijgt: de balk is maar 1rem
   hoog en `overflow: hidden`, dus een omlijning valt binnen zo'n vak weg. Zo zie je meteen
   hoe groot het déél is dat je te pakken hebt. */
.split-bar.has-hl .split-seg { opacity: 0.3; }
.split-bar.has-hl .split-seg.hl { opacity: 1; }

.split-sw { width: 10px; height: 10px; border-radius: var(--r-2xs); flex: 0 0 auto; }
/* Eén bron voor de kleuren: vak in de balk én blokje in de lijst. */
.split-seg.onderhoud,   .split-sw.onderhoud   { background: var(--cat-1); }
.split-seg.reparatie,   .split-sw.reparatie   { background: var(--cat-2); }
.split-seg.brandstof,   .split-sw.brandstof   { background: var(--cat-3); }
.split-seg.laden,       .split-sw.laden       { background: var(--cat-3); }
.split-seg.mrb,         .split-sw.mrb         { background: var(--cat-4); }
.split-seg.verzekering, .split-sw.verzekering { background: var(--cat-4); }
.split-seg.banden,      .split-sw.banden      { background: var(--cat-5); }
.split-seg.lease,       .split-sw.lease       { background: var(--cat-6); }
.split-seg.overig,      .split-sw.overig      { background: var(--cat-6); }
.split-seg.rest,        .split-sw.rest        { background: var(--surface-3); }
/* #4 — afschrijving krijgt bewust géén categoriekleur maar een streepjespatroon. Het is geen
   geld dat je hebt uitgegeven maar waarde die je kwijt bent, en de balk hoort dat verschil te
   laten zien in plaats van het te verdoezelen tussen acht gelijkwaardige vakjes. */
.split-seg.afschrijving {
  background: repeating-linear-gradient(-45deg,
    var(--label-quaternary) 0 3px, var(--surface-3) 3px 6px);
}
/* Het blokje in de legenda is 10 x 10 px; met dezelfde streepbreedte als in de balk wordt dat
   één vlekje. Smallere strepen met meer contrast zijn op die maat nog te herkennen. */
.split-sw.afschrijving {
  background: repeating-linear-gradient(-45deg,
    var(--label-tertiary) 0 2px, var(--surface-3) 2px 4px);
}

.split-legend { display: flex; flex-direction: column; margin-top: 10px; }
.split-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--label-secondary);
  font-family: inherit;
  font-size: var(--fs-sub);
  text-align: left;
  padding: 4px 4px;
  border-radius: var(--r-xs);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.split-row:hover, .split-row.hl { background: var(--surface-2); }
.split-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.split-amount { color: var(--label); font-variant-numeric: tabular-nums; }
.split-pct { width: 2.75rem; text-align: right; color: var(--label-tertiary); font-variant-numeric: tabular-nums; }
.split-rest-list { padding-left: 20px; }
/* De afschrijvingsrij is geen filterknop (zie splitRowHtml) en mag dus ook niet als knop
   aanvoelen: zelfde maatvoering, geen hover, geen cursor. */
.split-row-static { cursor: default; }
.split-row-static:hover { background: transparent; }
/* Geen hover-achtergrond (het is geen knop), maar de koppeling met de balk moet wél te zien
   zijn — anders is de afschrijvingsrij de enige die niet meedoet. Wijs je de rij zélf aan,
   dan licht alleen het vak in de balk op: een achtergrond onder je muis leest als een knop,
   en dat is deze rij bewust niet. */
.split-row-static.hl { background: var(--surface-2); }
.split-row-static.hl:hover { background: transparent; }
.split-row-rest[aria-expanded="true"] { color: var(--label); }

/* #82 — de schattingsregel staat vastgepind bovenaan de kostenlijst en moet er ánders
   uitzien dan een echte uitgave: hij telt niet mee in het totaal. */
.item-row.cost-est {
  background: transparent;
  border: 1px dashed var(--separator-opaque);
}
.item-row.cost-est .item-amount { color: var(--est-ink); }
.est-tag {
  font-size: var(--fs-meta);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--systemBlue);
  background: var(--tint-blue);
  border-radius: var(--r-pill);
  padding: 2px 8px;
  margin-left: 6px;
  vertical-align: 1px;
}

/* ============================================================
   #93 — beeldbord voor taken. Zelfde gegevens als de lijst, alleen groot: de eerste foto als
   heldplaatje. Zonder foto geen leeg kader maar een effen vlak met een icoon — anders werkt
   het bord alleen voor wie overal foto's bij zet.
   ============================================================ */
.task-board {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: 8px;
}
/* #150 — op een bureaublad drie kolommen (verzoek Gilles): met auto-fill werden het er vier
   of vijf, en dan is de kaart te smal voor wat er sinds deze ronde op staat. Geldt voor
   allebei de beeldborden (taken en reparaties), want die delen dit raster. */
@media (min-width: 861px) {
  .task-board { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* #150 — alle metadata op de kaart, net als in de lijst: het label, de subtaken en de
   notitie bij een taak; de onderdelen, de schatting en de notitie bij een reparatie. Het
   bord toonde alleen titel en één regel, terwijl juist de foto's ernaast vragen om de
   context erbij. Dezelfde chip als in de lijst (.qlabel), dezelfde metaregels als op de
   reparatiekaart (.rep-card-meta) — geen tweede vorm ernaast. */
.tcard-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.tcard-meta .qlabel { margin: 0; }
.tcard-note {
  display: block; margin-top: 6px;
  font-size: var(--fs-meta); color: var(--label-tertiary); line-height: 1.45;
  white-space: pre-wrap; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.tcard .rep-card-meta { padding: 0; margin-top: 8px; }
.tcard {
  position: relative;
  background: var(--surface);
  border-radius: var(--r-card);
  overflow: hidden;
}
.tcard.done { opacity: 0.55; }
.tcard.open { outline: 2px solid var(--systemBlue); outline-offset: -2px; }
.tcard-main {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  width: 100%;
  display: block;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
  color: var(--label);
  -webkit-tap-highlight-color: transparent;
}
.tcard-hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  background: var(--surface-2);
  overflow: hidden;
}
.tcard-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tcard-noimg .licon { width: 26px; height: 26px; color: var(--label-quaternary); }
.tcard-n {
  position: absolute;
  left: 7px;
  top: 7px;
  background: var(--scrim);
  color: var(--on-photo);
  border-radius: var(--r-pill);
  padding: 2px 8px;
  font-size: var(--fs-meta);
}
.tcard-body { display: block; padding: 8px 12px 12px; }
.tcard-title {
  display: block;
  font-size: var(--fs-body);
  line-height: 1.35;
  letter-spacing: -0.005em;
  /* Titels lopen af en toe over twee regels; drie is te veel voor een kaart. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tcard-sub { display: block; font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 4px; }
.tcard-check {
  position: absolute;
  right: 7px;
  top: 7px;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 50%;
  border: 1.5px solid rgba(223, 238, 243, 0.75);
  background: var(--scrim-soft);
  color: transparent;
  font-size: var(--fs-sub);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tcard-check.on { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); color: #fff; }
/* De uitklap-editor staat ónder het bord over de volle breedte; in een rasterkolom zou hij de
   kaarten uit elkaar trekken. */

/* ============ Kosten / Brandstof shared list styles ============ */
/* Energie-schakelaar (alleen PHEV): grote segmented control Tanken/Laden bovenaan
   de Brandstof-/Laden-tab. Houdt de onderbalk op 5 knoppen (#43). */
/* ============ Segmented control ============
   #146 — er waren er vijf: het ingelegde spoor van .energy-switch, de blauw
   gevulde knoppen van .garage-view en .plate-seg, de omrande .login-seg en de
   knoppenrij op het dashboard. Het ingelegde spoor is de rustigste en is nu de
   enige vorm; de andere selectors delen deze regels. */
.energy-switch,
.garage-view,
.login-seg,
.plate-seg {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--separator-opaque);
  border-radius: var(--r-control);
  border: 0;
  overflow: hidden;
}
.energy-switch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-bottom: 20px;
}
/* Het actieve segment licht op als een kaartje ín het spoor. */
.energy-seg.active,
.garage-view .gv.on,
.login-tab.active,
.plate-seg button.on {
  background: var(--surface);
  color: var(--label);
  font-weight: 600;
}
/* [hidden] verbergen: de display:grid hierboven (author-rule) wint anders van de
   UA-regel [hidden]{display:none}, waardoor de schakelaar áltijd zichtbaar bleef.
   Alleen PHEV toont de schakelaar (zie applyTabVisibility). (#43) */
.energy-switch[hidden] { display: none; }
.energy-seg {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 8px;
  border-radius: calc(var(--r-control) - 3px);
  background: transparent;
  color: var(--label-secondary);
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.01em;
  transition: background 0.15s ease, color 0.15s ease;
}
.energy-seg .es-ic { display: inline-flex; }
.energy-seg .es-ic .licon { width: var(--ic-md); height: var(--ic-md); }
.energy-seg.active {
  background: var(--surface);
  color: var(--label);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16);
}
.energy-seg:not(.active):active { background: var(--surface-3); }

.kpi-grid {
  display: grid;
  /* De kolombreedte telt in rem (UX-audit A7). Bij de standaard lettergrootte staan er
     net als altijd twee naast elkaar; zet iemand zijn browsertekst op 150 %, dan past er
     nog maar één tegel op een rij en stapelen ze vanzelf — i.p.v. dat `overflow: hidden`
     hieronder het bedrag halverwege afkapt ("$7,384." zonder cijfers erachter). */
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 2px;
  background: var(--separator-opaque);
  border-radius: var(--r-control);
  overflow: hidden;
  /* Verzoek Gilles (19-09-2026): "teveel marge op mobiel". Op een telefoon staan er
     drie van deze rasters onder elkaar op de Brandstof-tab, en 24 px onder élk raster
     plus 32 px boven elke sectiekop maakte van drie blokken een scrollpagina.
     16 px op de telefoon, 24 px zodra er ruimte is. */
  margin-bottom: var(--sp-4);
}
@media (min-width: 861px) { .kpi-grid { margin-bottom: var(--sp-6); } }
/* #150 — op het dashboard staan de tegels in een blok dat door een sectiekop (32 px
   erboven) wordt gevolgd; dezelfde afstand als de rijen daar (.dash-rows). */
.dash-tasks > .kpi-grid { margin-bottom: 8px; }
/* Geen lege grijze cel meer: een losse KPI (lege staat) of de 3e van precies
   drie pakt de volle breedte i.p.v. een leeg kwadrant te laten staan.
   Op breder scherm passen alle drie naast elkaar op één rij. */
.kpi-grid > .kpi:first-child:last-child,
.kpi-grid > .kpi:nth-child(3):last-child { grid-column: 1 / -1; }
@media (min-width: 560px) {
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
  .kpi-grid > .kpi:nth-child(3):last-child { grid-column: auto; }
}
.kpi {
  background: var(--surface);
  padding: 12px 12px;
  min-width: 0;
}
/* De twee uitsplitsbare kosten-KPI's zijn <button> (T7): ze wáren een <div tabindex="0">, dus
   ze kregen wel focus maar deden niets met Enter of spatie. Als button erven ze de knop-reset. */
button.kpi {
  border: 0;
  width: 100%;
  text-align: left;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  display: block;
}
.kpi .label {
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
}
.kpi .value {
  font-size: var(--fs-title);
  font-weight: 700;
  letter-spacing: -0.022em;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.kpi .unit {
  font-size: var(--fs-sub);
  font-weight: 500;
  color: var(--label-tertiary);
  margin-left: 2px;
}
.kpi .sub {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  margin-top: 1px;
  letter-spacing: -0.005em;
}

/* ---------- twee varianten op dezelfde tegel ----------
   Staan hier en niet bij .kpi-grid hierboven: ze overschrijven .kpi .value en .kpi .sub,
   en die hebben dezelfde soortelijkheid — dan wint de laatste regel. */

/* De onderregels van één rij lijnen op de bodem uit. Nodig zodra twee tegels naast elkaar
   een waarde van verschillende hoogte dragen ("4,42 L/100km" past op één regel,
   "23,45 kWh/100km" op twee); zonder dit staat de ene datum een regel hoger dan de andere. */
.kpi--even { display: flex; flex-direction: column; }
.kpi--even .sub { margin-top: auto; }

/* Een raster met ondersteunende cijfers in plaats van kopgetallen. Zelfde tegel, zelfde
   raster, alleen de waarde een stap kleiner: "Uitschieters" en "Ritme" staan ónder de drie
   kopgetallen en horen die niet te evenaren. Het is ook wat een meting mét eenheid
   ("23,45 kWh/100km") leesbaar houdt in twee kolommen. */
.kpi-grid--compact .kpi .value { font-size: var(--fs-body); letter-spacing: -0.01em; }
.kpi .value.good { color: var(--systemGreen); }
.kpi .value.bad  { color: var(--systemRed); }
/* Een meting mag afbreken in plaats van afgekapt worden: "23,45 kWh/10…" is onbruikbaar,
   over twee regels gewoon te lezen. Hij breekt op de spatie vóór de eenheid; het bedrag
   zelf blijft heel, want Intl zet daar een harde spatie. */
@media (max-width: 26rem) {
  .kpi-grid--compact .kpi .value { white-space: normal; overflow-wrap: anywhere; }
}

/* ============ Statistiekblok (#152) ============
   Brandstof en Laden hadden drie tegelrasters onder elkaar, elk met een eigen sectiekop.
   Het is nu één blok: de drie kerngetallen, een rij "Meer statistiek", en daaronder de rest.
   De buitenste laag levert de haarlijnen — de rasters erbinnen zijn doorzichtig en laten
   die 2 px doorschijnen, zodat elke tegelrij in het blok dezelfde scheiding heeft. */
.stat-block {
  display: grid;
  gap: 2px;
  background: var(--separator-opaque);
  border-radius: var(--r-control);
  overflow: hidden;
  margin-bottom: var(--sp-4);
}
.stat-block > .kpi-grid,
.stat-block .kpi-grid { margin-bottom: 0; border-radius: 0; background: transparent; }
.stat-more {
  appearance: none;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  background: var(--surface);
  border: 0;
  padding: 12px;
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--systemBlue);
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.stat-more:hover { background: var(--surface-2); }
.stat-more .disc-chev { color: inherit; }
/* De uitklapinhoud is zelf ook een rij in het blok: eigen ondergrond, en de rasters
   erbinnen scheiden zich met dezelfde 2 px. */
.stat-more-body { display: grid; gap: 2px; background: var(--separator-opaque); }
.stat-more-body > div:empty { display: none; }
/* Twee tegelrasters onder elkaar (uitschieters, ritme) krijgen dezelfde haarlijn ertussen
   als de rijen erboven. */
.stat-rows { display: grid; gap: 2px; }
/* Het omstandighedenblok is geen tegelraster maar een stel balkjes; het krijgt daarom
   zijn eigen vlak en een bescheiden kop — de sectiekop die het had past niet binnen een
   blok waar verder geen koppen staan. */
.stat-more-body > #fuel-cond-stats:not(:empty) { background: var(--surface); padding: 12px; }
/* De groepjes wáren losse kaarten op de pagina-achtergrond; binnen het blok is het blok
   zelf de kaart, dus hier geen tweede laag oppervlak eromheen. */
.stat-more-body .cond-stat-group { background: transparent; padding: 0; border-radius: 0; }
.stat-sub-head {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
  margin-bottom: var(--sp-2);
}

/* #152 — op het dashboard staan bij Kosten en Brandstof de tegels van élk voertuig, elk
   onder zijn eigen naam (verzoek Gilles). Zonder dat label zijn twee rijen tegels niet uit
   elkaar te houden. Zelfde koptekst als .stat-sub-head, maar met ruimte erónder én erboven:
   dit zijn losse blokken onder elkaar, geen kop binnen één blok. */
.dash-kpi-row + .dash-kpi-row { margin-top: var(--sp-3); }
.dash-kpi-label {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary);
  margin-bottom: var(--sp-1);
  padding-left: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dash-kpi-row .kpi-grid { margin-bottom: 0; }

/* Kosten-KPI: uitsplitsing per categorie (hover op desktop, tik op touch) */
.kpi-area { position: relative; margin-bottom: 24px; }
.kpi-area .kpi-grid { margin-bottom: 0; }
.kpi-has-pop { position: relative; cursor: pointer; }
.kpi-has-pop.active { background: var(--surface-2); }
/* UX-audit 3C/8C — nieuwe onderdelen van het kosten-KPI-blok:
   .kpi-est    de geschatte brandstof-/laadkosten (stonden eerst in de lijst)
   .kpi-nudge  wat er nog ontbreekt om per maand / per km te kunnen rekenen
   .kpi-dep    de schakelaar "afschrijving meetellen" */
/* 18B — het zojuist gelogde onderhoudspunt licht even op na het hersorteren. */
@keyframes justLoggedPulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--systemBlue) 55%, transparent); }
  100% { box-shadow: 0 0 0 10px transparent; }
}
.just-logged { animation: justLoggedPulse 1.3s ease-out 2; border-color: var(--systemBlue) !important; }
@media (prefers-reduced-motion: reduce) { .just-logged { animation: none; } }.kpi.kpi-nudge { grid-column: 1 / -1; }
.kpi.kpi-nudge .sub { margin-top: 2px; }
.kpi.kpi-nudge .btn { margin-top: 8px; }
.kpi-dep { margin: 8px 2px 0; }
.kpi-dep-toggle {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  font-size: var(--fs-sub); color: var(--label-secondary);
}
.kpi-dep-toggle input { accent-color: var(--btn-primary-bg); width: 16px; height: 16px; margin: 0; }
.kpi-dep-toggle .kdt-alt { color: var(--label-tertiary); }
.kpi-pop-hint {
  /* Was --label-quaternary: 1,38:1 in het lichte thema, dus praktisch onzichtbaar —
     terwijl dit de enige aanwijzing is dát de tegel uitleg bevat (UX-audit A4).
     --label-quaternary blijft voor streepjes en lege-staat-iconen; dit is een
     aanwijzer van een bedieningselement. */
  color: var(--label-tertiary); font-size: var(--fs-meta); margin-left: 3px;
}
.kpi-split {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: var(--z-menu);
  background: var(--surface);
  border: 0.5px solid var(--separator);
  border-radius: var(--r-card);
  padding: 8px 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
}
.kpi-pop-title {
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
  margin-bottom: 6px;
}
.kpi-pop-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 4px 0;
  font-size: var(--fs-sub);
}
.kpi-pop-row + .kpi-pop-row { border-top: 0.5px solid var(--separator); }
.kpi-pop-label { color: var(--label-secondary); }
.kpi-pop-value { font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: -0.005em; }
.kpi-pop-empty { font-style: italic; }

/* ============================================================
   #138-2 — de knoppenbalk rechtsboven, op elke pagina hetzelfde

   Elke tab had zijn eigen bakje boven de inhoud: het dashboard .dashboard-scope (tekstknoppen
   van 40 px), Onderhoud .maint-bar (een .btn-pil), Taken en Reparaties een .action-row met een
   "⋯"-menu van 34 x 34 px waar de acties in weggeklapt zaten — en dat menu verdween ook nog
   zodra de lijst leeg was. Drie vormen, drie maten, drie kleuren voor dezelfde plek.

   Nu is het één rij (.page-actions) met één knopvorm (.btn), rechts uitgelijnd, direct onder
   de auto-wisselaar. De knoppen staan er altijd, uitgeklapt, en een aan-stand is overal
   dezelfde donkerblauwe vulling (--btn-primary-bg) als de dashboardschakelaar.
   ============================================================ */
.page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  margin: 0 0 16px;
  min-height: var(--ctl-h);
}
/* De samenvattingsregel die op Taken/Reparaties/Brandstof links in deze rij stond ("3 van 7
   klaar") — geen knop, dus hij duwt de knoppen met margin-right naar rechts. */
.pga-sub {
  margin-right: auto;
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* #146 — .pgb bestaat niet meer: de knoppen in deze balk zíjn .btn. Wat hier
   overblijft is alleen de aan-stand, en die hangt aan `aria-pressed` — het
   attribuut dat er voor de schermlezer toch al stond. `.on` blijft meedoen,
   want een paar renderers zetten alleen die klasse. */
.btn.on,
.btn[aria-pressed="true"] { background: var(--btn-primary-bg); color: #fff; }
.btn.on:hover,
.btn[aria-pressed="true"]:hover { background: var(--btn-primary-bg); filter: brightness(1.12); }
.btn-ic { display: inline-flex; align-items: center; color: inherit; }
.btn .licon { width: var(--ic-sm); height: var(--ic-sm); }
/* De lijst/beeldbord-schakelaar staat in dezelfde rij en is even hoog; de losse
   .gv is elders (garage, tijdlijn) bewust kleiner. */
/* In de paginabalk is het spoor even hoog als een knop (--ctl-h), dus het
   segment erbinnen is dat min de 2 x 3 px rand van het spoor. */
.page-actions .garage-view { margin-left: 2px; min-height: var(--ctl-h); }
.page-actions .garage-view .gv {
  min-height: calc(var(--ctl-h) - 6px);
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.12s linear, color 0.12s linear;
}
/* Op een telefoon passen drie knoppen niet naast de samenvattingsregel; die krijgt dan een
   eigen regel, zodat de knoppen als groep bij elkaar blijven in plaats van dat er één alleen
   op de eerste regel achterblijft. */
@media (max-width: 600px) {
  /* #140 — de samenvattingsregel ("1/5 klaar") had een eigen regel voor zichzelf alleen, en
     de knoppen erboven pasten er net niet naast. Nu deelt hij zijn regel: wat er nog bij past
     schuift aan, de rest valt netjes naar de regel eronder. */
  .pga-sub { flex: 1 1 auto; margin-right: auto; }
  .page-actions .garage-view { flex: 0 0 auto; }
  .page-actions .btn { padding: 0 var(--sp-3); }
  /* Taken heeft drie bedieningen en die passen samen niet op 375 px. In plaats van er één
     willekeurig te laten afbreken of ze alle drie samen te persen: de schakelaar deelt de
     bovenste regel met de samenvatting, en de twee tekstknoppen delen de regel eronder in
     gelijke helften. Twee rustige regels in plaats van een ragged rij.

     De regelovergang wordt afgedwongen met een leeg flex-item van 100 % breed (::after) tussen
     de schakelaar en de knoppen; `order` zet het op de juiste plek. Zonder dat item krimpen de
     knoppen liever dan dat ze afbreken — en dan staat er "Group …" / "Hide d…". */
  [data-tab-content="taken"] .pga-sub { order: -2; }
  [data-tab-content="taken"] .page-actions .garage-view { order: -1; }
  [data-tab-content="taken"] .page-actions::after { content: ""; order: 0; flex: 0 0 100%; height: 0; }
  [data-tab-content="taken"] .page-actions .btn { order: 1; flex: 1 1 0; min-width: 0; }
  .page-actions .btn > span:not(.btn-ic) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* Vrije-tekst zoekbalk boven lijsten (tankbeurten / kosten / logboek) */
.list-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border-radius: var(--r-control);
  padding: 0 12px;
  margin: 0 0 8px;
}
.list-search[hidden] { display: none; }
.list-search-ic { flex: 0 0 auto; font-size: var(--fs-sub); line-height: 1; opacity: 0.55; }

.list-search-input::placeholder { color: var(--label-tertiary); }
.list-search:focus-within { box-shadow: 0 0 0 2px var(--systemBlue); }
.list-search-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--separator-opaque);
  cursor: pointer;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") center/12px no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 6l12 12M18 6L6 18' stroke='black' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E") center/12px no-repeat;
}.dash-tasks { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }.dash-chev { flex: 0 0 auto; color: var(--label-tertiary); font-size: var(--fs-heading); line-height: 1; padding-left: 4px; }

/* Cost / fueling rows */
.item-list {
  display: grid;
  gap: 4px;
  margin-bottom: 12px;
}
.item-row {
  appearance: none;
  background: var(--surface);
  border: 0;
  border-radius: var(--r-control);
  padding: 12px 12px;
  display: grid;
  grid-template-columns: 36px 1fr auto;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  font-family: inherit;
  color: var(--label);
  text-align: left;
  width: 100%;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.item-row:hover  { background: var(--surface-2); }
.item-row:active { background: var(--surface-3); }
.item-row.readonly { cursor: default; }
/* #114 — een kostenpost met deelbedragen (opknapwerk) krijgt een vierde kolom voor de
   uitvouw-chevron; de rij zelf is dan een <div> (bevat al een knop, zie costs.js) i.p.v.
   een <button>, maar blijft verder identiek getekend via dezelfde .item-row-regels. */
.item-row--exp { grid-template-columns: 36px 1fr auto auto; }
.cost-breakdown-toggle {
  appearance: none; background: none; border: 0; color: var(--label-tertiary); cursor: pointer;
  width: 28px; height: 28px; border-radius: var(--r-xs); display: flex; align-items: center; justify-content: center;
}
.cost-breakdown-toggle:hover { color: var(--label); background: var(--surface-3); }
.cost-breakdown { margin: 2px 0 4px; padding-left: 12px; }
.cost-breakdown .part-row { background: transparent; padding: 4px 12px; }
.cost-breakdown-total { border-top: 0.5px solid var(--separator); margin-top: 2px; padding-top: 8px !important; }
.cost-breakdown-total .pn, .cost-breakdown-total .pc { font-weight: 700; color: var(--label); }
.item-row.readonly:hover { background: var(--surface); }
.item-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--r-icon);
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-heading);
}
.item-body { min-width: 0; }
/* 4B — een afgekapte titel is aantikbaar en klapt dan uit. Het beletselteken komt van
   text-overflow; de onderstippeling laat zien dát er meer staat. */
.item-title.is-clipped, .qnm.is-clipped, .mc-name.is-clipped {
  cursor: pointer;
  text-decoration: underline dotted var(--label-tertiary);
  text-underline-offset: 3px;
}
.item-title.is-expanded, .qnm.is-expanded, .mc-name.is-expanded {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  /* Eén lang woord ("Kraftstofffilter") wikkelt niet vanzelf; zonder dit blijft ook de
     uitgeklapte versie afgekapt. */
  overflow-wrap: anywhere;
}
.item-title {
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.item-sub {
  font-size: var(--fs-meta);
  color: var(--label-secondary);
  margin-top: 2px;
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
  /* Tot 2 regels i.p.v. midden in het km-getal afkappen ("251.92…"); de
     " · "-scheidingen bevatten spaties, dus tokens wrappen netjes als geheel. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.item-amount {
  font-size: var(--fs-input);
  font-weight: 700;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.item-amount .unit {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  font-weight: 500;
  margin-left: 2px;
}
.item-amount .sub {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  font-weight: 500;
  margin-top: 2px;
}
.cat-pill {
  display: inline-block;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-right: 6px;
  vertical-align: 1px;
}
/* #146 — de pillen putten uit hetzelfde palet als de balk hierboven; ze stonden
   er los van (brandstof was blauw in de pil en oranje in de balk). */
.cat-pill.onderhoud  { background: color-mix(in srgb, var(--cat-1) 18%, transparent); color: var(--cat-1); }
.cat-pill.reparatie  { background: color-mix(in srgb, var(--cat-2) 18%, transparent); color: var(--cat-2); }
.cat-pill.brandstof  { background: color-mix(in srgb, var(--cat-3) 18%, transparent); color: var(--cat-3); }
.cat-pill.laden      { background: color-mix(in srgb, var(--cat-3) 18%, transparent); color: var(--cat-3); }
.cat-pill.mrb        { background: color-mix(in srgb, var(--cat-4) 18%, transparent); color: var(--cat-4); }
.cat-pill.verzekering{ background: color-mix(in srgb, var(--cat-4) 18%, transparent); color: var(--cat-4); }
.cat-pill.banden     { background: color-mix(in srgb, var(--cat-5) 18%, transparent); color: var(--cat-5); }
.cat-pill.lease      { background: color-mix(in srgb, var(--cat-6) 18%, transparent); color: var(--cat-6); }
.cat-pill.overig     { background: var(--surface-2);   color: var(--label-secondary); }/* Form select */
.field select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%238e8e93' d='M5 6 0 0h10z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 32px;
  transition: background-color 0.12s linear, box-shadow 0.12s linear;
}
.field select:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }
.field-note {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  margin-top: 4px;
  letter-spacing: -0.005em;
}

/* Toggle switch (iOS style) */
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--surface-2);
  border-radius: var(--r-control);
  padding: 12px 12px;
  margin-bottom: 12px;
}
.toggle-row .toggle-label {
  font-size: var(--fs-body);
  font-weight: 500;
  letter-spacing: -0.005em;
}
.toggle-row .toggle-sub {
  font-size: var(--fs-meta);
  color: var(--label-secondary);
  margin-top: 2px;
}
/* ============ Chip en badge ============
   #146 — een chip is aanklikbaar (filter, keuze, label), een badge niet (status,
   interval, telling). Meer smaken zijn er niet. Allebei pilvormig: dat is nu het
   enige dat nog een pil is, dus een chip is herkenbaar géén knop.

   De maten stonden hiervóór op 0,625 / 0,6875 / 0,75 / 0,8125 / 0,875 rem door
   elkaar; het zijn er twee geworden — een chip leest (--fs-sub), een badge telt
   (--fs-meta). */
/* Verzoek Gilles (19-09-2026): "bij bewerken veld taken is label lelijk vierkant".
   Terecht, en het was erger dan dat: dit gedeelde blok mist sinds #146 zijn eigen
   declaraties. Er stond nog wél vorm-gedrag in (display, gap, line-height), maar de
   maat, de vulling, de binnenruimte én de pilvorm waren eruit — precies het rijtje
   dat de kop hierboven belooft. `.cond-chip` zet die vier zelf nog een keer en zag er
   dus goed uit; `.elabel-chip` en `.svc-chip` vielen terug op wat de browser van een
   <input> en een <button> vindt: vierkant, met de standaard binnenruimte.

   Dit is dezelfde soort fout als de drie uit ronde #146 — een zoekvervanging die een
   gedeelde regel half opat — en hij is er doorheen geglipt omdat check-ui-tokens.mjs
   op verkeerde waarden let, niet op ontbrekende. */
.chip,
.svc-chip,
.svc-pill,
.elabel-chip,
.cond-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  line-height: 1.3;
  border: 0;
  -webkit-tap-highlight-color: transparent;
  font-family: inherit;
  font-size: var(--fs-sub);
  font-weight: 600;
  padding: 4px 10px;
  border-radius: var(--r-pill);
}
/* #149 — exact dezelfde fout als bij het chip-blok hierboven, en gevonden door dezelfde
   twee meldingen van Gilles: "2fa tag is lelijk vorm gegeven" en "alle tags op kosten zijn
   geen pil vorm meer, behalve schatting". Ook dít gedeelde blok werd in #146 ronde D geboren
   zonder de vier declaraties die het hoorde te dragen — de maat, het gewicht, de binnenruimte
   en de pilvorm. `.hi-badge` zet ze verderop zelf nog een keer en zag er dus goed uit;
   `.cat-pill` en `.settings-badge` vielen terug op de standaardvorm van de browser, en dus
   op een vierkant zonder binnenruimte. Dat `.est-tag` ("schatting") wél een pil bleef, was
   het verschil waaraan je het zag: die staat buiten dit blok en zet zijn vorm zelf.
   De maten komen uit de schaal: 0,625rem/0,6875rem van vóór #146 lagen onder de 12 px-
   ondergrens, dus het is --fs-meta. */
.badge,
.cat-pill,
.settings-badge,
.hi-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  line-height: 1.3;
  font-size: var(--fs-meta);
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--r-pill);
}

/* ============ Schakelaar ============
   #146 — er waren er twee: `.toggle` (een <div role="switch"> van 44 x 26 px die
   groen werd) en `.set-switch` (een <input type=checkbox> van 2,75 x 1,625 rem —
   precies dezelfde 44 x 26 px — die blauw werd). Dezelfde vorm, dezelfde maat,
   een andere kleur, afhankelijk van in welk scherm hij stond.

   Nu één definitie voor allebei de vormen, en aan is blauw (keuze van 19-09):
   blauw is overal in de app "dit kun je bedienen", en groen betekent hier juist
   "op schema". Een groene schakelaar zei twee dingen tegelijk. */
.toggle,
.set-switch {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  position: relative;
  width: 44px;
  height: 26px;
  background: var(--surface-3);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background-color 0.18s linear;
  flex: 0 0 auto;
}
.toggle::after,
.set-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  background: #fff;
  border-radius: var(--r-pill);
  box-shadow: var(--shadow-1);
  transition: transform 0.18s linear;
}
.toggle.on,
.set-switch:checked { background: var(--btn-primary-bg); }
.toggle.on::after,
.set-switch:checked::after { transform: translateX(18px); }
.toggle:focus-visible,
.set-switch:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }

.svc-chip {
  background: var(--surface);
  color: var(--label-secondary);
  cursor: pointer;
  letter-spacing: -0.005em;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.svc-chip:hover { background: var(--surface-3); color: var(--label); }
.svc-chip.active {
  background: var(--tint-blue);
  border-color: var(--systemBlue);
  color: var(--systemBlue);
  font-weight: 600;
}
.svc-chip .ic { font-size: var(--fs-body); line-height: 1; }/* Compacte onderdeel-kiezer in de event-modal */
.svc-selected { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.svc-none { color: var(--label-tertiary); font-size: var(--fs-sub); font-style: italic; }
.svc-pill {
  background: var(--tint-blue);
  border: 0;
  color: var(--systemBlue);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  -webkit-tap-highlight-color: transparent;
}
.svc-pill-x { font-size: var(--fs-meta); opacity: 0.7; }
.svc-pill:hover .svc-pill-x { opacity: 1; }
.svc-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  background: var(--surface-2);
  padding: 8px 12px;
  border-radius: var(--r-control);
  margin-top: 8px;
  max-height: 190px;
  overflow-y: auto;
}
.svc-picker[hidden] { display: none; }

@media (max-width: 600px) {
  .tabs .tab { font-size: var(--fs-sub); padding: 8px 4px; }
  .item-amount { font-size: var(--fs-body); }
}

@media (max-width: 600px) {
  /* #146 — de twee grootste maten schalen op een telefoon één stap terug. Dat
     gebeurt nu in de schaal zelf, niet per element: alles wat --fs-display of
     --fs-title gebruikt (paginatitel, heldnaam in de hub, sectiekop, KPI-waarde)
     schuift mee, en nieuwe schermen dus ook. */
  :root { --fs-display: 1.75rem; --fs-title: var(--fs-heading); }
  .container { padding: 20px 16px max(48px, env(safe-area-inset-bottom)) 16px; }

  /* ============================================================
     #153 — het eerste item sluit strak aan onder de header

     Verzoek Gilles: "het eerste item, de agenda, mag strak aansluiten onder de header op
     mobiel … eigenlijk mogen alle eerste items op alle pagina's strakker tegen de header.
     Beter gebruik van ruimte."

     Op een telefoon kostte de kop 24 px marge, en wat eronder stond vaak nóg eens 16 px
     (.page-actions) of 32 px (een h2.section als eerste element van een tab). Bij elkaar
     tot 56 px leeg scherm onder een titel van 28 px — op 375 px is dat een zesde van wat
     je ziet. De kop houdt 12 px; het eerste kind van een tabblad begint daar direct onder.

     Dit staat per pagina op `:first-child` binnen `.tab-section` en niet op de losse
     componenten: dan geldt het ook voor een tabblad dat er later bij komt, en blijft de
     afstand tússen de blokken ongemoeid. ============================================ */
  header { margin-bottom: 12px; }
  .tab-section > :first-child { margin-top: 0; }
  .tab-section > .page-actions:first-child { margin-bottom: 8px; }
}

/* ============================================================
   Login screen + car switcher additions (CarDB)
   ============================================================ */

.login-bg {
  position: fixed;
  inset: 0;
  background: var(--bg-grouped);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: var(--z-window);
}
.login-card {
  background: var(--surface);
  border-radius: var(--r-xl);
  padding: 24px 24px;
  max-width: 360px;
  width: 100%;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15);
}
.login-logo {
  display: block;
  width: 64px;
  height: 64px;
  margin: 0 auto 12px;
}
.login-card h1 {
  font-size: var(--fs-title);
  font-weight: 700;
  letter-spacing: -0.022em;
  margin-bottom: 6px;
}
.login-card .sub {
  color: var(--label-secondary);
  font-size: var(--fs-body);
  margin-bottom: 16px;
}
.login-card input {
  margin-bottom: 10px;
}
.login-card input:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }
/* Honeypot: visueel weg (niet display:none — bots negeren display:none vaker), buiten tab-volgorde. */
.hp-field { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.login-card /* 10B — één zin die zegt waar dit voor is. */
.login-pitch { font-size: var(--fs-sub); color: var(--label-secondary); text-align: center; margin: 0 0 4px; line-height: 1.45; }
.login-error {
  font-size: var(--fs-sub);
  color: var(--systemRed);
  min-height: 18px;
  margin-bottom: 6px;
}/* Loading + sync indicator */
.sync-indicator {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  text-align: center;
  margin: 8px 0;
  min-height: 14px;
  letter-spacing: -0.005em;
}
.sync-indicator.error { color: var(--systemRed); }
.sync-indicator.ok    { color: var(--systemGreen); }

.app-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 60vh;
  color: var(--label-tertiary);
  font-size: var(--fs-body);
}
.app-loading::before {
  content: '';
  width: 20px;
  height: 20px;
  border: 2px solid var(--surface-3);
  border-top-color: var(--systemBlue);
  border-radius: var(--r-pill);
  animation: spin 0.8s linear infinite;
  margin-right: 10px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Add-car CTA when no cars exist */
.empty-cars {
  display: flex;
  justify-content: center;
  padding: 48px 20px;
}
.empty-cars-card {
  text-align: center;
  max-width: 380px;
  width: 100%;
  padding: 32px 24px 32px;
  background: var(--surface);
  border-radius: var(--r-card);
  border: 0.5px solid var(--separator);
}
/* Het icoon is decoratie: het herhaalt wat de kop al zegt, dus aria-hidden in de markup. */
.empty-cars-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  margin-bottom: 16px;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--systemBlue);
}
.empty-cars-ic svg { width: 26px; height: 26px; }
.empty-cars h2 { font-size: var(--fs-title); margin-bottom: 8px; }
.empty-cars p { color: var(--label-secondary); margin-bottom: 24px; line-height: 1.45; }
.empty-cars .btn.primary { width: 100%; justify-content: center; }

/* ============================================================
   Attachments (bijlagen)
   ============================================================ */
.attachments-section {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 0.5px solid var(--separator);
}
.attachments-section .modal-section { margin: 0 0 8px; padding-top: 0; border-top: 0; }
.attachments-head {
  font-size: var(--fs-sub);
  font-weight: 600;
  color: var(--label-tertiary);
  margin: 0 0 8px;
}
.attachment-list { display: grid; gap: 4px; margin-bottom: 8px; }
.attachment-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px;
  background: var(--surface-2);
  border-radius: var(--r-control);
  font-size: var(--fs-sub);
}
.attachment-row .att-icon { font-size: var(--fs-heading); line-height: 1; }
.attachment-row a {
  flex: 1;
  min-width: 0;
  color: var(--systemBlue);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.attachment-row .att-size {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  white-space: nowrap;
}
.attachment-row .att-delete:hover { color: var(--systemRed); background: var(--tint-red); }
.attachment-item { display: grid; gap: 4px; }
.att-thumb-link { display: block; line-height: 0; }
.att-thumb {
  display: block;
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: var(--r-control);
  background: var(--surface-2);
}
/* 17A — de knop was een klein pilletje dat wegviel tussen de velden. Nu een zone over de
   volle breedte met een gestippelde rand: hij zégt dat je er iets in mag leggen, en hij is
   met een duim te raken. De tekst noemt de camera eerst — op een telefoon biedt een
   file-input zélf "Foto maken" aan, en dat is bij een bonnetje de gewone weg. */
.attachment-add-btn {
  appearance: none;
  display: flex;
  width: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 16px 12px;
  background: transparent;
  border: 1px dashed var(--separator-opaque);
  border-radius: var(--r-control);
  font-size: var(--fs-sub);
  font-weight: 500;
  cursor: pointer;
  color: var(--label-secondary);
  font-family: inherit;
  min-height: 56px;
}
.attachment-add-btn .licon { width: var(--ic-md); height: var(--ic-md); }
.attachment-add-btn:hover { color: var(--label); background: var(--surface-2); border-color: var(--btn-primary-bg); }
.attachment-add-btn:active { background: var(--surface-2); }
.att-pending-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ============ Kosten leef-cijfers regel ============ */
.costs-lifenote {
  font-size: var(--fs-meta);
  color: var(--label-tertiary);
  letter-spacing: -0.005em;
  margin: -16px 0 20px;
  padding-left: 4px;
}

/* ============ Bijlagen (inklapbaar) ============ */
.attachments-section > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 4px;
  -webkit-tap-highlight-color: transparent;
}
.attachments-section > summary::-webkit-details-marker { display: none; }

/* ============================================================
   Onderhoudsmodule (roadmap #14) — kop, wizard & item-editor
   ============================================================ */

/* #115 — de knoppenbalk van de tab is één knop (Schema). De statuschips (.seg-chip), het
   ⋯-menu en de keuringkaart (.keuring-mini) zijn vervallen: de bakjes zijn het filter, en het
   schema-scherm heeft de zes menu-acties overgenomen. Sinds #138-2 is de balk zelf
   .page-actions; hier blijft alleen de kolombreedte van de bakjes eronder staan. */
.maint-schema-btn .msb-ic { display: inline-flex; color: inherit; }

/* ============================================================
   #115 — bakjes (Nu · Gepland · Later · Nog geen startpunt)
   ============================================================ */
.maint-buckets { display: flex; flex-direction: column; gap: 16px; }
/* Op een breed scherm blijft een regel van 1.200 px leesbaar noch mooi: naam links, bedrag
   rechts, en een halve meter niets ertussen. Dezelfde grens als de oude catalogus. */
@media (min-width: 1040px) { .maint-buckets, .maint-bar { max-width: 980px; } }
/* De balk is rechts uitgelijnd binnen diezelfde kolom, niet tegen de rand van het scherm. */
/* #153 — de schemaknop staat sinds deze ronde ónder de onderhoudsbakjes (net boven de
   bandentracker), dus de lucht hoort erbóven en niet eronder. */
.maint-bar { margin-top: 16px; margin-bottom: 0; }
.mb-bucket { display: block; }
.mb-bucket.folded > summary { list-style: none; cursor: pointer; }
.mb-bucket.folded > summary::-webkit-details-marker { display: none; }
.mb-head {
  display: flex; align-items: baseline; gap: 8px; padding: 0 2px 8px;
}
.mb-title { font-size: var(--fs-sub); font-weight: 800;
  color: var(--label-tertiary); }
.mb-head.nu .mb-title { color: var(--systemRed); }
.mb-head.gepland .mb-title { color: var(--systemOrange); }
.mb-head.keuring .mb-title { color: var(--systemBlue); }
/* #verbeterpunten-maintenance-4 — de keuring staat los van de gewone bakjes, met wat
   ruimte erboven zodat hij niet als vierde bakje oogt. */
.mb-keuring { margin-bottom: 4px; }
.mb-count { font-size: var(--fs-meta); color: var(--label-tertiary); flex: 1; min-width: 0; }
.mb-cost { font-size: var(--fs-sub); font-weight: 700; color: var(--label-secondary);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.mb-rows { background: var(--surface); border: 0.5px solid var(--separator);
  border-radius: var(--r-lg); overflow: hidden; }
.mb-log { width: 100%; margin-top: 10px; }
.mb-allclear { color: var(--label-tertiary); font-size: var(--fs-body); padding: 16px 2px; }

/* De uitnodiging boven "Nog geen startpunt": zonder een laatste beurt loopt er geen teller,
   en dat is precies wat hier op te lossen valt. */
.mb-invite { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: transparent; border: 0; border-bottom: 0.5px solid var(--separator);
  padding: 12px; cursor: pointer; font-family: inherit; color: var(--label); }
.mb-invite:hover { background: var(--surface-2); }
.mb-invite .mbi-ic { display: inline-flex; color: var(--systemBlue); width: 22px; justify-content: center; }
.mb-invite .mbi-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mb-invite .mbi-nm { font-size: var(--fs-body); font-weight: 600; }
.mb-invite .mbi-sub { font-size: var(--fs-meta); color: var(--label-tertiary); }
.mb-invite .mbi-chev { color: var(--label-tertiary); }

/* ---------- één regel ---------- */
.mrow-wrap { border-bottom: 0.5px solid var(--separator); }
.mrow-wrap:last-child { border-bottom: 0; }
.mrow {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px;
  padding: 12px 12px; -webkit-tap-highlight-color: transparent;
  position: relative;
}
/* Dunne voortgangsbalk onderaan de ingeklapte regel — welke teller (km/tijd) het eerst
   aan de beurt is, zonder de rij open te klappen. */
.mrow-prog { position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: transparent; }
/* #verbeterpunten-2-maintenance-1 — ingeklapt is dit dé voortgang van de regel; uitgeklapt
   staan de volledige balken (km én tijd) er meteen onder, en dan zegt dit streepje hetzelfde
   nog een keer — kleiner en zonder label. */
.mrow-wrap[open] > .mrow .mrow-prog { display: none; }
.mrow-prog-fill { height: 100%; background: var(--systemGreen); }
.mrow-prog-fill.soon { background: var(--systemOrange); }
.mrow-prog-fill.overdue { background: var(--systemRed); }
.mrow-prog-fill.unknown { background: var(--label-quaternary); }
.mrow::-webkit-details-marker { display: none; }
.mrow:hover { background: var(--surface-2); }
.mrow-ic { font-size: var(--fs-heading); width: 22px; text-align: center; flex: none; }
.mrow-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mrow-nm { font-size: var(--fs-body); font-weight: 600; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mrow-sub { font-size: var(--fs-meta); color: var(--label-tertiary);
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.mrow-rt { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.mrow-when { font-size: var(--fs-meta); font-weight: 700; color: var(--label-secondary); white-space: nowrap; }
.mrow-when.overdue { color: var(--systemRed); }
.mrow-when.soon { color: var(--systemOrange); }
.mrow-when.unknown { color: var(--label-tertiary); font-weight: 500; }
.mrow-cost { font-size: var(--fs-meta); color: var(--label-tertiary);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.mrow-wrap[open] > .mrow { background: var(--surface-2); }
.mrow-detail { background: var(--surface-2); padding: 2px 12px 12px;
  display: flex; flex-direction: column; gap: 12px; }
/* De "net gelogd"-flits (18B) en scrollToService() mikken op de regel zelf. */
.mrow-wrap.just-logged > .mrow, .mrow-wrap.flash > .mrow { background: var(--systemBlue-tint); }

.mc-desc { font-size: var(--fs-sub); color: var(--label-secondary); }
.mc-est { font-size: var(--fs-meta); color: var(--label-tertiary); }
.mc-foot { display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding-top: 12px; border-top: 0.5px solid var(--separator); flex-wrap: wrap; }
/* #140 — "Item bewerken" staat als tweede knop naast "Klaar"/"Datum bijwerken"; samen rechts,
   tegenover de geschiedenis-regel links. */
.mc-foot-btns { display: flex; align-items: center; gap: 8px; margin-left: auto; }
/* "Item bewerken" staat op een kaart (--surface) en niet op de pagina-achtergrond; `--btn-bg`
   ligt daar zo dicht tegenaan dat de knop als kale tekst leest. Een dun kader maakt 'm weer
   herkenbaar als knop, zonder te concurreren met de gevulde primaire knop ernaast. */
.mc-foot-btns .btn:not(.primary) {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--separator-opaque);
  color: var(--label-secondary);
}
.mc-foot-btns .btn:not(.primary):hover { background: var(--btn-bg-hover); color: var(--label); }
/* Geschiedenis-regel: platte tekst, géén kader/achtergrond. */
.mc-last { background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer;
  font-family: inherit; font-size: var(--fs-meta); color: var(--label-tertiary); text-align: left; }
.mc-last:hover { color: var(--systemBlue); }
.mc-last.empty { cursor: default; font-style: italic; }

/* #138-8 — de familie-regel (.fam-member*, #114/#115) is vervallen met het ouder/kind-systeem:
   elke regel in de lijst is één onderhoudspunt, dus er is geen genest lid meer om te tekenen. */

/* Kleine maat: alleen waar een knop ín een rij of chipwolk staat. */
.btn.small { min-height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-sub); }

/* Preset-kaarten (wizard stap 1) */
.wiz-presets {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 8px; margin: 4px 0 16px;
}
.wiz-preset {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 8px; background: var(--surface); border: 1px solid var(--separator);
  border-radius: var(--r-control); cursor: pointer; color: var(--label);
  transition: background .15s, border-color .15s;
}
.wiz-preset:hover { background: var(--surface-2); }
.wiz-preset.sel { border: 2px solid var(--systemBlue); background: var(--tint-blue); padding: 12px 8px; }
.wiz-preset .wp-ic { font-size: var(--fs-title); line-height: 1; }
.wiz-preset .wp-nm { font-size: var(--fs-sub); font-weight: 600; }
.wiz-preset .wp-ct { font-size: var(--fs-meta); color: var(--label-tertiary); }

/* Schema importeren met AI — keuze onder de presets (#32) */
.wiz-disclaimer {
  margin: 12px 0 16px; padding: 12px 12px;
  background: var(--tint-orange); border: 1px solid var(--separator); border-radius: var(--r-control);
  color: var(--label-secondary); font-size: var(--fs-meta); line-height: 1.45;
}/* Import-scherm (#32) */
.imp-steps { margin: 2px 0 16px; padding: 0 0 0 2px; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.imp-steps li { font-size: var(--fs-sub); color: var(--label-secondary); line-height: 1.45; }
.imp-steps li b { color: var(--systemBlue); margin-right: 4px; }
.imp-prompt-wrap { margin-bottom: 16px; }
.imp-prompt {
  margin: 0 0 8px; padding: 12px; max-height: 168px; overflow: auto;
  background: var(--surface-2); border: .5px solid var(--separator); border-radius: var(--r-control);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-meta); line-height: 1.5;
  color: var(--label-secondary); white-space: pre-wrap; word-break: break-word;
}
.btn.imp-copy { width: 100%; }
.btn.imp-copy.done { background: var(--systemGreen); color: #fff; }
.imp-paste-label { display: block; font-size: var(--fs-meta); font-weight: 600; color: var(--label-secondary); margin: 4px 2px 4px; }
.imp-paste {
  width: 100%; padding: 12px; background: var(--surface-2); color: var(--label);
  border: .5px solid var(--separator); border-radius: var(--r-control);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-meta); line-height: 1.5; resize: vertical;
}
.imp-paste:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }
.imp-file { display: inline-block; margin: 8px 2px 0; font-size: var(--fs-sub); font-weight: 600; color: var(--systemBlue); cursor: pointer; }
.imp-err {
  margin: 12px 0 2px; padding: 8px 12px; border-radius: var(--r-control);
  background: var(--tint-red); color: var(--systemRed); font-size: var(--fs-meta); line-height: 1.4;
}
.imp-warn {
  margin: 0 0 12px; padding: 8px 12px; border-radius: var(--r-control);
  background: var(--tint-orange); color: var(--systemOrange);
  font-size: var(--fs-meta); line-height: 1.5;
}

/* Historie-import — controlelijst (#52) */
.hi-list { display: flex; flex-direction: column; gap: 8px; margin: 0; }
.hi-row {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 12px; background: var(--surface); border: 1px solid var(--separator);
  border-radius: var(--r-control); cursor: pointer;
}
.hi-row.off { opacity: 0.45; }
.hi-row input[type="checkbox"] { margin-top: 3px; flex: none; width: 18px; height: 18px; accent-color: var(--systemBlue); }
.hi-row-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hi-row-name { font-size: var(--fs-body); font-weight: 600; color: var(--label); }
.hi-row-meta { font-size: var(--fs-meta); color: var(--label-secondary); }
.hi-badge {
  display: inline-block; margin-left: 4px; padding: 1px 8px; border-radius: var(--r-pill);
  background: var(--tint-blue); color: var(--systemBlue); font-size: var(--fs-meta); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em; vertical-align: middle;
}

/* ============================================================
   #115 — schema-scherm, keuzes, beurtvenster en nulmeting
   ============================================================ */

/* Het schema: één regel per punt, dezelfde vorm als het overzicht zodat de twee schermen
   niet als twee verschillende apps aanvoelen. */
.sch-info { padding: 2px 2px 12px; }
.sch-info-t { font-size: var(--fs-body); font-weight: 600; }
.sch-info-s { font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 2px; }
.sch-rows { background: var(--surface); border: 0.5px solid var(--separator);
  border-radius: var(--r-lg); overflow: hidden; margin: 8px 0 12px; }
.sch-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  padding: 12px 12px; background: transparent; border: 0; border-bottom: 0.5px solid var(--separator);
  cursor: pointer; font-family: inherit; color: var(--label); }
.sch-row:last-child { border-bottom: 0; }
.sch-row:hover { background: var(--surface-2); }
.sch-row.off { opacity: 0.55; }
.sch-ic { font-size: var(--fs-heading); width: 22px; text-align: center; flex: none; }
.sch-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sch-nm { font-size: var(--fs-body); font-weight: 600; }
.sch-sub { font-size: var(--fs-meta); color: var(--label-tertiary);
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sch-chev { color: var(--label-tertiary); flex: none; }
.sch-archive { margin-bottom: 14px; }
.sch-archive > summary { cursor: pointer; font-size: var(--fs-meta); color: var(--label-tertiary);
  padding: 4px 2px; list-style: none; }
.sch-archive > summary::-webkit-details-marker { display: none; }

/* De drie dingen die een schema kunnen vervángen staan onderaan als bewuste keuze — niet meer
   als bijwerking van een tik op een presetkaart (vangrail G6). */
.sch-action { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
  background: var(--surface); border: 0.5px solid var(--separator); border-radius: var(--r-control);
  padding: 12px; margin-bottom: 8px; cursor: pointer; font-family: inherit; color: var(--label); }
.sch-action:hover { background: var(--surface-2); }
.sch-action .sca-nm { font-size: var(--fs-body); font-weight: 600; flex: none; }
.sch-action .sca-sub { font-size: var(--fs-meta); color: var(--label-tertiary); flex: 1; min-width: 0; }
.sch-action .sca-chev { color: var(--label-tertiary); }
.sch-note { text-align: center; margin-top: 10px; }

/* Het ingeklapte "Meer": omschrijving en de tussenbeurt-markering.
   Alle drie bestonden al in de data, maar waren tot #115 nergens in te stellen. */
.mt-advanced { border-top: 0.5px solid var(--separator); margin-top: 4px; padding-top: 8px; }
.mt-advanced > summary { cursor: pointer; list-style: none; display: flex; align-items: baseline;
  gap: 8px; font-size: var(--fs-sub); font-weight: 600; color: var(--label); padding: 4px 2px; }
.mt-advanced > summary::-webkit-details-marker { display: none; }
.mt-advanced .mt-more-sub { font-size: var(--fs-meta); color: var(--label-tertiary); font-weight: 400; flex: 1; }

/* Radio-keuzes (teller, koppeling, wizard). Eén vorm voor alle drie. */
/* ============================================================
   De item-editor van het onderhoudsschema (verzoek Gilles, 19-09-2026)

   "Schedule editor heeft nu vijf knoppen onderin: annuleren, klaar, archiveren,
   dupliceren en verwijderen. Dat is echt heftig veel en ziet er niet uit. Op desktop
   zijn ook niet alle knoppen zichtbaar." En: "op een groot scherm moet de schedule
   editor een groot two pane scherm worden."

   Drie van die vijf zijn acties óp dit punt en niet op dit formulier; ze horen dus bij
   de titel en niet naast "Klaar". Ze staan nu onder een ⋯-knop in de kopbalk, in het
   menu-component dat het kostenfilter ook gebruikt (.filter-menu). Onderin blijven
   annuleren en klaar.
   ============================================================ */
/* De ⋯-knop. Een vierkant raakdoel van --ctl-h, verder een gewone kopbalkknop. */
.icon-btn {
  appearance: none; background: transparent; border: 0; color: var(--systemBlue);
  font-family: inherit; font-size: var(--fs-title); line-height: 1;
  width: var(--ctl-h); height: var(--ctl-h); display: grid; place-items: center;
  border-radius: var(--r-control); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.icon-btn:hover { background: var(--surface-2); }
.icon-btn[aria-expanded="true"] { background: var(--surface-3); }
/* De wrap is het ankerpunt voor het menu (dat `position: absolute` is). */
.mt-more-wrap { position: relative; display: inline-flex; }
.mt-more-menu { min-width: 200px; }
.cfm-row--danger .cfm-nm { color: var(--systemRed); }

/* Twee panelen op een groot scherm. Onder 861 px — hetzelfde omslagpunt als de rest van
   de app — staan de twee .mt-pane's gewoon onder elkaar en is er geen verschil met
   hiervoor. `align-items: start` zodat het rechterpaneel niet meerekt met het linker:
   de checklist groeit met elk punt dat je toevoegt en zou het formulier ernaast anders
   uit elkaar trekken. */
@media (min-width: 861px) {
  .modal--wide { max-width: 880px; }
  .modal--wide .modal-scroll {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-6);
    align-items: start; padding: var(--sp-5) var(--sp-6) var(--sp-3);
  }
  /* #155 — álles wat niet een van de twee panelen is, hoort over de volle breedte: de
     ondertitel en de stapbalk zijn óók directe kinderen van .modal-scroll en namen anders
     de eerste cel in, waardoor de twee panelen een plek opschoven — links de secties,
     rechts de identiteitskaart, precies omgekeerd. */
  .modal--wide .modal-scroll > :not(.mt-pane) { grid-column: 1 / -1; }
}
.mt-choice { display: flex; flex-direction: column; gap: 8px; }
.mt-radio { display: flex; align-items: flex-start; gap: 8px; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--separator); border-radius: var(--r-control);
  padding: 8px 12px; cursor: pointer; font-family: inherit; color: var(--label); }
.mt-radio.on { border-color: var(--systemBlue); background: var(--tint-blue); }
.mt-radio .mr-dot { width: 16px; height: 16px; border-radius: 50%; flex: none; margin-top: 2px;
  border: 1.5px solid var(--label-tertiary); }
.mt-radio.on .mr-dot { border-color: var(--systemBlue);
  background: radial-gradient(circle, var(--systemBlue) 45%, transparent 47%); }
.mt-radio .mr-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.mt-radio .mr-nm { font-size: var(--fs-sub); font-weight: 600; }
.mt-radio .mr-sub { font-size: var(--fs-meta); color: var(--label-tertiary); }

/* De wizard: drie manieren om te beginnen, in dezelfde vorm als de keuzes hierboven. */
.wiz-choices { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.wiz-choice { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--surface); border: 1px solid var(--separator); border-radius: var(--r-control);
  padding: 12px; cursor: pointer; font-family: inherit; color: var(--label); }
.wiz-choice.sel { border-color: var(--systemBlue); background: var(--tint-blue); }
.wiz-choice .wc-ic { font-size: var(--fs-heading); width: 26px; text-align: center; flex: none; }
.wiz-choice .wc-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.wiz-choice .wc-nm { font-size: var(--fs-body); font-weight: 600; }
.wiz-choice .wc-sub { font-size: var(--fs-meta); color: var(--label-tertiary); }
.wiz-choice .wc-rec { font-size: var(--fs-meta); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--systemBlue); background: var(--tint-blue);
  border-radius: var(--r-2xs); padding: 2px 4px; }

/* Het beurtvenster: aanvinkregels met de reden erbij. De regel is een <label> (zodat de hele
   regel aanklikbaar is), dus de veldlabel-stijl van .field label moet hier expliciet terug naar
   normaal — anders staat elke naam in hoofdletters. */
.visit-rows { display: flex; flex-direction: column; gap: 8px; }
.field .visit-row, .visit-row { display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  cursor: pointer; text-transform: none; letter-spacing: normal; margin-bottom: 0;
  color: var(--label); font-size: var(--fs-sub); font-weight: 400;
  background: var(--surface); border: 1px solid var(--separator); border-radius: var(--r-control); }
.visit-row.on { border-color: var(--systemBlue); background: var(--tint-blue); }
.visit-row input { flex: none; width: 18px; height: 18px; accent-color: var(--systemBlue); }
.visit-ic { font-size: var(--fs-heading); width: 22px; text-align: center; flex: none; }
.visit-bd { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.visit-nm { font-size: var(--fs-sub); font-weight: 600; color: var(--label); text-transform: none; }
.visit-sub { font-size: var(--fs-meta); color: var(--label-tertiary); text-transform: none; font-weight: 400; }

/* De nulmeting: per punt een datum en (optioneel) een kilometerstand.

   #154 — de twee velden stonden elk op een eigen regel op volle breedte, dus elk punt was
   drie regels hoog en een lijst van negen punten een scherm vol lege datumkiezers. Ze delen
   nu één rij (.bl-fields): de datum krijgt de ruimte die er is, de km-stand een vaste smalle
   kolom. Daarmee is een punt twee regels, en lijnen de velden van alle punten onder elkaar
   uit — wat ze eerder niet deden, want een `input[type=date]` zonder breedte neemt zijn eigen
   browsermaat. */
.bl-rows { display: flex; flex-direction: column; gap: 6px; }
.bl-row { display: grid; grid-template-columns: 22px minmax(0, 1fr); align-items: center;
  column-gap: 8px; row-gap: 8px;
  background: var(--surface); border: 0.5px solid var(--separator);
  border-radius: var(--r-control); padding: 8px 12px; }
.bl-ic { font-size: var(--fs-input); text-align: center; grid-column: 1; }
.bl-nm { font-size: var(--fs-sub); font-weight: 600; min-width: 0; grid-column: 2; }
.bl-fields { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) 96px; gap: 8px; }
.bl-fields input { width: 100%; min-width: 0; }
@media (min-width: 560px) {
  .bl-row { grid-template-columns: 22px minmax(0, 1fr) 280px; }
  .bl-nm { align-self: center; }
  .bl-fields { grid-column: 3; grid-template-columns: minmax(0, 1fr) 110px; }
}
/* De snelle manieren bovenaan de nulmeting: pictogram · naam + uitleg · chevron — dezelfde
   opbouw als elke andere rij in de app, zodat ze niet als een blok tekst lezen. */
.sch-action .sca-ic { display: inline-flex; align-items: center; color: var(--systemBlue); flex: none; }
.sch-action .sca-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sch-action .sca-txt .sca-nm { flex: none; }
.sch-action .sca-txt .sca-sub { flex: none; }
.bl-list-head { margin-top: 16px; }

/* Item-editor: checklist-rijen */
.mt-pt { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.mt-pt-kind {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: var(--r-control);
  border: 1px solid var(--separator); background: var(--surface); cursor: pointer;
  font-size: var(--fs-body); line-height: 1; color: var(--label-secondary);
}
.mt-pt-kind.replace { color: var(--systemBlue); border-color: var(--systemBlue); }
.mt-pt-label { flex: 1; min-width: 0; }
.mt-pt-x:hover { color: var(--systemRed); }
.mt-pt-add {
  margin-top: 2px; padding: 4px 2px; background: none; border: none; cursor: pointer;
  color: var(--systemBlue); font-size: var(--fs-sub); font-weight: 600;
}/* Check-kaart: zichtbare controlepunten op de Onderhoud-tab */
.checkpoints {
  list-style: none; margin: 12px 0 0; padding: 12px 0 0;
  border-top: 0.5px solid var(--separator);
  display: flex; flex-direction: column; gap: 8px;
}
.checkpoints li { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sub); color: var(--label); }
.checkpoints li .marker { flex: 0 0 18px; text-align: center; font-size: var(--fs-sub); color: var(--label-tertiary); }
.checkpoints li.replace .marker { color: var(--systemBlue); }
.checkpoints li.check .marker { color: var(--systemGreen); }

/* ============================================================
   Accounts (roadmap #15) — login-tabs, verificatie, meekijken, beheer
   ============================================================ */

/* Login / registreren tabs */
.login-seg { margin: 4px 0 16px; }
.login-tab { flex: 1; padding: 8px 4px; background: none; border: 0; cursor: pointer; color: var(--label-secondary); font-size: var(--fs-body); font-family: inherit; border-radius: calc(var(--r-control) - 3px); }
.login-link { display: block; width: 100%; margin-top: 10px; background: none; border: none; padding: 4px; font-size: var(--fs-sub); color: var(--systemBlue); cursor: pointer; text-align: center; }
.login-link:hover { text-decoration: underline; }
/* #77 (K2): privacylink onderaan de login-/registratiekaart. Rustiger dan .login-link
   (dat zijn acties), want dit is een verwijzing die er permanent staat. */
.login-legal { display: block; width: 100%; margin-top: 14px; padding: 4px; font-size: var(--fs-meta); color: var(--label-secondary); text-align: center; text-decoration: none; }
.login-legal:hover { color: var(--systemBlue); text-decoration: underline; }
.login-reset { margin-top: 6px; display: flex; flex-direction: column; gap: 8px; text-align: left; }
.login-reset strong { color: var(--label); font-size: var(--fs-body); }
.login-verify { margin-top: 14px; padding: 12px 12px; border: 1px solid var(--separator); border-radius: var(--r-control); background: var(--surface-2); font-size: var(--fs-sub); color: var(--label-secondary); line-height: 1.5; }
.login-verify strong { display: block; color: var(--label); font-size: var(--fs-body); margin-bottom: 3px; }
.login-verify a { color: var(--systemBlue); }

/* Meekijk-balk (admin, alleen-lezen) */
.view-banner { display: flex; align-items: center; gap: 8px; padding: 8px 12px; margin: 0 0 16px; background: var(--systemOrange); color: var(--on-accent); font-size: var(--fs-sub); font-weight: 600; border-radius: var(--r-control); }
.view-banner[hidden] { display: none; }
.view-banner .vb-ic { font-size: var(--fs-input); flex: none; }
.view-banner .vb-text { flex: 1; min-width: 0; }
.view-banner .vb-back { background: rgba(0,0,0,.18); border: 0; color: var(--on-accent); font-weight: 600; font-size: var(--fs-meta); padding: 4px 12px; border-radius: var(--r-sm); cursor: pointer; flex: none; font-family: inherit; }
.view-banner .vb-back:hover { background: rgba(0,0,0,.28); }

/* #69 — demo-sandbox-balk (bovenaan de content) */
.demo-banner { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 12px; margin: 0 0 16px; background: var(--btn-primary-bg); color: #fff; font-size: var(--fs-sub); font-weight: 600; border-radius: var(--r-control); }
.demo-banner .demo-note { display: inline-flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.demo-banner .demo-note .licon { width: var(--ic-sm); height: var(--ic-sm); flex: none; }
.demo-banner .demo-actions { display: inline-flex; align-items: center; gap: 8px; flex: none; }
.demo-banner .demo-btn { display: inline-flex; align-items: center; gap: 4px; background: rgba(255,255,255,.18); border: 0; color: #fff; font-weight: 600; font-size: var(--fs-meta); padding: 0 var(--sp-3); min-height: 32px; border-radius: var(--r-control); cursor: pointer; text-decoration: none; font-family: inherit; }
.demo-banner .demo-btn .licon { width: var(--ic-sm); height: var(--ic-sm); }
.demo-banner .demo-btn:hover { background: rgba(255,255,255,.30); }
.demo-banner .demo-btn-primary { background: #fff; color: var(--systemBlue); }
.demo-banner .demo-btn-primary:hover { background: rgba(255,255,255,.85); }

/* M4 — op een telefoon liep de tekst over drie regels en stonden de knoppen eronder:
   samen 140 px, 17 % van het scherm, nog vóór de header. Nu één regel met de knoppen
   ernaast; de tekst kort zichzelf in met een beletselteken als het niet past. */
@media (max-width: 600px) {
  .demo-banner { gap: 8px; padding: 8px 12px; margin: 0 0 12px; flex-wrap: nowrap; font-size: var(--fs-meta); }
  .demo-banner .demo-note { min-width: 0; }
  .demo-banner .demo-note span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .demo-banner .demo-actions { gap: 4px; }
  .demo-banner .demo-btn { padding: 4px 8px; font-size: var(--fs-meta); white-space: nowrap; }
}

/* #18 fase 2 — offline-banner (zelfde opzet als .demo-banner, andere kleur) + sync-wachtrij-badge */
/* #74a (Audit 2, H5): wit-op-oranje faalt WCAG in beide thema's (~1,8:1 donker, ~2,9:1
   licht) — een vaste donkere tekstkleur i.p.v. wit haalt >4,5:1 in allebei (niet
   thema-afhankelijk, want --systemOrange zelf verschilt per thema). */
/* #74/M7 (Audit 2): sticky i.p.v. gewoon in de flow — scrolde eerder weg op lange lijsten
   (bv. Logboek), waardoor de enige blijvende indicator de kleine sync-badge was. Op
   desktop scrollt het venster (geen sticky header) dus top:0 volstaat; op mobiel wordt
   `header` zelf sticky (zie media-query onderaan) — daar duwt JS via --header-h de
   banner naar de juiste plek ónder de header i.p.v. erover. */
.offline-banner { position: sticky; top: 0; z-index: var(--z-sticky); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 12px; margin: 0 0 16px; background: var(--systemOrange); color: var(--on-accent); font-size: var(--fs-sub); font-weight: 600; border-radius: var(--r-control); }
.offline-banner .offline-note { display: inline-flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.offline-banner .offline-note .licon { width: var(--ic-sm); height: var(--ic-sm); flex: none; }
/* #146 — .btn small op een gekleurde banner: alleen de kleuren wijken af,
   de vorm en maat komen uit de knop zelf. */
.offline-banner .btn { flex: none; background: rgba(0,0,0,.14); color: var(--on-accent); }
.offline-banner .btn:hover { background: rgba(0,0,0,.24); }
.sync-queue-badge { display: block; margin: 0 auto 8px; padding: 3px 8px; background: none; border: 1px solid var(--systemOrange); color: var(--systemOrange); font-size: var(--fs-meta); font-weight: 600; border-radius: var(--r-pill); cursor: pointer; font-family: inherit; }
.sync-queue-badge:hover { background: var(--tint-orange); }
/* #74b (Audit 2, §5): grensgeval in licht thema (~3,2:1) — donkerder variant, alleen hier
   nodig (donker thema haalt al ruim >4,5:1 met de gewone --systemOrange). */
:root[data-theme="light"] .sync-queue-badge { border-color: #8f5322; color: #8f5322; }
:root[data-theme="light"] .sync-queue-badge:hover { background: rgba(143,83,34,.12); }

/* #74/M7: header wordt zelf sticky top:0 onder de max-width:860px-breakpoint (zie boven
   in het bestand) — de banner moet daaronder plakken, niet erover (JS zet --header-h via
   syncOfflineBannerOffset()). Bewust een NIEUW media-blok hier, ná de algemene
   .offline-banner-regel hierboven: gelijke specificiteit + eerder in broncode-volgorde zou
   deze override anders alsnog verliezen ondanks dat de media-query actief is. */
@media (max-width: 860px) {
  .offline-banner { top: var(--header-h, 54px); z-index: calc(var(--z-header) - 1); }
}

/* #74/H6 (Audit 2) — per-rij "wacht op sync"-indicator. `_pending` werd al gezet maar
   nergens gerenderd; alleen de globale badge/toast meldde het (verdwijnt bij scrollen). */
.pending-badge { display: inline-flex; vertical-align: -2px; margin-right: 4px; color: var(--systemOrange); flex: none; }
.pending-badge .licon { width: 13px; height: 13px; }

/* Read-only-lock: verberg toevoeg-/bewerk-affordances tijdens meekijken */
.app-shell.readonly #fabWrap,
.app-shell.readonly #maintHead .btn,
.app-shell.readonly .card-foot .btn,
.app-shell.readonly .mc-foot .btn,
.app-shell.readonly #addCarBtn { display: none !important; }

/* Beheer — accountlijst */
.admin-list { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 4px; }
/* Wrap toegestaan: op smal vallen de actieknoppen naar een eigen regel onder de
   naam/meta i.p.v. de body naar 0px te knijpen (tekst lekte anders onder de knoppen). */
.admin-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px; border: 1px solid var(--separator); border-radius: var(--r-control); padding: 8px 12px; }
.admin-av { width: 38px; height: 38px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-size: var(--fs-sub); font-weight: 600; background: var(--tint-blue); color: var(--systemBlue); }
.admin-body { flex: 1 1 auto; min-width: 120px; }
.admin-name { font-size: var(--fs-body); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-meta { font-size: var(--fs-meta); color: var(--label-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-actions { display: flex; gap: 4px; flex: 0 0 auto; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
.admin-me { font-size: var(--fs-meta); color: var(--label-tertiary); }

.btn:disabled { opacity: .55; cursor: default; }

/* Destructief: rode tekst op de standaardvulling. De `border-color` die hier
   stond deed niets — .btn heeft `border: 0` — en is weg. */
.btn.danger { color: var(--systemRed); }
.btn.danger:hover { background: var(--tint-red); }

/* Instellingen — account + wachtwoord wijzigen */
.settings-pw { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 4px; }

.settings-pw input:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }
.settings-pw .btn { width: 100%; }
.settings-pw-msg { font-size: var(--fs-meta); min-height: 16px; }
.settings-pw-msg.ok { color: var(--systemGreen); }
.settings-pw-msg.err { color: var(--systemRed); }


/* ============================================================
   Header: actieve paginatitel (links) + auto-pill (rechts)
   ============================================================ */
header { align-items: center; }
.title h1 { white-space: nowrap; cursor: default; }

.car-pill {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  max-width: 56vw;
  background: var(--surface-2);
  border: 1px solid var(--separator);
  color: var(--label);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.01em;
  padding: 8px 12px;
  border-radius: var(--r-pill);          /* altijd pilvorm, ook bij hover/active */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, border-color 0.12s linear;
}
.car-pill:hover  { background: var(--surface-3); border-color: var(--separator-opaque); }
.car-pill:active { background: var(--surface-3); }
.car-pill:focus-visible { outline: none; border-color: transparent; box-shadow: 0 0 0 2px var(--systemBlue); }.car-pill-row  { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.car-pill-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.car-pill-chev { color: var(--label-tertiary); font-size: var(--fs-meta); margin-left: -2px; }
.car-pill:hover .car-pill-chev { color: var(--label-secondary); }
.car-pill-plate { display: none; }

/* #44 — 3B: plaat boven, naam + chevron klein eronder (rechts uitgelijnd).
   Werkt op élke pagina; zonder kenteken valt de pill terug op de kale naam-pill. */
.car-pill.has-plate {
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
  min-height: 44px;
  max-width: 62vw;
  background: transparent;
  border-color: transparent;
  padding: 2px 0;
  border-radius: var(--r-control);
}
.car-pill.has-plate:hover,
.car-pill.has-plate:active { background: transparent; border-color: transparent; }
.car-pill.has-plate .car-pill-plate { display: block; }
.car-pill.has-plate .car-pill-plate .plate-svg {
  height: 22px;
  width: auto;
  max-width: 52vw;
  display: block;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.22));
}
.car-pill.has-plate .car-pill-plate .plate-na { height: 36px; }   /* #150 — zie .car-row-plate */
.car-pill.has-plate .car-pill-name {
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--label-secondary);
  max-width: 50vw;
}
.car-pill.has-plate .car-pill-chev { font-size: var(--fs-meta); margin-left: 0; }

/* ============================================================
   Dashboard — kerngegevens als mockup-kaarten (2 boven + 1 breed)
   ============================================================ */
/* #138-2 — de schakelaar is sinds deze ronde gewoon .page-actions/.btn; hier blijft alleen
   staan wat specifiek is voor het dashboard (op mobiel twee even brede knoppen). */
.dashboard-scope[hidden] { display: none; }
/* #verbeterpunten-2-dashboard-6 — de twee cijfertegels bovenaan "alle voertuigen"
   (.fleet-kpis/.fleet-kpi) zijn vervallen; de autolijst staat nu meteen bovenaan. */
/* #138-7 — de autolijst en de kalenderkaart eronder (.tl-card) stonden tegen elkaar aan;
   dezelfde afstand als tussen de cijfertegels en de lijst. */
.fleet-list { background:var(--surface); border-radius:var(--r-card); overflow:hidden; margin-bottom:16px; }
.fleet-row { width:100%; border:0; border-bottom:1px solid var(--separator); background:transparent; color:inherit; font:inherit; display:grid; grid-template-columns:10px minmax(0,1fr) auto 12px; align-items:center; column-gap:12px; row-gap:4px; padding:12px 16px; text-align:left; cursor:pointer; }
.fleet-row:last-child { border-bottom:0; }
.fleet-row:hover { background:var(--surface-2); }
.fleet-dot { width:9px; height:9px; border-radius:50%; background:var(--label-tertiary); }
.fleet-dot.overdue { background:var(--systemRed); }
.fleet-dot.soon { background:var(--systemOrange); }
.fleet-dot.ok { background:var(--systemGreen); }
.fleet-body,.fleet-money { display:flex; flex-direction:column; min-width:0; }
.fleet-name { font-weight:700; }
.fleet-next { color:var(--label-secondary); font-size: var(--fs-sub); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fleet-money { align-items:flex-end; font-variant-numeric:tabular-nums; }
.fleet-money > span { font-weight:700; }
.fleet-money small { color:var(--label-tertiary); font-size: var(--fs-meta); }
.fleet-chev { color:var(--label-tertiary); font-size: var(--fs-heading); grid-row:1; grid-column:4; }
/* #153 — een tweede onderregel per voertuig: gemiddeld verbruik links, kosten per km rechts
   (verzoek Gilles). Hij staat expliciet op rij 2 en beslaat de kolommen van de naam én het
   bedrag — zonder die plaatsing zou de browser hem onder de stip schuiven, want de chevron
   zit al in kolom 4 van rij 1. Ontbreekt een van de twee getallen, dan blijft die kant leeg
   en houdt de andere zijn plek: twee auto's onder elkaar horen op dezelfde plek hetzelfde
   soort getal te tonen. */
.fleet-meta {
  grid-row:2; grid-column:2 / 4;
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
  font-size: var(--fs-meta); color: var(--label-tertiary);
  font-variant-numeric: tabular-nums;
}
.fleet-meta .fm-left, .fleet-meta .fm-right { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.fleet-meta .fm-right { text-align:right; }
.fleet-dot, .fleet-body, .fleet-money { grid-row:1; }

/* #140 — de tegels bovenaan het dashboard (.dash-essentials/.dash-card*) zijn vervallen:
   beide standen tonen daar nu dezelfde voertuigregel(s) als "alle voertuigen" altijd al had
   (.fleet-list/.fleet-row hierboven). */

@media (max-width: 600px) {
  /* #verbeterpunten-2-dashboard-1 — de twee knoppen stonden met de 6 px van .page-actions uit
     elkaar terwijl alles eronder op 12 px staat; naast elkaar oogde dat als één dichtgeplakt
     blok. Nu dezelfde tussenruimte als de tegels/lijsten op deze pagina. */
  .dashboard-scope { margin-bottom:14px; gap:12px; }
  .dashboard-scope .btn { flex:1 1 auto; }
  .fleet-row { grid-template-columns:9px minmax(0,1fr) auto; gap:8px; padding:12px 12px; }
  .fleet-chev { display:none; }
  .fleet-money small { max-width:7rem; text-align:right; }
}

.svc-pill-wrap { display:inline-flex; align-items:center; gap:3px; }
.svc-primary { border:0; background:transparent; color:var(--label-tertiary); font-size: var(--fs-body); padding:4px; cursor:pointer; }
.svc-primary.on { color:var(--systemOrange); }
.mc-est.editable { border:0; background:transparent; color:var(--systemBlue); padding:0; font:inherit; cursor:pointer; text-align:left; }
[data-maint-est-edit] { cursor:pointer; }
/* ============================================================
   Auto-hub: volledig scherm — overzicht + beheer + wisselen
   ============================================================ */
.carhub-bg {
  position: fixed;
  inset: 0;
  /* 9A — de "‹ Terug"-knop van de hub (146 x 38 px, linksboven) lag volledig achter de
     sticky header (z-index 100) met zijn dekkende achtergrond: elementFromPoint() op het
     midden gaf de paginatitel. Tegelijk zet body.carhub-open de hamburger op display:none,
     dus linksboven stond helemaal niets meer en kwam je alleen nog weg via de auto-pill of
     Escape — en op een telefoon is er geen Escape (UX-audit U5).
     De hub blijft op 96: hem bóven de header tillen (110) loste dit óók op, maar dan komt
     hij ook boven een .modal-bg (100) — en de auto-modal wordt juist vanúít de hub geopend,
     dus die verdween erachter. Het is niet de hub die omhoog moet, het is de header die
     opzij moet. Zie `body.carhub-open header` hieronder. */
  z-index: var(--z-takeover);
  background: var(--bg);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.carhub-bg[hidden] { display: none; }
/* #150 — het VIN in het voertuigvenster: om te kopiëren, niet om te lezen. Eén tik
   selecteert het hele nummer (user-select: all); de knop ernaast zet het op het klembord. */
/* #153 — geen losse bak meer maar de laatste regel van .carhub-card, en zonder `flex-wrap`:
   het VIN, de kopieerknop en het label horen op één regel te blijven (verzoek Gilles:
   "copy knop kan op 1 lijn zonder tekst"). Het nummer krimpt mee en breekt desnoods af;
   de knop en het label houden hun maat. */
.carhub-vin {
  display: flex; align-items: center; gap: 8px;
  border-top: 0.5px solid var(--separator);
  padding: 8px 8px 8px 12px;
}
.carhub-vin .chv-label { font-size: var(--fs-meta); font-weight: 600; color: var(--label-tertiary); flex: none; }
.carhub-vin .chv-value {
  flex: 1 1 auto; min-width: 0;
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: var(--fs-sub); font-weight: 600;
  letter-spacing: 0.04em; color: var(--label);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  user-select: all; -webkit-user-select: all;
}
/* Alleen het pictogram: 32 px raakvlak, net als de wisknop bij een veld (#149). */
.carhub-vin .chv-copy {
  flex: none;
  width: 32px; min-width: 32px; min-height: 32px; height: 32px;
  padding: 0; display: inline-flex; align-items: center; justify-content: center;
}
/* De bevestiging: het kopieer-pictogram wisselt voor een groen vinkje. */
.chv-copy .chv-copy-ok { display: none; font-size: var(--fs-body); font-weight: 700; }
.chv-copy.done { color: var(--systemGreen); }
.chv-copy.done .licon { display: none; }
.chv-copy.done .chv-copy-ok { display: inline; }
/* #146 — een venster dat vanúít een venster opent (de back-up- en CSV-schermen uit
   instellingen). Hiervóór zette backup-export.js daar met de hand style.zIndex='1300'
   op; dat getal stond nergens in een schaal en was niet te plaatsen. */
.carhub-bg.is-stacked { z-index: var(--z-window-2); }
/* #150 — hetzelfde voor elk gewoon venster, maar dan automatisch: bindModalStacking() in
   modal-chrome.js zet .is-stacked op een venster dat opent terwijl er al één openstaat, en
   .is-stacked-2 op een derde laag (Instellingen → Voertuigen → Voertuig bewerken). */
.modal-bg.is-stacked { z-index: var(--z-window-2); }
.modal-bg.is-stacked-2 { z-index: calc(var(--z-window-2) + 10); }
/* #146 — hier stond een hack: de hub lag op 96 (net ónder .modal-bg op 100) en de
   header moest daarom zélf opzij (z-index 1), anders lag hij over de terug-knop van
   de hub. Met de lagenschaal is dat weg: de hub is een paginaovername
   (--z-takeover, boven de kopbalk) en een venster een laag daarboven
   (--z-window), dus de volgorde klopt vanzelf. */
.carhub {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: max(12px, env(safe-area-inset-top)) 20px calc(40px + env(safe-area-inset-bottom));
}
/* #146 — de hub had een eigen kopbalk (.carhub-top, 52 px hoog, op --bg, zonder
   onderlijn, titel in Manrope 700) naast die van elk venster. Er is er nu nog
   één: .modal-topbar. Wat hier overblijft is waar de hub écht van een venster
   verschilt — hij plakt bovenaan terwijl de inhoud eronder doorscrollt. */

/* ============================================================
   #153 — de huidige auto als één compacte kaart

   Verzoek Gilles: "car switcher mag compacter, ik bedoel alles vanaf de naam tot en met edit
   vehicle. Verder compacter, minder marges, maar wel elegant."

   Wat er stond: een gecentreerde held (naam op --fs-display, plaat 216 px breed eronder),
   twee losse statkaarten en een losse VIN-bak, elk met eigen padding en 16 px lucht ertussen.
   Op 375 px was dat ~360 px hoog vóór de eerste andere auto in beeld kwam — in een venster
   dat er juist is om te wisselen.

   Wat er staat: één .carhub-card op --surface met haarlijnen erbinnen in plaats van drie
   kaarten met lucht ertussen. Plaat en naam naast elkaar (de plaat is het herkenningspunt,
   de naam de titel), de twee feiten op één regel, het VIN op de laatste. De kaart is geen
   nieuw component: het is dezelfde --surface/--r-card als elke andere kaart, alleen met
   secties erin zoals een instellingenlijst dat ook doet.
   ============================================================ */
.carhub-card {
  background: var(--surface);
  border-radius: var(--r-card);
  overflow: hidden;
  margin-bottom: 8px;
}
.carhub-top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
}
.carhub-id { min-width: 0; flex: 1 1 auto; }
.carhub-hero-name {
  font-size: var(--fs-heading);
  font-weight: 700;
  letter-spacing: -0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.carhub-hero-sub {
  color: var(--label-secondary);
  font-size: var(--fs-sub);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Stats-rooster (brandstof, waarde) — km-stand/verbruik #10b verwijderd: staan al op het
   dashboard. Sinds #153 twee vakken bínnen de kaart, gescheiden door haarlijnen in plaats
   van door lucht: label boven, waarde eronder, zodat twee auto's op dezelfde regel te
   vergelijken blijven. */
.carhub-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--separator);
  border-top: 0.5px solid var(--separator);
}
.carhub-stat {
  appearance: none;
  background: var(--surface);
  border: 0;
  border-radius: 0;
  padding: 8px 12px;
  text-align: left;
  color: inherit;
  font-family: inherit;
}
button.carhub-stat {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
button.carhub-stat:hover  { background: var(--surface-2); }
button.carhub-stat:active { background: var(--surface-3); }
.carhub-stat .chs-value {
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.carhub-stat .chs-label {
  font-size: var(--fs-meta);
  font-weight: 600;
  color: var(--label-tertiary);
  margin-bottom: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* #146 — .btn met volle breedte; de eigen vulling, hoogte en hoek zijn weg. */
.carhub-edit-btn { width: 100%; }
/* #153 — dezelfde volle breedte voor "Schema bewerken" in het bewerkscherm. */
.car-schema-btn { width: 100%; }
.carhub-edit-btn .cheb-ic { font-size: var(--fs-body); color: var(--label-secondary); }

.carhub-section {
  font-size: var(--fs-heading);
  font-weight: 700;
  letter-spacing: -0.01em;
  /* #153 — was 24 px boven en 12 px onder; in een venster dat nu één compacte kaart boven
     zich heeft is dat de grootste overgebleven witruimte. */
  margin: 16px 0 8px;
}

.carhub-carlist { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; }
.carhub-carrow {
  appearance: none;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 0;
  padding: 12px 16px;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear;
}
.carhub-carrow:first-child { border-radius: var(--r-card) var(--r-card) 0 0; }
.carhub-carrow:hover { background: var(--surface-2); }
.carhub-carrow.active { background: var(--surface-2); }.att-status {
  min-height: 18px;
  margin: 12px 2px 0;
  font-size: var(--fs-meta);
  color: var(--label-secondary);
  text-align: center;
}
.att-status.ok    { color: var(--systemGreen); }
.att-status.error { color: var(--systemRed); }

/* 16B — voortgangsbalk bij "Back-up van alles". Een back-up van vier auto's met foto's
   duurt tientallen seconden; zonder balk is een knop die nadenkt niet te onderscheiden
   van een knop die stuk is. */
.bundle-bar {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  overflow: hidden;
  margin-top: 12px;
}
.bundle-bar-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--btn-primary-bg);
  transition: width 0.2s linear;
}

/* CSV-export (#49) — tabel-kiezer in de carhub-shell */
.csv-lbl { display: block; font-size: var(--fs-meta); color: var(--label-secondary); margin: 0 0 4px; }
.csv-car { width: 100%; margin: 0 0 16px; }
.csv-list { border: 1px solid var(--separator); border-radius: var(--r-md); overflow: hidden; }
.csv-row {
  appearance: none; display: flex; align-items: center; gap: 12px; width: 100%;
  text-align: left; background: var(--surface); border: 0;
  border-bottom: 1px solid var(--separator); padding: 12px 12px;
  font-family: inherit; font-size: var(--fs-body); color: var(--label); cursor: pointer;
}
.csv-row:last-child { border-bottom: 0; }
.csv-row:hover:not(.is-empty) { background: var(--surface-2); }
.csv-row.is-empty { opacity: 0.45; cursor: default; }
.csv-check {
  flex: 0 0 auto; width: 19px; height: 19px; border-radius: var(--r-2xs);
  border: 1.5px solid var(--separator-opaque); display: inline-flex;
  align-items: center; justify-content: center; font-size: var(--fs-meta); color: #fff;
}
.csv-row.on .csv-check { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); }
.csv-name { flex: 1; }
.csv-count { font-size: var(--fs-meta); color: var(--label-secondary); }
.csv-hint { margin: 12px 0 0; }
.csv-go { width: 100%; margin: 12px 0 0; justify-content: center; }
.csv-go:disabled { opacity: 0.5; cursor: default; }/* Rij-thumbnail (lijst + dashboard) */
.qthumb {
  flex: none; width: 38px; height: 38px; border-radius: var(--r-md); overflow: hidden;
  background: var(--surface-3); display: block;
}
.qthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }/* Foto-strip in de detail-editor */
.tk-photostrip { display: flex; flex-wrap: wrap; gap: 8px; }
.tk-photo { position: relative; width: 62px; height: 62px; }
.tk-photo img {
  width: 62px; height: 62px; object-fit: cover; display: block;
  border-radius: var(--r-md); background: var(--surface-3);
}
.tk-photo-del {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--systemRed); color: #fff; border: 2px solid var(--surface-2);
  font-size: var(--fs-meta); line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.tk-photo-add {
  width: 62px; height: 62px; border-radius: var(--r-md);
  background: transparent; border: 1px dashed var(--separator-opaque);
  color: var(--systemBlue); font-size: var(--fs-title); cursor: pointer; display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent;
}
.tk-photo-add:hover { background: var(--surface-3); }

/* Secties + koppen */
.qsection { margin-bottom: 6px; }
/* #61 — kopregel boven een gegroepeerde takenlijst (groeperen op label). */
.qgroup-h {
  display: flex; align-items: center; gap: 4px;
  margin: 12px 4px 4px; font-size: var(--fs-sub); font-weight: 700; color: var(--label-secondary);
}
.qgroup-n {
  font-weight: 600; color: var(--label-tertiary);
  background: var(--surface-2); border-radius: var(--r-pill);
  padding: 1px 8px; font-size: var(--fs-meta);
}
/* Eén lijstkaart met haarlijn-rijen (i.p.v. losse zwevende kaartjes). */
.qrows {
  display: flex; flex-direction: column;
  background: var(--surface); border: 0.5px solid var(--separator);
  border-radius: var(--r-control); overflow: hidden;
}/* Stille rij binnen de lijstkaart */
.qrow {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 12px; position: relative;
}
.qrow + .qrow { border-top: 0.5px solid var(--separator); }
.qrow:not(.done):hover { background: var(--surface-2); }.qmain {
  flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 8px;
  background: transparent; border: 0; cursor: pointer; font-family: inherit; text-align: left; padding: 0;
  color: var(--label);
}
.qnm { flex: 1 1 auto; min-width: 0; font-size: var(--fs-body); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qrow.done .qnm { color: var(--label-tertiary); text-decoration: line-through; }
.qhint { font-size: var(--fs-meta); color: var(--label-tertiary); flex: none; white-space: nowrap; }
.qhint.overdue { color: var(--systemRed); }
.qhint.today { color: var(--systemOrange); }/* #63 — sleep-greep op een taakrij (pointer-drag, iOS-vriendelijk). */
.qdrag {
  /* Was 14 × 23 px; WCAG 2.2 (2.5.8) vraagt 24 × 24 en de rijen liggen tegen elkaar,
     dus de uitzondering voor omringende ruimte gaat niet op (UX-audit A5). De
     negatieve marge houdt de rijhoogte gelijk. */
  flex: none; background: transparent; border: 0; padding: 0; margin: -2px -4px -2px 0;
  min-width: 24px; min-height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--label-tertiary); font-size: var(--fs-body); line-height: 1; cursor: grab;
  touch-action: none; -webkit-tap-highlight-color: transparent;
}
.qdrag:focus-visible { outline: 2px solid var(--systemBlue); outline-offset: -2px; border-radius: var(--r-2xs); }
.qdrag:active { cursor: grabbing; }
/* Tijdens slepen: de niet-opgepakte rijen schuiven soepel op. */
.qrows.dragging-active .qrow { transition: transform 0.18s cubic-bezier(0.2, 0, 0, 1); }
/* Het opgepakte item volgt de vinger 1:1 (geen transition) en wordt opgetild. */
.qrows.dragging-active .qrow.dragging {
  transition: none; z-index: 5; position: relative;
  background: var(--surface-2); border-radius: var(--r-sm);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.24);
}

/* Vinkje (open/klaar) + optioneel label */
.qcheck {
  width: 20px; height: 20px; border-radius: var(--r-2xs); flex: none;
  border: 1.6px solid var(--label-tertiary); background: transparent; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-size: var(--fs-meta); color: var(--on-accent); padding: 0; -webkit-tap-highlight-color: transparent;
}
.qcheck.on { background: var(--systemGreen); border-color: var(--systemGreen); }
.qlabel {
  flex: none; font-size: var(--fs-meta); font-weight: 600; color: var(--label-secondary);
  background: var(--surface-2); border: 0.5px solid var(--separator);
  border-radius: var(--r-pill); padding: 2px 8px; max-width: 40%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Label in de editor-kop: compacte pill (chip-look, bewerkbaar) */
.elabel-chip {
  flex: 0 1 auto; max-width: 46%; min-width: 64px;
  background: var(--surface-3); border: 0;
  color: var(--label-secondary);
}
.elabel-chip::placeholder { color: var(--label-tertiary); font-weight: 500; }
.elabel-chip:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }

/* Label-tint (#68) — stabiele kleur per vrij-tekstlabel.
   #146 — dit rekende met een hue van 0 tot 359 (--lab-h) en stond daarmee buiten
   elk palet. Calc.labelHue() geeft nu een plek in het categoriepalet, en tasks.js
   zet die als `--lab: var(--cat-N)`; de tint en de tekstkleur komen daar uit.
   Translucente vulling + gekleurde tekst werkt op beide thema's. */
.qlabel.tinted,
.elabel-chip.tinted {
  background: color-mix(in srgb, var(--lab) 18%, transparent);
  color: var(--lab);
}
.qlabel.tinted { border-color: color-mix(in srgb, var(--lab) 45%, transparent); }
/* Gekleurde stip vóór een groepskop (groeperen op label, #61) */
.qgroup-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--lab);
}

.etitle { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.etitle-in {
  flex: 1 1 auto; min-width: 0; background: transparent; border: 0; color: var(--label);
  font-family: inherit; font-size: var(--fs-input); font-weight: 700; letter-spacing: -0.01em; padding: 2px 0;
}
/* De focusrand mag weg, maar er moet dán wel iets voor in de plaats komen — anders zie je
   met het toetsenbord niet meer waar je bent. .task-title:focus doet dat al goed met een
   lichte achtergrond; deze drie deden alleen het weghalen. */
.etitle-in:focus { outline: none; background: var(--surface-2); }
.ecol { padding: 12px 0 2px; border-top: 0.5px solid var(--separator); margin-top: 8px; }
.ecol-h { font-size: var(--fs-sub); font-weight: 600; color: var(--label-tertiary); margin-bottom: 8px; }
.ecol-h .ecol-meta { text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--label-tertiary); font-variant-numeric: tabular-nums; }
.subtask-add .btn, .part-add .btn {
  flex: 0 0 auto; background: transparent; border: 0; color: var(--systemBlue);
  font-weight: 500; padding: 8px 4px;
}
.subtask-add .btn:hover, .part-add .btn:hover { background: transparent; color: var(--systemBlue); opacity: 0.7; }
/* #verbeterpunten-2-repairs-6 — eigen wisknop in het datumveld: het kruisje van de browser
   bestaat niet overal (en op iOS helemaal niet). Hij ligt in het veld, rechts. */
.date-clear-wrap { position: relative; display: block; }
/* De vrije ruimte rechts is de knop (32) plus zijn marge (4) plus wat lucht — anders
   loopt een lange datum eronder door. */
.date-clear-wrap input[type="date"] { width: 100%; padding-right: 40px; }
.date-clear {
  position: absolute; top: 50%; right: 4px; transform: translateY(-50%);
}
.date-clear:hover { background: var(--surface-3); color: var(--label); }
/* ============ Kentekenplaten (#11) ============ */
/* SVG schaalt op containerbreedte; hoogte volgt de viewBox-verhouding. */
.plate-svg { display: block; width: 100%; height: auto; }

/* Plaat-tegel op het bewerkscherm (#47) — opent de wizard */
.plate-tile {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  padding: 12px; margin: 2px 0 4px;
  background: var(--surface-2); border: 0.5px solid var(--separator); border-radius: var(--r-control);
}
.plate-tile .plate-tile-pv { flex: 0 0 116px; width: 116px; }
.plate-tile .plate-tile-pv .plate-svg { width: 100%; height: auto; display: block; border-radius: var(--r-2xs); filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.3)); }
.plate-tile .plate-tile-meta { min-width: 0; flex: 1; }
.plate-tile .ptm-plate { display: block; font-size: var(--fs-body); font-weight: 700; color: var(--label-primary); }
.plate-tile .ptm-sub { display: block; font-size: var(--fs-meta); color: var(--label-secondary); }
.plate-tile .plate-tile-edit { margin-left: auto; white-space: nowrap; font-size: var(--fs-sub); font-weight: 600; color: var(--systemBlue); }

/* Plaat-wizard: grote preview */
.pw-preview {
  display: flex; align-items: center; justify-content: center;
  min-height: 96px; padding: 16px; margin-bottom: 14px;
  background: var(--surface-2); border-radius: var(--r-control);
}
.pw-preview #pwPreview { width: 320px; max-width: 100%; }
.pw-preview .plate-svg { width: 100%; height: auto; filter: drop-shadow(0 3px 12px rgba(0, 0, 0, 0.4)); }
.pw-region button { flex: 1; }

.plate-seg { margin-top: 2px; }
.plate-seg button {
  flex: 1; padding: 8px; font-family: inherit; font-size: var(--fs-sub); font-weight: 500; cursor: pointer;
  color: var(--label-secondary); background: transparent; border: 0;
  border-radius: calc(var(--r-control) - 3px);
}/* Toon-plekken */
/* #153 — de plaat stond gecentreerd op 216 px ónder de naam; nu staat hij ernáást op 120 px.
   Een NA-plaat is vierkanter (300 x 150) dan een EU-plaat (520 x 110) en zou op dezelfde
   breedte twee keer zo hoog worden — vandaar een eigen, smallere maat, dezelfde afweging als
   bij de rij- en pill-vormen in #150. */
.carhub-hero-plate { display: flex; flex: none; }
.carhub-hero-plate .plate-svg { width: 120px; filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4)); }
.carhub-hero-plate .plate-na { width: 74px; }/* ============ Historie aanvullen — bulk per item (#13) ============ */
.history-add { margin-top: 6px; }
.history-add .hist-add-head {
  font-size: var(--fs-sub); font-weight: 700;
  color: var(--label-tertiary); margin: 12px 2px 8px; padding-top: 12px; border-top: 0.5px solid var(--separator);
}
.harow { display: grid; grid-template-columns: 1.15fr 0.95fr 0.8fr 24px; gap: 4px; align-items: center; margin-bottom: 7px; }
.harow.harow-head { margin-bottom: 4px; }
.harow.harow-head span {
  font-size: var(--fs-sub); color: var(--label-tertiary); padding-left: 2px;
}
.harow .hin {
  width: 100%; background: var(--surface-2); border: 0.5px solid var(--separator); border-radius: var(--r-sm);
  color: var(--label); font-size: var(--fs-sub); padding: 8px 8px; font-family: inherit;
}
.harow .hin:focus { outline: none; box-shadow: 0 0 0 2px var(--systemBlue); }
.harow .hin::placeholder { color: var(--label-tertiary); }
.harow .harow-rm:hover { color: var(--systemRed); }
.hist-addrow {
  width: 100%; background: none; border: 1px dashed var(--separator); border-radius: var(--r-md);
  color: var(--systemBlue); font-size: var(--fs-sub); font-weight: 600; padding: 8px; cursor: pointer; font-family: inherit; margin-top: 2px;
}
.hist-add-hint { font-size: var(--fs-meta); color: var(--label-tertiary); margin: 8px 2px 0; line-height: 1.4; }
.hist-save { width: 100%; margin-top: 12px; }

/* ============ Verkoopoverzicht exporteren — PDF (print) + databestand (#33) ============ */
.sale-export {
  position: fixed; inset: 0; z-index: var(--z-window); display: flex; flex-direction: column;
  background: var(--scrim);  /* donkere mat om het witte 'papier' te framen */
}
/* #152 — op desktop is dit geen venster over de app heen maar een eigen scherm: daar hoort
   de achtergrond van de app bij, niet een donkere mat die suggereert dat er iets achter
   ligt waar je naar terug kunt tikken. Op een telefoon blijft de mat — daar dekt het vel
   bijna de hele breedte en is het randje mat juist de vorm van het papier. */
@media (min-width: 861px) {
  .sale-export { background: var(--bg); }
}
.sale-export[hidden] { display: none; }
body.sale-open { overflow: hidden; }
/* #146 — het verkoopvenster had een derde eigen kopbalk (.sale-bar, titel 15/700,
   sluitknop in een vaste 76 px). Het is nu dezelfde .modal-topbar als overal;
   alleen de safe-area bovenin hoort bij dít venster, want het is altijd
   schermvullend. */
.sale-export > .modal-topbar {
  flex: none;
  padding-top: max(14px, calc(env(safe-area-inset-top, 0px) + 12px));
  padding-left: max(12px, env(safe-area-inset-left, 0px));
  padding-right: max(12px, env(safe-area-inset-right, 0px));
}
.sale-actions {
  flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  background: var(--surface); border-top: 0.5px solid var(--separator);
}
/* #152 — de twee downloadknoppen heten nu "Download …" en dat past op een telefoon niet
   meer naast elkaar én naast de kostenschakelaar. De rij mag daarom afbreken, en een label
   mag hier over twee regels: "Download databes…" zegt minder dan twee volle regels. */
.sale-actions { flex-wrap: wrap; }
.sale-actions .btn {
  flex: 1 1 120px; min-width: 0;
  white-space: normal; line-height: 1.2; text-align: center;
  padding: 6px var(--sp-3);
}

.sale-scroll { flex: 1; overflow: auto; display: flex; justify-content: center; padding: 20px 16px 32px; }
.sale-fit { flex: none; align-self: flex-start; margin: 0 auto; }

/* het witte document (print-doel) */
.sale-doc {
  --ink:#16181d; --ink2:#5b6270; --ink3:#8a909c; --hair:#e6e8ec; --hair2:#d3d7de;
  background: #fff; color: var(--ink); width: 660px; min-height: 933px; transform-origin: top left;
  border-radius: var(--r-2xs); box-shadow: 0 18px 60px rgba(0,0,0,.5); padding: 40px 44px 30px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-feature-settings: "tnum" 1;
}
/* #152 — kop met foto rechts. De tekstkolom houdt zijn eigen breedte, zodat een lange
   naam niet onder het beeld doorloopt. */
.sale-doc .s-head-l { min-width: 0; flex: 1; }
.sale-doc .s-photo { flex: none; width: 176px; }
.sale-doc .s-photo img { width: 100%; height: 110px; object-fit: cover; display: block;
  border-radius: 3px; border: 1px solid var(--hair2); }
.sale-doc .s-ident { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.sale-doc .s-plate { width: 112px; flex: none; }
.sale-doc .s-plate .plate-svg { width: 100%; height: auto; display: block; }
.sale-doc .s-vin { display: flex; align-items: baseline; gap: 5px; min-width: 0; }
.sale-doc .s-vl { font-size: 0.5625rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink3); }
.sale-doc .s-vv { font-size: 0.625rem; font-weight: 600; letter-spacing: .04em; color: var(--ink2);
  font-variant-numeric: tabular-nums; }

/* #152 — "de komende zes maanden": het eerste wat een koper wil weten, dus bovenaan en met
   een eigen vlak. Geen kleuraccent behalve rood voor achterstallig — het vel wordt zwart-wit
   geprint en moet dan nog steeds kloppen. */
.sale-doc .s-next { background: #f6f7fa; border: 1px solid var(--hair2); border-radius: 3px;
  padding: 12px 14px; margin-top: 16px; break-inside: avoid; }
.sale-doc .s-next-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; padding-bottom: 6px; border-bottom: 1px solid var(--hair2); }
.sale-doc .s-next-title { font-size: 0.5625rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--ink3); }
.sale-doc .s-next-sum { font-size: 0.75rem; font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.sale-doc .s-next-row { display: grid; grid-template-columns: 1fr auto auto; gap: 10px;
  align-items: baseline; padding: 4px 0; border-bottom: 1px solid var(--hair); }
.sale-doc .s-next-row:last-child { border-bottom: 0; }
.sale-doc .s-next-nm { font-size: 0.6875rem; font-weight: 600; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.sale-doc .s-next-when { font-size: 0.625rem; color: var(--ink2); white-space: nowrap; }
.sale-doc .s-next-row.od .s-next-when { color: #b02a2a; font-weight: 700; }
.sale-doc .s-next-est { color: var(--ink3); }
.sale-doc .s-next-amt { font-size: 0.625rem; color: var(--ink2); font-variant-numeric: tabular-nums;
  white-space: nowrap; min-width: 34px; text-align: right; }
.sale-doc.nocost .s-next-sum, .sale-doc.nocost .s-next-amt { display: none; }
.sale-doc .s-next-foot { font-size: 0.5625rem; color: var(--ink3); padding-top: 6px; }

.sale-doc .s-label { font-size: 0.5625rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink3); }
.sale-doc .s-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; margin-top: 4px; }
.sale-doc .s-nm { font-size: 1.25rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.1; }
.sale-doc .s-sub { font-size: 0.6875rem; color: var(--ink2); margin-top: 3px; }.sale-doc .s-rule { height: 1px; background: var(--hair2); margin: 14px 0; }
.sale-doc .s-facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.sale-doc .s-fl { font-size: 0.5625rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink3); margin-bottom: 2px; }
.sale-doc .s-fv { font-size: 0.875rem; font-weight: 700; letter-spacing: -.01em; }
.sale-doc .s-blocklabel { font-size: 0.5625rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ink3); margin: 18px 0 9px; }
.sale-doc .s-group { margin-bottom: 10px; break-inside: avoid; }
.sale-doc .s-ghead { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; border-bottom: 1px solid var(--hair2); padding-bottom: 4px; }
.sale-doc .s-gnm { font-size: 0.75rem; font-weight: 700; }
.sale-doc .s-gsum { font-size: 0.625rem; color: var(--ink2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.sale-doc .s-gocc { margin-top: 5px; }
.sale-doc .s-row { padding: 4px 0; border-bottom: 1px solid var(--hair); break-inside: avoid; }
.sale-doc .s-occ { display: flex; justify-content: space-between; gap: 12px; font-size: 0.625rem; }
.sale-doc .s-od { color: var(--ink2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sale-doc .s-amt { color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; flex: none; font-weight: 600; }
.sale-doc.nocost .s-amt { display: none; }
.sale-doc .s-onote { font-size: 0.625rem; color: var(--ink3); padding-top: 2px; line-height: 1.35; }
.sale-doc .s-empty { font-size: 0.6875rem; color: var(--ink3); padding: 6px 0; }
.sale-doc .s-total { display: flex; justify-content: space-between; align-items: baseline; margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--hair2); font-size: 0.75rem; font-weight: 700; }
.sale-doc .s-total .v { font-variant-numeric: tabular-nums; }
.sale-doc.nocost .s-total { display: none; }
.sale-doc .s-foot { margin-top: 22px; padding-top: 11px; border-top: 1px solid var(--hair2); display: flex; justify-content: space-between; gap: 16px; font-size: 0.625rem; color: var(--ink3); }
.sale-doc .s-foot .s-note { max-width: 72%; line-height: 1.4; }

/* Print: alleen het document, witte achtergrond, geen balk */
@media print {
  body { background: #fff !important; }
  body * { visibility: hidden !important; }
  .sale-export, .sale-export * { visibility: visible !important; }
  .sale-export { position: absolute; inset: 0; background: #fff !important; display: block; }
  .sale-export > .modal-topbar, .sale-actions { display: none !important; }
  .sale-scroll { overflow: visible !important; padding: 0 !important; display: block !important; }
  .sale-fit { width: auto !important; height: auto !important; margin: 0 !important; }
  .sale-doc { transform: none !important; box-shadow: none !important; width: auto !important; max-width: 100% !important; min-height: 0 !important; padding: 0 !important; border-radius: 0 !important; }
  /* audit-3/M10 — een geschat bedrag is op het scherm blauw (#153). Op papier draagt kleur
     niet over, en op een zwart-witprinter al helemaal niet, dus daar komt het tilde-teken
     terug. Dezelfde afweging die de PDF maakt; dit is de derde uitvoer van hetzelfde vel. */
  .sale-doc .est-amt { color: inherit !important; }
  .sale-doc .est-amt::before { content: '~'; }
  @page { margin: 14mm; }
}

/* ============================================================
   Lucide line-iconen (#— vervangen emoji). Maat = font-size van de
   container (icoon is 1em). Globaal vaste stroke 2,25.
   ============================================================ */
.licon{display:inline-block;width:1em;height:1em;vertical-align:-0.14em;fill:none;stroke:currentColor;
  stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;flex:none}
.licon-emoji{font-style:normal}

/* ---------- pictogramslots ----------
   Een "slot" is een plek waar een pictogram alléén staat: de kop van een rij, een
   menuregel, een tegel. Die erfden hun maat tot nu toe van de tekst ernaast
   (font-size: var(--fs-heading) — 17 px), en dat is een tekstmaat, geen
   pictogrammaat: op de telefoon bleef het pictogram even groot terwijl het daar
   juist het enige herkenningspunt van de rij is. Ze putten nu uit --ic-*, en die
   schaal schuift onder 860 px één stap op (zie onderaan dit bestand).

   Een pictogram dat ín een tekstregel meeloopt (badge, teller, chip) houdt 1em:
   dat hóórt de maat van zijn tekst te hebben. */
.dash-row-ic .licon, .item-icon .licon, .log-icon .licon, .cfm-ic .licon,
.side-tab .side-ic .licon, .fab-mi-ic .licon, .sch-ic .licon, .mrow-ic .licon,
.visit-ic .licon, .wiz-choice .wc-ic .licon, .attachment-row .att-icon .licon,
.mb-invite .mbi-ic .licon, .maint-schema-btn .msb-ic .licon, .car-add-ic .licon,
.set-navic .licon, .set-rowic .licon, .car-row-ic .licon, .car-row-edit .licon {
  width: var(--ic-md); height: var(--ic-md);
}
.wiz-preset .wp-ic .licon, .empty-cars-ic .licon,
.sidebar-brand .brand-icon .licon, .empty-section .licon {
  width: var(--ic-lg); height: var(--ic-lg);
}
/* De onderbalk stond op --ic-lg (26 px op de telefoon) en dat was een maat te groot —
   verzoek Gilles, 19-09-2026. Het zijn daar vijf pictogrammen náást elkaar zonder
   label eronder; die dragen hun herkenning vooral uit hun vorm, niet uit hun formaat. */
.bottom-tab .bt-ic .licon { width: var(--ic-md); height: var(--ic-md); }
.list-search-ic .licon, .carhub-edit-btn .cheb-ic .licon, .bl-ic .licon,
.view-banner .vb-ic .licon {
  width: var(--ic-sm); height: var(--ic-sm);
}

/* Icoon-kiezer (auto-icoon + custom onderhoudsitem) */
.licon-field{display:flex;align-items:center;gap:8px}
.licon-current{width:44px;height:44px;flex:none;display:grid;place-items:center;border-radius:var(--r-control);
  background:var(--surface-2);border:1px solid var(--separator);color:var(--label);font-size: var(--fs-title)}

.licon-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:8px;margin-top:10px;
  max-height:280px;overflow-y:auto;padding:2px}
.licon-pick{aspect-ratio:1/1;display:grid;place-items:center;border-radius:var(--r-control);
  background:var(--surface-2);border:1px solid var(--separator);color:var(--label-secondary);cursor:pointer;font-size: var(--fs-title)}
.licon-pick:hover{background:var(--surface-3);color:var(--label)}
.licon-pick.on{background:var(--tint-blue);border-color:var(--systemBlue);color:var(--systemBlue)}

/* ============================================================
   Kostenfilter in de zoekbalk (#41) — vervangt de losse chip-rij.
   ============================================================ */
.list-search.has-filter { position: relative; }
.list-search-filter {
  flex: 0 0 auto; width: 30px; height: 30px; margin: -3px 0; display: grid; place-items: center;
  position: relative; border: 0; background: transparent; color: var(--label-secondary);
  cursor: pointer; border-radius: var(--r-control); font-size: var(--fs-heading);
}
.list-search-filter:hover { background: var(--surface-3); color: var(--label); }
.list-search-filter.active { color: var(--systemBlue); }
.lsf-badge {
  position: absolute; top: -2px; right: -2px; min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: var(--r-pill); background: var(--btn-primary-bg); color: #fff; font-size: var(--fs-meta); font-weight: 700;
  line-height: 15px; text-align: center;
}
/* `.filter-menu` is de naam sinds #6; `.cost-filter-menu` blijft bestaan omdat de kosten-tab
   hem al gebruikte en een hernoeming daar niets oplevert. Eén blok regels voor allebei. */
/* Verzoek Gilles (19-09-2026): "de filtervelden zijn te smal". Ze stonden op
   232 px, en in een regel staan vier dingen naast elkaar: pictogram, naam, bedrag
   en vinkje. Bij een langere categorienaam ("Wegenbelasting") of een bedrag van
   vier cijfers botste dat, en in zeven talen is dat eerder regel dan uitzondering.
   Nu 288 px als ondergrens, groeiend met de inhoud tot 360 px — en op een smal
   scherm nooit breder dan het scherm zelf. */
.cost-filter-menu, .filter-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: var(--z-menu);
  min-width: 288px; width: max-content; max-width: min(360px, calc(100vw - 32px));
  background: var(--surface); border: 1px solid var(--separator); border-radius: var(--r-control);
  box-shadow: 0 12px 32px rgba(0,0,0,.28); padding: 4px; max-height: 320px; overflow-y: auto;
}
.cost-filter-menu[hidden], .filter-menu[hidden] { display: none; }
.cfm-row {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 8px; border: 0;
  background: transparent; color: var(--label); cursor: pointer; border-radius: var(--r-sm); text-align: left; font-size: var(--fs-body);
}
.cfm-row:hover { background: var(--surface-2); }
.cfm-row.on { background: var(--tint-blue); }
.cfm-ic { font-size: var(--fs-heading); color: var(--label-secondary); display: grid; place-items: center; flex: none; }
.cfm-row.on .cfm-ic { color: var(--systemBlue); }
.cfm-nm { flex: 1; }
.cfm-amt { font-size: var(--fs-sub); color: var(--label-secondary); font-variant-numeric: tabular-nums; }
.cfm-ck { width: 18px; display: grid; place-items: center; color: var(--systemBlue); font-size: var(--fs-body); flex: none; }
.cfm-reset { justify-content: center; color: var(--systemBlue); font-weight: 600; margin-top: 2px;
  border-top: 1px solid var(--separator); border-radius: 0; }
.cfm-reset:hover { background: transparent; text-decoration: underline; }
/* #59 — sectiekop in het kostenfilter (Categorie / Jaar). */
.cfm-head {
  font-size: var(--fs-sub); font-weight: 700;
  color: var(--label-tertiary); padding: 4px 8px 2px;
}
.cfm-head + .cfm-head, .cfm-row + .cfm-head { margin-top: 4px; }

/* ============================================================
   #106/#140 — "Uitschieters" en "Ritme" op de Brandstof- en Laden-tab

   Verzoek Gilles (19-09-2026): "kpi tegels bij brandstof zijn een rotzooitje […] er zijn
   2 verschillende soorten tegels". Dat klopte. Er stonden op één scherm twee tegelfamilies
   met hun eigen raster:

   · .kpi in .kpi-grid — haarlijnraster, waarde op --fs-title;
   · .stat-box in .stat-boxes — hetzelfde haarlijnraster, maar élke tegel droeg daarbinnen
     nóg eens een eigen --r-control. Daardoor liep de grijze rasterkleur als een rand om
     elke tegel heen: dát was de "achtergrondkleur erbij binnen de tegels".

   En daarboven lag .stat-grid, die de twee blokken op een breed scherm naast elkaar zette
   — elk mét een eigen sectiekop erin en een eigen kolomaantal (twee vaste kolommen tegen
   auto-fit op 7,5 rem). Drie rasters van drie breedtes onder elkaar; de "chaos op desktop".

   Nu is er één tegel (.kpi) in één raster (.kpi-grid), met twee varianten hierboven. De
   blokken staan onder elkaar over de volle breedte, dus elke rij op deze tab deelt dezelfde
   kolomlijnen.
   ============================================================ */

/* #6 — de strook die zegt dat de tegels eronder over een deel van de beurten gaan.
   Hij zit tussen de kop en de tegels, want daar leest hij als een bijschrift bij die tegels;
   onderaan bij de filterknop zou hij het gemiddelde erboven niet meer van een voetnoot
   voorzien. */
.energy-filter-note {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin-bottom: 10px;
  padding: 8px 12px;
  border-radius: var(--r-control);
  background: var(--tint-blue);
  font-size: var(--fs-sub);
}
.efn-tag {
  font-size: var(--fs-meta); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--systemBlue);
}
.efn-desc { color: var(--label); min-width: 0; }
.efn-count { color: var(--label-tertiary); font-variant-numeric: tabular-nums; }
.efn-clear {
  margin-left: auto; appearance: none; background: transparent; border: 0; padding: 0;
  font-family: inherit; font-size: var(--fs-sub); font-weight: 600; color: var(--systemBlue);
  cursor: pointer;
}
.efn-clear:hover { text-decoration: underline; }

/* ============================================================
   T8 — de vervangers van de 31 browserpopups
   ============================================================ */

/* Foutmelding ónder het veld waar hij over gaat. Een `alert()` zei alleen dát er iets fout
   was; dit wijst aan wát. Ruimte wordt pas ingenomen als er echt een fout is — een vaste
   min-height zou elk formulier permanent uit elkaar trekken voor iets dat er meestal niet is. */
.field-error {
  margin: 4px 2px 0;
  font-size: var(--fs-meta);
  font-weight: 600;
  line-height: 1.35;
  color: var(--systemRed);
}
/* Het veld zelf markeren, niet alleen de tekst eronder: op een lang formulier zie je anders
   bij het terugscrollen niet meer welk veld erbij hoorde. Een box-shadow i.p.v. een border,
   want .field input heeft border:0 — een border zou het veld 2px laten verspringen. */
.field input.has-error,
.field select.has-error,
.field textarea.has-error {
  box-shadow: inset 0 0 0 1.5px var(--systemRed);
}

/* Het gedeelde bevestigingsvenster. Hoger dan .modal-bg (z-index 100), want het wordt
   vrijwel altijd vanuit een openstaande modal geopend — een vraag die achter het scherm
   valt waar hij over gaat is geen vraag. */
.confirm-bg { z-index: var(--z-confirm); }
.confirm-modal { max-width: 380px; }
.confirm-body {
  color: var(--label);
  font-size: var(--fs-body);
  line-height: 1.45;
  margin: 8px 0 0;
}
/* De extra waarschuwing bij een vraag (bv. "dit bestand bevat géén taken"). Stond vroeger met
   een \n\n achter de vraag geplakt in de popup, en las daar als één grijze brei. */
.confirm-note {
  margin: 12px 0 0;
  padding: 8px 12px;
  border-radius: var(--r-md);
  background: var(--tint-red);
  color: var(--systemRed);
  font-size: var(--fs-sub);
  font-weight: 600;
  line-height: 1.4;
}
.confirm-modal .modal-actions { margin-top: 20px; }

/* De bevestigknop van een verwijdering. `.btn.danger` bestond al, maar zet alleen de tékst
   rood — bovenop de blauwe .primary-vulling levert dat rood-op-blauw op, onleesbaar (in de
   browser gezien). Een destructieve hoofdknop hoort zelf rood te zijn. */
.btn.primary.danger {
  background: var(--systemRed);
  color: #fff;
}
.btn.primary.danger:hover { background: var(--systemRed); filter: brightness(1.08); }

/* Melding in de bovenste laag, voor het handjevol berichten dat niet bij een veld hoort.
   Boven álles (ook boven het bevestigingsvenster): dit is de laag waarin feedback hoort als
   er een modal openstaat — #syncIndicator onder de header valt daarachter (13-09-2026). */
.app-notice {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 88px);
  transform: translate(-50%, 12px);
  z-index: var(--z-toast);
  max-width: min(420px, calc(100vw - 32px));
  padding: 12px 16px;
  border-radius: var(--r-pill);
  background: var(--label);
  color: var(--surface);
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s linear, transform 0.18s linear;
}
.app-notice.show { opacity: 1; transform: translate(-50%, 0); }
.app-notice.error { background: var(--systemRed); color: #fff; }
.app-notice.ok { background: var(--systemGreen); color: #fff; }
@media (min-width: 768px) {
  /* Op desktop is er geen bottom-nav om overheen te vallen. */
  .app-notice { bottom: calc(env(safe-area-inset-bottom, 0px) + 28px); }
}

/* Op ≤600px wordt élke modal een full-screen sheet — terecht voor een formulier, maar niet
   voor een ja/nee-vraag: die werd een leeg wit scherm met twee knoppen in de bovenhoek, en je
   zag niet meer waar de vraag over ging (in de browser gezien op 375 px). Deze twee blijven
   dus ook op mobiel een kaartje in het midden, mét de achtergrond eronder zichtbaar. */
@media (max-width: 600px) {
  .confirm-bg { padding: 20px; align-items: center; justify-content: center; }
  .confirm-modal {
    width: 100%;
    max-width: 380px;
    border-radius: var(--r-xl);
    max-height: 80vh;
    /* De safe-area-regel voor niet-sheet modals hierboven slaat hier niet op: dit kaartje
       staat gecentreerd en komt nooit in de buurt van de notch. */
    padding-top: 20px;
  }
}

/* ============================================================
   #88 — de omstandigheden van een tankbeurt (stap 4) en de uitsplitsing
   Chips in plaats van velden: bij de pomp tik je, je typt niet. De stijl volgt
   bewust `.svc-chip` uit de kostenmodal — hetzelfde gebaar hoort er hetzelfde
   uit te zien, ook al staat het in een ander venster.
   ============================================================ */
.fuel-cond { margin-top: 4px; }
.cond-group { margin-bottom: 14px; }
.cond-label {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary-strong);
  margin-bottom: 6px;
}
.cond-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.cond-chip {
  appearance: none;
  background: var(--surface-2);
  border: 1px solid transparent;
  color: var(--label-secondary);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 500;
  /* Ruimer dan .svc-chip: dit is een knop die je staand, met één hand raakt. */
  padding: 8px 12px;
  border-radius: var(--r-pill);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.12s linear, color 0.12s linear, border-color 0.12s linear;
}
.cond-chip:hover { background: var(--surface-3); color: var(--label); }
.cond-chip.active {
  background: var(--tint-blue);
  border-color: var(--systemBlue);
  color: var(--systemBlue);
  font-weight: 600;
}

/* De uitsplitsing op de Brandstof-tab. Eén schaal over alle groepen heen, zodat de
   balkjes onderling vergelijkbaar zijn — zie renderFuelConditions() in energy.js. */
.cond-stats { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.cond-stat-group {
  background: var(--surface);
  border-radius: var(--r-card);
  padding: 12px 16px;
}
.cond-stat-dim {
  font-size: var(--fs-sub);
  font-weight: 700;
  color: var(--label-tertiary-strong);
  margin-bottom: 10px;
}
.cond-stat + .cond-stat { margin-top: 12px; }
.cond-stat-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.cond-stat-name { font-size: var(--fs-body); color: var(--label); }
.cond-stat-val { font-size: var(--fs-body); color: var(--label); font-variant-numeric: tabular-nums; }
.cond-stat-bar {
  margin-top: 4px;
  height: 6px;
  border-radius: var(--r-2xs);
  background: var(--surface-3);
  overflow: hidden;
}
.cond-stat-bar span { display: block; height: 100%; background: var(--systemBlue); border-radius: var(--r-2xs); }
.cond-stat-sub { font-size: var(--fs-meta); color: var(--label-tertiary); margin-top: 4px; }
.cond-stats-note { margin-top: 10px; }/* #91 — de eerstvolgende beurt in een autorij/-kaart. Eigen regel, niet tussen de
   neutrale feiten: dit is het enige gegeven in de rij waar je iets mee moet. De kleur
   volgt dezelfde drie niveaus als de onderhoudspagina, zodat "over tijd" er overal
   hetzelfde uitziet. */
.car-row-next, .car-card-facts + .car-row-next {
  display: flex; align-items: baseline; gap: 8px;
  margin-top: 4px; min-width: 0;
  font-size: var(--fs-meta); color: var(--label-tertiary);
}
.car-row-next .crn-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.car-row-next .crn-when { flex: none; font-variant-numeric: tabular-nums; }
.car-row-next.overdue .crn-when { color: var(--systemRed); font-weight: 600; }
.car-row-next.soon .crn-when { color: var(--systemOrange); font-weight: 600; }

/* ============================================================
   Croptool voor de autofoto (14-09-2026)
   Het kader staat vast op 16:10 — gelijk aan .car-card-hero, zodat de voorvertoning
   niet iets anders belooft dan de kaart straks laat zien.
   ============================================================ */
.modal--crop { max-width: 34rem; }
.crop-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-control);
  overflow: hidden;
  background: var(--surface-3);
  /* Zonder dit sleept een vinger de pagina mee in plaats van de foto. */
  touch-action: none;
}
.crop-stage canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: grab;
}
.crop-stage canvas:active { cursor: grabbing; }
.crop-zoom { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.crop-zoom-ic { flex: none; color: var(--label-tertiary); display: flex; }
.crop-zoom-ic .licon { width: var(--ic-md); height: var(--ic-md); }
.crop-zoom input[type="range"] { flex: 1; min-width: 0; accent-color: var(--systemBlue); }

/* ============================================================
   #98 — onboarding in stappen
   ============================================================ */
/* De plaat als spiegel: je typt en ziet je eigen kenteken ontstaan. Zonder tekst staat er
   een voorbeeld, wat lichter, zodat zichtbaar is dat het nog niet van jou is. */
.onb-plate-pv {
  display: flex; align-items: center; justify-content: center;
  padding: 16px 12px; margin: 4px 0 16px;
  background: var(--surface-2); border-radius: var(--r-control);
  min-height: 84px;
}
.onb-plate-pv svg { max-width: 100%; height: auto; max-height: 56px; }
.onb-plate-pv.leeg { opacity: 0.45; }

/* De twee uitwegen onder de plaatstap: geen knoppen maar tekstlinks — ze horen kleiner te
   wegen dan "Verder", want dat is het pad dat je bedoelt. */
.onb-outs { display: flex; flex-direction: column; gap: 2px; margin-top: 14px; align-items: flex-start; }
.onb-out {
  appearance: none; background: none; border: 0; padding: 4px 0;
  font-family: inherit; font-size: var(--fs-sub); color: var(--systemBlue);
  cursor: pointer; text-align: left;
}
.onb-out:hover { text-decoration: underline; }

/* De drie taken op de laatste stap. Zelfde vorm als .wiz-mode: een brede rij met icoon,
   titel en een onderregel die zegt wát het oplevert. */
.onb-tasks { display: grid; gap: 8px; margin: 4px 0 12px; }
.onb-task {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 12px 16px; cursor: pointer; text-align: left;
  background: var(--surface); border: 1px solid var(--separator); border-radius: var(--r-control);
  color: var(--label); font-family: inherit; transition: background .15s, border-color .15s;
}
.onb-task:hover { background: var(--surface-2); border-color: var(--systemBlue); }
.onb-task .ot-ic { flex: none; color: var(--systemBlue); display: flex; }
.onb-task .ot-ic .licon { width: var(--ic-md); height: var(--ic-md); }
.onb-task .ot-tx { flex: 1; min-width: 0; display: block; }
.onb-task .ot-nm { display: block; font-size: var(--fs-body); font-weight: 600; }
.onb-task .ot-sub { display: block; margin-top: 2px; font-size: var(--fs-sub); color: var(--label-tertiary-strong); }
.onb-task .ot-chev { flex: none; color: var(--label-tertiary); font-size: var(--fs-heading); }

/* ============================================================
   Pictogrammen op de telefoon (verzoek Gilles, 19-09-2026)

   Eén blok, geen losse uitzonderingen: de schaal uit :root schuift onder 860 px
   — hetzelfde omslagpunt waarop de zijbalk een lade wordt en de onderbalk
   verschijnt — één stap op. Alles wat uit --ic-* put groeit mee; een pictogram
   dat bewust 1em is (badge, teller) blijft bij zijn tekst.
   ============================================================ */
@media (max-width: 860px) {
  :root {
    --ic-sm: 18px;
    --ic-md: 21px;
    --ic-lg: 26px;
  }
}

/* ============================================================
   #153 — een geschat bedrag draagt zijn eigen inkt

   Het tilde-teken stond op elf plekken hard voor het bedrag geplakt (`~€ 420`). Verzoek
   Gilles: "ik wil een elegantere manier om geschatte bedragen weer te geven i.p.v. ~; liever
   met kleur onderscheiden van vaste bedragen." Het teken is vervallen; `estAmt()` /
   `fmtEstShort()` in core.js zetten het bedrag in deze klasse.

   Deze regel staat bewust achteraan in het bestand: de plekken die hem dragen
   (.tl-item-cost, .mrow-cost, .mb-cost, .tl-cost, .tl-row-cost, .item-amount) zetten zelf
   ook een kleur, met dezelfde specificiteit. Bij gelijke specificiteit wint de laatste regel,
   en dat hoort deze te zijn — een schatting is een schatting, in welke lijst hij ook staat.
   ============================================================ */
.est-amt { color: var(--est-ink); }
.est-amt .unit,
.est-amt .sub { color: inherit; opacity: 0.8; }
