/* Composer op volume — /composer/
   ------------------------------------------------------------------
   Stijl: de gedeelde tokens (The Whitest Boy Alive) — warm wit, donkergrijs,
   geen harde zwart-witcontrasten, geen schaduwen of gradienten, veel witruimte
   en grote doelen. Wat je niet nodig hebt op dit niveau, zie je niet
   (progressive disclosure); wat je wel ziet mag groot en rustig zijn.

   Twee kolommen: links de BOOM van volumes per onderdeel, rechts het GEKOZEN
   volume. Alle namen beginnen met `cmp-` zodat deze module nooit met de
   blokken-composer (`off-`) in de knoop raakt. */

.cmp-page {
    max-width: 1500px;
    margin: 0 auto;
    padding: var(--space-lg) var(--space-lg) var(--space-2xl);
}

.laad-scherm {
    padding: var(--space-2xl);
    text-align: center;
    color: var(--tekst-secundair);
}

/* --- Kop ------------------------------------------------------------------ */

.cmp-kop {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-md);
    padding-bottom: var(--space-md);
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--space-lg);
}

.cmp-kop h1 {
    font-size: 1.55rem;
    font-weight: var(--font-weight-medium);
    margin: 0 0 2px;
    letter-spacing: -0.01em;
}

.cmp-sub { color: var(--tekst-secundair); font-size: 0.9rem; }

.cmp-totalen { display: flex; gap: var(--space-lg); text-align: right; }
.cmp-totaal .label {
    display: block;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--tekst-tertiair);
}
.cmp-totaal .waarde { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.cmp-totaal.groot .waarde { font-size: 1.5rem; }

.cmp-knoppenrij {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    align-items: center;
    margin-bottom: var(--space-lg);
}
.cmp-knoppenrij .rek { flex: 1; }
.cmp-knoppenrij select {
    max-width: 26rem;
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-kaart);
    font: inherit;
    font-size: 0.85rem;
    color: var(--tekst);
}

/* --- Meldingen ------------------------------------------------------------ */

.cmp-melding {
    border-left: 3px solid var(--border-sterk);
    background: var(--bg-kaart);
    padding: var(--space-sm) var(--space-md);
    margin-bottom: var(--space-sm);
    font-size: 0.88rem;
    border-radius: 0 var(--radius) var(--radius) 0;
}
.cmp-melding.fout  { border-color: var(--rood);   background: var(--rood-bg); }
.cmp-melding.letop { border-color: var(--oranje); background: var(--oranje-bg); }
.cmp-melding.info  { border-color: var(--blauw);  background: var(--blauw-bg); }
.cmp-melding.ok    { border-color: var(--groen);  background: var(--groen-bg); }
.cmp-melding .bron { color: var(--tekst-secundair); font-size: 0.8rem; }

.cmp-strip { margin: var(--space-sm) 0; }
.cmp-strip > summary {
    cursor: pointer;
    font-size: 0.8rem;
    color: var(--tekst-tertiair);
    user-select: none;
    padding: 2px 0;
}
.cmp-strip > summary:hover { color: var(--tekst-secundair); }
.cmp-strip-body { margin-top: var(--space-xs); }

.cmp-bevroren {
    border: 1px solid var(--border-sterk);
    background: var(--bg-sidebar);
    padding: var(--space-md);
    border-radius: var(--radius);
    margin-bottom: var(--space-lg);
}
.cmp-bevroren strong { display: block; margin-bottom: 4px; }

/* --- Twee kolommen -------------------------------------------------------- */

/* De boomkolom kreeg op 1600 px zo'n 390 px en kapte namen af ("tussenschot 1
   va…") terwijl rechts een halve schermbreedte leeg bleef. Nu mag hij
   meegroeien tot een derde van het scherm; de maten- en prijskolom staan rechts
   op vaste breedte, dus alle winst gaat naar de naam. */
.cmp-kolommen {
    display: grid;
    grid-template-columns: minmax(400px, 34%) 1fr;
    gap: var(--space-lg);
    align-items: start;
}
/* Een grid-kolom is standaard `min-width: auto` en groeit dus mee met zijn
   BREEDSTE kind. De vakkentabel is sinds 3 sep 2026 `width: max-content` (anders
   kapt hij zijn keuzelijsten af), en zonder deze regel duwde die tabel het hele
   rechterpaneel — en daarmee de pagina — breder dan het scherm. Nu krimpt de
   kolom en scrollt de TABEL binnen zijn eigen vlak. */
.cmp-kolommen > * { min-width: 0; }
@media (max-width: 1000px) { .cmp-kolommen { grid-template-columns: 1fr; } }

/* --- De boom -------------------------------------------------------------- */

/* De boom van een keuken telt al gauw veertig rijen. Zonder eigen scrollgebied
   is het rechterpaneel na de eerste tien rijen uit beeld en scroll je heen en
   weer tussen "welk volume" en "wat zit erin". Dus: de boom blijft staan en
   scrollt in zichzelf; het paneel ernaast blijft in beeld. */
.cmp-boom { display: grid; gap: var(--space-md); }

.cmp-boomwrap {
    position: sticky;
    top: var(--space-md);
    /* Aan de BOVENkant van het grid-vak verankerd: zonder dit begon de boom bij
       een lange rechterkaart pas halverwege de pagina, met een derde scherm
       leegte erboven. */
    align-self: start;
    max-height: calc(100vh - 2 * var(--space-md));
    overflow-y: auto;
    padding-right: 2px;
}
@media (max-width: 1000px) {
    .cmp-boomwrap { position: static; max-height: none; overflow: visible; }
}

.cmp-onderdeel {
    background: var(--bg-kaart);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.cmp-onderdeel.actief { border-color: var(--border-sterk); }

.cmp-onderdeel-kop {
    display: flex;
    align-items: stretch;
    border-bottom: 1px solid var(--border-licht);
    background: var(--bg-sidebar);
}
.cmp-onderdeel-kop > button.titel {
    flex: 1;
    min-width: 0;
    text-align: left;
    background: none;
    border: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
    padding: var(--space-sm) var(--space-md);
}
.cmp-onderdeel-kop .naam {
    display: block;
    font-weight: var(--font-weight-medium);
}
.cmp-onderdeel-kop .meta {
    display: flex;
    justify-content: space-between;
    gap: var(--space-sm);
    font-size: 0.8rem;
    color: var(--tekst-secundair);
    font-variant-numeric: tabular-nums;
}
.cmp-onderdeel-kop .weg {
    flex: 0 0 auto;
    background: none;
    border: 0;
    padding: 0 var(--space-md);
    cursor: pointer;
    font: inherit;
    color: var(--tekst-tertiair);
    opacity: 0;
    transition: opacity 0.12s ease;
}
.cmp-onderdeel-kop:hover .weg,
.cmp-onderdeel-kop .weg:focus-visible { opacity: 1; }
.cmp-onderdeel-kop .weg:hover { color: var(--rood); }

.cmp-rij {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--border-licht);
    font: inherit;
    color: inherit;
    cursor: pointer;
    padding: 7px var(--space-md);
}
.cmp-rij:hover  { background: var(--bg-hover); }
.cmp-rij.actief { background: var(--bg-actief); }

/* De klap-driehoek staat NAAST de rij-knop: een knop in een knop mag niet. */
.cmp-rijwrap { display: flex; align-items: stretch; }
.cmp-rijwrap > .cmp-klap {
    flex: 0 0 auto;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--border-licht);
    color: var(--tekst-tertiair);
    cursor: pointer;
    font: inherit;
    padding: 0 2px 0 var(--space-sm);
    width: 1.6rem;
}
.cmp-rijwrap > .cmp-klap:hover { color: var(--tekst); }
.cmp-rijwrap > .cmp-rij { flex: 1; min-width: 0; }

/* Het soort-vlaggetje. Geen kleurenfestival: alleen een rustige letterbadge,
   zodat VOL/VOM/POM/BLAD op een rij van veertig rijen te scannen zijn. */
.cmp-soort {
    flex: 0 0 auto;
    font-size: 0.62rem;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    border: 1px solid var(--border-sterk);
    border-radius: var(--radius-sm);
    padding: 1px 5px;
    color: var(--tekst-secundair);
    background: var(--bg);
}
.cmp-soort.vol  { border-color: var(--accent);      color: var(--accent); }
.cmp-soort.vom  { border-color: var(--accent-warm); color: var(--accent-warm); }
.cmp-soort.pom  { border-color: var(--border-sterk); }
.cmp-soort.blad { border-color: var(--blauw);       color: var(--blauw); }

.cmp-rij .rijnaam { flex: 1; min-width: 0; }
.cmp-rij .rijnaam .roep {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cmp-rij .rijnaam .sk {
    display: block;
    font-size: 0.72rem;
    color: var(--tekst-tertiair);
}
.cmp-rij .maten {
    flex: 0 0 auto;
    font-size: 0.75rem;
    color: var(--tekst-tertiair);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.cmp-rij .prijs {
    flex: 0 0 auto;
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
    min-width: 5.5rem;
    text-align: right;
}
.cmp-rij .tel {
    flex: 0 0 auto;
    font-size: 0.7rem;
    border-radius: 9px;
    padding: 0 6px;
    background: var(--oranje-bg);
    color: var(--oranje);
}
.cmp-rij .tel.fout { background: var(--rood-bg); color: var(--rood); }
.cmp-rij.leeg .roep { color: var(--tekst-tertiair); font-style: italic; }

/* Nesting: een streepje links laat de laag zien zonder een boomdiagram te
   tekenen. Elke stap 18px — genoeg om te zien, weinig genoeg om drie lagen
   diep nog te kunnen lezen. */
.cmp-diep-1 { padding-left: calc(var(--space-md) + 18px); }
.cmp-diep-2 { padding-left: calc(var(--space-md) + 36px); }
.cmp-diep-3 { padding-left: calc(var(--space-md) + 54px); }
.cmp-kind { border-left: 2px solid var(--border-licht); }

.cmp-boom-voet {
    padding: var(--space-sm) var(--space-md);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.85rem;
    color: var(--tekst-secundair);
    font-variant-numeric: tabular-nums;
}

/* --- Rechterpaneel -------------------------------------------------------- */

.cmp-paneel {
    background: var(--bg-kaart);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--space-lg);
}

.cmp-paneelkop {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
}
.cmp-paneelkop h2 {
    margin: 0;
    font-size: 1.2rem;
    font-weight: var(--font-weight-medium);
}
.cmp-paneelkop .weg-pad {
    font-size: 0.8rem;
    color: var(--tekst-tertiair);
}

.cmp-sectiekop {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--tekst-tertiair);
    margin: var(--space-lg) 0 var(--space-sm);
}

/* DE VELDRIJ (herzien 3 sep 2026, feedback Luc). De invoervakken van één rij
   stonden niet op één lijn: een label van twee regels ("Bladhoogte (mm, dikte
   voorrand)") duwde zijn vak omlaag terwijl "Plinthoogte (mm)" ernaast bleef
   staan. Twee regels lossen dat op:

   1. het LABELVAK heeft een vaste hoogte (twee regels passen erin) en zijn
      tekst staat onderaan — daarmee begint elk invoervak op dezelfde baseline;
   2. de cellen zijn `align-items: start`, zodat een hint onder het vak blijft
      plakken in plaats van naar de onderkant van de hoogste cel te zakken.

   De maat staat als variabele naast de checkbox-uitlijning eronder: één getal,
   twee lezers. */
.cmp-page { --cmp-labelhoogte: 2.3rem; }

.cmp-veldrij {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-md);
    align-items: start;
}

.cmp-veld { display: flex; flex-direction: column; }
.cmp-veld > label {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1.25;
    color: var(--tekst-tertiair);
    margin-bottom: 3px;
    min-height: var(--cmp-labelhoogte);
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 4px 6px;
}
.cmp-veld input[type="text"],
.cmp-veld input[type="number"],
.cmp-veld select,
.cmp-veld textarea {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg);
    font: inherit;
    font-size: 0.92rem;
    color: var(--tekst);
}
.cmp-veld textarea { min-height: 64px; resize: vertical; }
.cmp-veld .hint {
    font-size: 0.75rem;
    color: var(--tekst-tertiair);
    margin-top: auto;
    padding-top: 2px;
}
.cmp-veld .vast {
    padding: 8px 0;
    font-size: 0.92rem;
    font-variant-numeric: tabular-nums;
}
/* Een vinkje heeft geen labelvak boven zich; hij zakt met de hand naar de
   hoogte van de invoervakken ernaast: labelhoogte + marge + de helft van het
   hoogteverschil tussen een invoervak en een vinkje-regel. */
.cmp-veld.bool {
    flex-direction: row;
    /* `flex-start`, niet `center`: een label van twee regels zou het vinkje
       anders naar beneden trekken en dan staan twee vinkjes naast elkaar op
       verschillende hoogte (gemeten in de UX-ronde van 3 sep 2026). */
    align-items: flex-start;
    align-self: start;
    gap: 8px;
    padding-top: calc(var(--cmp-labelhoogte) + 12px);
}
.cmp-veld.bool > input[type="checkbox"] { margin-top: 1px; }
.cmp-veld.bool > label {
    min-height: 0;
    display: inline;
    text-transform: none;
    letter-spacing: 0;
    margin: 0;
    font-size: 0.9rem;
    color: var(--tekst);
}
.cmp-veld.breed { grid-column: 1 / -1; }
.cmp-veld.breed > label { min-height: 0; }

/* Herkomst-label. Klein, grijs, altijd naast het label van het veld — zo weet
   je bij elke waarde waar hij vandaan komt zonder dat het scherm gaat schreeuwen.
   "uit model" = de lezing, "afgeleid" = de machine rekende het uit,
   "aangepast" = Luc heeft hem aangeraakt. */
.cmp-bron {
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-radius: var(--radius-sm);
    padding: 0 5px;
    background: var(--bg-hover);
    color: var(--tekst-tertiair);
}
.cmp-bron.model     { background: var(--blauw-bg);  color: var(--blauw); }
.cmp-bron.afgeleid  { background: var(--oranje-bg); color: var(--oranje); }
.cmp-bron.aangepast { background: var(--groen-bg);  color: var(--groen); }
.cmp-bron.erft      { background: var(--bg-hover);  color: var(--tekst-tertiair); }
/* "standaard" = de default uit het recept. Bewust het zwakste label van de
   vier: het zegt "hier is niets besloten", en dat mag je overslaan. Tot 3 sep
   2026 droeg zo'n waarde het label "aangepast" — precies het omgekeerde. */
.cmp-bron.standaard { background: transparent; color: var(--tekst-tertiair);
                      border: 1px solid var(--border-licht); }

/* Een groep velden binnen één kaart (Kantenband, Afwerking). Geen kader: een
   streepje en een kopje zijn genoeg om te zien waar het over gaat. */
.cmp-groep { margin: var(--space-md) 0 var(--space-sm); }
.cmp-groep > .kop {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--tekst-tertiair);
    border-bottom: 1px solid var(--border-licht);
    padding-bottom: 3px;
    margin-bottom: var(--space-sm);
}

/* Een feit uit het model dat GEEN invoer is: de maten van een getekend paneel.
   Ze staan er als regel, niet als vakje — de tekening is de bron. */
.cmp-leesregel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    font-size: 0.85rem;
    color: var(--tekst-secundair);
    font-variant-numeric: tabular-nums;
    padding: 2px 0 var(--space-sm);
}

/* De canon-sectie hoort ONDERAAN de onderdeelkaart (feedback Luc, 3 sep 2026):
   de kop is waar je keuzes maakt, de canon is de uitgang. Een lijn erboven en
   wat lucht maken dat zichtbaar. */
.cmp-canonsectie {
    margin-top: var(--space-xl);
    padding-top: var(--space-md);
    border-top: 2px solid var(--border);
}

/* Gecheckt: een rustige groene rij met een vinkje. Zelfde tint als de
   ok-melding, geen nieuwe kleur erbij. */
.cmp-rij.gecheckt { background: var(--groen-bg); }
.cmp-rij.gecheckt:hover { background: var(--groen-bg); filter: brightness(0.98); }
.cmp-rij .vink { flex: 0 0 auto; color: var(--groen); font-size: 0.85rem; }
.cmp-gecheckt {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    margin-top: var(--space-lg);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-licht);
}
.cmp-gecheckt .uitleg { font-size: 0.8rem; color: var(--tekst-tertiair); }
.cmp-telling { font-size: 0.8rem; color: var(--tekst-secundair); }

/* De maatregel van een volume: het modelfeit, altijd zichtbaar, nooit invoer. */
.cmp-modelregel {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-sm);
    background: var(--bg);
    border: 1px solid var(--border-licht);
    border-radius: var(--radius);
    padding: var(--space-sm) var(--space-md);
    font-size: 0.85rem;
    color: var(--tekst-secundair);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--space-md);
}

/* --- Componentkaarten ----------------------------------------------------- */

.cmp-kaart {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: var(--space-sm);
    overflow: hidden;
    background: var(--bg-kaart);
}
.cmp-kaart-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    background: var(--bg-sidebar);
    padding: var(--space-sm) var(--space-md);
    cursor: pointer;
}
.cmp-kaart-kop .titel { font-weight: var(--font-weight-medium); }
.cmp-kaart-kop .samenvatting {
    font-size: 0.85rem;
    color: var(--tekst-secundair);
}
.cmp-kaart-kop .knoppen { display: flex; gap: 2px; flex: 0 0 auto; }
.cmp-kaart-kop .greep {
    color: var(--tekst-tertiair);
    cursor: grab;
    margin-right: 6px;
    user-select: none;
}
.cmp-kaart-body {
    padding: var(--space-md);
    border-top: 1px solid var(--border-licht);
}
.cmp-kaart.sleept { opacity: 0.4; }
.cmp-kaart.sleep-boven { box-shadow: inset 0 3px 0 0 var(--accent); }
.cmp-kaart.sleep-onder { box-shadow: inset 0 -3px 0 0 var(--accent); }

.cmp-geavanceerd {
    margin-top: var(--space-md);
    border-top: 1px solid var(--border-licht);
    padding-top: var(--space-sm);
}
.cmp-geavanceerd > summary {
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--tekst-secundair);
    user-select: none;
}
.cmp-geavanceerd > summary .badge { margin-left: var(--space-xs); }

/* De kiezer: één keuzelijst per kaart, gefilterd op wat DIT volume mag
   bevatten. Geen palet met alles erin — je kiest op de laag waar je staat. */
.cmp-kiezer {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    align-items: center;
    padding-top: var(--space-md);
    border-top: 1px dashed var(--border);
    margin-top: var(--space-md);
}
.cmp-kiezer select { min-width: 220px; }
.cmp-kiezer label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--tekst-tertiair);
}

/* --- Tabellen ------------------------------------------------------------- */

.cmp-tabel {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin-top: var(--space-sm);
}
.cmp-tabel th {
    text-align: left;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--tekst-tertiair);
    border-bottom: 1px solid var(--border);
    padding: 4px 8px 4px 0;
    font-weight: var(--font-weight-normaal);
}
.cmp-tabel td {
    padding: 4px 8px 4px 0;
    border-bottom: 1px solid var(--border-licht);
    vertical-align: middle;
}
.cmp-tabel td.num, .cmp-tabel th.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.cmp-tabel .canon { color: var(--tekst-tertiair); font-size: 0.75rem; }

.cmp-vaktabel td { padding: 2px 4px 2px 0; }
.cmp-vaktabel td.nr { white-space: nowrap; color: var(--tekst-tertiair); }
.cmp-vaktabel input,
.cmp-vaktabel select { width: 100%; min-width: 6rem; padding: 3px 5px;
                       border: 1px solid var(--border); border-radius: var(--radius-sm);
                       background: var(--bg); font: inherit; font-size: 0.85rem;
                       color: var(--tekst); }
/* Een KEUZELIJST moet zijn langste optie kunnen tonen ("Deur-op-deur",
   "Onderkastlijn"): een afgekapte keuze lees je verkeerd, en dat is precies wat
   deze tabel niet mag doen. Een GETALVELD heeft daar niets aan — vier cijfers
   passen in de helft. Zo houdt de tabel het binnen de paneelbreedte zonder te
   scrollen én zonder te kappen. */
.cmp-vaktabel select { min-width: 7.5rem; }
.cmp-vaktabel input[type="number"] { min-width: 4.5rem; }

/* --- Uit SketchUp (preview) ------------------------------------------------ */

.cmp-sketchup {
    background: var(--bg-kaart);
    border: 1px solid var(--border-sterk);
    border-radius: var(--radius);
    padding: var(--space-lg);
    margin-bottom: var(--space-lg);
}
.cmp-sketchup h2 {
    margin: 0 0 var(--space-xs);
    font-size: 1.1rem;
    font-weight: var(--font-weight-medium);
}
.cmp-diffrij {
    display: flex;
    gap: var(--space-lg);
    flex-wrap: wrap;
    margin: var(--space-sm) 0;
    font-size: 0.85rem;
}
.cmp-diffrij b { font-variant-numeric: tabular-nums; }

/* --- Balk onderaan -------------------------------------------------------- */

.cmp-balk {
    position: sticky;
    bottom: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    background: var(--bg);
    border-top: 1px solid var(--border);
    padding: var(--space-md) 0;
    margin-top: var(--space-lg);
    z-index: 5;
}
.cmp-balk .status { font-size: 0.85rem; color: var(--tekst-secundair); }
.cmp-balk .knoppen { display: flex; gap: var(--space-sm); flex-wrap: wrap; }

/* --- Projectlijst --------------------------------------------------------- */

.cmp-projecten { display: grid; gap: var(--space-sm); }
.cmp-project {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    background: var(--bg-kaart);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--space-sm) var(--space-md);
    color: inherit;
    text-decoration: none;
}
.cmp-project:hover { background: var(--bg-hover); }
.cmp-project .code { font-weight: var(--font-weight-medium); min-width: 90px; }
.cmp-project .meta { color: var(--tekst-secundair); font-size: 0.85rem; }

.cmp-gelijk { margin-top: var(--space-md); }
.cmp-gelijk > summary { cursor: pointer; font-size: 0.85rem;
                        color: var(--tekst-secundair); }
.cmp-gelijk label { display: block; font-size: 0.88rem; padding: 2px 0; }


/* --- UX-ronde 2 sep 2026 --------------------------------------------------- */

/* Welk totaal staat hier? Zonder label wisselde hetzelfde vak stilzwijgend van
   betekenis (oude offerte / doorgerekende volumes / oude offerte weer). */
.cmp-totaalbron {
    grid-column: 1 / -1;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tekst-tertiair);
    margin-bottom: 2px;
}

/* Welke lezing er onder deze offerte ligt — als losse regel, zodat je er niet
   voor in een keuzelijst hoeft te kijken. */
.cmp-lezingregel { margin: calc(-1 * var(--space-md)) 0 var(--space-lg); }

/* Een kop-veld dat leeg bleef omdat het model zichzelf tegenspreekt (929 én
   930): de vraag staat over de volle breedte onder het veld, met de kandidaten
   als knop. */
.cmp-kopvraag { grid-column: 1 / -1; margin-top: calc(-1 * var(--space-sm)); }

/* "→ derden": dit blad verhuist bij het opslaan naar een eigen onderdeel. */
.cmp-vlag {
    font-size: 0.68rem;
    border: 1px solid var(--blauw);
    color: var(--blauw);
    border-radius: var(--radius-sm);
    padding: 0 4px;
    white-space: nowrap;
}

/* Een volume waarvan de kosten op onderdeel-grain zitten (de plintsegmenten)
   toont geen € 0,00 — dat leest als gratis en betekent in dezelfde boom ook
   "nog leeg". */
.cmp-rij .prijs .stil {
    color: var(--tekst-tertiair);
    font-size: 0.75rem;
    font-style: italic;
}

/* De volle materiaal- en arbeidtabellen: eigen scrollgebied in plaats van een
   pagina van 16.000 pixels. */
.cmp-regeltabel {
    max-height: 60vh;
    overflow: auto;
    border: 1px solid var(--border-licht);
    border-radius: var(--radius);
    padding: 0 var(--space-sm);
}
.cmp-regeltabel thead th {
    position: sticky;
    top: 0;
    background: var(--bg-kaart);
    z-index: 1;
}

/* Een legplank-aantal dat uit de vakhoogte is afgeleid: zelfde kleur als het
   "afgeleid"-label, zodat je in één oogopslag ziet wat de machine invulde en
   wat jij zelf zette. */
.cmp-vaktabel input.afgeleid { color: var(--oranje); }

/* Een rij die ALLEEN vinkjes bevat heeft niets om mee uit te lijnen; de
   inspringing die de vinkjes op de hoogte van de invoervakken zet is daar
   alleen maar een gat (de kantenband-groep op een POM-kaart). */
.cmp-veldrij:not(:has(> .cmp-veld:not(.bool))) > .cmp-veld.bool { padding-top: 0; }

/* --- Ronde 4 (3 sep 2026) ------------------------------------------------- */

/* Het klapteken rechts op een kaartkop. De kop is al helemaal klikbaar; dit is
   het teken dát hij dat is — zonder pijltje leest een dichte kaart als een
   titel zonder inhoud. */
.cmp-kaart-kop .cmp-klapteken {
    flex: 0 0 auto;
    color: var(--tekst-tertiair);
    font-size: 0.85rem;
}

/* Een heel onderdeel inklappen in de boom. Zelfde knop-vorm als de klap van een
   volume-rij, maar op de onderdeelkop — dus zonder de onderrand die daar de
   rijen scheidt. */
.cmp-onderdeel-kop > .cmp-klap {
    flex: 0 0 auto;
    background: none;
    border: 0;
    color: var(--tekst-tertiair);
    cursor: pointer;
    font: inherit;
    padding: 0 2px 0 var(--space-sm);
    width: 1.4rem;
    align-self: stretch;
}
.cmp-onderdeel-kop > .cmp-klap:hover { color: var(--tekst); }

/* Een keuzelijst in de vakkentabel waarvan de machine de waarde invulde (de
   achterwand van een apparaatvak). Zelfde kleur als het afgeleide plank-aantal
   en als het "afgeleid"-label ernaast. */
.cmp-vaktabel select.afgeleid { color: var(--oranje); }

/* Een cel die voor dit vak niet bestaat: de frontsplitsing van een vak zonder
   frontplaat. Een streepje zegt "hier valt niets te kiezen"; een lege cel zou
   als "nog niet ingevuld" lezen. */
.cmp-vaktabel td.nvt {
    color: var(--tekst-tertiair);
    text-align: center;
}

/* De vakkentabel mag binnen zijn eigen vlak horizontaal scrollen; de kaart
   eromheen blijft staan. Sinds de tabel nog maar zes kolommen telt (ronde 5,
   3 sep 2026: de zeldzame velden staan in een regel onder hun vak) past hij op
   een paneel van ±700 px en is `width: 100%` de juiste maat — met `max-content`
   wilde hij 972 px en scrollde hij dus altijd, ook als er ruimte genoeg was.
   De `min-width` op de invoervakken hieronder houdt de keuzelijsten leesbaar
   ("Deur-op-deur", "Onderkastlijn"); wordt het paneel smaller dan die som, dan
   scrolt hij alsnog in plaats van de tekst af te kappen. */
.cmp-vaktabel-wrap { overflow-x: auto; }
.cmp-vaktabel-wrap > .cmp-vaktabel { width: 100%; }

/* --- Ronde 5 (3 sep 2026) ------------------------------------------------- */

/* DE VAKKENTABEL COMPACT. Negen kolommen pasten niet op een paneel smaller dan
   ±1450 px; de achterwand-kolom viel buiten beeld en een kolom die je niet ziet
   vul je niet in. De kern (vak · maat uit · maat · front · planken · achterwand)
   staat in de tabel, de zeldzame velden (inbouwmaat, apparaat, front splitsen)
   in een regel ONDER het vak waarvoor ze gelden. Welke kolom waar hoort komt uit
   `toon_als` in de velddefinitie, niet uit deze CSS. */
.cmp-vak-extra > td { border-bottom: 1px solid var(--border-licht); padding-top: 0; }
.cmp-vak-extra-velden {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
    padding: 0 0 4px 0;
}
.cmp-vak-extra-velden > label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: var(--tekst-secundair);
}
/* Smal: deze velden zijn de uitzondering, ze horen de tabel niet te verbreden. */
.cmp-vak-extra-velden input,
.cmp-vak-extra-velden select { width: auto; min-width: 6.5rem; max-width: 11rem; }

/* De vul-knoppen op een lege VOM: één rij voorstellen, geen paneel vol keuzes. */
.cmp-vulknoppen { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.cmp-vulknoppen select { max-width: 16rem; }

/* Een uitgeschakelde secundaire knop moet er ook uitgeschakeld UITZIEN. In
   `base.css` staat die stand alleen voor `.btn-primary`; de kist-knop op een
   lege VOM is secundair en zag er actief uit terwijl hij niets deed (de reden
   staat in zijn title en in de hint eronder). */
.btn-secondary:disabled,
.btn-ghost:disabled { opacity: 0.45; cursor: not-allowed; }

/* Plaat-voorselectie per onderdeel (7 sep 2026): vinklijst van canon-platen. */
.cmp-vinklijst { display: grid; grid-template-columns: 1fr; gap: 2px; margin-top: var(--space-xs); max-height: 18rem; overflow-y: auto; }
.cmp-vink { display: flex; gap: var(--space-xs); align-items: center; font-size: 0.9em; }
.cmp-vink input { margin: 0; }

.cmp-boom-plus { text-align: right; padding: 2px var(--space-sm); }
.cmp-boom-plus .btn { opacity: .7; }

/* Bron-link op een vrije materiaalpost (7 sep 2026): intern, waar komt de prijs vandaan. */
.bron-cel{display:flex;gap:4px;align-items:center;min-width:160px}
.bron-cel input{flex:1;min-width:0;font-size:12px}
.bron-link{text-decoration:none;font-size:14px;line-height:1;padding:2px 4px}
