/* moneybirdtool-python — themalaag bovenop missing.css (`static/missing.min.css`).

   De maten en kleuren hieronder zijn die van de **LSR-huisstijl**, zoals de
   oude app ze had (`public/style.css` daar, met de Figma-tokens in de kop).
   Dat is met opzet: de oude app zag eruit zoals hij hoorde te zien, en dit is
   dezelfde huisstijl in een andere dragende laag. Wie hier iets verandert
   verandert dus de huisstijl, niet alleen deze app.

   Wat er niet uit overgenomen is: de lettertypes. `Commissioner` en `Poppins`
   zijn Google Fonts, en `docs/BESLUITEN.md` heeft besloten geen externe
   lettertypes te laden. De systeemletter blijft dus, en dat is het enige
   zichtbare verschil met de oude app -- afgewogen en afgewezen, geen open
   vraag. Komt iemand er ooit op terug, dan gevendored in `static/` en niet
   via een CDN: `SECURE_CSP` staat op `default-src 'self'`.

   Structuur: eerst de tokens, dan de basis, dan het rooster, dan de
   componenten. Canonieke markup staat in `docs/UI.md`. */

/* ── Tokens: de LSR-huisstijl in de variabelen van missing.css ──────────── */

:root {
	/* Geen externe lettertypes; de oude app noemde Commissioner en Poppins
	   met deze zelfde systeemval erachter. */
	--main-font: system-ui, -apple-system, "Segoe UI", sans-serif;
	--secondary-font: var(--main-font);
	--display-font: var(--main-font);
	--mono-font: ui-monospace, monospace;

	/* De maten van de oude app. 13px body is dicht, en dat hoort ook: dit
	   zijn tabelschermen waar je veel in één blik wil zien. */
	--tekst: 13px;
	--tekst-klein: 12px;
	--tekst-meta: 11.5px;
	--kop-1: 18px;
	--kop-2: 14.5px;

	/* Drie tussenruimtes, en niet meer. Er stonden dertien harde waarden in
	   zes maten -- 2, 4, 6, 8, 12 en 14px -- en dat verschil zag niemand,
	   terwijl elke nieuwe regel weer een eigen getal koos. `--gap` van
	   missing.css is 22,4px en dat is voor deze dichtheid te ruim; dit is de
	   schaal eronder. */
	--gap-krap: 4px;
	--gap-klein: 8px;
	--gap-ruim: 12px;

	/* Rondingen zoals de oude app ze had: kaart 10, knop 11, veld 8,
	   modal en inlogkaart 14, chip 9. De skeletcel is van ons -- die had de
	   oude app niet. */
	--border-radius: 10px;
	--interactive-border-radius: 8px;
	--ronding-knop: 11px;
	--ronding-groot: 14px;
	--ronding-chip: 9px;
	--ronding-skelet: 6px;

	/* Merk en accent. Navy is de merkkleur, blauw de linkkleur. */
	--accent: light-dark(#1f3864, #a9c3e8);
	/* De balk heeft eigen tokens en niet `--accent`. In donkere modus is
	   `--accent` lichtblauw -- dat is goed voor koppen op een donkere pagina,
	   maar als balkvulling geeft het een lichte strook boven een donker
	   scherm. De balk hoort in beide modi donker navy te zijn. */
	--balk-bg: light-dark(#1f3864, #16233a);
	--balk-fg: light-dark(#ffffff, #dce6f5);
	/* De linkkleur is een tint donkerder dan de #2e74b5 van de huisstijl, en
	   dat is een contrastcorrectie zoals bij `--faded-fg` hieronder. Nagemeten:
	   #2e74b5 op de paginakleur (#f3f5f8) haalt 4,49:1 waar WCAG AA 4,5 eist --
	   op wit haalt hij het wél (4,91), dus het viel alleen op waar een link
	   direct op de pagina staat: de sorteerlinks in een tabelkop en de weg
	   terug. #2b6da9 brengt dat op 4,98 en op wit op 5,4. Donkere modus
	   raakte het niet: die zat op 7,6. */
	--muted-accent: light-dark(#2b6da9, #6aa6f5);
	--link-fg: light-dark(#2b6da9, #6aa6f5);
	--navy-hover: light-dark(#16294a, #cddcf2);
	--accent-zacht: light-dark(#e7f1fa, #16233a);

	/* Oppervlaktes en tekst. */
	--bg: light-dark(#f3f5f8, #0e1014);
	--fg: light-dark(#1c1e21, #e6e8ec);
	/* Twee namen, één waarde -- en met opzet in deze richting. Een colorway
	   van missing.css (`.plain`, `.ok`, `.warn`, `.bad`, `.info`) zet
	   `--muted-fg: var(--graphical-fg)`, dus binnen zo'n element wordt
	   "stille tekst" ineens de randkleur: op een stille knop was dat #e2e5ea
	   op wit, oftewel onleesbaar. Bedoel je stil, gebruik dan `--stil-fg` --
	   die kan een colorway niet overschrijven. `--muted-fg` is er voor
	   missing.css zelf en volgt hem, zodat er één waarde te wijzigen valt. */
	--stil-fg: light-dark(#4b4f56, #99a1af);
	--muted-fg: var(--stil-fg);
	/* Geen eigen token maar een override: `--faded-fg` is van missing.css, en
	   dit is de metakleur van de huisstijl in plaats van zijn eigen waarde.
	   Wij gebruiken hem nergens zelf, en met reden -- nagemeten haalt hij op
	   klein schrift geen WCAG AA (3,73:1 op de paginakleur, waar 4,5 nodig
	   is). Tekst die je léést krijgt `--stil-fg`; zie `docs/UI.md`,
	   "Contrast". */
	--faded-fg: light-dark(#7a7e86, #7d8592);
	--plain-bg: light-dark(#ffffff, #16181d);
	--plain-fg: light-dark(#1f3864, #a9c3e8);
	--plain-graphical-fg: light-dark(#e2e5ea, #2c303a);
	/* De vulling van een invulveld. Stond als losse waarde bij de velden zelf,
	   met een derde donkere tint (#22262e) in dit token die daardoor nergens
	   won -- een naam die niets beschreef. Nu de waarde die er echt staat;
	   missing.css leest hem ook voor zijn eigen componenten. */
	--interactive-bg: light-dark(#ffffff, #1a1d23);

	/* De statuskleuren, elk als bg/graphical/text-drietal. */
	--ok-bg: light-dark(#e1f5ee, #10241c);
	--ok-fg: light-dark(#0f6e56, #7fd9ab);
	--ok-graphical-fg: light-dark(#1d9e75, #5cc48a);

	--warn-bg: light-dark(#faeeda, #2a2013);
	--warn-fg: light-dark(#854f0b, #f0c37e);
	--warn-graphical-fg: light-dark(#ba7517, #e0aa53);

	--bad-bg: light-dark(#fcebeb, #2a1414);
	--bad-fg: light-dark(#791f1f, #f5a3a3);
	--bad-graphical-fg: light-dark(#a32d2d, #f08585);

	--info-bg: light-dark(#e7f1fa, #16233a);
	--info-fg: light-dark(#1f3864, #a9c3e8);
	--info-graphical-fg: light-dark(#2e74b5, #6aa6f5);

	/* De maat voor lopende tekst en formulieren. */
	--line-length: 46rem;

	/* Hoe hoog de merkbalk is. Die plakt bovenaan (`position: sticky`,
	   z-index 5), dus een plakkende kolomkop moet er precies onder beginnen --
	   anders schuift hij eronder en zie je hem niet meer. Nagemeten: 58px, en
	   dat volgt uit zijn eigen padding (12px) en regelhoogte.
	   Een waarde en geen berekening, want CSS kan de hoogte van een ander
	   element niet lezen. Verandert de balk, dan valt
	   `kern/tests/test_browser.py::test_de_kolomkop_plakt_onder_de_balk` om --
	   dat is de bewaking. */
	--balk-hoogte: 58px;

	/* Schaduwen: alleen waar iets écht boven de pagina hangt. */
	--schaduw-kaart: 0 1px 2px light-dark(rgb(31 56 100 / 0.06), rgb(0 0 0 / 0.3));
	--schaduw-hoog: 0 20px 60px light-dark(rgb(31 56 100 / 0.15), rgb(0 0 0 / 0.5));
}

/* ── Basis ──────────────────────────────────────────────────────────────── */

body {
	font-size: var(--tekst);
	line-height: 1.45;
}

h1 {
	font-family: var(--display-font);
	font-size: var(--kop-1);
	font-weight: 700;
	line-height: 1.3;
	color: var(--accent);
	margin-block: 0 calc(var(--gap) / 3);
}

h2 {
	font-family: var(--display-font);
	font-size: var(--kop-2);
	font-weight: 600;
	line-height: 1.35;
	color: var(--accent);
}

h3 {
	font-size: var(--kop-2);
	font-weight: 600;
	line-height: 1.35;
}

/* Een label is kleiner en stiller dan wat je invult. Niet als het een
   aanvinkvakje omsluit -- dat is een zin, geen label. */
label:not(:has(input[type="checkbox"], input[type="radio"])) {
	font-size: var(--tekst-klein);
	font-weight: 500;
	color: var(--stil-fg);
}

/* Eén maat voor alle bijzaak, zodat het rustig blijft. */
.toelichting, .helptext, .wanneer {
	font-size: var(--tekst-klein);
	color: var(--stil-fg);
}

.errorlist { color: var(--bad-fg); }

/* ── Rooster ────────────────────────────────────────────────────────────── */

/* De oude app had één gecentreerd canvas van 1200px. Dat is de basis; een
   scherm dat écht de hele breedte nodig heeft zegt dat zelf met `.breed` op
   `main`. Per scherm en niet per element: twee verschillende linkermarges op
   één pagina is precies hoe het rommelig werd. */
main {
	max-inline-size: 1200px;
	inline-size: 100%;
	margin-inline: auto;
	padding: 22px 24px 60px;
}

main.breed { max-inline-size: none; }

/* Lopende tekst en formulieren houden een maat, links uitgelijnd. */
.kolom { max-inline-size: var(--line-length); }

/* `.f-row` van missing.css is een flexrij, maar hij wrapt niet -- en op deze
   schermen moet dat: een naam met vier chips erachter hoort op een smal venster
   door te lopen in plaats van uit het scherm te schuiven.

   Wanneer je `.f-row` gebruikt en wanneer een eigen klasse: een component die
   zélf «een rij van iets» betekent (`.kpi`, `.kop`) regelt zijn
   eigen `display: flex`, want die staat op meerdere plekken en dan is «vergeet
   `.f-row` niet» precies de kwetsbaarheid die we kwijt willen. `.f-row` is
   voor een eenmalige rij in de markup, waar een eigen klasse alleen maar
   `display: flex` zou bevatten. */
.f-row { flex-wrap: wrap; }

/* Een scherm dat in de modal opengaat (`templates/popup.html`). Het krijgt
   geen eigen breedte -- de modal bepaalt die, en als volledige pagina staat
   het op hetzelfde canvas als de rest. Wat het wél doet: de lopende tekst die
   er direct in staat op leesbreedte zetten, zodat de uitleg boven een
   bevestiging niet over 1200px uitloopt. Tabellen en formulieren erin blijven
   ongemoeid; die zeggen zelf wat ze nodig hebben. */
.popup > p { max-inline-size: var(--line-length); }

/* missing.css' `.grid` maakt pas kolommen als een kind met `data-cols` zegt
   waar het hoort. Deze variant vult zichzelf -- nodig voor een formulier
   waarvan het aantal velden uit een Django-form komt. */
.grid.kolommen { grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }

/* Kop met acties ernaast. */
.kop {
	display: flex;
	flex-flow: row wrap;
	align-items: baseline;
	gap: var(--gap);

	/* De acties staan in een eigen `.kopacties` en niet los naast de kop, en
	   dan is één regel genoeg om ze rechts te zetten. Eerst hing dat aan
	   `> :first-child`: `space-between` werkte namelijk alleen bij precies
	   twee kinderen, en met drie knoppen stond de middelste midden in de balk
	   te zweven. Met een doos eromheen is het aantal knoppen niet meer van
	   belang -- en `templates/scherm.html` zet die doos er altijd, dus geen
	   scherm kan hem vergeten. */
	> .kopacties {
		margin-inline-start: auto;
		display: flex;
		flex-wrap: wrap;
		gap: var(--gap-klein);
		align-items: baseline;
	}
}

/* ── Balk en navigatie ──────────────────────────────────────────────────── */

/* De oude app had twee balken: een navy topbar met de merknaam en de
   gebruiker, en daaronder een witte balk met tabbladen. Die tweede balk is
   waaraan je het herkent, dus die staat hier ook. */
.navbar {
	padding: 12px 24px;
	background: var(--balk-bg);
	color: var(--balk-fg);
	border-block-end: none;
	font-size: var(--tekst);
	/* missing.css geeft een `body > header` een marge eronder; de tweede balk
	   hoort er tegenaan te zitten. */
	margin-block-end: 0;

	a { color: inherit; }

	form { display: flex; align-items: center; gap: var(--gap-klein); }

	button {
		color: inherit;
		/* Op een donkere balk, in beide modi: een lichte doorschijnende vulling. */
		background: rgb(255 255 255 / 0.14);
		border-color: rgb(255 255 255 / 0.45);
		box-shadow: none;
		font-size: var(--tekst-klein);

		&:hover, &:focus-visible {
			background: rgb(255 255 255 / 0.26);
			filter: none;
		}
	}

	.merk { font-family: var(--display-font); font-weight: 700; font-size: 1.05rem; }
	.gebruiker { font-size: var(--tekst-meta); opacity: 0.75; }
}

/* De merknaam links, de gebruiker met zijn uitlogknop rechts.

   Deze drie regels spiegelen een regel van missing.css, en dat is met opzet.
   Hij centreert de inhoud van een `.navbar` namelijk zélf:

       .navbar:not(.expanded) {
         > :first-child, nav > :first-child { margin-inline-start: auto }
         > :last-child,  nav > :last-child  { margin-inline-end: auto }
       }

   Zonder tegenwicht staan merknaam en uitlogknop dus midden in de balk. Het
   moet op deze selector: `.navbar > *` weegt (0,2,0) en verliest van zijn
   (0,3,0). Een `space-between` op de balk zetten helpt niet -- een auto-marge
   slokt de vrije ruimte op vóórdat `justify-content` aan bod komt. Nagemeten:
   dan schuiven ze naar het midden.

   Zijn `nav >`-varianten spiegelen we niet: in deze balk staat geen `<nav>`.
   De tweede balk (`.hoofdnav`) is een broer van de eerste en geen kind.
   Nagemeten over negentien schermen: die selector raakte nergens iets.

   Waarom niet gewoon `!important`: dan staat er een regel die alles overstemt
   en niets uitlegt. Zo staat er wat er tegen wordt gehouden. */
.navbar:not(.expanded) {
	> :first-child { margin-inline-start: 0; }
	> :last-child { margin-inline-end: 0; margin-inline-start: auto; }
}

/* De tweede balk: witte tabbladen met een navy onderstreping op de actieve. */
.hoofdnav {
	display: flex;
	flex-wrap: wrap;
	/* Niet op de schaal hierboven: tabbladen horen tegen elkaar te staan,
	   anders lezen ze als losse knoppen. */
	gap: 2px;
	padding-inline: 24px;
	background: var(--plain-bg);
	border-block-end: 1px solid var(--plain-graphical-fg);

	a {
		padding: 11px 14px;
		font-size: var(--tekst);
		font-weight: 600;
		color: var(--stil-fg);
		text-decoration: none;
		/* Geen ronding: missing.css geeft elke link 8px, en dan buigt de
		   onderstreping hieronder om tot een doosje. */
		border-radius: 0;
		border-block-end: 2px solid transparent;
	}

	a:hover { color: var(--accent); }

	a[aria-current="page"] {
		color: var(--accent);
		border-block-end-color: var(--accent);
	}
}

/* ── Knoppen en velden ──────────────────────────────────────────────────── */

/* De maten van `.tp-btn` uit de oude app. missing.css zet `padding-block` op
   0, en dan is een knop precies zo hoog als zijn letters. */
:where(button, input[type="submit"], input[type="reset"], input[type="button"], .\<button\>):not(.\<a\>) {
	padding: 9px 16px;
	min-block-size: 0;
	font-size: 12.5px;
	font-weight: 700;
	border-radius: var(--ronding-knop);
	justify-content: center;
	box-shadow: none;
}

/* Twee maten, en niet meer.

   - **Volle maat** -- hierboven: `padding: 9px 16px`, ronding 11px. Een knop
     in een tool-bar, onder een formulier, of naast de kop.
   - **Regelmaat** -- hieronder: `padding: 2px 8px`, ronding 9px. Alles wat op
     één tabelregel naast elkaar staat: de chip die een stand toont, de
     rijactie ernaast, het adresveldje op het accountscherm.

   Regelmaat staat in één regel en niet per component, en dat is geleerd:
   dezelfde padding en letter stonden op drie plekken uitgeschreven, maar de
   ronding liep uiteen (9px naast 11px) en de regelhoogte ook (chip 23px, knop
   20px). Naast elkaar in dezelfde rij zag je de knoppen wegzakken. Eén maat
   hoort één selector te zijn; wie hier een vierde plek bij maakt, zet hem
   erbij in plaats van de waarden over te typen.

   Kleur, gewicht en rand blijven wél per component. Een chip is een label en
   een rijactie is een actie, en die horen niet hetzelfde te zien
   (`docs/UI.md`). Het gaat hier alleen over de maat.

   Twee dingen aan de selector. Hij is een nazaat en geen direct kind, want de
   hoofdactie staat in een `<strong>` (`docs/UI.md`) -- met `>` viel juist die
   knop terug op de volle padding, en daarmee de hele rij op 55px. En een
   echte `<button>` telt mee naast de knoplink: op het koppelscherm staat
   «Gelijktrekken» naast «Bewerken…», en die hoort even smal te zijn.

   Nagemeten kost dit 3px rijhoogte, 41 wordt 44: een chip is `inline` en
   draagt zijn padding niet aan de regel af, een knop is `inline-flex` en wel.
   Bewust betaald -- het gaat om gelijke hoogte naast elkaar, en 3px is niet de
   15px waar de volle maat tegen beschermt. */
.chip,
.rijacties :is(.\<button\>, button),
.rijacties .adresveld input {
	padding: 2px 8px;
	border-radius: var(--ronding-chip);
	font-size: var(--tekst-klein);
	/* De regelhoogte van de pagina, ook op een knop: missing.css drukt die op
	   1.125 en dan is een knop lager dan de chip ernaast. Een chip erft hem
	   al, dus voor die kant is dit een no-op. */
	line-height: inherit;
}

/* De hoofdactie is navy gevuld; `strong > button` is het idioom van
   missing.css daarvoor en dat klopt hier precies.

   `:is()` en niet `:where()`, want dat weegt nul. Binnen een gekleurde kaart
   zet een colorway `--fg: var(--box-bg)`, en met (0,0,1) verloor de witte
   tekst hieronder daarvan: de pushknop in het blauwe blok kreeg #e7f1fa in
   plaats van wit. Leesbaar (10,2:1), maar niet wat hier staat -- en dat is
   precies de valkuil uit `docs/UI.md`. */
strong > :is(button, input[type="submit"], .\<button\>) {
	background: var(--accent);
	color: light-dark(#ffffff, #0e1014);
	border-color: transparent;

	&:hover { background: var(--navy-hover); filter: none; }
}

/* En de rustige variant: wit met een lichte rand, navy bij hover -- de
   `.tp-btn.alt` van de oude app. Ook zonder `.plain`, want een kale
   `<button>` en een `<a class="<button>">` zijn dezelfde soort actie; met
   alleen de `.plain`-regel kreeg de kale knop de zwaardere rand van
   missing.css en verschilden twee neutrale knoppen naast elkaar. */
:is(button, input[type="submit"], input[type="button"], .\<button\>):not(
	strong > *, .navbar *, .ok, .warn, .bad, .info
) {
	background: var(--plain-bg);
	color: var(--stil-fg);
	border-color: var(--plain-graphical-fg);

	&:hover { color: var(--accent); border-color: var(--muted-accent); filter: none; }
}

/* Zonder `:where()`, want dat weegt nul en dan wint missing.css met zijn
   gewone elementselectors. Die zetten `font-size: 1rem` (16px, waar de
   huisstijl 13 zegt), `padding: calc(var(--rhythm) / 4)` en
   `background: var(--bg)` -- en dan is een veld te groot en valt het weg
   tegen de pagina. Zelfde valkuil als bij de balk; zie `docs/UI.md`,
   "Let op de specificiteit van missing.css". */
input:not([type]),
input[type="text"], input[type="search"], input[type="tel"], input[type="url"],
input[type="email"], input[type="password"], input[type="date"],
input[type="number"], select, textarea {
	padding: 9px 11px;
	font-size: var(--tekst);
	border-color: var(--plain-graphical-fg);
	background: var(--interactive-bg);

	/* missing.css zet `text-align: end` op de tiphint, in een regel die in
	   dezelfde selectorlijst genest staat -- (0,1,2), dus een losse
	   `::placeholder` (0,0,1) verliest ervan. Vandaar hier genest en niet
	   ernaast. Een tiphint tegen de rechterrand leest als een ingevulde
	   waarde die verkeerd staat; hij hoort te beginnen waar je gaat typen.
	   En `--muted-fg` wordt binnen een colorway de randkleur, dus
	   `--stil-fg`. */
	&::placeholder {
		text-align: start;
		color: var(--stil-fg);
	}
}

/* De focusring van missing.css is 0,2em massief; dat is op een 13px-scherm een
   dikke navy balk om een veld. Hier subtieler, met dezelfde kleur. */
:where(input, select, textarea):focus-visible {
	outline: 2px solid var(--muted-accent);
	outline-offset: 0;
}

/* De gekozen knop in een groep: het filter op het koppelscherm, het sjabloon
   op het SMS-scherm. Beide zetten `aria-current="page"` op de actieve knop,
   maar alleen `.hoofdnav` deed daar iets mee -- op die twee schermen was dus
   niet te zien wat er aan stond. Niet navy gevuld: dat is de hoofdactie, en
   een gekozen filter is geen actie maar een stand.

   `="page"` en niet het kale attribuut: `aria-current="false"` is geldige
   ARIA voor "niet de huidige", en dat mag er niet als gekozen uitzien. De
   `&:hover` moet er ook staan, want die van de stille knop hierboven weegt
   (0,3,1) -- zonder deze verloor de gekozen knop zijn navy rand precies waar
   je hem aanwijst. */
:is(button, input[type="submit"], .\<button\>)[aria-current="page"] {
	background: var(--accent-zacht);
	border-color: var(--accent);
	color: var(--accent);

	&:hover { border-color: var(--accent); color: var(--accent); }
}

/* Ruimte tussen de velden van een `as_div`-formulier. Django zet elk veld in
   een eigen div, en die staan van zichzelf tegen elkaar. */
form div:has(> label, > input, > select, > textarea) { margin-block-end: var(--gap-ruim); }

:where(input[type="checkbox"], input[type="radio"]) { padding: 0; }

/* Een `label` die zijn veld omsluit staat naast dat veld, niet erboven -- zo
   staan de zoek- en filterrijen opgeschreven. Zonder flex zit de labeltekst
   op de basislijn van de regel en dus tegen de bovenkant van een veld dat
   39px hoog is; dat leest als een label dat te hoog hangt. Aanvinkvakjes
   blijven erbuiten: daar is het label een zin, geen label. */
label:has(> input:not([type="checkbox"], [type="radio"]), > select, > textarea) {
	display: inline-flex;
	align-items: center;
	gap: var(--gap-klein);
}

/* Een aanvinkvakje in een zin blijft `inline` -- `inline-flex` zou de tekst
   van het vinkje losmaken en niet meer laten teruglopen. Maar het stond 3,4px
   van zijn label af (alleen de spatie uit de opmaak; missing.css haalt de
   eigen marge van een `input` weg), terwijl elk ander label-en-veldpaar
   hierboven 8px heeft. Vier erbij komt daarop uit. Dit raakt juist de
   bevestiging, en die hoort niet krapper te zitten dan de rest. */
label > input:is([type="checkbox"], [type="radio"]) {
	margin-inline-end: var(--gap-krap);
}

/* missing.css maakt een veld binnen een `label` inline en haalt zijn
   `padding-block` weg. Dat is bedoeld voor een aanvinkvakje in een zin, maar
   het raakt ook het zoekveld in een `tool-bar`: dan is hetzelfde veld op het
   ene scherm 19px hoog en op het andere 37. Zijn selector weegt (0,1,2) --
   `:not([...])` telt als attribuut -- dus deze doet dat ook, en wint op
   volgorde. Aanvinkvakjes blijven erbuiten: die hóren geen padding te hebben. */
label :is(input, select, textarea):not([type="checkbox"], [type="radio"]) {
	padding-block: 9px;
}

/* Een rijtje radio's onder elkaar. Krapper dan losse velden, want dit is één
   keuze en geen drie velden -- en de labels zijn zinnen, dus zonder deze doos
   lopen ze achter elkaar door. */
.keuzelijst {
	display: grid;
	justify-items: start;
	gap: var(--gap-krap);
	margin-block-end: var(--gap-klein);
}

/* Het vrije-tekstveld naast een knop mag de rij vullen. */
.notitietekst { flex: 1; min-inline-size: 12rem; }

/* Een rij besturingselementen lijnt op de onderkant uit. */
.tool-bar { align-items: end; }

/* Een knop náást een veld hoort even hoog te zijn. Een veld is 39px (padding
   9px plus tekst op 13px), een knop 34px (dezelfde padding, tekst op 12,5px),
   en `align-items: end` lijnt de onderkanten uit -- dus verschilt de bovenkant
   5px en leest de filterbalk als onaf.

   Met `:has()` en niet op elke knop: een balk met alléén knoppen, zoals de
   bulkacties onder het debiteurenoverzicht, houdt de maat uit de oude app. */
.tool-bar:has(:is(input, select, textarea)) :is(button, .\<button\>) {
	padding-block: 11.5px;
}

/* Het bevestigingsblok: het vinkje op zijn eigen regel, de knoppen eronder
   (`docs/UI.md`). Zonder deze marge zit de knop 4px onder de labeltekst, en
   dat is te dicht voor het vinkje dat een mutatie tegenhoudt. */
label + .tool-bar { margin-block-start: var(--gap-klein); }

/* ── Kaarten ────────────────────────────────────────────────────────────── */

/* Wit, een dunne rand, ronding 10 -- zoals de oude app. Geen zware schaduw:
   die had de oude app alleen voor wat écht boven de pagina hangt.

   `--box-bg` en `--graphical-fg` en niet de `plain`-varianten: die twee zijn
   precies wat een colorway herdefinieert. Met `--plain-bg` hardgecodeerd was
   élke `.box warn`, `.box info` en élke flash-melding wit -- de rollen uit
   `docs/UI.md` deden niets meer dan de tekstkleur. In de neutrale stand zijn
   deze twee dezelfde waarde, dus er verandert alleen iets waar een rol staat. */
.box, dialog, details, figure {
	padding: 16px 18px;
	background: var(--box-bg);
	border-color: var(--graphical-fg);
	box-shadow: var(--schaduw-kaart);
}

/* ── Chips ──────────────────────────────────────────────────────────────── */

/* De pil uit de oude app. Zijn maat staat bij «Twee maten» hierboven, samen
   met de rijactie ernaast; hier alleen wat hem een chip maakt. */
.chip {
	font-weight: 500;
	border-color: var(--plain-graphical-fg);
	background: var(--bg);
	color: var(--stil-fg);
	white-space: nowrap;
}

.chip:is(.ok, .warn, .bad, .info) {
	background: var(--box-bg);
	color: var(--accent);
	border-color: var(--graphical-fg);
}

/* ── Meldingen ──────────────────────────────────────────────────────────── */

/* De colorway hoort bij de Django-tag, en die komt uit `messages` -- dus
   vertaalt de CSS hem, niet de markup. */
.melding {
	&.success { --box-bg: var(--ok-bg); --accent: var(--ok-fg); --graphical-fg: var(--ok-graphical-fg); }
	&.warning { --box-bg: var(--warn-bg); --accent: var(--warn-fg); --graphical-fg: var(--warn-graphical-fg); }
	&.error { --box-bg: var(--bad-bg); --accent: var(--bad-fg); --graphical-fg: var(--bad-graphical-fg); }
	&.info, &.debug { --box-bg: var(--info-bg); --accent: var(--info-fg); --graphical-fg: var(--info-graphical-fg); }
}

/* ── Tabellen ───────────────────────────────────────────────────────────── */

/* Geen vaste hoogte en geen paginering: de lijst loopt door en scrollt.
   Zie docs/KOPPELSCHERM.md — ontworpen voor een handvol, bestand tegen meer. */
table {
	inline-size: 100%;
	background: var(--plain-bg);
	border-radius: var(--border-radius);
	box-shadow: var(--schaduw-kaart);
}

/* `10px 12px` -- de celmaat van de oude app. */
td, th {
	padding: 10px 12px;
	vertical-align: top;
}

/* missing.css zet `td,th{&:not(:last-child){padding-inline-end:1rlh}}`, en dat
   weegt (0,1,1) tegen de (0,0,1) hierboven. Elke cel behalve de laatste kreeg
   daardoor 22,4px rechts en 12px links -- zichtbaar scheef in elke tabel.
   Dezelfde specificiteit dus, en dan wint deze op volgorde. */
td:not(:last-child), th:not(:last-child) { padding-inline-end: var(--gap-ruim); }

/* De ronde hoeken van de tabel, op de cellen zelf. Stonden eerst als
   `overflow: hidden` op de `table`, en dat is wat de kolomkop niet liet
   plakken: `overflow` maakt van een element een scrollcontainer, en een
   `position: sticky` erin plakt dan aan die container in plaats van aan het
   scherm. De kop schoof dus gewoon met de tabel mee de pagina uit -- de regel
   stond er, hij deed alleen niets. Nagemeten: na 600px scrollen stond de kop
   op -244px.

   Per hoekcel en niet per rij, want `border-radius` op een `<tr>` doet niets
   bij `border-collapse: collapse`. De onderste twee hangen aan de láátste
   `tbody`: het debiteurenoverzicht heeft er één per klant. */
thead th:first-child { border-start-start-radius: var(--border-radius); }
thead th:last-child { border-start-end-radius: var(--border-radius); }
tbody:last-of-type tr:last-child {
	& td:first-child { border-end-start-radius: var(--border-radius); }
	& td:last-child { border-end-end-radius: var(--border-radius); }
}

thead th {
	position: sticky;
	/* Onder de merkbalk, die zelf bovenaan plakt. Zie `--balk-hoogte`. */
	inset-block-start: var(--balk-hoogte);
	z-index: 1;
	font-size: var(--tekst-meta);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--stil-fg);
	background: var(--bg);
	border-block-end: 1px solid var(--plain-graphical-fg);
}

tbody { border: none; }
tbody tr { border-block-end: 1px solid var(--plain-graphical-fg); }
tbody tr:last-child { border-block-end: none; }
tbody tr:hover { background: var(--accent-zacht); }
/* Aangesprongen via een anker, bv. vanaf de klantpagina. */
tbody tr:target { background: var(--warn-bg); }

/* De kop van een klantgroep op het debiteurenoverzicht. Een rij met dezelfde
   kolommen als de facturen eronder, en niet meer één cel met `colspan`: het
   klanttotaal hoort in de kolom «Openstaand», onder de bedragen die het
   optelt. Wat per bedrijf niets betekent blijft leeg. */
.klantregel {
	font-weight: 600;
	background: var(--bg);

	/* De stille bijschriften binnen die rij erven het vet niet: het aantal
	   facturen en de herkomst van een telefoonnummer zijn bijzaak naast het
	   bedrag en het nummer zelf. */
	& .toelichting {
		font-weight: 400;
		font-size: var(--tekst-klein);
	}
}

/* De bedrijfsnaam met zijn chips. De naam krimpt met een beletselteken in
   plaats van af te breken: een rij die op één regel past is meer waard dan de
   laatste drie tekens van een handelsnaam, en de volledige naam staat in de
   `title` én op de klantpagina erachter. De chips houden hun maat. */
.klantnaam {
	flex-wrap: nowrap;

	/* Zodat de kolom mág krimpen. In een tabel met `table-layout: auto` telt
	   de *inhoud* van een cel mee voor de minimumbreedte van zijn kolom, ook
	   als die inhoud een beletselteken krijgt: een lange bedrijfsnaam duwde de
	   tabel zo 280px uit het scherm. Deze twee samen (`max` nul, `min` de
	   celbreedte) maken de bijdrage nul en laten de kolom alsnog de ruimte
	   vullen die overblijft. */
	max-inline-size: 0;
	min-inline-size: 100%;

	/* Twee dingen die een flexrij stil twee regels hoog maken, allebei
	   nagemeten in `kern/tests/test_browser.py`: de blokmarges van missing.css
	   tellen hier gewoon mee (ze vallen niet samen), en een item krimpt tot
	   onder zijn tekst -- «· Amsterdam» achter de naam werd zo op twee regels
	   gezet in 71px. Alles wat geen naam is houdt dus zijn maat. */
	& > * {
		margin-block: 0;
		flex: none;
		white-space: nowrap;
	}

	/* De naam is het enige dat mag krimpen, en doet dat met een beletselteken
	   in plaats van af te breken. `min-inline-size: 0` moet erbij: een flexitem
	   krimpt anders niet onder zijn eigen tekst en duwt de rij alsnog breder. */
	& > a {
		flex: 1 1 auto;
		min-inline-size: 0;
		overflow: hidden;
		text-overflow: ellipsis;
	}
}

/* Het klanttotaal, met het aantal facturen erachter. Op één regel, net als de
   rest van de rij; de kolom is daarvoor breder dan zijn getal
   (`.bedragkolom`). */
.klantbedrag {
	text-align: end;
	white-space: nowrap;
}

/* Wat al over de ouderdomsgrens is, in rood en vet. Dat is het getal waarop
   iemand besluit of de website eraf gaat. */
.oud {
	color: var(--bad-fg);
	font-weight: 700;
	font-size: var(--tekst-klein);
}

/* De bulkknoppen bóven de tabel. Dat ze eruitzien alsof ze uit staan doet
   missing.css al -- `opacity: .7` plus `filter: grayscale(1)` op een
   `:disabled`. Hier stond een eigen `opacity: .5` bovenop; die haalde het niet
   tegen zijn selector en deed dus niets. Nagemeten: 0,7. */
.selectiebalk {
	margin-block-end: var(--gap-ruim);
}

/* Het einde van een `.tool-bar`, losgetrokken van de rest: de ophaalknop
   staat in de selectiebalk maar hoort niet bij «voor de selectie». */
.duwrechts { margin-inline-start: auto; }

/* Getallen en datums horen niet af te breken; tekstkolommen juist wel. */
.rechts, .nietafbreken { white-space: nowrap; }
.rechts { text-align: end; }

/* Kolommen die op hun inhoud blijven, en de kolom die de rest opslokt --
   die laatste krijgt met opzet géén breedte. */
.krimpkolom { inline-size: 1%; white-space: nowrap; }
.rekkolom { inline-size: auto; }

/* Twee kolommen van het debiteurenoverzicht dragen méér dan één waarde: het
   bedrag met zijn aantal facturen, en het nummer met zijn herkomst. Ze krijgen
   daarom een eigen breedte in plaats van `krimpkolom` -- dat zet ze op hun
   inhoud, en dan breekt de tweede waarde af naar een tweede regel en wordt de
   rij twee keer zo hoog. De breedte staat in `debiteuren/overzicht.py` bij het
   opschrift, zodat de echte tabel en het skelet hem delen. */
/* De kolom met de bedrijfsnaam mag krimpen (`.klantnaam` hieronder), maar
   niet tot niets: zonder bodem kromp hij op een smal venster tot nul en was
   de klantnaam onzichtbaar én onklikbaar. Dan liever een tabel die opzij
   scrolt. Nagemeten in `kern/tests/test_browser.py`. */
.naamkolom { min-inline-size: 9rem; }

.bedragkolom { inline-size: 11ch; white-space: nowrap; text-align: end; }
.telefoonkolom { inline-size: 20ch; white-space: nowrap; }

.selectiekolom {
	inline-size: 1%;
	text-align: center;
	vertical-align: middle;
}

/* De credit-telling op de twee creditschermen: het getal waarop je die lijst
   leest, dus in de alarmkleur en vet. Zoals in de oude app. */
.telling {
	font-weight: 700;
	color: var(--bad-fg);
}

/* Eén verrichte actie in de kolom «Acties verricht» op de klantpagina: de
   soort als chip met wie en wanneer erachter. Ze staan onder elkaar, want het
   zijn er meestal één of twee en dan is een lijstje leesbaarder dan een rij
   die uitwaaiert. */
.verricht {
	display: flex;
	flex-flow: row wrap;
	align-items: baseline;
	gap: var(--gap-klein);

	& + & { margin-block-start: 2px; }
}

/* De waarschuwing onder een status: «N andere facturen recent offline». Klein
   en in de alarmkleur, want het is een reden om níet te doen wat je van plan
   was -- maar het is geen fout, dus geen kader eromheen. */
.waarschuwing {
	margin-block-start: 2px;
	font-size: var(--tekst-klein);
	font-weight: 700;
	color: var(--bad-fg);
	white-space: normal;
}

/* De vier acties op een factuurregel. Het zijn links die als knop lezen
   (`docs/UI.md`) en geen chips: een chip is in deze tabel een statuslabel
   («late», «2× herinnerd»), en een actie die er precies zo uitziet vind je
   niet terug.

   Wel smaller dan een gewone knop. Met de volle `padding: 9px 16px` hierboven
   wordt de rij 55px in plaats van 44px, en dat is op 404 rijen zo'n 4500px
   extra pagina — het gat dat deze acties juist moesten dichten. Deze maat laat
   de rand en de achtergrond staan, dus het blijft een knop. */
.rijacties {
	white-space: nowrap;

	/* De maat van de knoppen hierin staat bij «Twee maten» bovenaan, in
	   dezelfde regel als de chip ernaast. Hier alleen wat de cel zelf doet. */

	/* Een `<form>` is een blok, dus zonder dit valt zo'n knop onder de
	   andere in plaats van ernaast -- en deze cel heeft met opzet geen
	   `display: flex` (hierboven). */
	& form { display: inline; }

	/* Een marge tussen de broers en geen `gap`, en dat is hier geen
	   ouderwetsheid: dit is een `<td>`. Zet je daar `display: flex` op, dan is
	   het geen tabelcel meer, wikkelt de browser hem in een anonieme cel en
	   wordt de rij 67px in plaats van 41px. Nagemeten. Wil je toch `gap`, dan
	   moet er een `<div>` in de cel -- een extra element voor vier pixels
	   ruimte. */
	& > * + * { margin-inline-start: var(--gap-krap); }
}

/* ── KPI-tegels ─────────────────────────────────────────────────────────── */

.kpi {
	display: flex;
	flex-flow: row wrap;
	gap: var(--gap-ruim);
	margin-block: var(--gap);

	/* Een tegel is een `<li>` of een `<a>`: op het koppelscherm ís de tegel
	   het filter, dus daar is hij aanklikbaar. Dezelfde doos, zodat de twee
	   schermen niet uit elkaar lopen. */
	> :is(li, a) {
		padding: 12px 16px;
		background: var(--plain-bg);
		border: 1px solid var(--plain-graphical-fg);
		border-radius: var(--border-radius);
		box-shadow: var(--schaduw-kaart);
		font-size: var(--tekst-klein);
		color: var(--stil-fg);
	}

	/* Een tegel die linkt leest als een tegel en niet als lopende tekst. */
	> a {
		text-decoration: none;

		&:hover { border-color: var(--accent); }

		/* Waar je bent. `aria-current` en geen eigen klasse: de markering is
		   er dan voor een schermlezer én voor het oog, uit één bron. */
		&[aria-current] {
			border-color: var(--accent);
			box-shadow: inset 0 0 0 1px var(--accent), var(--schaduw-kaart);
			color: var(--fg);
		}
	}

	/* Een tegel die zélf een filter is, maar in een lijst staat. Op het
	   koppelscherm ís de tegel de link; op het debiteurenoverzicht is er van
	   de vier maar één aanklikbaar, en een `<ul>` mag geen `<a>` als direct
	   kind. De link zit daar dus ín de `<li>` en rekt zich met een
	   pseudo-element over de hele doos uit. De opmaak blijft op de `<li>`,
	   zodat een klikbare tegel er precies zo uitziet als de rest -- en de
	   markering voor «dit filter staat aan» dezelfde is als hierboven. */
	> li:has(> a) {
		position: relative;

		&:hover { border-color: var(--accent); }

		/* Geen `color` hier: een tegel die alarm slaat (`li.bad`) hoort rood
		   te blijven als je erop filtert. De markering is de rand. */
		&:has(> a[aria-current]) {
			border-color: var(--accent);
			box-shadow: inset 0 0 0 1px var(--accent), var(--schaduw-kaart);
		}

		> a {
			text-decoration: none;
			color: inherit;

			/* Over de hele doos, zodat de tegel klikt zoals hij eruitziet.
			   `background` en `block-size` staan er expliciet bij: missing.css
			   geeft `[aria-current=page]::after` een balk van 6px in
			   currentcolor, en dat is hetzelfde pseudo-element als dit. Zonder
			   die twee regels stond er een streep onder de actieve tegel én
			   was de rest van de doos niet meer klikbaar. */
			&::after {
				content: "";
				position: absolute;
				inset: 0;
				background: none;
				block-size: auto;
			}
		}
	}

	/* Eén tegel mag alarm slaan: «te controleren» op het
	   debiteurenoverzicht, zolang het getal niet nul is. Zelfde colorway als
	   een `.chip bad`, dus dezelfde tokens en geen eigen kleuren. */
	> li.bad {
		background: var(--bad-bg);
		border-color: var(--bad-graphical-fg);
		color: var(--bad-fg);

		& .getal { color: var(--bad-fg); }
	}

	/* Getal en opschrift op één regel, niet onder elkaar. Een tegel is een
	   feit van drie woorden -- «2 te controleren» -- en dat leest als zin, niet
	   als kop met onderschrift. Scheelt bovendien een regel hoogte boven élke
	   tabel. Geen `display: block` dus; een `<span>` is vanzelf inline en het
	   spatie-teken in de markup doet de tussenruimte. */
	.getal {
		/* Plus het spatie-teken uit de markup: samen genoeg lucht tussen een
		   bedrag en zijn opschrift. */
		margin-inline-end: var(--gap-krap);
		font-family: var(--display-font);
		font-size: 20px;
		font-weight: 700;
		font-variant-numeric: tabular-nums;
		line-height: 1.2;
		color: var(--accent);
	}
}

/* ── Wachten ────────────────────────────────────────────────────────────── */

.skelet {
	display: block;
	block-size: 1em;
	inline-size: 100%;
	background: var(--plain-graphical-fg);
	/* Kleiner dan de veldronding, want dit is een tekstregel en geen doosje. */
	border-radius: var(--ronding-skelet);
	animation: pulseren 1.4s ease-in-out infinite;
}

.laden {
	display: flex;
	align-items: center;
	gap: var(--gap-klein);
	font-size: var(--tekst-klein);
	font-style: italic;
	color: var(--stil-fg);
}

.laden::before {
	content: "";
	flex: none;
	inline-size: 1.1em;
	block-size: 1.1em;
	border: 2px solid var(--plain-graphical-fg);
	border-block-start-color: var(--accent);
	border-radius: 50%;
	animation: tollen 0.7s linear infinite;
}

@keyframes pulseren { 50% { opacity: 0.45; } }
@keyframes tollen { to { transform: rotate(1turn); } }

/* Een balk bovenaan zolang htmx íets ophaalt. Via `:has()`, dus geen enkel
   scherm hoeft er iets voor te doen. */
body:has(.htmx-request)::after {
	content: "";
	position: fixed;
	inset-block-start: 0;
	inset-inline: 0;
	block-size: 3px;
	z-index: 10;
	background: linear-gradient(90deg, transparent, var(--muted-accent), var(--accent), transparent);
	background-size: 40% 100%;
	background-repeat: no-repeat;
	animation: voortgang 1.1s ease-in-out infinite;
}

@keyframes voortgang {
	from { background-position: -40% 0; }
	to { background-position: 140% 0; }
}

@media (prefers-reduced-motion: reduce) {
	.skelet, .laden::before, body:has(.htmx-request)::after { animation: none; }
}

/* ── Empty state ────────────────────────────────────────────────────────── */

/* De oude app gaf een lege lijst ruimte in plaats van een regeltje: gecentreerd
   met veel lucht eromheen. Een lege lijst is geen storing. */
.niets {
	padding: 48px 40px;
	text-align: center;
	font-size: var(--tekst);
	color: var(--stil-fg);
	background: var(--plain-bg);
	border: 1px solid var(--plain-graphical-fg);
	border-radius: var(--border-radius);
}

/* Staat hij al in een kaart, dan is een tweede kaartrand eromheen dubbelop --
   en 48px lucht binnen een kaart die er zelf 16 heeft is te veel. */
.box > .niets, dialog > .niets {
	padding: 24px 20px;
	background: none;
	border: none;
}

/* ── Tijdlijn ───────────────────────────────────────────────────────────── */

.tijdlijn {
	> li {
		padding-block: 10px;
		border-block-end: 1px solid var(--plain-graphical-fg);
	}

	> li:last-child { border-block-end: none; }
	p { margin-block: 4px; }
	form { display: inline; }
}

/* ── Gegevenslijst ──────────────────────────────────────────────────────── */

.gegevens dl {
	display: grid;
	grid-template-columns: max-content 1fr;
	gap: var(--gap-krap) var(--gap-ruim);
	margin: 0;

	dt { font-size: var(--tekst-klein); color: var(--stil-fg); }
	dd { margin: 0; }
}

/* ── Credentials ────────────────────────────────────────────────────────── */

.credential {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: end;
	gap: var(--gap-ruim);
	margin-block-end: var(--gap-ruim);

	/* Zonder dit staat de chip 12px onder het veld waar hij bij hoort. De
	   linkerkolom is een `div` en die krijgt van missing.css 12px marge
	   onderaan; `align-items: end` lijnt dan uit op de onderkant van díe
	   marge in plaats van op het veld. */
	& > * { margin-block-end: 0; }
}

/* Wat er bij de laatste push misging, onder de stand van die rij. De melding
   mag afbreken -- het is een API-antwoord en dat is soms een alinea -- dus deze
   cel niet op `.nietafbreken` zetten. */
.pushfout {
	white-space: normal;

	& > div {
		margin-block-start: 2px;
		font-size: var(--tekst-meta);
		color: var(--stil-fg);
	}
}

/* ── Koppelscherm ───────────────────────────────────────────────────────── */

/* De requesternaam met zijn chips erachter (`koppeling/_requester.html`). Dit
   stond op `.f-row packed`, en `.packed` zet `--density: 0` -- dus gap 0, en
   dan raakte de naam de eerste chip. Een `.f-row` zonder `.packed` is met
   22,4px juist veel te ruim voor een naam met een label erachter. */
.requester { gap: var(--gap-krap); }

.zoekresultaten {
	li { display: flex; align-items: center; gap: var(--gap-klein); }
	form { display: inline; }
}

/* ── Modal ──────────────────────────────────────────────────────────────── */

/* Ronding 14 en een hoge schaduw: dit hangt écht boven de pagina, en dat is
   waar de oude app die schaduw voor gebruikte. */
/* Zolang er een modal openstaat, scrollt de pagina eronder niet mee. Een
   `<dialog>` blokkeert wel de *interactie* met de rest, maar niet het wiel:
   scroll je met de muis buiten de doos, dan schuift de lijst eronder weg en
   sta je na het sluiten ergens anders.

   `:modal` en niet `[open]`: dat eerste is waar voor een dialog die écht in de
   top layer staat. Een `<dialog open>` die daar niet in staat is geen modal en
   hoort de pagina niet te vergrendelen -- `static/modal.js` kent dat geval,
   het komt terug uit de geschiedenis van htmx.

   `scrollbar-gutter` hoort erbij: zonder die regel verdwijnt de schuifbalk bij
   het openen en springt de hele pagina 15px opzij. */
html { scrollbar-gutter: stable; }
html:has(dialog:modal) { overflow: hidden; }

.modal {
	/* Smal, zoals de popups van de oude app. Stond op 1100px, en dan zweeft
	   een formulier van leesbreedte in een half lege doos -- het SMS-scherm
	   zag er daardoor twee keer zo groot uit als het is. Dit is de maat voor
	   een scherm zónder tabel; de twee ruimere maten kiezen zichzelf, zie de
	   twee `:has()`-regels hieronder (`docs/UI.md`, "Een scherm in een
	   modal"). */
	inline-size: min(94vi, 560px);
	max-inline-size: none;
	max-block-size: 90vh;
	overflow: auto;
	position: relative;
	/* Geen padding bóven en onder, want dit is de scrollcontainer: de ruimte
	   die daar zou staan hoort bij de inhoud en moet mee wegscrollen. Stond ze
	   hier, dan bleef er een strook van 22px open bóven een `position: sticky`
	   kolomkop -- die plakt aan de rand van het content-vak, niet aan de rand
	   van de doos -- en zag je de rijen daar langs schuiven. Nagemeten. De
	   ruimte zelf staat op `#modal-inhoud` hieronder.

	   Expliciet op nul en niet weggelaten: missing.css zet zelf padding op een
	   `dialog`, en die viel er anders voor terug -- 16px, precies genoeg om de
	   strook terug te brengen. */
	padding-block: 0;
	padding-inline: 24px;
	border: none;
	border-radius: var(--ronding-groot);
	box-shadow: var(--schaduw-hoog);

	/* Een scherm met een tabel erin vraagt meer, en zegt dat niet zelf: een
	   eigen breedte per scherm is een knop die iemand vergeet. Nagemeten in
	   560: de WIK-brief vraagt 630px en het rij-actiescherm 579, dus in beide
	   viel de rechterkolom weg -- bij de WIK-brief was dat het invulveld «Te
	   vorderen», dat daarmee onbereikbaar was. Op 760 passen ze allebei
	   zonder zijwaarts schuiven, en blijft er niet de halve doos leeg die
	   1180 hier geeft. Een scherm zónder tabel is een formulier van
	   leesbreedte en blijft op 560. */
	&:has(.popup table) { inline-size: min(94vi, 760px); }

	/* En één scherm vraagt écht de volle breedte: `.breed` op zijn wortel
	   (`templates/scherm.html`, blok `schermklasse`). Dat is de klantpagina,
	   met een facturentabel van 1132px erin. Deze regel staat ná die
	   hierboven, want de klantpagina heeft óók een tabel en de laatste wint.
	   Zet dit niet op een scherm met een formulier — dan is het weer 1100px
	   zoals het was. */
	&:has(.popup.breed) { inline-size: min(94vi, 1180px); }

	&::backdrop {
		background: light-dark(rgb(28 30 33 / 0.45), rgb(0 0 0 / 0.6));
		backdrop-filter: blur(2px);
	}

	> [data-sluit] {
		position: absolute;
		inset-block-start: 12px;
		inset-inline-end: 12px;
		font-size: 1.4rem;
		z-index: 3;
	}

	.kop { padding-inline-end: 2.5rem; }
	h1:first-of-type { margin-block-start: 0; }

	/* missing.css zet `overflow: clip` op `.box`, en dat knipt hier stil weg
	   wat niet past: een tabel die breder is dan de doos verloor zijn
	   rechterkolom zónder scrollbalk, dus die was met geen muis te bereiken.
	   Hier geeft een doos zijn overloop door aan de modal, die er wél een
	   scrollbalk voor heeft (`overflow: auto` hierboven). Buiten de modal
	   blijft het knippen van missing.css staan. */
	.box { overflow: visible; }

	/* De ruimte boven en onder de inhoud. Hier en niet op `.modal`, zodat ze
	   met de inhoud mee wegscrolt en een plakkende kolomkop tot aan de rand
	   van de doos komt (hierboven). */
	> #modal-inhoud { padding-block: 22px; }

	/* In de modal plakt de kop aan de modal en niet aan het scherm: de
	   merkbalk staat hier niet boven, dus die ruimte hoort er ook niet af. */
	thead th { inset-block-start: 0; }
}

/* In een modal is de terugkoppeling overbodig -- de sluitknop en Esc doen dat
   al -- en zou hij de hele pagina wegnavigeren. */
#modal-inhoud .terug { display: none; }

/* Het e-mailadres op het accountscherm is een veldje met een knop ernaast, in
   de cel zelf. Een apart scherm voor één veld is een klik te veel; een veld
   zonder knop zou een wijziging stil laten verdampen.

   De knop erlangs krijgt zijn maat van `.rijacties` hierboven -- die cel staat
   er met opzet omheen, zodat dit dezelfde component is als de acties rechts in
   de rij en niet een tweede die er toevallig op lijkt. Hier staat alleen wat
   er ánders is: het veld ernaast.

   `.rijacties .adresveld` en niet kaal `.adresveld`: die cel zet
   `form { display: inline }` -- nodig voor een knop die post -- en dat is één
   klasse plus één element, dus specifieker dan een losse klasse. Kaal
   geschreven verliest dit blok zijn `display: flex` en valt de knop onder het
   veld in plaats van ernaast. */
.rijacties .adresveld {
	display: flex;
	gap: var(--gap-krap);
	align-items: center;

	& input {
		flex: 1;
		/* Klein genoeg om te krimpen. Een ruimere minimumbreedte duwde de
		   actiekolom op een laptopbreedte uit de tabel: dit is de enige
		   kolom die meegeeft, dus zijn minimum is dat van de hele tabel
		   (`docs/UI.md`, de valkuilen bij tabellen). */
		min-inline-size: 7rem;
	}
}

/* ── Smalle vensters: kolommen die mogen vallen ─────────────────────────── */

/* Deze tabellen zijn 1327px breed en het canvas is 1200. Onder die maat scrolt
   de pagina zijwaarts -- niets raakt zoek, maar op een tablet kijk je liever
   naar een tabel die past. Daarom valt er per drempel een kolom weg, en niet
   allemaal: wat overblijft is waar debiteurenbeheer over gaat.

   Waarom kolommen verbergen en niet de tabel zelf laten schuiven: een doos met
   `overflow-x: auto` wordt een scrollcontainer, en dan plakt de kolomkop aan
   díe doos in plaats van aan het scherm (`docs/UI.md`). Je kunt zijwaarts
   schuiven óf een plakkende kop hebben, niet allebei.

   `display: none` en niet `visibility`: een tabelkolom verdwijnt alleen als
   zowel de `<th>` als elke `<td>` eronder weg is, en dat is wat de klassen op
   beide kanten doen (`debiteuren/overzicht.py`, `KOLOMMEN`). */
@media (max-width: 1200px) {
	/* De factuurdatum. De vervaldatum blijft: dáár gaat het om. */
	.datumkolom { display: none; }

	/* Het telefoonnummer. Staat ook op de klantpagina, één klik verder. */
	.telefoonkolom { display: none; }

	/* En de actiekolom wikkelt in plaats van op één regel te blijven. Dat is
	   de breedste van allemaal -- vier knoppen naast elkaar is 353px, gewikkeld
	   180 -- en het kost alleen rijhoogte, en alleen hier. Meer waard dan nog
	   een kolom verbergen: een actie die je niet ziet kun je niet doen. */
	.rijacties { white-space: normal; }
}

@media (max-width: 800px) {
	/* De statuschip mag over twee regels. Hij is de breedste cel die overblijft
	   -- «Controleer of deze offline moet» is 221px -- en op deze breedte is
	   een chip van twee regels beter dan een tabel die het venster uit loopt.
	   Alleen in een tabelcel: een chip achter een bedrijfsnaam of in een
	   tool-bar hoort zijn maat te houden. */
	td .chip { white-space: normal; }
}

/* ── Inlogscherm ────────────────────────────────────────────────────────── */

/* `:not(:has(.navbar))` hoort erbij: dit maakt van `body` een flexrij, en met
   een balk erboven worden die balk, de navigatie en `main` dan drie kolommen
   naast elkaar. Het inlogscherm heeft nooit een balk, maar het scherm achter
   de uitnodigingslink wel zodra iemand hem opent terwijl hij al ingelogd is
   (`kern/templates/kern/wachtwoord-instellen.html`). Dan hoort de kaart
   gewoon in de pagina te staan en niet het scherm te kapen. */
body:not(:has(.navbar)):has(.inlog-kaart) {
	display: flex;
	/* `align-items: center` en niet alleen `margin: auto`: bij de standaard
	   `stretch` is `main` al zo hoog als het scherm, en dan heeft een
	   automatische marge geen ruimte om iets te centreren. */
	align-items: center;
	justify-content: center;
	min-block-size: 100vh;

	main { max-inline-size: 420px; padding: 20px; }
}

.inlog-kaart {
	padding: 32px 30px;
	border: none;
	border-radius: var(--ronding-groot);
	box-shadow: var(--schaduw-hoog);

	h1 { font-size: 1.4rem; margin-block-end: 4px; }
	p.toelichting { margin-block-end: 22px; }
	input { padding: 10px 12px; font-size: 14px; }
	button { inline-size: 100%; padding-block: 11px; font-size: 13.5px; }
}

/* ── De gemaakte WIK-brief ──────────────────────────────────────────────── */

/* Het voorbeeld van de brief die net gemaakt is. Een hoogte is nodig: een
   `<iframe>` zonder is 150px hoog en dan zie je het briefhoofd en verder
   niets. `aspect-ratio` en geen vaste hoogte, want een A4 is hoger dan breed
   en de modal bepaalt de breedte. */
.briefvoorbeeld {
	inline-size: 100%;
	aspect-ratio: 1 / 1.414;
	max-block-size: 70vh;
	margin-block-start: var(--gap-klein);
	border: 1px solid var(--plain-graphical-fg);
	border-radius: var(--border-radius);
}
