/* ============================================================================
   Ontwerpsysteem opname-app — DE ene bron voor kleur, vorm en gedeelde
   onderdelen. Zie notes/opname-app-ontwerp.md voor de spelregels.

   Stijl: verfijnd klassiek iPadOS. Rustig grijs grondvlak, grouped lists met
   haarlijnen, één groen accent, dekkende balken. Donkere modus volgt het
   systeem via de tokens hieronder; schermen gebruiken UITSLUITEND tokens,
   nooit losse hexwaarden.

   Cache: de service worker behandelt dit bestand network-first (zoals de
   HTML zelf), anders bleef na een deploy de oude stijl eeuwig staan.
   ========================================================================= */

:root {
  color-scheme: light dark;

  /* -- vlakken -- */
  --ks-bg:        #F2F2F7;   /* grondvlak, iOS grouped background */
  --ks-surface:   #FFFFFF;   /* kaarten, balken, velden */
  --ks-surface-2: #F7F7FA;   /* subtiele nadruk binnen een kaart */
  --ks-veld:      rgba(120, 120, 128, 0.12);  /* zoekveld, segmentenbak, stille vulling */
  --ks-track:     #EFEFF0;   /* voortgangsbalk-achtergrond */
  /* Twee extra treden in de vullingtrap van iOS. --ks-veld-zacht is de
     lichtste (een ingezet vlak bínnen een kaart, waar een rand lelijk zou
     zijn); --ks-veld-knop is één trede zwaarder dan --ks-veld, zodat een
     stille knop óók op een wit vlak nog als knop leest. */
  --ks-veld-zacht: rgba(120, 120, 128, 0.07);
  --ks-veld-knop:  rgba(120, 120, 128, 0.16);

  /* -- tekst -- */
  --ks-ink:       #1C1C1E;   /* koppen en gewone tekst */
  --ks-ink-2:     #6E6E73;   /* bijschrift, labels */
  --ks-ink-3:     #A1A1A6;   /* plaatshouders, uitgeschakeld */

  /* -- lijnen -- */
  --ks-line:      rgba(60, 60, 67, 0.12);  /* haarlijn binnen een groep */
  --ks-line-2:    rgba(60, 60, 67, 0.22);  /* rand van een veld */
  /* De scheiding tússen twee regels van een lijst is een andere lijn dan de
     rand ván een veld: hij hoort net zichtbaar te zijn en verder weg te
     kijken. Vooral op donker scheelde dat alles — daar tekende de veldrand
     een raster door elke lijst heen. */
  --ks-scheiding: rgba(60, 60, 67, 0.26);

  /* -- accent: het productgroen -- */
  --ks-tint:          #34795C;
  --ks-tint-dim:      #2B6650;   /* ingedrukt */
  --ks-tint-soft:     #EAF2EE;   /* zachte vulling */
  --ks-tint-contrast: #FFFFFF;   /* tekst óp het accent */

  /* -- betekenis -- */
  --ks-danger:      #C4362B;
  --ks-danger-soft: #FBEDEC;
  --ks-danger-contrast: #FFFFFF;   /* tekst óp een vlak in de gevaarkleur */
  --ks-warn:        #8A5B18;
  --ks-warn-soft:   #FAF2E6;
  --ks-ok:          #34795C;
  --ks-ok-soft:     #EAF2EE;

  /* -- vorm -- */
  --ks-r-groep:   12px;    /* inset grouped list */
  --ks-r-card:    14px;    /* losse kaarten en panelen */
  --ks-r-control: 10px;    /* knoppen, velden, segmenten */
  --ks-r-pill:    999px;   /* statuslabels */
  --ks-r-klein:   8px;     /* icoonknop, klein vlakje binnen een regel */
  --ks-r-blad:    18px;    /* zwevend paneel; iOS zet sheets ruimer af */

  /* -- ritme: één trap voor alle afstanden, zodat er niets meer op gevoel
        wordt gekozen. --ks-kantlijn is de inzet van het grondvlak (waar de
        titel en de groepen beginnen), --ks-rij-inzet de vulling bínnen een
        regel; samen bepalen ze de tekstlijn van een lijst. -- */
  --ks-ruimte-1: 4px;
  --ks-ruimte-2: 8px;
  --ks-ruimte-3: 12px;
  --ks-ruimte-4: 16px;
  --ks-ruimte-5: 22px;
  --ks-ruimte-6: 32px;
  --ks-kantlijn:  22px;
  --ks-rij-inzet: 16px;

  /* -- maten: één aanraakmaat, één balkhoogte, één controlehoogte. Alles
        wat je met een vinger raakt haalt 44px (Apple's ondergrens). -- */
  --ks-raak:          44px;
  --ks-hoogte-balk:   56px;
  --ks-hoogte-veld:   40px;   /* zoekveld, keuzelijst en segmentenbak in een filterbalk */

  /* -- tekststijlen: de iOS-trap. Schermen kiezen een trede, ze verzinnen
        geen eigen maat. -- */
  --ks-tekst-groot:  34px;   /* Large Title */
  --ks-tekst-t1:     28px;
  --ks-tekst-t2:     22px;
  --ks-tekst-t3:     20px;
  --ks-tekst-body:   17px;   /* Body / regeltitel */
  --ks-tekst-knop:   16px;
  --ks-tekst-sub:    15px;   /* Subheadline / bijschrift */
  --ks-tekst-voet:   13px;   /* Footnote / groeplabel */
  --ks-tekst-klein:  12px;   /* Caption */
  /* Optische spatiëring. SF wordt op grote maten vanzelf smaller; deze twee
     waarden zetten de twee koppen waar Apple ze zet. */
  --ks-spatie-groot: -0.4px;
  --ks-spatie-titel: -0.2px;

  /* -- beweging: één curve (de iOS-vertraging) en twee duren -- */
  --ks-veer:      cubic-bezier(0.32, 0.72, 0, 1);
  --ks-duur-tik:  0.16s;
  --ks-duur-blad: 0.3s;

  /* -- diepte: spaarzaam, iOS werkt vooral met vlakken en haarlijnen -- */
  --ks-schaduw-zweef: 0 8px 24px -8px rgba(0, 0, 0, 0.22);   /* menu's, sheets */
  --ks-schaduw-segment: 0 1px 4px rgba(0, 0, 0, 0.14);       /* actief segment */
  /* Twee gelaagde schaduwen: een harde contactlijn plus een wijde, zachte
     val. Eén enkele laag is precies wat een paneel goedkoop laat ogen. */
  --ks-schaduw-blad:
    0 0 0 0.5px rgba(0, 0, 0, 0.06),
    0 2px 6px rgba(0, 0, 0, 0.06),
    0 18px 44px -12px rgba(0, 0, 0, 0.22);
  --ks-schaduw-kaart:
    0 0 0 0.5px rgba(0, 0, 0, 0.04),
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 10px 28px -14px rgba(0, 0, 0, 0.16);

  /* -- veilige zone van het toestel -- */
  --ks-veilig-boven:  env(safe-area-inset-top, 0px);
  --ks-veilig-onder:  env(safe-area-inset-bottom, 0px);
  --ks-veilig-links:  env(safe-area-inset-left, 0px);
  --ks-veilig-rechts: env(safe-area-inset-right, 0px);

  /* -- op beeld: etiketten die bovenop een foto of een voorbeeld liggen.
        Bewust vast in béide themastanden — een plaatje is in de lichte stand
        even donker als in de donkere, dus een etiket dat meekleurt verdwijnt.
        Zelfde afspraak en zelfde reden als de --rb-*-doektokens. -- */
  --ks-op-beeld:     rgba(28, 28, 30, 0.72);
  --ks-op-beeld-ink: rgba(255, 255, 255, 0.94);

  /* -- scrim: modal-achtergronden en overlays -- */
  --ks-scrim: rgba(28, 28, 30, 0.32);

  /* -- zwevend paneel: op licht gewoon het grondvlak, op donker een trede
        lichter. Een zwart paneel op een zwarte pagina heeft geen vorm; iOS
        licht in donkere modus alles op wat boven de pagina zweeft. -- */
  --ks-blad-vlak: var(--ks-bg);
  --ks-blad-groep: var(--ks-surface);

  /* -- oude namen die alleen detail.astro nog gebruikt; weg zodra die
        bij zijn volgende onderhoudsronde is gemigreerd -- */
  --ks-muted:       var(--ks-ink-2);
  --ks-line-strong: var(--ks-line-2);
  --ks-gold:        var(--ks-warn);
  --ks-cream:       var(--ks-bg);
}

/* De donkere stand volgt het systeem. iOS-systeemwaarden, met het groen
   opgelicht zodat het op donker dezelfde rol kan spelen als op licht. */
@media (prefers-color-scheme: dark) {
  :root {
    --ks-bg:        #000000;
    --ks-surface:   #1C1C1E;
    --ks-surface-2: #2C2C2E;
    --ks-veld:      rgba(120, 120, 128, 0.24);
    --ks-track:     #2C2C2E;
    --ks-veld-zacht: rgba(120, 120, 128, 0.14);
    --ks-veld-knop:  rgba(120, 120, 128, 0.32);

    /* Wit is op donker écht wit: iOS dempt de labelkleur niet, en 0,92 gaf
       koppen een grauwsluier die je alleen op donker zag. */
    --ks-ink:       #FFFFFF;
    --ks-ink-2:     #98989E;
    --ks-ink-3:     #636369;

    --ks-line:      rgba(84, 84, 88, 0.55);
    --ks-line-2:    rgba(84, 84, 88, 0.85);
    /* Halverwege de twee: zichtbaar genoeg om regels te scheiden, licht
       genoeg om geen raster te tekenen. */
    --ks-scheiding: rgba(84, 84, 88, 0.5);

    --ks-tint:          #4FAF82;
    --ks-tint-dim:      #449A72;
    --ks-tint-soft:     rgba(79, 175, 130, 0.18);
    --ks-tint-contrast: #04150D;

    --ks-danger:      #E5695E;
    --ks-danger-soft: rgba(229, 105, 94, 0.16);
    --ks-danger-contrast: #220906;
    --ks-warn:        #E0AF62;
    --ks-warn-soft:   rgba(224, 175, 98, 0.16);
    --ks-ok:          #5CBE90;
    --ks-ok-soft:     rgba(92, 190, 144, 0.16);

    --ks-schaduw-zweef: 0 8px 24px -6px rgba(0, 0, 0, 0.65);
    --ks-schaduw-segment: 0 1px 4px rgba(0, 0, 0, 0.4);
    /* Op donker doet een schaduw bijna niets; de vorm moet het van een
       oplichtende bovenrand hebben — zoals iOS zijn sheets aftekent. */
    --ks-schaduw-blad:
      inset 0 0.5px 0 rgba(255, 255, 255, 0.09),
      0 0 0 0.5px rgba(0, 0, 0, 0.8),
      0 20px 48px -12px rgba(0, 0, 0, 0.8);
    --ks-schaduw-kaart:
      inset 0 0.5px 0 rgba(255, 255, 255, 0.06),
      0 12px 32px -16px rgba(0, 0, 0, 0.7);

    --ks-scrim: rgba(0, 0, 0, 0.5);

    --ks-blad-vlak:  #1C1C1E;
    --ks-blad-groep: #2C2C2E;
  }
}

/* ============================================================================
   Grondregels — golden voorheen per bestand, nu één keer.
   ========================================================================= */

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

html, body {
  margin: 0; padding: 0;
  background: var(--ks-bg); color: var(--ks-ink);
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Inter, sans-serif;
  font-size: 17px; line-height: 1.4;   /* min 16px voorkomt iOS Safari input-zoom */
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
  touch-action: manipulation;          /* geen double-tap zoom op iPad */
}

/* Twee soorten pagina's, twee scroll-regimes. De body kiest er één:
   .ks-vast  — app-scherm: een kader van precies één scherm hoog, scrollen
               gebeurt in panelen bínnen het scherm (100dvh, geen 100vh:
               iOS rekent 100vh groter dan het venster).
   .ks-scrol — leespagina (inloggen, account, beheer): de pagina zelf scrolt. */
body.ks-vast {
  height: 100dvh; overflow: hidden;
  padding: var(--ks-veilig-boven) var(--ks-veilig-rechts) var(--ks-veilig-onder) var(--ks-veilig-links);
}
body.ks-scrol {
  min-height: 100dvh; overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding-top: var(--ks-veilig-boven);
  padding-left: var(--ks-veilig-links);
  padding-right: var(--ks-veilig-rechts);
}

button, a, [role="tab"], [role="button"] {
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
button { font-family: inherit; font-size: inherit; cursor: pointer; color: inherit; }
input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
::placeholder { color: var(--ks-ink-3); opacity: 1; }

:focus-visible { outline: 2px solid var(--ks-tint); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }

/* Alleen voor een schermlezer: een etiket dat in beeld overbodig is omdat de
   plaatshouder het al zegt, maar dat wel voorgelezen moet worden. */
.ks-alleen-voorlezen {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ============================================================================
   Gedeelde onderdelen. Alles met de voorvoegsel .ks- zodat het naast de
   bestaande schermklassen kan staan tot elk scherm is omgebouwd.
   ========================================================================= */

/* ---- Navigatiebalk: dekkend, in het grondvlak; haarlijn pas na scrollen
        (het script zet .is-gescrold op de balk). ---- */
.ks-balk {
  position: sticky; top: 0; z-index: 30;
  background: var(--ks-bg);
  padding: 0 var(--ks-kantlijn);
  /* Eén balkhoogte voor de hele app: schermen verschilden hiervoor 48-64px,
     en dat zag je meteen als je tussen twee schermen sprong. De haarlijn
     komt pas na scrollen, en dan met een zachte overgang. */
  min-height: var(--ks-hoogte-balk);
  box-shadow: 0 0.5px 0 transparent;
  transition: box-shadow 0.2s ease;
}
.ks-balk.is-gescrold { box-shadow: 0 0.5px 0 var(--ks-scheiding); }

.ks-titel {
  font-size: var(--ks-tekst-groot); font-weight: 700;
  letter-spacing: var(--ks-spatie-groot); line-height: 1.2; margin: 0;
}
.ks-titel-klein {
  font-size: var(--ks-tekst-t2); font-weight: 700;
  letter-spacing: var(--ks-spatie-titel); line-height: 1.25; margin: 0;
}

/* ---- Segmenten (filtertabs) — de iOS-vorm: grijze bak, licht actief blokje.
        Twee standen: zonder duim licht het actieve segment zelf op (het oude
        gedrag, dat andere schermen gebruiken); mét .heeft-duim schuift er één
        blokje onder de segmenten door. Een scherm zet die klasse zelf en
        plaatst de duim met offsetLeft/offsetWidth. ---- */
.ks-segmenten {
  display: flex; position: relative;
  background: var(--ks-veld); border-radius: 9px; padding: 2px;
  transition: transform var(--ks-duur-tik) var(--ks-veer);
}
.ks-segmenten:active { transform: scale(0.985); }
.ks-segment {
  flex: 1; position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--ks-ink);
  font-size: 14px; font-weight: 500; padding: 0 14px; border-radius: 7px;
  /* 36 + 2×2 padding van de bak = 40, gelijk aan het zoekveld ernaast.
     Apple's eigen segment is 32pt; op een iPad die je met handschoenen
     bedient is dat aan de krappe kant. */
  min-height: 36px;
  white-space: nowrap;
  transition: background var(--ks-duur-tik) ease, color var(--ks-duur-tik) ease,
              font-weight var(--ks-duur-tik) ease;
}
.ks-segment.is-actief,
.ks-segment[aria-pressed="true"] {
  background: var(--ks-surface); font-weight: 600; box-shadow: var(--ks-schaduw-segment);
}
@media (prefers-color-scheme: dark) {
  .ks-segment.is-actief,
  .ks-segment[aria-pressed="true"] { background: var(--ks-ink-3); }
}
.ks-segment[hidden] { display: none; }
/* Een segment mag ook een link zijn (zie .ks-weergave hieronder). */
a.ks-segment {
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none; color: var(--ks-ink);
}

/* ---- Weergaveschakelaar ----
        De app heeft drie overzichten van hetzelfde werk: de lijst, de kaart
        en de scangalerij. Drie losse tekstknoppen naast elkaar in de balk
        lezen als een rijtje links; dit is één bedieningsdeel dat óók zegt
        waar je bent — precies waar iOS een segment voor gebruikt (Foto's:
        Jaren / Maanden / Dagen). Het actieve segment vervangt daarmee de
        inline paginatitel: die zou hetzelfde twee keer zeggen.
        Hoort in het midden van .ks-balk; het huidige overzicht is een
        <span class="ks-segment is-actief">, de andere twee zijn <a>. ---- */
.ks-weergave { flex: none; padding: 2px; }
.ks-weergave .ks-segment {
  flex: none; min-height: 40px; padding: 0 16px;
  font-size: var(--ks-tekst-sub);
}
/* De schuivende duim. Hij ligt óp het spoor en ónder de tekst; het actieve
   segment zelf blijft dan kleurloos, anders staan er twee blokjes. */
.ks-segment-duim {
  position: absolute; z-index: 0; top: 2px; bottom: 2px; left: 0;
  border-radius: 7px; background: var(--ks-surface);
  box-shadow: var(--ks-schaduw-segment);
  transform: translateX(0); width: 0;
  transition: transform 0.28s var(--ks-veer), width 0.28s var(--ks-veer);
  pointer-events: none;
}
@media (prefers-color-scheme: dark) { .ks-segment-duim { background: var(--ks-ink-3); } }
.ks-segmenten.heeft-duim .ks-segment.is-actief,
.ks-segmenten.heeft-duim .ks-segment[aria-pressed="true"] {
  background: none; box-shadow: none;
}
/* Tot de eerste meting staat de duim stil; anders vliegt hij bij het laden
   vanuit de linkerhoek naar zijn plek. */
.ks-segmenten:not(.duim-loopt) .ks-segment-duim { transition: none; }

/* ---- Zoekveld ---- */
.ks-zoek {
  display: flex; align-items: center; gap: 7px;
  background: var(--ks-veld); border-radius: var(--ks-r-control);
  padding: 0 12px; min-height: var(--ks-hoogte-veld); color: var(--ks-ink-3);
}
.ks-zoek input {
  flex: 1; border: 0; background: none; padding: 0; margin: 0;
  font-size: var(--ks-tekst-sub); color: var(--ks-ink); min-width: 0;
}
.ks-zoek input:focus { outline: none; }
.ks-zoek svg { flex: none; }
/* Het wisknopje van een zoekveld is bij WebKit een blauw systeemteken — de
   enige blauwe stip in een groen product. Hier is het een kruisje in de
   bijschriftkleur: hetzelfde gedrag, wel onze kleur. De vorm komt uit twee
   verlopen, zodat er geen plaatje met een vaste kleur aan te pas komt. */
.ks-zoek input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; margin-left: 6px; cursor: pointer;
  background: var(--ks-ink-3);
  -webkit-mask-image:
    linear-gradient(45deg, transparent 45.5%, #000 45.5%, #000 54.5%, transparent 54.5%),
    linear-gradient(-45deg, transparent 45.5%, #000 45.5%, #000 54.5%, transparent 54.5%);
  mask-image:
    linear-gradient(45deg, transparent 45.5%, #000 45.5%, #000 54.5%, transparent 54.5%),
    linear-gradient(-45deg, transparent 45.5%, #000 45.5%, #000 54.5%, transparent 54.5%);
}

/* ---- Inset grouped list ---- */
.ks-groeplabel {
  font-size: var(--ks-tekst-voet); font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ks-ink-2);
  margin: var(--ks-ruimte-5) var(--ks-kantlijn) var(--ks-ruimte-2);
}
/* Groepslabel voor een reeks inhoud in plaats van een reeks instellingen
   (Vandaag / Deze week / Eerder). iOS zet zo'n kop groot en in gewone
   schrijfwijze — de kleine kapitalen zijn voor instellingsgroepen. */
.ks-groeplabel-groot {
  font-size: var(--ks-tekst-t3); font-weight: 700;
  letter-spacing: var(--ks-spatie-titel); text-transform: none;
  color: var(--ks-ink);
  margin: var(--ks-ruimte-6) var(--ks-kantlijn) var(--ks-ruimte-2);
}
.ks-groeplabel-groot:first-child { margin-top: var(--ks-ruimte-3); }
.ks-groep {
  background: var(--ks-surface); border-radius: var(--ks-r-groep);
  margin: 0 var(--ks-kantlijn); overflow: hidden;
}
.ks-rij {
  display: flex; align-items: center; gap: var(--ks-ruimte-3);
  padding: 11px var(--ks-rij-inzet); position: relative;
  min-height: var(--ks-raak);   /* elke regel is een volwaardig aanraakvlak */
  color: inherit; text-decoration: none;
  width: 100%; text-align: left; border: 0; background: none;
}
.ks-rij + .ks-rij::before {
  content: ""; position: absolute; top: 0; left: var(--ks-rij-inzet); right: 0;
  height: 0.5px; background: var(--ks-scheiding);
}
a.ks-rij, button.ks-rij, .ks-rij.is-klikbaar { cursor: pointer; }
a.ks-rij, button.ks-rij, .ks-rij.is-klikbaar { transition: background var(--ks-duur-tik) ease; }
a.ks-rij:active, button.ks-rij:active, .ks-rij.is-klikbaar:active {
  background: var(--ks-veld-zacht); transition-duration: 0s;
}
/* iPadOS kent een echte aanwijzer (Magic Keyboard, trackpad); een regel die
   daaronder oplicht voelt af. Alleen waar hover ook echt bestaat. */
@media (hover: hover) and (pointer: fine) {
  a.ks-rij:hover, button.ks-rij:hover, .ks-rij.is-klikbaar:hover { background: var(--ks-veld-zacht); }
}
.ks-rij-tekst { flex: 1; min-width: 0; }
.ks-rij-titel {
  font-size: var(--ks-tekst-body); font-weight: 600; line-height: 1.3; margin: 0;
  letter-spacing: -0.2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ks-rij-sub  { font-size: var(--ks-tekst-sub); color: var(--ks-ink-2); line-height: 1.35; margin: 2px 0 0; }
/* Bijschrift én metaregel staan in de bijschriftkleur: --ks-ink-3 is de
   kleur van plaatshouders en uitgeschakelde tekst, en haalde op 13px bij
   lange na geen leesbaar contrast. Het verschil zit nu in de maat. */
.ks-rij-meta { font-size: var(--ks-tekst-voet); color: var(--ks-ink-2); line-height: 1.3; margin: 3px 0 0; font-variant-numeric: tabular-nums; }
/* De waarde rechts op een sleutel-waarderegel: iOS zet die grijs, niet vet. */
.ks-rij-waarde {
  margin-left: auto; color: var(--ks-ink-2); font-size: var(--ks-tekst-body);
  text-align: right; overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}
.ks-chevron { color: var(--ks-ink-3); flex: none; }

/* ---- App-icoon als tegel ----
        Het icoon is een PNG met een wit vlak eromheen. Op een licht scherm
        verdwijnt dat vlak en blijft er een zwevend blauw teken over; een
        haarlijn eromheen maakt er weer een tegel van, zoals iOS app-iconen
        in lijsten aftekent. Het logo zelf blijft ongemoeid. ---- */
.ks-appicoon {
  display: block; border-radius: 22.37%;   /* de squircle-verhouding van iOS */
  box-shadow: inset 0 0 0 0.5px var(--ks-line-2);
}

/* ---- Raster van kaarten ----
        De tweede vorm waarin een reeks gelijksoortige dingen kan staan: niet
        als regels onder elkaar maar als kaarten naast elkaar, elk met een
        voorbeeld erop. Voor dingen die je op hun áánzicht herkent en niet op
        hun naam (een ruimtescan, een foto, een plattegrond). Een lijst blijft
        de eerste keuze; dit is voor beeld. ---- */
.ks-raster {
  display: grid; gap: var(--ks-ruimte-4);
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  margin: 0 var(--ks-kantlijn);
}
.ks-kaart {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--ks-surface); border-radius: var(--ks-r-card);
  overflow: hidden; color: inherit; text-decoration: none;
  transition: transform var(--ks-duur-tik) var(--ks-veer), background var(--ks-duur-tik) ease;
}
a.ks-kaart, button.ks-kaart { cursor: pointer; border: 0; padding: 0; text-align: left; }
.ks-kaart:active { transform: scale(0.985); background: var(--ks-surface-2); transition-duration: 0s; }
@media (hover: hover) and (pointer: fine) {
  a.ks-kaart:hover, button.ks-kaart:hover { background: var(--ks-surface-2); }
}
/* Vaste beeldverhouding, zodat het raster niet verspringt terwijl de
   voorbeelden binnendruppelen. */
.ks-kaart-beeld {
  position: relative; aspect-ratio: 8 / 5; width: 100%;
  background: var(--ks-surface-2); overflow: hidden;
}
.ks-kaart-beeld > img {
  position: absolute; inset: 0; z-index: 1;
  display: block; width: 100%; height: 100%; object-fit: cover;
}
/* De plaatshouder ligt eronder, niet erover: een kaart zonder voorbeeld is
   dan een kaart met een rustig teken, nooit een gebroken plaatje. */
.ks-kaart-plaats {
  position: absolute; inset: 0; z-index: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--ks-ruimte-2); padding: var(--ks-ruimte-3);
  color: var(--ks-ink-3); text-align: center; font-size: var(--ks-tekst-klein);
}
/* Etiket óp het beeld. Gebruikt de vaste op-beeld-tokens, want wat op een
   foto ligt hoort in beide themastanden hetzelfde te zijn. */
.ks-kaart-etiket {
  position: absolute; bottom: var(--ks-ruimte-2); z-index: 2;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.01em;
  padding: 3px 8px; border-radius: var(--ks-r-pill);
  background: var(--ks-op-beeld); color: var(--ks-op-beeld-ink);
  font-variant-numeric: tabular-nums;
}
.ks-kaart-etiket.is-links  { left: var(--ks-ruimte-2); }
.ks-kaart-etiket.is-rechts { right: var(--ks-ruimte-2); }
.ks-kaart-etiket[hidden] { display: none; }
.ks-kaart-tekst { padding: 11px 13px 13px; min-width: 0; }
/* Skelet in kaartvorm: hetzelfde raster, hetzelfde beeldvlak. */
.ks-skelet-kaart { background: var(--ks-surface); border-radius: var(--ks-r-card); overflow: hidden; }
.ks-skelet-beeld {
  aspect-ratio: 8 / 5;
  background: linear-gradient(90deg, var(--ks-veld) 25%, var(--ks-track) 45%, var(--ks-veld) 65%);
  background-size: 200% 100%;
  animation: ks-glans 1.3s ease-in-out infinite;
}
.ks-skelet-kaart-tekst { padding: 12px 13px 14px; }
@media (max-width: 640px) {
  .ks-raster { margin-inline: var(--ks-ruimte-3); grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
}

/* ---- Groepslabel met een actie erachter — de "Toon alles"-regel van iOS.
        De kop blijft links staan, de verwijzing rechts. ---- */
.ks-groeplabel-rij {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--ks-ruimte-3); margin-inline: var(--ks-kantlijn);
}
.ks-groeplabel-rij > .ks-groeplabel,
.ks-groeplabel-rij > .ks-groeplabel-groot { margin-inline: 0; flex: 1 1 auto; min-width: 0; }
.ks-groeplabel-actie {
  flex: none; color: var(--ks-tint); text-decoration: none;
  font-size: var(--ks-tekst-sub); font-weight: 590; letter-spacing: -0.2px;
  display: inline-flex; align-items: center; gap: 3px;
  padding: 6px 0;
}

/* ---- Statuslabels ---- */
.ks-pil {
  font-size: 12px; font-weight: 600; padding: 4px 10px;
  border-radius: var(--ks-r-pill); white-space: nowrap;
}
.ks-pil.is-stil     { background: var(--ks-veld);        color: var(--ks-ink-2); }
.ks-pil.is-warn     { background: var(--ks-warn-soft);   color: var(--ks-warn); }
.ks-pil.is-ok       { background: var(--ks-ok-soft);     color: var(--ks-ok); }
.ks-pil.is-danger   { background: var(--ks-danger-soft); color: var(--ks-danger); }
.ks-pil.is-neutraal { background: var(--ks-veld);        color: var(--ks-ink); }

/* ---- Knoppen ----
        Elke knop haalt de 44px van Apple; schermen hoefden dat hiervoor met
        eigen min-height's bij te werken, en deden dat lang niet overal. ---- */
.ks-knop {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; border-radius: var(--ks-r-control);
  min-height: var(--ks-raak); padding: 10px 18px;
  font-size: var(--ks-tekst-knop); font-weight: 600; letter-spacing: -0.2px;
  transition: transform var(--ks-duur-tik) var(--ks-veer),
              background var(--ks-duur-tik) ease, opacity var(--ks-duur-tik) ease;
}
.ks-knop:active { transform: scale(0.96); transition-duration: 0s; }
.ks-knop:disabled { opacity: 0.45; transform: none; cursor: default; }
.ks-knop[hidden] { display: none; }  /* anders wint display:inline-flex van hidden */
label.ks-knop { cursor: pointer; }   /* verborgen file-inputs achter een label-knop */
a.ks-knop { text-decoration: none; } /* een knop is geen weblink; geen onderstreping */
.ks-rij[hidden] { display: none; }   /* anders wint display:flex van hidden */
.ks-knop-primair { background: var(--ks-tint); color: var(--ks-tint-contrast); }
.ks-knop-primair:active { background: var(--ks-tint-dim); }
/* Eén trede zwaarder dan --ks-veld: op een wit vlak verdween de oude stille
   knop bijna, en dan leest hij als uitgeschakeld in plaats van als knop. */
.ks-knop-stil    { background: var(--ks-veld-knop); color: var(--ks-tint); }
.ks-knop-blank   { background: none; color: var(--ks-tint); padding: 10px 10px; }
.ks-knop-gevaar  { background: var(--ks-danger-soft); color: var(--ks-danger); }
@media (hover: hover) and (pointer: fine) {
  .ks-knop-primair:hover:not(:disabled) { background: var(--ks-tint-dim); }
  .ks-knop-stil:hover:not(:disabled),
  .ks-knop-blank:hover:not(:disabled) { background: var(--ks-veld); }
  .ks-knop-gevaar:hover:not(:disabled) { opacity: 0.8; }
}
/* Kleine icoonknop in een regel: rond aanraakvlak van 44px, maar optisch zo
   groot als het icoon. Hiervoor tekenden schermen die zelf, elk 34px. */
.ks-icoonknop {
  flex: none; width: var(--ks-raak); height: var(--ks-raak); padding: 0;
  border: 0; border-radius: var(--ks-r-klein); background: none;
  color: var(--ks-ink-3);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--ks-duur-tik) ease, color var(--ks-duur-tik) ease,
              transform var(--ks-duur-tik) var(--ks-veer);
}
.ks-icoonknop:active { transform: scale(0.9); transition-duration: 0s; }
.ks-icoonknop:disabled { opacity: 0.4; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .ks-icoonknop:hover:not(:disabled) { background: var(--ks-veld); color: var(--ks-ink-2); }
}

/* ---- Invoervelden ---- */
.ks-invoer {
  width: 100%; border: 1px solid var(--ks-line-2); border-radius: var(--ks-r-control);
  background: var(--ks-surface); color: var(--ks-ink);
  min-height: var(--ks-raak); padding: 10px 12px; font-size: 16px;
  transition: border-color var(--ks-duur-tik) ease, box-shadow var(--ks-duur-tik) ease;
}
.ks-invoer:focus { border-color: var(--ks-tint); outline: none; box-shadow: 0 0 0 3px var(--ks-tint-soft); }
/* Gevulde variant: op een wit vlak leest een omlijnd wit veld als een
   webformulier. iOS vult het veld en laat de rand weg. */
.ks-invoer.is-vlak {
  border-color: transparent; background: var(--ks-veld);
}
.ks-invoer.is-vlak:focus { border-color: var(--ks-tint); background: var(--ks-surface); }

/* ---- Veldgroep: velden onder elkaar in één afgeronde bak met haarlijnen
        ertussen — de vorm die iOS voor aanmeld- en wijzigformulieren
        gebruikt. Geen losse randjes per veld. ---- */
.ks-veldgroep {
  background: var(--ks-veld-zacht); border-radius: var(--ks-r-groep); overflow: hidden;
}
.ks-veldgroep > * { position: relative; }
.ks-veldgroep > * + *::before {
  content: ""; position: absolute; top: 0; left: var(--ks-rij-inzet); right: 0;
  height: 0.5px; background: var(--ks-scheiding); z-index: 1;
}
.ks-veldgroep input,
.ks-veldgroep textarea {
  display: block; width: 100%; border: 0; background: none; color: var(--ks-ink);
  min-height: 48px; padding: 13px var(--ks-rij-inzet); font-size: 17px;
  border-radius: 0;
}
.ks-veldgroep input:focus,
.ks-veldgroep textarea:focus { outline: none; background: var(--ks-veld-zacht); }
/* Etiket vóór het veld, op één regel — de vorm van "Naam / waarde" in iOS. */
.ks-veldrij { display: flex; align-items: center; gap: var(--ks-ruimte-3); }
.ks-veldrij > span {
  flex: none; min-width: 108px; padding-left: var(--ks-rij-inzet);
  font-size: 17px; color: var(--ks-ink);
}
.ks-veldrij input { padding-left: 0; }

/* ---- Keuzelijst: de browserknop eruit, de iOS-vorm erin. Een gevuld vlak
        met een zelfgetekende chevron; in een data-URI past geen token, dus
        de chevron is twee randen. ---- */
.ks-keuze { position: relative; display: inline-block; }
.ks-keuze::after {
  content: ""; position: absolute; right: 14px; top: 50%;
  width: 7px; height: 7px; pointer-events: none;
  border-right: 1.8px solid var(--ks-ink-2);
  border-bottom: 1.8px solid var(--ks-ink-2);
  transform: translateY(-70%) rotate(45deg);
}
.ks-keuze > select {
  width: 100%; appearance: none; -webkit-appearance: none;
  border: 0; border-radius: var(--ks-r-control);
  background: var(--ks-veld); color: var(--ks-ink);
  min-height: var(--ks-hoogte-veld); padding: 0 32px 0 12px;
  font-size: var(--ks-tekst-sub);
  text-overflow: ellipsis;
}
.ks-keuze > select[hidden] { display: none; }
@media (hover: hover) and (pointer: fine) {
  .ks-keuze > select:hover { background: var(--ks-veld-knop); }
}

/* ---- Sync-stip ---- */
.ks-sync { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ks-ink-2); }
.ks-sync .ks-stip { width: 7px; height: 7px; border-radius: 50%; background: var(--ks-ok); }
.ks-sync .ks-stip.is-offline { background: var(--ks-ink-3); }
.ks-sync .ks-stip.is-syncing { background: var(--ks-warn); }

/* ---- Lege stand en meldingen ---- */
.ks-leeg {
  text-align: center; color: var(--ks-ink-2); font-size: var(--ks-tekst-sub);
  padding: 40px 24px; line-height: 1.5;
}
/* Een volwaardige lege stand: teken, kop, uitleg, eventueel één knop —
   de vorm van ContentUnavailableView. Losse grijze tekst midden in een
   wit vlak is geen lege stand, dat is een gat. */
.ks-leegstand {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--ks-ruimte-2); padding: 52px var(--ks-ruimte-5) 56px;
  max-width: 42ch; margin-inline: auto;
}
.ks-leegstand-teken {
  width: 56px; height: 56px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--ks-veld); color: var(--ks-ink-3);
  margin-bottom: var(--ks-ruimte-1);
}
.ks-leegstand-teken svg { width: 26px; height: 26px; }
.ks-leegstand-titel {
  margin: 0; font-size: var(--ks-tekst-t3); font-weight: 600;
  letter-spacing: var(--ks-spatie-titel); color: var(--ks-ink);
}
.ks-leegstand-tekst {
  margin: 0; font-size: var(--ks-tekst-sub); line-height: 1.45; color: var(--ks-ink-2);
}
.ks-leegstand .ks-knop { margin-top: var(--ks-ruimte-2); }
/* De technische oorzaak hoort erbij, maar niet in dezelfde stem als de
   uitleg: klein, gedempt en op een eigen regel. */
.ks-leegstand-code {
  display: block; margin-top: var(--ks-ruimte-2);
  font-size: var(--ks-tekst-klein); color: var(--ks-ink-3);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}

.ks-melding {
  border-radius: var(--ks-r-control); padding: 11px 14px; font-size: 14.5px; line-height: 1.45;
}
.ks-melding.is-ok     { background: var(--ks-ok-soft);     color: var(--ks-ok); }
.ks-melding.is-warn   { background: var(--ks-warn-soft);   color: var(--ks-warn); }
.ks-melding.is-danger { background: var(--ks-danger-soft); color: var(--ks-danger); }
.ks-melding.is-stil   { background: var(--ks-veld);        color: var(--ks-ink-2); }

/* ---- Laadskelet ---- */
.ks-skelet {
  background: var(--ks-surface); border-radius: var(--ks-r-groep);
  margin: 0 var(--ks-kantlijn) 12px; padding: 16px;
}
.ks-skelet-lijn {
  height: 12px; border-radius: 6px; margin: 6px 0;
  background: linear-gradient(90deg, var(--ks-veld) 25%, var(--ks-track) 45%, var(--ks-veld) 65%);
  background-size: 200% 100%;
  animation: ks-glans 1.3s ease-in-out infinite;
}
@keyframes ks-glans {
  0% { background-position: 180% 0; }
  100% { background-position: -60% 0; }
}
/* Skelet in lijstvorm: één groep met regels en haarlijnen, precies de vorm
   die er straks staat. Los zwevende kaartjes lieten de lijst verspringen op
   het moment dat de gegevens binnenkwamen — juist wat een skelet moet
   voorkomen. */
.ks-skelet-groep { background: var(--ks-surface); border-radius: var(--ks-r-groep);
  margin: 0 var(--ks-kantlijn); overflow: hidden; }
.ks-skelet-rij { position: relative; padding: 13px var(--ks-rij-inzet); min-height: var(--ks-raak); }
.ks-skelet-rij + .ks-skelet-rij::before {
  content: ""; position: absolute; top: 0; left: var(--ks-rij-inzet); right: 0;
  height: 0.5px; background: var(--ks-scheiding);
}

/* ---- Zwevend paneel (blad) en zijn scrim ----
        Eén vorm voor elk paneel dat over het scherm komt: popover-radius,
        gelaagde schaduw, en een opkomst die uit het niets omhoog veert zoals
        iPadOS dat doet. Schermen die hun eigen paneel tekenden hadden elk
        een andere hoek, schaduw en (geen) beweging. ---- */
.ks-scrim {
  position: fixed; inset: 0; z-index: 30; background: var(--ks-scrim);
  animation: ks-scrim-op 0.22s ease both;
}
.ks-scrim[hidden] { display: none; }
.ks-blad {
  background: var(--ks-blad-vlak); border-radius: var(--ks-r-blad);
  box-shadow: var(--ks-schaduw-blad);
  animation: ks-blad-op var(--ks-duur-blad) var(--ks-veer) both;
}
.ks-blad[hidden] { display: none; }
/* Groepen bínnen een zwevend paneel staan een trede hoger dan groepen op de
   pagina; anders vallen ze op donker samen met het paneel zelf. */
.ks-blad .ks-groep, .ks-blad .ks-veldgroep { background: var(--ks-blad-groep); }
@keyframes ks-scrim-op { from { opacity: 0; } to { opacity: 1; } }
@keyframes ks-blad-op {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---- Uitklapregel: de vorm van iOS, niet het driehoekje van de browser.
        Een <details class="ks-uitklap"> met een <summary> wordt een gewone
        lijstregel met een chevron die een kwartslag draait. ---- */
.ks-uitklap > summary {
  display: flex; align-items: center; gap: var(--ks-ruimte-3);
  min-height: var(--ks-raak); padding: 11px var(--ks-rij-inzet);
  cursor: pointer; user-select: none; list-style: none;
  font-size: var(--ks-tekst-body); font-weight: 400; color: var(--ks-ink);
  transition: background var(--ks-duur-tik) ease;
}
.ks-uitklap > summary::-webkit-details-marker { display: none; }
.ks-uitklap > summary::after {
  content: ""; flex: none; margin-left: auto;
  width: 7px; height: 7px;
  border-right: 2px solid var(--ks-ink-3); border-bottom: 2px solid var(--ks-ink-3);
  border-radius: 1px; opacity: 0.6;
  transform: rotate(-45deg); transform-origin: 60% 60%;
  transition: transform 0.24s var(--ks-veer);
}
.ks-uitklap[open] > summary::after { transform: rotate(45deg); }
.ks-uitklap > summary:active { background: var(--ks-veld-zacht); }
@media (hover: hover) and (pointer: fine) {
  .ks-uitklap > summary:hover { background: var(--ks-veld-zacht); }
}
.ks-uitklap-inhoud {
  padding: 0 var(--ks-rij-inzet) var(--ks-ruimte-4);
  font-size: var(--ks-tekst-sub); line-height: 1.5; color: var(--ks-ink-2);
  animation: ks-uitklap-op 0.24s var(--ks-veer) both;
}
@keyframes ks-uitklap-op {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- Keuze met een vinkje: hoe iOS één-uit-meer in een lijst toont. Het
        hele regeloppervlak is het aanraakvlak; het bolletje van de browser
        blijft uit beeld. ---- */
.ks-vinkrij > input[type="radio"],
.ks-vinkrij > input[type="checkbox"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.ks-vinkrij .ks-vink {
  flex: none; width: 22px; height: 22px; color: var(--ks-tint);
  opacity: 0; transform: scale(0.6);
  transition: opacity 0.2s var(--ks-veer), transform 0.2s var(--ks-veer);
}
.ks-vinkrij:has(> input:checked) .ks-vink { opacity: 1; transform: scale(1); }
.ks-vinkrij:has(> input:checked) .ks-rij-titel { color: var(--ks-ink); }
.ks-vinkrij:has(> input:focus-visible) { box-shadow: inset 0 0 0 2px var(--ks-tint); }

/* ---- Opstartscherm: dekt het scherm tot de gegevens binnen zijn ---- */
.op-start {
  position: fixed; inset: 0; z-index: 10000; display: flex;
  flex-direction: column; align-items: center; justify-content: center; gap: 26px;
  background: var(--ks-bg); padding: 24px;
  transition: opacity 0.28s ease, visibility 0.28s;
}
.op-start img { width: 72px; height: 72px; border-radius: 16px; box-shadow: inset 0 0 0 0.5px var(--ks-line-2); }
/* Het spoor moet je zien: --ks-track ligt zo dicht tegen het grondvlak aan
   dat er alleen een groen streepje leek te zweven. */
.op-start-balk {
  width: min(50vw, 160px); height: 4px; border-radius: 2px;
  background: var(--ks-veld); overflow: hidden;
}
.op-start-balk span {
  display: block; width: 40%; height: 100%; border-radius: 2px;
  background: var(--ks-tint); animation: op-start-loop 1.15s ease-in-out infinite;
}
@keyframes op-start-loop {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(310%); }
}
.op-start.is-weg { opacity: 0; visibility: hidden; }
.op-start[hidden] { display: none; }  /* anders wint display:flex van hidden */
@media (prefers-reduced-motion: reduce) {
  .op-start { transition: none; }
  .op-start-balk span { animation: none; width: 100%; }
}
