  /* Merktokens — zie BRANDING.md. Kleur is de uitzondering, niet de regel:
     accent alleen waar geklikt of gekeken moet worden. */
  :root {
    /* Vlakken, van achter naar voren */
    --bg: #F6F7FB; --panel: #EEEFF6; --panel-2: #E3E4EE; --card: #fff; --fill: #F3F4FA;
    /* --muted was #7C7C99 en haalde op wit maar 4,04:1 — net onder de 4,5 die
       nodig is om gewone tekst leesbaar te noemen, en op --panel zelfs 3,52.
       #6A6A85 haalt 5,23 op de kaart, 4,77 op --fill en 4,56 op --panel, en
       houdt dezelfde blauwpaarse zweem: de neutralen hier zijn met opzet geen
       kaal grijs. Nagemeten 04-08-2026; het donkere thema zat met 6,33 al goed. */
    --ink: #16163A; --on-ink: #fff; --muted: #6A6A85; --line: #E6E7F0;
    /* Oranje is de bediening. Op een oranje vlak hoort donkere tekst (5,4:1);
       oranje áls tekst is een tint donkerder dan het vlak, anders haalt hij
       de leesbaarheidsnorm niet. */
    --accent: #EA580C; --accent-600: #C2410C; --accent-50: #FFF1E9;
    --accent-text: #C2410C; --on-accent: #1A1005;
    /* Het merk volgt het actieve project; zonder project is het oranje.
       --brand-ink is het vinkje erin: wit op oranje, donker op een lichte
       projectkleur — anders verdwijnt het merk in zijn eigen vlak. */
    --brand: var(--accent); --brand-ink: #fff;
    /* Tekst op een lichte projectkleur — die kleuren zijn te licht voor wit. */
    --on-color: #10131A;
    --danger: #DC2626; --warn-bg: #FDF3E3; --danger-bg: #FDF2F2;
    --ok: #15803D; --ok-bg: #EFF7EF; --warn: #B45309;
    --info: #1D4ED8; --info-bg: #EEF6FF;
    --claude: #B45309; --claude-bg: #FEF3E2; --claude-line: #F3DCB8;
    /* radius vertelt de rol: pil = primaire actie, card = drijvend vlak,
       ctrl = alledaagse besturing */
    --r-pill: 999px; --r-card: 14px; --r-ctrl: 9px;
    --shadow: 0 8px 30px rgba(22,22,58,.10);
    --shadow-card: 0 1px 2px rgba(22,22,58,.07);
    --shadow-menu: 0 10px 34px rgba(22,22,58,.16);
    --shadow-dlg: 0 20px 60px rgba(22,22,58,.25);
    --toon-shadow: rgba(22,22,58,.85);
    --scrim: rgba(22,22,58,.35); --scrim-strong: rgba(16,16,40,.6);
    /* het vergrootglas in het zoekveld zit in een data-URI en kan geen
       variabele lezen — vandaar één keer licht en één keer donker */
    --search-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237C7C99' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E");
    /* ── Wat er onderaan het scherm staat ────────────────────────
       Vier dingen wilden de bodem: de kolomnavigatie, de balk bij een opgepakte
       kaart, het paneel met draaiende AI-taken, en de onderruimte van het bord.
       Ze rekenden alle vier met een eigen getal, en dus klopte er altijd wel
       eentje niet. Eén hoogte, één inzet, en iedereen wijst hierheen.
       Boven 560px staat er geen balk: dan is --balkh 0 en verandert er niets. */
    --balkh: 0px;
    --balk-onder: 0px;
    /* Hoe ver de balk zelf van de onderrand zweeft. Zit in --bodem, zodat alles
       wat eromheen moet dat in één getal krijgt. */
    --balk-zweef: 0px;
    /* Wat een zwevend paneel of een opgepakte kaart vrij moet houden. */
    --bodem: calc(var(--balkh) + var(--balk-onder) + var(--balk-zweef));
  }

  /* ── Donker: zwart met oranje ──────────────────────────────────
     Zelfde tokens, andere waarden. Alles wat hieronder in het blad staat
     rekent met de tokens, dus het thema is één omschakeling. */
  :root[data-theme="dark"] {
    --bg: #0B0C10; --panel: #15171D; --panel-2: #1E212A; --card: #1B1E26; --fill: #22262F;
    --ink: #F4F5F7; --on-ink: #0B0C10; --muted: #98A0AE; --line: #2A2F3A;
    --accent: #EA580C; --accent-600: #F97316; --accent-50: #2E1608;
    --accent-text: #FB923C; --on-accent: #140A02;
    --on-color: #10131A;
    --danger: #F87171; --warn-bg: #2A1F08; --danger-bg: #2B1516;
    --ok: #4ADE80; --ok-bg: #12251A; --warn: #FBBF24;
    --info: #93C5FD; --info-bg: #13223B;
    --claude: #FBBF24; --claude-bg: #2A1D09; --claude-line: #4A3413;
    --shadow: 0 12px 34px rgba(0,0,0,.6);
    --shadow-card: 0 1px 2px rgba(0,0,0,.5);
    --shadow-menu: 0 14px 38px rgba(0,0,0,.65);
    --shadow-dlg: 0 24px 64px rgba(0,0,0,.7);
    --toon-shadow: rgba(0,0,0,.8);
    --scrim: rgba(0,0,0,.62); --scrim-strong: rgba(0,0,0,.72);
    --search-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2398A0AE' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E");
    color-scheme: dark;
  }
  * { box-sizing: border-box; margin: 0; }
  body { font: 15px/1.5 -apple-system, 'Segoe UI', Roboto, sans-serif; background: var(--bg); color: var(--ink); }
  button { font: inherit; cursor: pointer; }
  input, textarea, select { font: inherit; color: inherit; background: var(--card); }
  /* ⚠️ De uitklaplijst van een <select> heeft een eigen achtergrond nodig.
     Zonder deze regel is een <option> doorzichtig (`rgba(0,0,0,0)`) en erft hij
     via `color: inherit` de bijna-witte tekstkleur van het donkere thema. Windows
     tekent die lijst dan wit → witte letters op wit. Gemeld 04-08-2026 op de
     statuskiezer: alleen de blauw gemarkeerde regel was te lezen.
     `color-scheme: dark` staat er wél en is niet genoeg: die kleurt het venster,
     niet een option die zelf geen achtergrond heeft.
     Deze regel repareert meteen de kiezers die hun tekst op `--muted` zetten
     (.cl-item select) — een expliciete regel wint van overerving. */
  option, optgroup { background-color: var(--card); color: var(--ink); }

  /* De inzet bovenaan is er alleen in een geïnstalleerde app op een toestel met
     een inkeping; in een browser is hij 0. Onvoorwaardelijk dus — sinds de meta
     op `viewport-fit=cover` staat loopt de pagina tot de rand door, en zonder
     dit schuift deze plakkende balk onder de statusbalk. */
  header { display: flex; align-items: center; gap: 10px; padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 12px; background: var(--card); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5; flex-wrap: nowrap; }
  header h1 { font-size: 1.05rem; margin-inline-end: 4px; flex-shrink: 1; white-space: nowrap;
              overflow: hidden; text-overflow: ellipsis; max-width: 26vw; }
  header h1 span { color: var(--accent-text); }
  /* On phones, hide the title so the whole top bar fits on one line. */
  /* Mobile top bar: title hidden; the project selector moves into that
     leading space instead of being left empty, +Task and avatar stay right. */
  /* Sinds 16-08-2026 houdt de kopbalk op een telefoon nog drie dingen vast:
     wélk bord je ziet, wat op je ja wacht, en jijzelf. De weergavewissel, de
     plus en de kolomnavigatie staan onderin in #actiebalk — zie daar. */
  @media (max-width: 560px) {
    header h1 { display: none; }
    /* ⚠️ `.brandmark` en `.searchwrap` staan hier níét, maar helemaal onderaan
       bij de actiebalk. Hun basisregels staan verderop in dit blad (regel ~1420
       en ~127) en die winnen bij gelijke specificiteit op volgorde — precies
       zoals eerder al gebeurde met `.viewbtn`. Nagemeten 16-08-2026: het merkje
       en het vergrootglas bleven gewoon 28 en 44 pixels innemen. */
    /* De spacer duwde de rechterkant naar rechts. Nu is er geen rechterkant om
       te duwen: de projectknop groeit zelf op tot wat er over is. */
    header .sp { display: none; }
    header { gap: 8px; padding: calc(12px + env(safe-area-inset-top, 0px)) 12px 12px; }
    .viewwrap { order: -1; flex: 1 1 auto; min-width: 0; }
    /* Pas afkappen als het écht niet past, in plaats van altijd op 40vw. */
    .viewbtn { max-width: none; }
    /* button sits left now — align the panel to its left edge so it stays on screen */
    .viewwrap .menu.viewpanel { inset-inline-start: 0; inset-inline-end: auto; max-width: calc(100vw - 26px); }
  }

  /* ── Zoeken in de kopbalk ──────────────────────────────────────
     Op een breed scherm staat het zoekveld gewoon open; op een smal
     scherm zou dat de halve balk opeten, dus daar staat een vergrootglas
     dat het veld over de balk heen uitklapt. Eén zoekopdracht, twee vormen. */
  .searchwrap { display: inline-flex; align-items: center; flex: 0 1 240px; min-width: 0; }
  .searchwrap input.search { width: 100%; border: 1.5px solid var(--line); border-radius: var(--r-ctrl);
                             padding: 6px 10px 6px 30px; font-size: .82rem; background: var(--card) no-repeat;
                             background-image: var(--search-icon);
                             background-size: 15px; background-position: left 9px center; }
  [dir="rtl"] .searchwrap input.search { padding: 6px 30px 6px 10px; background-position: right 9px center; }
  .searchwrap input.search:focus { outline: none; border-color: var(--accent); }
  .searchbtn { display: none; }
  /* .menu staat verderop in dit blad en wint anders op volgorde — vandaar de dubbele klasse */
  .menu.searchpanel { min-width: 340px; max-width: calc(100vw - 20px); }
  .searchpanel .results { max-height: 60vh; }
  @media (max-width: 700px) {
    .searchwrap { flex: 0 0 auto; }
    .searchbtn { display: inline-flex; align-items: center; justify-content: center; padding: 5px 9px; font-size: 1rem; line-height: 1; }
    .searchwrap input.search { display: none; }
    /* uitgeklapt: het veld legt zich over de balk, breed genoeg om te typen */
    .searchwrap.open { position: static; }
    .searchwrap.open input.search { display: block; position: absolute; inset-inline: 12px; top: 9px;
                                    width: auto; z-index: 41; box-shadow: var(--shadow); }
    .searchwrap.open .searchbtn { display: none; }
    .menu.searchpanel { inset-inline-start: auto; inset-inline-end: 0; min-width: 0; width: calc(100vw - 24px); }
  }
  .chip { border: 1.5px solid var(--line); background: var(--card); border-radius: 999px; padding: 3px 12px; font-size: .82rem; font-weight: 600; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
  .chip .dot { width: 9px; height: 9px; border-radius: 50%; }
  .chip.on { color: var(--ink); border-color: currentColor; background: var(--card); }
  .hbtn { border: 1.5px solid var(--line); background: var(--card); border-radius: var(--r-ctrl); padding: 5px 12px; font-size: .82rem; font-weight: 600; color: var(--ink); flex-shrink: 0; transition: background .12s ease, border-color .12s ease; }
  .hbtn:hover { border-color: var(--accent); color: var(--accent-text); }
  /* de primaire actie is de enige pil op het scherm */
  .hbtn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); border-radius: var(--r-pill); padding: 6px 18px; font-weight: 700; }
  /* de plus in de kopregel: rond, en breed genoeg voor een duim */
  #newTaskBtn { padding: 4px 13px; font-size: 1.15rem; line-height: 1.25; }
  .hbtn.primary:hover { background: var(--accent-600); border-color: var(--accent-600); color: var(--on-accent); }
  input:focus-visible, textarea:focus-visible, select:focus-visible, .hbtn:focus-visible, button:focus-visible,
  .task:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 1px; }
  .avatar { width: 30px; height: 30px; border-radius: 50%; border: 1.5px solid var(--line); cursor: pointer; display: block; flex-shrink: 0; }
  .sp { flex: 1 1 0; min-width: 0; }

  /* header view button (holds the search + selectors dropdown) */
  .viewbtn { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 1; min-width: 0; max-width: 46vw; }
  .viewbtn #viewLabel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .vdot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
  .menu.viewpanel { min-width: 300px; padding: 12px; }
  .viewhead { display: flex; align-items: center; gap: 8px; font-weight: 600; font-size: .9rem; padding: 2px 4px 10px; }
  .viewhead .vdot2 { width: 10px; height: 10px; border-radius: 50%; flex: none; }
  .viewpanel input.search { width: 100%; border: 1.5px solid var(--line); border-radius: 8px; padding: 8px 10px; font-size: .85rem; }
  .viewpanel .selrow { display: flex; gap: 8px; margin-top: 10px; }
  .viewpanel .selcol { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
  .viewpanel .selcol label { font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
  .viewpanel select { width: 100%; border: 1.5px solid var(--line); border-radius: 8px; padding: 6px 7px; font-size: .8rem; font-weight: 600; color: var(--ink); background: var(--card); }
  .viewpanel .owneractions { display: flex; gap: 8px; margin-top: 10px; }
  .viewpanel .owneractions .hbtn { flex: 1; }
  .viewpanel .viewfoot { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
  .viewpanel .viewfoot .hbtn { width: 100%; }
  /* De ronde vink uit de kaart, maar hier in de voet van het paneel: de
     absolute verankering is voor de kaartdialoog en zou hier uit de voet
     ontsnappen. Rechts uitgelijnd, zelfde plek als op de kaart — en de voet
     kleeft aan de onderkant van het schuivende menu, want de secties naast
     elkaar maken het paneel zo hoog als de lángste en dan lag de vink onder
     de vouw (Svens foto, 22-08-2026). */
  .viewpanel .viewfoot { display: flex; justify-content: flex-end;
                         position: sticky; bottom: -5px; background: var(--card);
                         padding-bottom: 10px; margin-bottom: -5px; }
  /* ⚠️ Voluit herhalen, niet alleen de positie: de generieke menuknop-regel
     (.menu button — volle breedte, geen achtergrond) wint anders op
     specificiteit en de vink werd een witte balk (Svens foto, 22-08-2026). */
  .viewpanel .viewfoot .dlg-done { position: static; flex: 0 0 auto;
                                   width: 44px; height: 44px; padding: 0;
                                   display: flex; align-items: center; justify-content: center;
                                   border: none; border-radius: 50%; cursor: pointer;
                                   background: var(--accent); color: #fff;
                                   font-weight: 700; font-size: 1.15rem;
                                   box-shadow: 0 4px 14px rgb(0 0 0 / .35); }
  /* tab strip inside the view panel */
  .viewtabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); padding-bottom: 8px; margin-bottom: 8px; }
  .viewtab { flex: 1; border: 1.5px solid var(--line); background: var(--card); border-radius: 8px; padding: 6px 4px; font-size: .78rem; font-weight: 600; color: var(--muted); text-align: center; }
  /* specifiek genoeg om van de hover-regels in .menu te winnen — anders valt de
     tekst van de actieve tab weg tegen zijn eigen achtergrond */
  .viewtabs .viewtab.on,
  .viewtabs .viewtab.on:hover,
  .viewtabs .viewtab.on:focus { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
  .opt { display: flex; align-items: center; gap: 8px; width: 100%; text-align: start; border: none; background: none; border-radius: 7px; padding: 7px 8px; font-size: .85rem; color: var(--ink); }
  .opt:hover { background: var(--fill); }
  .opt.on { color: var(--accent-text); font-weight: 600; }
  /* horizontally swipeable sections; each snaps left-aligned */
  .viewsections { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: 0 -12px; }
  .viewsections::-webkit-scrollbar { display: none; }
  /* ⚠️ Géén eigen `max-height` + `overflow-y` meer. Die zat genest ín .menu,
     dat zelf al schuift op 64vh — twee verticale schuifbalken naast elkaar, en
     dan weet je nooit welke je te pakken hebt. Gemeld 18-08-2026. Nu schuift
     alleen het menu; de secties groeien mee. Zie .menu hierboven. */
  .viewsection { flex: 0 0 100%; min-width: 100%; scroll-snap-align: start; scroll-snap-stop: always; padding: 0 12px; box-sizing: border-box; }

  /* De harmonica per bedrijf. Een kop is nu een knop, geen kopje. */
  .optkop.harmonica { display: flex; align-items: center; gap: 7px; width: 100%;
                      border: 0; background: none; font: inherit; color: inherit;
                      cursor: pointer; text-align: start; }
  .optkop.harmonica .ghaak { transition: transform .15s ease; opacity: .55; }
  .optkop.harmonica.uit .ghaak { transform: rotate(90deg); }
  .optkop.harmonica .gnaam { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Het aantal blijft staan als de groep dicht is — dan zie je nog wat erin zit. */
  .optkop.harmonica .gtal { flex: 0 0 auto; opacity: .5; font-variant-numeric: tabular-nums; }
  .optgroep.dicht { display: none; }
  .results { margin-top: 10px; max-height: 40vh; overflow-y: auto; }
  .results .rlabel { font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 6px 2px 2px; }
  .results button { display: flex; align-items: center; gap: 8px; width: 100%; text-align: start; border: none; background: none; border-radius: 7px; padding: 7px 8px; font-size: .84rem; color: var(--ink); }
  .results button:hover { background: var(--fill); }
  .results .rmeta { color: var(--muted); font-size: .74rem; margin-inline-start: auto; white-space: nowrap; }
  .results .empty { color: var(--muted); font-size: .82rem; padding: 8px 2px; }

  /* context bar + dropdown menus (Option B layout) */
  .contextbar { display: flex; gap: 8px; align-items: center; padding: 8px 18px; background: var(--card); border-bottom: 1px solid var(--line); flex-wrap: wrap; position: sticky; top: 55px; z-index: 4; }
  .ddl { display: inline-flex; align-items: center; gap: 7px; border: 1.5px solid var(--line); background: var(--card); border-radius: 8px; padding: 5px 11px; font-size: .82rem; font-weight: 600; color: var(--ink); max-width: 60vw; }
  .ddl > span:not(.dot):not(.caret) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ddl .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); flex: none; }
  .ddl .caret { color: var(--muted); font-size: .6rem; flex: none; }
  .menuwrap { position: relative; display: inline-flex; }
  .menu { position: absolute; top: calc(100% + 5px); inset-inline-start: 0; min-width: 210px; max-width: calc(100vw - 16px); max-height: 64vh; overflow-y: auto; background: var(--card); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-menu); padding: 5px; z-index: 40; }
  .menu.right { inset-inline-start: auto; inset-inline-end: 0; }
  /* ── Het plusmenu ín een kaart ────────────────────────────────
     Hing tot 03-08-2026 onder de plusknop, en die staat aan het eind van de
     chiprij — dus ergens rechts in het midden, en op een volle rij zelfs een
     regel lager. Gemeten in een kaart van 560×426: het menu kwam op 210 breed
     en 525 hoog uit, hoger dus dan de kaart zelf.

     `.morewrap` staat op `position: static`, waardoor dit menu zich richt naar
     de <dialog> eromheen in plaats van naar de knop. Twee dingen volgen daaruit:
     het staat altijd op dezelfde plek linksboven, en `.dlg` knipt het niet af —
     die is niet het bevattende blok, dus zijn `overflow` geldt hier niet.

     ⚠️ Dubbele klasse, en dat is geen sierletter. `.menuwrap` zet hierboven
     `position: relative`; met één klasse elk (0,1,0 tegen 0,1,0) besliste
     louter de vólgorde in dit blad wie er won. Zet iemand later een regel
     onderaan die `.menuwrap` opnieuw op relative zet, dan wordt de knop ineens
     het bevattende blok — en dan valt dit menu terug op zijn breedte, want die
     stond op een percentage van datzelfde blok. Met `.menuwrap.morewrap` (0,2,0)
     wint deze regel op specificiteit en dus altijd. */
  .menuwrap.morewrap { position: static; }
  /* ⚠️ De breedte in schermeenheden en niet in procenten van het bevattende
     blok. Gemeld 16-08-2026 op een telefoon: het menu kwam als een lange witte
     streep van zestien pixels in beeld — precies `48 - 32`, de breedte van de
     ＋-knop. Het blok was dus de knóp geworden in plaats van het venster, en
     `calc(100% - 32px)` rekende braaf mee. Elke tekst viel daarna letter voor
     letter onder elkaar; dezelfde vertoning als "C h e c k l i s t" op
     03-08-2026.
     `min()` op de viewport kan dat niet overkomen: die weet niets van
     voorouders, dus het menu houdt zijn maat ook als het ergens anders aan
     komt te hangen. */
  #moreMenu { top: 54px; inset-inline-start: 16px; inset-inline-end: auto;
              width: min(320px, calc(100vw - 32px)); min-width: 0; max-width: none;
              max-height: calc(84vh - 74px); }
  .menu button, .menu a { display: flex; align-items: center; gap: 9px; width: 100%; text-align: start; border: none; background: none; border-radius: 7px; padding: 8px 10px; font-size: .85rem; font-weight: 500; color: var(--ink); text-decoration: none; }
  .menu button:hover, .menu a:hover { background: var(--fill); }
  .menu button.on { color: var(--accent-text); }
  .menu .sep { height: 1px; background: var(--line); margin: 5px 4px; }
  .menu .mlabel { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 6px 10px 3px; }
  .fchip { border: 1.5px solid var(--line); background: var(--card); border-radius: 999px; padding: 3px 12px; font-size: .8rem; font-weight: 600; color: var(--muted); }
  .fchip.on { background: var(--ink); border-color: var(--ink); color: var(--on-ink); }

  .board { display: grid; grid-template-columns: repeat(5, minmax(230px, 1fr)); gap: 12px; padding: 14px 18px; overflow-x: auto; min-height: calc(100vh - 104px); align-items: start; }
  .col { background: var(--panel); border-radius: 12px; padding: 8px; min-height: 120px; }
  .col h2 { font-size: .72rem; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); padding: 4px 8px 8px; display: flex; justify-content: space-between; }
  .col.dragover { outline: 2px dashed var(--accent); outline-offset: -4px; }
  .col .add { width: 100%; border: none; background: none; color: var(--muted); text-align: start; padding: 6px 8px; border-radius: 8px; font-size: .85rem; }
  .col .add:hover { background: var(--panel-2); color: var(--ink); }
  /* Het archief onder de Done-kolom: een stippellijn eromheen zegt "hier ligt
     nog iets, maar het is opgeruimd" — een volle knop zou om aandacht vragen
     die afgeronde kaarten niet verdienen. */
  .col .archbtn { width: 100%; border: 1.5px dashed var(--line); background: none; color: var(--muted);
                  text-align: center; padding: 6px 8px; border-radius: 8px; font-size: .8rem;
                  font-weight: 600; margin-bottom: 7px; }
  .col .archbtn:hover { border-color: var(--accent); color: var(--accent-text); }

  /* Elke kaart draagt de kleur van zijn project: als rand én als gloed
     eromheen. Zonder project blijft --pcol doorzichtig en valt de gloed
     vanzelf weg. */
  .task { --pcol: transparent; background: var(--card); border-radius: 10px; padding: 9px 11px; margin-bottom: 7px;
          box-shadow: var(--shadow-card),
                      0 0 0 1px color-mix(in srgb, var(--pcol) 32%, transparent),
                      0 3px 16px color-mix(in srgb, var(--pcol) 20%, transparent);
          cursor: grab; border-inline-start: 3px solid transparent; }
  .task:hover { box-shadow: var(--shadow-card),
                            0 0 0 1.5px color-mix(in srgb, var(--pcol) 48%, transparent),
                            0 4px 22px color-mix(in srgb, var(--pcol) 30%, transparent); }
  .task:active { cursor: grabbing; }
  .task.dragging { opacity: .45; }

  /* ── "Sleep een kaart naar de volgende kolom" ─────────────────
     Die stap had als enige geen plek om naartoe te wijzen: slepen is een
     gebaar, geen knop, dus het stapvenster bood alleen een demo. Nu wijst het
     bord het zélf aan — op de kaart waar het om gaat.
     Drie dingen samen, want los is elk te subtiel: een gloed in `--warn` (zelfde
     betekenis als het uitroepteken), een kaart die uit zichzelf een stukje de
     goede kant op wipt, en een pijl ernaast.
     `--kant` draait de richting om in het Arabisch: daar ligt de volgende kolom
     links. */
  .task.lk-sleep { --kant: 1; position: relative; z-index: 2;
                   box-shadow: 0 0 0 2px var(--warn),
                               0 6px 22px color-mix(in srgb, var(--warn) 45%, transparent);
                   animation: sleepWenk 2.6s ease-in-out infinite; }
  [dir="rtl"] .task.lk-sleep { --kant: -1; }
  .task.lk-sleep::after { content: '→'; position: absolute; top: 50%; inset-inline-end: -26px;
                          transform: translateY(-50%); color: var(--warn); font-size: 1.15rem;
                          font-weight: 700; pointer-events: none;
                          animation: sleepPijl 2.6s ease-in-out infinite; }
  [dir="rtl"] .task.lk-sleep::after { content: '←'; }
  @keyframes sleepWenk { 0%, 100% { transform: none; }
                         45% { transform: translateX(calc(10px * var(--kant))); } }
  @keyframes sleepPijl { 0%, 100% { transform: translateY(-50%); }
                         45% { transform: translateY(-50%) translateX(calc(7px * var(--kant))); } }
  /* Tijdens het slepen zelf niets: een bewegend element geeft een scheve
     sleepafbeelding, en de aanwijzing heeft dan zijn werk al gedaan. */
  .task.lk-sleep.dragging { animation: none; transform: none; box-shadow: var(--shadow-card); }
  .task.lk-sleep.dragging::after { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .task.lk-sleep, .task.lk-sleep::after { animation: none; }
    .task.lk-sleep { transform: translateX(calc(6px * var(--kant))); }
  }
  .task .t { font-size: .9rem; font-weight: 500; }
  .task .m { display: flex; gap: 6px; align-items: center; margin-top: 6px; flex-wrap: wrap; }
  .task .m:empty { display: none; }
  .badge { font-size: .68rem; font-weight: 700; border-radius: 999px; padding: 1px 8px; background: var(--accent-50); color: var(--accent-text); }
  .badge.claude { background: var(--claude-bg); color: var(--claude); }
  .badge.wait { background: var(--danger-bg); color: var(--danger); font-weight: 600; }
  .badge.proj { color: var(--on-color); }
  .badge.due { background: var(--info-bg); color: var(--info); }
  .badge.due.over { background: var(--danger-bg); color: var(--danger); }
  .badge.check { background: var(--ok-bg); color: var(--ok); }
  .badge.prop { background: var(--claude-bg); color: var(--claude); }
  .task.proposal { border-style: dashed; border-width: 1.5px; border-color: var(--claude); border-inline-start-width: 3px; }
  .done .t { text-decoration: line-through; color: var(--muted); }

  /* ⚠️ `margin: auto` hoort hierbij en is geen opsmuk. Zonder die regel komt een
     venster met wat inhoud linksboven te staan in plaats van in het midden —
     korte meldingen ontsnapten eraan, waardoor het lang onopgemerkt bleef.
     Ontdekt op 01-08 bij het inlogvenster en op 02-08 bij het projectvenster;
     toen pas bleek dat het elk venster raakt, niet één. */
  dialog { border: none; border-radius: 14px; padding: 0; width: min(560px, 92vw); box-shadow: var(--shadow-dlg); background: var(--card); color: var(--ink);
           position: relative; margin: auto; }
  dialog::backdrop { background: var(--scrim); }
  /* Het kruisje rechtsboven. Het staat búiten `.dlg` — dus buiten het vak dat
     scrolt — en blijft daardoor staan hoe ver je ook naar beneden bent. Tot
     01-08-2026 zat de enige sluitknop ónder de inhoud: bij een lange lijst
     open uitnodigingen moest je eerst naar beneden om weg te kunnen. */
  .dlg-x { position: absolute; top: 10px; inset-inline-end: 10px; z-index: 5;
           width: 30px; height: 30px; padding: 0; line-height: 1; font-size: .8rem;
           display: flex; align-items: center; justify-content: center;
           border: 1.5px solid var(--line); border-radius: 999px;
           background: var(--card); color: var(--muted); cursor: pointer; }
  .dlg-x:hover { background: var(--fill); color: var(--ink); }
  .dlg-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  /* De zwevende Klaar-knop op een open kaart (Sven, 22-08-2026): altijd
     bereikbaar, ook op een volle kaart die scrolt — zelfde verankering als het
     kruisje, maar onderin. */
  .dlg-done { position: absolute; bottom: 12px; inset-inline-end: 12px; z-index: 5;
              width: 44px; height: 44px; padding: 0; border: none; border-radius: 50%;
              display: flex; align-items: center; justify-content: center; cursor: pointer;
              background: var(--accent); color: #fff; font-weight: 700; font-size: 1.15rem;
              box-shadow: 0 4px 14px rgba(0, 0, 0, .35); }
  .dlg-done { transition: transform .15s ease; }
  .dlg-done:hover { filter: brightness(1.08); }
  .dlg-done:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  /* Lucht onderin de kaart, anders schuilt de laatste regel achter de knop. */
  #taskDlg .dlg, #setDlg .dlg, #projDlg .dlg { padding-bottom: 64px; }
  /* Ruimte vrijhouden, anders loopt een lange kop onder het kruisje door. */
  .dlg > h2:first-child, .dlg > h3:first-child, .dlg > .tdoc-head { padding-inline-end: 34px; }
  /* Een geopende kaart mag nooit zijwaarts schuiven: als je moet slepen om bij
     Bewaren te komen, is de knop er in de praktijk niet. Vandaar drie regels:
     alles breekt af (ook een sleutel of URL zonder spaties), flex-kinderen
     mogen krimpen onder hun inhoud (`min-width: 0` — zonder dat weigert een
     flexvak smaller te worden dan zijn langste woord), en verticaal scrollen
     mag, horizontaal niet. */
  .dlg { padding: 20px; display: flex; flex-direction: column; gap: 12px; max-height: 84vh;
         overflow-y: auto; overflow-x: hidden; overflow-wrap: anywhere; }
  .dlg > *, .dlg .row > *, .dlg .actions > * { min-width: 0; }
  .dlg h3 { font-size: 1rem; }
  .dlg label { font-size: .75rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; display: block; margin-bottom: 4px; }
  .dlg input[type=text], .dlg input[type=password], .dlg input[type=date], .dlg textarea, .dlg select { width: 100%; border: 1.5px solid var(--line); border-radius: 8px; padding: 8px 10px; background: var(--card); }
  .dlg textarea { resize: vertical; min-height: 70px; }
  .row { display: flex; gap: 10px; }
  .row > * { flex: 1; }
  /* De knoppenrij mag over meerdere regels vallen; liever twee regels dan een
     knop die buiten de kaart valt. `.right` houdt zijn groep bij elkaar en
     blijft rechts staan, ook als hij op een eigen regel terechtkomt. */
  .dlg .actions { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; margin-top: 4px; }
  .dlg .actions .right { display: flex; flex-wrap: wrap; gap: 8px; margin-inline-start: auto; justify-content: flex-end; }
  /* Op een telefoon is naast elkaar geen optie meer: twee velden naast elkaar
     worden allebei te smal om in te typen, en drie knoppen op één regel passen
     niet. Alles onder elkaar, knoppen over de volle breedte zodat ze met een
     duim te raken zijn. */
  @media (max-width: 560px) {
    .dlg .row { flex-direction: column; gap: 12px; }
    /* Volgorde blijft die van het scherm: eerst het uitzonderlijke (verwijderen),
       onderaan de gewone afsluiting — Bewaren zit zo het dichtst bij je duim. */
    .dlg .actions { flex-direction: column; align-items: stretch; }
    .dlg .actions .right { flex-direction: column; align-items: stretch; margin-inline-start: 0; }
    .dlg .actions .hbtn, .dlg .actions .tbtn { width: 100%; text-align: center; }
  }
  /* ── De kaart als document ─────────────────────────────────────
     Een taak is een titel, wat context en je tekst. Titel en notities zijn
     daarom randloze velden die pas bij aanwijzen laten zien dat je erin kunt
     typen; de rest van de kaart is één rij chips. Zo leest een kaart als een
     document en niet als een formulier met acht vragen. */
  .tdoc-head { display: flex; align-items: flex-start; gap: 8px; }
  .tdoc-title { flex: 1; width: 100%; border: 1.5px solid transparent; background: none; color: var(--ink);
                font: inherit; font-size: 1.05rem; font-weight: 700; line-height: 1.3;
                resize: none; overflow: hidden; padding: 4px 6px; border-radius: 8px; }
  .tdoc-notes { width: 100%; border: 1.5px solid transparent; background: none; color: var(--ink);
                font: inherit; line-height: 1.55; resize: none; overflow: hidden;
                padding: 6px; border-radius: 8px; min-height: 44px; }
  .tdoc-title:hover, .tdoc-notes:hover { background: var(--fill); }
  .tdoc-title:focus, .tdoc-notes:focus { outline: none; background: var(--fill); border-color: var(--line); }

  /* Chips zijn gewone <select>/<input> in een pilvorm. Bewust native: op een
     telefoon krijg je zo de eigen keuzewiel en datumkiezer van het toestel,
     toetsenbord en schermlezer werken vanzelf, en een eigen menu zou áchter
     de dialoog vallen (zie de opmerking bij tipEl). */
  .chiprow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
  .chip-f { display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
            border: 1.5px solid transparent; background: var(--fill); border-radius: 999px; padding: 2px 8px; }
  .chip-f:hover { border-color: var(--line); }
  .chip-f:focus-within { border-color: var(--accent); }
  /* Aanwijzen zonder pijl: de chip zelf gloeit tot je gekozen hebt. Gezet vanuit
     runNow() in js/task.js zodra je "Kies de AI op de kaart" aantikt — die knop
     staat onderin het venster en de chip bovenin, en dat is precies de afstand
     waarop een tekst alleen niet genoeg is. Sven, 17-08-2026.
     `!important` op de rand omdat :hover en :focus-within dezelfde eigenschap
     zetten en die anders wint zodra de muis er langsgaat. */
  /* Suggesties bij het typen van een @. Vast gepositioneerd en aan <body>
     gehangen: de chat zit in een venster met eigen schuifgedrag, en een lijst
     die daarbinnen hangt wordt afgeknipt door de eerste `overflow` die hij
     tegenkomt. */
  /* De regel in het stappaneel die zegt wélke handeling de sport afrondt. Wél
     opvallend en niet als `.note` weggezet: het paneel legde tot 18-08-2026
     alleen uit wát een functie is en waaróm hij vrijblijvend is, en nooit wat
     je moest doen. Dit is het antwoord op die vraag, dus het mag gezien worden. */
  .hoe { margin-top: 14px; padding: 9px 11px; border-radius: 10px;
         background: var(--fill); border-inline-start: 3px solid var(--accent); }

  .noemlijst { position: fixed; z-index: 90; background: var(--card);
               border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
               box-shadow: 0 10px 30px rgba(0,0,0,.18); }
  .noemrij { display: flex; align-items: center; gap: 8px; width: 100%;
             padding: 7px 10px; border: 0; background: none; cursor: pointer;
             text-align: start; font: inherit; color: inherit; }
  .noemrij.aan, .noemrij:hover { background: var(--fill); }
  .noemrij img, .noemrij .noemleeg { width: 20px; height: 20px; border-radius: 50%; flex: 0 0 auto; }
  .noemrij .noemleeg { background: var(--fill); border: 1px solid var(--line); }
  .noemrij .noemai { width: 20px; text-align: center; color: var(--accent); flex: 0 0 auto; }
  .noemrij .note { margin-inline-start: auto; font-size: 12px; }
  /* Eén vermelding in het overzicht. De tekst mag afbreken maar niet uitlopen:
     het fragment is 200 tekens en een lange regel zou het venster verbreden. */
  .noemmelding { padding: 9px 0; border-block-end: 1px solid var(--line); overflow-wrap: anywhere; }
  .noemmelding:last-of-type { border-block-end: 0; }

  .chip-f.gloed { border-color: var(--accent) !important;
                  animation: chipgloed 1.6s ease-in-out infinite; }
  @keyframes chipgloed {
    0%, 100% { box-shadow: 0 0 0 0 rgba(234, 88, 12, .45); }
    50%      { box-shadow: 0 0 0 6px rgba(234, 88, 12, 0); }
  }
  /* Wie beweging heeft uitgezet krijgt een stilstaande ring — hetzelfde
     signaal, zonder de puls. Weglaten zou de aanwijzing juist dáár slopen. */
  @media (prefers-reduced-motion: reduce) {
    .chip-f.gloed { animation: none; box-shadow: 0 0 0 3px rgba(234, 88, 12, .35); }
  }
  /* De uitleg blijft in de keuzelijst staan ("Claude Code — volledige toegang
     tot de computer"); alleen de chip zelf kort af. Zo hou je een leesbare
     keuze zonder dat de rij dichtslibt. */
  /* De tijd naast een datum: smal, want het is altijd HH:MM. */
  .chip-f > input.tijd { max-width: 88px; }
  /* ── Waarop wacht deze kaart ──────────────────────────────────
     Een eigen blok en geen chip meer: drie soorten, en per soort een keuzelijst,
     een lijst blokkeerders of een tekstveld — plus een datum met een tijd. Dat
     past niet meer op één regel. Zie het commentaar bij #waitBox in js/task.js. */
  .waitbox { border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
             margin: 12px 0; background: var(--panel); display: flex; flex-direction: column; gap: 8px; }
  .wsoorten { display: flex; gap: 6px; flex-wrap: wrap; }
  .wsoort { border: 1.5px solid var(--line); background: var(--card); border-radius: var(--r-pill);
            padding: 4px 12px; font-size: .8rem; font-weight: 600; color: var(--muted); cursor: pointer; }
  .wsoort.on { border-color: var(--accent); color: var(--accent-text); background: var(--accent-50); }
  .waitbox .frow { display: flex; align-items: center; gap: 8px; }
  .waitbox .frow > input, .waitbox .frow > select { flex: 1 1 auto; min-width: 0;
    border: 1.5px solid var(--line); border-radius: 8px; padding: 7px 10px; background: var(--card); color: var(--ink); }
  .waitbox .frow.wanneer > input { flex: 0 1 auto; }
  .waitbox .flbl { font-size: .72rem; font-weight: 700; color: var(--muted); text-transform: uppercase;
                   letter-spacing: .05em; flex: 0 0 auto; }
  .wnieuw { display: flex; flex-direction: column; gap: 6px; }
  .wnieuw input { border: 1.5px solid var(--line); border-radius: 8px; padding: 7px 10px; background: var(--card); color: var(--ink); }
  .wblokken { display: flex; flex-direction: column; gap: 4px; }
  /* min-width: 0 op de titel — anders legt een lange kaarttitel zijn volle
     breedte op als ondergrens en groeit het blok buiten de kaart. Vandaag voor
     de vijfde keer; zie de opmerking bij .calmain. */
  .wblok { display: flex; align-items: center; gap: 6px; font-size: .82rem;
           background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 4px 8px; }
  .wblok > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .wblok.klaar { color: var(--muted); text-decoration: line-through; }
  .wtreffers { display: flex; flex-direction: column; gap: 3px; }
  .wtreffer { text-align: start; border: 1px dashed var(--line); background: none; border-radius: 8px;
              padding: 5px 9px; font-size: .8rem; color: var(--ink); cursor: pointer;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .wtreffer:hover { border-color: var(--accent); background: var(--accent-50); }
  /* ── Het adresboek in de instellingen ─────────────────────────
     Eén regel per contact: naam boven, adres en nummer eronder in het klein.
     min-width: 0 op de naamkolom — anders legt een lang e-mailadres zijn volle
     breedte op en groeit de rij buiten het venster. */
  .crow { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--line); }
  .crow:first-child { border-top: 0; }
  .cnaam { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
  .cnaam b { font-size: .88rem; }
  .cnaam .note, .crow > .note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .csep { font-size: .72rem; font-weight: 700; color: var(--muted); text-transform: uppercase;
          letter-spacing: .05em; margin: 12px 0 2px; }
  .cshare { background: var(--fill); border-radius: 8px; padding: 8px 10px; margin: 2px 0 8px;
            display: flex; flex-direction: column; gap: 5px; }
  .cshare .inline { display: flex; align-items: center; gap: 7px; font-size: .84rem; }

  /* ── Erachteraan gaan ─────────────────────────────────────────
     Eén belknop die een rijtje uitklapt. Uitklappen en geen zwevend menu: dat
     werkt op een telefoon zonder positieberekening, en het valt nooit achter een
     venster — de kaart is een <dialog> en die staat in de top layer. */
  /* De landvraag verschijnt pas ná het opslaan van een nummer, op de plek waar
     dat gebeurde. Amber, want het is een vraag en geen fout. */
  .landvraag { background: var(--warn-bg); border-radius: 8px; padding: 9px 11px; margin-top: 8px;
               display: flex; flex-direction: column; gap: 7px; }
  .landvraag .frow { display: flex; gap: 8px; align-items: center; }
  .landvraag select { flex: 1 1 auto; min-width: 0; border: 1.5px solid var(--line);
                      border-radius: 8px; padding: 7px 10px; background: var(--card); color: var(--ink); }
  .cactie { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
  .ckanalen { display: inline-flex; gap: 4px; flex-wrap: wrap; }
  .ckanalen .mini { text-decoration: none; white-space: nowrap; }
  .wcontact { gap: 10px; }
  .wcontact .note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* ── De agenda: vandaag, zeven dagen, of een periode ──────────
     Dag voor dag, en binnen een dag eerst wat een tijdstip heeft. Op een
     telefoon is dit de vorm die het maandraster nooit kon zijn. */
  .calper { display: inline-flex; gap: 4px; background: var(--fill); border-radius: var(--r-pill); padding: 3px; }
  .calperk { border: 0; background: none; border-radius: var(--r-pill); padding: 4px 11px;
             font-size: .78rem; font-weight: 600; color: var(--muted); cursor: pointer; }
  .calperk.on { background: var(--card); color: var(--ink); box-shadow: var(--shadow-card); }
  .agenda { display: flex; flex-direction: column; gap: 14px; }
  .adagkop { font-size: .8rem; font-weight: 700; color: var(--muted); text-transform: capitalize;
             padding: 0 0 5px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
  .adagkop.nu { color: var(--accent-text); }
  .agrij { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-radius: 8px; cursor: pointer; }
  .agrij:hover { background: var(--fill); }
  /* Vaste breedte voor de tijd, zodat de titels onder elkaar uitlijnen — een
     lijst waarin de tekst per regel opschuift leest twee keer zo traag. */
  .atijd { flex: 0 0 46px; font-size: .8rem; font-weight: 700; color: var(--muted); text-align: end; font-variant-numeric: tabular-nums; }
  .agrij.opvolg .atijd { color: var(--accent-text); }
  .agrij.laat .atijd { color: var(--danger); }
  .atitel { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
  .atitel b { font-size: .88rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .atitel .note { display: flex; align-items: center; gap: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .atitel .chipdot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
  .chip-f > select, .chip-f > input { width: auto; max-width: min(38vw, 190px); border: none; background: none;
                                      color: var(--ink); font: inherit; font-size: .8rem; font-weight: 600;
                                      padding: 3px 0; border-radius: 0;
                                      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
                                      appearance: none; -webkit-appearance: none; }
  /* Geen ring bij een muisklik, wél bij Tab: `:focus` zonder meer nam de
     toetsenbordgebruiker zijn enige aanwijzing af (analyse 05-09-2026). */
  .chip-f > select:focus:not(:focus-visible), .chip-f > input:focus:not(:focus-visible) { outline: none; }
  .chip-f.ai > select { color: var(--accent-text); }
  .chipdot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
  /* Dezelfde plus als in de kopregel: oranje vlak met donkere tekst
     (--on-accent, want wit op oranje haalt de contrastnorm niet). Eén teken,
     één betekenis — "hier komt er iets bij" — dus ook één uiterlijk. */
  .chipadd { border: 1.5px solid var(--accent); background: var(--accent); color: var(--on-accent);
             border-radius: 999px; width: 27px; height: 27px; font-size: .95rem; font-weight: 700;
             line-height: 1; flex: 0 0 auto; transition: background .12s ease, border-color .12s ease; }
  .chipadd:hover { background: var(--accent-600); border-color: var(--accent-600); color: var(--on-accent); }
  /* Op een groot scherm is 27px een speldenknop naast chips die het dubbele
     breed zijn — hij valt weg in de rij. Drie keer zo breed maakt er een échte
     knop van zonder dat hij iets anders gaat betekenen; hoogte en vorm blijven.
     Op een telefoon blijft hij rond: daar is de chiprij krap en is 27px al een
     prima raakvlak. */
  @media (min-width: 561px) { .chipadd { width: 81px; } }

  /* Onderbalk: links wat er met je wijziging gebeurde, rechts de enige actie. */
  .tdoc-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px;
               border-top: 1px solid var(--line); padding-top: 11px; }
  .savestate { flex: 1; font-size: .75rem; color: var(--muted); min-width: 120px; }
  .savestate button { border: none; background: none; color: var(--accent-text); font-size: .75rem; font-weight: 600; padding: 0 2px; }
  .tsec { font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
          color: var(--muted); margin-top: 6px; }
  @media (max-width: 560px) {
    .chip-f > select, .chip-f > input { max-width: 60vw; }
    .tdoc-foot .hbtn { width: 100%; text-align: center; }
  }
  .link { background: none; border: none; color: var(--danger); font-size: .82rem; padding: 0; }
  .comments { border-top: 1px solid var(--line); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
  .comment { background: var(--fill); border-radius: 8px; padding: 7px 10px; font-size: .85rem; white-space: pre-wrap; }
  .comment b { font-size: .75rem; color: var(--accent-text); display: block; white-space: normal; }
  .comment.claude b { color: var(--claude); }
  .comment .when { float: right; font-size: .7rem; color: var(--muted); }

  .cl-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
  .cl-item input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); }
  .cl-item .txt { flex: 1; font-size: .88rem; }
  .cl-item.done .txt { text-decoration: line-through; color: var(--muted); }
  .cl-item .mini { border: none; background: none; color: var(--muted); font-size: .75rem; padding: 2px 5px; border-radius: 5px; }
  .cl-item .mini:hover { background: var(--accent-50); color: var(--accent-text); }
  .prop-banner { background: var(--claude-bg); border: 1.5px dashed var(--claude); border-radius: 10px; padding: 10px 12px; font-size: .85rem; }
  /* Wacht op een bestemming: oranje in plaats van het AI-paars. Dit is geen
     voorstel van de AI om te beoordelen maar een vraag aan jou die openstaat
     zolang je hem laat staan. */
  .prop-banner.pending { background: var(--accent-50); border-color: var(--accent); border-style: solid; }
  .prop-banner.pending b { color: var(--accent-text); }
  .badge.pending { background: var(--accent-50); color: var(--accent-text); }
  .prop-banner b { color: var(--claude); }
  .prop-banner .opts { margin: 8px 0; display: flex; flex-direction: column; gap: 5px; }
  /* Wikkelen, niet uitpuilen. Op 375px passen twee knoppen met een leesbaar
     opschrift niet naast elkaar; zonder deze regel duwen ze de kaart zijwaarts
     open, en horizontaal schuiven is precies wat een geopende kaart nooit mag. */
  .prop-banner .pbtns { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
  .prop-banner .pbtns > * { min-width: 0; }
  @media (max-width: 560px) {
    .prop-banner .pbtns { flex-direction: column; align-items: stretch; }
    .prop-banner .pbtns .hbtn { width: 100%; text-align: center; }
  }

  .proj-list { display: flex; flex-direction: column; gap: 10px; }
  .proj-row { border: 1.5px solid var(--line); border-radius: 10px; padding: 10px 12px; }
  .proj-row .head { display: flex; align-items: center; gap: 8px; }
  .proj-row .head b { flex: 1; }
  .proj-row .small { font-size: .78rem; color: var(--muted); margin-top: 4px; }
  .invite-box { font-size: .78rem; background: var(--fill); border-radius: 8px; padding: 6px 9px; margin-top: 6px; word-break: break-all; }
  .members { margin-top: 6px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
  .members img { width: 22px; height: 22px; border-radius: 50%; vertical-align: middle; }

  .cl-item select { width: auto; max-width: 120px; font-size: .75rem; padding: 2px 6px; border-radius: 6px; border: 1px solid var(--line); color: var(--muted); }
  .file-item { border: 1.5px solid var(--line); border-radius: 10px; margin-top: 6px; }
  .file-item summary { cursor: pointer; padding: 8px 10px; font-size: .85rem; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  /* ⚠️ De naam mag krimpen, de regel erachter niet. Een bestandsnaam is hier de
     kaarttitel + ".md" en dus lang; met `flex: 1` op de meta hield de naam alle
     ruimte en werd "Sven Stigter · 2026-08-03" tot nul geknepen — waarna de
     browser hem letter voor letter onder elkaar zette. Dezelfde val als het
     menu-item dat op 03-08-2026 "C h e c k l i s t" werd.
     Met flex-wrap zakt de meta naar een tweede regel als het écht niet past,
     in plaats van te verticaliseren. */
  .file-item summary > b { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
  .file-item summary .meta, .file-item.drive .meta {
    flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden;
    text-overflow: ellipsis; color: var(--muted); font-size: .75rem; }
  .file-item.drive > b { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
  .file-item pre { margin: 0 10px 10px; padding: 10px; background: var(--fill); border-radius: 8px; font-size: .8rem; white-space: pre-wrap; word-break: break-word; max-height: 260px; overflow-y: auto; }
  /* ── Werkbalk onderin terwijl de AI werkt ───────────────────── */
  /* Onderin, gecentreerd, boven de kolomnavigatie op mobiel. De balk laat zien
     dát er iets gebeurt en waaraan; de melding erboven zegt dat het klaar is. */
  #aiBar { position: fixed; inset-inline: 0; bottom: 0; z-index: 60; display: flex;
           flex-direction: column; align-items: center; gap: 8px; padding: 12px;
           pointer-events: none; }
  #aiBar:empty { display: none; }
  .aijob, .aitoast { pointer-events: auto; width: min(460px, calc(100vw - 24px));
                     background: var(--card); border: 1px solid var(--line);
                     border-radius: 12px; box-shadow: var(--shadow); }
  .aijob { padding: 9px 13px; }
  /* In een venster (de "bak"-optie van aiJobStart, zoals #chatWacht in de
     chat) is 100vw breder dan het venster zelf en stak het blok er rechts
     uit (Sven, 23-08-2026, telefoon). Daarbinnen geldt de vensterbreedte. */
  dialog .aijob, dialog .aitoast { width: 100%; }
  .aijob .top { display: flex; align-items: center; gap: 8px; font-size: .84rem; }
  .aijob .name { flex: 1; min-width: 0; font-weight: 600; overflow: hidden;
                 text-overflow: ellipsis; white-space: nowrap; }
  .aijob .pct { color: var(--muted); font-variant-numeric: tabular-nums; font-size: .78rem; }
  .aijob .sub { font-size: .74rem; color: var(--muted); margin-top: 3px; }
  /* Meelezen met de AI. Er is bewust geen scrollbalk: het venster schuift mee
     met de laatste regels, zoals een terminal. Twee regels is genoeg om te
     zien dát er iets gebeurt zonder dat de balk het scherm opeet. */
  .aijob .live { font-size: .74rem; color: var(--ink); margin-top: 5px; max-height: 2.6em;
                 overflow: hidden; white-space: pre-wrap; overflow-wrap: anywhere;
                 display: flex; flex-direction: column-reverse; }
  .aijob.done .live, .aijob.fail .live { display: none; }
  .aijob .spin { display: inline-block; animation: aispin 1.1s linear infinite; }
  .aijob.done .spin, .aijob.fail .spin { animation: none; }
  @keyframes aispin { to { transform: rotate(360deg); } }
  .aijob .track { height: 4px; border-radius: 999px; background: var(--line);
                  margin-top: 7px; overflow: hidden; }
  .aijob .fill { height: 100%; width: 0; background: var(--accent);
                 border-radius: 999px; transition: width .45s ease; }
  .aijob.done .fill { background: var(--ok); }
  .aijob.fail .fill { background: var(--danger); }
  .aitoast { display: flex; align-items: center; gap: 10px; padding: 10px 12px; font-size: .84rem; }
  .aitoast .ic { color: var(--ok); }
  .aitoast.fail .ic { color: var(--danger); }
  .aitoast .txt { flex: 1; min-width: 0; }
  .aitoast .txt b { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .aitoast .note { font-size: .74rem; color: var(--muted); }
  .aitoast .x { border: none; background: none; color: var(--muted); font-size: .8rem; padding: 2px 4px; }
  /* De zwevende kolomnavigatie schuift omhoog zodra er iets draait — maar alleen
     zolang ze nog zweeft, dus boven 560px. */
  @media (min-width: 561px) { body.has-aijobs #boardNav { bottom: 104px; } }
  /* ⚠️ Onder 560px is de richting omgedraaid. De actiebalk is meubilair onder je
     duim en mag niet bewegen omdat er toevallig een AI-taak loopt; het paneel is
     voorbijgaand en gaat er dus bóvenop staan. Dat repareert meteen het oude
     scheve geval: .pickbar week hier nóóit voor, #boardNav wel. */
  @media (max-width: 560px) { #aiBar { bottom: var(--bodem); } }

  /* Het antwoordveld van de brainstorm: altijd vier regels hoog, hoe breed het
     scherm ook is. Niet meegroeien met wat je typt — dan springt de knop
     eronder weg terwijl je bezig bent. */
  /* dubbele klasse, want `.dlg textarea` verderop zet een eigen min-height */
  .dlg textarea.bninput { width: 100%; resize: vertical; min-height: 0; line-height: 1.5; }
  .chat-channels { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
  .chat-channels .fchip.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
  .chat-msgs { border: 1.5px solid var(--line); border-radius: 12px; padding: 10px 12px; height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; background: var(--bg); }
  /* Hetzelfde gesprek, maar in de installatie staat er nog een kop, een
     antwoordveld en een knoppenrij onder. 46vh zou dat van het scherm duwen,
     dus hier meegroeien tot een plafond in plaats van een vaste hoogte. */
  .chat-msgs.sbchat { height: auto; min-height: 120px; max-height: 34vh; }
  .chat-msg { max-width: 88%; }
  .chat-msg .who { font-size: .72rem; font-weight: 700; color: var(--accent-text); }
  .chat-msg .who .when { font-weight: 400; color: var(--muted); margin-inline-start: 6px; }
  .chat-msg .bubble { background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 7px 11px; font-size: .9rem; white-space: pre-wrap; word-break: break-word; }
  .chat-msg.mine { align-self: flex-end; } .chat-msg.mine .bubble { background: var(--accent-50); }
  /* Je eigen naam hoort rechts boven je eigen bel (Sven, 23-08-2026) — de
     bel staat rechts, dus het naamlabel erboven ook. */
  .chat-msg.mine .who { text-align: end; }
  .chat-msg.claude .who { color: var(--claude); }
  .chat-msg.claude .bubble { background: var(--claude-bg); border-color: var(--claude-line); }
  .mention { color: var(--accent-text); font-weight: 700; background: var(--accent-50); border-radius: 5px; padding: 0 3px; }
  .mention.claude { color: var(--claude); background: var(--claude-bg); }
  .vault-item { border: 1.5px solid var(--line); border-radius: 10px; padding: 10px 12px; }
  .vault-item .vhead { display: flex; align-items: center; gap: 8px; }
  .vault-item .vhead b { flex: 1; }
  .vault-item .vrow { display: flex; gap: 8px; align-items: center; font-size: .85rem; margin-top: 4px; }
  .vault-item .vrow .k { color: var(--muted); font-size: .72rem; text-transform: uppercase; width: 76px; flex-shrink: 0; }
  .vault-item .vrow code { background: var(--fill); border-radius: 6px; padding: 2px 8px; word-break: break-all; }
  .vault-timer { font-size: .75rem; color: var(--muted); }
  .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 8px; }
  .stat { background: var(--fill); border-radius: 10px; padding: 10px 12px; text-align: center; }
  .stat b { font-size: 1.25rem; display: block; }
  .stat span { font-size: .7rem; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; }
  table.mini { width: 100%; border-collapse: collapse; font-size: .82rem; }
  table.mini th { text-align: start; color: var(--muted); font-size: .7rem; text-transform: uppercase; padding: 4px 6px; border-bottom: 1px solid var(--line); }
  table.mini td { padding: 5px 6px; border-bottom: 1px solid var(--line); }
  .tokenbox { font-family: ui-monospace, monospace; font-size: .78rem; background: var(--fill); border-radius: 8px; padding: 8px 10px; word-break: break-all; }
  .note { font-size: .78rem; color: var(--muted); }
  /* Een notitie die niet alleen vertelt maar waarschuwt — de briefmeter boven
     zijn grens. Gedempt grijs zou hem laten wegvallen tussen de rest. */
  .note.warn { color: var(--warn); font-weight: 600; }
  .ok { color: var(--ok); font-weight: 700; font-size: .8rem; }

  /* ── De voordeur ────────────────────────────────────────────────
     #login was een smalle kaart in het midden; sinds 01-08-2026 is het de héle
     pagina, met de landingssectie boven en de inlogkaart eronder. Wie al is
     ingelogd ziet dit nooit — showLogin()/enterApp() schakelen nog steeds op
     precies dit ene element. */
  #login { display: block; max-width: none; margin: 0; padding: 0;
           background: none; box-shadow: none; text-align: start; }
  .loginbox { max-width: 400px; margin: 0 auto 48px; background: var(--card); border-radius: var(--r-card);
              padding: 28px; box-shadow: var(--shadow); display: flex; flex-direction: column;
              gap: 14px; text-align: center; scroll-margin-top: 24px; }
  .loginbox h2 span { color: var(--accent-text); }
  #gbtn { display: flex; justify-content: center; }
  .loginbox details { text-align: start; }
  .loginbox summary { font-size: .78rem; color: var(--muted); cursor: pointer; }
  .loginbox input { border: 1.5px solid var(--line); border-radius: 8px; padding: 10px 12px; width: 100%; margin-top: 8px; }
  .loginbox .tbtn { background: var(--ink); color: var(--on-ink); border: none; border-radius: 8px; padding: 9px; font-weight: 700; width: 100%; margin-top: 8px; }
  #driveGate, #countryGate { max-width: 420px; margin: 16vh auto; background: var(--card); border-radius: 14px; padding: 28px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 12px; text-align: center; }
  #driveGate h2 span, #countryGate h2 span { color: var(--accent-text); }
  #driveGate .tbtn, #countryGate .tbtn { background: var(--accent); color: var(--on-accent); border: none; border-radius: 8px; padding: 11px; font-weight: 700; width: 100%; }
  #driveGate .tbtn:disabled, #countryGate .tbtn:disabled { opacity: .6; }
  #countryGate select { border: 1.5px solid var(--line); border-radius: 8px; padding: 10px 12px; width: 100%; background: var(--card); color: var(--ink); }
  .err { color: var(--danger); font-size: .85rem; }
  .hidden { display: none !important; }

  /* ── Installatie in stappen ─────────────────────────────────── */
  #setup { max-width: 430px; margin: 10vh auto; background: var(--card); border-radius: 14px;
           padding: 26px 24px; box-shadow: var(--shadow); }
  #setup h2 { font-size: 1.1rem; text-align: center; margin-bottom: 4px; }
  #setup p.sub { font-size: .85rem; color: var(--muted); text-align: center; line-height: 1.5; margin-bottom: 16px; }
  #setup label { font-size: .72rem; font-weight: 700; color: var(--muted); text-transform: uppercase;
                 letter-spacing: .05em; display: block; margin: 10px 0 4px; }
  /* Ook textarea. Die stond er niet bij, en de regel die hem elders breed maakt
     (`.dlg textarea.bninput`) geldt alleen binnen een venster — de installatie
     is geen venster. Gevolg: het antwoordveld van de brainstorm viel terug op
     de standaardbreedte van de browser, zo'n twintig tekens, midden in een
     kaart van 430 px. Gezien op 02-08-2026. */
  #setup input, #setup select, #setup textarea { width: 100%; border: 1.5px solid var(--line); border-radius: 8px; padding: 9px 11px; }
  /* ── De profielvraag: het eerste scherm van de installatie ────
     Vier tegels, één tik. Onder elkaar en niet in een raster van twee: op een
     telefoon van 375 blijft er dan 160px per tegel over, en daar past de
     onderregel niet in — dan lees je alleen de kop en is de keuze weer een gok.
     Liggend leest het ook sneller: kop en uitleg naast het pictogram. */
  .profkeuze { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
  .profkaart { display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: start;
               border: 1.5px solid var(--line); background: var(--card); border-radius: 12px;
               padding: 12px 14px; cursor: pointer; transition: border-color .12s ease, background .12s ease; }
  .profkaart:hover, .profkaart:focus-visible { border-color: var(--accent); background: var(--accent-50); }
  .profkaart .pf-ic { font-size: 1.35rem; line-height: 1.2; flex: 0 0 auto; }
  /* min-width: 0 — anders legt de onderregel zijn volle tekstbreedte op als
     ondergrens en wordt de tegel breder dan het scherm. Vandaag vier keer
     tegengekomen; zie de opmerking bij .calmain. */
  .profkaart .pf-tx { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .profkaart .pf-tx b { font-size: .92rem; color: var(--ink); }
  .profkaart .pf-tx span { font-size: .78rem; color: var(--muted); line-height: 1.4; }
  /* Een textarea erft het lettertype niet vanzelf; zonder dit staat het
     antwoordveld in de systeem-monospace terwijl de rest van de kaart dat niet doet. */
  #setup textarea { font: inherit; line-height: 1.5; resize: vertical; }
  #setup .steps { display: flex; gap: 6px; justify-content: center; margin-bottom: 14px; }
  #setup .steps i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
  #setup .steps i.on { background: var(--accent); width: 20px; border-radius: 999px; }
  #setup .steps i.ok { background: var(--ok); }
  #setup .btns { display: flex; gap: 8px; margin-top: 18px; }
  #setup .btns .hbtn { flex: 1; }
  #setup .ok { display: flex; align-items: center; gap: 8px; font-size: .85rem;
               background: var(--ok-bg); color: var(--ok); border-radius: 9px; padding: 9px 11px; }
  #setup .note { font-size: .78rem; color: var(--muted); }

  /* het kaartje op het bord voor wie stappen oversloeg */
  .setupcard { background: var(--card); border: 1.5px solid var(--line); border-radius: 12px;
               padding: 11px 13px; margin: 0 18px 10px; }
  .setupcard .h { display: flex; align-items: center; gap: 8px; font-size: .85rem; font-weight: 600; }
  .setupcard .h .x { margin-inline-start: auto; border: none; background: none; color: var(--muted); }
  .setupcard button.row2 { display: flex; align-items: center; gap: 8px; width: 100%; text-align: start;
                           border: none; background: none; color: var(--ink); font-size: .84rem;
                           padding: 6px 4px; border-radius: 7px; }
  .setupcard button.row2:hover { background: var(--fill); }
  .setupcard .dot { color: var(--accent); }

  /* ── Links in free text + hover preview ─────────────────────── */
  a.ext { color: var(--accent-text); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, var(--accent-text) 35%, transparent); word-break: break-word; }
  a.ext:hover { border-bottom-color: var(--accent-text); }
  .comment a.ext, .bubble a.ext { font-weight: 600; }
  .bubble a.ext { color: inherit; border-bottom-color: currentColor; opacity: .95; }
  #notesLinks { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
  #notesLinks:empty { display: none; }
  #notesLinks a { display: inline-flex; align-items: center; gap: 5px; max-width: 260px; padding: 3px 9px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); font-size: .75rem; color: var(--ink); text-decoration: none; }
  #notesLinks a:hover { border-color: var(--accent); color: var(--accent-text); }
  #notesLinks a span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  #linkPreview { position: fixed; z-index: 9999; width: 320px; max-width: calc(100vw - 24px); background: var(--card); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-menu); overflow: hidden; font-size: .82rem; pointer-events: none; opacity: 0; transform: translateY(4px); transition: opacity .12s ease, transform .12s ease; }
  #linkPreview.show { opacity: 1; transform: translateY(0); }
  #linkPreview .lp-img { display: block; width: 100%; height: 150px; object-fit: cover; background: var(--bg); border-bottom: 1px solid var(--line); }
  #linkPreview .lp-body { padding: 9px 11px 11px; }
  #linkPreview .lp-site { display: flex; align-items: center; gap: 5px; color: var(--muted); font-size: .72rem; margin-bottom: 3px; }
  #linkPreview .lp-site img { width: 13px; height: 13px; border-radius: 3px; }
  #linkPreview .lp-title { font-weight: 700; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  #linkPreview .lp-desc { color: var(--muted); margin-top: 4px; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
  #linkPreview .lp-load { padding: 11px; color: var(--muted); }
  #linkPreview.file .lp-img { height: auto; max-height: 260px; object-fit: contain; padding: 6px; background: var(--card); }

  /* ── Drive file rows: hover thumbnail, click = full viewer ───── */
  .file-item.drive { cursor: pointer; }
  .file-item.drive:hover { background: color-mix(in srgb, var(--accent) 6%, transparent); }
  #fileViewer::backdrop { background: var(--scrim); }
  #fileViewer { border: none; border-radius: 14px; padding: 0; width: min(940px, 94vw); max-width: 94vw; background: var(--card); color: var(--ink); }
  #fileViewer .fv-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); font-size: .9rem; }
  #fileViewer .fv-head b { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #fileViewer iframe { display: block; width: 100%; height: min(78vh, 720px); border: 0; }
  /* ── De landingssectie ──────────────────────────────────────────
     Drie kolommen: de hoofdstukken links, het bord in het midden (70% van de
     breedte), en rechts in woorden wat er op dat moment gebeurt. Het middenvak
     draagt zijn eigen lichte tokens — de film is een verlicht scherm, ook als
     de rest van de app op donker staat. Dat is de enige plek waar het thema
     niet meebeweegt met de voorkeur van de gebruiker. */
  #landing { max-width: 1440px; margin: 0 auto; padding: 28px 20px 20px; position: relative; }
  /* ⚠️ Niet `.lp-rij` noemen: die naam is al in gebruik voor de regels binnen de
     panelen van de film (verderop in dit blad), en een tweede regel met
     dezelfde naam overschreef daar stilletjes de uitlijning. */
  .lp-koprij { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
  /* Geen vlak maar een randje: het oranje op dit scherm is de startknop, en
     twee oranje knoppen maken van geen van beide een aanwijzing. */
  .lp-inlog { border: 1px solid var(--line); background: var(--panel); color: var(--ink);
              border-radius: var(--r-pill); padding: 7px 15px; font: inherit; font-size: 13px;
              font-weight: 600; cursor: pointer; }
  /* Op een breed scherm naar de rechterbovenhoek, want daar zoeken mensen hem —
     en daar is ruimte genoeg naast de gecentreerde kop. Op een smal scherm
     blijft hij in de rij bij de taalkeuze staan: rechtsboven liep hij daar
     dwars door de koptekst heen. */
  @media (min-width: 621px) {
    .lp-inlog { position: absolute; top: 22px; inset-inline-end: 20px; z-index: 3; }
  }
  .lp-inlog:hover { border-color: var(--muted); }
  .lp-inlog:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .lp-top { display: flex; flex-direction: column; align-items: center; gap: 10px;
            text-align: center; margin-bottom: 22px; }
  .lp-top .brandmark.big { margin: 0; display: block; }
  /* Het logo is een link naar de voorpagina (07-09-2026): geen onderstreping,
     wél een zichtbare focusring. */
  .lp-logo { display: inline-flex; border-radius: 13px; line-height: 0; }
  .lp-logo:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
  .lp-kop { font-size: 30px; line-height: 1.12; font-weight: 800; margin: 0; text-wrap: balance; }
  .lp-sub { font-size: 14.5px; line-height: 1.55; color: var(--muted); margin: 0; max-width: 60ch; }
  /* ── Voor / na: wat erin gaat en wat eruit komt ──────────────────
     Het bewijs, vóór de rondleiding. Drie kolommen — invoer, naad, uitkomst —
     die onder de 780px onder elkaar vallen en waarbij de naad meekantelt. */
  .lp-vn { max-width: 980px; margin: 0 auto 30px; background: var(--card);
           border: 1px solid var(--line); border-radius: var(--r-card);
           box-shadow: var(--shadow-card); padding: 26px 26px 22px; }
  .lp-vn-toon { display: grid; grid-template-columns: 1fr 92px 1fr; align-items: center; }
  /* ⚠️ `align-content: start` hoort erbij. Zonder die regel rekken de rijen mee
     tot de hoogte van de langste kolom, en dan is de hoogte van de kaart geen
     gevolg van zijn inhoud maar van de foto ernaast — gemeten 03-08-2026: een
     kaart van vijf regels werd 311px hoog. Het uitlijnen van de kolommen
     onderling doet .lp-vn-toon met align-items: center. */
  .lp-vn-kol { display: grid; gap: 12px; justify-items: center; align-content: start;
               min-width: 0; text-align: center; }
  .lp-vn-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
               color: var(--muted); }
  .lp-vn-kol .note { font-size: 12px; max-width: 34ch; }
  .lp-vn-in, .lp-vn-uit { display: grid; justify-items: center; align-content: start; width: 100%; }

  /* Papier blijft papier, ook op een donker scherm — daarom vaste kleuren en
     geen tokens. Dat is hier een keuze en geen vergeten thema. */
  .lp-foto { background: #fff; color: #16163A; width: 100%; max-width: 300px; text-align: start;
             border-radius: 8px; box-shadow: 0 14px 40px rgba(22,22,58,.18);
             padding: 18px 20px 20px; transform: rotate(-1.6deg); font-size: 12.5px; line-height: 1.5; }
  .lp-foto .briefkop { font-weight: 700; font-size: 14px; letter-spacing: -.01em; margin-bottom: 3px; }
  .lp-foto .briefsub { color: #7C7C99; font-size: 11px; margin-bottom: 12px; }
  .lp-foto .streep { height: 7px; border-radius: 4px; background: #EEEFF6; margin-bottom: 6px; }
  .lp-foto .streep.kort { width: 62%; }
  .lp-foto .feiten { margin-top: 13px; padding-top: 11px; border-top: 1px solid #E6E7F0; display: grid; gap: 4px; }
  .lp-foto .feit { display: flex; justify-content: space-between; gap: 12px; }
  .lp-foto .feit span:first-child { color: #7C7C99; }
  .lp-foto .feit span:last-child { font-weight: 700; font-variant-numeric: tabular-nums; }

  /* Wat de bezoeker zélf intypte, in dezelfde vorm als het papier — anders
     lijkt het alsof er een ándere route in werking treedt. */
  .lp-brief { background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
              padding: 14px 16px; max-width: 300px; width: 100%; text-align: start;
              font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }

  .lp-vn-naad { display: grid; justify-items: center; align-content: center; gap: 8px; height: 100%; }
  .lp-vn-naad .lijn { width: 1px; flex: 1; background: var(--line); min-height: 22px; }
  .lp-vn-naad .bol { width: 32px; height: 32px; border-radius: var(--r-pill);
                     border: 1px solid var(--line); background: var(--card); color: var(--accent-text);
                     display: grid; place-items: center; font-size: 14px; box-shadow: var(--shadow-card); }
  .lp-vn-naad .tijd { font-size: 10px; font-weight: 700; letter-spacing: .06em; color: var(--muted);
                      white-space: nowrap; }

  /* De kaart hergebruikt .task, dus alles wat daar verandert verandert hier
     mee. Eén ding moet wél terug: aan deze kaart valt niet te slepen. */
  .lp-vn-kaart { max-width: 320px; width: 100%; text-align: start; cursor: default; margin: 0; }
  .lp-vn-kaart:active { cursor: default; }
  /* Hier gaat het accent heen: dit regeltje is het hele argument, want het laat
     zien dat het ding je project al kende. */
  .lp-vn-reden { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--line);
                 font-size: 11.5px; line-height: 1.45; color: var(--muted); }
  .lp-vn-reden b { display: block; color: var(--accent-text); font-weight: 700; font-size: 10px;
                   letter-spacing: .04em; text-transform: uppercase; margin-bottom: 2px; }

  /* De vier borden waaruit hij kiest. Zonder deze rij zegt "hij koos Klanten"
     niets: je moet de keuze kunnen zien. */
  .lp-vn-borden { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px;
                  margin: 22px 0 0; }
  .lp-vn-bord { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line);
                border-radius: var(--r-pill); padding: 4px 12px 4px 9px; font-size: 12px;
                font-weight: 600; color: var(--muted); background: var(--card);
                transition: color .15s ease, border-color .15s ease; }
  .lp-vn-bord i { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; opacity: .45;
                  transition: opacity .15s ease; }
  .lp-vn-bord.on { color: var(--ink); border-color: var(--accent); }
  .lp-vn-bord.on i { opacity: 1; }

  .lp-vn-proef { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 16px; }
  .lp-vn-proef input { flex: 1 1 340px; max-width: 460px; min-width: 0;
                       border: 1.5px solid var(--line); border-radius: var(--r-pill);
                       padding: 9px 16px; font-size: 14px; background: var(--card); }
  .lp-vn-go { background: var(--accent); border: 1.5px solid var(--accent); color: var(--on-accent);
              border-radius: var(--r-pill); padding: 9px 20px; font: inherit; font-size: 14px;
              font-weight: 700; cursor: pointer; flex: 0 0 auto; }
  .lp-vn-go:hover:not(:disabled) { background: var(--accent-600); border-color: var(--accent-600); }
  .lp-vn-go:disabled { opacity: .55; cursor: default; }
  .lp-vn-terug { background: none; border: 0; color: var(--muted); font: inherit; font-size: 12.5px;
                 text-decoration: underline; cursor: pointer; flex: 0 0 auto; }
  .lp-vn-terug:hover { color: var(--ink); }
  .lp-vn-uitleg { text-align: center; font-size: 11.5px; margin: 10px 0 0; opacity: .8; }

  /* ── Wachten op de AI ────────────────────────────────────────
     Een lege kaart in dezelfde vorm, die zich vult. Tot 03-08-2026 verbleekte
     hier de vórige kaart — en dan lijkt het antwoord er al te staan terwijl
     het nog moet komen, precies in de seconden waarin iemand beoordeelt of
     dit ding werkt. */
  /* Een gestreepte rand, dezelfde taal als .task.proposal: nog niet definitief.
     Zonder rand zweven de balkjes los op het paneel — het vlak van de kaart is
     var(--card) en dat is precies de kleur van het blok eromheen. */
  .lp-vn-skelet { --pcol: transparent; box-shadow: none;
                  border: 1.5px dashed var(--line); border-inline-start-width: 3px; }
  .lp-vn-skelet .sk { display: block; border-radius: 6px; background: var(--fill); }
  .lp-vn-skelet .sk-titel { height: 13px; width: 92%; margin-bottom: 7px; }
  .lp-vn-skelet .sk-titel.kort { width: 58%; }
  .lp-vn-skelet .sk-chip { height: 15px; border-radius: var(--r-pill); display: inline-block; }
  .lp-vn-skelet .sk-reden { margin-top: 10px; padding-top: 9px; border-top: 1px dashed var(--line);
                            display: grid; gap: 5px; }
  .lp-vn-skelet .sk-regel { height: 9px; width: 100%; }
  .lp-vn-skelet .sk-regel.kort { width: 54%; }
  /* De glans loopt over de balkjes heen. Eén animatie voor alle vier, zodat ze
     als één vlak lezen in plaats van als vier losse dingetjes. */
  .lp-vn-skelet .sk {
    background-image: linear-gradient(90deg, transparent 0%,
      color-mix(in srgb, var(--ink) 9%, transparent) 50%, transparent 100%);
    background-size: 260px 100%; background-repeat: no-repeat;
    animation: lpVnGlans 1.25s linear infinite;
  }
  @keyframes lpVnGlans {
    from { background-position: -260px 0; }
    to   { background-position: calc(100% + 260px) 0; }
  }
  .lp-vn-wacht { display: flex; align-items: center; justify-content: center; gap: 7px;
                 margin-top: 10px; font-size: 12px; color: var(--muted); }
  .lp-vn-wacht .draai { display: inline-block; color: var(--accent-text);
                        animation: lpVnDraai 1s linear infinite; }
  @keyframes lpVnDraai { to { transform: rotate(360deg); } }

  @media (prefers-reduced-motion: reduce) {
    /* Zonder beweging moet het nog steeds te zien zijn dát er gewacht wordt —
       vandaar dat de balkjes blijven staan en alleen het lopen eruit gaat. */
    .lp-vn-skelet .sk { animation: none; background-image: none; }
    .lp-vn-wacht .draai { animation: none; }
    .lp-vn-bord, .lp-vn-bord i { transition: none; }
  }

  @media (max-width: 780px) {
    .lp-vn { padding: 20px 16px 18px; }
    .lp-vn-toon { grid-template-columns: 1fr; }
    /* ⚠️ Expliciet plaatsen, niet `grid-auto-flow: column`. Met automatisch
       plaatsen claimt `.tijd` eerst een eigen kolom en verhuist hij dáárna pas
       naar rij 2 — er blijft dan een gat staan waardoor de bol uit het midden
       schuift en de twee lijnen ongelijk worden. */
    .lp-vn-naad { grid-template-columns: 1fr auto 1fr; align-items: center;
                  height: auto; padding: 12px 0; }
    .lp-vn-naad .lijn { width: 100%; height: 1px; min-height: 0; min-width: 20px; flex: none; }
    .lp-vn-naad .lijn:first-child { grid-area: 1 / 1; }
    .lp-vn-naad .bol { grid-area: 1 / 2; }
    .lp-vn-naad .lijn:last-child { grid-area: 1 / 3; }
    .lp-vn-naad .tijd { grid-area: 2 / 1 / 3 / -1; }
    .lp-foto { transform: none; }
    .lp-vn-proef input { flex: 1 1 100%; max-width: none; }
    .lp-vn-go { flex: 1 1 100%; }
  }

  /* Alleen voor voorleessoftware: het woord "Taal" naast het wereldbolletje.
     Wegstoppen met display:none zou het óók voor de voorlezer wegnemen. */
  .sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
        overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
  .lp-taal { display: inline-flex; align-items: center; gap: 6px; margin-top: 2px;
             border: 1px solid var(--line); border-radius: var(--r-pill); padding: 4px 10px 4px 12px;
             background: var(--panel); cursor: pointer; }
  .lp-taal select { border: 0; background: none; color: var(--ink); font: inherit; font-size: 13px;
                    cursor: pointer; padding: 2px 2px 2px 0; }
  .lp-taal:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* Twee kolommen sinds 02-08-2026: de hoofdstukken en het toneel. Het verhaal
     stond in een derde kolom rechts en zit nu als ondertiteling ín het beeld,
     dus het toneel krijgt die ruimte erbij — precies wat de vijf kolommen
     nodig hadden. */
  .lp-film { display: grid; grid-template-columns: 15fr 85fr; gap: 18px; align-items: start; }

  /* ── Links: de hoofdstukken ──────────────────────────────────── */
  .lp-clips { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .lp-clips h2 { font-size: 10.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
                 color: var(--muted); margin: 0 0 6px; padding-inline-start: 10px; }
  .lp-clip { display: flex; align-items: center; gap: 8px; width: 100%; text-align: start;
             background: none; border: 0; border-radius: var(--r-ctrl); cursor: pointer;
             padding: 7px 10px; font-size: 13px; line-height: 1.3; color: var(--muted);
             font-family: inherit; }
  .lp-clip:hover { background: var(--panel); color: var(--ink); }
  .lp-clip .nr { font-size: 10.5px; font-variant-numeric: tabular-nums; opacity: .7; min-width: 1.2em; }
  .lp-clip[aria-current="true"] { color: var(--ink); font-weight: 700; background: var(--panel); }
  /* Het streepje links markeert waar je bent. Bewust niet oranje: het oranje op
     dit scherm is de startknop, en twee oranjes maken van geen van beide een
     aanwijzing. */
  .lp-clip[aria-current="true"] .nr { opacity: 1; color: var(--ink); }
  .lp-voortgang { height: 2px; border-radius: 2px; background: var(--line); overflow: hidden; margin-top: 10px; }
  .lp-voortgang i { display: block; height: 100%; background: var(--ink); opacity: .45;
                    width: 0; transition: width .2s linear; }

  /* ── Midden: het toneel ──────────────────────────────────────── */
  .lp-midden { display: flex; flex-direction: column; align-items: center; gap: 14px; min-width: 0; }
  .lp-stage {
    /* Altijd licht, ongeacht het thema van de gebruiker. */
    --bg: #F6F7FB; --panel: #EEEFF6; --panel-2: #E3E4EE; --card: #fff; --fill: #F3F4FA;
    --ink: #16163A; --muted: #7C7C99; --line: #E6E7F0;
    --accent-50: #FFF1E9; --accent-text: #C2410C;
    --ok: #15803D; --ok-bg: #EFF7EF; --warn: #B45309; --warn-bg: #FDF3E3;
    --info: #1D4ED8; --info-bg: #EEF6FF;
    --claude: #B45309; --claude-bg: #FEF3E2; --claude-line: #F3DCB8;
    /* Een kolom: eerst de band met de ondertiteling, daaronder het bord. De
       poster en de vensterlaag liggen er los overheen (absolute), dus die doen
       aan deze verdeling niet mee. */
    display: flex; flex-direction: column;
    position: relative; width: 100%; aspect-ratio: 16 / 9; min-height: 340px;
    /* Het toneel mag nooit onder de vouw uitsteken. Dat gold al voor lage
       schermen, maar sinds de ondertiteling ónderin het beeld zit is het voor
       élke hoogte gaan gelden: viel de onderrand net buiten beeld, dan miste je
       precies de regel die vertelt wat je ziet. 300px is wat de kop, de
       taalregel met de startknop en de belofte eronder samen innemen. */
    max-height: calc(100svh - 300px);
    background: var(--bg); color: var(--ink); border: 1px solid #DFE1EC;
    border-radius: var(--r-card); box-shadow: var(--shadow); overflow: hidden;
  }
  /* ── De statische voordeur ──────────────────────────────────
     Ligt precies over het toneel en gaat weg zodra de film soepel kan draaien.
     Exact dezelfde plek en maat, dus er verspringt niets bij de wissel. */
  .lp-poster { position: absolute; inset: 0; z-index: 2; background: var(--bg);
               padding: 14px; overflow-y: auto; transition: opacity .35s ease; }
  .lp-poster.weg { opacity: 0; pointer-events: none; }
  .lp-poster.dicht { display: none; }
  .lp-pgrid { display: grid; gap: 8px; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  .lp-pk { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-ctrl);
           border-inline-start: 3px solid #93C5FD; padding: 8px 10px; min-width: 0;
           display: flex; flex-direction: column; gap: 3px; box-shadow: var(--shadow-card); }
  .lp-pk .nr { font-size: 10px; font-weight: 700; color: var(--muted);
               font-variant-numeric: tabular-nums; }
  .lp-pk b { font-size: 12px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
  .lp-pk span:last-child { font-size: 10.5px; line-height: 1.35; color: var(--muted); }

  /* Vijf kolommen, net als op het echte bord. Auto-tracks en geen vaste `5`:
     verbergt de mediaregel hieronder er twee, dan verdeelt de rest zich vanzelf
     over de breedte in plaats van dat er twee gaten blijven staan. */
  /* Vult wat er onder de ondertitelband overblijft. Niet meer `absolute; inset:0`:
     dan lag hij eronder in plaats van erna, en dekte de band de kolomkoppen af.
     `min-height: 0` hoort erbij — zonder dat weigert een flex-kind te krimpen
     en groeit het toneel buiten zijn eigen hoogte. */
  .lp-bord { flex: 1 1 auto; min-height: 0; display: grid; grid-auto-flow: column;
             grid-auto-columns: 1fr; gap: 10px; padding: 14px; }
  .lp-kolom { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
  .lp-kolom h3 { font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
                 color: var(--muted); margin: 0 0 2px; }
  .lp-kaart { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-ctrl);
              border-inline-start: 3px solid #93C5FD; padding: 7px 9px;
              display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
              box-shadow: var(--shadow-card); }
  .lp-kaart b { flex: 1 1 100%; font-size: 12px; font-weight: 600; line-height: 1.3;
                overflow-wrap: anywhere; }
  .lp-kaart.nieuw { animation: lpIn .22s cubic-bezier(.2,.8,.3,1); }
  /* Een kaartje op pootjes, binnen het toneel. Kleiner dan het botje op het
     echte bord (zie .botje), verder hetzelfde idee. */
  .lp-kaart.loopt { position: relative; }
  .lp-ogen { display: flex; gap: 4px; flex: 1 1 100%; }
  .lp-ogen i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink);
               position: relative; animation: boKnipper 2.6s infinite; }
  .lp-ogen i::after { content: ''; position: absolute; top: 1px; inset-inline-start: 2.5px;
                      width: 2px; height: 2px; border-radius: 50%; background: var(--card); }
  .lp-poot { position: absolute; bottom: -7px; width: 2.5px; height: 8px; border-radius: 2px;
             background: var(--ink); transform-origin: top center; }
  .lp-poot.links { inset-inline-start: 34%; animation: boStap .3s ease-in-out infinite alternate; }
  .lp-poot.rechts { inset-inline-start: 60%; animation: boStap .3s ease-in-out infinite alternate-reverse; }
  .lp-vonken { position: absolute; z-index: 3; pointer-events: none; }
  .lp-vonken i { position: absolute; width: 5px; height: 5px; border-radius: 50%;
                 animation: boVonk .85s cubic-bezier(.15,.7,.3,1) forwards; }
  .lp-kaart.pak { outline: 2px solid var(--ink); outline-offset: 1px; }
  @keyframes lpIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
  .lp-chip { font-size: 9.5px; font-weight: 700; line-height: 1; border-radius: var(--r-pill);
             padding: 3px 7px; background: var(--fill); color: var(--muted); }
  .lp-chip.wie { background: var(--accent-50); color: var(--accent-text); }
  .lp-chip.ai { background: var(--claude-bg); color: var(--claude); }
  .lp-chip.klaar { background: var(--ok-bg); color: var(--ok); }
  .lp-chip.wacht { background: var(--warn-bg); color: var(--warn); }
  .lp-chip.datum { background: var(--info-bg); color: var(--info); }
  .lp-chip.uren { font-variant-numeric: tabular-nums; }

  /* De laag eroverheen: kaartvenster, AI-antwoord, agenda, telefoon. Eén plek,
     want er is er nooit meer dan één tegelijk te zien. */
  .lp-laag { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
             padding: 16px; background: rgba(22,22,58,.28); backdrop-filter: blur(1.5px);
             animation: lpIn .18s ease; }
  .lp-laag.hidden { display: none; }
  .lp-venster { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
                box-shadow: var(--shadow-dlg); width: min(78%, 460px); max-height: 100%;
                overflow: hidden; display: flex; flex-direction: column; }
  .lp-venster header { padding: 9px 12px; border-bottom: 1px solid var(--line);
                       font-size: 12.5px; font-weight: 700; display: flex; gap: 8px; align-items: center; }
  .lp-venster .body { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px;
                      font-size: 11.5px; line-height: 1.45; }
  .lp-regel { display: flex; align-items: center; gap: 7px; color: var(--muted); }
  .lp-regel .vink { width: 13px; height: 13px; border: 1.5px solid var(--line); border-radius: 4px;
                    flex: none; display: grid; place-items: center; font-size: 9px; }
  .lp-regel.af .vink { background: var(--ok-bg); border-color: var(--ok); color: var(--ok); }
  .lp-regel.af span { text-decoration: line-through; }
  .lp-bubbel { border-radius: var(--r-ctrl); padding: 8px 10px; font-size: 11.5px; line-height: 1.45; }
  .lp-bubbel.van-jou { background: var(--fill); color: var(--ink); align-self: flex-end; max-width: 82%; }
  .lp-bubbel.van-ai { background: var(--claude-bg); border: 1px solid var(--claude-line);
                      color: var(--ink); align-self: flex-start; max-width: 88%; }
  .lp-typt { display: inline-flex; gap: 3px; }
  .lp-typt i { width: 4px; height: 4px; border-radius: 50%; background: var(--claude);
               animation: lpTyp 1s infinite; }
  .lp-typt i:nth-child(2) { animation-delay: .15s; }
  .lp-typt i:nth-child(3) { animation-delay: .3s; }
  @keyframes lpTyp { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }
  .lp-balk { height: 6px; border-radius: 3px; background: var(--fill); overflow: hidden; }
  .lp-balk i { display: block; height: 100%; background: var(--ok); width: 0; transition: width .4s ease; }
  .lp-balk.over i { background: var(--danger, #DC2626); }
  .lp-rij { display: flex; justify-content: space-between; gap: 10px; font-size: 11.5px; }
  .lp-rij b { font-variant-numeric: tabular-nums; }
  .lp-agenda { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
  .lp-dag { border: 1px solid var(--line); border-radius: 6px; min-height: 40px; padding: 3px;
            font-size: 9px; color: var(--muted); display: flex; flex-direction: column; gap: 2px; }
  .lp-dag .stip { border-radius: 3px; background: var(--info-bg); color: var(--info);
                  padding: 2px 3px; font-size: 8.5px; font-weight: 700; }
  .lp-lijn { display: flex; flex-direction: column; gap: 5px; }
  .lp-lijn .staaf { height: 13px; border-radius: 4px; background: var(--accent-50);
                    border: 1px solid #F5D3BC; }
  .lp-telefoon { width: 148px; border: 6px solid #16163A; border-radius: 20px; background: var(--card);
                 padding: 8px 7px; display: flex; flex-direction: column; gap: 6px; }
  .lp-telefoon .kop { font-size: 10px; font-weight: 700; text-align: center; }

  /* De enige oranje knop op dit scherm. Staat sinds 02-08-2026 in de kopregel
     naast de taalkeuze en niet meer onder de film: daar hing zichtbaarheid af
     van de hoogte van het scherm, en bij een korte viewport stond hij onder de
     vouw. Iets wat je moet zoeken is geen oproep.
     Iets kleiner dan hij was — hij staat nu naast tekst in plaats van alleen
     onder een bord, en moet de kopregel niet uit balans trekken. */
  .lp-start { background: var(--accent); color: var(--on-accent); border: 0;
              border-radius: var(--r-pill); padding: 9px 20px; font-weight: 700; font-size: 14px;
              cursor: pointer; font-family: inherit; }
  .lp-start:hover { background: var(--accent-600); }
  /* "Geen creditcard, eerste gebruiker gratis" hoort bij de knop, dus vlak
     eronder en gecentreerd onder dezelfde regel. */
  .lp-startnoot { font-size: 12px; color: var(--muted); margin: 10px auto 0; text-align: center; max-width: 760px; }

  /* ── Rechts: wat je ziet, in woorden ─────────────────────────── */
  /* ── Ondertiteling ───────────────────────────────────────────── */
  /* Bovenin, als een band boven het bord — niet eroverheen. Hij stond onderin
     en over het toneel gelegd; daar las je hem pas nadat je het beeld al had
     bekeken, en op een kort scherm viel hij als eerste buiten beeld.
     Daarom een echte laag in de kolom en géén absolute balk: dan duwt hij het
     bord naar beneden in plaats van er kaarten mee af te dekken, en hoeft
     niemand een hoogte gelijk te houden met een tekst die kan aflopen.
     Donkere band met lichte tekst: het toneel is altijd licht, dus dit is wat
     er als ondertiteling van te onderscheiden valt. */
  .lp-ondertitel { position: relative; z-index: 4; flex: 0 0 auto;
                   display: flex; align-items: baseline; gap: 10px;
                   padding: 9px 14px 10px; pointer-events: none;
                   background: #0F121A;
                   border-start-start-radius: inherit; border-start-end-radius: inherit; }
  /* Zolang de poster er nog overheen ligt is er geen film om te ondertitelen.
     Op DOM-volgorde en niet op een vlag in de code: de poster weet zelf wanneer
     hij weg is, en dan hoeft niemand die twee gelijk te houden.
     ⚠️ Geen overgang op deze `opacity`. Hij stond er eerst wel, en toen bleef de
     ondertiteling onzichtbaar: een bevroren overgang (playState "running",
     currentTime 0 — wat een tabblad op de achtergrond doet) houdt de beginwaarde
     vast en wint zelfs van een inline `!important`. Gemeten op 02-08-2026.
     Zichtbaarheid mag nooit van een lopende animatie afhangen; dat is dezelfde
     regel als in js/anim.js. */
  .lp-poster:not(.weg):not(.dicht) ~ .lp-ondertitel { opacity: 0; }
  .lp-ondertitel .tel { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
                        color: rgb(255 255 255 / .55); font-variant-numeric: tabular-nums; }
  .lp-ondertitel p { margin: 0; font-size: 13.5px; line-height: 1.45; font-weight: 600;
                     color: #fff; text-wrap: balance; }
  @media (prefers-reduced-motion: no-preference) {
    /* Elke regel schuift even op zijn plek. Om dezelfde reden als hierboven
       zit er géén opacity in deze animatie: blijft hij hangen op beeld nul, dan
       staat de tekst er alsnog — alleen niet geschoven. Een leesbare regel op de
       verkeerde plek is beter dan een onzichtbare op de goede. */
    .lp-ondertitel p { animation: lpOndIn .28s ease-out; }
  }
  @keyframes lpOndIn { from { transform: translateY(5px) } to { transform: none } }

  /* Staat nu ónder het toneel en alleen voor wie geen film krijgt. Leeg is weg:
     anders houdt een lege aside de ruimte van de flex-gap bezet. */
  .lp-verhaal { min-width: 0; width: 100%; }
  .lp-verhaal:empty { display: none; }
  .lp-verhaal h2 { font-size: 15px; font-weight: 800; margin: 0 0 4px; line-height: 1.25; }
  .lp-verhaal .tel { font-size: 10.5px; color: var(--muted); margin: 0 0 10px;
                     font-variant-numeric: tabular-nums; }
  .lp-verhaal ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
  .lp-verhaal li { font-size: 12.5px; line-height: 1.5; color: var(--muted); opacity: .55;
                   border-inline-start: 2px solid transparent; padding-inline-start: 9px;
                   transition: opacity .15s ease, color .15s ease; }
  .lp-verhaal li.nu { color: var(--ink); opacity: 1; border-inline-start-color: var(--ink); }
  .lp-verhaal li.geweest { opacity: .85; }

  @media (max-width: 1100px) {
    .lp-film { grid-template-columns: 1fr; gap: 14px; }
    /* Het bord eerst: op een smal scherm wil je zien wát het is voordat je een
       lijst met namen leest. */
    .lp-midden { order: -1; }
    /* De hoofdstukken worden een rij chips die opzij schuift. */
    /* Bewust géén scroll-behavior: smooth. Waar zacht schuiven niet werkt,
       slikt het óók het harde zetten van de stand op en blijft de rij staan —
       dan volgt de markering het hoofdstuk niet meer. Springen werkt altijd. */
    .lp-clips { flex-direction: row; overflow-x: auto; gap: 6px; padding-bottom: 4px; }
    .lp-clips h2, .lp-voortgang { display: none; }
    .lp-clip { white-space: nowrap; border: 1px solid var(--line); border-radius: var(--r-pill);
               padding: 6px 12px; font-size: 12px; }
    .lp-verhaal ol { gap: 5px; }
  }
  /* Onder de 900px passen er geen vijf kolommen meer zonder dat de kaarttitels
     in stroken van een paar tekens breken. Dan vallen "Wachten op" en
     "Ooit / misschien" weg — dat zijn de twee waar in de film het minst gebeurt,
     en de regel tekst ernaast blijft vertellen wat er gebeurt. Inbox, Volgende
     en Klaar blijven staan, want dat is de beweging die het verhaal draagt. */
  @media (max-width: 900px) {
    .lp-kolom[data-kolom="waiting"], .lp-kolom[data-kolom="someday"] { display: none; }
  }
  @media (max-width: 620px) {
    #landing { padding: 20px 14px 16px; }
    .lp-kop { font-size: 24px; }
    /* Op een telefoon staat "Inloggen" niet rechtsboven maar in de rij, en dan
       vielen taal, startknop en inloggen alle drie op een eigen regel — drie
       regels boven de film, gemeten op 375px. Nu taal en inloggen naast elkaar
       en de startknop daaronder over de volle breedte: één regel korter, en de
       knop wordt er groter van in plaats van kleiner.
       ⚠️ Deze regel hoort in de bréédte-mediaregel. Hij stond eerst in
       `max-height: 720px` hierboven, en die geldt op een telefoon van 812 hoog
       juist niet — de opmaak was er dus wel en deed niets. */
    .lp-koprij .lp-start { order: 3; width: 100%; }
    .lp-stage { aspect-ratio: 4 / 3; min-height: 300px; }
    .lp-bord { gap: 6px; padding: 9px; }
    .lp-kolom { gap: 6px; }
    .lp-kaart { padding: 6px 7px; }
    .lp-kaart b { font-size: 11px; }
    .lp-chip { padding: 2px 5px; font-size: 9px; }
    .lp-venster { width: 92%; }
    /* Alle tien de functies moeten hier passen zónder te schuiven: de poster
       staat maar even, dus wat je moet scrollen zie je nooit. De omschrijving
       gaat eraf — die staat een stukje lager alsnog, per hoofdstuk. */
    .lp-poster { padding: 9px; }
    .lp-pgrid { gap: 6px; grid-template-columns: repeat(2, 1fr); }
    .lp-pk { padding: 6px 8px; gap: 1px; }
    .lp-pk b { font-size: 11.5px; }
    .lp-pk span:last-child { display: none; }
  }
  /* ── De knop moet zonder scrollen in beeld ───────────────────
     Een startknop waar je eerst naartoe moet scrollen is geen startknop. Op een
     laag scherm — een kleine telefoon, of een laptopvenster dat niet schermvullend
     staat — geeft eerst de kop ruimte terug en daarna het toneel.
     `svh` en niet `vh`: op een telefoon rekent vh de adresbalk mee die er wél
     staat, en dan valt de knop er alsnog net onder. */
  @media (max-height: 720px) {
    #landing { padding-top: 12px; }
    .lp-top { gap: 6px; margin-bottom: 12px; }
    .lp-top .brandmark.big { width: 38px; height: 38px; border-radius: 10px; }
    .lp-kop { font-size: 21px; }
    /* De belofte staat ook in het inlogvenster; op een krap scherm is de kop
       genoeg en telt de ruimte zwaarder. */
    .lp-sub { display: none; }
    .lp-stage { max-height: calc(100svh - 290px); min-height: 170px; }
    .lp-startnoot { font-size: 11px; }
    /* Het toneel is nu lager, dus de poster moet krapper — anders moet je erin
       schuiven, en wat je moet schuiven zie je nooit in de twee tellen dat hij
       er staat. Het nummertje gaat eraf: dat kostte een hele regel per kaart,
       en de hoofdstukkenlijst nummert ze verderop toch al. */
    .lp-poster { padding: 7px; }
    .lp-pgrid { gap: 5px; }
    .lp-pk { padding: 5px 7px; }
    .lp-pk .nr { display: none; }
    .lp-pk b { font-size: 11px; line-height: 1.2; }
    .lp-pk span:last-child { display: none; }
  }
  @media (max-height: 560px) {
    /* Nog lager: dan wordt het merkteken klein en het toneel ook. Niet
       verbergen: sinds 07-09-2026 is het logo de weg terug naar de voorpagina.
       Wat overblijft is de belofte, iets om naar te kijken, en de knop. */
    .lp-top .brandmark.big { width: 28px; height: 28px; border-radius: 8px; }
    .lp-kop { font-size: 18px; }
    .lp-stage { max-height: calc(100svh - 210px); min-height: 120px; }
  }

  /* Wie beweging heeft uitgezet krijgt geen film maar een boek: elk hoofdstuk
     staat stil in zijn eindbeeld, en rechts staan alle regels tegelijk. Je moet
     dan zelf doorklikken. Er gaat niets verloren behalve het vanzelf gaan. */
  @media (prefers-reduced-motion: reduce) {
    .lp-kaart.nieuw, .lp-laag, .lp-typt i { animation: none; }
    .lp-ogen i, .lp-poot { animation: none; }
    .lp-vonken { display: none; }
    .lp-verhaal li { opacity: 1; color: var(--ink); }
  }

  /* ── Aanmelden met een code per mail ────────────────────────────
     Staat onder de Google-knop, met een streep ertussen. Bewust even breed als
     die knop (280px), zodat de twee routes gelijkwaardig ogen — de e-mailroute
     is geen tweede keus maar een andere deur. */
  .loginsep { display: flex; align-items: center; gap: 10px; width: min(280px, 100%);
              margin: 14px auto 10px; color: var(--muted); font-size: 13px; }
  .loginsep::before, .loginsep::after { content: ''; flex: 1; height: 1px; background: var(--line); }
  #mailLogin { display: flex; flex-direction: column; gap: 8px;
               width: min(280px, 100%); margin: 0 auto; }
  #mailLogin input { width: 100%; border: 1.5px solid var(--line); border-radius: var(--r-ctrl);
                     padding: 9px 11px; background: var(--card); color: var(--ink); font: inherit; }
  #mailLogin input:focus { outline: none; border-color: var(--accent); }
  #mailLogin #mlCodeRow { display: flex; flex-direction: column; gap: 8px; }
  /* Zes cijfers uit elkaar: dan lees je terug wat je hebt ingetikt zonder te
     tellen, en zie je meteen of er eentje te veel of te weinig staat. */
  #mailLogin #mlCode { text-align: center; font-size: 1.25rem; font-weight: 700;
                       letter-spacing: .35em; text-indent: .35em; font-variant-numeric: tabular-nums; }
  #mailLogin .note { margin: 2px 0 0; text-align: start; }
  #mailLogin .note.err { color: var(--danger); }

  /* ── De voortgangsbalk ──────────────────────────────────────────
     Eén regel boven het bord: wat er nu open staat, hoe ver je bent. Hij is
     bewust dun en stil — hij begeleidt het werk, hij is niet het werk. Zodra de
     ladder af is verdwijnt hij helemaal (`hidden`), dus hij kost dan ook geen
     hoogte meer. */
  /* ⚠️ Amber en niet groen of oranje — dat is een keuze, geen smaak.
     `--warn` betekent in dit product al "er wacht iets op jou": het gele
     uitroepteken bij de volgende stap draagt hem, en sinds 03-08-2026 ook de
     stip op een menuknop. Eén kleur voor één betekenis, dus deze balk hoort
     erbij. Groen zou "af" zeggen terwijl er juist nog iets ligt, en oranje is
     de kleur van de knop waar je op moet drukken — dan gaat de balk daarmee
     concurreren in plaats van ernaar te wijzen.
     De streep links maakt hem opvallend zonder hem luid te maken: hij begeleidt
     het werk, hij is niet het werk. */
  .ladderbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
               padding: 8px 16px; border-bottom: 1px solid var(--line);
               border-inline-start: 4px solid var(--warn);
               background: var(--warn-bg); font-size: 13px; }
  /* Op amber leest het oranje van --accent-text te zwak; --warn is hier de
     tekstkleur die bij het vlak hoort en in beide thema's contrast haalt. */
  .ladderbar .lb-next b, .ladderbar .lb-step { color: var(--warn); }
  .ladderbar .lb-track i { background: var(--warn); }
  .lb-next { flex: 1 1 auto; min-width: 0; overflow: hidden;
             text-overflow: ellipsis; white-space: nowrap; }
  /* De naam van de stap is een knop naar de uitleg — de enige ingang voor
     sporten die nergens een menu-item hebben. Ziet eruit als tekst met nadruk,
     gedraagt zich als een knop. */
  .lb-next b, .lb-step { color: var(--accent-text); font-weight: 700; }
  .lb-step { border: none; background: none; padding: 0; font: inherit; font-weight: 700;
             cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
  .lb-step:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
  .lb-track { flex: 0 0 120px; height: 6px; border-radius: var(--r-pill);
              background: var(--fill); overflow: hidden; }
  .lb-track i { display: block; height: 100%; background: var(--accent);
                border-radius: var(--r-pill); transition: width .15s; }
  .lb-count { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }
  @media (max-width: 560px) {
    /* Op een telefoon is de kopbalk al vol en staat de kolomnavigatie onderin.
       Twee regels kostte daar 60px; met de meter weg is het er 30. Er gaat
       niets verloren: "5 van 45" zegt hetzelfde als het streepje, en van de
       twee is het getal het enige dat je op die breedte echt leest. */
    .ladderbar { padding: 6px 12px; gap: 8px; }
    .lb-track { display: none; }
  }

  /* ── Wat op jouw ja wacht ───────────────────────────────────────
     Dezelfde amber als de stroken hierboven, want het is dezelfde boodschap:
     hier ligt iets voor je klaar. Klein en zonder tekst — hij staat in de
     kopbalk, waar elke letter breedte kost op een telefoon; het cijfer ís het
     bericht. Ingeschakeld wordt hij vol amber, zodat je ziet waaróm het bord
     ineens weinig laat zien. */
  .wachtbtn { display: inline-flex; align-items: center; gap: 5px; color: var(--warn); }
  .wachtbtn b { font-variant-numeric: tabular-nums; }
  .wachtbtn.on { background: var(--warn-bg); border-color: var(--warn); color: var(--warn);
                 box-shadow: inset 0 0 0 1px var(--warn); }
  .wachtbtn:hover, .wachtbtn.on:hover { border-color: var(--warn); color: var(--warn); }
  /* De zandloper leent de wachtbtn-vorm maar niet de waarschuwingskleur:
     stilstaan is neutraal, lopen is accent — geen alarm. */
  .tijdchip { color: var(--muted); }
  /* De teller op de kaart: dezelfde chipvorm als de andere kaartvelden,
     oranje zolang hij op deze kaart loopt. */
  .tijdkaart { cursor: pointer; font: inherit; color: var(--ink); }
  .tijdkaart.on { border-color: var(--accent); color: var(--accent); }
  .tijdkaart b { font-variant-numeric: tabular-nums; }
  /* Het bordkeuzevenster van de zandloper: één rij per urenbord, het actieve
     bord bovenaan en gemarkeerd. */
  #tijdKiesDlg .tijdrijen { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
  #tijdKiesDlg .tijdrij { display: inline-flex; align-items: center; justify-content: flex-start; gap: 8px; }
  #tijdKiesDlg .tijdrij.hier { border-color: var(--accent); }
  /* ── De doelgroep-pagina (/voor/<slug>) ─────────────────────────
     Het gezicht komt uit de sfeervelden van het dashboard: het beeld staat
     als CSS-var (--voor-beeld, twee lagen: upload + gecureerde terugval —
     een laag die 404't laat de volgende zien), de overlay-gradient houdt de
     tekst leesbaar, en --accent-voor kleurt de startknop. De kleuren óver
     de foto zijn bewust vast: dit is één beeld, geen thema.
     ⚠️ Niets hiervan mag als direct kind in .lp-film hangen (elk kind is
     daar een grid-cel) en zichtbaarheid hangt nergens aan een overgang. */
  .doelgroep-pagina .lp-film, .doelgroep-pagina .lp-profvraag,
  .doelgroep-pagina .lp-profraster, .doelgroep-pagina .lp-hoe { display: none; }
  .doelgroep-pagina .lp-start { background: var(--accent-voor, var(--accent)); }
  .lp-top.lp-voor-held { background-image: var(--voor-overlay), var(--voor-beeld, none);
                         background-size: cover; background-position: center;
                         border-radius: 16px; padding: 46px 20px 54px; }
  .lp-voor-held.voor-donker { --voor-overlay: linear-gradient(rgba(8,9,12,.5), rgba(8,9,12,.78)); color: #fff; }
  .lp-voor-held.voor-licht { --voor-overlay: linear-gradient(rgba(250,250,252,.55), rgba(250,250,252,.88)); color: #14161c; }
  /* De ondertitel erft de heldkleur: --muted op een donkere overlay was onleesbaar. */
  .lp-voor-held .lp-sub { color: inherit; opacity: .88; }
  .doelgroep-pagina .lp-kop { font-size: clamp(1.6rem, 4vw, 2.3rem); max-width: 24ch; margin-inline: auto; }
  .lp-voor-scenario { max-width: 1060px; margin: 26px auto 8px; }
  .lp-voor-scenario h2 { text-align: center; margin-bottom: 14px; }
  .lp-voor-stappen { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
  @media (max-width: 900px) { .lp-voor-stappen { grid-template-columns: 1fr; } }
  .lp-voor-stap { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; background: var(--card); }
  .lp-voor-stap .note { margin-top: 6px; }
  .lp-voor-alle { text-align: center; margin: 20px 0 6px; }
  /* .link is de rode tekstknop (verwijderen, verlaten); een uitgang is geen gevaar. */
  .lp-voor-alle a { color: var(--accent-text); font-size: inherit; }

  /* De bordkeuze van de chatbel leent de rijen van de urenkiezer. */
  #chatKiesDlg .tijdrijen { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
  #chatKiesDlg .tijdrij { display: inline-flex; align-items: center; justify-content: flex-start; gap: 8px; }
  #chatKiesDlg .ck-n { margin-inline-start: auto; min-width: 18px; height: 18px; padding: 0 4px;
                       border-radius: 999px; background: var(--accent); color: #fff;
                       font-size: 11px; line-height: 18px; text-align: center;
                       font-variant-numeric: tabular-nums; }
  .tijdchip.on { background: transparent; border-color: var(--accent); color: var(--accent); }
  .tijdchip.on:hover, .tijdchip:hover { border-color: var(--accent); color: var(--accent); }

  /* ── "Je hebt iets onder de knip" ───────────────────────────────
     Onder de ladderbalk en in dezelfde amber, want het is dezelfde boodschap:
     hier ligt iets voor je klaar. Eén regel hoog — twee zou het bord omlaag
     duwen, en dan is het geen zetje meer maar een banner. */
  .knipstrook { display: flex; align-items: center; gap: 10px;
                padding: 6px 16px; border-bottom: 1px solid var(--line);
                border-inline-start: 4px solid var(--warn);
                background: var(--warn-bg); font-size: 13px; }
  .knipstrook .ks-txt { flex: 1 1 auto; min-width: 0; overflow: hidden;
                        text-overflow: ellipsis; white-space: nowrap; }
  .knipstrook .hbtn { flex: 0 0 auto; padding: 3px 10px; font-size: .78rem; }
  .knipstrook .ks-weg { flex: 0 0 auto; border: none; background: none;
                        color: var(--muted); cursor: pointer; font-size: .9rem;
                        line-height: 1; padding: 4px; }
  .knipstrook .ks-weg:hover { color: var(--ink); }
  @media (max-width: 560px) { .knipstrook { padding: 6px 12px; gap: 8px; } }

  /* ── Gastbalk ───────────────────────────────────────────────────
     Zelfde vorm als de knipstrook hierboven, maar in het accent en zónder
     kruisje: dit is geen zetje dat je kunt wegzetten maar de stand van zaken.
     Wie deze browser deelt, deelt dit bord — dat hoort te blijven staan tot
     iemand zich aanmeldt of vertrekt.
     ⚠️ Niet `position: sticky`. De kopbalk is dat al, en twee plakkende lagen
     boven elkaar eten op een telefoon het halve bord op. */
  .gastbalk { display: flex; align-items: center; gap: 10px;
              padding: 6px 16px; border-bottom: 1px solid var(--line);
              border-inline-start: 4px solid var(--accent);
              background: color-mix(in srgb, var(--accent) 10%, var(--card));
              font-size: 13px; }
  .gastbalk .gb-txt { flex: 1 1 auto; min-width: 0; overflow: hidden;
                      text-overflow: ellipsis; white-space: nowrap; }
  .gastbalk .hbtn { flex: 0 0 auto; padding: 3px 10px; font-size: .78rem; }
  @media (max-width: 560px) {
    .gastbalk { padding: 6px 12px; gap: 8px; }
    /* Op een telefoon telt elke regel: de datum staat in de zin, en "weggaan"
       staat ook in het avatarmenu. */
    .gastbalk #gastWeg { display: none; }
  }

  /* ── Sleepvlak voor bestanden ───────────────────────────────────
     Over álles heen, ook over de kopbalk: je sleept met je hand op de muis en
     moet in één oogopslag zien dat loslaten hier veilig is.
     ⚠️ `pointer-events: none` op het geheel. Het vlak mag geen enkele
     sleepgebeurtenis opvangen — de luisteraars hangen aan window, en een vlak
     dat zelf `dragleave` opwekt laat zichzelf knipperen. */
  .dropzone { position: fixed; inset: 0; z-index: 90; pointer-events: none;
              display: flex; align-items: center; justify-content: center;
              padding: 24px; background: color-mix(in srgb, var(--accent) 12%, var(--scrim)); }
  .dz-kader { display: flex; flex-direction: column; align-items: center; gap: 6px;
              text-align: center; padding: 28px 40px; border-radius: 18px;
              border: 3px dashed var(--accent); background: var(--card);
              box-shadow: var(--shadow); max-width: 420px;
              animation: dzKom .18s ease-out; }
  .dz-icoon { font-size: 2rem; line-height: 1; }
  .dz-kader b { font-size: 1.05rem; }
  @keyframes dzKom { from { transform: scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
  @media (prefers-reduced-motion: reduce) { .dz-kader { animation: none; } }

  /* Er is een níéuwe sport aan de beurt: de balk vraagt vijf seconden aandacht
     en is daarna weer stil. Twee rondes van 2,5s — hetzelfde ritme als het
     wenken elders, zodat het één taal blijft.

     ⚠️ De balk zélf schuift niet. Hij loopt van rand tot rand, en dan komt er
     links een strook leeg te staan die als tekenfout leest. Het vlak licht
     daarom op en de tekst erin doet de gewone wenkbeweging. */
  .ladderbar.lb-wenk { animation: balkwenk 2.5s ease-in-out 2; }
  .ladderbar.lb-wenk .lb-next { --kant: 1; animation: wenk 2.5s ease-in-out 2; }
  [dir="rtl"] .ladderbar.lb-wenk .lb-next { --kant: -1; }
  @keyframes balkwenk {
    0%, 100% { background: var(--warn-bg); }
    45% { background: color-mix(in srgb, var(--warn) 24%, var(--warn-bg)); }
  }
  /* Zonder beweging blijft de oplichtende balk over — die draagt de boodschap
     ook, en dat is precies waarom hij er niet alleen als beweging is. */
  @media (prefers-reduced-motion: reduce) {
    .ladderbar.lb-wenk .lb-next { animation: none; }
  }

  /* ── Nog op slot ────────────────────────────────────────────────
     Gedimd, niet weg: zo blijft de app op elk moment herkenbaar en verspringt
     er niets zodra iets vrijkomt. Het menu-item wordt twee regels — de tweede
     zegt waaróp het wacht. */
  [data-step] { position: relative; }
  .lk-locked { opacity: .5; cursor: default; }
  .lk-locked:hover { background: none; }
  .lk-why { display: block; font-size: 11.5px; line-height: 1.35; color: var(--muted);
            margin-top: 2px; overflow-wrap: anywhere; }
  /* Het gele uitroepteken: hier ben je. `--warn` betekent in de merkrichtlijn
     al "wacht op actie" — geen nieuwe kleur, en zeker geen tweede accent.
     Het is een knop: erop klikken legt uit wat de functie doet en wat er
     dichtblijft als je hem laat liggen. Vandaar ook een zichtbare focusring. */
  /* ── Wat je moet aanraken, wenkt ────────────────────────────
     Eén taal voor alle sporten: het element dat aan de beurt is wipt uit
     zichzelf een klein stukje opzij, met een ring eromheen. Verving op
     03-08-2026 drie losse tekens — een uitroepteken op het element, een stip op
     de menuknop en een zwevende pijl ernaast — die alle drie eerst geduid
     moesten worden.

     De ring is een box-shadow en geen border: die verandert de indeling niet,
     dus er verspringt niets als hij aan- of uitgaat. `--warn` omdat dat token
     in dit product al "er wacht iets op jou" betekent. */
  .lk-hier { --kant: 1; position: relative; z-index: 2;
             box-shadow: 0 0 0 2px var(--warn),
                         0 4px 16px color-mix(in srgb, var(--warn) 40%, transparent);
             animation: wenk 2.6s ease-in-out infinite; }
  [dir="rtl"] .lk-hier { --kant: -1; }
  @keyframes wenk { 0%, 100% { transform: none; }
                    45% { transform: translateX(calc(5px * var(--kant))); } }

  /* ⚠️ Invoervelden en keuzelijsten bewegen niet. Mikken op een tekstvak dat
     onder je cursor wegschuift is vervelend, en je moet er juist ín klikken om
     te typen. Maar een stílle ring was niet genoeg: hij is oranje, net als
     gewone focus, en Sven las hem op 22-08-2026 als "een actief veld" — geen
     nudge. Dus pulseert de ríng (niet het veld): onmiskenbaar, zonder dat het
     doelwit wegschuift. */
  @keyframes wenkRing {
    0%, 100% { box-shadow: 0 0 0 2px var(--warn),
                           0 4px 16px color-mix(in srgb, var(--warn) 40%, transparent); }
    50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--warn) 85%, transparent),
                      0 4px 24px color-mix(in srgb, var(--warn) 60%, transparent); }
  }
  input.lk-hier, textarea.lk-hier, select.lk-hier { animation: wenkRing 1.6s ease-in-out infinite; }

  /* Stilstaan zodra iemand mikt: anders beweegt het doel weg op precies het
     moment dat de cursor er is. */
  .lk-hier:hover, .lk-hier:focus, .lk-hier:focus-within { animation-play-state: paused; }

  @media (prefers-reduced-motion: reduce) {
    /* ⚠️ Zonder pijl en zonder uitroepteken is deze ring voor wie beweging heeft
       uitgezet de énige aanwijzing die overblijft. Hij blijft dus staan; alleen
       het wippen gaat eruit — en de pulserende ring op invoervelden ook
       (input.lk-hier is specifieker dan .lk-hier, dus die moet hier apart). */
    .lk-hier, input.lk-hier, textarea.lk-hier, select.lk-hier { animation: none; }
  }

  .lk-next { font-weight: 700; }
  /* Overgeslagen, maar er staat nog iets achter. Niet gedimd — je mag hem
     gewoon gebruiken — alleen gemarkeerd, want dit is de weg terug. */
  .lk-parked { opacity: 1; }

  /* ── Urenregistratie ────────────────────────────────────────────
     Eén venster voor de teller, het budget en de geboekte regels. De maten
     rekenen op de breekpunten die de rest van de app ook gebruikt: onder 560px
     valt alles onder elkaar, want twee velden naast elkaar worden op een
     telefoon allebei te smal om in te vullen. */
  .tt-running { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
                background: var(--accent-50); border: 1.5px solid var(--accent);
                border-radius: 12px; padding: 12px 14px; }
  /* Vaste breedte en cijfers van gelijke breedte: anders springt de hele regel
     bij elke tik van de klok. */
  .tt-clock { font-size: 1.5rem; font-weight: 700; color: var(--accent-text);
              font-variant-numeric: tabular-nums; flex: 0 0 auto; min-width: 76px; }
  .tt-what { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
  .tt-what b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tt-running .hbtn { flex: 0 0 auto; }
  .tt-longrun { color: var(--danger); }
  .tt-start { display: flex; flex-direction: column; gap: 8px; }
  .tt-start .tt-go { width: 100%; }

  .tt-budget, .tt-team { border: 1.5px solid var(--line); border-radius: 10px;
                         padding: 10px 12px; margin-bottom: 8px; }
  .tt-budget-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .tt-budget-head .dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
  .tt-budget-head b { flex: 1; min-width: 0; overflow-wrap: anywhere; }
  .tt-bar { height: 8px; border-radius: 999px; background: var(--fill); overflow: hidden; margin: 8px 0 6px; }
  .tt-bar i { display: block; height: 100%; background: var(--ok); transition: width .3s; }
  .tt-bar.warn i { background: var(--accent); }
  .tt-bar.over i { background: var(--danger); }
  .tt-warn { font-size: .78rem; font-weight: 700; color: var(--accent-text); }
  .tt-warn.over { color: var(--danger); }

  .tt-listhead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0 6px; }
  .tt-who { margin-inline-start: auto; }
  .tt-rows { display: flex; flex-direction: column; }
  .tt-row { display: flex; align-items: center; gap: 8px; padding: 7px 0;
            border-bottom: 1px solid var(--line); }
  .tt-row.editing { display: block; }
  .tt-day { flex: 0 0 auto; font-size: .74rem; color: var(--muted); min-width: 62px; }
  .tt-dur { flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 44px; }
  .tt-title { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: .88rem; }
  .tt-title, .tt-title .note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tt-money { flex: 0 0 auto; font-variant-numeric: tabular-nums; color: var(--muted); }
  .tt-row .mini { flex: 0 0 auto; border: none; background: none; color: var(--muted);
                  font-size: .8rem; padding: 2px 5px; border-radius: 5px; }
  .tt-row .mini:hover { background: var(--accent-50); color: var(--accent-text); }
  .tt-total { display: flex; gap: 8px; padding: 9px 0; font-variant-numeric: tabular-nums; }
  .tt-total b { flex: 1; }
  .tt-editbox { display: flex; flex-direction: column; gap: 8px; padding: 6px 0 10px; }
  .tt-set { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 10px; }
  .tt-set:first-child { border-top: none; margin-top: 0; padding-top: 0; }
  .tt-set .flbl .dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }
  /* De chip op de kaart: alleen lezen, dus geen randje van een invulveld. */
  .chip-t { display: inline-flex; align-items: center; gap: 5px; font-size: .78rem;
            border-radius: 999px; padding: 3px 10px; background: var(--fill); color: var(--muted); }
  .chip-t.over { background: var(--danger-bg); color: var(--danger); font-weight: 700; }
  @media (max-width: 560px) {
    /* Op een telefoon staat de klok bóven wat je aan het doen bent, en de
       stopknop over de volle breedte — die moet je met een duim kunnen raken. */
    .tt-running { gap: 8px; }
    .tt-what { flex: 1 0 100%; order: 2; }
    .tt-running .hbtn { flex: 1 0 100%; order: 3; }
    .tt-day { min-width: 0; }
    .tt-row { flex-wrap: wrap; }
    .tt-title { flex: 1 0 100%; order: 3; white-space: normal; }
    .tt-title, .tt-title .note { white-space: normal; }
  }

  /* ── Merkteken ──────────────────────────────────────────────── */
  .brandmark { flex-shrink: 0; border-radius: 7px; display: block; }
  .brandmark.big { width: 52px; height: 52px; border-radius: 13px; margin: 0 auto 10px; }

  /* ── Instellingen in stappen ────────────────────────────────── */
  /* Genummerde stappen, één regel per instelling, en alle uitleg in een ⓘ —
     zo past het scherm op een telefoon zonder eindeloos scrollen. */
  .setstep { border-top: 1px solid var(--line); padding-top: 12px; }
  .setstep:first-of-type { border-top: none; padding-top: 0; }
  /* De tabbladwikkels van Instellingen (05-09-2026): zelf een flexkolom met
     dezelfde gap als .dlg, anders zakten de blokken erin op elkaar; en het
     eerste blok van de tweede iedereen-wikkel houdt zijn scheidslijn. */
  .settab-everyone, .settab-builders { display: flex; flex-direction: column; gap: 12px; }
  .settab-builders + .settab-everyone > .setstep:first-of-type { border-top: 1px solid var(--line); padding-top: 12px; }
  .stephead { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
  .stephead b { font-size: .92rem; font-weight: 600; }
  .stepnum { flex: 0 0 22px; height: 22px; border-radius: 50%; background: var(--accent);
             color: var(--on-accent); font-size: .72rem; font-weight: 700;
             display: flex; align-items: center; justify-content: center; }
  .stepnum.done { background: var(--ok); color: var(--on-accent); }
  .stepnum.plain { background: var(--line); color: var(--muted); }
  .frow { display: flex; align-items: center; gap: 8px; margin: 7px 0; flex-wrap: wrap; }
  .frow > select, .frow > input { flex: 1; min-width: 120px; border: 1.5px solid var(--line);
                                  border-radius: 8px; padding: 7px 10px; font-size: .85rem; }
  .frow .flbl { flex: 0 0 132px; font-size: .78rem; color: var(--muted);
                display: flex; align-items: center; gap: 5px; }
  .frow .inline { display: flex; align-items: center; gap: 7px; font-size: .85rem; flex: 1; }
  .frow .inline input { width: 16px; height: 16px; accent-color: var(--accent); }
  @media (max-width: 560px) { .frow .flbl { flex: 0 0 100%; } }
  .advanced { margin-top: 10px; }
  .advanced summary { font-size: .78rem; color: var(--muted); cursor: pointer; }

  /* de ⓘ zelf: aanwijzen of aantikken toont de uitleg */
  .tip { width: 15px; height: 15px; flex: 0 0 auto; border-radius: 50%; border: 1px solid var(--muted);
         color: var(--muted); font-size: .6rem; font-weight: 700; display: inline-flex;
         align-items: center; justify-content: center; cursor: help; position: relative; }
  .tip:hover, .tip:focus { border-color: var(--accent); color: var(--accent); outline: none; }
  /* ⚠️ `fixed` en niet `absolute`. Deze ⓘ's staan in het instellingenvenster, en
     dat scrollt zelf (`overflow: auto`). Een absoluut geplaatst vak dat naar
     bóven opent wordt daar afgeknipt zodra de ⓘ bovenin staat — gemeld
     04-08-2026 bij "Websites", nagemeten: de bovenkant van het vak lag boven de
     bovenkant van het venster. `overflow: auto` knipt een `fixed` kind niet af.
     De plek wordt bij het zweven berekend; zie plaatsTipbox() in js/core.js. */
  .tip .tipbox { display: none; position: fixed; width: 240px;
                 max-height: calc(100vh - 16px); overflow-y: auto;
                 max-width: calc(100vw - 40px); z-index: 50; background: var(--fill);
                 border: 1px solid var(--line); border-radius: 9px; padding: 8px 10px;
                 font-size: .76rem; font-weight: 400; line-height: 1.5; color: var(--ink);
                 text-align: start; box-shadow: var(--shadow-menu); }
  .tip:hover .tipbox, .tip:focus .tipbox { display: block; }

  /* ── Meldingen van de app ───────────────────────────────────── */
  /* Midden op het scherm, oranje kader, anderhalve graad scheef en een korte
     veerbeweging — genoeg om te zien dat het van de app komt en niet van de
     browser. Goed nieuws draait naar links, een vraag naar rechts. */
  /* width/margin expliciet, want de algemene dialog-regel hierboven zet een
     vaste breedte van 560px — dan staat het vlakje links in plaats van midden */
  #popDlg { border: none; background: none; padding: 0; overflow: visible;
            width: max-content; max-width: calc(100vw - 24px); margin: auto; box-shadow: none; }
  #popDlg::backdrop { background: var(--scrim); }
  .popbody { width: min(340px, calc(100vw - 32px)); background: var(--card); color: var(--ink);
             border: 2.5px solid var(--accent); border-radius: 16px; padding: 18px 18px 15px;
             text-align: center; box-shadow: var(--shadow-dlg), 0 0 0 6px color-mix(in srgb, var(--accent) 10%, transparent);
             transform: rotate(-1.5deg); animation: popIn .28s cubic-bezier(.2,1.4,.4,1); }
  @keyframes popIn { from { transform: rotate(-1.5deg) scale(.9); opacity: 0 } to { transform: rotate(-1.5deg) scale(1); opacity: 1 } }
  .popbody.ask { border-color: var(--accent-600); transform: rotate(1.3deg); animation-name: popInAsk; }
  @keyframes popInAsk { from { transform: rotate(1.3deg) scale(.9); opacity: 0 } to { transform: rotate(1.3deg) scale(1); opacity: 1 } }
  .popbody.oops { border-color: var(--danger); box-shadow: var(--shadow-dlg), 0 0 0 6px color-mix(in srgb, var(--danger) 10%, transparent); }
  .popbody .emo { font-size: 1.9rem; display: block; margin-bottom: 6px; }
  .popbody h4 { font-size: .98rem; font-weight: 600; margin-bottom: 5px; }
  .popbody p { font-size: .84rem; line-height: 1.55; color: var(--muted); white-space: pre-wrap; word-break: break-word; }
  .popbody .btns { display: flex; gap: 8px; justify-content: center; margin-top: 14px; flex-wrap: wrap; }
  .popbody .hbtn { flex: 0 1 auto; }
  .popbody.oops .hbtn.primary { background: var(--danger); border-color: var(--danger); }
  /* confetti: alleen bij echt goed nieuws, anders went het en wordt het ruis */
  .confetti { position: fixed; inset: 0; pointer-events: none; z-index: 9999; overflow: hidden; }
  .confetti i { position: absolute; top: -20px; width: 7px; height: 11px; border-radius: 2px;
                animation: confFall 1.9s linear forwards; }
  @keyframes confFall { to { transform: translateY(105vh) rotate(420deg); opacity: .2 } }

  /* ── Leven op het bord ───────────────────────────────────────
     Een kaart die de AI verplaatst loopt er zelf heen; nieuw werk bouwt zich
     op; wat op Klaar landt viert het. Alles hier is een laag erboven — de
     échte kaart staat al goed, zie js/anim.js. Onder 1100px staat het uit:
     daar is geen ruimte om iets te laten lopen. */
  /* Drie lagen, elk met één taak — anders vechten de transformaties om dezelfde
     eigenschap. De buitenste laag verplaatst (dat is de wandeling) en geeft het
     perspectief mee; .bo-lijf kantelt overeind en weer plat, met de onderrand
     als scharnier. Zonder perspectief is dat draaien geen opstaan maar
     platdrukken. Beginstand is plat: hij ligt zoals de kaart op het bord lag. */
  .botje { position: fixed; z-index: 9998; pointer-events: none; perspective: 640px; }
  .bo-lijf { transform-origin: bottom center; transform-style: preserve-3d;
             transform: rotateX(74deg); }
  .bo-kaart { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-ctrl);
              border-inline-start: 3px solid var(--accent); padding: 8px 10px 10px;
              box-shadow: var(--shadow-menu); }
  /* Wiegen, knipperen en stappen doet hij alleen rechtop. Een liggende kaart
     die met zijn ogen knippert is geen kaart meer maar een spook. */
  .botje.staat .bo-kaart { animation: boWieg .34s ease-in-out infinite alternate; }
  .bo-t { font-size: .8rem; font-weight: 600; line-height: 1.25; overflow: hidden;
          display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
  .bo-ogen { display: flex; gap: 6px; margin-bottom: 5px; }
  .bo-ogen i { width: 9px; height: 9px; border-radius: 50%; background: var(--ink);
               position: relative; opacity: 0; transition: opacity .2s ease .12s; }
  .botje.staat .bo-ogen i { opacity: 1; animation: boKnipper 2.6s infinite; }
  /* Het witte puntje maakt van een stip een oog. Zonder dat kijkt het nergens
     naar en is het gewoon een bolletje. */
  .bo-ogen i::after { content: ''; position: absolute; top: 1.5px; inset-inline-start: 4px;
                      width: 3px; height: 3px; border-radius: 50%; background: var(--card); }
  /* Pootjes horen bij rechtop staan. Onder een liggende kaart zijn het losse
     stokjes, dus die trekken zich in zodra hij weer gaat liggen. */
  .bo-poot { position: absolute; bottom: -9px; width: 3px; height: 10px; border-radius: 2px;
             background: var(--ink); transform-origin: top center;
             opacity: 0; transition: opacity .12s ease; }
  .bo-poot.links { inset-inline-start: 32%; }
  .bo-poot.rechts { inset-inline-start: 62%; }
  .botje.staat .bo-poot { opacity: 1; }
  .botje.staat .bo-poot.links { animation: boStap .34s ease-in-out infinite alternate; }
  .botje.staat .bo-poot.rechts { animation: boStap .34s ease-in-out infinite alternate-reverse; }
  @keyframes boStap { from { transform: rotate(-24deg); } to { transform: rotate(24deg); } }
  @keyframes boWieg { from { transform: translateY(0); } to { transform: translateY(-3px); } }
  @keyframes boKnipper { 0%, 92%, 100% { transform: scaleY(1); } 96% { transform: scaleY(.1); } }
  /* Even laten weten dat hij er is; daarna is het weer een gewone kaart. */
  .task.net-aangekomen { animation: boLand .4s cubic-bezier(.2,.8,.3,1); }
  @keyframes boLand { 0% { transform: scale(.94); } 60% { transform: scale(1.03); } 100% { transform: none; } }

  /* Nieuw werk bouwt zich op: eerst een streepje, dan de hele kaart. */
  /* fill-mode both: tijdens de wachttijd (animation-delay, gezet vanuit
     js/anim.js) staat de kaart al ingeklapt in plaats van eerst compleet in
     beeld te springen. */
  .task.bouwt { animation: boBouw .55s cubic-bezier(.2,.8,.3,1) both; transform-origin: top center; }
  .task.bouwt-af { animation: boGlans .7s ease; }
  @keyframes boBouw {
    0%   { transform: scaleY(.06); opacity: .2; }
    45%  { transform: scaleY(1.04); opacity: 1; }
    100% { transform: none; }
  }
  @keyframes boGlans {
    0%   { box-shadow: 0 0 0 0 var(--accent); }
    100% { box-shadow: 0 0 0 7px transparent; }
  }

  /* Het feestje. */
  .task.viert { animation: boJuich .7s cubic-bezier(.2,.8,.3,1); }
  @keyframes boJuich {
    0% { transform: none; } 25% { transform: translateY(-7px) rotate(-2deg); }
    50% { transform: translateY(0) rotate(1.5deg); } 75% { transform: translateY(-3px) rotate(-1deg); }
    100% { transform: none; }
  }
  .vonken { position: fixed; z-index: 9999; pointer-events: none; }
  .vonken i { position: absolute; width: 6px; height: 6px; border-radius: 50%;
              animation: boVonk .9s cubic-bezier(.15,.7,.3,1) forwards; }
  @keyframes boVonk {
    0%   { transform: translate(0,0) scale(1); opacity: 1; }
    100% { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0; }
  }
  /* De high five: twee kaarten leunen naar elkaar toe, met de handen ertussen. */
  .task.five-op { animation: boFiveOp .7s cubic-bezier(.2,.8,.3,1); }
  .task.five-neer { animation: boFiveNeer .7s cubic-bezier(.2,.8,.3,1); }
  @keyframes boFiveOp { 0%, 100% { transform: none; } 45% { transform: translateY(9px) rotate(2.5deg); } }
  @keyframes boFiveNeer { 0%, 100% { transform: none; } 45% { transform: translateY(-9px) rotate(-2.5deg); } }
  .high-five { position: fixed; z-index: 9999; pointer-events: none; font-size: 22px;
               transform: translate(-50%, -50%); animation: boKlap .7s ease forwards; }
  @keyframes boKlap {
    0% { opacity: 0; transform: translate(-50%,-50%) scale(.4); }
    45% { opacity: 1; transform: translate(-50%,-50%) scale(1.25); }
    100% { opacity: 0; transform: translate(-50%,-50%) scale(1); }
  }

  /* Onder 1100px gebeurt er niets — js/anim.js begint er niet eens aan, dit is
     de vangnetregel voor het geval een scherm tijdens een beweging krimpt. */
  @media (max-width: 1099px) {
    .botje, .vonken, .high-five { display: none; }
    .task.bouwt, .task.bouwt-af, .task.viert, .task.five-op, .task.five-neer,
    .task.net-aangekomen { animation: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .botje, .vonken, .high-five { display: none; }
    .bo-kaart, .bo-poot, .bo-ogen i, .bo-lijf { animation: none; }
    .task.bouwt, .task.bouwt-af, .task.viert, .task.five-op, .task.five-neer,
    .task.net-aangekomen { animation: none; }
  }

  /* ── Blok om te plakken, met kopieerknop ────────────────────── */
  .codeblock { position: relative; margin: 8px 0; }
  .codeblock pre { background: var(--fill); border: 1px solid var(--line); border-radius: 9px;
                   padding: 10px 12px; padding-inline-end: 74px; font-family: ui-monospace, monospace;
                   font-size: .78rem; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
                   max-height: 320px; overflow-y: auto; }
  .codeblock .copy { position: absolute; top: 7px; inset-inline-end: 7px; border: 1px solid var(--line);
                     background: var(--card); color: var(--ink); border-radius: 7px;
                     padding: 3px 9px; font-size: .72rem; font-weight: 600; }
  .codeblock .copy:hover { border-color: var(--accent); color: var(--accent-text); }

  /* ── Kleurstalen bij een project ─────────────────────────────── */
  .swatches { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
  .swatch { width: 24px; height: 24px; border-radius: 7px; border: 1.5px solid var(--line); padding: 0; }
  .swatch:hover { transform: scale(1.08); }
  .swatch:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

  /* ── Bord op mobiel: één kolom per scherm ───────────────────── */
  /* Kolommen zijn schermbreed en klikken vast bij het swipen, zodat je nooit
     tussen twee kolommen blijft hangen. De balk onderin zegt waar je bent en
     of er links of rechts nog een kolom staat. */
  /* basis eerst, dan pas de media-query — anders wint deze regel alsnog */
  #boardNav { display: none; position: fixed; left: 50%; transform: translateX(-50%); bottom: 14px; z-index: 6;
              align-items: center; gap: 4px; background: var(--card); border: 1px solid var(--line);
              border-radius: var(--r-pill); padding: 5px 6px; box-shadow: var(--shadow); }
  #boardNav button { border: 0; background: transparent; color: var(--ink); font-size: 1.15rem; line-height: 1;
                     padding: 5px 11px; border-radius: var(--r-pill); }
  #boardNav button:disabled { opacity: .22; }
  #boardNav button:not(:disabled):active { background: var(--accent-50); }
  #navDots { display: flex; align-items: center; gap: 6px; padding: 0 5px; }
  #navDots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); transition: all .15s ease; }
  #navDots i.on { background: var(--accent); width: 18px; border-radius: var(--r-pill); }
  #navLabel { font-size: .78rem; font-weight: 700; color: var(--muted); padding: 0 4px; white-space: nowrap; }
  @media (max-width: 900px) {
    /* Géén scroll-behavior: smooth hier. In combinatie met mandatory snapping
       wordt elke geanimeerde scroll per frame teruggesnapt naar de huidige
       kolom, waardoor de pijlen niets leken te doen. Vegen blijft native
       soepel; de pijlen springen direct. */
    .board { grid-template-columns: repeat(5, calc(100vw - 36px)); scroll-snap-type: x mandatory;
             padding-bottom: 68px; }
    .col { scroll-snap-align: center; }
    #boardNav { display: flex; }
  }

  /* ── De actiebalk op een telefoon ────────────────────────────────
     Onder 560px stond er van alles in de kopbalk dat niet paste: op 375px
     telden we zeven raakvlakken naast elkaar. Wat vertelt wáár je bent blijft
     boven (project ▼ · wacht-op · avatar); wat je dóét staat hier, onder je
     duim. Zie plaatsBalkKnoppen() in js/views.js voor het verhuiswerk.

     Eén balk en niet twee. Het middenstuk (.ab-mid) draagt de kolomnavigatie,
     en die verdwijnt in de kalender en de tijdlijn. Zat ze in een eigen pil
     bóven deze balk, dan schoof de balk bij elke weergavewissel op en neer —
     knoppen die van plaats veranderen zijn de vervelendste soort. Met flex:1
     op een middenstuk dat er altijd staat blijven zoeken links en de plus
     rechts op de millimeter liggen. */
  /* Zwevend, niet vastgeplakt aan de onderrand: dezelfde taal als #boardNav en
     .pickbar, die hier altijd al als pil boven de rand hingen. Een balk die van
     rand tot rand loopt leest als systeemmeubilair van de telefoon zelf en voelt
     daardoor zwaarder dan hij is. Wél nog links en rechts uitgelijnd en niet op
     inhoudsbreedte: het middenstuk krimpt en groeit met de kolomnaam, dus een pil
     op maat zou bij elke veeg een andere breedte hebben. */
  #actiebalk { display: none; position: fixed; inset-inline: 12px;
               bottom: calc(14px + env(safe-area-inset-bottom, 0px)); z-index: 6;
               align-items: center; gap: 8px; background: var(--card);
               border: 1px solid var(--line); border-radius: var(--r-pill);
               box-shadow: var(--shadow); padding: 5px 8px; }
  #actiebalk .ab-mid { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; min-width: 0; }
  /* ⚠️ Een vaste breedte, want het opschrift is het pictogram van de huidige
     weergave — en 📅 is breder dan ▦. Zonder dit schoof de plus 5 pixels op bij
     elke wissel naar de kalender, en dat is precies het soort bewegend
     meubilair waarvoor deze balk bestaat. Nagemeten 16-08-2026. */
  #actiebalk #viewModeBtn { min-width: 48px; display: inline-flex; align-items: center; justify-content: center; }
  /* ⚠️ Een afstammelingsregel en geen klasse die JS erop zet: een menu in deze
     balk moet naar bóven openklappen, en dat mag niet uit de pas kunnen lopen
     met de verhuizing. Zonder dit valt #addMenu (en #viewModeMenu) onder de
     schermrand — en dan wijst de ladderpijl trots naar een menu-item dat je
     niet ziet, want inBeeld() kijkt alleen naar afmeting, niet naar zicht.

     De .menuwrap gaat hier op `position: static`, zodat het menu zich richt naar
     de bálk en niet naar de knop — hetzelfde trucje als #moreMenu in de kaart.
     Anders is de knop het bevattende blok en eindigt `bottom: 100%` bij de
     onderkant van de knop, dus mídden in de balk: nagemeten 16-08-2026 stak het
     weergavemenu er 7 pixels overheen, precies de bovenlucht van de balk.
     Beide menu's hangen aan de rechterkant, want beide knoppen staan daar. */
  #actiebalk .menuwrap { position: static; }
  #actiebalk .menu { top: auto; bottom: calc(100% + 5px);
                     inset-inline-start: auto; inset-inline-end: 8px; }
  @media (max-width: 560px) {
    :root { --balkh: 46px; --balk-onder: env(safe-area-inset-bottom, 0px); --balk-zweef: 14px; }
    #actiebalk { display: flex; }
    /* In de balk is de pil geen pil meer: geen eigen rand, geen eigen schaduw,
       geen eigen plek. syncBoardNav() merkt hier niets van — die meet .col in
       #board en schrijft via id. */
    #boardNav { position: static; transform: none; inset: auto;
                background: transparent; border: 0; box-shadow: none; padding: 0; }
    /* De onderruimte van het bord rekent nu met de balk in plaats van met 68px
       voor een pil die daar niet meer zweeft. */
    .board { padding-bottom: calc(14px + var(--bodem)); }

    /* ── Wat er uit de kopbalk moet, maar pas hier kán ────────────
       Deze twee horen bij het blok rond `header` bovenin. Ze staan hier omdat
       hun basisregels verderop in het blad staan (`.searchwrap` op ~127,
       `.brandmark` op ~1420) en bij gelijke specificiteit de laatste wint. Wie
       ze naar boven verplaatst, ziet ze stil niets doen. */
    /* Het merkje kleurt mee met het project, maar de projectknop ernaast zegt
       hetzelfde mét de naam erbij. Op 375px is dat 28px voor niets. */
    .brandmark { display: none; }
    /* Gesloten neemt het zoeken geen breedte en geen gap meer in de kopbalk: de
       opener staat onderin in de balk. Uitgeklapt bestaat het volop — de
       dubbele klasse (0,2,0) wint van de enkele erboven (0,1,0). */
    .searchwrap { display: none; }
    .searchwrap.open { display: block; position: static; }
  }

  /* ── Rondleiding: cartoon-tekstballonnen ────────────────────── */
  #tour { position: fixed; inset: 0; z-index: 9998; }
  #tourHole { position: absolute; border-radius: 12px; box-shadow: 0 0 0 9999px var(--scrim-strong);
              transition: top .22s ease, left .22s ease, width .22s ease, height .22s ease; pointer-events: none; }
  .toon { position: absolute; width: min(320px, calc(100vw - 32px)); background: var(--card); color: var(--ink);
          border: 3px solid var(--ink); border-radius: 20px; padding: 15px 17px;
          box-shadow: 5px 5px 0 var(--toon-shadow); animation: toonPop .18s ease-out; }
  @keyframes toonPop { from { transform: scale(.94); opacity: 0 } to { transform: scale(1); opacity: 1 } }
  .toon h4 { font-size: 1.02rem; margin-bottom: 5px; }
  .toon p { font-size: .87rem; line-height: 1.5; color: var(--muted); }
  .toon .toonfoot { display: flex; align-items: center; gap: 8px; margin-top: 13px; }
  .toon .step { font-size: .76rem; font-weight: 700; color: var(--muted); margin-inline-end: auto; }
  .toon .tbtn2 { border: 2px solid var(--ink); background: var(--card); border-radius: var(--r-pill);
                 padding: 5px 14px; font-size: .8rem; font-weight: 700; color: var(--ink); }
  .toon .tbtn2.go { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
  /* het staartje: twee driehoeken over elkaar, buitenste in inkt, binnenste wit */
  .toon .tail, .toon .tail::after { position: absolute; width: 0; height: 0; border: 13px solid transparent; }
  .toon .tail::after { content: ''; }
  .toon.below .tail { top: -26px; border-bottom-color: var(--ink); }
  .toon.below .tail::after { top: -10px; left: -13px; border-bottom-color: var(--card); }
  .toon.above .tail { bottom: -26px; border-top-color: var(--ink); }
  .toon.above .tail::after { bottom: -10px; left: -13px; border-top-color: var(--card); }

  /* ── Aanwijspijl ────────────────────────────────────────────── */
  /* Ligt boven de rondleiding (9998) en boven een modaal, want juist dáár moet
     hij een knop kunnen aanwijzen. Vangt geen klikken op: hij wijst naar iets
     wat je moet aanraken, dus hij mag er nooit tussen komen te staan. */
  .wijzer { position: fixed; z-index: 10000; pointer-events: none; display: flex;
            align-items: center; gap: 8px; opacity: 0; transition: opacity .18s ease; }
  .wijzer .pijl { width: 0; height: 0; border: 11px solid transparent; filter: drop-shadow(0 1px 2px rgb(0 0 0 / .25)); }
  /* ⚠️ Geen nowrap: een lange staptip werd één eindeloze regel die links en
     rechts buiten de kaart stak (Svens foto, 22-08-2026). max-content houdt
     korte tips strak als pil; lange wikkelen binnen een maat die altijd op
     het scherm en in de kaart past. */
  .wijzer .wtekst { background: var(--accent); color: var(--on-accent); border-radius: 14px;
                    padding: 6px 12px; font-size: .8rem; font-weight: 700;
                    width: max-content; max-width: min(66vw, 300px); line-height: 1.35;
                    box-shadow: 0 2px 8px rgb(0 0 0 / .2); }
  /* De punt wijst naar het doelwit, dus de gekleurde rand zit aan de kant van
     het doelwit — bij een pijl rechts ervan is dat de linkerrand. */
  .wijzer[data-kant="rechts"] .pijl { border-left-width: 0; border-right-color: var(--accent); }
  .wijzer[data-kant="links"]  { flex-direction: row-reverse; }
  .wijzer[data-kant="links"]  .pijl { border-right-width: 0; border-left-color: var(--accent); }
  .wijzer[data-kant="onder"]  { flex-direction: column; }
  .wijzer[data-kant="onder"]  .pijl { border-top-width: 0; border-bottom-color: var(--accent); }
  .wijzer[data-kant="boven"]  { flex-direction: column-reverse; }
  .wijzer[data-kant="boven"]  .pijl { border-bottom-width: 0; border-top-color: var(--accent); }
  /* Het wippen doet het werk: een stilstaande pijl leest als versiering. */
  .wijzer[data-kant="rechts"] .pijl { animation: wipX 1.1s ease-in-out infinite; }
  .wijzer[data-kant="links"]  .pijl { animation: wipXom 1.1s ease-in-out infinite; }
  .wijzer[data-kant="onder"]  .pijl { animation: wipY 1.1s ease-in-out infinite; }
  .wijzer[data-kant="boven"]  .pijl { animation: wipYom 1.1s ease-in-out infinite; }
  @keyframes wipX   { 0%,100% { transform: translateX(0) } 50% { transform: translateX(-6px) } }
  @keyframes wipXom { 0%,100% { transform: translateX(0) } 50% { transform: translateX(6px) } }
  @keyframes wipY   { 0%,100% { transform: translateY(0) } 50% { transform: translateY(-6px) } }
  @keyframes wipYom { 0%,100% { transform: translateY(0) } 50% { transform: translateY(6px) } }
  @media (prefers-reduced-motion: reduce) {
    .wijzer .pijl { animation: none; }
  }

  /* ── Rechts naar links (Arabisch) ───────────────────────────── */
  /* De opmaak rekent in logische kanten (inline-start/-end), dus dir="rtl" op
     <html> spiegelt de hele app vanzelf. Wat overblijft: pijlpunten wijzen de
     verkeerde kant op, want die tekens spiegelen niet mee. */
  [dir="rtl"] #navPrev, [dir="rtl"] #navNext { transform: scaleX(-1); }

  /* ── Weergaven: wissel, kalender, tijdlijn ──────────────────── */
  /* Alles hieronder staat op dezelfde tokens en breekpunten als het bord.
     Nieuwe kleuren zijn er niet: WAITING is overal een streepjesrand in
     --danger, een voorstel is --claude, en de projectkleur komt via --pcol. */

  .vsw { display: flex; gap: 2px; background: var(--fill); border: 1px solid var(--line);
         border-radius: var(--r-pill); padding: 2px; flex: 0 0 auto; }
  .vsw button { border: 0; background: transparent; color: var(--muted); cursor: pointer;
                border-radius: var(--r-pill); padding: 5px 10px; font-size: .82rem; line-height: 1;
                display: flex; align-items: center; gap: 5px; white-space: nowrap; }
  .vsw button[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: var(--shadow); }
  .vsw.narrow { background: transparent; border: 0; padding: 0; }
  #boardNav, .pickbar { --nav-shadow: var(--shadow); }
  body:not([data-view="board"]) #boardNav { display: none; }

  .calendar, .timeline { padding: 14px 18px 80px; min-height: calc(100vh - 104px); }
  .calbar, .tlbar-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
  .calbar .sp, .tlbar-top .sp { flex: 1; }
  .calttl { font-size: 1rem; min-width: 9ch; text-align: center; }
  .vnotice { color: var(--warn); font-size: .78rem; cursor: help; }
  .vsaved { font-size: .78rem; color: var(--muted); }
  .vsaved .link { border: 0; background: none; color: var(--accent-text); cursor: pointer; padding: 0; font: inherit; }

  /* Kalender: raster links, strook rechts. Onder 900px onder elkaar. */
  /* ⚠️ minmax(0, 1fr) en niet 1fr — dezelfde val als bij .calgrid hieronder, maar
     één niveau hóger, en dáár deed hij pas echt pijn. Onder 900px staan het
     maandraster en het blok "Nog geen datum" in dezelfde ene baan, en de
     automatische ondergrens van een `1fr`-baan is de min-content van zijn
     breedste kind. Een kaart in dat blok zet zijn titel op `nowrap`, dus zijn
     min-content ís de volle titel: gemeten 16-08-2026 op een echt bord duwde
     één kaart van 435px de baan naar 491px op een scherm van 375 — en het
     maandraster groeide mee tot ruim twee keer de schermbreedte. Op een telefoon
     zag je nog drie van de zeven dagen.
     De kaart knipt zijn tekst zelf al af zodra hij een breedte krijgt; hij moet
     alleen niet mogen bepalen wélke breedte dat is. */
  .calmain { display: grid; grid-template-columns: minmax(0, 1fr) 240px; gap: 14px; align-items: start; }
  /* Tweede slot, aan de kant van het kind: als grid-item mag dit blok nooit een
     eigen ondergrens opleggen aan de baan waar het in staat. */
  .park, .parklist { min-width: 0; }
  /* minmax(0, 1fr) en niet 1fr: de standaard-min van een kolom is zijn
     inhoud, dus één lange kaarttitel duwt de hele week scheef. Dezelfde val als
     bij de vensters hierboven — de kaart knipt zijn tekst zelf al af. */
  .calgrid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
  .calhead { font-size: .72rem; color: var(--muted); text-align: center; padding: 2px 0; text-transform: uppercase; }
  .daycell { min-width: 0; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; min-height: 92px;
             padding: 4px; display: flex; flex-direction: column; gap: 3px; position: relative; }
  .daycell.out { opacity: .45; }
  .daycell.today { outline: 2px solid var(--accent); outline-offset: -1px; }
  .daycell.dragover { border-color: var(--accent); background: var(--accent-50); }
  .daycell.armed { border-style: dashed; border-color: var(--accent); cursor: pointer; }
  .dnum { font-size: .72rem; color: var(--muted); text-align: end; }
  .dmore, .dadd { border: 0; background: transparent; color: var(--muted); font-size: .72rem; cursor: pointer; padding: 1px; }
  .dadd { opacity: 0; align-self: center; font-size: 1rem; }
  .daycell:hover .dadd, .dadd:focus-visible { opacity: .5; }
  /* Op touch is er geen hover: daar stond de plus onzichtbaar maar wél
     aantikbaar in elke lege dag — een blinde tik opende een venster. Zelfde
     patroon als de archiefknop in het bordmenu: altijd zichtbaar, gedimd. */
  @media (hover: none) { .dadd { opacity: .45; } }

  /* Eén kaartvorm voor kalender, tijdlijn en de strook. */
  .vcard { display: flex; align-items: center; gap: 4px; background: var(--card); border: 1px solid var(--line);
           border-inline-start: 3px solid var(--pcol, transparent); border-radius: 6px; padding: 3px 5px;
           font-size: .75rem; cursor: pointer; box-shadow: 0 0 0 1px var(--pcol, transparent) inset; }
  .vcard .vt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; min-width: 0; }
  /* ⚠️ Ook dít deel moet kunnen krimpen. Het stond op `nowrap` zonder
     `min-width: 0`, en dan is de automatische ondergrens van een flex-item zijn
     min-content — dus de volle wacht-op-tekst. Gevolg, gezien op een telefoon
     op 16-08-2026: de titel werd weggeknepen tot "👤 …" en de kaart liep alsnog
     buiten zijn vak. Eén regel wacht-op van 60 tekens was genoeg.
     De helft als bovengrens, zodat de titel altijd leesbaar blijft: waaróp je
     wacht is de bijzaak, wát je doet de hoofdzaak. */
  .vcard .vw { color: var(--danger); font-size: .68rem; white-space: nowrap;
               overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; max-width: 50%; }
  /* Zelf ook geen ondergrens opleggen aan de lijst waar hij in staat. */
  .vcard { min-width: 0; }
  .vcard.wait { border: 1.5px dashed var(--danger); background: var(--danger-bg); }
  /* ── Op de kalender vanwege een opvolgdatum ───────────────────
     Dezelfde kaart, andere reden. Een deadline zegt "dit moet dan af", een
     opvolgdatum "dan ga ik erachteraan" — en dat zijn twee afspraken die je
     uit elkaar moet kunnen houden op een dag waar ze allebei staan. Rustiger
     dan een deadline: dit is een herinnering, geen alarm. */
  .vcard.opvolg { border-style: dotted; background: var(--panel); }
  .vcard.opvolg .vgrip { cursor: default; color: var(--accent-text); }
  /* Op de tijdlijn is het een punt van één dag, geen balk. */
  .tlbar.opvolg { background: none; border: 1.5px dotted var(--pcol); }
  .tlbar.opvolg .diamond { color: var(--accent-text); }
  .vcard.proposal { border-color: var(--claude); }
  .vcard.picked { outline: 2px solid var(--accent); }
  .vcard.dragging { opacity: .45; }
  .vgrip { border: 0; background: transparent; color: var(--muted); cursor: grab; padding: 0 2px;
           font-size: .8rem; line-height: 1; flex: 0 0 auto; min-width: 18px; min-height: 18px; }

  .park { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px; }
  .park.dragover, #parkBox.dragover { border-color: var(--accent); background: var(--accent-50); }
  .park label { display: flex; align-items: center; gap: 6px; font-size: .82rem; font-weight: 600; }
  .park .cnt, .tlgroup .cnt { background: var(--fill); border-radius: var(--r-pill); padding: 0 6px; font-size: .72rem; color: var(--muted); }
  .parklist { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
  .daysheet { margin-top: 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px; }
  .daysheet label { display: flex; justify-content: space-between; align-items: center; font-weight: 600; font-size: .85rem; }
  .callegend { margin-top: 10px; font-size: .74rem; }

  /* De balk onderin zolang er een kaart is opgepakt — zelfde vorm als #boardNav.
     Op een telefoon gaat hij bóven de actiebalk staan in plaats van erop:
     --bodem is 0 zolang die balk er niet is, dus dit is één regel voor beide.

     ⚠️ Centreren met twee inzetten en `margin-inline: auto`, en níét met
     `left: 50%` plus een verschuiving terug. Dat laatste stond er tot
     16-08-2026, en dan is de beschikbare ruimte voor een element dat zichzelf
     mag opmeten alles rechts van dat startpunt — dus precies de hálve
     schermbreedte. Een titel die daar niet in past viel om in een smalle kolom,
     en met een rand van 999px werd dat blokje een cirkel. Zo op een telefoon
     gezien: een witte bol midden op de maandkalender. */
  .pickbar { position: fixed; inset-inline: 12px; margin-inline: auto;
             width: fit-content; max-width: calc(100vw - 24px);
             bottom: calc(14px + var(--bodem)); z-index: 6;
             display: flex; align-items: center; gap: 10px; background: var(--card); border: 1px solid var(--line);
             border-radius: var(--r-pill); padding: 6px 12px; box-shadow: var(--shadow-menu); font-size: .82rem; }
  /* Eén regel, en de titel kapt af met puntjes op de píxel in plaats van hard op
     teken 40 — dat sneed midden in een woord ("WhatsApp n"). */
  .pickbar > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .pickbar .hbtn { flex: 0 0 auto; }

  /* Tijdlijn: een grid over dagen, geen pixelrekenwerk. Spiegelt vanzelf in RTL. */
  .tlscroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
  .tlinner { min-width: max-content; }
  .tlruler, .tlrow { display: grid; grid-template-columns: 180px 1fr; align-items: center; }
  .tlname { position: sticky; inset-inline-start: 0; background: var(--panel); z-index: 2; padding: 4px 8px;
            font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
  .tltrack { display: grid; grid-template-columns: repeat(var(--days), var(--daypx)); min-height: 22px; align-items: center; }
  .tltrack.dragover { background: var(--accent-50); }
  .tlruler { border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 3; background: var(--panel); }
  .tlday { font-size: .62rem; color: var(--muted); text-align: center; padding: 3px 0; overflow: hidden; }
  .tlday.today { color: var(--accent-text); font-weight: 700; }
  .tlday.mstart { border-inline-start: 1px solid var(--line); }
  .tlbar { height: 14px; border-radius: 7px; background: var(--pcol); position: relative; cursor: pointer; }
  .tlbar.due { background: transparent; display: flex; align-items: center; justify-content: center; }
  .tlbar.due .diamond { color: var(--pcol); font-size: .8rem; }
  .tlbar.open { mask-image: linear-gradient(to right, #000 65%, transparent); }
  .tlbar.over { background: var(--danger); }
  .tlbar.wait { background: repeating-linear-gradient(45deg, var(--pcol) 0 4px, transparent 4px 8px); border: 1px dashed var(--danger); }
  .tlbar .clipmark { position: absolute; inset-inline-start: -2px; top: -3px; color: var(--muted); font-size: .7rem; }
  .tlgroup summary { display: flex; align-items: center; gap: 6px; padding: 5px 8px; font-size: .8rem;
                     font-weight: 600; cursor: pointer; border-top: 1px solid var(--line); }
  .gdot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
  .tlempty, .tlro { padding: 12px; }

  @media (max-width: 900px) {
    /* Ook hier minmax(0, …): dit is precies de baan waarin het maandraster en
       "Nog geen datum" samen komen te staan. Zie de opmerking bij .calmain. */
    .calmain { grid-template-columns: minmax(0, 1fr); }
    .daycell { min-height: 62px; }
    .calendar, .timeline { padding: 12px 10px 80px; }
  }
  @media (max-width: 700px) { .vsw .vl { display: none; } }
  @media (max-width: 560px) {
    /* ⚠️ Hier stond `.viewbtn { max-width: 30vw }` en dat won van de regel in de
       kopbalksectie hierboven — gelijke specificiteit, latere plek. De
       projectnaam is op een telefoon het enige wat nog vertelt wélk bord je
       ziet; die mag de vrije ruimte hebben. Zie de ≤560-regels bij `header`. */
    .vsw button { padding: 4px 7px; }
    .daycell { min-height: 54px; padding: 2px; }
    .vcard { font-size: .7rem; }
    .tlruler, .tlrow { grid-template-columns: 120px 1fr; }
    /* De 80px hierboven was een los getal dat niets wist van wat er onder stond.
       Nu volgt de onderruimte de balk, net als bij het bord. */
    .calendar, .timeline { padding-bottom: calc(14px + var(--bodem)); }
    /* ⚠️ Een harde garantie dat de pagina op een telefoon niet zijwaarts kan
       schuiven. De kalender rékent al goed — het raster staat op
       `repeat(7, minmax(0, 1fr))` en elke kaart knipt zijn eigen titel af — maar
       één toekomstige toevoeging met een vaste breedte is genoeg om de hele
       maand scheef te duwen, en dan zie je het pas op een echt toestel.
       `clip` en niet `hidden`: dat maakt geen schuifbak van dit vak, dus de
       plakkende kopbalk en de tijdlijn met zijn eigen zijwaartse schuif
       (.tlscroll) blijven werken zoals ze werkten. */
    .calendar, .timeline { overflow-x: clip; }
  }

  /* ── "Staat dit er misschien al?" ───────────────────────────── */
  /* Verschijnt in het nieuwe-taakvenster en in het plakscherm. Geen alarm —
     een zachte hint met twee knoppen, want in de meeste gevallen wil je gewoon
     doorgaan met de nieuwe kaart. */
  .simbox { background: var(--warn-bg, var(--fill)); border: 1px solid var(--line);
            border-radius: 8px; padding: 8px 10px; margin: 4px 0; }
  .simhead { font-size: .76rem; color: var(--muted); margin-bottom: 5px; }
  .simrow { display: flex; align-items: center; gap: 6px; padding: 3px 0; }
  .simrow .simt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                  white-space: nowrap; font-size: .82rem; }
  .simrow .mini.primary { background: var(--accent); color: var(--on-accent); border-color: transparent; }
  /* Wat je plakte of deelde, klein ernaast. Een naam als "plak-2026-08-02-2318.png"
     zegt niets; het plaatje zelf zegt in één oogopslag of je het goede te pakken
     had. `contain` en geen `cover`: bij een schermafbeelding is juist de rand
     waar je aan herkent wat het is. */
  .capthumb { flex: 0 0 auto; width: 54px; height: 40px; object-fit: contain;
              border-radius: 5px; border: 1px solid var(--line); background: var(--fill); }
  /* En wat het model er zelf in ziet, vóór de knop die er een kaart van maakt.
     Vandaar dat dit een blok is en geen .note: dit is het antwoord op "heeft hij
     wel naar mijn bon gekeken?" en dat hoort niet als voetnoot te lezen. */
  .capseen { margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--line);
             font-size: .8rem; line-height: 1.5; }
  .capseen b { display: block; color: var(--muted); font-size: .74rem;
               font-weight: 600; margin-bottom: 2px; }
  /* Weet de AI het niet, dan hoort de keuzelijst eruit te springen. Anders lees
     je over de vraag heen en staat het alsnog op het verkeerde bord. */
  select.pickme { border-color: var(--accent); }
  /* Het bijstuurblok staat sinds 04-08-2026 áltijd onder de bordkiezer: je moet
     ook een goed antwoord kunnen corrigeren. Daarom standaard stil — een grijs
     bijzinnetje, geen kader, geen achtergrond. Alleen als de AI het zelf niet
     wist (.unsure) mag het opvallen. Zonder dat verschil leest élk antwoord als
     twijfel, en dan zegt het niets meer. */
  /* Wat er ligt te wachten terwijl de AI kijkt. Stil grijs: het is er om te
     herkennen ("ja, dát bedoelde ik"), niet om te lezen — het antwoord komt
     er zo overheen. Vandaar ook een maximumhoogte: een geplakte mail van drie
     schermen zou het wachtscherm langer maken dan het resultaat. */
  .capwacht { margin-top: 10px; }
  .capwacht-url { word-break: break-all; }
  .capwacht-tekst { margin: 6px 0 0; padding: 8px 10px; background: var(--fill);
                    border-radius: 8px; font-size: .78rem; color: var(--muted);
                    white-space: pre-wrap; word-break: break-word;
                    max-height: 140px; overflow-y: auto; }
  .hintrow { margin: 6px 0; }
  .hintrow label { font-size: .8rem; color: var(--muted); font-weight: 400; }
  .hintrow.unsure label { color: var(--ink); font-weight: 600; }
  .hintrow.unsure .row2 input { border-color: var(--accent); }
  .hintrow .row2 { display: flex; gap: 6px; align-items: center; }
  .hintrow .row2 input { flex: 1; min-width: 0; }
  .hintrow .row2 .hbtn { white-space: nowrap; }
  .hintrow .row2 .hbtn[disabled] { opacity: .5; cursor: default; }

  @media (max-width: 560px) {
    .simrow { flex-wrap: wrap; }
    .simrow .simt { flex: 1 0 100%; }
    /* Een bijlagenregel heeft geen knop achter zich, alleen de grootte. Die
       hoeft dus niet naar een eigen regel — en juist op de telefoon is delen
       de gewone route. */
    .simrow.filerow .simt { flex: 1 1 auto; }
  }

  /* ── Kaarten samenvoegen ────────────────────────────────────── */
  /* Het doel van een sleepbeweging licht op zodra je lang genoeg boven het
     midden hangt. Duidelijk anders dan .dragover op een kolom: dáár gaat het
     om herordenen, hier om samenvoegen. */
  .task.mergetarget { outline: 2px solid var(--accent); outline-offset: 1px;
                      background: var(--accent-50); transform: scale(1.02); }
  .task.merged { opacity: .55; }
  .task.merged .t { text-decoration: none; }

  .mergepair { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0; }
  .mergecard { border: 1px solid var(--line); border-radius: 8px; padding: 8px; min-width: 0; }
  .mergecard.keeps { border-color: var(--ok); }
  .mergecard.goes { border-color: var(--line); opacity: .75; }
  .mergecard .mlabel { font-size: .68rem; text-transform: uppercase; color: var(--muted); margin-bottom: 4px; }
  .mergecard .mn { max-height: 5.4em; overflow: hidden; }
  @media (max-width: 560px) { .mergepair { grid-template-columns: 1fr; } }

  /* ── Bedrijven en klanten ─────────────────────────────────────
     Een dunne laag boven het bord: een naam met een kleur. Zie de opmerking bij
     `groups` in server.js voor waarom hij zo dun is. */
  .grow { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
  .grow .gKleur { flex: 0 0 34px; height: 30px; border: 1.5px solid var(--line); border-radius: 8px; background: var(--card); }
  .grow .gNaam { flex: 1 1 auto; min-width: 0; border: 1.5px solid var(--line); border-radius: 8px;
                 padding: 6px 9px; background: var(--card); color: var(--ink); }
  .grow .note { flex: 0 0 auto; white-space: nowrap; }
  .pgroep .flbl { flex: 0 0 auto; }
  .pgroep select { flex: 1 1 auto; min-width: 0; }
  /* Het kopje boven een groep borden in het projectmenu. */
  .optkop { display: flex; align-items: center; gap: 6px; font-size: .7rem; font-weight: 700;
            color: var(--muted); text-transform: uppercase; letter-spacing: .05em; padding: 9px 8px 3px; }
  .gdot2 { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }

  /* ── Het urenrapport ──────────────────────────────────────────
     Bewust boven de regellijst: die toont maximaal 200 regels en beantwoordt
     "wat heb ik geboekt", dit beantwoordt "hoeveel is het samen". */
  .rapbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
  .rapbar input, .rapbar select { border: 1.5px solid var(--line); border-radius: 8px;
                                  padding: 6px 9px; background: var(--card); color: var(--ink); }
  .raptotaal { display: flex; align-items: baseline; gap: 12px; padding: 8px 0 10px; }
  .raptotaal b { font-size: 1.25rem; }
  .raptotaal span { color: var(--accent-text); font-weight: 700; }
  .raplijst { display: flex; flex-direction: column; }
  .raplijst.klein { margin-top: 8px; opacity: .85; }
  .raprij { display: flex; align-items: center; gap: 10px; padding: 5px 0; border-top: 1px solid var(--line); font-size: .85rem; }
  /* min-width: 0 op de naam — anders duwt een lange bordnaam de bedragen weg. */
  .rapnaam { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .rapgeld { flex: 0 0 auto; font-variant-numeric: tabular-nums; color: var(--muted); }

/* ── Bordrij met archiefknop, in het projectmenu ──────────────── */
/* De knop verschijnt pas bij hover of toetsenbordfocus: hij mag er zijn, maar
   niet naast elke bordnaam om aandacht schreeuwen. Op touch is er geen hover,
   dus daar staat hij altijd — zie de media-query hieronder. */
.optrij { display: flex; align-items: center; gap: 2px; }
.optrij > .opt { flex: 1 1 auto; min-width: 0; }
.optrij .rijact { flex: 0 0 auto; border: 0; background: none; cursor: pointer;
                  padding: 4px 6px; border-radius: 8px; opacity: 0; font-size: 14px;
                  transition: opacity .12s ease; }
.optrij:hover .rijact, .optrij .rijact:focus-visible { opacity: .7; }
.optrij .rijact:hover { opacity: 1; background: var(--fill); }
@media (hover: none) { .optrij .rijact { opacity: .55; } }
/* Een gearchiveerd bord: doorgestreept, met de teller waar de naam stond. */
.optrij.weg .opt.uit { display: flex; align-items: center; gap: 8px; flex: 1 1 auto;
                       min-width: 0; padding: 7px 9px; opacity: .55; }
.optrij.weg .opt.uit > span:nth-child(2) { text-decoration: line-through;
                       overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.optrij.weg .adot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.optrij.weg .aftel { flex: 0 0 auto; font-size: 12px; opacity: .8;
                     font-variant-numeric: tabular-nums; }
.optrij.weg .rijact.terug { opacity: .8; }
/* Bordnaam op één regel. Alleen het label (het span dat rekt), níét het
   kleurbolletje ervoor: dat trof de vorige versie ook, en toen kromp de hele
   knop naar nul en verdwenen alle namen uit het menu. 18-08-2026. */
.optrij > .opt { flex: 1 1 0; min-width: 0; }
.optrij .optlabel { min-width: 0; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ `width: auto` is hier niet cosmetisch. Knoppen in dit menu krijgen
   `width: 100%` van de .opt-regel; zonder deze correctie werd de archiefknop
   539px breed, kreeg de bordnaam 0 px en waren op 18-08-2026 álle namen uit het
   menu verdwenen. Het lag dus niet aan de tekst maar aan de knop ernaast. */
.optrij .rijact { width: auto; }

/* ── Chatbel ──────────────────────────────────────────────────── */
/* Rechtsonder op desktop; onder 560px verhuist hij naar #actiebalk, want daar
   loopt die balk van rand tot rand en zou een zwevende bel er bovenop landen.
   ⚠️ Neutrale vulling met de bordkleur als ring, níét een gevulde cirkel: dan
   staan er twee gekleurde ronde knoppen die allebei "hoofdactie" roepen,
   terwijl de oranje + dat is. Sven, 18-08-2026. */
.chatfab { position: fixed; inset-inline-end: 18px; z-index: 7;
           bottom: calc(18px + var(--bodem, 0px));
           display: flex; align-items: center; gap: 6px;
           width: 52px; height: 52px; justify-content: center;
           border-radius: 999px; cursor: pointer;
           background: var(--card); color: inherit;
           border: 2px solid var(--pcol, var(--line));
           box-shadow: var(--shadow-menu); }
.chatfab:hover { transform: translateY(-1px); }
.chatfab .cf-ic { font-size: 20px; line-height: 1; }
/* De teller. Leeg = geen bolletje: een knop die altijd op nul staat leert je
   hem te negeren. */
.chatfab b { position: absolute; top: -4px; inset-inline-end: -4px; min-width: 18px;
             height: 18px; padding: 0 4px; border-radius: 999px;
             background: var(--accent); color: #fff; font-size: 11px; line-height: 18px;
             text-align: center; font-variant-numeric: tabular-nums; }
.chatfab b:empty { display: none; }
/* Tussen 561 en 900 zweeft #boardNav gecentreerd onderaan; de bel iets hoger,
   dan staan ze naast elkaar in plaats van over elkaar. */
@media (min-width: 561px) and (max-width: 900px) { .chatfab { bottom: 78px; } }
/* In de balk is hij geen zwevende bel meer maar gewoon een icoon. */
#actiebalk .chatfab { position: static; width: auto; height: auto; inset: auto;
                      border: 0; box-shadow: none; background: none; padding: 6px 8px; }
#actiebalk .chatfab b { position: static; margin-inline-start: 2px; }

/* De wachtregel van de AI binnen het chatvenster. In #aiBar heeft .aijob een
   eigen achtergrond en marges die bij een balk onderin horen; hier moet hij
   meelopen met het gesprek. */
#chatWacht:empty { display: none; }
#chatWacht { margin: 6px 0 0; }
#chatWacht .aijob { margin: 0; border-radius: 10px; }

/* Het vinkje "voortaan automatisch" onder de bijstuurrij. Een aparte regel en
   niet in de knoppenrij: het is een instelling, geen actie. */
.capauto { display: flex; align-items: center; gap: 6px; margin-top: 8px; cursor: pointer; }

/* ── Urenvenster: uitleg en wegwijzers ────────────────────────── */
/* De uitlegregel zolang er nog niets geboekt is, en de verwijzing naar waar de
   tarieven staan. Beide een terzijde, geen kop: ze vertellen iets, ze vragen
   niets. */
.tt-uitleg { margin: 8px 0 14px; }
.tt-tarieven { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
               margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.tt-tarieven .hbtn { flex: 0 0 auto; }
/* De andere borden met een budget, achter één regel. */
.tt-meer > summary { cursor: pointer; padding: 6px 0; }
.tt-meer[open] > summary { margin-bottom: 6px; }

/* De actiebalk beweegt mee met het toetsenbord — zie tilActiebalk() in core.js. */
#actiebalk { transition: transform .15s ease; }
  /* Het kiespaneel van de ladder: één rij per aan te zetten ladder, met de
     winst-regel eronder; "past bij jou" markeert de top-3 van je profiel. */
  .kiesrijen { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
  .kiesrij { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; text-align: start; padding: 10px 12px; }
  .kiesrij .kiesnaam { font-weight: 600; }
  .kiesrij .note { font-weight: 400; }
  .kiesfit { color: var(--accent); font-size: .72rem; border: 1px solid var(--accent);
             border-radius: 999px; padding: 1px 7px; margin-inline-start: 6px; font-weight: 600; }
  /* Kluis: AI-badge op een gedeeld item, en de uitklapbare deelblokken. */
  .vault-aibadge { color: var(--accent); font-size: .72rem; border: 1px solid var(--accent);
                   border-radius: 999px; padding: 1px 7px; }
  .vdeel { margin-top: 6px; padding: 8px; border: 1px dashed var(--line); border-radius: 8px; }
  /* ── Profielraster op de voordeur (24-08-2026) ── */
  .lp-prof { max-width: 1060px; margin: 26px auto 0; padding: 0 16px; }
  .lp-profvraag { text-align: center; font-weight: 600; margin-bottom: 12px; }
  /* Zoveel kolommen als er passen: vijf tegels stonden anders als vier plus
     een wees op een tweede rij (analyse 05-09-2026). ⚠️ 190px en niet 200:
     de bak is 1060 − 2×16 = 1028px breed, en vijf kolommen mét vier keer 12px
     tussenruimte passen pas vanaf 5×196. */
  .lp-profraster { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; }
  /* De belofte van de doelgroep als uitkomstregel (06-09-2026); flex:1 houdt
     de knop onderaan, ook als de ene belofte langer is dan de andere. */
  .lp-profwin { margin: 0; font-size: .9rem; flex: 1; }
  /* Fototegels (06-09-2026): de foto loopt tot de rand (negatieve marge tot
     de paddingrand; overflow knipt de hoeken), 3:2 zoals de bron, en een
     vlak in de kaartkleur zolang hij lui laadt — geen wit gat op donker. */
  .lp-proffoto { display: block; width: calc(100% + 28px); max-width: none; margin: -14px -14px 2px;
                 aspect-ratio: 3 / 2; height: auto; object-fit: cover; object-position: center;
                 background: var(--panel-2); }
  .lp-profleer { display: block; text-align: center; text-decoration: none; box-sizing: border-box; color: var(--on-accent); }
  .lp-profleer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  /* Vijf fototegels op één rij vragen meer breedte dan de tekstversie. */
  .voordeur-pagina .lp-prof { max-width: 1320px; }
  @media (max-width: 1100px) and (min-width: 621px) {
    /* Twee kolommen van ±490px: een 3:2-foto werd daar 345px hoog en duwde
       de eerste knoppen onder de vouw van een 768-scherm. Liggender dus. */
    .lp-proffoto { aspect-ratio: 2 / 1; }
    /* Vijf tegels in twee kolommen laat de laatste alleen staan: die neemt
       de hele rij, met een liggend beeld in plaats van een 3:2-blok. */
    .lp-profkaart:last-child:nth-child(odd) { grid-column: 1 / -1; }
    .lp-profkaart:last-child:nth-child(odd) .lp-proffoto { aspect-ratio: auto; height: 180px; }
  }
  @media (max-width: 620px) { .lp-proffoto { aspect-ratio: 2 / 1; } }
  /* Het proefpaneel komt ná de klik in beeld; iets lucht boven de rand. */
  .lp-profpaneel { scroll-margin-top: 16px; }
  @media (max-width: 1100px) { .lp-profraster { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 620px) { .lp-profraster { grid-template-columns: 1fr; } }
  .lp-profkaart { display: flex; flex-direction: column; gap: 8px; padding: 14px; overflow: hidden; cursor: pointer;
                  border: 1.5px solid var(--line); border-radius: 14px; background: var(--card); }
  .lp-profkaart.aan { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-50); }
  .lp-profkaart .lp-profkop { display: flex; align-items: center; gap: 8px; font-size: 1.02rem; }
  .lp-profkaart .pf-ic { font-size: 1.4rem; }
  .lp-profpunten { margin: 0; padding: 0 0 0 1.1em; display: flex; flex-direction: column; gap: 5px;
                   font-size: .84rem; flex: 1; }
  .lp-profkaart .lp-start { width: 100%; margin-top: 4px; }
  .lp-profpaneel { margin-top: 14px; padding: 16px; border: 1.5px solid var(--line);
                   border-radius: 14px; background: var(--card); }
  /* De overdracht onder de proef (06-09-2026): het resultaat wordt jouw bord. */
  .lp-bordcta { margin-top: 14px; padding: 14px 16px; border-radius: 12px; background: var(--bg);
                border: 1.5px solid var(--accent-voor, var(--accent)); }
  .lp-bordcta h4 { margin: 0; }
  .lp-bordcta-naam { font-weight: 600; margin: 8px 0 0; }
  .lp-bordcta .lp-start, .lp-bordcta .lp-hoe { margin-top: 10px; }
  .lp-bordcta .note { margin-top: 8px; }
  .doelgroep-pagina .lp-startnoot { margin-top: 14px; }
  .lp-profpaneel h3 { margin-bottom: 8px; }
  .lp-profpaneel textarea, .lp-profpaneel input[type="text"] { width: 100%; }
  .lp-vn-try-row { display: flex; gap: 8px; margin-top: 8px; align-items: center; }
  .lp-vn-try-row input { flex: 1; }
  .lp-mini-bord { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
  .lp-mini-kaart { display: flex; justify-content: space-between; gap: 8px; align-items: center;
                   border: 1px solid var(--line); border-radius: 10px; padding: 7px 11px;
                   background: var(--bg); font-size: .9rem; }
  .lp-mini-kaart .st { font-size: .7rem; color: var(--muted); border: 1px solid var(--line);
                       border-radius: 999px; padding: 1px 7px; white-space: nowrap; }
  .lp-doc { border: 1px dashed var(--line); border-radius: 10px; padding: 9px 12px;
            white-space: pre-wrap; font-size: .86rem; margin-top: 8px; }
  .lp-chat { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
  .lp-chat .bubbel { max-width: 88%; border: 1px solid var(--line); border-radius: 10px;
                     padding: 6px 10px; font-size: .86rem; background: var(--bg); }
  .lp-chat .bubbel.mijn { align-self: flex-end; background: var(--accent-50); }
  /* De hoe-knop naast de start; de afspeelknop midden op de poster. De
     prijzenlink (07-09-2026) leent dezelfde huid, als link in plaats van knop.
     Bewust een eigen klasse: `.doelgroep-pagina .lp-hoe` verbergt de filmknop,
     en de prijzenlink hoort op /voor juist wél te staan. */
  .lp-hoe, .lp-prijslink { border: 1.5px solid var(--line); background: var(--card); border-radius: 999px;
            padding: 10px 16px; cursor: pointer; font: inherit; }
  .lp-prijslink { display: inline-block; text-decoration: none; color: var(--ink); box-sizing: border-box; }
  .lp-prijslink:hover { border-color: var(--muted); }
  .lp-prijslink:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .lp-play { position: absolute; inset: 0; margin: auto; width: 74px; height: 74px;
             border-radius: 50%; border: none; background: var(--accent); color: #fff;
             font-size: 1.7rem; cursor: pointer; box-shadow: 0 6px 22px rgba(0,0,0,.35);
             display: flex; align-items: center; justify-content: center; z-index: 3; }
  .lp-play:hover { filter: brightness(1.08); }
  /* ⚠️ Hier stond een tweede plaatsingsregel voor de poster (weg 06-09-2026).
     De poster staat op regel 1121 al op absolute met inset 0 — dus al een
     verankering voor deze knop. Die tweede regel haalde hem uít de bedekking
     en zette hem in de kolom van het toneel: met beweging uit duwde hij bord
     en ondertiteling permanent uit een bak met overflow:hidden. Niet
     terugzetten. */
  /* De wizard-tegel die op de site al gekozen was. */
  .profkaart.vooraf { border-color: var(--accent); }
  .pf-vooraf { display: block; font-size: .72rem; color: var(--accent-text); margin-top: 4px; }
  /* ── De filmpagina en de voordeur delen de opmaak; alleen wat je ziet
     verschilt (24-08-2026). ── */
  .voordeur-pagina .lp-film { display: none; }
  /* Het slot van de film (06-09-2026): staat in de kolom onder het toneel,
     dus als grid-kind een eigen volle rij — zie de valkuil bij .lp-terug. */
  .lp-einde { grid-column: 1 / -1; width: 100%; max-width: 560px; margin: 18px auto 0;
              display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
  .lp-einde h2 { margin: 0; }
  .lp-einde .note { margin: 0; }
  /* De vloer van de voordeur: één actie, drie stille links. */
  .lp-voet { max-width: 1060px; margin: 34px auto 0; padding: 20px 16px 8px;
             border-top: 1px solid var(--line); display: flex; flex-direction: column;
             align-items: center; gap: 12px; }
  .lp-voetlinks { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; font-size: 13px; }
  .lp-voetlinks a { color: var(--muted); text-decoration: none; }
  .lp-voetlinks a:hover { color: var(--ink); }
  /* Op /hoe eindigt de film al op een knop, en de filmlink wijst naar de
     pagina waar je staat. */
  .hoe-pagina .lp-voetstart, .hoe-pagina .lp-voet-hoe { display: none; }
  /* Een uitnodiging is geen keuzemenu: de tegels zouden je naar /voor/<slug>
     sturen en de code staat alleen in het adres (joinMatch, js/session.js) —
     één klik en de uitnodiging is weg. */
  .join-pagina .lp-prof, .join-pagina .lp-vn { display: none; }
  /* De uitnodiging en de wachtende deling: twee blokken boven de keuze. */
  .lp-join, .lp-gedeeld { max-width: 620px; margin: 0 auto 18px; padding: 16px 18px;
                          border: 1.5px solid var(--accent); border-radius: 14px;
                          background: var(--card); text-align: center; }
  .lp-join h2, .lp-gedeeld .lp-gedeeld-kop { margin: 0 0 6px; font-size: 1.1rem; font-weight: 700; }
  .lp-join .note, .lp-gedeeld .lp-gedeeld-wat { margin: 0 0 12px; }
  .lp-gedeeld-wat { font-size: .9rem; color: var(--muted); word-break: break-word; }
  /* Al ingelogd op de film- of advertentiepagina: één deur naar je eigen bord
     in plaats van twee deuren naar een account dat je al hebt. */
  #lpNaarBord { display: none; text-decoration: none; }
  .lp-ingelogd #lpNaarBord { display: inline-block; }
  /* Sinds 07-09-2026 óók het filmslot en de startknoppen op de prijzenpagina:
     die maken een gastbord, en wie al binnen is heeft er al een. */
  .lp-ingelogd #lpStart, .lp-ingelogd #lpLogin, .lp-ingelogd .lp-voetstart,
  .lp-ingelogd #lpEindeGo, .lp-ingelogd .lp-prijs [data-gast] { display: none; }
  .hoe-pagina .lp-prof, .hoe-pagina .lp-vn, .hoe-pagina #lpHoe { display: none; }
  /* ⚠️ De teruglink is een gríd-kind van .lp-film (15fr 85fr). Zonder eigen
     rij schuift hij alle kinderen één cel op: de hoofdstukken belandden in de
     brede kolom en het toneel in de smalle — de film speelde op 15% van het
     scherm (Sven, 03-09-2026). De link krijgt dus zijn eigen volle rij. */
  .lp-terug { display: block; grid-column: 1 / -1; margin: 0 0 10px; color: var(--accent-text); }
  .voordeur-pagina .lp-terug { display: none; }
  /* ── De prijzenpagina (07-09-2026) ── */
  .lp-prijs { display: none; max-width: 1060px; margin: 8px auto 0; padding: 0 16px; }
  .prijs-pagina .lp-prijs { display: block; }
  .prijs-pagina .lp-prof, .prijs-pagina .lp-vn, .prijs-pagina .lp-film,
  .prijs-pagina .lp-prijslink, .prijs-pagina .lp-voet-prijs { display: none; }
  /* De kaarten hebben elk hun eigen startknop; de kop- en voetknop met het
     sterretje verwijzen naar een prijsnoot die hier niet staat. */
  .prijs-pagina #lpStart, .prijs-pagina .lp-voetstart { display: none; }
  .lp-prijsraster { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: stretch; }
  @media (max-width: 900px) { .lp-prijsraster { grid-template-columns: 1fr; } }
  .lp-prijskaart { display: flex; flex-direction: column; gap: 10px; padding: 18px 18px 16px;
                   border: 1.5px solid var(--line); border-radius: 14px; background: var(--card); }
  .lp-prijskaart h3 { margin: 0; font-size: 1.05rem; }
  .lp-prijsbedrag { margin: 0; font-size: 1.35rem; font-weight: 800; letter-spacing: -.01em; }
  .lp-prijskaart ul { margin: 0; padding-inline-start: 18px; font-size: .9rem; line-height: 1.55; flex: 1; }
  .lp-prijskaart li { margin: 3px 0; }
  .lp-prijskaart .lp-start, .lp-prijskaart .lp-hoe { align-self: flex-start; }
  .lp-prijs-ai { margin: 4px 0 0; }
  .lp-prijsnoot { text-align: center; margin: 14px auto 0; max-width: 760px; font-size: 12.5px; }
  /* De gastnoot onder de kopregel: niet voor wie al binnen is, en niet op een
     uitnodigingspagina (daar blijft de knop de inlogdeur). */
  .lp-gastnoot { margin: 0; font-size: 12.5px; }
  .join-pagina .lp-gastnoot, .lp-ingelogd .lp-gastnoot { display: none; }
  /* De spiegelchip op een kaart die ook op een ander bord staat. */
  .spiegelchip { gap: 4px; }
  .spiegelchip .mini { padding: 0 4px; line-height: 1; }
  /* ── Instellingen als accordeon (23-08-2026) ── */
  details.setstep > summary.stephead { cursor: pointer; list-style: none; margin-bottom: 0; }
  details.setstep > summary.stephead::-webkit-details-marker { display: none; }
  details.setstep > summary.stephead::after { content: '▸'; margin-inline-start: auto; color: var(--muted); transition: transform .15s ease; }
  details.setstep[open] > summary.stephead { margin-bottom: 8px; }
  details.setstep[open] > summary.stephead::after { transform: rotate(90deg); }
  details.setstep > summary.stephead:hover b { color: var(--accent-text, var(--accent)); }
  /* Het wijzigingsvoorstel van de AI op een kaart. */
  .patchbox { border: 1.5px solid var(--accent); border-radius: 12px; padding: 10px 12px;
              margin: 8px 0; background: var(--accent-50); }
  .patchkop { margin-bottom: 6px; }
  .patchrij { display: flex; gap: 10px; padding: 2px 0; align-items: baseline; }
  .patchrij .patchnieuw { white-space: pre-wrap; flex: 1; font-size: .9rem; }
  /* De urenknop op een bedrijfskopje in het projectmenu (23-08-2026). */
  .optkop .guren { margin-inline-start: 6px; padding: 0 6px; border-radius: 6px; opacity: .65; }
  .optkop .guren:hover, .optkop .guren:focus-visible { opacity: 1; background: var(--fill); outline: none; }
  /* ── Borden en bedrijven: twee helften, tarieven onder het vinkje ── */
  .projtabs { margin: 0 0 10px; }
  .projhelp { margin-bottom: 10px; }
  .ptarieven { margin: 6px 0 2px; padding: 8px 10px; border: 1px solid var(--line);
               border-radius: 10px; background: var(--fill); }
  .ptarieven .trate { align-items: center; gap: 8px; }
  .ptarieven .ttsRate { flex: 0 0 92px; text-align: end; }
  .ptarieven .ttsRate.bewaard { border-color: var(--ok); }
  .ptarieven .tavatar { width: 22px; height: 22px; border-radius: 50%; flex: 0 0 auto; }
  .gtijd { margin: 2px 0 0 2px; }
  /* ── Ruimte in Borden en bedrijven (23-08-2026) ──
     De blokken stonden strak op elkaar en tegen de rand; met een lange lijst
     eronder leest dat als één massa in plaats van losse kaarten. */
  #projDlg .dlg { padding: 22px 20px 72px; gap: 14px; }
  .projtabs { margin: 2px 0 4px; }
  .pmodus, .gmodus { align-self: flex-start; margin: 2px 0 6px; }
  #pNieuwBlok, #gNieuw { display: flex; flex-direction: column; gap: 10px;
                         padding: 14px; border: 1.5px solid var(--line);
                         border-radius: 12px; background: var(--fill); }
  #pNieuwBlok .row, #gNieuw .row { gap: 10px; }
  #pNieuwBlok .swatches { margin-top: 2px; }
  #projDlg .proj-list { display: flex; flex-direction: column; gap: 12px; }
  #projDlg .proj-row { padding: 14px 16px; }
  #projDlg .grow { margin-bottom: 4px; }
  #projDlg .gtijd { margin: 0 0 14px 2px; }
  /* ── De aanmaakknop in Borden en bedrijven (23-08-2026) ──
     De ＋-knop stond als grijze pilhelft naast "beheren" en las als een
     filterstand. Het is een handeling: oranje, met de tekst in het accent en
     een echte hover. De beheer-kant blijft rustig, want dat is waar je meestal
     al bent. */
  .pmodus, .gmodus { background: transparent; border: 0; padding: 0; gap: 8px; }
  .pmodus button, .gmodus button { padding: 8px 14px; font-size: .86rem; font-weight: 600;
                                   border: 1.5px solid var(--line); background: var(--card);
                                   border-radius: var(--r-pill); transition: background .15s ease, border-color .15s ease; }
  .pmodus button[data-pmode="new"], .gmodus button[data-gmode="new"] {
    background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
  .pmodus button[data-pmode="new"]:hover, .gmodus button[data-gmode="new"]:hover {
    background: var(--accent-600); border-color: var(--accent-600); }
  /* Aangedrukt: de gekozen kant krijgt de nadruk, de andere zakt terug. */
  .pmodus button[aria-pressed="true"], .gmodus button[aria-pressed="true"] {
    background: var(--panel-2); color: var(--ink); box-shadow: none; }
  .pmodus button[data-pmode="new"][aria-pressed="true"],
  .gmodus button[data-gmode="new"][aria-pressed="true"] {
    background: var(--accent-600); border-color: var(--accent-600); color: var(--on-accent); }
  .pmodus button:focus-visible, .gmodus button:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px; }
  #pArchToon { align-self: flex-start; gap: 8px; }
  #pArchToon .tal { background: var(--panel-2); color: var(--muted); border-radius: var(--r-pill);
                    padding: 1px 8px; font-size: .78rem; font-weight: 700; }
  /* De twee exportvormen: een knop met een regel uitleg eronder, zodat je
     niet hoeft te raden wat je krijgt. */
  .xvorm { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
  .xvorm .hbtn { flex-direction: column; align-items: flex-start; gap: 2px;
                 padding: 12px 14px; text-align: start; }
  .xvorm .hbtn .note { font-weight: 400; }
  /* Een vaste klus draagt een klein rondje: hij komt terug. */
  .task.herhaalt .t::after { content: ' 🔁'; opacity: .55; font-size: .85em; }
  /* ── Weekoverzicht (24-08-2026) ── */
  .revstappen { display: flex; gap: 6px; margin: 2px 0 10px; }
  .revstap { width: 24px; height: 24px; border-radius: 50%; background: var(--panel-2);
             color: var(--muted); display: flex; align-items: center; justify-content: center;
             font-size: .78rem; font-weight: 700; }
  .revstap.nu { background: var(--accent); color: var(--on-accent); }
  .revstap.af { background: var(--ok); color: var(--on-accent); }
  .revlijst { display: flex; flex-direction: column; gap: 8px; max-height: 48vh; overflow-y: auto; }
  .revrij { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
            border: 1.5px solid var(--line); border-radius: 10px; padding: 10px 12px; }
  .revrij.laat { border-color: var(--danger); }
  .revdot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
  .revtitel { background: none; border: 0; color: var(--ink); cursor: pointer;
              font: inherit; text-align: start; padding: 0; flex: 1 1 200px; }
  .revtitel:hover { color: var(--accent-text, var(--accent)); }
  .revbord { flex: 0 0 auto; }
  .revknoppen { display: flex; gap: 4px; flex: 0 0 auto; }
  .badge.laat { background: var(--danger); color: #fff; }
  .revleeg { text-align: center; padding: 24px 0; color: var(--muted); }
  .revklaar { text-align: center; padding: 18px 0; }
  .revgroot { font-size: 1.1rem; font-weight: 700; margin-bottom: 6px; }

/* De verificatiecode in het knopvenster: groot genoeg om in één oogopslag
   over te nemen, met tabular-nums zodat de cijfers niet dansen. Een gebruikte
   code blijft staan maar dooft — je plakt wel eens mis. */
.codeGroot { font-size: 1.5rem; font-weight: 700; letter-spacing: .18em; font-variant-numeric: tabular-nums; }
.codeRij.op .codeGroot { opacity: .45; text-decoration: line-through; }

/* Het postvak: één kolom die het hele vlak mag gebruiken. */
#board.postvak { grid-template-columns: 1fr; }
#board.postvak .col { max-width: 720px; margin-inline: auto; width: 100%; }
.postvakrij .opt .gtal { margin-inline-start: 6px; opacity: .7; }

/* ── De documentenbak: de mindmap ─────────────────────────────── */
/* Beeldvullend op desktop (Sven, 25-08): de mindmap is een werkvlak, geen
   popup. Op een telefoon vult een dialoog het scherm toch al. */
#docsDlg { width: 100vw; height: 100dvh; max-width: none; max-height: none;
           margin: 0; border-radius: 0; border: none; }
#docsDlg .dlg { max-width: none; max-height: none; height: 100%;
                display: flex; flex-direction: column; }
#docsDlg .dvlakwrap { flex: 1; min-height: 0; }
.drij { display: flex; gap: 8px; margin-bottom: 8px; }
.drij input[type="search"] { flex: 1; }
.dchips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.dchip { border: 1.5px solid var(--line); background: var(--card); border-radius: 999px;
         padding: 3px 10px; font-size: .78rem; cursor: pointer; }
.dchip.on { border-color: var(--tagkleur, var(--accent)); box-shadow: inset 0 0 0 1px var(--tagkleur, var(--accent)); }
.dchip span { opacity: .6; }
/* Kolom, overal: het vlak boven, het voorbeeld eronder over de volle
   breedte — op een verticaal scherm is een smalle zijkolom onleesbaar. */
.dvlakwrap { position: relative; display: flex; flex-direction: column;
             gap: 10px; min-height: 340px; }
.dvlak { position: relative; overflow: auto; flex: 1; border: 1px solid var(--line);
         border-radius: 10px; background: var(--card); }
.dvlak svg { position: absolute; inset: 0; pointer-events: none; }
.dvlak svg line { pointer-events: stroke; cursor: pointer; }
.dvast { stroke: var(--accent); stroke-width: 2; }
.dstip { stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 5 5; opacity: .6; }
.dkaart { position: absolute; width: 210px; padding: 8px 10px; border: 1.5px solid var(--line);
          border-radius: 10px; background: var(--bg); cursor: grab; user-select: none;
          touch-action: none; font-size: .84rem; box-shadow: 0 1px 4px rgb(0 0 0 / .12); }
.dkaart b { display: block; overflow-wrap: anywhere; }
.dkaart.sel { border-color: var(--accent); }
.dkaart.linkbron { outline: 2px dashed var(--accent); }
.dkaart.dim { opacity: .25; }
.dtags { display: flex; gap: 3px; margin-top: 5px; }
.dtags i { width: 14px; height: 5px; border-radius: 3px; display: inline-block; }
.dpaneel { width: 100%; border: 1px solid var(--line); border-radius: 10px;
           padding: 12px; overflow: auto; max-height: 45dvh; background: var(--card); }
.dkop { display: flex; justify-content: space-between; align-items: start; gap: 8px; }
.dtagrij { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin: 6px 0; }
.dtag { color: #fff; border-radius: 999px; padding: 2px 8px; font-size: .74rem; }
.dtag button { background: none; border: none; color: #fff; cursor: pointer; padding: 0 0 0 2px; }
.dtekst { white-space: pre-wrap; overflow-wrap: anywhere; font-size: .82rem;
          max-height: 34vh; overflow: auto; background: var(--bg); border-radius: 8px; padding: 8px; }
.daiZin { margin: 0 0 8px; padding: 8px 12px; border-radius: 10px;
          background: var(--card); border: 1px solid var(--line); font-size: .86rem; }
.dstapel { position: absolute; width: 220px; padding: 14px 12px; cursor: pointer;
           border: 2px solid var(--tagkleur, var(--line)); border-radius: 12px;
           background: var(--bg); text-align: start; font-size: .9rem;
           box-shadow: 3px 3px 0 var(--line), 6px 6px 0 var(--card); }
.dstapel span { display: block; color: var(--muted); font-size: .78rem; margin-top: 3px; }
@media (max-width: 700px) {
  .dkaart { width: 160px; font-size: .78rem; }
  .dstapel { width: 170px; }
}

/* De inbox-doorloop: het voorstel onder de titel, knoppen rechts. */
.iarij { display: flex; flex-direction: column; gap: 4px; }
.iakop { display: flex; align-items: center; gap: 8px; }
.iavoorstel { display: flex; align-items: center; justify-content: space-between;
              gap: 8px; font-size: .84rem; padding-inline-start: 17px; flex-wrap: wrap; }
.iavoorstel i { color: var(--muted); font-style: normal; }
.iaknoppen { display: flex; gap: 4px; flex: 0 0 auto; }
.iakies { display: flex; gap: 6px; padding-inline-start: 17px; }
.aiInbox { margin: 0 0 8px; font-size: .8rem; width: 100%; }

/* De wachttip in de inbox-doorloop: aanwezig maar kalm. */
.iatip { font-style: italic; opacity: .75; transition: opacity .4s; }

/* ── De vertaalmodus ──────────────────────────────────────────── */
body.vertmodus * { cursor: crosshair; }
#vertKnop { position: fixed; bottom: 14px; left: 14px; z-index: 300;
            width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid var(--line);
            background: var(--card); font-size: 1.1rem; cursor: pointer;
            box-shadow: 0 2px 8px rgb(0 0 0 / .25); }
#vertBalk { position: fixed; bottom: 14px; left: 62px; z-index: 300;
            display: flex; align-items: center; gap: 8px; padding: 8px 12px;
            border: 1.5px solid var(--accent); border-radius: 999px;
            background: var(--card); font-size: .82rem; }
#vertPaneel { position: fixed; bottom: 64px; left: 14px; z-index: 301;
              width: min(420px, calc(100vw - 28px)); padding: 12px;
              border: 1.5px solid var(--accent); border-radius: 12px;
              background: var(--card); box-shadow: 0 6px 24px rgb(0 0 0 / .3);
              display: flex; flex-direction: column; gap: 8px; }
#vertPaneel .vertDicht { position: absolute; top: 6px; inset-inline-end: 6px; }
#vertPaneel textarea { min-height: 70px; }
.vertSleutel { font-size: .72rem; color: var(--muted); }
.vertKandidaat { display: flex; flex-direction: column; align-items: start; gap: 2px;
                 border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
                 padding: 6px 8px; cursor: pointer; text-align: start; }
.vertKandidaat code { font-size: .7rem; color: var(--muted); }
.admtable td { padding: 2px 8px 2px 0; font-size: .82rem; }

/* In vertaalmodus met Shift ingedrukt: de klik bedient de app — en de
   cursor zegt dat alvast. */
body.vertmodus.vertshift * { cursor: auto; }

/* Het menu onder het vertaalknopje. */
#vertMenu { position: fixed; bottom: 62px; left: 14px; z-index: 301;
            display: flex; flex-direction: column; gap: 2px; padding: 6px;
            border: 1.5px solid var(--line); border-radius: 12px;
            background: var(--card); box-shadow: 0 6px 24px rgb(0 0 0 / .3); }
#vertMenu button, #vertMenu a { border: none; background: none; color: inherit;
            text-align: start; padding: 8px 12px; border-radius: 8px;
            font-size: .86rem; cursor: pointer; text-decoration: none; }
#vertMenu button:hover, #vertMenu a:hover { background: var(--bg); }
.vertuitleg { white-space: pre-line; }

/* De contact-chip op een kaart: een voorstel, dus met een randje uitnodiging. */
.contactchip { cursor: pointer; border: 1.5px dashed var(--accent); border-radius: 999px;
               padding: 2px 10px; }
.contactchip:hover { background: var(--card); }
/* De dicteerknop: in de hoek van zijn veld, en hij gloeit zolang hij luistert. */
.micveld { position: relative; }
.micveld textarea { width: 100%; }
.micknop { position: absolute; right: 8px; bottom: 8px; width: 36px; height: 36px;
           border-radius: 50%; border: 1.5px solid var(--line); background: var(--card);
           font-size: 1rem; cursor: pointer; padding: 0; line-height: 1; }
.micknop.aan { border-color: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 25%, transparent);
               animation: micpuls 1.2s ease-in-out infinite; }
@keyframes micpuls { 50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 12%, transparent); } }
@media (prefers-reduced-motion: reduce) { .micknop.aan { animation: none; } }
/* Het snelmenu bij vasthouden op de plus: drie duimrijen boven de actiebalk. */
#snelMenu { position: fixed; right: 12px; bottom: calc(72px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 2px; z-index: 90;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  padding: 8px; box-shadow: var(--shadow); }
#snelMenu.hidden { display: none; }
#snelMenu button { border: 0; background: none; text-align: left; font-size: 1.05rem;
  padding: 12px 14px; border-radius: 10px; cursor: pointer; color: inherit; }
#snelMenu button:active { background: var(--bg); }
/* Vasthouden mag geen tekstselectie of bel-uitklapper van het systeem geven. */
#newTaskBtn { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* De agent-estafette: de start-vanzelf-vlag als chip, de agentrijen in het
   bordbeheer, en de ketenbanners op de kaart. */
.chip-f.autorun { gap: 4px; cursor: pointer; font-size: .85rem; }
.chip-f.autorun input { margin: 0; }
.agentrij { border: 1px solid var(--line); border-radius: 10px; padding: 8px; margin-top: 8px; }
.agentrij .row { display: flex; gap: 6px; align-items: center; }
.agentrij textarea { width: 100%; margin-top: 6px; }
.prop-banner.keten { border-color: var(--accent); }
