/* Grip — stijl.
   Uitgangspunten: rustig, contrastrijk, grote klikvlakken, en kleur die
   betekenis draagt (rood = te laat, oranje = nu, blauw = straks, groen = klaar).
   Geen externe fonts of bibliotheken: alles werkt zonder internet. */

:root {
  --achtergrond: #f6f7f9;
  --vlak: #ffffff;
  --vlak-2: #f1f3f6;
  --rand: #e2e6ec;
  --rand-sterk: #cbd3de;
  --tekst: #16202e;
  --tekst-zacht: #5b6879;
  /* Was #8593a5, maar dat haalde 3,13:1 op wit en 2,81:1 op --vlak-2 -- te
     weinig voor de 4,5:1 die kleine tekst nodig heeft. Deze kleur zit in
     tabelkoppen, cijferlabels, datums en alle hulpteksten, dus dit ene getal
     tilt de hele app op. Nu 4,65:1 op wit en 4,18:1 op --vlak-2. */
  --tekst-zachter: #5f6d7e;

  --accent: #3b5bdb;
  --accent-zacht: #e7ecfd;
  --accent-donker: #2f49af;
  /* Tekstkleur óp een gevuld vlak van deze kleur. In het lichte thema is dat
     wit; in het donkere thema worden de vlakken juist licht en moet de tekst
     donker worden. Zie de opmerking in het donkerblok. */
  --op-gevuld: #ffffff;

  --laat: #d63939;
  --laat-zacht: #fdeaea;
  --nu: #d97706;
  --nu-zacht: #fdf1e0;
  --straks: #2b7fbf;
  --straks-zacht: #e7f2fb;
  /* Was #2f9e63: wit daarop haalde 3,39:1 op de knop "Betaald". Donkerder
     groen haalt 5,1:1, en als tekstkleur op een licht vlak wordt het ook
     beter in plaats van slechter. */
  --klaar: #1f7d4c;
  --klaar-zacht: #e6f6ed;

  --radius: 14px;
  --radius-klein: 9px;
  --schaduw: 0 1px 2px rgba(16, 24, 40, .05), 0 6px 20px rgba(16, 24, 40, .05);
  --schaduw-hoog: 0 2px 4px rgba(16, 24, 40, .06), 0 12px 32px rgba(16, 24, 40, .1);
  /* Ruim, want de transactietabellen hebben negen kolommen. Op een 1920-scherm
     blijft er precies genoeg over voor de marge; smallere schermen krimpen
     gewoon mee, want dit is een maximum en geen vaste maat.

     Dit is een LEESgrens en geen schermgrens. Een tabelrij lees je van links
     naar rechts: eerst de naam, dan de datum, dan het bedrag. Hoe breder de
     tabel, hoe verder die drie uit elkaar staan en hoe vaker je met je ogen
     terug moet om te zien bij welke regel een bedrag hoort. Gemeten op
     /uitgaven, van de kop "Datum" tot de kop "Bedrag": mét deze grens 1545 px
     op zowel een 2560- als een 3840-scherm, zonder deze grens 1950 px op 2560
     en 3025 px op 3840 -- op 4K bijna twee keer zo ver. Onder de 1888 px doet
     de grens niets (gemeten 1106 px op 1440 en 1412 px op 1920), dus hij kost
     op gewone schermen niets. Daarom blijft hij staan voor pagina's die uit
     tekst en tabellen bestaan.

     Het overzicht valt er niet onder; zie .omhulsel.breed hieronder. */
  --breedte: 1888px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --achtergrond: #10151d;
    --vlak: #171e29;
    --vlak-2: #1e2735;
    --rand: #2a3546;
    --rand-sterk: #3a4759;
    --tekst: #e8edf4;
    --tekst-zacht: #a3b0c2;
    /* Was #7a889b; dat haalde 4,17:1 op --vlak-2, net onder de 4,5 die de
       tabelkoppen nodig hebben. */
    --tekst-zachter: #8b99ac;

    --accent: #7f9cf5;
    --accent-zacht: #232f4d;
    --accent-donker: #97aefa;

    --laat: #f87171;
    --laat-zacht: #3a1e21;
    --nu: #fbbf24;
    --nu-zacht: #3a2f16;
    --straks: #60a5fa;
    --straks-zacht: #16283f;
    --klaar: #4ade80;
    --klaar-zacht: #14301f;

    /* In het donker zijn accent, klaar en laat juist lichte kleuren. Witte
       tekst daarop haalde 1,74:1 op de knop 'Betaald' en 2,63:1 op de
       hoofdknop -- onleesbaar. Donkere tekst op diezelfde vlakken haalt ruim
       8:1. Vandaar één variabele in plaats van een hardgecodeerde #fff. */
    --op-gevuld: #101821;

    --schaduw: 0 1px 2px rgba(0, 0, 0, .3), 0 6px 20px rgba(0, 0, 0, .25);
    --schaduw-hoog: 0 2px 4px rgba(0, 0, 0, .35), 0 12px 32px rgba(0, 0, 0, .4);
  }
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  color: var(--tekst);
  background: var(--achtergrond);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0 0 .5rem; line-height: 1.25; font-weight: 650; letter-spacing: -.01em; }
h1 { font-size: 1.65rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }
p { margin: 0 0 .8rem; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.zacht { color: var(--tekst-zacht); }
.zachter { color: var(--tekst-zachter); }
.laat-kleur { color: var(--laat); }
.klein { font-size: .875rem; }
.kleiner { font-size: .8rem; }
.groot { font-size: 1.35rem; }
.vet { font-weight: 650; }
.rechts { text-align: right; }
.midden { text-align: center; }
.getal { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }
.verborgen { display: none !important; }
/* Het hidden-attribuut verliest van elke regel die 'display' zet -- en dat
   doen .knop en .badge allebei. Zonder deze regel staan verborgen knoppen
   gewoon in beeld. */
[hidden] { display: none !important; }
/* Wel voor een schermlezer, niet voor het oog. */
.alleen-voorlezen {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------- layout */

.omhulsel { max-width: var(--breedte); margin: 0 auto; padding: 0 1.5rem; }

/* Het overzicht mag wél de volle breedte pakken. Daar staan geen tabelrijen
   maar blokken op een raster, en die worden bij meer ruimte niet verder uit
   elkaar gezet: het raster telt gewoon kolommen bij, dus je krijgt grotere
   vakken en meer plek om ze in te delen. De leesgrens van --breedte lost daar
   dus niets op en kost alleen ruimte: met de grens bleef het raster op elk
   breed scherm op 1840 px steken, en dat kostte 241 px lege marge per kant op
   een 2560-scherm en 881 px per kant op 4K. Zonder de grens meet het raster
   2322 px op 2560 en 3602 px op 3840 -- 60 respectievelijk 90 kolommen in
   plaats van de 45 die er met de grens overbleven. */
.omhulsel.breed { max-width: none; }

/* ------------------------------------------------------- paneel links */

/* Het paneel staat naast de inhoud in plaats van erboven. Op een breed
   scherm is verticale ruimte schaars en horizontale ruimte over: een balk
   bovenaan kost je elke pagina 60 px hoogte, een paneel kost breedte die
   je toch niet gebruikt. Ingeklapt blijven de pictogrammen staan. */
body { display: flex; align-items: flex-start; min-height: 100vh; }

/* Geen transitie op de breedte. Dat zag er soepeler uit, maar op een sticky
   flexitem bleef de oude breedte staan: de klasse wisselde wel en de cascade
   gaf 64px, maar het element bleef 190px. Met de transitie eruit klapt hij
   meteen om -- en dat scheelt ook een reflow van de hele pagina. */
.paneel {
  width: 190px; flex-shrink: 0;
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--vlak); border-right: 1px solid var(--rand);
}
html.paneel-smal .paneel { width: 64px; }
/* Ingeklapt verdwijnt alle tekst en blijft alleen het pictogram staan. */
html.paneel-smal .paneel-tekst { display: none; }

.paneel-kop {
  display: flex; align-items: center; gap: .5rem;
  padding: .8rem .7rem; border-bottom: 1px solid var(--rand); min-height: 57px;
}
/* Ingeklapt blijven logo en knop naast elkaar staan, alleen krapper: onder
   elkaar zetten verplaatst de knop en dan moet je hem opnieuw zoeken. */
html.paneel-smal .paneel-kop { gap: .15rem; padding: .8rem .25rem; }

.merk {
  display: flex; align-items: center; gap: .5rem; flex: 1; min-width: 0;
  font-weight: 750; font-size: 1.15rem; color: var(--tekst); letter-spacing: -.02em;
}
.merk:hover { text-decoration: none; }
.merk-punt {
  width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent), #7048e8);
  display: grid; place-items: center; color: #fff; font-size: .9rem; font-weight: 800;
}

.paneel-knop {
  font: inherit; line-height: 0; cursor: pointer; display: grid; place-items: center;
  width: 26px; height: 26px; padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-klein);
  background: transparent; color: var(--tekst-zacht); flex-shrink: 0;
}
.paneel-knop:hover { background: var(--vlak-2); color: var(--tekst); }
.paneel-knop:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* De chevron wijst de kant op waar het paneel heen gaat: naar links om te
   sluiten, naar rechts om te openen. */
.chevron { grid-area: 1 / 1; }
.chevron-open { display: none; }
html.paneel-smal .chevron-dicht { display: none; }
html.paneel-smal .chevron-open { display: block; }

/* De knop blijft ook ingeklapt staan, en blijft rechts van het logo: verdwijnt
   hij of verspringt hij, dan moet je opnieuw zoeken waar je moet klikken. */
html.paneel-smal .merk { flex: 0 0 auto; }
html.paneel-smal .merk-punt { width: 24px; height: 24px; font-size: .8rem; }
html.paneel-smal .paneel-knop { width: 22px; height: 22px; }
html.paneel-smal .paneel-kop .merk { cursor: pointer; }

.paneel-nav { display: flex; flex-direction: column; gap: .1rem; padding: .6rem .5rem;
  flex: 1; overflow-y: auto; overflow-x: hidden; }

.paneel-nav a, .paneel-voet a, .paneel-voet button {
  display: flex; align-items: center; gap: .65rem; position: relative;
  padding: .55rem .6rem; border-radius: var(--radius-klein);
  color: var(--tekst-zacht); font: inherit; font-size: .93rem; font-weight: 550;
  border: 0; background: transparent; width: 100%; text-align: left; cursor: pointer;
  white-space: nowrap;
}
.paneel-nav a:hover, .paneel-voet a:hover, .paneel-voet button:hover {
  background: var(--vlak-2); color: var(--tekst); text-decoration: none;
}
.paneel-nav a.aan, .paneel-voet a.aan {
  background: var(--accent-zacht); color: var(--accent-donker); font-weight: 650;
}
.paneel-nav a:focus-visible, .paneel-voet a:focus-visible, .paneel-voet button:focus-visible {
  outline: 3px solid var(--accent); outline-offset: -1px;
}
.paneel-icoon { font-size: 1.15rem; line-height: 1; width: 22px; text-align: center; flex-shrink: 0; }
html.paneel-smal .paneel-nav a, html.paneel-smal .paneel-voet a,
html.paneel-smal .paneel-voet button { justify-content: center; padding: .55rem .3rem; }

.paneel-voet {
  padding: .5rem .5rem .7rem; border-top: 1px solid var(--rand);
  display: flex; flex-direction: column; gap: .1rem;
}

/* line-height expliciet op 1: anders erft het cijfer de regelhoogte van de
   body (1,55) en zakt het onderuit het bolletje. */
/* Vlak achter de tekst in plaats van tegen de rechterrand. De negatieve marge
   haalt de gap van de link zelf (.65rem) er weer af -- die is bedoeld voor de
   ruimte tussen pictogram en tekst, niet voor het bolletje. */
.nav-teller {
  min-width: 19px; height: 19px; padding: 0 5px; margin-left: -.42rem;
  border-radius: 10px; background: var(--laat); color: var(--op-gevuld);
  font-size: .7rem; font-weight: 700; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.nav-teller.stil { background: var(--rand-sterk); color: var(--tekst); }
/* Ingeklapt past er geen getal naast de tekst, dus wordt het een bolletje
   rechtsboven op het pictogram. */
html.paneel-smal .nav-teller {
  position: absolute; top: 2px; right: 6px; margin: 0;
  min-width: 16px; height: 16px; padding: 0 3px; font-size: .6rem;
  border: 2px solid var(--vlak); box-sizing: content-box;
}

main { flex: 1; min-width: 0; padding: 1.75rem 0 4rem; }

.pagina-kop {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem;
}
.pagina-kop h1 { margin-bottom: .15rem; }

.rooster { display: grid; gap: 1rem; }
.rooster-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.rooster-3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.rooster-4 { grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); }
.stapel { display: grid; gap: 1rem; }
.rij { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.rij-tussen { display: flex; gap: .6rem; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.duw { margin-left: auto; }

/* ----------------------------------------------------------------- kaart */

.kaart {
  background: var(--vlak);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schaduw);
  overflow: hidden;
}
.kaart-kop {
  padding: .9rem 1.15rem; border-bottom: 1px solid var(--rand);
  display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap;
}
.kaart-kop h2, .kaart-kop h3 { margin: 0; }
.kaart-body { padding: 1.15rem; }
.kaart-body.strak { padding: 0; }
.kaart-voet {
  padding: .75rem 1.15rem; border-top: 1px solid var(--rand);
  background: var(--vlak-2); font-size: .875rem;
}

/* ------------------------------------------------------------ kerncijfer */

.cijfer { padding: 1.05rem 1.15rem; }
.cijfer-label {
  font-size: .78rem; font-weight: 650; letter-spacing: .04em; text-transform: uppercase;
  color: var(--tekst-zachter); margin-bottom: .3rem;
}
.cijfer-waarde { font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.cijfer-onder { font-size: .84rem; color: var(--tekst-zacht); margin-top: .15rem; }
.cijfer.laat .cijfer-waarde { color: var(--laat); }
.cijfer.klaar .cijfer-waarde { color: var(--klaar); }
.cijfer.nu .cijfer-waarde { color: var(--nu); }

/* ------------------------------------------------------------ actiekaart */

/* Vijf naast elkaar: rekeningen over datum, deze week, inbox, te ontvangen
   factuurbetalingen en de BTW-aangifte. Altijd alle vijf, altijd in dezelfde
   volgorde, ook als er niets te melden is -- zo hoef je nooit te zoeken waar
   iets stond. */

.actie {
  display: flex; flex-direction: column; gap: .55rem;
  padding: 1rem 1.15rem; border-radius: var(--radius);
  border: 1px solid var(--rand); border-top-width: 5px;
  background: var(--vlak); box-shadow: var(--schaduw); min-width: 0;
}
.actie-icoon { font-size: 1.6rem; line-height: 1; }
.actie-tekst { flex: 1; min-width: 0; }
.actie-titel { font-weight: 650; font-size: 1.02rem; margin-bottom: .15rem; }
.actie-toelichting { font-size: .86rem; color: var(--tekst-zacht); }
.actie-bedrag { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.actie .knop { width: 100%; margin-top: auto; }

/* Drie datums onder elkaar in plaats van in één zin: in een vakje van 400 px
   leest niemand een zin met drie datums erin. */
.actie-regels {
  display: grid; grid-template-columns: 1fr auto; gap: .2rem .75rem;
  margin: 0; font-size: .84rem;
}
.actie-regels dt { color: var(--tekst-zacht); }
.actie-regels dd {
  margin: 0; font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* De coulancetermijn is een marge, geen uitstel — die mag niet even hard
   binnenkomen als de echte uiterste datum. */
.actie-regels dt:last-of-type, .actie-regels dd:last-of-type { color: var(--tekst-zachter); font-weight: 550; }

/* ------------------------------------------------- zelf ingedeeld overzicht */

/* De blokken staan in een raster van vierkante vakjes van rond de 40 px; hoe
   breed je scherm is bepaalt hoeveel stappen er in passen en daarmee ook hoe
   groot een vakje precies wordt. Breedte en hoogte komen van gridstack, dus
   hier staat alleen wat er bínnen een blok moet gebeuren. */
.grid-stack-item-content { display: flex; }
.grid-stack-item-content > .kaart, .grid-stack-item-content > .actie {
  width: 100%; margin: 0; min-height: 0;
}
/* GEEN overflow:hidden op een actievak. Dat stond er even, om te voorkomen dat
   de inhoud over de rand loopt als er iets bijkomt. Het gevolg was erger dan
   de kwaal: op 1280 en 1440 px werd de hoofdknop "Bekijk en betaal" voor meer
   dan de helft afgeknipt en verdween de regel "Einde coulancetermijn"
   volledig. Iets dat een stukje overloopt kun je nog lezen; iets dat is
   weggeknipt bestaat niet meer. */
/* Een blok heeft nu een vaste hoogte, dus wat er niet in past scrollt binnen
   het blok in plaats van eroverheen te lopen. */
.grid-stack-item-content > .kaart { display: flex; flex-direction: column; overflow: hidden; }
.grid-stack-item-content > .kaart > .kaart-body.strak { overflow-y: auto; flex: 1; min-height: 0; }

/* Krappere cellen in een dashboardblok dan in een tabel op een eigen pagina.
   1,15rem links en rechts is royaal als de tabel het scherm heeft, maar in een
   blok van 449 px kostten vijf kolommen daarmee 184 px aan alleen lucht -- bijna
   een derde van de tabel. Gevolg: een horizontale schuifbalk en een afgekapte
   kolom "Bedrag". Met 0,6rem past "Maandelijkse lasten" weer helemaal en scheelt
   de rekeningentabel 87 px. Buiten het dashboard verandert er niets. */
.grid-stack-item-content .kaart-body.strak table.tabel th,
.grid-stack-item-content .kaart-body.strak table.tabel td {
  padding-left: .6rem;
  padding-right: .6rem;
}

/* --- bewerkmodus --- */
.bewerk-knoppen { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
#bewerk-aan { font-size: 1.15rem; }

/* Het kader om het hele vak heen, niet om de kaart erbinnen: anders valt hij
   bij een blok met een schuifbalk aan de verkeerde kant daarvan. */
body.indeling-bewerken .grid-stack-item-content {
  outline: 2px dashed var(--accent); outline-offset: -2px; border-radius: var(--radius);
}
/* Je pakt het vak overal op, dus mag de cursor dat overal laten zien. Alleen
   de hoek rechtsonder blijft van het formaat wijzigen. */
body.indeling-bewerken .grid-stack-item-content { cursor: move; }
body.indeling-bewerken .grid-stack-item > .ui-resizable-se { cursor: se-resize; }
/* Tijdens het schuiven wil je niet per ongeluk een rekening afvinken. */
body.indeling-bewerken .grid-stack-item-content a,
body.indeling-bewerken .grid-stack-item-content button,
body.indeling-bewerken .grid-stack-item-content select,
body.indeling-bewerken .grid-stack-item-content input { pointer-events: none; }

/* Gridstack tekent zelf een greep rechtsonder; dit geeft hem Grips kleur en
   laat hem alleen zien als je aan het indelen bent. */
/* Gridstack draait dit hoekje zelf -45 graden, waardoor het als een punt naar
   buiten steekt. Rechtgezet valt het samen met de hoek van het vak en leest
   het als een greep in plaats van als een losse punt. */
.grid-stack-item > .ui-resizable-se {
  width: 14px; height: 14px; right: 5px; bottom: 5px;
  background: none; border-right: 3px solid var(--accent);
  border-bottom: 3px solid var(--accent); border-radius: 0 0 3px 0;
  transform: none;
  opacity: 0; transition: opacity .12s ease;
}
body.indeling-bewerken .grid-stack-item > .ui-resizable-se { opacity: .85; }
.grid-stack-item.ui-draggable-dragging { opacity: .85; }
/* De plek waar het vak neerkomt. */
.grid-stack > .grid-stack-placeholder > .placeholder-content {
  background: var(--accent-zacht); border: 2px dashed var(--accent); border-radius: var(--radius);
}

/* Een vak zonder nieuws blijft staan, maar hoeft geen aandacht te trekken. */
.actie.rustig { background: var(--vlak); border-top-color: var(--rand-sterk); }
.actie.rustig .actie-icoon, .actie.rustig .actie-bedrag { opacity: .45; }
.actie.rustig .actie-titel { color: var(--tekst-zacht); }

.actie.te_laat { border-top-color: var(--laat); background: var(--laat-zacht); }
.actie.nu       { border-top-color: var(--nu); background: var(--nu-zacht); }
.actie.binnenkort { border-top-color: var(--straks); background: var(--straks-zacht); }
/* 'rustig' staat hierboven bij de rest van die stand: groen zou het net zo
   hard laten opvallen als de kleuren die wél iets van je vragen. */

/* -------------------------------------------------------------- grafieken */

/* Taart links, legenda rechts, allebei op elkaars midden. Vaste maat voor de
   taart: apexcharts schaalt hem anders naar de beschikbare breedte, waardoor
   dezelfde grafiek in een breed vak veel groter werd dan in een smal vak. */
.grafiek-blok {
  display: flex; align-items: center; gap: 1.5rem;
  padding: .25rem 0;
}
.grafiek { width: 142px; height: 142px; flex: 0 0 142px; }

.grafiek-legenda {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .1rem; min-width: 0; flex: 1;
}
.grafiek-legenda-knop {
  display: flex; align-items: center; gap: .5rem; width: 100%;
  padding: .2rem .3rem; border: 0; border-radius: var(--radius-klein);
  background: transparent; color: var(--tekst-zacht);
  font: inherit; font-size: .82rem; text-align: left; cursor: pointer;
}
.grafiek-legenda-knop:hover { background: var(--vlak-2); color: var(--tekst); }
.grafiek-legenda-knop:focus-visible { outline: 3px solid var(--accent); outline-offset: -1px; }
/* Uitgeklikt punt: nog leesbaar, maar duidelijk niet meegeteld. */
.grafiek-legenda-knop.uit { opacity: .4; text-decoration: line-through; }
.grafiek-stip { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.grafiek-legenda-naam {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.grafiek-legenda-bedrag { margin-left: auto; font-weight: 650; white-space: nowrap; }
.grafiek-legenda-totaal {
  display: flex; align-items: center; gap: .5rem;
  margin-top: .3rem; padding: .35rem .3rem 0;
  border-top: 1px solid var(--rand);
  font-size: .82rem; color: var(--tekst-zacht);
}
.grafiek-legenda-totaal .getal {
  margin-left: auto; font-weight: 700; font-size: .95rem; color: var(--tekst);
}
/* Zonder legenda ernaast staat de taart alleen; dan mag hij het midden pakken. */
.grafiek-blok:not(:has(.grafiek-legenda)) { justify-content: center; }
/* Kleurstip vóór de naam in de tabel, als vervanging van een legenda die
   dezelfde namen zou herhalen. */
.tabel-stip { display: inline-block; margin-right: .45rem; vertical-align: baseline; }
td.met-stip { text-indent: 0; }
/* De bibliotheek zet zijn eigen lettertype neer; dit haalt hem terug naar dat
   van Grip zodat een grafiek niet uit een andere app lijkt te komen. */
.apexcharts-canvas, .apexcharts-canvas * { font-family: inherit !important; }
.apexcharts-tooltip {
  background: var(--vlak) !important; color: var(--tekst) !important;
  border: 1px solid var(--rand-sterk) !important; box-shadow: var(--schaduw-hoog) !important;
}
.apexcharts-tooltip-title {
  background: var(--vlak-2) !important; border-bottom: 1px solid var(--rand) !important;
}

/* ----------------------------------------------------------------- knop */

.knop {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  padding: .55rem .95rem; min-height: 40px;
  border: 1px solid var(--rand-sterk); border-radius: var(--radius-klein);
  background: var(--vlak); color: var(--tekst);
  font: inherit; font-size: .92rem; font-weight: 600;
  cursor: pointer; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, transform .06s ease;
}
.knop:hover { background: var(--vlak-2); text-decoration: none; }
.knop:active { transform: translateY(1px); }
.knop:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

.knop.hoofd { background: var(--accent); border-color: var(--accent); color: var(--op-gevuld); }
.knop.hoofd:hover { background: var(--accent-donker); border-color: var(--accent-donker); }
.knop.goed { background: var(--klaar); border-color: var(--klaar); color: var(--op-gevuld); }
.knop.goed:hover { filter: brightness(.94); }
.knop.gevaar { color: var(--laat); border-color: color-mix(in srgb, var(--laat) 35%, var(--rand)); }
.knop.gevaar:hover { background: var(--laat-zacht); }
.knop.klein { padding: .3rem .6rem; min-height: 32px; font-size: .84rem; }
.knop.breed { width: 100%; }
.knop.kaal { border-color: transparent; background: transparent; }
.knop.kaal:hover { background: var(--vlak-2); }
.knop[disabled] { opacity: .5; cursor: not-allowed; }

.knoppen { display: flex; gap: .5rem; flex-wrap: wrap; }
.knop-groep { display: inline-flex; border-radius: var(--radius-klein); overflow: hidden; border: 1px solid var(--rand-sterk); }
.knop-groep a, .knop-groep button {
  border: 0; border-radius: 0; border-right: 1px solid var(--rand-sterk);
}
.knop-groep > :last-child { border-right: 0; }

/* ---------------------------------------------------------------- badge */

.badge {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .18rem .5rem; border-radius: 999px;
  font-size: .76rem; font-weight: 650; letter-spacing: .01em;
  background: var(--vlak-2); color: var(--tekst-zacht); border: 1px solid var(--rand);
}
.badge.laat   { background: var(--laat-zacht); color: var(--laat); border-color: color-mix(in srgb, var(--laat) 25%, transparent); }
.badge.nu     { background: var(--nu-zacht); color: var(--nu); border-color: color-mix(in srgb, var(--nu) 25%, transparent); }
.badge.straks { background: var(--straks-zacht); color: var(--straks); border-color: color-mix(in srgb, var(--straks) 25%, transparent); }
.badge.klaar  { background: var(--klaar-zacht); color: var(--klaar); border-color: color-mix(in srgb, var(--klaar) 25%, transparent); }
.badge.accent { background: var(--accent-zacht); color: var(--accent-donker); border-color: color-mix(in srgb, var(--accent) 25%, transparent); }

/* ---------------------------------------------------------------- tabel */

.tabel-omhulsel { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.tabel { width: 100%; border-collapse: collapse; font-size: .93rem; }
table.tabel th {
  text-align: left; padding: .65rem 1.15rem; font-size: .76rem; font-weight: 650;
  letter-spacing: .04em; text-transform: uppercase; color: var(--tekst-zachter);
  border-bottom: 1px solid var(--rand); white-space: nowrap; background: var(--vlak-2);
}
table.tabel td { padding: .7rem 1.15rem; border-bottom: 1px solid var(--rand); vertical-align: middle; }
table.tabel tr:last-child td { border-bottom: 0; }
table.tabel tbody tr:hover { background: var(--vlak-2); }
table.tabel td.getal, table.tabel th.getal { text-align: right; font-variant-numeric: tabular-nums; }

/* Een streep tussen de kolommen. Bij zes tekstkolommen naast elkaar loopt
   anders alles in elkaar over en lees je zo een waarde uit de verkeerde kolom. */
table.tabel th + th, table.tabel td + td { border-left: 1px solid var(--rand); }

/* Op een breed scherm rekt een tabel met vijf kolommen alles uit elkaar: de
   naam staat links en het bedrag duizend pixels verderop. Met 'gebundeld'
   slokt de eerste kolom de overtollige ruimte op en blijven datum, status,
   bedrag en knop bij elkaar staan. */
table.tabel.gebundeld td:first-child, table.tabel.gebundeld th:first-child { width: 100%; }
table.tabel.gebundeld td:not(:first-child), table.tabel.gebundeld th:not(:first-child) {
  width: 1%; white-space: nowrap;
}

/* ------------------------------------------------- kolombreedte verstellen */

/* De greep zit in de kop, over de scheidingslijn heen. Alleen zichtbaar als je
   er met de muis bij in de buurt komt, zodat de kop rustig blijft. */
table.tabel th.verstelbaar { position: relative; }
.kolom-greep {
  position: absolute; top: 0; right: -4px; bottom: 0; width: 9px;
  cursor: col-resize; user-select: none; touch-action: none; z-index: 2;
}
.kolom-greep::after {
  content: ""; position: absolute; top: 15%; bottom: 15%; left: 4px; width: 2px;
  background: var(--accent); border-radius: 2px; opacity: 0;
  transition: opacity .12s ease;
}
.kolom-greep:hover::after, .kolom-greep.sleept::after { opacity: 1; }
/* Tijdens het slepen mag de cursor niet omslaan boven andere elementen. */
body.kolom-sleept, body.kolom-sleept * { cursor: col-resize !important; user-select: none; }

/* Zodra de breedtes vastliggen moet te lange tekst binnen zijn kolom blijven.
   Zonder dit loopt een IBAN dwars door de kolom ernaast heen zodra je hem
   smaller maakt. */
table.tabel.kolommen-vast th, table.tabel.kolommen-vast td {
  overflow: hidden; text-overflow: ellipsis;
}

tr.laat td:first-child { box-shadow: inset 3px 0 0 var(--laat); }
tr.nu td:first-child { box-shadow: inset 3px 0 0 var(--nu); }
tr.betaald { opacity: .62; }
tr.betaald .omschrijving { text-decoration: line-through; }

/* --------------------------------------------------------------- formulier */

.veld { margin-bottom: 1rem; }
.veld:last-child { margin-bottom: 0; }
.veld label, .veld-label {
  display: block; font-size: .87rem; font-weight: 600; margin-bottom: .3rem; color: var(--tekst);
}
.veld .hulp { font-size: .8rem; color: var(--tekst-zachter); margin-top: .3rem; }

input[type="text"], input[type="password"], input[type="email"], input[type="number"],
input[type="date"], input[type="tel"], input[type="url"], input[type="month"],
input[type="search"], select, textarea {
  width: 100%; padding: .6rem .75rem; min-height: 42px;
  font: inherit; font-size: .95rem; color: var(--tekst);
  background: var(--vlak); border: 1px solid var(--rand-sterk); border-radius: var(--radius-klein);
  transition: border-color .12s ease, box-shadow .12s ease;
}
input:focus, select:focus, textarea:focus {
  outline: 0; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}
input[type="color"] { padding: .2rem; height: 42px; cursor: pointer; }
textarea { min-height: 80px; resize: vertical; line-height: 1.5; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--tekst-zacht) 50%), linear-gradient(135deg, var(--tekst-zacht) 50%, transparent 50%); background-position: calc(100% - 18px) 19px, calc(100% - 13px) 19px; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 2.2rem; }
input[type="file"] { padding: .5rem; background: var(--vlak-2); }

.euro-veld { position: relative; }
.euro-veld input { padding-left: 1.9rem; font-variant-numeric: tabular-nums; }
.euro-veld::before {
  content: "€"; position: absolute; left: .75rem; top: 50%; transform: translateY(-50%);
  color: var(--tekst-zachter); font-size: .95rem; pointer-events: none;
}

.aanvink {
  display: flex; align-items: flex-start; gap: .6rem; cursor: pointer;
  padding: .6rem .75rem; border: 1px solid var(--rand); border-radius: var(--radius-klein);
  background: var(--vlak-2);
}
.aanvink input { width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--accent); flex-shrink: 0; cursor: pointer; }
.aanvink span { font-size: .9rem; font-weight: 550; }
.aanvink .hulp { font-weight: 400; }
.aanvink:hover { border-color: var(--rand-sterk); }

fieldset { border: 0; padding: 0; margin: 0 0 1.5rem; }
fieldset legend {
  padding: 0; margin-bottom: .75rem; font-size: .78rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--tekst-zachter);
}

.veld-rij { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }

/* --------------------------------------------------------------- melding */

.meldingen { display: grid; gap: .6rem; margin-bottom: 1.25rem; }
.melding {
  padding: .8rem 1rem; border-radius: var(--radius-klein);
  border: 1px solid var(--rand); border-left: 4px solid var(--klaar);
  background: var(--klaar-zacht); font-size: .93rem; font-weight: 500;
}
.melding.fout { border-left-color: var(--laat); background: var(--laat-zacht); }
.melding.info { border-left-color: var(--straks); background: var(--straks-zacht); }

.uitleg {
  padding: .85rem 1rem; border-radius: var(--radius-klein);
  background: var(--accent-zacht); border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
  font-size: .9rem; color: var(--tekst);
}
.uitleg p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- voortgang */

.balk { height: 10px; border-radius: 999px; background: var(--vlak-2); overflow: hidden; border: 1px solid var(--rand); }
/* Effen groen en geen verloop meer. Het eindpunt was hardgecodeerd #4ade80 en
   ging niet mee toen --klaar donkerder werd: in het licht liep de balk van
   donkergroen naar bijna onzichtbaar (1,57:1 tegen de baan) en juist de punt
   is waar je afleest hoe ver je bent. In het donker deed het verloop niets,
   want daar zijn beide uiteinden dezelfde kleur. */
.balk-vul { height: 100%; border-radius: 999px; background: var(--klaar); transition: width .4s ease; }
.balk.dik { height: 16px; }

.staafjes { display: flex; align-items: flex-end; gap: .5rem; height: 90px; }
.staafje { flex: 1; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: .3rem; height: 100%; }
.staafje-vul { width: 100%; background: var(--accent); border-radius: 5px 5px 0 0; min-height: 3px; opacity: .85; }
.staafje:last-child .staafje-vul { opacity: 1; }
.staafje-label { font-size: .72rem; color: var(--tekst-zachter); }

.verdeling { display: grid; gap: .55rem; }
.verdeling-rij { display: grid; grid-template-columns: 1.7rem 1fr auto; gap: .6rem; align-items: center; font-size: .9rem; }
.verdeling-balk { height: 8px; border-radius: 999px; background: var(--vlak-2); overflow: hidden; }
.verdeling-balk span { display: block; height: 100%; border-radius: 999px; }

/* ---------------------------------------------------------------- leeg */

.leeg { padding: 2.5rem 1.5rem; text-align: center; color: var(--tekst-zacht); }
.leeg-icoon { font-size: 2.4rem; margin-bottom: .5rem; }
.leeg h3 { color: var(--tekst); }

/* -------------------------------------------------------------- factuur */

.regels-tabel { width: 100%; border-collapse: collapse; }
.regels-tabel th {
  text-align: left; font-size: .76rem; font-weight: 650; text-transform: uppercase;
  letter-spacing: .04em; color: var(--tekst-zachter); padding: 0 .4rem .4rem; white-space: nowrap;
}
.regels-tabel td { padding: .25rem .4rem; vertical-align: top; }
.regels-tabel input, .regels-tabel select { min-height: 40px; }
.regels-tabel .k-aantal { width: 90px; }
.regels-tabel .k-eenheid { width: 100px; }
.regels-tabel .k-prijs { width: 130px; }
.regels-tabel .k-btw { width: 150px; }
.regels-tabel .k-totaal { width: 110px; text-align: right; font-variant-numeric: tabular-nums; padding-top: .85rem; font-weight: 600; }
.regels-tabel .k-weg { width: 44px; }

/* Vast-bedrag-stand (standaard): verberg de aantal- en eenheidkolommen en
   noem de prijskolom 'Bedrag'. Met het vinkje 'Reken met aantallen' komen ze
   terug en heet de kolom weer 'Prijs per stuk'. De verborgen invoervelden
   blijven hun waarde meesturen (aantal 1, eenheid 'opdracht'). */
.regels-tabel:not(.met-aantallen) .k-aantal,
.regels-tabel:not(.met-aantallen) .k-eenheid { display: none; }
.regels-tabel .label-prijs { display: none; }
.regels-tabel.met-aantallen .label-prijs { display: inline; }
.regels-tabel.met-aantallen .label-bedrag { display: none; }

.totalen { margin-left: auto; max-width: 340px; }
.totalen-rij { display: flex; justify-content: space-between; gap: 2rem; padding: .35rem 0; font-size: .93rem; }
.totalen-rij.eind {
  border-top: 2px solid var(--rand-sterk); margin-top: .35rem; padding-top: .6rem;
  font-size: 1.15rem; font-weight: 700;
}
.totalen-rij .getal { font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- tabbladen */

.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--rand); margin-bottom: 1.25rem; overflow-x: auto; }
.tabs a {
  padding: .6rem .9rem; font-size: .92rem; font-weight: 600; color: var(--tekst-zacht);
  border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;
}
.tabs a:hover { color: var(--tekst); text-decoration: none; }
.tabs a.aan { color: var(--accent); border-bottom-color: var(--accent); }

/* --------------------------------------------------------------- inloggen */

/* `flex: 1` is hier geen opsmuk maar de reden dat de kaart in het midden
   staat. `body` is sinds het paneel links een flexcontainer. Op inloggen,
   welkom en de foutpagina is er geen paneel en is dit vak het enige flexkind,
   en een flexkind groeit uit zichzelf niet: het kromp tot de breedte van de
   kaart (285 px op een scherm van 1443 px). `place-items: center` centreerde
   daarna keurig binnen die 285 px, dus de kaart plakte tegen de linkerrand
   met de rest van het scherm leeg. Met `flex: 1` vult het vak het scherm en
   centreert het waar je het verwacht. */
.midden-scherm {
  flex: 1;
  min-height: 100vh; display: grid; place-items: center; padding: 1.5rem;
  background: linear-gradient(160deg, var(--achtergrond), var(--vlak-2));
}
.midden-kaart { width: 100%; max-width: 430px; }

/* ------------------------------------------------------------- responsive */

/* Grip is een bureaubladtoepassing; smalle schermen worden niet getest of
   onderhouden. Wat hieronder staat voorkomt alleen dat het onleesbaar wordt. */
@media (max-width: 1200px) {


}

@media (max-width: 860px) {
  .paneel { width: 64px; }
  .paneel .paneel-tekst { display: none; }
  .paneel-knop { display: none; }

  h1 { font-size: 1.4rem; }
  .kaart-body { padding: 1rem; }
  table.tabel th, table.tabel td { padding: .6rem .8rem; }
  .verberg-mobiel { display: none !important; }
  .regels-tabel, .regels-tabel tbody, .regels-tabel tr, .regels-tabel td { display: block; width: 100%; }
  .regels-tabel thead { display: none; }
  .regels-tabel tr {
    border: 1px solid var(--rand); border-radius: var(--radius-klein);
    padding: .6rem; margin-bottom: .75rem; background: var(--vlak-2);
  }
  .regels-tabel td { padding: .2rem 0; }
  .regels-tabel td::before {
    content: attr(data-label); display: block; font-size: .75rem; font-weight: 650;
    text-transform: uppercase; letter-spacing: .04em; color: var(--tekst-zachter); margin-bottom: .15rem;
  }
  .regels-tabel .k-totaal { text-align: left; padding-top: .4rem; }
  .totalen { max-width: none; }
}

@media print {
  .paneel, .knoppen, .knop, .tabs, .meldingen { display: none !important; }
  body { background: #fff; display: block; }
  .kaart { box-shadow: none; border-color: #ccc; }
}
