:root {
    color-scheme: light dark;

    --bg: #f5f6f8;
    --surface: #ffffff;
    --surface-2: #f9fafb;
    --ink: #111827;
    --muted: #6b7280;
    --line: #e4e7ec;
    --accent: #dc2626;
    --accent-ink: #ffffff;
    /* Rustige tweede kleur voor tekst: titels en links (MEL-134). */
    --sub: #334155;

    /* Eén kleur per status, zodat je de lijst kunt lezen zonder te lezen. */
    --open: #b45309;
    --open-bg: #fef3c7;
    --open-line: #f59e0b;
    --done: #047857;
    --done-bg: #d1fae5;
    --done-line: #10b981;
    --archived: #6b7280;
    --archived-line: #d1d5db;
    /* Ter review (MEL-100): eigen kleur, los van open (oranje) en gesloten (groen). */
    --review: #6d28d9;
    --review-bg: #ede9fe;
    --review-line: #8b5cf6;
    /* Wacht op antwoord (MEL-154): ligt over open heen, dus een eigen tint die opvalt
       zonder met open (oranje) of ter review (paars) te botsen. */
    --wacht: #0369a1;
    --wacht-bg: #e0f2fe;
    --wacht-line: #0ea5e9;
    /* Nieuwe reactie (MEL-212): de klant heeft gereageerd en wij zijn aan zet - dat moet opvallen. */
    --reactie: #be123c;
    --reactie-bg: #ffe4e6;
    --reactie-line: #f43f5e;
    /* Mee bezig (MEL-256): de tickets waar je nu aan werkt, als tabjes onder de menubalk. */
    --bezig: #c2410c;
    --bezig-bg: #ffedd5;
    /* Eén kleur voor alle Grafiek::-lijnen/staven (MEL-68/MEL-99) - vroeger alleen op .dash gezet. */
    --viz-1: #d12f2f;

    --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .1);
    --shadow-lift: 0 6px 16px rgba(16, 24, 40, .1);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #0f1115;
        --surface: #171a21;
        --surface-2: #1d212a;
        --ink: #e7e9ee;
        --muted: #949cab;
        --line: #272c37;
        --accent: #f87171;
        --accent-ink: #1a0b0b;
        --sub: #b0bdcd;

        --open: #fbbf24;
        --open-bg: #3b2f0d;
        --open-line: #d97706;
        --done: #34d399;
        --done-bg: #0d2c22;
        --done-line: #059669;
        --archived: #8b94a3;
        --archived-line: #39404e;
        --review: #c4b5fd;
        --review-bg: #2e1065;
        --review-line: #8b5cf6;
        --wacht: #7dd3fc;
        --wacht-bg: #0c2b3f;
        --wacht-line: #0ea5e9;
        --reactie: #fda4af;
        --reactie-bg: #4c0519;
        --reactie-line: #f43f5e;
        --bezig: #fdba74;
        --bezig-bg: #3a1a08;
        --viz-1: #ef4444;

        --shadow: 0 1px 2px rgba(0, 0, 0, .5);
        --shadow-lift: 0 8px 20px rgba(0, 0, 0, .55);
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    /* Vangnet tegen horizontale scroll op mobiel (MEL-82): een lange ongebroken tekst (bv. een
       URL in een omschrijving of reactie) kan de pagina anders breder maken dan het scherm. De
       elementen die zelf bewust opzij scrollen (.snippet, table.keys) hebben hun eigen
       overflow-x: auto, dus die blijven gewoon werken. */
    overflow-x: hidden;
}

a { color: var(--sub); }

.topbar {
    display: flex; align-items: center; gap: 28px;
    padding: 0 24px; height: 58px;
    background: var(--surface); color: var(--ink);
    border-bottom: 1px solid var(--line);
    position: sticky; top: 0; z-index: 10;
}
.topbar .brand { color: var(--ink); font-weight: 700; font-size: 17px; text-decoration: none; letter-spacing: -.2px; }
.topbar .brand::before {
    content: ''; display: inline-block; width: 9px; height: 9px; margin-right: 8px;
    border-radius: 50%; background: #dc2626; vertical-align: 1px;
}
.topbar nav { display: flex; gap: 18px; flex: 1; }
.topbar nav a {
    color: var(--muted); text-decoration: none; font-size: 14px; padding: 6px 10px;
    border-radius: 6px; transition: background .12s, color .12s;
}
.topbar nav a:hover { color: var(--ink); background: var(--surface-2); }
.topbar nav a.active { color: var(--ink); background: var(--surface-2); font-weight: 600; }

/* Balk met de lopende moneybird-timer (MEL-91 vervolg), direct onder de topbar - sticky op
   dezelfde manier, met de topbar-hoogte (58px) als top zodat ze niet overlappen. */
.mb-timer-balk {
    display: flex; align-items: center; gap: 10px;
    padding: 6px 24px; font-size: 13px; color: var(--ink);
    background: color-mix(in srgb, var(--accent) 12%, var(--surface));
    border-bottom: 1px solid var(--line);
    position: sticky; top: 58px; z-index: 9;
}
/* [hidden] en .mb-timer-balk wegen even zwaar (allebei 1 klasse/attribuut), dus zonder dit
   wint de eigen stylesheet altijd van de standaard [hidden] { display:none } van de browser -
   de balk bleef daardoor leeg in beeld staan zolang er geen timer liep (MEL-93). */
.mb-timer-balk[hidden] { display: none; }
.mb-timer-stip {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%; flex: none;
    background: #16a34a; animation: mb-timer-pols 1.6s ease-in-out infinite;
}
#mb-timer-duur { font-variant-numeric: tabular-nums; font-weight: 600; margin-left: auto; }
@keyframes mb-timer-pols { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .mb-timer-stip { animation: none; } }

/* Mee bezig (MEL-256): de tickets waar je nu aan werkt als tabjes onder de menubalk. Niet sticky:
   de timerbalk erboven is dat al, en twee plakkende balken vreten op een laptop te veel hoogte. */
.bezig-tabs {
    display: flex; align-items: center; gap: 6px; padding: 6px 24px;
    background: var(--surface); border-bottom: 1px solid var(--line);
    overflow-x: auto; scrollbar-width: thin;
}
.bezig-label { flex: none; margin-right: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; color: var(--bezig); }
.bezig-tab {
    display: flex; align-items: center; flex: none; max-width: 280px;
    background: var(--surface-2); border: 1px solid var(--line); border-radius: 8px;
}
.bezig-tab:hover { border-color: var(--bezig); }
.bezig-tab.is-huidig { background: var(--bezig-bg); border-color: var(--bezig); }
.bezig-tab a { display: flex; align-items: center; min-width: 0; padding: 4px 4px 4px 8px; text-decoration: none; color: var(--ink); font-size: 13px; }
.bezig-tab .code { flex: none; margin-right: 6px; font-size: 11px; }
.bezig-titel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bezig-tab.is-huidig .bezig-titel { font-weight: 600; }
.bezig-tab form { display: flex; margin: 0; }
.bezig-tab button {
    margin: 0; padding: 0 8px; height: 26px; border: 0; background: none; box-shadow: none;
    color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer; border-radius: 0 8px 8px 0;
}
.bezig-tab button:hover { color: var(--ink); background: var(--surface); }
/* Op een breed scherm staat rechts de strook met recent bekeken tickets (fixed, vanaf top 100px):
   de tabjes houden daar ruimte voor vrij, anders schuiven ze er bij veel tabjes onderdoor. */
@media (min-width: 1780px) { .bezig-tabs { padding-right: 230px; } }

main { max-width: 1360px; margin: 0 auto; padding: 28px 24px 64px; }

.page-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
/* Paginatitels in de merkkleur (rood), net als de stip in het logo. */
.page-head h1 { margin: 0; font-size: 22px; color: var(--sub); }
/* De titel hoort altijd op één regel te passen (MEL-151): hij is het kortste stuk
   van de kop, maar als flex-item kromp hij als eerste en viel "SWI Purchase" uiteen
   over twee regels terwijl de tellerregel ernaast ruim op één regel stond. Nu wijkt
   die regel uit in plaats van de titel.
   Niet op een ticketpagina (MEL-162): daar is de titel geen korte paginanaam maar de
   tekst van de melder, en die hoort juist wél af te breken - anders loopt hij achter de
   ticketcode en de kopieerknop langs. */
.page-head:not(.issue-page-head) h1 { flex: 0 0 auto; white-space: nowrap; }
.page-head p.muted { min-width: 0; }

/* Ticketdetail: het afvink-/terug-rondje, de titel, de ticketcode/copy-knop en het
   omgevingslabel op één regel; alleen de status-tag (ter review) staat apart in de zijbalk
   bij Status, die hoort inhoudelijk bij het statusveld daar (MEL-107, MEL-110, MEL-113,
   MEL-114 - een paar rondes heen en weer voor deze indeling stond). */
.issue-page-head { align-items: flex-start; }
.issue-titelblok { min-width: 0; flex: 1 1 auto; }
.issue-titel { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 0; font-size: 22px; line-height: 1.35; }
.issue-status-controle { display: inline-flex; align-items: center; gap: 8px; flex: none; }
/* Een lange titel breekt af op spaties, en een woord dat zelf al te lang is (een url
   die de melder erin plakte) breekt waar het moet - anders loopt hij de code voorbij. */
.issue-titel .title-text { flex: 1 1 240px; min-width: 0; white-space: normal; overflow-wrap: anywhere; }
/* Code en copy-knop als één groepje, niet twee losse dingen naast elkaar. */
.code-groep { display: inline-flex; align-items: center; gap: 6px; }
.code-groep .code { margin-right: 0; }
.code-groep .copy-link-knop {
    width: 24px; height: 24px; margin: 0; vertical-align: 0;
    border: 1px solid var(--line); border-radius: 6px;
}
.code-groep .copy-link-knop svg { width: 14px; height: 14px; }
.muted { color: var(--muted); font-size: 13px; margin: 0; font-weight: 400; }
.back { margin: 0 0 12px; font-size: 13px; }
.issue-nav { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.issue-nav .back { margin: 0; }
.pager { margin: 0 0 12px; font-size: 13px; display: flex; gap: 16px; }

/* Klik-om-te-bewerken: titel (inline in de h1) en omschrijving. Het
   invoerveld moet er hetzelfde uitzien als de tekst zelf - geen kader of
   achtergrond die verraadt dat het een formulierveld is. */
.editable { cursor: text; border-radius: 6px; transition: background .12s; }
.editable:not(.editing):hover, .editable:not(.editing):focus-visible { background: var(--surface-2); outline: none; }
h1 .editable { padding: 2px 6px; margin: -2px -6px; }
.description.placeholder { color: var(--muted); font-style: italic; }
.inline-edit {
    display: block; width: 100%; font: inherit; font-weight: inherit; line-height: inherit; color: inherit;
    padding: 0; margin: 0; border: 0; background: none; outline: none;
}
h1 .inline-edit { font-size: 22px; }
textarea.inline-edit { resize: vertical; min-height: 100px; overflow: hidden; }
/* Omschrijving (MEL-196): bewerken via een knopje rechtsboven, niet door op de tekst
   te klikken - zo blijven links klikbaar en tekst selecteerbaar. */
.editable.met-knop:not(.placeholder) { cursor: auto; position: relative; }
.editable.met-knop:not(.placeholder):not(.editing):hover { background: var(--surface); }
.bewerk-knop {
    float: right; margin: -6px -6px 6px 10px; padding: 3px 9px; font: inherit; font-size: 12px;
    color: var(--muted); background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
    opacity: .7; transition: opacity .12s, color .12s;
}
.editable.met-knop:hover .bewerk-knop, .bewerk-knop:focus-visible { opacity: 1; color: inherit; }
.inline-edit.fout { outline: 2px solid #dc2626; outline-offset: 3px; border-radius: 4px; }

.flash { padding: 10px 14px; border-radius: 6px; font-size: 14px; }
.flash.ok { background: var(--done-bg); color: var(--done); }
.flash a { color: inherit; font-weight: 600; text-decoration: underline; }
.flash.error { background: #fee2e2; color: #b91c1c; }

.filters { display: flex; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.filters select, .filters input, .filters button {
    padding: 8px 11px; border: 1px solid var(--line); border-radius: 8px;
    font-size: 14px; background: var(--surface); color: var(--ink);
}
.filters input { flex: 1; min-width: 180px; }
.filters button { background: var(--accent); color: var(--accent-ink); border-color: transparent; cursor: pointer; font-weight: 600; }
/* Snelfilters (MEL-214): status en soort als labels om aan en uit te klikken, net als de projectknoppen in de
   planning. Het vinkje zelf is verstopt; een aangeklikt label kleurt in de kleur van zijn status. */
.snelfilters { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.snelfilter {
    --kl: var(--accent);
    display: inline-flex; align-items: center; gap: 4px; padding: 4px 11px 4px 9px; border-radius: 999px; font-size: 13px;
    background: var(--surface); color: var(--ink); border: 1px solid var(--line); cursor: pointer; user-select: none;
}
.snelfilter::before { content: ''; width: 8px; height: 8px; margin-right: 3px; border-radius: 50%; background: var(--kl); opacity: .45; }
/* min-width/padding/border op nul: anders erft het verstopte vinkje de 180px van `.filters input` en steekt het op
   een smal scherm buiten beeld, waardoor de hele pagina horizontaal gaat scrollen (MEL-251). */
.snelfilter { position: relative; }
.snelfilter input { position: absolute; left: 0; top: 0; opacity: 0; width: 1px; height: 1px; min-width: 0; padding: 0; border: 0; pointer-events: none; }
.snelfilter:hover { border-color: var(--kl); }
.snelfilter:has(input:focus-visible) { outline: 2px solid var(--kl); outline-offset: 1px; }
.snelfilter:has(input:checked) { border-color: var(--kl); background: color-mix(in srgb, var(--kl) 18%, var(--surface)); font-weight: 600; }
.snelfilter:has(input:checked)::before { opacity: 1; }
.snelfilter.status-open { --kl: var(--open-line); }
.snelfilter.status-reactie { --kl: var(--reactie-line); }
.snelfilter.status-wacht { --kl: var(--wacht-line); }
.snelfilter.status-ter-review { --kl: var(--review-line); }
.snelfilter.status-closed { --kl: var(--done-line); }
.snelfilter-scheiding { width: 1px; height: 18px; margin: 0 4px; background: var(--line); }

.empty { padding: 48px; text-align: center; color: var(--muted); background: var(--surface); border: 1px dashed var(--line); border-radius: 12px; }

.issues { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.issue {
    display: flex; gap: 16px; padding: 14px 16px 14px 13px;
    background: var(--surface); border: 1px solid var(--line);
    border-left: 4px solid var(--open-line); border-radius: 10px;
    box-shadow: var(--shadow);
    transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}
.issue:hover { box-shadow: var(--shadow-lift); transform: translateY(-1px); }
/* Afgehandeld mag rustiger ogen, maar moet leesbaar blijven - vandaar kleur
   op de rand in plaats van de hele rij vervagen. */
.issue.is-closed { border-left-color: var(--done-line); }
.issue.is-review { border-left-color: var(--review-line); }
/* Na is-review, want een ticket dat op antwoord wacht is het dringendst van de twee. */
.issue.is-wacht { border-left-color: var(--wacht-line); }
/* Daarna nog: een nieuwe reactie van de klant gaat boven alles, daar zijn wij aan zet (MEL-212). */
.issue.is-reactie { border-left-color: var(--reactie-line); }
.issue.is-archived { border-left-color: var(--archived-line); }
.issue .thumb {
    flex: 0 0 148px; height: 92px; overflow: hidden; border-radius: 8px;
    background: var(--surface-2); border: 1px solid var(--line);
    display: flex; align-items: center; justify-content: center;
}
.issue .thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
/* Geen screenshot (MEL-201): kleurvlakken in de klantkleur, een vervagend puntenraster en het ticketnummer groot,
   in dezelfde stijl als .project-kunst op de projectenpagina. Alleen CSS; licht en donker volgen de variabelen. */
.issue .thumb:has(.ticket-kunst) { position: relative; border-color: color-mix(in srgb, var(--kl, var(--line)) 30%, var(--line)); }
.ticket-kunst {
    position: absolute; inset: 0; overflow: hidden;
    background:
        radial-gradient(120% 100% at 0% 0%, color-mix(in srgb, var(--kl) 38%, transparent) 0%, transparent 62%),
        radial-gradient(90% 90% at 100% 100%, color-mix(in srgb, var(--kl) 26%, transparent) 0%, transparent 66%),
        linear-gradient(160deg, color-mix(in srgb, var(--kl) 10%, var(--surface-2)), var(--surface-2));
}
.ticket-kunst::before {
    content: ''; position: absolute; inset: 0;
    background-image: radial-gradient(color-mix(in srgb, var(--kl) 60%, transparent) 1.1px, transparent 1.5px);
    background-size: 10px 10px; opacity: .5;
    -webkit-mask-image: linear-gradient(205deg, #000 0%, transparent 70%); mask-image: linear-gradient(205deg, #000 0%, transparent 70%);
}
.ticket-kunst-prefix {
    position: absolute; left: 9px; top: 8px; z-index: 1;
    font: 700 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .5px;
    color: color-mix(in srgb, var(--kl) 75%, var(--ink));
}
.ticket-kunst-nummer {
    position: absolute; right: 9px; bottom: 4px; z-index: 1;
    font: 800 46px/1 ui-sans-serif, system-ui, sans-serif; letter-spacing: -2px;
    color: color-mix(in srgb, var(--kl) 80%, var(--ink));
}
.ticket-kunst-nummer.smal { font-size: 36px; letter-spacing: -1.5px; }
.ticket-kunst-tekst { position: absolute; left: 9px; top: 23px; z-index: 1; font-size: 9px; color: var(--muted); }
.issue-top {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px 9px; margin: 0 0 5px;
    font-size: 12px; line-height: 1;
}
/* Status in kleur én in woord: kleur om op te scannen, woord omdat kleur
   alleen niet voor iedereen leesbaar is. */
.state {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600; letter-spacing: .1px;
}
.state .dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 7px; background: currentColor; }
.state-open { color: var(--open); }
.state-open .dot { box-shadow: 0 0 0 3px var(--open-bg); }
.state-done { color: var(--done); }
.state-done .dot { box-shadow: 0 0 0 3px var(--done-bg); }
.state-review { color: var(--review); }
.state-review .dot { box-shadow: 0 0 0 3px var(--review-bg); }
.state-prive { color: var(--muted); }
.state-prive .dot { box-shadow: 0 0 0 3px var(--surface-2); }
.issue-code {
    font: 500 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: .3px; color: var(--muted);
}
/* Linkje-kopiëren-knopje (MEL-94), naast een ticketcode in de lijst en op de detailpagina. */
.copy-link-knop {
    display: inline-flex; align-items: center; justify-content: center;
    width: 18px; height: 18px; padding: 0; margin: 0 -2px;
    border: 0; border-radius: 4px; background: transparent; color: var(--muted);
    cursor: pointer; vertical-align: -4px;
}
.copy-link-knop:hover { color: var(--accent); background: var(--surface-2); }
.copy-link-knop svg { width: 12px; height: 12px; }
.copy-link-knop.is-gekopieerd { color: #16a34a; }
/* Bewerken/verwijderen bij een reactie als icoontjes (MEL-197), zelfde maat als de kopieerknop. */
.reactie-acties { margin-left: auto; display: flex; gap: 2px; }
.icoon-knop {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; padding: 0;
    border: 0; border-radius: 4px; background: transparent; color: var(--muted);
    cursor: pointer;
}
.icoon-knop:hover { color: var(--accent); background: var(--surface-2); }
.icoon-knop.gevaar:hover { color: #dc2626; }
.icoon-knop svg { width: 14px; height: 14px; }
.issue-project { font-size: 12px; color: var(--sub); font-weight: 600; text-decoration: none; }
.issue-project:hover { text-decoration: underline; }
.chip {
    padding: 1px 7px; border-radius: 999px; background: var(--surface-2);
    color: var(--muted); font-size: 11px; border: 1px solid var(--line);
}

/* De titel is waar je op scant, dus die krijgt het meeste gewicht - niet het
   ticketnummer, dat alleen een verwijzing is. */
.issue-title {
    display: block; font-weight: 600; font-size: 16px; color: var(--ink);
    text-decoration: none; margin-bottom: 5px; line-height: 1.35;
    letter-spacing: -.1px;
}
.issue-title:hover { color: var(--sub); }
.issue .meta { margin: 0; font-size: 13px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.issue .meta .vervallen { color: #dc2626; font-weight: 600; }
.issue-body { min-width: 0; }
.tag {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 9px; border-radius: 999px;
    background: var(--surface-2); color: var(--muted);
    font-size: 12px; font-weight: 500; border: 1px solid var(--line);
}
.tag.project { background: transparent; color: var(--sub); border-color: transparent; padding-left: 0; font-weight: 600; }
.tag.status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.tag.status-open { background: var(--open-bg); color: var(--open); border-color: transparent; }
.tag.status-closed { background: var(--done-bg); color: var(--done); border-color: transparent; }
.tag.closed { background: var(--surface-2); color: var(--archived); }
.tag.ter-review { background: var(--review-bg); color: var(--review); border-color: transparent; }
.tag.wacht { background: var(--wacht-bg); color: var(--wacht); border-color: transparent; white-space: nowrap; }
.tag.bezig { background: var(--bezig-bg); color: var(--bezig); border-color: transparent; white-space: nowrap; font-weight: 600; }
.tag.gesnoozed { background: var(--surface-2); color: var(--muted); white-space: nowrap; }
/* Snoozen tot een gekozen dag (MEL-216/217): de tekst boven het datumveld, anders drukt het veld in het smalle menu
   de tekst samen tot één letter per regel. */
.status-kiezer .snooze-datum label { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; color: var(--ink); }
.status-kiezer .snooze-datum input[type=date] { width: 100%; box-sizing: border-box; padding: 4px 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--ink); font: inherit; font-size: 13px; }
.tag.reactie { background: var(--reactie-bg); color: var(--reactie); border-color: transparent; white-space: nowrap; font-weight: 600; }

/* Het reactieformulier op de publieke pagina's (/r/ en /d/). Die pagina's lenen deze stylesheet
   maar staan buiten het dashboard, dus de velden kregen hier de kale browserstijl: label en veld
   op een regel, een invoerveld zonder rand of ruimte (MEL-156). */
.publieke-reactie .veld { margin: 0 0 14px; }
.publieke-reactie label {
    display: block; margin-bottom: 5px; font-size: 13px; font-weight: 600; color: var(--sub);
}
.publieke-reactie label .muted { font-weight: 400; }
.publieke-reactie input[type="text"],
.publieke-reactie input:not([type]),
.publieke-reactie textarea {
    display: block; width: 100%; box-sizing: border-box; padding: 10px 12px;
    border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2);
    color: inherit; font: inherit;
}
.publieke-reactie input:focus, .publieke-reactie textarea:focus {
    border-color: var(--accent); outline: none;
}
.publieke-reactie input[type="file"] { display: block; max-width: 100%; font-size: 13px; }
/* Een bijlage bij een reactie op de publieke pagina: dezelfde vorm als in het dashboard, maar
   zonder vergrootglas-cursor - daar hoort een lightbox bij en die staat op die kale pagina niet. */
.comment-shot.publiek { max-height: 420px; cursor: default; }

/* Uren wegstrepen tegen een vaste-prijsfactuur (MEL-164): een keuzelijst waarin je per regel
   aanvinkt, en op de klantpagina het logboek van wat er al weg is. */
.wegstreep-form label { display: block; font-size: 13px; font-weight: 600; color: var(--sub); margin-bottom: 5px; }
.wegstreep-form input[name="factuur_nummer"] {
    display: block; margin: 0 0 16px; max-width: 420px; width: 100%; box-sizing: border-box;
    padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface-2); color: inherit; font: inherit;
}
.wegstreep-form input[name="factuur_nummer"]:focus { border-color: var(--accent); outline: none; }
.wegstreep-tabel, .afboekingen-tabel { width: 100%; border-collapse: collapse; font-size: 13px; }
.wegstreep-tabel th, .afboekingen-tabel th {
    text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .4px;
    color: var(--muted); font-weight: 600; padding: 6px 8px; border-bottom: 1px solid var(--line);
}
.wegstreep-tabel td, .afboekingen-tabel td { padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.wegstreep-tabel td.getal, .wegstreep-tabel th.getal,
.afboekingen-tabel td.getal { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wegstreep-tabel tr:last-child td, .afboekingen-tabel tr:last-child td { border-bottom: 0; }
.afboekingen { margin-top: 12px; }
.afboekingen summary { font-size: 13px; color: var(--sub); cursor: pointer; }
.afboekingen > table { margin-top: 8px; }
.afboekingen .muted { margin: 8px 0 0; font-size: 12px; }
.afboekingen form { display: inline; }
/* Twee losse acties i.p.v. de gewone vinkknop-toggle (MEL-100 kent alleen open/closed): elk
   een eigen rondje in dezelfde stijl als .status-check, zodat "afronden" ook echt aanvoelt
   als het afvinkrondje - niet als kale tekstlinks naast de tag (MEL-102). */
.review-actie {
    width: 26px; height: 26px; padding: 0;
    border: 2px solid var(--line); border-radius: 50%; background: var(--surface);
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer; transition: background .15s ease, border-color .15s ease;
}
.review-actie svg { width: 14px; height: 14px; }
.review-actie.terug { color: var(--muted); }
.review-actie.terug:hover { border-color: var(--accent); color: var(--accent); }
.review-actie.afronden { background: #16a34a; border-color: #16a34a; }
.review-actie.afronden:hover { background: #15803d; border-color: #15803d; }
.tag.todo { background: var(--accent); color: var(--accent-ink); border-color: transparent; text-transform: uppercase; letter-spacing: .4px; font-size: 11px; }

.due-date-form { display: inline-block; }
.due-date-form input[type=date], .due-date-form input[type=time] {
    padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px;
    font: inherit; background: var(--surface-2); color: var(--ink);
}

/* Grote checkbox vóór de ticketcode, Basecamp-stijl: dat is de ene handeling
   die je op vrijwel elke melding doet, dus die verdient meer gewicht dan een
   knop tussen de rest (tussentijdse feedback op MEL-51). Een <button> i.p.v.
   een native checkbox-input: is zo even makkelijk met toetsenbord/scherm-
   lezer te bedienen als de rest van de pagina. Klikken gaat via fetch()
   (MEL-55) - de omringende <form> blijft in de HTML staan als terugval voor
   als JS een keer niet laadt. */
.status-check-form { display: inline-flex; vertical-align: 0; margin-right: 2px; }
.status-check {
    width: 26px; height: 26px; padding: 0; border: 2px solid var(--line); border-radius: 50%;
    background: var(--surface); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background .15s ease, border-color .15s ease;
}
.status-check:hover { border-color: var(--accent); }
.status-check.is-done { background: #16a34a; border-color: #16a34a; }
.status-check svg {
    width: 15px; height: 15px; stroke: #fff; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round;
    fill: none; opacity: 0; transition: opacity .1s ease;
}
.status-check.is-done svg { opacity: 1; }
.status-check svg polyline { stroke-dasharray: 16; stroke-dashoffset: 16; }
.status-check.is-done svg polyline { stroke-dashoffset: 0; transition: stroke-dashoffset .25s ease .05s; }
/* Klein feestje bij het afvinken (MEL-55: "is toch leuk om een ticket af te
   vinken") - alleen bij het dichtklikken, niet bij heropenen, en JS zet de
   klasse er telkens opnieuw op (een animatie herhaalt niet vanzelf als de
   klasse al stond). */
.issue-actions .status-check { padding: 0; border: 2px solid var(--line); border-radius: 50%; background: var(--surface); }
.issue-actions .status-check:hover { border-color: var(--accent); }
.issue-actions .status-check.is-done { background: #16a34a; border-color: #16a34a; }
.issue-actions .status-check.klein { width: 26px; height: 26px; }
.issue-actions .status-check.klein svg { width: 15px; height: 15px; }
.status-check.klein { width: 20px; height: 20px; border-width: 2px; }
.status-check.klein svg { width: 12px; height: 12px; }
.status-check-form.in-lijst { margin: 0 6px 0 0; vertical-align: middle; }
.status-check.pop { animation: meldr-check-pop .4s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes meldr-check-pop {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.3); }
    60%  { transform: scale(.92); }
    100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
    .status-check.pop { animation: none; }
    .status-check.is-done svg polyline { transition: none; }
}

/* Losse integraties (GitHub, Basecamp, ...) achter een "meer acties"-menu,
   zelfde <details>-patroon als .gebruikersmenu in de topbar - zo blijft de
   titelbalk even breed als er ooit een derde koppeling bijkomt (MEL-51). */
.head-actions details { position: relative; }
.head-actions details summary {
    display: flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); border-radius: 8px;
    color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer; list-style: none; user-select: none;
}
.head-actions details summary::-webkit-details-marker { display: none; }
.head-actions details summary:hover, .head-actions details[open] summary { color: var(--ink); border-color: var(--ink); }
.head-actions details .menu-lijst {
    position: absolute; right: 0; top: calc(100% + 6px); min-width: 200px; padding: 6px; z-index: 20;
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-lift);
}
.head-actions details .menu-lijst form { margin: 0; }
.head-actions details .menu-lijst a, .head-actions details .menu-lijst button {
    display: block; width: 100%; padding: 8px 10px; border: 0; border-radius: 6px; background: none;
    color: var(--ink); text-decoration: none; font-size: 14px; text-align: left; cursor: pointer; font: inherit;
}
.head-actions details .menu-lijst a:hover, .head-actions details .menu-lijst button:hover { background: var(--surface-2); }

/* Statusbadge in de zijbalk klikbaar (MEL-125): zelfde <details>-patroon als hierboven, de tag
   zelf is de summary zodat het klikken er niet anders uitziet dan de badge nu al doet. */
.status-kiezer { position: relative; display: inline-block; }
.status-kiezer summary { cursor: pointer; list-style: none; user-select: none; }
.status-kiezer summary::-webkit-details-marker { display: none; }
.status-kiezer .menu-lijst {
    position: absolute; left: 0; top: calc(100% + 6px); min-width: 190px; padding: 6px; z-index: 20;
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-lift);
}
.status-kiezer .menu-lijst form { margin: 0; }
.status-kiezer .menu-lijst button {
    display: block; width: 100%; padding: 8px 10px; border: 0; border-radius: 6px; background: none;
    color: var(--ink); font-size: 14px; text-align: left; cursor: pointer; font: inherit;
}
.status-kiezer .menu-lijst button:hover { background: var(--surface-2); }

/* minmax(0, 1fr) i.p.v. 1fr (MEL-252): een kale 1fr is minmax(auto, 1fr) en groeit
   dan mee met de breedste onafbreekbare regel erin - op mobiel duwde de nowrap-titel
   van een gekoppelde pull request de hele pagina zo naar 672px breed. */
.detail { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 20px; align-items: start; }
@media (max-width: 860px) { .detail { grid-template-columns: minmax(0, 1fr); } }
/* max-height: een portrait screenshot (mobiel, in het echt vaak 3x zo hoog
   als breed) trekt de hele pagina anders schreeuwend lang uit. Bij een
   gewone liggende screenshot blijft max-width de bepalende grens, zoals
   voorheen - alleen bij een staande afbeelding grijpt de hoogtegrens in. */
.detail-main .screenshot { max-width: 100%; max-height: 70vh; width: auto; height: auto; display: block; margin: 0 auto; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); cursor: zoom-in; }
.description { margin-top: 16px; padding: 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; overflow-wrap: anywhere; }

/* Markdown-opmaak in omschrijving en reacties (MEL-89): koppen, code, lijstjes en
   taaklijstjes renderen nu i.p.v. de tekens (##, **, `, - [ ]) er letterlijk bij te
   tonen. white-space: pre-line is weg - dat was voor platte tekst, en botst nu met de
   marges die de blok-elementen (h1-h4, p, ul) zelf al meebrengen. */
.description :first-child, .comment-body :first-child { margin-top: 0; }
.description :last-child, .comment-body :last-child { margin-bottom: 0; }
.description h1, .description h2, .description h3, .description h4,
.comment-body h1, .comment-body h2, .comment-body h3, .comment-body h4 { margin: 16px 0 8px; line-height: 1.3; }
.description h1, .comment-body h1 { font-size: 20px; }
.description h2, .comment-body h2 { font-size: 17px; }
.description h3, .comment-body h3 { font-size: 15px; }
.description h4, .comment-body h4 { font-size: 14px; }
.description p, .comment-body p { margin: 0 0 10px; }
.description ul, .description ol, .comment-body ul, .comment-body ol { margin: 0 0 10px; padding-left: 22px; }
.description li, .comment-body li { margin: 2px 0; }
.description li > ul, .description li > ol, .comment-body li > ul, .comment-body li > ol { margin-bottom: 0; }
.description code, .comment-body code {
    padding: 1px 5px; border-radius: 4px; background: var(--surface-2);
    font: 13px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace;
}
.description pre, .comment-body pre { margin: 0 0 10px; padding: 10px 12px; border-radius: 8px; background: var(--surface-2); overflow-x: auto; }
.description pre code, .comment-body pre code { padding: 0; background: none; }
.description blockquote, .comment-body blockquote { margin: 0 0 10px; padding: 2px 12px; border-left: 3px solid var(--line); color: var(--muted); }
.description hr, .comment-body hr { margin: 14px 0; border: 0; border-top: 1px solid var(--line); }
.description table, .comment-body table { border-collapse: collapse; margin: 0 0 10px; font-size: 13px; }
.description th, .description td, .comment-body th, .comment-body td { border: 1px solid var(--line); padding: 4px 8px; }
.description a, .comment-body a { color: var(--sub); }
/* Een taaklijstje (- [ ]) krijgt van CommonMark een gewoon <li> met een checkbox erin -
   het bolletje ervoor oogt dan raar naast de checkbox. */
.description li:has(input[type=checkbox]), .comment-body li:has(input[type=checkbox]) { list-style: none; margin-left: -22px; }
.description input[type=checkbox], .comment-body input[type=checkbox] { margin-right: 6px; }
.detail-side { padding: 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; font-size: 14px; }
.detail-side h2 { margin: 20px 0 10px; font-size: 13px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); }
/* minmax(0, 1fr): een gewone 1fr-kolom krimpt niet onder de breedte van zijn
   inhoud, en dan duwt één lang e-mailadres zonder breekpunt het kader open. */
.detail-side dl { margin: 0; display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 6px 10px; }
.detail-side dt { color: var(--muted); font-size: 13px; }
.detail-side dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.detail-side .break { overflow-wrap: anywhere; }
.detail-side details { margin-top: 14px; font-size: 13px; }
/* Zijbalk netjes (MEL-221): labels op de eerste tekstregel van hun waarde, één stijl en hoogte voor alle
   velden en knoppen, de statuslabels als een nette rij en lange adressen afgekapt in plaats van midden in
   een woord gebroken. De statuskiezer is ook een <details>, maar hoort niet de marge hierboven te krijgen. */
.detail-side dl { align-items: baseline; row-gap: 10px; }
.detail-side .status-kiezer { margin-top: 0; }
.detail-side .status-dd { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.detail-side .status-dd .tag { margin-right: 0; white-space: nowrap; }
.detail-side .afkappen { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.detail-side .due-date-form, .detail-side .timer-form { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.detail-side .due-date-form input[type=date] { flex: 1 1 120px; }
.detail-side .due-date-form input[type=time] { flex: 1 1 80px; }
.detail-side .due-date-form input[type=date], .detail-side .due-date-form input[type=time], .detail-side .due-date-form select {
    min-width: 0; height: 32px; box-sizing: border-box; padding: 4px 8px;
    border: 1px solid var(--line); border-radius: 6px; background: var(--surface-2); color: var(--ink); font: inherit; font-size: 13px;
}
.detail-side .due-date-form select { width: 100%; }
.detail-side .due-date-form input:disabled { opacity: .5; }
.detail-side .timer-form button {
    height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface); color: var(--ink); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
}
.detail-side .timer-form button:hover { border-color: var(--accent); color: var(--accent); }
/* Elk blok (techniek, bestanden, pull requests, relaties) door een lijn gescheiden, met gelijke ruimte. */
.detail-side h2 { margin: 18px 0 10px; padding-top: 16px; border-top: 1px solid var(--line); }
.detail-side .bestanden-blok, .detail-side .pr-blok, .detail-side .links-blok { margin-top: 0; }
.detail-side > details { margin-top: 10px; }
.ua { overflow-wrap: anywhere; color: var(--muted); font-size: 12px; }
/* Inklapbare secties (MEL-226): techniek, bestanden, pull requests en relaties zijn dicht één regel,
   met de lijn erboven die eerst bij de h2 hoorde. De kop is het klikvlak, met een driehoekje ervoor. */
.detail-side .zijbalk-sectie { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 14px; }
.detail-side .zijbalk-sectie > summary {
    display: flex; align-items: baseline; gap: 8px; min-width: 0; cursor: pointer; list-style: none;
}
.detail-side .zijbalk-sectie > summary::-webkit-details-marker { display: none; }
.detail-side .zijbalk-sectie > summary::before {
    content: '▸'; flex-shrink: 0; width: 10px; color: var(--muted); font-size: 12px; transition: transform .15s;
}
.detail-side .zijbalk-sectie[open] > summary::before { transform: rotate(90deg); }
.detail-side .zijbalk-sectie > summary h2 { display: inline; margin: 0; padding: 0; border: 0; }
.detail-side .zijbalk-sectie > summary:hover h2 { color: var(--ink); }
.detail-side .zijbalk-sectie .sectie-kort { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.detail-side .zijbalk-sectie[open] .sectie-kort { visibility: hidden; }
.detail-side .zijbalk-sectie[open] > summary { margin-bottom: 10px; }
.detail-side .zijbalk-sectie .bestand-upload-toggle { margin-top: 6px; }

/* Bestanden bij een ticket (MEL-86 comment): klein, onderaan de zijbalk - geen
   hoofdzaak van een ticket, dus geen ruimte in de hoofdkolom. */
.bestanden-blok { margin-top: 20px; }
.bestanden-lijst { margin: 0 0 10px; padding: 0; list-style: none; font-size: 13px; }
.bestanden-lijst li {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 4px 0; border-top: 1px solid var(--line);
}
.bestanden-lijst li:first-child { border-top: 0; }
.bestanden-lijst a { overflow-wrap: anywhere; }
.bestanden-lijst form { flex-shrink: 0; }
.bestanden-lijst .muted { white-space: nowrap; }

/* Notities bij een ticket (MEL-230): de tekst is meteen het bewerkveld, zoals op de notitiepagina,
   maar zonder rand tot je erin klikt - in de zijbalk leest het als een rijtje aantekeningen. */
.ticket-notitie { padding: 6px 0; border-top: 1px solid var(--line); }
.ticket-notitie:first-of-type { border-top: 0; padding-top: 0; }
.ticket-notitie .notitie-tekst {
    width: 100%; min-height: 0; margin: 0; padding: 2px 0; border: 0; background: transparent;
    font: inherit; font-size: 13px; line-height: 1.45; resize: none; overflow: hidden;
}
.ticket-notitie .notitie-tekst:focus { outline: 1px dashed var(--open-line); outline-offset: 2px; }
.ticket-notitie-voet { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.ticket-notitie-voet button[type="submit"]:first-of-type { margin-left: auto; }
.notities-blok select { max-width: 160px; margin-top: 6px; }

/* Pull requests in de zijbalk (MEL-225): de kleuren van GitHub, open groen, draft grijs, gemerged paars, gesloten rood. */
.pr-lijst { margin: 0 0 10px; padding: 0; list-style: none; font-size: 13px; }
.pr-lijst li { padding: 5px 0; border-top: 1px solid var(--line); }
.pr-lijst li:first-child { border-top: 0; }
/* Eén regel per PR, uitklappen voor de rest (MEL-227). */
.pr-item > summary { display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none; min-width: 0; }
.pr-item > summary::-webkit-details-marker { display: none; }
.pr-regel { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pr-item[open] > summary .pr-regel { color: var(--sub); }
.pr-details { padding: 6px 0 2px; display: flex; flex-direction: column; gap: 6px; }
.pr-details a { overflow-wrap: anywhere; }
.pr-details dl { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin: 0; font-size: 12px; }
.pr-details dt { color: var(--sub); }
.pr-details dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.pr-details code { font-size: 11px; }
.pr-details form { align-self: flex-start; }
.pr-details .link-button { font-size: 12px; color: var(--sub); }
.pr-leeg { margin: 0 0 8px; font-size: 13px; }
.pr-staat {
    flex-shrink: 0; padding: 1px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 600; line-height: 18px;
    --pr: #1a7f37; color: var(--pr); background: color-mix(in srgb, var(--pr) 14%, transparent);
}
.pr-draft { --pr: #6e7781; }
.pr-gemerged { --pr: #8250df; }
.pr-gesloten { --pr: #cf222e; }
.pr-blok input[type=url] { width: 100%; }
@media (prefers-color-scheme: dark) {
    .pr-staat { --pr: #3fb950; }
    .pr-draft { --pr: #9198a1; }
    .pr-gemerged { --pr: #ab7df8; }
    .pr-gesloten { --pr: #f85149; }
}
.bestanden-lijst .link-button { font-size: 16px; line-height: 1; text-decoration: none; }
/* Thumbnail on hover bij een afbeelding in de bestandenlijst (MEL-124): puur CSS, geen JS nodig -
   de link is de enige :hover-drager, dus de preview verdwijnt vanzelf zodra de muis weg is. */
.bestand-preview-link { position: relative; display: inline-block; }
.bestand-preview {
    display: none; position: absolute; left: 0; bottom: 100%; margin-bottom: 6px; z-index: 50;
    padding: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow-lift);
}
.bestand-preview img { display: block; max-width: 220px; max-height: 220px; border-radius: 4px; }
.bestand-preview-link:hover .bestand-preview, .bestand-preview-link:focus .bestand-preview { display: block; }
.bestand-upload-toggle summary { font-size: 13px; color: var(--sub); cursor: pointer; }
.bestand-upload-toggle form { margin-top: 8px; }
.dropzone-naam { margin: 0; font-size: 13px; overflow-wrap: anywhere; }

/* Relaties tussen tickets (MEL-157): zelfde opzet als de bestandenlijst ernaast. */
.links-blok { margin-top: 20px; }
.links-lijst { margin: 0 0 10px; padding: 0; list-style: none; font-size: 13px; }
.links-lijst li {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 4px 0; border-top: 1px solid var(--line);
}
.links-lijst li:first-child { border-top: 0; }
.links-lijst a { overflow-wrap: anywhere; }
.links-lijst form { flex-shrink: 0; margin-left: auto; }
.links-lijst .link-button { font-size: 16px; line-height: 1; text-decoration: none; }
.link-toevoegen-form { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.link-toevoegen-form select, .link-toevoegen-form input[type="text"] { font-size: 13px; }
.link-toevoegen-form input[type="text"] { width: 100px; }

.card { padding: 18px; margin-bottom: 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.card h2 { margin: 0 0 12px; font-size: 16px; }
.card h3 { margin: 22px 0 8px; font-size: 14px; }
.card dl.report { margin: 0; display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 8px 12px; font-size: 14px; }
.card dl.report dt { color: var(--muted); }
.card dl.report dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.card details { margin-top: 14px; font-size: 13px; }
.plugin-lijst { margin: 8px 0 0; padding: 0; list-style: none; font-size: 13px; }
.plugin-lijst li { padding: 5px 0; border-top: 1px solid var(--line); }
.plugin-lijst li:first-child { border-top: 0; }
.card label { display: block; margin: 12px 0 4px; font-size: 13px; font-weight: 600; }
.card input[type=text], .card input[name=name], .card input[type=email], .card input[type=url],
.card input[type=date], .card input[type=number], .card input[type=password], .card input[type=search], .card select, .card textarea {
    width: 100%; padding: 9px 11px; border: 1px solid var(--line); border-radius: 8px;
    font: inherit; background: var(--surface-2); color: var(--ink);
}
.card .row { display: flex; gap: 16px; align-items: flex-end; }
.card .row[hidden] { display: none; }
.card .grow { flex: 1; }
.card .checkbox label { font-weight: 400; white-space: nowrap; }
.type-keuze { display: flex; gap: 20px; margin: 0 0 16px; }
.type-keuze label { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 14px; font-weight: 400; }
.snippet { padding: 14px; background: #10131a; color: #d7dbe3; border-radius: 8px; font-size: 12px; line-height: 1.6; overflow-x: auto; border: 1px solid var(--line); }
.actions { display: flex; gap: 10px; margin-top: 14px; }
.actions button { padding: 9px 17px; border: 0; border-radius: 8px; background: var(--accent); color: var(--accent-ink); font-size: 14px; font-weight: 600; cursor: pointer; }
.actions button.secondary { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }
/* Een link die als knop meedoet in .actions - zelfde maat, zelfde uitlijning. */
.actions a.button {
    display: inline-flex; align-items: center; padding: 9px 17px; border-radius: 8px;
    background: var(--accent); color: var(--accent-ink); font-size: 14px; font-weight: 600; text-decoration: none;
}
.actions a.button.secondary { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }
.status-line { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; font-size: 14px; }
.accounts { margin: 0 0 12px; padding: 0; list-style: none; }
.accounts li { padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 6px; font-size: 14px; }
.waarschuwing {
    padding: 14px 16px; border: 1px solid var(--open-line); border-radius: 8px;
    background: var(--open-bg); color: var(--open); font-size: 14px; line-height: 1.55; margin-bottom: 12px;
}
.waarschuwing p { margin: 0 0 10px; }
.waarschuwing p:last-child { margin-bottom: 0; }
.waarschuwing code { background: rgba(0,0,0,.06); padding: 1px 5px; border-radius: 4px; }

/* Ticketcode: NC-01. white-space: nowrap omdat de code in een smalle kolom (een planningkaart,
   de strook met recent bekeken tickets) anders midden in zichzelf afbreekt: "MEL-" op de ene
   regel en "141" op de volgende, in hetzelfde labeltje. */
.code {
    display: inline-block; padding: 2px 7px; margin-right: 8px;
    border-radius: 5px; background: var(--ink); color: var(--bg);
    font: 600 12px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: .4px; vertical-align: 1px; white-space: nowrap;
}
h1 .code { font-size: 14px; padding: 2px 8px; vertical-align: 3px; }

/* Projectenoverzicht */
.button {
    padding: 9px 17px; border-radius: 8px; background: var(--accent);
    color: var(--accent-ink); font-size: 14px; font-weight: 600; text-decoration: none;
}
.button:hover { background: #b91c1c; }

.project-grid {
    display: grid; gap: 16px;
    /* Was minmax(280px, 1fr): op middelgrote schermen (~1200px) paste dat net geen
       4e kolom en werden de 3 overgebleven kaarten enorm uitgerekt (MEL-83). Een
       vaste bovengrens loste dat op maar liet een lege kolom over (MEL-84) - met
       een lager minimum past die 4e kolom wél, en 1fr vult de rij weer volledig. */
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.project {
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
    transition: box-shadow .15s, transform .15s;
}
.project:hover { box-shadow: 0 6px 18px rgba(0,0,0,.09); transform: translateY(-1px); }
.project.is-inactive { opacity: .6; }

.project-shot {
    text-decoration: none; color: inherit;
    position: relative; display: flex; align-items: center; justify-content: center;
    height: 150px; background: var(--bg); border-bottom: 1px solid var(--line); overflow: hidden;
}
.project-shot img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
.project-shot { background: var(--surface-2); }
.project-shot .no-thumb { color: var(--muted); font-size: 12px; text-align: center; }
.project-code {
    position: absolute; left: 10px; bottom: 10px;
    padding: 2px 8px; border-radius: 4px;
    background: rgba(17,24,39,.85); color: #fff;
    font: 600 12px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .4px;
}

.project-body { padding: 14px 16px 16px; }
.project-body h2 { margin: 0 0 6px; font-size: 16px; }
.project-body h2 a { color: var(--ink); text-decoration: none; }
.project-body h2 a:hover { color: var(--sub); }
.project-counts { margin: 0 0 2px; font-size: 14px; }
.project-counts strong { font-size: 18px; }
/* Eén regel voor uren, WordPress-versie en updates (MEL-135). Die stond eerst op twee regels die
   allebei niet mochten doorlopen, waardoor de tags bij een volle kaart over de rand liepen en midden
   in hun eigen tekst afbraken ("4 upda-tes"). Een tag breekt nu nooit meer af en springt in zijn
   geheel naar de volgende regel. Staat er niets in, dan valt de regel zelf weg. */
.project-meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; font-size: 13px; }
.project-meta:not(:has(.tag)) { display: none; }
.project-counts .tag, .project-meta .tag { white-space: nowrap; flex: 0 0 auto; }

.card .prefix {
    width: 110px; text-transform: uppercase; letter-spacing: .5px;
    font: 600 14px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Notities (MEL-87): losse blokjes i.p.v. één tekstveld, met een warme tint (dezelfde
   als de "open"-status) zodat ze op het eerste gezicht niet als meldingen ogen. */
.notities-grid {
    display: grid; gap: 14px; align-items: start;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
}
.notitie-blok {
    display: flex; flex-direction: column;
    background: var(--open-bg); border: 1px solid var(--open-line); border-radius: 10px;
    padding: 14px 14px 12px;
}
.notitie-blok textarea {
    /* Een textarea stretcht niet vanzelf mee met een flex-kolom: zijn intrinsieke breedte
       komt van het cols-attribuut (standaard 20), niet van de omringende container. Hoogte
       komt van JS (auto-resize.js) die 'm op de inhoud past - min-height is alleen de
       ondergrens voor een lege/korte notitie (MEL-121: stond vast op 340px, ook voor drie
       woorden). */
    flex: 1; width: 100%; box-sizing: border-box; resize: vertical; border: 0; background: transparent; color: var(--ink);
    font: inherit; padding: 0; margin: 0 0 8px; min-height: 90px; overflow-y: hidden;
}
.notitie-blok textarea:focus { outline: 1px dashed var(--open-line); outline-offset: 4px; }
.notitie-voet {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-size: 12px; color: var(--open);
}
.notitie-voet button {
    padding: 5px 10px; border: 1px solid var(--open-line); border-radius: 6px;
    background: transparent; color: var(--open); font-size: 12px; cursor: pointer;
}
.notitie-verwijder { margin-top: 6px; text-align: right; }
.card input[name=ticket_prefix] { padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px; }
.card .row { align-items: flex-end; }

/* Archiveren */
.filter-link {
    align-self: center; padding: 8px 12px; border: 1px solid var(--line);
    border-radius: 8px; background: var(--surface); color: var(--muted);
    font-size: 13px; text-decoration: none;
}
.filter-link.active { border-color: var(--ink); color: var(--ink); }
.paginering {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 18px 0 4px; font-size: 14px;
}
.paginering a, .paginering .huidig {
    min-width: 34px; padding: 6px 10px; text-align: center; border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--muted); text-decoration: none;
}
.paginering a:hover { border-color: var(--accent); color: var(--ink); }
.paginering .huidig { border-color: var(--ink); color: var(--ink); font-weight: 600; }
.paginering .muted { margin-left: auto; }
.issue-actions {
    display: flex; align-items: center; gap: 10px; margin-left: auto;
    opacity: 0; transition: opacity .15s ease;
}
.issue:hover .issue-actions, .issue-actions:focus-within { opacity: 1; }
@media (hover: none) { .issue-actions { opacity: 1; } }
.issue-actions button {
    padding: 7px 12px; border: 1px solid var(--line); border-radius: 8px;
    background: var(--surface); color: var(--muted); font-size: 13px; cursor: pointer;
    transition: border-color .12s, color .12s;
}
.issue-actions button:hover { border-color: var(--ink); color: var(--ink); }
/* De actiekolom is smal en krijgt geen extra ruimte: wat erin staat mag nooit midden in een woord
   afbreken, anders staat er een blob in plaats van een knop (MEL-136). */
.issue-actions button, .issue-actions .tag { white-space: nowrap; flex: 0 0 auto; }
.head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.head-actions details { flex-shrink: 0; }

/* API-sleutels */
.token-once { border-color: var(--open-line); background: var(--open-bg); }
.checkbox-inline { display: block; margin: 12px 0 0; font-weight: 400; }
.checkbox-inline input { width: auto; margin-right: 6px; }
table.keys { width: 100%; border-collapse: collapse; font-size: 14px; }
table.keys th { text-align: left; font-size: 12px; color: var(--muted); font-weight: 600; padding-bottom: 6px; }
table.keys td { padding: 8px 12px 8px 0; border-top: 1px solid var(--line); }
table.keys td:last-child { padding-right: 0; white-space: nowrap; }
table.keys button.verwijder-rij {
    padding: 5px 10px; border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface); color: var(--muted); font: inherit; font-size: 12px; cursor: pointer;
}
.link-button { border: 0; background: none; padding: 0; color: #b91c1c; font-size: 13px; cursor: pointer; text-decoration: underline; }
/* Archiveren staat in het rood (waarschuwend), Activeren (hersteld) juist niet. */
.link-button.herstellen { color: var(--sub); }

/* Instellingen per project: menu links, één paneel tegelijk rechts (MEL-57). */
.settings { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 20px; align-items: start; }
.settings-nav {
    position: sticky; top: 20px; display: flex; flex-direction: column; gap: 2px;
    padding: 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
}
.settings-nav a {
    padding: 8px 10px; border-radius: 7px; font-size: 14px; color: var(--muted);
    text-decoration: none; white-space: nowrap;
}
.settings-nav a:hover { background: var(--surface-2); color: var(--ink); }
.settings-nav a.actief { background: var(--surface-2); color: var(--ink); font-weight: 600; }
.settings-nav a.gevaar { color: #b91c1c; margin-top: 6px; border-top: 1px solid var(--line); border-radius: 0 0 7px 7px; padding-top: 12px; }
.settings-nav a.gevaar:hover, .settings-nav a.gevaar.actief { color: #b91c1c; }
.settings-body .card:last-of-type { margin-bottom: 0; }
.settings-actions {
    position: sticky; bottom: 0; display: flex; gap: 10px;
    padding: 14px 0; background: linear-gradient(to top, var(--bg) 70%, transparent);
}
.settings-actions button { padding: 9px 17px; border: 0; border-radius: 8px; background: var(--accent); color: var(--accent-ink); font-size: 14px; font-weight: 600; cursor: pointer; }

@media (max-width: 860px) {
    .settings { grid-template-columns: minmax(0, 1fr); }
    .settings-nav { position: static; flex-direction: row; overflow-x: auto; }
    .settings-nav a.gevaar { margin-top: 0; padding-top: 8px; border-top: 0; border-left: 1px solid var(--line); }
}

/* Gevarenzone: duidelijk anders dan de rest van de kaarten, zonder overdreven te zijn. */
.card.danger { border-color: rgba(220, 38, 38, .35); background: rgba(220, 38, 38, .04); }
.card.danger h2 { color: #b91c1c; }
button.danger {
    padding: 9px 17px; border: 1px solid #b91c1c; border-radius: 8px;
    background: #fff; color: #b91c1c; font-size: 14px; font-weight: 600; cursor: pointer;
}
button.danger:hover { background: #b91c1c; color: #fff; }
@media (prefers-color-scheme: dark) {
    .card.danger { background: rgba(220, 38, 38, .08); }
    button.danger { background: transparent; }
}

/* Reacties */
.comments { margin-top: 20px; padding: 16px 18px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; }
.comments h2 { margin: 0 0 12px; font-size: 13px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); }
.comment { padding: 10px 0; border-top: 1px solid var(--line); }
.comment:first-of-type { border-top: 0; padding-top: 0; }
.comment-head { margin: 0 0 3px; font-size: 13px; display: flex; gap: 8px; align-items: center; }
.comment-body { margin: 0; font-size: 14px; line-height: 1.55; overflow-wrap: anywhere; }
.comment.via-api .comment-body { color: var(--ink); }
.comments textarea {
    width: 100%; margin-top: 12px; padding: 13px 15px;
    border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2);
    color: var(--ink); font: inherit; font-size: 15px; line-height: 1.6;
    min-height: 150px; resize: vertical;
}
.comments textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; border-color: transparent; }
.comments .actions { margin-top: 10px; }
.comments .actions button { padding: 9px 17px; border: 0; border-radius: 8px; background: var(--accent); color: var(--accent-ink); font-size: 14px; font-weight: 600; cursor: pointer; }

.project-counts strong.is-open { color: var(--open); }
.project-body h2 a { color: var(--ink); }
.detail-side dd .tag { margin-right: 4px; }

/* Overzicht met zijbalk: de lijst krijgt de ruimte, de activiteit ernaast.
   Onder de 1000px schuift de zijbalk onder de lijst in plaats van hem te knijpen. */
.overzicht { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start; }
@media (max-width: 1000px) { .overzicht { grid-template-columns: 1fr; } }

.activiteit { position: sticky; top: 76px; display: flex; flex-direction: column; gap: 16px; }
.activiteit section {
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px;
}
.activiteit h2 { margin: 0 0 10px; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
.activiteit h2 .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }

.tijdlijn { list-style: none; margin: 0; padding: 0; }
.tijdlijn li {
    display: grid; grid-template-columns: 1fr auto; gap: 8px; padding: 8px 0 8px 12px;
    border-top: 1px solid var(--line); position: relative;
}
.tijdlijn li:first-child { border-top: 0; padding-top: 2px; }
/* Een streepje links per soort, zodat je nieuwe meldingen en commits uit elkaar houdt zonder te lezen. */
.tijdlijn li::before { content: ''; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 2px; background: var(--line); }
.tijdlijn li:first-child::before { top: 4px; }
.tijdlijn .soort-melding::before { background: var(--open-line); }
.tijdlijn .soort-reactie::before { background: var(--accent); }
.tijdlijn .soort-pr::before      { background: #8b5cf6; }
.tijdlijn .soort-commit::before  { background: var(--done-line); }

.tijdlijn a { color: inherit; text-decoration: none; min-width: 0; }
.tijdlijn a:hover .tijdlijn-tekst { color: var(--sub); }
.tijdlijn-kop { display: block; font-size: 12px; color: var(--muted); margin-bottom: 2px; }
.tijdlijn-tekst { display: block; font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.tijdlijn time { font-size: 12px; color: var(--muted); white-space: nowrap; }

.pr-status { font-size: 11px; padding: 0 6px; border-radius: 999px; border: 1px solid var(--line); }
.pr-open, .pr-draft { color: var(--done); border-color: var(--done-line); }
.pr-gemerged { color: #7c3aed; border-color: #8b5cf6; }
.pr-gesloten { color: var(--muted); }

/* Knop in de kop van het overzicht, naast de tellers. */
.page-head a.button.nieuw {
    display: inline-block; margin-left: auto; flex: 0 0 auto; padding: 7px 14px; border-radius: 8px;
    background: var(--accent); color: var(--accent-ink); font-size: 13px; font-weight: 600; text-decoration: none;
}

/* Screenshot plakken of slepen. Het echte bestandsveld blijft bestaan, maar
   onzichtbaar: de zone eromheen is wat je ziet en waar je naartoe sleept. */
.dropzone {
    position: relative; padding: 18px; border: 2px dashed var(--line); border-radius: 10px;
    background: var(--surface-2); text-align: center; transition: border-color .12s, background .12s;
}
.dropzone:focus-within, .dropzone.sleep { border-color: var(--accent); }
.dropzone.sleep { background: var(--surface); }
.dropzone input[type=file] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.dropzone-tekst { margin: 0; font-size: 14px; color: var(--muted); }
.dropzone.gevuld .dropzone-tekst { display: none; }
.dropzone img { display: block; max-width: 100%; max-height: 360px; margin: 0 auto 10px; border: 1px solid var(--line); border-radius: 6px; }
.dropzone label.link { display: inline; margin: 0; font-size: inherit; font-weight: 400; color: var(--sub); text-decoration: underline; cursor: pointer; }
.dropzone.dropzone-klein { padding: 10px; margin: 10px 0; }
.dropzone.dropzone-klein .dropzone-tekst { font-size: 13px; }
.dropzone.dropzone-klein img { max-height: 200px; }

/* Screenshot achteraf toevoegen/vervangen op de detailpagina (MEL-105). */
.screenshot-vervangen { margin-top: 10px; }
.screenshot-vervangen summary { cursor: pointer; color: var(--sub); font-size: 13px; }
.screenshot-vervangen summary::-webkit-details-marker { display: none; }
.screenshot-form .actions { margin-top: 0; }

.comment-shot { display: block; max-width: 100%; max-height: 360px; margin-top: 8px; border: 1px solid var(--line); border-radius: 8px; cursor: zoom-in; }

/* Modal voor een grote screenshot - van de melding zelf of bij een reactie. */
.lightbox {
    position: fixed; inset: 0; z-index: 200; padding: 40px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .85); cursor: zoom-out;
}
.lightbox[hidden] { display: none; }
.lightbox img { max-width: 100%; max-height: 100%; display: block; border-radius: 8px; box-shadow: var(--shadow-lift); cursor: default; }
.lightbox-close {
    position: absolute; top: 16px; right: 20px; padding: 4px 10px; border: 0; border-radius: 6px;
    background: rgba(255, 255, 255, .12); color: #fff; font-size: 26px; line-height: 1.2; cursor: pointer;
}
.lightbox-close:hover { background: rgba(255, 255, 255, .22); }
kbd { padding: 1px 5px; border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 4px; font: 12px ui-monospace, Menlo, monospace; background: var(--surface); }

/* Menu naast de gebruikersnaam: GitHub, API en uitloggen. */
.gebruikersmenu, .mobielmenu { position: relative; }
.gebruikersmenu summary, .mobielmenu summary {
    display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 8px;
    color: var(--muted); font-size: 13px; cursor: pointer; list-style: none; user-select: none;
}
.gebruikersmenu summary { position: relative; }
.gebruikersmenu .alarm-stip {
    position: absolute; top: 2px; right: 2px; width: 9px; height: 9px; border-radius: 50%;
    background: #f87171; box-shadow: 0 0 0 2px var(--bg, #0f1115);
}
.gebruikersmenu summary::-webkit-details-marker, .mobielmenu summary::-webkit-details-marker { display: none; }
.gebruikersmenu summary:hover, .gebruikersmenu[open] summary,
.mobielmenu summary:hover, .mobielmenu[open] summary { color: var(--ink); background: var(--surface-2); }
.gebruikersmenu .menu-lijst, .mobielmenu .menu-lijst {
    position: absolute; right: 0; top: calc(100% + 6px); min-width: 190px; padding: 6px; z-index: 20;
    background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow-lift);
}
.gebruikersmenu .menu-lijst a, .mobielmenu .menu-lijst a {
    display: block; padding: 8px 10px; border-radius: 6px; color: var(--ink); text-decoration: none; font-size: 14px;
}
.gebruikersmenu .menu-lijst a:hover, .gebruikersmenu .menu-lijst a.active,
.mobielmenu .menu-lijst a:hover, .mobielmenu .menu-lijst a.active { background: var(--surface-2); }
.gebruikersmenu hr { border: 0; border-top: 1px solid var(--line); margin: 6px 0; }

/* Standaard verborgen: de gewone balk (.topbar nav) is er al voor desktop. Alleen op smalle
   schermen (zie media query onderaan) wisselen ze om. */
.mobielmenu { display: none; }

/* Live, staging of dev (localhost), afgeleid van de pagina. Live in rood:
   daar zitten echte bezoekers, dus daar wil je het verschil niet over het
   hoofd zien. Dev in grijs: geen echte omgeving, puur "dit kwam van iemands
   eigen machine tijdens het bouwen". */
.omgeving {
    display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;
    letter-spacing: .2px; vertical-align: middle; white-space: nowrap;
}
.omgeving-live { background: rgba(220, 38, 38, .12); color: #b91c1c; border: 1px solid rgba(220, 38, 38, .35); }
.omgeving-staging { background: rgba(124, 58, 237, .1); color: #6d28d9; border: 1px solid rgba(124, 58, 237, .3); }
.omgeving-dev { background: rgba(100, 116, 139, .12); color: #475569; border: 1px solid rgba(100, 116, 139, .35); }
@media (prefers-color-scheme: dark) {
    .omgeving-live { color: #fca5a5; }
    .omgeving-staging { color: #c4b5fd; }
    .omgeving-dev { color: #cbd5e1; }
}
h1 .omgeving { font-size: 12px; margin-left: 6px; }

/* Reactie ook naar de melder: het vinkje naast de knop, en in het gesprek een
   label bij wat de melder te lezen kreeg. */
.reactie-acties { align-items: center; flex-wrap: wrap; }
.mail-melder { display: flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.mail-melder input { width: auto; margin: 0; }
.tag.gemaild { color: var(--accent); border-color: var(--accent); }

/* ── Gebruikers en uitnodigingen (MEL-58) ─────────────────────────────────
   Eén pagina met het uitnodigingsformulier, de openstaande uitnodigingen en de
   accounts eronder; per klant staan de projecten die hij mag zien als een rij
   vinkjes onder zijn naam. */
.projectkeuze { margin: 14px 0 0; padding: 12px 14px; border: 1px solid var(--line); border-radius: 8px; }
.projectkeuze legend { padding: 0 6px; font-size: 13px; font-weight: 600; }
.projectkeuze .checkbox-inline,
.projectkeuze-form .checkbox-inline { display: inline-flex; align-items: center; gap: 6px; margin: 0 14px 6px 0; font-size: 14px; font-weight: 400; }

.gebruiker { padding: 14px 0; border-top: 1px solid var(--line); }
.gebruiker:first-of-type { border-top: 0; padding-top: 0; }
.gebruiker.is-inactive { opacity: .6; }
.gebruiker-kop { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 14px; }
/* Overzichtstabel op /gebruikers (MEL-130) i.p.v. een kaart per gebruiker met alles erop en eraan. */
.gebruikers-tabel tr.is-inactive { opacity: .6; }

/* Cronjobs (MEL-147): een uitgezette job blijft leesbaar maar staat op de achtergrond, en de
   url mag lang zijn zonder de tabel uit elkaar te trekken - hij breekt dan maar af. */
.cronjobs-tabel tr.is-uit { opacity: .55; }
.cronjobs-tabel .cron-url { max-width: 340px; }
.cronjobs-tabel .cron-url a { overflow-wrap: anywhere; font-size: 13px; }
.cronjobs-tabel .cron-acties { white-space: nowrap; }
.cronjobs-tabel .cron-acties form { display: inline; margin-right: 10px; }
.cronjobs-tabel .cron-bewerk { display: inline-block; vertical-align: top; }
.cronjobs-tabel .cron-uitvoer { margin-top: 4px; }
.cronjobs-tabel .cron-uitvoer pre { max-width: 52ch; max-height: 18em; overflow: auto; margin: 4px 0 0; padding: 8px; font-size: 12px; white-space: pre-wrap; background: var(--surface-2); color: var(--ink); border: 1px solid var(--line); border-radius: 4px; }
.cronjobs-tabel .cron-balk { display: flex; gap: 2px; margin-top: 6px; }
.cronjobs-tabel .cron-blok { flex: 0 0 5px; height: 18px; border-radius: 1px; background: var(--archived-line); }
.cronjobs-tabel .cron-blok-leeg { opacity: .25; }
.cronjobs-tabel .cron-blok-gelukt { background: var(--done-line); }
.cronjobs-tabel .cron-blok-overgeslagen { background: var(--done-line); opacity: .45; }
.cronjobs-tabel .cron-blok-mislukt { background: var(--accent); }
.cronjobs-tabel .cron-bewerk summary { cursor: pointer; color: var(--sub); font-size: 13px; text-decoration: underline; }
.cronjobs-tabel .cron-bewerk[open] { display: block; margin-top: 8px; }
.cronjobs-tabel .cron-bewerk form { display: block; margin: 0; }
.projectkeuze-form { margin: 10px 0 4px; }
.projectkeuze-form .actions { margin-top: 8px; }
.uitnodiging-acties { display: flex; gap: 12px; }

/* Uitnodigen in een modal en projectkeuze als doorzoekbare lijst per klant (MEL-171). */
.page-head-acties { display: flex; flex-wrap: wrap; gap: 10px; }
button.button { border: 0; cursor: pointer; }
dialog.modal { width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 48px); margin: auto; padding: 18px 20px; color: var(--ink); border-radius: 12px; box-shadow: var(--shadow-lift); }
dialog.modal::backdrop { background: rgba(15, 17, 21, .55); }
.modal-kop { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.modal-kop h2 { margin: 0; }
.modal-sluit { padding: 2px 10px; font-size: 22px; line-height: 1; color: var(--muted); background: transparent; border: 0; }
.modal-sluit:hover { color: var(--ink); background: var(--surface-2); }
.multiselect-kop { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.multiselect-kop .multiselect-zoek { flex: 1; margin: 0; }
.multiselect-teller { flex: none; font-size: 13px; }
.multiselect-lijst { max-height: 320px; overflow-y: auto; padding: 4px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
.multiselect-groep { padding: 8px 0; border-top: 1px solid var(--line); }
.multiselect-groep:first-child { border-top: 0; }
.multiselect .multiselect-groep[hidden], .multiselect .multiselect-optie[hidden] { display: none; }
.multiselect .multiselect-groepnaam, .multiselect .multiselect-optie { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 14px; }
.multiselect .multiselect-groepnaam { font-weight: 600; }
.multiselect .multiselect-optie { padding: 3px 0 3px 24px; font-weight: 400; }
.multiselect-optie .muted { font-size: 12px; }
.multiselect input[type="checkbox"] { width: auto; margin: 0; }

/* De uitnodigingspagina staat op zichzelf, zonder navigatie eromheen. */
.topbar-kaal { justify-content: flex-start; }
.uitnodiging { max-width: 460px; margin: 40px auto; }
.uitnodiging h1 { margin: 0 0 10px; font-size: 21px; }
.uitnodiging input[disabled] { opacity: .65; }

/* ── Voorpagina (MEL-58) ──────────────────────────────────────────────────
   Eén scherm: links wat Meldr is met een nagebouwd voorbeeld van de lijst,
   rechts inloggen en beta-toegang aanvragen. Het voorbeeld is met opzet geen
   echte schermafdruk - daar zouden namen van klanten op staan. */
.landing { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(320px, .75fr); gap: 34px; align-items: start; }
.landing-intro h1 { margin: 6px 0 14px; font-size: 32px; line-height: 1.2; letter-spacing: -.02em; color: var(--sub); }
.landing-lead { margin: 0 0 22px; font-size: 16px; line-height: 1.65; color: var(--muted); max-width: 58ch; }
.landing-punten { margin: 0 0 26px; padding: 0; list-style: none; display: grid; gap: 14px; }
.landing-punten li { padding-left: 26px; position: relative; font-size: 14px; line-height: 1.6; color: var(--muted); }
.landing-punten li::before {
    content: ""; position: absolute; left: 4px; top: 7px; width: 9px; height: 9px;
    border-radius: 50%; background: var(--accent);
}
.landing-punten strong { display: block; margin-bottom: 2px; font-size: 15px; color: var(--ink); }

/* De demovideo op de landingspagina (MEL-133), in de plaats van het nagebouwde
   voorbeeldlijstje dat hier eerst stond. Achter de video staan schermafdrukken uit hetzelfde
   demoproject: doorschuiven gaat met scroll-snap, dus vegen op mobiel en het trackpad op
   desktop werken vanzelf - het scriptje eronder doet alleen de stippen en pauzeert de video
   zodra je 'm wegschuift. Staand (4:5), dus een maximumbreedte: anders vult hij op een breed
   scherm de halve pagina. */
.landing-slider { max-width: 420px; margin: 0 auto; }
.ls-venster { position: relative; }
.ls-pijl {
    position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
    display: flex; align-items: center; justify-content: center; width: 38px; height: 38px; padding: 0;
    border: 1px solid var(--line); border-radius: 50%; background: color-mix(in srgb, var(--surface) 92%, transparent);
    color: var(--ink); cursor: pointer; box-shadow: var(--shadow); backdrop-filter: blur(4px);
}
.ls-pijl:hover:not(:disabled) { background: var(--surface); border-color: var(--muted); }
.ls-pijl:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ls-pijl:disabled { opacity: .3; cursor: default; }
.ls-pijl svg { width: 17px; height: 17px; }
.ls-pijl.vorige { left: 10px; }
.ls-pijl.volgende { right: 10px; }
.ls-spoor {
    display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory;
    scroll-behavior: smooth; scrollbar-width: none; border-radius: 12px;
}
.ls-spoor::-webkit-scrollbar { display: none; }
.ls-spoor:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.ls-slide {
    position: relative; flex: 0 0 100%; margin: 0; scroll-snap-align: center;
    border-radius: 12px; overflow: hidden; border: 1px solid var(--line);
    background: var(--surface-2); box-shadow: var(--shadow-lift);
}
.ls-slide video, .ls-slide img { display: block; width: 100%; height: auto; }
.ls-slide figcaption {
    position: absolute; left: 0; right: 0; bottom: 0; padding: 26px 14px 12px;
    font-size: 13px; line-height: 1.45; color: #fff;
    background: linear-gradient(to top, rgba(17, 24, 39, .82), transparent);
}
.ls-stippen { display: flex; justify-content: center; gap: 8px; margin-top: 12px; }
.ls-stippen button {
    width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%;
    background: var(--line); cursor: pointer; transition: background .15s ease, transform .15s ease;
}
.ls-stippen button:hover { background: var(--muted); }
.ls-stippen button.actief { background: var(--accent); transform: scale(1.25); }

.landing-zij .card { margin-bottom: 14px; }
.landing-zij textarea { min-height: 76px; resize: vertical; }
/* Het valstrikveld bestaat alleen voor bots; mensen horen het nooit te zien. */
.valstrik { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.inloggen { max-width: 400px; margin: 48px auto; }
.inloggen h1 { margin: 0 0 14px; font-size: 21px; }

/* ── Organisaties (MEL-58) ────────────────────────────────────────────── */
table.organisaties th:not(:first-child),
table.organisaties td.getal { text-align: right; white-space: nowrap; }
table.organisaties td.getal { font-variant-numeric: tabular-nums; font-weight: 600; }
/* Een nul is geen nieuws; die hoeft niet net zo hard te schreeuwen als een cijfer. */
table.organisaties td.getal.is-leeg { color: var(--muted); font-weight: 400; }
table.organisaties td.getal .muted { font-weight: 400; }
.page-head p.muted { margin: 4px 0 0; font-size: 13px; }

table.organisaties .org-naam { font-weight: 600; }
.rol-form { display: flex; align-items: center; gap: 8px; margin: 8px 0 4px; font-size: 14px; }
.rol-form label { margin: 0; font-size: 13px; color: var(--muted); font-weight: 400; }
.rol-form select { width: auto; padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; font: inherit; background: var(--surface-2); color: var(--ink); }
.projectkeuze[hidden] { display: none; }

/* ── Beta-aanvragen ───────────────────────────────────────────────────── */
.aanvraag { padding: 14px 0; border-top: 1px solid var(--line); }
.aanvraag:first-of-type { border-top: 0; padding-top: 0; }
.aanvraag-kop { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 14px; }
.aanvraag-tekst { margin: 8px 0 0; font-size: 14px; line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }

/* ── Smalle schermen (MEL-23) ─────────────────────────────────────────────
   Gemeten op 352px: zonder dit werd elke pagina 444 tot 608px breed, omdat de
   balk, de kop van een pagina en de rijen in de lijst alles naast elkaar
   hielden. Hier gaat alles onder elkaar wat op een telefoon niet naast elkaar
   past. */
@media (max-width: 640px) {
    .topbar { gap: 10px; padding: 0 12px; }
    .topbar .brand { font-size: 16px; white-space: nowrap; }
    /* De horizontale balk paste met SLA/Mail erbij niet meer naast elkaar - op
       smalle schermen dus een hamburgermenu in plaats van 7 knoppen op een rij. */
    .topbar nav { display: none; }
    /* Zonder de brede nav ertussen schuiven brand en de twee menu's naast elkaar op links -
       dit duwt de menu's (hamburger + account) naar de rechterkant van de balk. */
    .mobielmenu { display: block; margin-left: auto; }
    .mobielmenu summary { padding: 8px; }
    /* De naam kost te veel ruimte; het icoon zegt genoeg. */
    .gebruikersmenu summary span { display: none; }
    .gebruikersmenu summary { padding: 8px; }

    main { padding: 18px 14px 48px; }

    .page-head { flex-wrap: wrap; align-items: flex-start; gap: 10px; }
    .page-head h1 { font-size: 19px; line-height: 1.3; overflow-wrap: anywhere; flex: 1 1 100%; white-space: normal; }
    .page-head p.muted { margin: 0; flex: 1 1 100%; line-height: 1.7; }
    .page-head a.button.nieuw { margin: 6px 0 0; }
    .head-actions { flex-wrap: wrap; gap: 8px; }

    .filters > select, .filters > input { flex: 1 1 100%; min-width: 0; }

    /* Rij in de lijst: kleine screenshot links, tekst rechts, knop eronder. */
    .issue { display: grid; grid-template-columns: 84px minmax(0, 1fr); gap: 10px 12px; padding: 12px 12px 12px 11px; }
    .issue .thumb { height: 60px; }
    .ticket-kunst-nummer { font-size: 28px; letter-spacing: -1px; right: 6px; bottom: 3px; }
    .ticket-kunst-nummer.smal { font-size: 22px; }
    .ticket-kunst-prefix { left: 6px; top: 6px; font-size: 9px; }
    .ticket-kunst-tekst { display: none; }
    .issue-title { overflow-wrap: anywhere; }
    .issue-actions { grid-column: 1 / -1; margin-left: 0; justify-content: flex-end; opacity: 1; }
    .issue-actions button { padding: 6px 10px; }
    .issue:hover { transform: none; }

    .activiteit { position: static; }

    .project-grid { grid-template-columns: minmax(0, 1fr); }

    .card { padding: 14px; }
    .card .row { flex-direction: column; align-items: stretch; gap: 0; }

    .detail-side dl { grid-template-columns: 84px minmax(0, 1fr); }
    .comments { padding: 14px; }
    .comment-head { flex-wrap: wrap; }

    .landing { grid-template-columns: minmax(0, 1fr); gap: 24px; }
    .landing-intro h1 { font-size: 25px; }
    .landing-slider { max-width: none; }

    table.keys { display: block; overflow-x: auto; }
    .snippet { font-size: 11px; }
}

/* Rijen van kaarten naast elkaar (dashboard, /financieel) en het label/lege-staat erin - hier en
   niet meer alleen inline in start/index.php sinds MEL-108: /financieel gebruikt dezelfde indeling
   en had zelf geen kopie, waardoor de kolommen daar al sinds MEL-99 niet echt naast elkaar stonden. */
.dash-rij { display: grid; gap: 16px; margin-bottom: 16px; }
.dash-rij.groot { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
.dash-rij.drie { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
/* Deze maand, volgende maand zeker en volgende maand prognose naast elkaar (MEL-213). */
.dash-rij.verwachting { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr) minmax(0, 2fr); }
@media (max-width: 1200px) { .dash-rij.verwachting { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .dash-rij.verwachting > :first-child { grid-column: 1 / -1; } }
@media (max-width: 900px) { .dash-rij.groot, .dash-rij.verwachting { grid-template-columns: minmax(0, 1fr); } .tegel-hero { grid-column: span 1; } }
.tegel-label { margin: 0; font-size: 13px; color: var(--muted); }
.dash-leeg { margin: 0; font-size: 13px; color: var(--muted); }
/* Groot omzetgetal boven aan een kaart (/financieel, MEL-99/MEL-108) - niet .tegel-waarde: die
   hoort bij de kleine-tegel-grid van het dashboard, dit is een kaart op zichzelf. */
.groot-cijfer { margin: 2px 0 6px; font-size: 44px; font-weight: 650; letter-spacing: -1px; }
.groot-cijfer.klein { font-size: 30px; }
/* Opbouw van een verwachting onder het grote cijfer op /financieel (MEL-173). */
.opbouw { width: 100%; margin: 4px 0 8px; border-collapse: collapse; font-size: 14px; }
.opbouw td { padding: 4px 0; border-top: 1px solid var(--line); }
.opbouw td:last-child { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.opbouw tr[title] { cursor: help; }
.opbouw-noot { margin: 0; font-size: 13px; }
/* De laatste bij- en afschrijvingen onder banksaldo en kosten (MEL-187). */
.mutaties-kop { margin-top: 16px; }
/* Een subtiele sparkline naast het grote cijfer (MEL-174), zoals bij de tegels op het dashboard. */
.groot-cijfer-rij { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 12px; }
.groot-cijfer-rij .groot-cijfer { min-width: 0; }

/* Grafieken (App\Libraries\Grafiek, MEL-68) - hier en niet meer alleen inline in start/index.php
   sinds MEL-99: /financieel tekent dezelfde .viz-hit-elementen en heeft geen eigen kopie nodig. */
.viz { margin: 0; }
.viz-svg { display: block; width: 100%; height: auto; overflow: visible; }
.viz-raster { stroke: var(--line); stroke-width: 1; }
.viz-as { fill: var(--muted); font-size: 11px; }
.viz-waarde-label { fill: var(--ink); font-size: 12px; font-weight: 600; }
.viz-kolom { fill: var(--viz-1); }
.viz-kolom.viz-nu { opacity: .55; }
.viz-doel { fill: transparent; }
.viz-hit { cursor: default; outline: none; }
.viz-hit:hover .viz-kolom, .viz-hit:focus .viz-kolom { filter: brightness(1.15); }
.viz-hit:focus-visible .viz-doel { stroke: var(--accent); stroke-width: 1.5; }
.viz-balken { list-style: none; margin: 0; padding: 0; }
.viz-rij { display: grid; grid-template-columns: minmax(0, 36%) minmax(0, 1fr); align-items: center; gap: 10px; padding: 5px 4px; margin: 0 -4px; border-radius: 6px; color: inherit; text-decoration: none; }
a.viz-rij:hover, .viz-rij:focus-visible { background: var(--surface-2); outline: none; }
.viz-naam { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viz-spoor { display: flex; align-items: center; gap: 8px; min-width: 0; }
.viz-balk { display: block; height: 14px; min-width: 2px; background: var(--viz-1); border-radius: 0 4px 4px 0; }
.viz-waarde { font-size: 12px; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.viz-spark { flex: none; }
.viz-spark polyline { fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; opacity: .7; }
.viz-spark circle { fill: var(--viz-1); stroke: var(--surface); stroke-width: 2; }
.viz-prognose line { stroke: var(--muted); stroke-width: 2; stroke-dasharray: 3 4; stroke-linecap: round; opacity: .7; }
.viz-prognose .viz-grens { stroke: var(--muted); stroke-width: 1; stroke-dasharray: none; opacity: .4; } /* het maximum (MEL-249) */
.viz-tabel { margin-top: 10px; }
.viz-tabel summary { cursor: pointer; font-size: 12px; color: var(--muted); }
.viz-tabel table { width: 100%; margin-top: 6px; border-collapse: collapse; font-size: 12px; font-variant-numeric: tabular-nums; }
.viz-tabel th { text-align: left; font-weight: 600; color: var(--muted); padding: 3px 0; }
.viz-tabel td { padding: 3px 0; border-top: 1px solid var(--line); }
.viz-tabel .rechts { text-align: right; }

.viz-tip { position: fixed; z-index: 60; pointer-events: none; padding: 8px 10px; background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow-lift); font-size: 12px; }
.viz-tip[hidden] { display: none; }
.viz-tip-kop { color: var(--muted); }
.viz-tip-waarde { display: flex; align-items: center; gap: 6px; margin-top: 2px; font-size: 14px; font-weight: 650; }
.viz-tip-sleutel { display: inline-block; width: 12px; height: 3px; border-radius: 2px; background: var(--viz-1); }

/* Sleepbare planning (/planning, MEL-123): "Geen datum" vast links, de dagen erna scrollen
   horizontaal weg zodra ze niet meer passen. Elke kolom heeft een eigen begrensde hoogte met
   interne verticale scroll (i.p.v. de hele pagina te rekken) - bij tientallen tickets zonder
   datum zou de kop van de dagkolommen anders ver buiten beeld schuiven, en zou je voor het
   slepen zelf ook nog heen en weer moeten scrollen. */
.planning-layout { display: flex; align-items: flex-start; gap: 16px; }
.planning-ongepland { flex: 0 0 240px; }
.planning-dagen { flex: 1; display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; min-width: 0; }
.planning-kolom {
    flex: 0 0 220px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
    padding: 10px; min-height: 100px; max-height: 72vh; display: flex; flex-direction: column;
}
.planning-ongepland .planning-kolom { flex-basis: auto; }
.planning-ongepland .planning-niet-planbaar { margin-top: 12px; }
.planning-kolom h3 { margin: 0 0 8px; font-size: 13px; font-weight: 600; flex: none; }
.planning-kolom.planning-vandaag { border-color: var(--accent); }
.planning-kolom.planning-verlopen h3 { color: #dc2626; }
.planning-kolom.sleep-doel { outline: 2px dashed var(--accent); outline-offset: -2px; }
.planning-lijst { display: flex; flex-direction: column; gap: 6px; min-height: 36px; flex: 1 1 auto; overflow-y: auto; }
.planning-kaart {
    display: block; padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--line);
    border-radius: 8px; font-size: 13px; color: inherit; text-decoration: none; cursor: grab;
}
.planning-kaart:hover { border-color: var(--accent); }
.planning-kaart:active { cursor: grabbing; }
.planning-kaart.slepen { opacity: .4; }
.planning-kaart .meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 12px; color: var(--muted); }
.planning-kaart .meta > * { flex: 0 0 auto; }
.planning-kaart .titel { display: block; margin-top: 3px; overflow-wrap: anywhere; color: var(--ink); }
/* Reeks over meerdere dagen (MEL-126): dezelfde kaart staat dan in elke kolom ertussen. */
.planning-kaart.meerdaags { border-left: 3px solid var(--accent); }
.planning-kaart .reeks-badge { font-size: 11px; color: var(--accent); white-space: nowrap; }
.planning-kaart .schatting-badge { margin-left: auto; font-size: 11px; color: var(--muted); white-space: nowrap; }
.planning-kolom h3 .dag-totaal { float: right; font-weight: 600; color: var(--accent); }
.planning-kolom h3 .dag-totaal:empty { display: none; }
/* Projectbalk (MEL-203): bovenaan de projecten met ingepland werk als filterknoppen, en per dag een dunne
   strook met de verdeling over projecten in de klantkleur. */
.planning-projectbalk { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 12px; }
.planning-projectbalk[hidden] { display: none; }
.project-chip {
    display: inline-flex; align-items: center; gap: 2px; padding: 4px 10px 4px 8px; border-radius: 999px; font: inherit; font-size: 12px;
    background: var(--surface); color: var(--ink); border: 1px solid var(--line); cursor: pointer;
}
.project-chip::before { content: ''; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--kl, var(--muted)); }
.project-chip:hover { border-color: var(--kl, var(--accent)); }
.project-chip[aria-pressed="true"] { border-color: var(--kl, var(--accent)); background: color-mix(in srgb, var(--kl, var(--accent)) 22%, var(--surface)); }
.dag-projecten { display: flex; gap: 2px; height: 6px; margin: -2px 0 8px; flex: none; }
.dag-projecten:empty { display: none; }
.dag-projecten > span { flex-basis: 0; min-width: 6px; border-radius: 3px; background: var(--kl, var(--muted)); }
.planning-kaart.gedimd { opacity: .25; }
@media (max-width: 900px) {
    .planning-layout { flex-direction: column; }
    .planning-ongepland { flex: none; width: 100%; }
    .planning-ongepland .planning-lijst { flex-direction: row; flex-wrap: wrap; }
    .planning-ongepland .planning-kaart { flex: 0 0 200px; }
    /* align-items: flex-start op de layout zet de stretch uit, dus werd de dagenrij hier zo breed
       als alle kolommen samen: hij liep buiten het scherm in plaats van zelf te scrollen, en met
       overflow-x: hidden op body waren de laatste dagen op een telefoon niet te bereiken. */
    .planning-dagen { width: 100%; }
}
/* Lijst of kalender (MEL-206), met de weeknavigatie van de kalender op dezelfde regel. */
.planning-weergave { margin: 0 0 14px; flex-wrap: wrap; align-items: center; }
.planning-weeknav { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; font-size: 14px; }
.planning-weeknav .button { padding: 6px 12px; }
.planning-kaart .tijd { font-weight: 600; color: var(--ink); white-space: nowrap; }

/* Kalender met tijdsloten (MEL-206): een tijdas links en per dag een raster waarop de blokken absoluut staan.
   --van/--tot (minuten na middernacht) komen van de server en rekken op als er iets buiten 8-18 uur valt; een blok
   heeft --start, --duur en voor overlap --kolom/--kolommen. 1 px per minuut (60 px per uur, MEL-207: bij 0,8 was een
   kwartier te laag voor tekst) moet gelijk blijven aan PX_PER_MINUUT in het script. */
.kalender { --px: 1px; flex: 1; display: flex; min-width: 0; overflow-x: auto; padding-bottom: 10px; }
/* Drie weken naast elkaar (MEL-210): een dag is een vijfde van de zichtbare breedte, zodat één werkweek het scherm vult
   en de volgende weken rechts staan om naartoe te scrollen. De tijdas blijft links staan tijdens het scrollen. */
.kalender-as { flex: 0 0 44px; position: sticky; left: 0; z-index: 6; background: var(--bg); }
.kalender-dag { flex: 0 0 max(180px, calc((100% - 44px) / 5)); min-width: 0; border-left: 1px solid var(--line); }
.kalender-dag.nieuwe-week { border-left: 3px solid var(--muted); }
.kalender-weeknr { font-size: 11px; font-weight: 600; color: var(--muted); }
/* Status in de kalender (MEL-211): een klein woordje, en wat ter review of afgerond is staat gedimd - het is er wel,
   maar het is geen werk meer. Bij hover weer vol, zodat je het goed kunt lezen. */
.kalender-status { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .3px; white-space: nowrap; color: var(--muted); }
.kalender-status.is-wacht { color: var(--ink); opacity: .7; }
.kalender-status.is-reactie { color: var(--reactie); }
.planning-kaart.status-review { opacity: .6; }
.planning-kaart.status-klaar { opacity: .4; }
.planning-kaart.status-klaar .titel { text-decoration: line-through; }
.planning-kaart.status-review:hover, .planning-kaart.status-klaar:hover { opacity: 1; }
.kalender-kop {
    height: 44px; padding: 4px 6px; font-size: 13px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; box-sizing: border-box;
}
.kalender-dag.vandaag .kalender-kop strong { color: var(--accent); }
.kalender-kop .dag-totaal { margin-left: auto; font-weight: 600; color: var(--muted); }
.kalender-dag.overboekt .kalender-kop .dag-totaal, .kalender-waarschuwing { color: #dc2626; }
.kalender-waarschuwing { font-size: 11px; font-weight: 600; }
.kalender-dag.overboekt { background: color-mix(in srgb, #dc2626 4%, transparent); }
.kalender-dag.verleden { opacity: .7; }
/* "Hele dag": één regel per ticket, en in alle dagen even hoog (--heledag rijen, van de server) zodat de tijdassen
   gelijk blijven lopen. */
.kalender-heledag-label, .kalender-heledag { height: calc(var(--heledag) * 28px + 8px); box-sizing: border-box; }
.kalender-heledag-label { font-size: 11px; text-align: right; padding: 4px 6px 0 0; }
.kalender-heledag { overflow-y: auto; padding: 4px; display: flex; flex-direction: column; gap: 4px; border-bottom: 1px solid var(--line); }
.kalender-heledag .planning-kaart { flex: none; display: flex; align-items: center; gap: 6px; height: 24px; padding: 0 6px; font-size: 12px; box-sizing: border-box; }
.kalender-heledag .planning-kaart .meta { flex: none; flex-wrap: nowrap; }
.kalender-heledag .planning-kaart .code { margin-right: 0; padding: 0 5px; font-size: 11px; }
.kalender-heledag .planning-kaart .tag.todo { display: none; }
.kalender-heledag .planning-kaart .titel { flex: 1; min-width: 0; margin-top: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kalender-uren, .kalender-raster { position: relative; height: calc((var(--tot) - var(--van)) * var(--px)); }
.kalender-uren span { position: absolute; right: 6px; top: calc((var(--start) - var(--van)) * var(--px) - 7px); font-size: 11px; color: var(--muted); }
.kalender-uren span:first-child { top: 0; }
/* Uurlijnen; --van is altijd een heel uur, dus de eerste lijn valt bovenaan. */
.kalender-raster { background-image: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px calc(60 * var(--px))); }
.kalender-dag.vandaag .kalender-raster { background-color: color-mix(in srgb, var(--accent) 4%, transparent); }
.kalender-raster.sleep-doel, .kalender-heledag.sleep-doel { outline: 2px dashed var(--accent); outline-offset: -2px; }
.kalender-blok {
    position: absolute; box-sizing: border-box; overflow: hidden; padding: 3px 6px; font-size: 12px;
    top: calc((var(--start) - var(--van)) * var(--px) + 1px); height: calc(var(--duur) * var(--px) - 2px); min-height: 18px;
    left: calc(100% / var(--kolommen) * var(--kolom) + 2px); width: calc(100% / var(--kolommen) - 4px);
    background: color-mix(in srgb, var(--kl, var(--accent)) 18%, var(--surface)); border-left: 3px solid var(--kl, var(--accent));
}
.kalender-blok .meta { flex-wrap: nowrap; overflow: hidden; }
.kalender-blok .code { margin-right: 0; }
.kalender-blok.ongeschat { border-style: dashed; }
/* Een blok van een half uur of korter (MEL-207): alles op één regel - tijd, code, titel - met een kleinere code, anders
   valt de tekst onder de rand weg. De volledige titel staat in de tooltip, en bij hover schuift het blok naar voren. */
.kalender-blok.kort { display: flex; align-items: center; gap: 5px; padding: 0 6px; font-size: 11px; line-height: 11px; min-height: 13px; }
.kalender-blok.kort .meta { flex: none; gap: 4px; font-size: 11px; }
.kalender-blok.kort .code { padding: 0 4px; font-size: 10px; line-height: 11px; }
.kalender-blok.kort .schatting-badge, .kalender-blok.kort .tag.todo { display: none; }
.kalender-blok.kort .titel { flex: 1; min-width: 0; margin-top: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kalender-blok:hover { z-index: 4; }
/* Knippen en samenvoegen (MEL-208): knopjes rechtsboven die pas bij hover verschijnen, zodat een blok rustig blijft. */
.kalender-heledag .planning-kaart { position: relative; }
.kalender-acties { position: absolute; top: 1px; right: 2px; display: none; gap: 2px; z-index: 5; }
.planning-kaart:hover .kalender-acties, .kalender-acties:focus-within { display: inline-flex; }
.kalender-actie {
    display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 4px;
    background: var(--surface); border: 1px solid var(--line); color: var(--ink); font-size: 12px; line-height: 1; cursor: pointer;
}
.kalender-blok.kort .kalender-actie { width: 14px; height: 11px; font-size: 10px; }
.kalender-blok.kort .kalender-acties { top: 0; }
.kalender-actie:hover { border-color: var(--accent); color: var(--accent); }
/* Een stuk van een geknipt ticket: een dubbele streep links, zodat je ziet dat er elders nog een deel staat. */
.kalender-blok.stuk { border-left-style: double; border-left-width: 4px; }
.kalender-blok.overlapt, .kalender-blok.buiten-werktijd { outline: 1px solid #dc2626; outline-offset: -1px; }
/* Vrije tijd (MEL-215): grijs gestreept, zodat je ziet dat de tijd weg is zonder dat het op werk lijkt. */
.planning-kaart.vrij {
    color: var(--muted); border-color: var(--line);
    background: repeating-linear-gradient(135deg, var(--surface-2) 0 6px, color-mix(in srgb, var(--muted) 14%, var(--surface-2)) 6px 12px);
}
.kalender-blok.vrij { border-left: 3px solid var(--muted); }
/* Uitrekken (MEL-215): een greep over de hele onderrand; bij hover een streepje zodat je ziet dat het kan. */
.kalender-rek { position: absolute; left: 0; right: 0; bottom: 0; height: 7px; cursor: ns-resize; z-index: 5; }
.kalender-rek::after { content: ''; position: absolute; left: 50%; bottom: 2px; width: 24px; height: 3px; margin-left: -12px; border-radius: 2px; background: var(--muted); opacity: 0; }
.kalender-blok:hover .kalender-rek::after, .kalender-blok.rekken .kalender-rek::after { opacity: .7; }
.kalender-blok.rekken { z-index: 6; box-shadow: var(--shadow-lift); }
.planning-kaart.vrij .titel { font-weight: 600; }
.vrij-bron { margin-bottom: 12px; }
.vrij-bron .planning-kaart { text-align: center; }
.vrij-bron p { margin: 4px 2px 0; font-size: 11px; }
.kalender-nu { position: absolute; left: 0; right: 0; top: calc((var(--start) - var(--van)) * var(--px)); border-top: 2px solid #dc2626; z-index: 2; pointer-events: none; }
.kalender-schaduw {
    position: absolute; left: 0; right: 0; top: calc((var(--start) - var(--van)) * var(--px)); border-top: 2px solid var(--accent);
    font-size: 11px; font-weight: 600; color: var(--accent); padding-left: 4px; z-index: 3; pointer-events: none;
}
@media (max-width: 900px) {
    .kalender { width: 100%; }
}

/* De regel onder de tabbladen op /mail: wanneer de agent keek, met "Nu ophalen" ernaast
   (MEL-139, MEL-143). Het formulier hoort op dezelfde regel als de tekst, niet eronder. */
.agent-regel { margin: -6px 0 14px; font-size: 13px; }
.agent-nu { display: inline-flex; align-items: center; gap: 6px; vertical-align: baseline; }
.agent-nu .link-button { font-size: 13px; }
/* Gericht een mailtje oppikken (MEL-153): staat in de lopende zin, dus klein en onopvallend -
   het is de uitzondering, niet de hoofdweg. Bewust een vaste breedte: een veld dat bij focus
   uitklapt duwt de knop ernaast weg op het moment dat je erop drukt, en dan mist de klik. */
.agent-nu input[type="search"] {
    width: 240px; padding: 3px 8px; border: 1px solid var(--line); border-radius: 6px;
    background: var(--surface-2); color: inherit; font: inherit; font-size: 12px;
}
.agent-nu input[type="search"]:focus { border-color: var(--accent); outline: none; }
.agent-gevraagd { color: var(--sub); }

/* Recent bekeken tickets (MEL-141): een strook in de lege ruimte rechts naast de pagina, om snel
   terug te kunnen naar het ticket waar je net mee bezig was. Alleen zodra die ruimte er echt is -
   main is 1360px breed, dus pas vanaf ongeveer 1780px past er een strook náást zonder eroverheen
   te gaan liggen. Daaronder blijft hij weg: een zwevend blok bovenop de inhoud zou meer in de weg
   zitten dan het oplevert. */
.recent-rail { display: none; }
@media (min-width: 1780px) {
    /* De strook zelf is alleen de plek; elk blok erin is een eigen kaart (MEL-229 comment). */
    .recent-rail {
        display: flex; flex-direction: column; gap: 10px; position: fixed; top: 100px; right: 16px; width: 190px; z-index: 8;
        max-height: calc(100dvh - 130px); overflow-y: auto; overflow-x: hidden;
    }
    .recent-rail > section {
        flex-shrink: 0; padding: 10px 12px; background: var(--surface);
        border: 1px solid var(--line); border-radius: 10px;
    }
    .recent-rail h2 { margin: 0 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); }
    .recent-rail ul { list-style: none; margin: 0; padding: 0; }
    .recent-rail li + li { border-top: 1px solid var(--line); }
    .recent-rail a { display: block; padding: 6px 0; text-decoration: none; font-size: 13px; }
    .recent-rail .code { font-size: 11px; }
    .recent-rail .recent-titel { display: block; margin-top: 2px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .recent-rail a:hover .recent-titel { text-decoration: underline; }
    .recent-rail li.is-klaar .recent-titel { color: var(--muted); }
    .recent-rail h2 a { display: inline; padding: 0; font-size: inherit; color: inherit; text-decoration: none; }
    .recent-rail h2 a:hover { text-decoration: underline; }
    .recent-rail .rail-tijd { margin-left: 4px; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
    .recent-rail li.is-huidig .recent-titel { font-weight: 600; }
    /* Vandaag op de planning (MEL-229) alleen als het scherm hoog genoeg is: anders past het niet
       naast de recente tickets en moet je in een smalle strook gaan scrollen. */
    .recent-rail .rail-vandaag { display: none; }
    .recent-rail.alleen-vandaag { display: none; }
}
@media (min-width: 1780px) and (min-height: 1000px) {
    .recent-rail .rail-vandaag { display: block; }
    .recent-rail.alleen-vandaag { display: flex; }
}

/* Het planbord krijgt het hele scherm (MEL-140). Dit is het enige scherm waar je horizontaal
   langs de dagen kijkt: in de gewone kolom van 1360px vielen de laatste dagen weg achter de rand
   terwijl er links en rechts witruimte stond, en met max-height: 72vh bleef de onderste kwart van
   het scherm leeg. Body wordt hier een kolom van schermhoogte, main krijgt de rest en geeft die
   door aan de kolommen - die scrollen intern al. Onder 900px blijft alles bij het oude: daar
   staan de kolommen onder elkaar en zou een vaste schermhoogte juist in de weg zitten. */
@media (min-width: 901px) {
    body:has(.planning-layout) { height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
    /* min-width: 0 op allebei: zonder dat gaan main en de layout mee met de breedte van álle
       dagkolommen samen (flexbox rekent standaard met de inhoud als ondergrens) en loopt het bord
       buiten beeld in plaats van dat .planning-dagen zelf horizontaal scrollt. */
    /* margin: 0 hoort erbij: main staat normaal op "margin: 0 auto" om te centreren, en een auto-
       marge in de dwarsrichting zet de stretch van flexbox uit - dan wordt main alsnog zo breed
       als zijn inhoud. */
    body:has(.planning-layout) main { max-width: none; margin: 0; flex: 1 1 auto; min-height: 0; min-width: 0; display: flex; flex-direction: column; padding-bottom: 20px; }
    body:has(.planning-layout) .planning-layout { flex: 1 1 auto; min-height: 0; min-width: 0; align-items: stretch; }
    /* Een kolom-flex, geen rij: anders bepaalt de langste kaarttitel de breedte van "Geen datum"
       en loopt die kolom buiten zijn eigen 240px. */
    body:has(.planning-layout) .planning-ongepland { display: flex; flex-direction: column; }
    body:has(.planning-layout) .planning-ongepland .planning-kolom { flex: 1 1 auto; }
    body:has(.planning-layout) .planning-ongepland .planning-kolom.planning-niet-planbaar { flex: 0 1 30%; }
    body:has(.planning-layout) .planning-kolom { max-height: none; }
}

/* Een kale Outlook- of Gmail-url in een omschrijving of reactie wordt een klein knopje (MEL-199, zie Markdown). */
.description .gmail-link, .comment-body .gmail-link {
    display: inline-block; padding: 1px 8px; border: 1px solid var(--line); border-radius: 999px;
    font-size: 12px; line-height: 1.5; text-decoration: none; white-space: nowrap;
}
.description .gmail-link:hover, .comment-body .gmail-link:hover { border-color: var(--accent); }

/* Activiteitenlog (MEL-258): per dag een lijst, één regel per gebeurtenis. */
.activiteit-log { background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 4px 18px 10px; }
.activiteit-log ul { list-style: none; margin: 0; padding: 0; }
.activiteit-dagkop { margin: 16px 0 6px; font-size: 12px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); }
.activiteit-regel {
    display: grid; grid-template-columns: 44px 84px minmax(90px, 160px) 1fr; gap: 12px; align-items: baseline;
    padding: 6px 0; border-top: 1px solid var(--line); font-size: 14px;
}
.activiteit-regel time { color: var(--muted); font-variant-numeric: tabular-nums; font-size: 13px; }
.activiteit-soort {
    justify-self: start; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600;
    background: var(--surface-2); color: var(--muted); white-space: nowrap;
}
.activiteit-soort.soort-user { background: var(--done-bg); color: var(--done); }
.activiteit-soort.soort-agent { background: var(--review-bg); color: var(--review); }
.activiteit-soort.soort-cron { background: var(--wacht-bg); color: var(--wacht); }
.activiteit-soort.soort-melder, .activiteit-soort.soort-gast { background: var(--open-bg); color: var(--open); }
.activiteit-soort.soort-webhook { background: var(--bezig-bg); color: var(--bezig); }
.activiteit-wie { color: var(--sub); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activiteit-wat { min-width: 0; overflow-wrap: anywhere; }
.activiteit-wat .code { text-decoration: none; margin-right: 0; }
.activiteit-meer { margin-top: 14px; text-align: center; }
.filters .activiteit-dag { flex: 0 0 auto; min-width: 0; }
@media (max-width: 700px) {
    .activiteit-regel { grid-template-columns: 44px auto 1fr; }
    .activiteit-wat { grid-column: 1 / -1; }
}

/* Voortgang getrackt/schatting (MEL-292): smalle balk met percentage onder het veld Getrackt */
.voortgang { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.voortgang-balk { flex: 1; height: 4px; border-radius: 2px; background: rgba(128, 128, 128, .25); overflow: hidden; }
.voortgang-balk span { display: block; height: 100%; background: #4caf7d; }
.voortgang.over .voortgang-balk span { background: #e5534b; }
.voortgang-pct { font-size: 11px; opacity: .75; font-variant-numeric: tabular-nums; }

/* Klantfocus (MEL-300): de klantkiezer in de bovenbalk; oplichtend zolang er een focus staat. */
.klantfocus { margin: 0 0.75rem 0 auto; }
.klantfocus select { max-width: 11rem; padding: 0.25rem 0.5rem; font: inherit; font-size: 0.85rem; }
.klantfocus.aan select { border-color: var(--accent, #f87171); box-shadow: 0 0 0 1px var(--accent, #f87171); font-weight: 600; }
