:root{
  --white:#FFFFFF;
  --primary:#2864AE;
  --secondary:#17223A;   /* ibley.nl, gemeten */
  --gray:#F8F9FA;        /* ibley.nl, gemeten */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;

  /* Het TV-dashboard zelf schaalt automatisch mee op elk scherm (zie
     .tv-canvas + fitTvCanvas() in app.js) en heeft dus geen zoom-factor
     meer nodig — dat voorkwam eerder juist het correcte 16:9-vastzetten
     op bv. een ultrawide scherm. */
  /* Zelfde idee voor de backoffice, die je vaker van dichtbij (laptop/monitor) bekijkt. */
  --office-zoom: 1.3;

  /* ---------- overgenomen van ibley.nl (gemeten 24-08-2026) ----------
     Twan: "We worden volledig zonder ingekleurde randen maar gebruiken een
     subtiele schaduw om het contrast te vergroten."

     De schaduw hieronder is letterlijk die van de webshop. De schaduw die dit
     dashboard tot nu toe gebruikte was ruim tweemaal zo donker (7% tegen 3%)
     en spreidde dubbel zo ver (14px tegen 7px), waardoor kaarten hier zwaarder
     op het vlak lagen dan in de winkel.

     De radii zijn er drie met elk een rol, zoals op ibley.nl. Dit dashboard had
     er acht (4, 5, 6, 7, 8, 9, 10 en 20px) zonder duidelijk onderscheid. */
  --schaduw-kaart: 0 0 1px 1px rgba(0,15,30,0.01), 0 2px 7px rgba(0,15,30,0.03), 0 1px 3px rgba(0,15,30,0.01);
  /* De breedte waarop Verzendklaar zijn kaarten en zijn balk centreert. */
  --wms-lijst-breed: 1300px;
  --radius-knop: 5px;
  --radius-veld: 8px;
  --radius-kaart: 12px;

  /* ---------- drie tekstkleuren, alle drie nagerekend (01-09-2026) ----------
     Aanleiding: een doorlichting van twaalf schermen in een echte browser gaf
     209 stukken tekst met te weinig contrast. Eén grijstint droeg vrijwel alle
     uitleg in de app en haalde 2,64 waar 4,5 het minimum is; de sorteerpijltjes
     zaten op 1,64 en waren daarmee praktisch onzichtbaar.

     De getallen hieronder zijn de gemeten verhouding op wit. Vervang deze
     waarden niet zonder opnieuw te rekenen — juist de kleine stapjes lichter
     ("het mag wel iets zachter") brachten het eerder onder de grens.

       --tekst          #17223A op wit = 15,8   gewone tekst
       --tekst-uitleg   #5D6675 op wit =  5,8   uitleg, bijschrift, kolomkop
       --tekst-zwak     #6B7486 op wit =  4,7   het zwakste dat nog mag

     GEEN vierde, lichtere tint erbij. Onder de 4,5 is het geen ontwerpkeuze
     meer maar tekst die een deel van de mensen niet leest. Wil je iets minder
     nadruk geven, gebruik dan een kleinere letter of meer witruimte — niet een
     lichter grijs. */
  --tekst: var(--secondary);
  --tekst-uitleg: #5D6675;
  --tekst-zwak: #6B7486;

  /* ---------- de afstandsladder (01-09-2026) ----------
     Gemeten over twaalf schermen: vijftien verschillende binnenmarges op
     vakken — 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 en 22 punten, kriskras
     door elkaar. Twee kaarten naast elkaar hadden zo 11 en 12 punten lucht:
     te weinig verschil om bedoeld te lijken, genoeg om onrustig te ogen.

     Vier waarden, net zoals er drie hoekafrondingen en één schaduw zijn.
     Nieuwe regels gebruiken deze; bestaande zijn hierheen afgerond waar dat
     zonder verspringen kon. Zit je te twijfelen tussen twee treden, neem dan
     de grotere — te veel lucht valt niemand op, te weinig wel. */
  --ruimte-krap: 6px;    /* binnen een regel: icoon naast tekst */
  --ruimte-klein: 10px;  /* binnen een vak: label boven waarde */
  --ruimte: 16px;        /* standaard binnenmarge van een vak */
  --ruimte-ruim: 24px;   /* tussen secties */

  /* ---------- DRIE VARIABELEN DIE GEBRUIKT WERDEN MAAR NIET BESTONDEN ----------
     Gevonden 01-09-2026: var(--border) staat op 37 plekken, var(--lijn) op 3,
     var(--card) op 4 — en geen van drieën was ooit gedefinieerd. Een
     declaratie met een onbekende variabele is ongeldig, dus die 37 regels
     deden letterlijk niets.

     WAT DAT BETEKENDE. Van die 37 zijn er 25 een scheidingslijn ín een
     component: de regels tussen orderregels in het inpakscherm, tussen de
     rijen van de paktabel, de lijn naast een groepskop. Die waren er dus
     gewoon niet — een tabel zonder rijlijnen.

     WAAROM DIT GEEN BOTSING IS MET "GEEN INGEKLEURDE RANDEN".
     Twan, 24-08-2026: "We worden volledig zonder ingekleurde randen maar
     gebruiken een subtiele schaduw om het contrast te vergroten." Dat gaat
     over de rand ROND een witte kaart; die komt van --schaduw-kaart en blijft
     zo. Een lijn TUSSEN twee rijen binnen zo'n kaart is iets anders en heeft
     de app al 25 keer met #e3e4e6 letterlijk in de code staan. Deze waarde is
     dus geen nieuwe keuze maar dezelfde die er al is. */
  --border: #e3e4e6;
  /* --lijn en --card krijgen bewust GEEN waarde. Allebei worden ze alleen
     aangeroepen mét terugval — var(--lijn, #E3E7EC), var(--card, #fff) — dus
     ze werken al. Ze alsnog definiëren maakt een tweede bron van waarheid voor
     "wit" en "lijn" naast --card/--border, en dat is precies hoe je twee
     kleuren krijgt die net niet gelijk zijn. tests/wms-nakijken.test.js legde
     dat voor --card al vast; hier dus met rust gelaten. --border is een ander
     geval: die wordt 25 keer ZONDER terugval gebruikt en werkte dus niet. */

  /* Ook zonder definitie in gebruik: --danger (2x) en --warning (1x), allebei
     op de waarschuwingskaart over achtergrondtaken — een gekleurde linkerrand
     plus het icoon. Zonder waarde geen rand en geen kleur, dus die kaart zag
     er precies zo uit als een gewone. Beide waarden komen uit wat de app al
     gebruikt: #993C1D is het rood van .btn-danger (6,96 op wit), #9A5B00 het
     oranje van de analysebanner (5,43). */
  --danger: #993C1D;
  --warning: #9A5B00;

  /* --muted WERD OP 20 PLEKKEN GEBRUIKT MAAR NERGENS GEDEFINIEERD (gevonden
     01-09-2026). `color: var(--muted)` zonder definitie is ongeldig en valt
     terug op de geërfde kleur — die twintig plekken waren dus helemaal niet
     gedempt, ze namen gewoon de kleur van hun ouder over. Hier alsnog
     vastgelegd, als dezelfde kleur als de uitleg. */
  --muted: var(--tekst-uitleg);

  /* GEEN INGEKLEURDE RANDEN OM WITTE VLAKKEN. Gemeten op ibley.nl: nul. Dit
     dashboard had er vijftien. Contrast komt van --schaduw-kaart.
     Uitzonderingen die WEL een rand houden: een driehoekje dat met `border`
     wordt getekend (.adv-waarschuwing::before) en een lichte rand op een DONKER
     vlak (.refresh-status-pill) — dat is geen grijze lijn om wit. */
}

*{ box-sizing:border-box; }
html,body{ margin:0; height:100%; font-family:var(--font-sans); background:var(--gray); }
.view{ display:none; }
.view.active{ display:flex; }

button, input, select{ font-family:inherit; }

/* ---------- Login ---------- */
.login-view{ min-height:100vh; align-items:center; justify-content:center; background:#fff; }
.login-card{ display:flex; flex-direction:column; align-items:center; gap:14px; }
.brand-logo{ width:56px; height:56px; border-radius:14px; background:var(--primary); color:#fff; display:flex; align-items:center; justify-content:center; font-size:20px; font-weight:500; }
.brand-title{ font-size:20px; font-weight:500; color:var(--secondary); }
.login-form{ display:flex; flex-direction:column; gap:10px; width:260px; }

/* ---------- hoe oud is wat je ziet (01-09-2026) ----------
   Kleur volgt de leeftijd: onder het kwartier rustig, daarboven oranje, boven
   het uur rood. Alle drie nagerekend op het lichte vlak waar ze op staan —
   #5D6675 geeft 5,5, #9A5B00 geeft 5,2 en #993C1D geeft 6,6. */
.versheid{
  display:inline-flex; align-items:center; gap:5px;
  font-size:11.5px; color:var(--tekst-uitleg);
  background:transparent; border:none; padding:4px 6px; border-radius:var(--radius-knop);
  font-family:inherit; cursor:default;
}
button.versheid{ cursor:pointer; }
button.versheid:hover{ background:var(--gray); }
.versheid i{ font-size:13px; }
.versheid.ouder{ color:#9A5B00; }
.versheid.oud{ color:#993C1D; }

/* ---------- skeletschermen (01-09-2026) ----------
   Achttien plekken toonden een draaiend rondje met "Laden…". Op de telefoon
   staat hier al een skelet, en dat werkt beter: je ogen weten alvast waar wat
   komt, en de bladzijde springt niet als de echte inhoud arriveert.

   De glans is letterlijk dezelfde als in mobile.css — zelfde verloop, zelfde
   1,25 seconde. Twee apparaten, één beweging. */
/* NIET var(--gray). Dat is #F8F9FA, het paginavlak — op een witte kaart geeft
   dat 1,05 en dan zie je de blokjes gewoon niet. #E9ECF1 geeft 1,18 op wit en
   1,12 op het grijze vlak: zichtbaar als vorm, zonder dat het eruitziet als
   echte inhoud. Een skelet dat je aanziet voor tekst is erger dan geen skelet. */
.sk{ background:#E9ECF1; border-radius:6px; position:relative; overflow:hidden; display:block; }
.sk::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.62), transparent);
  transform:translateX(-100%); animation:sk-glans 1.25s infinite;
}
@keyframes sk-glans{ 100%{ transform:translateX(100%); } }
/* Wie beweging heeft uitgezet krijgt de blokjes zonder glans. De vorm blijft,
   en die is het halve punt. */
@media (prefers-reduced-motion: reduce){ .sk::after{ animation:none; } }

.sk-scherm{ padding-top:4px; }
.sk-rij{ display:flex; align-items:center; gap:10px; padding:10px 0; border-bottom:1px solid var(--border); }
.sk-rij:last-child{ border-bottom:none; }
.sk-cijfers{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:16px; margin-bottom:24px; }
.sk-cijfer{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:16px; }
.sk-kaarten{ display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:16px; }
.sk-kaart{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:16px; }

/* ---------- het opstartscherm na het inloggen (01-09-2026) ----------
   Twan: "Een animatie zodra je de juiste inloggegevens hebt ingevoerd lijkt me
   wel handig. Hier wacht ik regelmatig 5 seconden namelijk."

   Zelfde breedte als het formulier dat het vervangt (260px), zodat de kaart
   niet verspringt op het moment dat je op Inloggen drukt. Dat verspringen is
   precies wat je niet wilt bij iets dat bedoeld is om rust te geven.

   Contrast nagerekend op de witte kaart: de kop 15,8, de stap-tekst 5,8, het
   groene vinkje 6,3. */
.login-splash{ width:260px; display:flex; flex-direction:column; gap:10px; }
.login-splash-kop{
  display:flex; align-items:center; gap:7px;
  font-size:14px; font-weight:500; color:var(--secondary);
}
.login-splash-kop i{ color:#2F6B4F; font-size:16px; }
.login-splash-balk{ height:4px; background:var(--gray); border-radius:999px; overflow:hidden; }
/* De breedte wordt door JavaScript gezet, per binnengekomen verzoek. De
   overgang maakt van negen sprongen één vloeiende beweging; zonder deze regel
   klikt de balk zichtbaar door in stappen van elf procent. */
.login-splash-balk i{
  display:block; height:100%; width:4%;
  background:var(--primary); border-radius:999px;
  transition:width .35s cubic-bezier(.4,0,.2,1);
}
.login-splash-stap{ font-size:12.5px; color:var(--tekst-uitleg); }
/* Wie beweging heeft uitgezet krijgt de balk zonder overgang: hij springt dan
   gewoon naar de juiste stand. De informatie blijft, de animatie niet. */
@media (prefers-reduced-motion: reduce){
  .login-splash-balk i{ transition:none; }
}
.login-form input, .login-form select{ font-size:14px; padding:10px 16px; border-radius:var(--radius-veld); border:none; background:var(--gray); color:#000; width:100%; box-sizing:border-box; }
.login-form button{ background:var(--primary); color:#fff; border:none; font-size:14px; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; margin-top:4px; }
.login-error{ color:#993C1D; font-size:12px; min-height:16px; text-align:center; }
.login-toggle-link{ font-size:13px; text-align:center; }
.login-toggle-link a{ color:var(--primary); text-decoration:none; cursor:pointer; }
.login-toggle-link a:hover{ text-decoration:underline; }

/* ---------- Office / backoffice ---------- */
.office-view{ flex-direction:column; min-height:100vh; zoom:var(--office-zoom); }
/* Feedback (na styleguide-preview op basis van ibley.nl): "Header, goeie
   verbetering" — enige onderdeel van het restyle-voorstel dat is goedgekeurd
   (knoppen/badges/statkaarten expliciet "huidig is beter", dus ongewijzigd
   gelaten). Header krijgt kleur i.p.v. wit, verder blijven alle bestaande
   elementen/knopklassen (tabs, .btn-soft, avatar) hetzelfde — enkel de
   kleuren eronder zijn aangepast zodat ze op de gekleurde achtergrond
   blijven werken.
   Feedback (2e ronde): "de header klopt niet qua achtergrondkleur, je
   styleguide had #2864AE, niet #17223A — die is enkel bedoeld voor een
   omroepbalk voor storingen enzo." Dus var(--primary) i.p.v.
   var(--secondary). De navy blijft gereserveerd voor precies dat: zie
   .office-incident-bar hieronder, een dunne storingsbalk die alleen
   verschijnt zodra er actieve sync-/API-problemen zijn (zelfde telling als
   het rode badge bij Connecties, zie foutmeldingenCount in app.js). */
/* GAP, ZODAT DE TWEE GROEPEN ELKAAR NIET RAKEN.
   Zonder deze gap groeit de linkergroep (flex:1 1 auto) tot precies tegen de
   rechtergroep aan, en dan staat de "Meer"-knop tegen "Naar sales dashboard"
   geplakt. space-between verdeelt alleen wat er OVER is — en er is niets
   over zodra de tabbladen de ruimte opvullen. */
/* ---------- de kopbalk (02-09-2026) ----------
   Twan: "Wellicht kunnen we de topbar nu ook wat mooier maken?"

   Het grootste probleem was niet de kleur maar de UITLIJNING. De inhoud staat
   sinds vandaag in een kolom van 1600 die op een ultrawide in het midden
   hangt; de kopbalk liep nog van rand tot rand, dus het logo stond 475 punten
   links van alles eronder en het accountmenu net zoveel rechts ervan. Dezelfde
   formule als bij .office-body zet ze op één lijn — met de 52 van de
   ingeklapte rail erin, zodat de kopbalk NIET verspringt als je het menu
   vastspeldt.

   Verder: 12 in plaats van 16 hoog (de balk was met de tabbladen eruit te dik
   voor wat er nog in staat), een verloop en een donkere haarlijn onderaan,
   zodat het een oppervlak is en geen vlak.

   HET VERLOOP GAAT NAAR BENEDEN DONKERDER, NIET LICHTER. Eerste versie liep
   van #2E6DB8 naar #2864AE, dus de bovenkant werd lichter — en daar zakte
   .account-label (wit op 86%, zie hieronder) van 4,87 naar 3,94. Nu begint hij
   op de bestaande kleur en wordt hij alleen donkerder, waardoor geen enkel
   contrast in deze balk omlaag kan. */
.office-header{
  background:linear-gradient(180deg,var(--primary) 0%, #245C9F 100%);
  box-shadow:inset 0 -1px 0 rgba(0,0,0,.18);
  /* DE KOPBALK LOOPT NU MEE MET DE INHOUD (06-09-2026).
     Twan: "het logo en het account icoon rechts in de balk lijnen niet uit met
     de content eronder ... tenminste als het menu vastgezet is."

     Hier stond een vaste 52 in de formule — de breedte van de INGEKLAPTE rail.
     Dat was met opzet: zo verspringt de balk niet als je het menu vastspeldt.
     Maar het gevolg is dat de inhoud eronder wél opschuift, van 52 naar 250,
     en dan staat de balk 294 punten uit de pas. Gemeten op 1600 breed:
       niet vastgezet: logo 31, inhoud 68   -> 36 verschil
       vastgezet:      logo 31, inhoud 325  -> 294 verschil
     Ook zonder vastzetten liep het dus al 36 uit de pas.

     Nu gebruikt de balk exact dezelfde maten als .office-body: dezelfde
     railbreedte (die meebeweegt met vastspelden) en dezelfde inspringing.
     Hij verspringt daardoor wél bij vastspelden — maar dat doet de hele
     inhoud eronder ook, dus dat is precies wat je wilt zien. */
  --zb-breedte: 52px;
  --zb-inspring: max(0px, calc((100% - var(--zb-breedte) - 1648px) / 2));
  padding:12px var(--zb-inspring) 12px calc(var(--zb-breedte) + var(--zb-inspring));
  display:flex; align-items:center; justify-content:space-between; flex-shrink:0; gap:var(--ruimte-ruim);
}
/* De lichte variant. Twan koos "allebei uitwerken", dus dit is een schakelaar
   bij Instellingen > Geavanceerd en geen tweede app. Per APPARAAT, net als het
   openklappen van de menugroepen: de inpak-pc staat in ander licht dan de
   werkplek, en dit verandert niets aan de gegevens.
   Wit op #F8F9FA is bijna hetzelfde, dus de balk krijgt hier een echte rand;
   zonder dat zweeft hij. */
.kop-licht .office-header{
  background:#fff;
  border-bottom:1px solid var(--border);
  box-shadow:0 1px 2px rgba(20,26,34,.04);
}
.kop-licht .office-brand-logo{ background:var(--primary); color:#fff; }
.kop-licht .office-brand-title{ color:var(--secondary); }
/* Alles wat in de blauwe balk wit was, moet hier de donkere tekstkleur
   krijgen. 5,80 op wit (zie --tekst-uitleg) voor het bijschrift, de volle
   tekstkleur voor de naam zelf. */
.kop-licht .office-header-right,
.kop-licht .office-header-right button,
.kop-licht .office-header-right a{ color:var(--secondary); }
/* Deze twee stonden op doorzichtig wit; op een witte balk zijn ze dan weg.
   #5D6675 geeft 5,80 op wit, en de avatar krijgt de merkkleur in plaats van
   een grijswaas. */
.kop-licht .office-header .account-label{ color:var(--tekst-uitleg); }
.kop-licht .office-header .avatar{ background:var(--primary); color:#fff; box-shadow:none; }
.kop-licht .office-header .wk-knop{ background:#fff; border-color:var(--border); color:var(--secondary); }
.kop-licht .office-header .wk-knop:hover{ background:var(--gray); }
/* De storingsbalk is donker en zat tegen het blauw aan; onder een witte balk
   heeft hij zijn eigen scheiding nodig. */
.kop-licht .office-incident-bar{ border-top:none; }

/* De winkelkiezer als pil: het is één keuze, geen knop die iets doet. */
.office-header .wk-knop{
  background:rgba(255,255,255,.12); border:1px solid rgba(255,255,255,.22);
  color:#fff; border-radius:999px; padding:6px 10px; font-size:12.5px;
}
.office-header .wk-knop:hover{ background:rgba(255,255,255,.20); }
.office-brand-title{ font-size:15px; letter-spacing:.01em; }
.office-incident-bar{ display:none; align-items:center; gap:8px; background:var(--secondary); color:#fff; padding:6px 24px; font-size:12.5px; flex-shrink:0; }
.office-incident-bar.show{ display:flex; }
.office-incident-bar i{ font-size:14px; color:#FFD166; }
/* Stond op 19 punten hoog. Een tekstlink in een smalle balk mag laag blijven,
   maar niet lager dan waar je hem nog raakt: met verticale ruimte eromheen
   komt hij op 24 zonder dat de balk dikker wordt. */
.office-incident-link{ background:none; border:none; color:#fff; text-decoration:underline; cursor:pointer; font-size:12.5px; padding:6px 0; margin-left:2px; font-family:inherit; }
/* DE RECHTERKANT VAN DE KOPBALK MAG NOOIT BUITEN BEELD VALLEN (01-09-2026).
   Gemeten: de balk had 1832 beeldpunten nodig. Op een 14"-scherm viel 320px
   buiten beeld, op een 16" nog 104px — en dat is precies het stuk waar je
   accountmenu staat. De hele pagina kreeg er een horizontale schuifbalk van.

   Oorzaak: `justify-content:space-between` verdeelt wat er OVER is, maar de
   linkergroep (logo + twaalf tabbladen) kon niet krimpen. Een flex-item heeft
   standaard `min-width:auto`, en dat betekent "nooit smaller dan mijn
   inhoud" — dus duwde de linkerkant de rechterkant er gewoon uit.

   min-width:0 links laat hem wél krimpen; flex-shrink:0 rechts zet vast dat
   het accountmenu als laatste inlevert, namelijk nooit. Sinds de zijbalk
   (02-09-2026) staan er nog maar drie dingen in de kopbalk — logo,
   winkelkiezer en account — dus het knelt er niet meer. */
.office-header-left{ display:flex; align-items:center; gap:22px; min-width:0; flex:1 1 auto; }
.office-brand{ display:flex; align-items:center; gap:9px; }
/* HET ECHTE WOORDMERK IN DE KOPBALK (03-09-2026).
   Twan: "Ook het Ibley sales icoon mag een ibley icoon worden in de topbar."
   Hier stond een "IB"-monogram in een blokje. Nu hetzelfde logo als de mobiele
   app: favicon.png als MASKER, zodat de PNG alleen de vorm bepaalt en de kleur
   uit ons stylesheet komt. Dat is nodig omdat de kopbalk #2864AE is — het
   tweekleurige logo (donkerblauw "Ibl") zou daarop wegvallen. Wit dus, in één
   kleur; de kopbalk is al blauw genoeg. */
/* HET LOGO WERD AFGESNEDEN, EN HAD DE VERKEERDE KLEUR (06-09-2026).
   Twan: "Waarom snijd het logo deels af?" en "waarom is het logo niet in de
   juiste kleurstelling?"

   Eén oorzaak voor allebei: dit was een CSS-masker van favicon.png.
     - favicon.png is 512x512, met het woordmerk in een band in het midden.
       `100% auto` maakte hem 62 breed en dus 62 hoog, in een vakje van 22.
       De staart van de "y" viel als eerste weg.
     - Een masker gooit alle kleur weg; je vult de vorm met één effen kleur.
       Het echte logo is tweekleurig: "Ibl" donkerblauw, "ey" blauw.

   Nu staat er public/logo.png — hetzelfde beeld, bijgesneden tot de rand van
   de inkt (512x253, verhouding 2,02:1) door tools/logo-bijsnijden.js. Het
   vakje volgt die verhouding, dus er wordt niets meer afgesneden.

   OP DE BLAUWE BALK BLIJFT HET WIT, zoals het was. Twan: "met de blauwe
   achtergrond kunnen we toch het witte logo gebruiken zoals de eerdere versie
   had?" Daar is het masker juist het goede gereedschap — het maakt van elke
   vorm één effen wit. Op de lichte balk tonen we de echte afbeelding, want
   daar kán de eigen kleurstelling. */
.office-merk{
  width:62px; height:31px; flex-shrink:0; display:block;
  background:#fff;
  -webkit-mask:url('/logo.png') no-repeat center / contain;
  mask:url('/logo.png') no-repeat center / contain;
}
/* Lichte kopbalk: het echte logo, in zijn eigen twee kleuren. Het masker moet
   dan uit, anders overschrijft de effen vulling de afbeelding alsnog. */
.kop-licht .office-merk{
  background:url('/logo.png') no-repeat center / contain;
  -webkit-mask:none; mask:none;
}
.office-brand-logo{ width:26px; height:26px; border-radius:7px; background:#fff; color:var(--secondary); font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center; }
.office-brand-title{ font-weight:500; color:#fff; }
.tabs{ display:flex; gap:4px; min-width:0; }
/* WIT OP 86%, NIET 68% (01-09-2026).
   De kopbalk is #2864AE. Wit op 68% geeft daar 3,68 — onder de eis van 4,5,
   en dit is de navigatie van de hele app. 86% brengt het op 4,87. */
.tabs button{ background:transparent; border:none; font-size:13px; font-weight:500; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; color:rgba(255,255,255,0.86); }
/* EEN DONKERE VULLING, GEEN LICHTE.
   Het tabblad waar je op staat werd gemarkeerd met wit op 16%. Dat maakt de
   achtergrond lichter en drukt het contrast van de witte tekst juist omlaag,
   naar 4,25 — het actieve tabblad las dus slechter dan alle andere. Zwart op
   18% doet hetzelfde werk (je ziet welke aan staat), maar brengt het contrast
   op 7,87. Het leest bovendien als ingedrukt, wat hier ook klopt. */
.tabs button.active{ background:rgba(0,0,0,0.18); color:#fff; }
/* Analyse-hoofdtab: hover-dropdown die splitst in Bol/Shopify (zie
   ANALYSE_TOOLS/renderTabs() in app.js). .nav-dropdown is een gewone flex-
   child van .tabs (position:relative erbovenop voor het absoluut
   gepositioneerde menu); de knop zelf erft de normale .tabs button-stijl
   via de descendant-selector hierboven. */
.nav-dropdown{ position:relative; }
.nav-new-badge{ background:#FFD166; color:#7A4A00; font-size:8.5px; font-weight:700; padding:1.5px 6px; border-radius:999px; margin-left:2px; vertical-align:middle; text-transform:uppercase; letter-spacing:.02em; }
.nav-dropdown-menu{ display:none; position:absolute; left:0; top:100%; background:#fff; border-radius:var(--radius-kaart); box-shadow:0 4px 16px rgba(0,0,0,0.14); min-width:260px; z-index:60; padding:6px; }
.nav-dropdown:hover .nav-dropdown-menu{ display:block; }
.nav-dropdown-group{ font-size:10px; text-transform:uppercase; letter-spacing:.04em; color:var(--tekst-uitleg); font-weight:600; padding:10px 10px 6px; }
.nav-dropdown-menu .nav-dropdown-item{ display:flex; align-items:center; gap:8px; width:100%; background:none; border:none; text-align:left; font-size:12.5px; color:var(--secondary); padding:10px 10px; border-radius:var(--radius-knop); cursor:pointer; font-weight:400; }
.nav-dropdown-menu .nav-dropdown-item:hover{ background:var(--gray); }
.nav-dropdown-menu .nav-dropdown-item.active{ background:#EAF0F8; color:var(--primary); font-weight:500; }
.nav-dropdown-menu .nav-dropdown-item i{ font-size:14px; color:var(--tekst-uitleg); width:16px; }

/* Hier stond het "Meer"-menu: de opvang voor tabbladen die niet in de
   horizontale balk pasten. Met de zijbalk (02-09-2026) past alles en is die
   constructie overbodig. */
/* Analyse-tools tonen bewust voorbeelddata (nog geen live koppeling) — deze
   banner staat bovenaan elke tool, zelfde functie als de "Voorbeeld (met
   nepdata)"-labels in retouren-kpi-voorstel.html, maar dan permanent
   zichtbaar zolang de echte koppeling er nog niet is. */
.analyse-demo-banner{ display:flex; align-items:center; gap:8px; background:#FFF4E5; color:#9A5B00; border-radius:var(--radius-kaart); padding:10px 16px; font-size:12px; margin-bottom:16px; }
.analyse-demo-banner i{ font-size:15px; flex-shrink:0; }
.niche-chip{ font-size:11.5px; padding:6px 10px; border-radius:999px; background:var(--gray); color:var(--secondary); border:none; cursor:pointer; }
.niche-chip.on{ background:var(--primary); color:#fff; font-weight:500; }
.niche-chip[disabled]{ cursor:default; opacity:.85; }
/* Dezelfde melding op de telefoon (zie mMeld in mobile.js). */
.m-melding{ background:#FDECEC; color:#9B1C1C; border-radius:var(--radius-kaart);
  padding:10px 16px; margin:0 0 10px 0; font-size:13px; line-height:1.5; }
.m-melding > div{ font-weight:400; margin-top:2px; }

/* Het dagoverzicht: de bronlink achter een bewering. Het grijze vak waar de
   alinea in stond is weg — die zin staat nu in het blad zelf (zie .dag-blad),
   want een eigen grijs kader maakte er een terzijde van terwijl het de
   samenvatting van de dag is. */
/* De bron achter een bewering. Hij hoort als verwijzing te lezen, niet als
   het begin van de volgende zin — vandaar de ruimte ervoor, het stippellijntje
   eronder, en dat hij nooit halverwege afbreekt. */
.dag-bron{ font-size:11px; color:var(--primary); text-decoration:none;
  white-space:nowrap; margin:0 6px 0 2px; border-bottom:1px dotted currentColor;
  transition:color .15s ease, border-color .15s ease; }
.dag-bron:hover{ border-bottom-style:solid; }
.dag-bron:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; border-radius:2px; }
.dag-strip{ display:flex; align-items:center; gap:10px; justify-content:space-between;
  background:var(--gray); border-radius:var(--radius-kaart); padding:10px 16px; margin-bottom:10px; font-size:12.5px; }

/* De balk van de kwaliteitsscore: 0 tot 100, met de drie grenzen van bol als
   streepjes erin. Een getal alleen zegt niets; naast de grens waar Select Deals
   begint zegt het alles. */
.kwaliteit-balk{ position:relative; height:10px; background:var(--gray); border-radius:999px; overflow:hidden; }
.kwaliteit-balk-vulling{ height:100%; border-radius:999px; }
.kwaliteit-grens{ position:absolute; top:0; bottom:0; width:2px; background:rgba(22,34,58,0.35); }

/* MELDINGEN IN HET SCHERM ZELF (07-09-2026) — de vervanging van alert().
   Klein, bovenaan het formulier of de lijst waar de handeling gebeurde, en
   met genoeg contrast om op te vallen zonder het scherm te blokkeren. */
.scherm-melding{ display:flex; align-items:flex-start; gap:8px; margin:0 0 10px 0;
  padding:10px 16px; border-radius:var(--radius-kaart); font-size:12px; line-height:1.5; }
.scherm-melding.fout{ background:#FDECEC; color:#9B1C1C; }
.scherm-melding.goed{ background:#E9F5E6; color:#3B6D11; }
.scherm-melding i{ flex-shrink:0; margin-top:1px; }
.scherm-melding > div{ flex:1; min-width:0; }
.scherm-melding > div > div{ font-weight:400; margin-top:2px; }
.scherm-melding-sluit{ background:none; border:none; cursor:pointer; color:inherit; opacity:.7;
  padding:0 2px; line-height:1; }
.scherm-melding-sluit:hover{ opacity:1; }

/* UITLEG IS GEEN WAARSCHUWING (07-09-2026).
   Twan: "uitleg is geen melding ... uitlegteksten alleen als vaste hulptekst
   bij het onderdeel waar ze over gaan." De oranje .analyse-caveat hieronder is
   een voorbehoud bij een cijfer — dat mag opvallen. Gewone uitleg hoort rustig
   te zijn, anders leest elk scherm als een storing. */
.uitleg-blok{ background:var(--gray); color:var(--tekst-uitleg); border-radius:var(--radius-kaart);
  padding:10px 16px; font-size:11.5px; margin-top:10px; line-height:1.6; max-width:70ch; }
.uitleg-blok.status-bad{ background:#FAECE7; color:#993C1D; }
/* HOE OUD ZIJN DEZE CIJFERS? (20-09-2026, keuze 1 uit het voorstel)
   Eén regel onder de titel op de zes schermen die op een sync leunen. Geen
   pop-up en geen kader om het hele scherm: je moet het zien zonder dat het je
   werk onderbreekt.
   Hij deelt de opmaak van .analyse-caveat en heeft dus GEEN eigen kleuren: het
   is dezelfde soort mededeling — wat je ziet klopt, maar het is niet compleet —
   en een tweede keer #FAECE7 intypen is precies wat bouwdoos-waarden.test.js
   tegenhoudt. Alleen de indeling komt erbij, met waarden van de afstandsladder. */
.verouderd-regel{ display:flex; align-items:center; gap:var(--ruimte-krap); flex-wrap:wrap;
  margin-top:0; margin-bottom:var(--ruimte-klein); }
.verouderd-regel a{ color:inherit; font-weight:600; text-decoration:underline; }
.analyse-caveat, .verouderd-regel{ background:#FAECE7; color:#993C1D; border-radius:var(--radius-kaart); padding:10px 16px; font-size:11.5px; margin-top:10px; line-height:1.6; }
/* Doorzoekbare productkiezer bij de Concurrentietracker (feedback: "kan
   beter een filterbare pop-up lijst zijn... bij veel EAN's wordt dit anders
   niet te doen") — losse rijen i.p.v. pil-knoppen, schaalt naar veel EAN's. */
.concurrent-picker-list{ display:flex; flex-direction:column; gap:4px; max-width:480px; max-height:360px; overflow-y:auto; }
.concurrent-picker-item{ display:flex; align-items:center; gap:10px; width:100%; background:#fff; border:none; box-shadow:var(--schaduw-kaart); text-align:left; padding:10px 10px; border-radius:var(--radius-kaart); cursor:pointer; font-size:12.5px; color:var(--secondary); }
.concurrent-picker-item:hover{ background:var(--gray); }
/* Feedback (Twan): "een grid inladen met alle artikelen (4 breed) en dan
   een kaart uitklappen om daar alles in te zetten" — vervangt de aparte
   kies-/detailpagina's door 1 doorlopend grid met inline uitklapbare
   kaarten (wisselen tussen pagina's scheelt, meerdere producten snel
   achter elkaar controleren gaat sneller). De uitgeklapte-detail-tegel
   krijgt grid-column:1/-1 zodat 'ie een eigen volle rij pakt precies waar
   'ie in de DOM-volgorde staat — CSS Grid regelt de rest vanzelf. */
.concurrent-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }
@media (max-width:1100px){ .concurrent-grid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:640px){ .concurrent-grid{ grid-template-columns:1fr; } }
/* Feedback (Twan): "graag nog de grijze lijn om de productkaarten weg en
   vervangen voor een schaduw erachter" — zelfde patroon als .card hierboven
   (geen rand, alleen een zachte schaduw). */
.concurrent-card{ position:relative; display:flex; flex-direction:column; gap:8px; background:#fff; border:none; border-radius:var(--radius-kaart); padding:10px; cursor:pointer; text-align:left; box-shadow:var(--schaduw-kaart); }
.concurrent-card:hover{ background:var(--gray); }
.concurrent-card.expanded{ background:#F3F7FC; box-shadow:0 0 0 1px rgba(40,100,174,0.18), 0 2px 7px rgba(40,100,174,0.10); }
.concurrent-card-untrack{ position:absolute; top:8px; right:8px; background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-knop); width:24px; height:24px; display:flex; align-items:center; justify-content:center; color:#993C1D; cursor:pointer; }
.concurrent-card-title{ font-weight:500; font-size:12.5px; color:var(--secondary); line-height:1.35; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.concurrent-detail-tile{ grid-column:1/-1; background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-kaart); padding:16px; }
/* "Trainen"-knoppen bij de Concurrentietracker (feedback: "geef je mij
   knoppen om een gevonden EAN te markeren als concurrent of geen
   concurrent") — zelfde kleine pil-knop-stijl als .niche-chip. */
.concurrent-mark-btn{ background:#fff; border:none; box-shadow:var(--schaduw-kaart); color:var(--tekst-uitleg); font-size:11px; padding:4px 10px; border-radius:var(--radius-knop); cursor:pointer; margin-right:4px; }
.concurrent-mark-btn:hover{ background:var(--gray); }
.concurrent-mark-btn.on[data-mark="concurrent"]{ background:#FAECE7; color:#993C1D; border-color:#FAECE7; }
.concurrent-mark-btn.on[data-mark="geen-concurrent"]{ background:#E9F5EE; color:#0F6E56; border-color:#E9F5EE; }
/* Matchtermen als losse, verwijderbare pilletjes (feedback: "afstandsbedieningen
   kunnen wel meer dan 50 modellen ondersteunen voor 1 merk" — dus meerdere
   matchtermen per product, niet 1 los tekstveld). Zelfde pil-vorm als
   .niche-chip, met een eigen kruisje i.p.v. een aan/uit-toggle. */
.term-chip{ display:inline-flex; align-items:center; gap:5px; font-size:11px; padding:4px 6px 4px 10px; border-radius:999px; background:var(--gray); color:var(--secondary); margin:2px 4px 2px 0; }
.term-chip button{ background:none; border:none; color:#9aa0a6; cursor:pointer; font-size:12px; line-height:1; padding:0 2px; }
.term-chip button:hover{ color:#993C1D; }
/* AI-overzicht-blok (feedback: "kunnen we ook een soort AI overzicht erbij
   maken van de verschillen?") — bewust een ANDERE kleur dan de oranje
   .analyse-caveat, zodat meteen duidelijk is dat dit een samenvatting is en
   geen waarschuwing. In de demo puur tekst getemplate uit de voorbeelddata
   zelf (zie matchDemoAiOverzicht in app.js) — geen echte AI-aanroep. */
.ai-summary-box{ background:#EEF2FF; color:#3730A3; border-radius:var(--radius-kaart); padding:10px 16px; font-size:12px; line-height:1.6; margin-top:10px; }
.office-header-right{ display:flex; align-items:center; gap:12px; flex-shrink:0; }
/* .btn-xs — BESTOND NIET, terwijl app.js hem 121x gebruikt (gevonden
   24-08-2026 door tests/tracker-scherm-klassen.test.js). Alle "kleine"
   knoppen door de hele app kregen dus gewoon de normale maat. Eén regel,
   afgeleid van de bestaande knopmaten: .btn-outline/.btn-primary staan op
   9px 16px / 13px, dus een kleine variant zit daar netjes onder. Bewust
   generiek (niet gescopet), want hij wordt overal gebruikt. */
.btn-xs{ padding:6px 10px; font-size:12px; border-radius:var(--radius-knop); }
.btn-xs.btn-soft{ gap:5px; }

/* Kleurverschil tussen de oordelen (Twan: "geen kleuronderscheid tussen de
   labels voor geen concurrent en wel een concurrent"). Hergebruikt de
   bestaande statuskleuren, met een betekenis die klopt:
     concurrent      amber  — hier moet je op letten
     geen concurrent groen  — afgehandeld, geen actie
     eigen product   blauw  — informatief
   Een AI-oordeel krijgt dezelfde kleur maar met een stippellijn eronder, zodat
   "het model denkt dit" en "dit heb jij vastgelegd" op één blik te scheiden
   zijn zonder een tweede kleurdimensie te introduceren. */
.oordeel-ai{ border-bottom:1px dashed currentColor; opacity:.85; }

/* Concurrentietracker: de oordeelknoppen naast elkaar. Nodig omdat .btn-soft
   zelf display:flex is en dus een hele regel pakt — drie knoppen onder elkaar
   maakt elke tabelrij drie keer zo hoog. */
.concurrent-acties{ display:flex; gap:6px; flex-wrap:wrap; }
.concurrent-acties .btn-soft{ padding:6px 10px; font-size:12px; }
.btn-soft{ display:flex; align-items:center; gap:7px; background:#EAF0F8; color:var(--primary); border:none; font-size:13px; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; }
/* DONKERE VULLING, NIET LICHTE (01-09-2026).
   Zelfde meting als bij het actieve tabblad: een lichte vulling over het
   blauw maakt de ondergrond lichter en drukt het contrast van de witte tekst
   omlaag — 4,43, net onder de eis. Zwart op 20% geeft 8,13 en ziet er op de
   blauwe balk hetzelfde uit: een knop die een tint dieper ligt. */
.office-header .btn-soft{ background:rgba(0,0,0,0.20); color:#fff; }
.account-label{ font-size:12px; color:var(--tekst-uitleg); }
/* Je eigen naam stond op 3,52. Op 86% wordt dat 4,87. */
.office-header .account-label{ color:rgba(255,255,255,0.86); }
.avatar{ width:30px; height:30px; border-radius:50%; background:var(--primary); color:#fff; font-size:12px; font-weight:500; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.avatar-lg{ width:56px; height:56px; font-size:20px; }
/* Bug: sinds de header-achtergrond naar var(--primary) is gezet, viel de
   avatar-cirkel (ook var(--primary)) volledig weg tegen de header — enkel
   de witte letter ("C") bleef zichtbaar, zonder cirkel eromheen. Zelfde
   trucje als .office-header .btn-soft hierboven: lichte, semi-transparante
   achtergrond zodat de cirkel altijd contrasteert met de headerkleur. */
/* De letter in het rondje stond op 3,77. Ook hier: donker vullen in plaats
   van licht (7,87), met de lichte rand eromheen zodat het rondje zelf op de
   blauwe balk blijft aftekenen. */
.office-header .avatar{ background:rgba(0,0,0,0.18); box-shadow:inset 0 0 0 1px rgba(255,255,255,0.4); }
/* Feedback: "Kan je ook de mogelijkheid toevoegen om vanuit het instellingen
   dashboard een klein menu te maken waarmee ik kan uitloggen" — klikbaar
   avatar-menu in de backoffice-header (voorheen bestond een logout-knop
   alleen op het TV-dashboard, niet in de backoffice zelf). */
.office-account-menu{ position:relative; }
/* Feedback: "waarom zie ik veel plekken toch grijze lijnen om een sectie met
   een witte achtergrond? Enkel een schaduw is daar nodig" — border naast de
   schaduw verwijderd, zelfde principe als .card/.modal-card die overal
   elders in de app al alleen op een schaduw leunen. */
.office-account-dropdown{ display:none; position:absolute; right:0; top:38px; background:#fff; border-radius:var(--radius-kaart); box-shadow:0 4px 16px rgba(0,0,0,0.08); min-width:140px; z-index:50; overflow:hidden; }
.office-account-dropdown.show{ display:block; }
.office-dropdown-item{ display:flex; align-items:center; gap:6px; width:100%; padding:10px 10px; border:none; background:none; text-align:left; font-size:12.5px; color:#993C1D; cursor:pointer; }
.office-dropdown-item:hover{ background:var(--gray); }
/* Variantkiezer voor het kassageluid (accountmenu). Bewust ingesprongen en
   kleiner dan de gewone menu-items: het is een sub-instelling van de
   Kassageluid-knop erboven, geen losse actie. Iets breder menu, anders passen
   de labels niet. */
.office-account-dropdown{ min-width:200px; }
.sound-varianten{ border-top:0.5px solid #eceff2; padding:4px 0; }
.sound-varianten.uit{ opacity:0.45; }
.sound-variant{ display:flex; align-items:center; gap:7px; width:100%; padding:6px 10px 6px 16px; border:none; background:none; text-align:left; font-size:11.5px; color:var(--secondary); cursor:pointer; }
.sound-variant:hover:not(:disabled){ background:var(--gray); }
.sound-variant:disabled{ cursor:default; }
.sound-variant .ti-circle, .sound-variant .ti-circle-check-filled{ font-size:13px; flex-shrink:0; }
.sound-variant.actief{ color:#993C1D; }
.sound-variant span{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Het afspeel-pijltje is een hint dat klikken hoorbaar is, geen aparte knop:
   het hele item speelt af én kiest. Daarom gedempt tot je erover hovert. */
.sound-variant .ti-player-play{ font-size:11px; color:#c3c8ce; flex-shrink:0; }
.sound-variant:hover:not(:disabled) .ti-player-play{ color:var(--secondary); }
/* Feedback: "handig om ergens in het dashboard een icoontje te laten zien
   indien [de automatische refresh] op de achtergrond bezig is" */
/* BTW 9%/21%-toggle (feedback: "Kan je voor de BTW instelling een toggle
   maken voor 9% en 21%?" i.p.v. een los invoerveld). */
.btw-toggle{ display:flex; border:0.5px solid #e5e7eb; border-radius:var(--radius-knop); overflow:hidden; flex-shrink:0; }
.btw-toggle-btn{ padding:6px 16px; border:none; background:#fff; color:var(--secondary); font-size:12.5px; cursor:pointer; }
.btw-toggle-btn.active{ background:var(--primary); color:#fff; }
.refreshing-indicator{ display:inline-flex; align-items:center; color:var(--tekst-uitleg); font-size:15px; }
/* Taak #405: compacte, schermonafhankelijke statuspil voor "Ververs alle
   kanalen" in de backoffice-header (zie #refreshStatusPill in index.html).
   Zelfde soort dempte header-typografie als .refreshing-indicator hierboven;
   het mini-balkje hergebruikt de kleuren van .sync-progress-fill zodat de pil
   en de volledige voortgangsbalk op Connecties er als één ding uitzien. */
/* DE STATUSPIL WIJKT VOOR DE NAVIGATIE (01-09-2026).
   Op 340 punten breed (442 op het scherm, door de zoom) duwde deze pil de
   tabbladen weg zodra het verversen liep: op 1280 bleef er nog één tabblad in
   de balk staan en verdween de rest onder "Meer". De pil is tijdelijke
   informatie, de navigatie is er altijd — dus de pil levert in.

   min-width:0 is nodig naast max-width: zonder dat weigert een flex-item
   smaller te worden dan zijn inhoud, en dan doet de text-overflow op
   .rsp-text niets. */
.refresh-status-pill{ display:inline-flex; align-items:center; gap:7px; max-width:200px; min-width:0; flex-shrink:1; padding:4px 10px; border-radius:999px; background:rgba(0,0,0,0.20); color:#eef2f8; font-size:12px; line-height:1.2; cursor:pointer; border:1px solid rgba(255,255,255,0.18); }
.refresh-status-pill:hover{ background:rgba(0,0,0,0.28); }
.refresh-status-pill .rsp-text{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.refresh-status-pill .rsp-track{ flex:0 0 54px; height:4px; border-radius:999px; background:rgba(255,255,255,0.28); overflow:hidden; }
.refresh-status-pill .rsp-fill{ height:100%; width:0%; border-radius:999px; background:#4ade80; transition:width .25s ease; }
.refresh-status-pill.is-error{ background:rgba(220,38,38,0.28); border-color:rgba(248,113,113,0.5); }
/* Feedback: "kan je dat ook per connectie doen? dan gaat de knop ronddraaien
   tijdens een sync" — .spin was hiervoor alleen binnen .refreshing-indicator
   gescoped (het icoontje naast de accountnaam voor de automatische
   achtergrond-refresh). Nu een algemene klasse, zodat 'm ook op de
   per-koppeling "Sync nu"-knop en de "Ververs alle kanalen"/"Ververs
   nu"-knoppen gezet kan worden. */
.spin{ animation:spin-icon 1s linear infinite; }
/* ELK BEZIG-ICOON DRAAIT (01-09-2026).
   Twan vroeg naar animaties voor wachttijden. Bij het uitzoeken bleek de
   indicator er al te zijn maar niets te doen: ti-loader-2 wordt 37 keer
   gebruikt als "bezig"-teken en kreeg maar 6 keer de .spin-klasse. De andere
   31 stonden stil — het icoon veranderde van vorm maar bewoog niet, en er was
   geen enkele regel die dat alsnog deed.
   Op het icoon zelf regelen in plaats van per gebruiksplek: dan kan het niet
   opnieuw vergeten worden. tests/wachtindicator.test.js dwingt dit af. */
.ti-loader-2{ animation:spin-icon 1s linear infinite; display:inline-block; }
@media (prefers-reduced-motion: reduce){
  .ti-loader-2, .spin{ animation:none; }
}
@keyframes spin-icon{ from{ transform:rotate(0deg); } to{ transform:rotate(360deg); } }
/* .panel staat verderop, bij de breedtebegrenzing. */
.card{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); }

/* Popups: normale flow ipv flex-center, anders kun je op lange pop-ups niet
   naar de bovenkant scrollen (bekende flexbox+overflow beperking). */
.modal-overlay{ display:none; position:fixed; inset:0; background:rgba(22,34,58,0.45); z-index:50; overflow-y:auto; }
.modal-overlay.active{ display:block; }
.modal-card{ background:#fff; border-radius:var(--radius-kaart); padding:24px 24px; width:420px; max-width:90%; box-shadow:0 8px 24px rgba(22,34,58,0.2); margin:40px auto; box-sizing:border-box; }
.modal-wide{ width:640px; }
.modal-head{ display:flex; justify-content:space-between; align-items:center; margin-bottom:14px; }
.modal-title{ font-size:15px; font-weight:500; color:var(--secondary); }
/* Het sluitkruisje was 21 bij 13 — smaller dan hoog, en te klein om
   betrouwbaar te raken. Een vast vlak van 32 bij 32 met het kruisje in het
   midden. */
.modal-close{
  background:transparent; border:none; color:var(--tekst-uitleg); cursor:pointer; font-size:18px;
  width:32px; height:32px; display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--radius-knop); line-height:1;
}
.modal-close:hover{ background:var(--gray); color:var(--secondary); }
.modal-actions{ display:flex; justify-content:flex-end; gap:8px; margin-top:16px; }
.modal-actions-split{ display:flex; justify-content:space-between; align-items:center; margin-top:12px; }
.pill-tabs{ margin-bottom:12px; display:flex; flex-wrap:wrap; gap:5px; }
/* De tekst van de omlijnde knop stond op #6b7280. Op wit is dat 4,83 en dus
   net goed, maar deze knop staat óók op gekleurde ondergronden — in de
   waarschuwingsbalk van Verzendmethodes zakte hij naar 4,19 en in een grijze
   telbadge naar 4,04. Met --tekst-uitleg is het overal ruim goed: 5,80 op
   wit, 5,50 op het lichtgrijze vlak, 5,03 op de waarschuwingsbalk. */
.btn-outline{ background:transparent; border:0.5px solid #e3e4e6; color:var(--tekst-uitleg); font-size:13px; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; }
.btn-primary{ background:var(--primary); color:#fff; border:none; font-size:13px; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; }
/* Feedback: "handmatig alle opgeslagen data van het account verwijderen" —
   nieuwe, expliciet destructieve knopstijl (rood i.p.v. de neutrale
   .btn-primary/.btn-outline), zelfde rode tint als .icon-btn-danger. */
.btn-danger{ background:#993C1D; color:#fff; border:none; font-size:13px; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; }

/* ---------- DE KNOPREGEL (01-09-2026) ----------

   Aanleiding: een telling over de hele app liet zien dat dezelfde handeling
   niet steeds dezelfde zwaarte kreeg. "Opslaan" stond 19 keer als zware knop
   en 9 keer als lichte. "Verwijderen" stond nul keer in het rood — vier keer
   zelfs in .btn-soft, het zachte blauw dat verder "handig hulpje" betekent.
   Je kunt dan niet leren aflezen wat de hoofdactie is, want er valt niets te
   leren.

   De regel, en tests/knophierarchie.test.js bewaakt hem:

     .btn-primary       de handeling waarvoor je op dit scherm bent.
                        Maximaal één per vak.
     .btn-outline       alles wat je daarnaast kunt doen, Annuleren incluis.
     .btn-soft          alleen hulpmiddelen die NIETS wijzigen — openen,
                        kopiëren, bekijken, ergens heen springen.
     .btn-danger-outline  alles dat verwijdert.
     .btn-danger        alleen als het onomkeerbaar is en alles raakt.

   WAAROM EEN OMLIJNDE RODE EN NIET GEWOON DE GEVULDE. Een gevulde rode knop
   trekt net zoveel aandacht als de hoofdactie, en dan staan er twee dingen te
   schreeuwen op een scherm waar verwijderen bijna nooit is wat je wilt. Rood
   omlijnd is onmiskenbaar rood zonder de zwaarste vorm op te eisen; de
   gevulde blijft over voor het echte eindpunt ("Verwijder alle accountdata").

   De tekstkleur #993C1D geeft 6,96 op wit en 6,26 op de lichte hover-vulling
   — allebei ruim boven de eis. */
/* ---------- ZICHTBARE FOCUS (01-09-2026) ----------

   Gemeten: 5 focusregels in 2538 regels stijlblad, en geen enkele op een knop
   of invoerveld. De hele app leunde dus op de standaardring van de browser.
   Dat is precies verkeerd voor de manier waarop Twan werkt: hij scant met een
   handscanner en tabt langs velden. Als je niet ziet waar de focus staat, weet
   je niet waar je scan terechtkomt — en een scanner tikt in één keer een hele
   code plus Enter.

   :focus-visible en niet :focus. Het verschil telt: :focus vuurt ook bij een
   muisklik, en dan zie je na élke klik een ring staan. :focus-visible laat de
   browser bepalen of je aan het navigeren bent met het toetsenbord.

   DE RING IS DONKER, MET AFSTAND. Nagerekend tegen elke ondergrond waar hij
   op kan komen: #0B1220 haalt 18,7 op wit, 17,8 op het grijze vlak en 16,3 op
   het zachte blauw. De eis voor een focusaanduiding is 3.

   outline-offset:2px zet de ring NAAST het element in plaats van eroverheen.
   Daardoor ligt hij op de paginaondergrond en niet op de knopkleur — een ring
   ín een blauwe knop zou 1,0 halen en dus onzichtbaar zijn. */
:focus-visible{
  outline:2px solid #0B1220;
  outline-offset:2px;
}
/* Op de blauwe kopbalk ligt de ring wél op blauw; daar is een donkere ring
   2,66 en dus te weinig. Wit haalt daar 5,96. */
.office-header :focus-visible,
.office-incident-bar :focus-visible{ outline-color:#fff; }

/* HET SCANVELD KRIJGT MEER DAN EEN RING.
   Dit is het enige veld waar je blind op vertrouwt: je kijkt naar de doos, niet
   naar het scherm, en tikt de code erin. Een gevulde rand maakt van een afstand
   zichtbaar dat de scan hier landt. */
.verw-pik-scan:focus-visible,
.verw-pak-scan:focus-visible,
input[data-wms="retour-zoek"]:focus-visible{
  outline:2px solid var(--primary);
  outline-offset:2px;
  box-shadow:0 0 0 4px #EAF0F8;
}

.btn-danger-outline{
  background:transparent; border:1px solid #993C1D; color:#993C1D;
  font-size:13px; padding:10px 16px; border-radius:var(--radius-knop);
  cursor:pointer; font-weight:500;
}
.btn-danger-outline:hover{ background:#FBF1EC; }
.btn-xs.btn-danger-outline{ padding:4px 10px; font-size:12px; }

/* FILTERS ZIJN GEEN HANDELINGEN.
   Op het scherm Orders was de enige zware blauwe knop het filter "Alle (3)" —
   de zwaarste vorm op dat scherm was dus een stand, geen handeling. Een
   filter krijgt daarom een eigen vorm: rond, en als hij aan staat blauw
   omlijnd in plaats van blauw gevuld. Nog steeds duidelijk welke aan staat,
   maar niet meer het zwaarste ding op het scherm. */
.filter-chip{
  background:transparent; border:.5px solid #e3e4e6; color:var(--tekst-uitleg);
  font-size:12px; padding:6px 10px; border-radius:999px; cursor:pointer;
  font-weight:400; white-space:nowrap;
}
.filter-chip:hover{ background:var(--gray); }
.filter-chip.aan{
  background:#EAF0F8; color:var(--primary); font-weight:500;
  box-shadow:inset 0 0 0 1px var(--primary); border-color:transparent;
}
.test-result{ font-size:12px; }

.field-row{ display:flex; justify-content:space-between; align-items:center; gap:8px; margin-bottom:8px; }
.field-row span{ font-size:12px; color:var(--tekst-uitleg); flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.field-row input{ width:90px; flex-shrink:0; font-size:12px; padding:6px 10px; border-radius:var(--radius-veld); border:none; text-align:right; background:var(--gray); color:#000; }
.field-col{ margin-bottom:10px; }
.field-col label{ font-size:12px; color:var(--tekst-uitleg); }
.field-col input, .field-col select{ width:100%; box-sizing:border-box; font-size:12px; padding:10px 10px; border-radius:var(--radius-veld); border:none; margin-top:3px; background:var(--gray); color:#000; }
.auto-row{ display:flex; justify-content:space-between; align-items:center; background:var(--gray); border-radius:var(--radius-knop); padding:6px 10px; margin-bottom:5px; font-size:12px; }
.auto-row b{ color:var(--secondary); font-weight:500; }
.note{ font-size:10.5px; color:var(--tekst-uitleg); margin-bottom:8px; }
.section-title{ font-size:12px; font-weight:500; color:var(--secondary); margin-bottom:6px; }
.two-col{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:22px; }
.one-col{ display:grid; grid-template-columns:minmax(0,1fr); gap:22px; }
.tag-active{ background:#EAF3DE; color:#3B6D11; font-size:9.5px; font-weight:500; padding:2px 6px; border-radius:999px; }
.tag-muted{ color:var(--tekst-uitleg); font-weight:400; font-size:10.5px; }

/* UITLEG KRIJGT EEN REGELLENGTE (01-09-2026).
   Gemeten op het scherm Verzendmethodes: 13 van de 14 uitlegblokken liepen
   over de volle breedte, 175 tot 184 tekens per regel. Comfortabel lezen doe
   je tussen de 60 en 80; boven de 90 vindt je oog het begin van de volgende
   regel niet meer terug en lees je een regel dubbel of sla je er een over.
   De regelafstand stond bovendien op `normal` (ongeveer 1,2), wat dat effect
   versterkt.

   ALLEEN DE BLOK-VARIANTEN. .tag-muted wordt 676 keer gebruikt, waarvan 362
   keer als <span> midden in een zin ("geen locatie", "1 stuk tekort"). Daar
   moet niets aan veranderen — een max-width op een inline-element doet toch
   niets, maar de regelafstand zou wel doorwerken en die zinnen uit elkaar
   trekken. Vandaar dat hier expliciet op div/p geselecteerd wordt.

   Elf blokken hebben al een eigen, smallere max-width in een style-attribuut.
   Die winnen van deze regel en blijven dus zoals ze zijn. */
div.tag-muted, p.tag-muted,
/* Dezelfde behandeling voor de andere dragers van uitlegtekst. Gevonden door
   ná de eerste ingreep opnieuw te meten: .tag-muted dekte de WMS-schermen af,
   maar op Producten, Advertentie en Analyse stond de uitleg in vijf andere
   klassen — 109 tot 192 tekens per regel. Eén regel voor alles wat uitleg is,
   in plaats van per scherm een breedte verzinnen. */
.note, .notif-body, .wms-banner, .uitleg-body, .analyse-caveat, .row-sub{
  max-width:70ch; line-height:1.55;
}
.mode-toggle{ display:flex; gap:5px; margin-bottom:10px; }
.mode-toggle button{ flex:1; border:none; box-shadow:var(--schaduw-kaart); font-size:11px; padding:10px 4px; border-radius:var(--radius-knop); cursor:pointer; background:#fff; color:var(--tekst-uitleg); }
.mode-toggle button.active{ background:#EAF0F8; color:var(--primary); }
.radio-row{ display:flex; align-items:center; gap:7px; font-size:12px; color:var(--secondary); margin-bottom:5px; }

/* ---------- PIM rich-text-editor (vervolgopdracht Fase 2) ----------
   Lichte, dependency-vrije contenteditable-editor (zie public/js/app.js#
   pimRichTextEditorHtml) — vervangt de kale <textarea> voor de centrale
   beschrijving + kanaal-override-beschrijvingen, zodat de gebruiker ECHTE
   opmaak ziet (vet/kop/bullets) i.p.v. rauwe HTML-tags. */
.pim-rt-toolbar{ display:flex; gap:4px; flex-wrap:wrap; margin-bottom:6px; }
.pim-rt-btn{ background:#fff; border:none; box-shadow:var(--schaduw-kaart); color:var(--tekst-uitleg); font-size:12px; min-width:30px; height:28px; padding:0 10px; border-radius:var(--radius-knop); cursor:pointer; display:inline-flex; align-items:center; justify-content:center; }
.pim-rt-btn:hover{ background:var(--gray); color:var(--secondary); }
.pim-rt-editor{ width:100%; box-sizing:border-box; min-height:110px; font-size:13px; line-height:1.5; padding:10px 10px; border-radius:var(--radius-kaart); border:none; background:var(--gray); color:#000; overflow-y:auto; }
.pim-rt-editor:focus{ outline:2px solid #cfe0f5; }
.pim-rt-editor p, .pim-rt-preview p{ margin:0 0 8px 0; }
.pim-rt-editor p:last-child, .pim-rt-preview p:last-child{ margin-bottom:0; }
.pim-rt-editor h3, .pim-rt-preview h3, .pim-rt-editor h2, .pim-rt-preview h2{ margin:0 0 6px 0; font-size:14px; font-weight:600; color:var(--secondary); }
.pim-rt-editor ul, .pim-rt-editor ol, .pim-rt-preview ul, .pim-rt-preview ol{ margin:0 0 8px 0; padding-left:20px; }
.pim-rt-editor li, .pim-rt-preview li{ margin-bottom:2px; }
.pim-rt-preview{ font-size:13px; line-height:1.5; color:var(--secondary); }
.pim-rt-preview-bol{ background:var(--gray); border-radius:var(--radius-kaart); padding:10px 10px; }
/* Live-overname-banner (Fase 2, punt 3): "Bol.com heeft al een
   beschrijving/titel voor dit product" — bewust een opvallende, maar niet
   alarmerende stijl (blauwtint, geen rode/gele waarschuwingskleur — dit is
   informatief, geen foutmelding). */
.pim-live-banner{ display:flex; gap:10px; align-items:flex-start; background:#EAF0F8; color:#1c3a63; border-radius:var(--radius-kaart); padding:10px 16px; margin-bottom:10px; font-size:12.5px; }
.pim-live-banner i{ margin-top:2px; }

/* Feedback (screenshot): "dit bedoelde ik... 2 gelijke rijen met ieders 3
   KPI's" — met repeat(4,1fr) en 6 kaarten (Orders/Sales/Bruto omzet/Totale
   kosten in rij 1, Totale winst/Retouren in rij 2) bleven de laatste 2
   kaarten van rij 2 elk een volle grid-kolom van de 4 innemen — met maar 2
   items in een 4-koloms-rij werden die dus dubbel zo breed als de kaarten
   erboven. repeat(3,1fr) geeft nu 2 nette, even brede rijen van 3. */
.stat-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-bottom:16px; }
.stat-card{ background:#fff; border-radius:var(--radius-kaart); padding:16px 16px; box-shadow:var(--schaduw-kaart); }
/* Bugfix (Twan: "die lijngrafieken zou niet over de hele breedte gaan maar
   enkel rechts in het vak, en ook niet te groot"): binnen de Dashboard-KPI-
   grid (.stat-cards) is .stat-card nu een rij (flex) i.p.v. een gestapeld
   blok, met de tekst links (.stat-card-main) en de sparkline — indien
   aanwezig — klein en vast-breed rechts uitgelijnd (.stat-card-spark), in
   plaats van een los blok dat de volle kaartbreedte onder de tekst innam.
   Bewust gescopet op ".stat-cards .stat-card" (niet globaal op .stat-card):
   retailerRatingCardHtml() in app.js hergebruikt dezelfde .stat-card-klasse
   voor de Reviews-tab-kaarten, die WEL gestapelde losse content hebben (naam,
   cijfer, delta-badges) en dus het oude blok-gedrag nodig hebben. */
.stat-cards .stat-card{ display:flex; align-items:center; justify-content:space-between; gap:10px; position:relative; }
.stat-card-main{ min-width:0; }
.stat-card-label{ font-size:11px; color:var(--tekst-uitleg); }
.stat-card-value{ font-size:22px; font-weight:500; color:var(--secondary); }
/* Feedback: "Dashboard: periode-vergelijking (vs vorige periode) op kaarten"
   — klein badge-lijntje onder de kaartwaarde. delta-good/bad kleuren op
   basis van of de verandering gunstig is (bij Retouren is een STIJGING juist
   slecht, zie invert-param bij periodDeltaHtml in app.js). */
.stat-card-delta{ font-size:11px; margin-top:4px; }
.stat-card-delta.delta-good{ color:#0F6E56; }
.stat-card-delta.delta-bad{ color:#993C1D; }
.stat-card-delta.delta-flat{ color:var(--tekst-uitleg); }
/* Feedback (interactie-voorstel, "sparklines"): kleine trendlijn (periode-
   breedte volgt dashPeriod, zie dashSparkSeries()), alleen bij Orders/Sales
   (stuks)/Bruto omzet/Retouren. Vaste kleine afmeting rechts in de kaart. */
/* Bugfix (Twan: "deze mag opzich wel 50% breder zodat je makkelijker iets
   kan hoveren, nu is elke muisbeweging niet secuur genoeg"): 56px -> 84px
   (+50%). De SVG zelf (viewBox 0 0 100 26, preserveAspectRatio="none") en de
   hit-rects daarin schalen hier vanzelf in mee, geen JS-wijziging nodig. */
.stat-card-spark{ flex:0 0 auto; width:84px; height:24px; }
.kpi-sparkline{ width:84px; height:24px; display:block; opacity:.85; cursor:crosshair; }
/* Feedback (Twan: "kan je hier ook een hover aan toevoegen die de specifieke
   data laat zien? Met enkel een lijn zonder parameters kunnen we niet zoveel,
   en parameters zien er niet mooi uit daar dus enkel die hover is prima") —
   zwevend tooltipje, zelfde donkere stijl als .euro-chart-tooltip maar
   compacter (dit sparkline-vakje is zelf maar 56x24px, ver kleiner dan de
   Advertentie/Verzending-grafieken). Geclamped binnen de bredere .stat-card
   (position:relative hierboven), niet binnen .stat-card-spark zelf — zie
   wireSparklineHover() in app.js (gebruikt op zowel Dashboard als, sinds het
   Retouren-KPI-voorstel, de Retouren-tab). */
.spark-tooltip{ display:none; position:absolute; z-index:20; background:#1c2129; color:#fff; font-size:10px; line-height:1.4; padding:6px 6px; border-radius:var(--radius-kaart); box-shadow:0 8px 20px rgba(20,24,31,0.25); pointer-events:none; white-space:nowrap; }
/* Feedback (voorstelpagina retouren-kpi-voorstel.html, alle 3 ideeën
   bevestigd door Twan): kleine toelichtingsregel onder een KPI-waarde (bv.
   "23 retouren ÷ 479 verkochte stuks"), en de retourpercentage-balkjes in de
   "Hoogste retourpercentage"-tabel — zelfde stijl als op de voorstelpagina. */
.kpi-note{ font-size:10.5px; color:var(--tekst-uitleg); margin-top:4px; }
.rr-bar-track{ background:#F1F2F4; border-radius:4px; height:6px; width:70px; overflow:hidden; flex-shrink:0; }
.rr-bar-fill{ height:6px; border-radius:4px; }
.returns-rate-row{ cursor:pointer; }
.returns-rate-row:hover{ background:#F7F8F9; }

.period-row{ display:flex; gap:6px; margin-bottom:14px; flex-wrap:wrap; }
.period-row button{ background:#fff; color:var(--tekst-uitleg); border:none; box-shadow:var(--schaduw-kaart); font-size:12px; padding:6px 16px; border-radius:var(--radius-knop); cursor:pointer; }
.period-row button.active{ background:var(--primary); color:#fff; border-color:var(--primary); }

.notif-list{ display:flex; flex-direction:column; gap:7px; }
.notif{ border-radius:var(--radius-kaart); padding:10px 16px; display:flex; align-items:center; gap:10px; font-size:13px; }
.notif i{ font-size:16px; flex-shrink:0; }
.notif-warn{ background:#FAEEDA; color:#854F0B; }
.notif-error{ background:#FAECE7; color:#993C1D; }
.notif-info{ background:#E6F1FB; color:#0C447C; }
/* Feedback: "meldingen voorzien van datum/tijdstempel + optie om te
   verbergen" — tijdstempel als kleine, minder opvallende regel onder de
   melding-tekst; verberg-knop (×) rechts uitgelijnd, alleen zichtbaar bij
   hover om de meldingenlijst niet drukker te maken dan nodig. */
.notif-body{ flex:1; min-width:0; }
.notif-time{ font-size:10.5px; opacity:0.7; margin-top:2px; }
/* Was 13 bij 21 — smaller dan hoog en te klein om te raken. 24 bij 24 is de
   ondergrens; het kruisje zelf blijft even groot, alleen het vlak eromheen
   groeit. */
.notif-dismiss{ flex-shrink:0; opacity:0.45; font-size:15px; line-height:1; padding:0;
  width:24px; height:24px; display:inline-flex; align-items:center; justify-content:center;
  border-radius:var(--radius-knop); }
.notif-dismiss:hover{ opacity:1; }
.foutmelding-row{ position:relative; }
.foutmelding-row .notif-time{ margin-top:1px; }
.foutmelding-row .notif-dismiss{ position:absolute; right:0; top:2px; }

.data-table{ width:100%; border-collapse:collapse; font-size:12.5px; }
.data-table th{ color:var(--tekst-uitleg); text-align:left; font-weight:400; padding:10px 10px; }
/* Feedback (interactie-voorstel, "sorteerbare kolommen"): klikbare kolomkop
   bij Bestsellers — financieel, zie bestFinSortKey/sortBestFinRows(). */
.sortable-th{ cursor:pointer; user-select:none; white-space:nowrap; }
.sortable-th:hover{ color:var(--primary); }
.data-table td{ padding:10px 10px; border-top:0.5px solid #f0f1f2; background:#fff; color:var(--secondary); }
/* Bugfix (feedback: "de hele UI is kapot" bij Bestellingen op een heel
   breed/ultrawide scherm — headers leken naar rechts geduwd, kolommen niet
   meer nette balken): de eerste kolom (foto + titel, o.a. Product in
   Bestellingen/Producten en Dashboard-bestsellers) is een flex-rij met een
   <span> ernaast. Een flex-item heeft standaard min-width:auto — dat
   voorkomt dat de tekst ooit kan afbreken/krimpen, waardoor een lange
   producttitel de héle kolom (en dus de tabel, table-layout:auto rekent
   met de breedste inhoud per kolom) tot ver voorbij zijn eerlijke aandeel
   opblies. Op een normaal scherm viel dat niet erg op; op een ultrawide
   monitor (bv. 3440px) trok dat zoveel breedte naar zich toe dat alle
   overige, korte kolommen (EAN, BTW, Status, ...) samengeperst tegen de
   rechterkant kwamen te staan — precies het gemelde "headers staan rechts,
   informatie naar links gedrukt, geen mooie balken (badges) meer". Fix:
   die kolom mag nu gewoon afbreken over meerdere regels i.p.v. eindeloos
   breed te worden. */
.data-table td:first-child > div{ min-width:0; }
.data-table td:first-child span, .data-table td:first-child > div > div{ white-space:normal; overflow-wrap:break-word; min-width:0; }
/* Poging 2 (table-layout:fixed + colgroup) werd door live meting + Twans
   eigen terugkoppeling ("het is slechter geworden") teruggedraaid: de
   header respecteerde de colgroup-breedtes wél, maar de databody-cellen
   bleven op hun oude, kleinere content-breedte staan — nog verder uit
   elkaar dan voorheen, plus de producttitel werd nu in een veel te smalle
   kolom over te veel regels afgebroken. Nog niet opgelost; verder
   onderzoek nodig vóór een volgende poging (zie taken). */
/* Feedback: "een hover met licht grijs toevoegen wanneer ik hover op een
   regel van een product/bestelling" — geldt voor Producten- en
   Bestellingen-tab (beide gebruiken .data-table). */
.data-table tbody tr:hover td{ background:#F7F8F9; }
/* Feature (Twan): multi-item orders in het Verzending-detailscherm nu 1 rij
   per artikel i.p.v. 1 rij per order met een "+N artikelen"-tag (zie
   shipOrderItemRowHtml in app.js). Deze regel verwijdert de bovenrand tussen
   itemrijen van DEZELFDE order, zodat je in één oogopslag ziet welke rijen
   bij elkaar horen zonder dat er per se een zichtbare scheidingslijn nodig
   is — de volgende order krijgt gewoon weer de normale rand terug. */
.ship-detail-order-row-extra td{ border-top:none; }
/* Bugfix (Twan: "de hover gaat nog maar op 1 van de 2 producten tegelijk"):
   met rowspan zitten bestelnummer/track&trace/... in de EERSTE <tr> van een
   order, dus de standaard `tr:hover` hierboven kan nooit alle rijen van
   dezelfde order tegelijk laten oplichten. Deze klasse wordt door de kleine
   hover-groepering in app.js (data-ship-group) op ALLE rijen van dezelfde
   order gezet zodra je over willekeurig welke rij hovert — zelfde kleur als
   de gewone hover, dus geen zichtbaar verschil, alleen nu op de hele groep. */
.ship-detail-group-hover td{ background:#F7F8F9; }
/* Feedback: "visuele dag-scheidingen tussen verschillende dagen" in de
   Bestellingen-tab. */
.day-separator-row td{ background:var(--gray); font-size:11.5px; font-weight:600; color:var(--secondary); padding:6px 10px; border-top:none; }
.day-separator-row:hover td{ background:var(--gray); }
.table-wrap{ overflow-x:auto; }
.product-thumb{ width:30px; height:30px; border-radius:var(--radius-veld); background:var(--gray); border:0.5px solid #eee; display:flex; align-items:center; justify-content:center; color:var(--tekst-uitleg); flex-shrink:0; }
/* Feedback: "de afbeelding van het product zelf mag wel een stukje groter,
   dat is nu 40x40px volgensmij maar dat mag naar 150x150px" — alleen gebruikt
   in de productinfo-header van de kosten-pop-up (zie renderCostModalBody),
   niet in de Producten-tabel zelf (die blijft compact via .product-thumb). */
.product-thumb-lg{ width:150px; height:150px; border-radius:var(--radius-kaart); font-size:32px; }
/* Hover-preview (feedback: "hover die de afbeelding op 1000x1000 formaat
   toont") bij het kleine thumbnail in de Producten-tab — .thumb-zoom-preview
   toont dezelfde afbeelding groot, normaal verborgen en zichtbaar bij hover
   op de wrapper. Vast op de linkerkant + iets naar boven zodat 'm nooit
   buiten de rand van het scherm/tabel valt bij rijen bovenaan. */
/* flex-shrink:0 — Twan zag productafbeeldingen over de tekst heen staan bij
   Bestellingen. Oorzaak: dit omhulsel stond als flex-item toe te krimpen,
   terwijl de afbeelding erin `flex-shrink:0` heeft. Bij een lange producttitel
   werd het omhulsel platgedrukt tot 13px terwijl de afbeelding 30px bleef, en
   stak die er dus 17px overheen. Bestond al vóór de breedte-aanpassing; die
   maakte de kolom smaller en daarmee zichtbaar wat er al fout stond. */
.thumb-zoom{ position:relative; display:inline-flex; flex-shrink:0; }
.thumb-zoom-preview{ display:none; position:absolute; left:0; top:36px; width:320px; height:320px; object-fit:contain; background:#fff; border-radius:var(--radius-kaart); box-shadow:0 8px 24px rgba(20,24,31,0.18); z-index:50; }
.thumb-zoom:hover .thumb-zoom-preview{ display:block; }
/* Feedback (Retouren-tab): "wanneer ik hover over de i krijg ik nog niet de
   informatie die ik gevraagd had want er gebeurt momenteel niks" — dit was
   een losse HTML `title`-attribuut (native browser-tooltip, met vertraging
   en soms onbetrouwbaar). Zelfde bewezen hover-patroon als .thumb-zoom
   hierboven: een eigen, direct zichtbare tooltip-box i.p.v. op de browser
   te vertrouwen. */
.info-tooltip{ position:relative; display:inline-flex; cursor:help; }
.info-tooltip-box{ display:none; position:absolute; right:0; top:22px; width:260px; background:#1f2430; color:#fff; font-size:11.5px; line-height:1.6; padding:10px 10px; border-radius:var(--radius-kaart); box-shadow:0 8px 24px rgba(20,24,31,0.25); z-index:60; text-align:left; }
.info-tooltip-box a{ color:#8ab4ff; }
.info-tooltip:hover .info-tooltip-box{ display:block; }
/* Het kanaal als pictogram, naast de vlag (21-09-2026). Zelfde kleuren als de
   chip met de naam erin, alleen zonder tekst — voor plekken waar geen ruimte is
   voor een naam: de rij en de kop van een retour. Geen eigen waarden: hij erft
   de maat van .chan-badge. */
.chan-icoon{ display:inline-flex; align-items:center; justify-content:center; }
.verw-rij-thumb{ display:inline-flex; align-items:center; }
.chan-badge, .chan-icoon{ font-size:9.5px; font-weight:500; padding:3px 6px; border-radius:999px; display:inline-block; }
/* Feedback (2e ronde): bol-badge-achtergrond klopte niet — moet #0000A4 zijn,
   dezelfde blauw als bol.com's "Omzet"-lijn in de Advertentie-grafiek,
   i.p.v. de generieke --secondary-navy. */
.chan-bol{ background:#0000A4; color:#fff; }
/* Feedback: "waarom klopt bij producten de kleur van de shopify badge niet
   met die van het icoon of de conversiepercentage grafiek?" — #5DCAA5 was een
   losstaand muntgroen dat nergens anders in de app voorkomt. #96BF43 is
   Shopify's eigen merkgroen — zelfde kleur als SHOP_LOGO (het echte Shopify-
   tasje-icoon) en als de Shopify-lijn in de conversiepercentage-grafiek op
   het sales-dashboard (zie chartSeries in app.js, kleur '#96BF43').
   Feedback (2e ronde): "shopify"-tekst wit maken zodat het overeenkomt met
   het icoontje" — was donkergroene tekst, nu wit net als "bol". */
/* Witte tekst op het Shopify-groen gaf 2,14 — de slechtst leesbare tekst in
   de hele app. Het groen is de herkenbare kanaalkleur en blijft dus staan;
   de tekst wordt donker (7,41). */
.chan-shop{ background:#96BF43; color:#17223A; }
.status-ok{ background:#EAF3DE; color:#3B6D11; font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; }
.status-bad{ background:#FAECE7; color:#993C1D; font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; }
/* #71 (Twan: "rood als er nog niks gebeurt en oranje zodra het pakket is
   ontvangen tot het bezorgd wordt, want bezorgd is groen") — status-bad
   hierboven blijft voor het "nog niet ontvangen"-geval (rood), dit is de
   tussenfase (ontvangen/onderweg, nog niet bezorgd). Zelfde amber-tint als
   .notif-warn elders in de app, voor een consistente kleurtaal. */
.status-warn{ background:#FAEEDA; color:#854F0B; font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; }
.icon-btn{ background:none; border:none; padding:0; cursor:pointer; display:inline-flex; align-items:center; justify-content:center; font-size:16px; }
.icon-btn-primary{ color:var(--primary); }
.icon-btn-danger{ color:#993C1D; }

.conn-row, .fixed-row{ background:#fff; border-radius:var(--radius-kaart); padding:10px 16px; display:flex; align-items:center; gap:10px; box-shadow:var(--schaduw-kaart); flex-wrap:wrap; margin-bottom:7px; }
.sync-progress-wrap{ align-items:center; gap:10px; padding:0 16px 10px 57px; margin-top:-7px; margin-bottom:7px; }
.sync-progress-track{ flex:1; height:6px; background:#EAF0F8; border-radius:4px; overflow:hidden; }
.sync-progress-fill{ height:100%; background:var(--primary); border-radius:4px; transition:width .3s; }
.sync-progress-label{ font-size:11px; color:var(--tekst-uitleg); white-space:nowrap; }
.conn-icon{ width:32px; height:32px; border-radius:var(--radius-veld); background:var(--gray); display:flex; align-items:center; justify-content:center; color:var(--tekst-uitleg); flex-shrink:0; }
.row-title{ font-size:13px; color:var(--secondary); }
.row-sub{ font-size:11px; color:var(--tekst-uitleg); }
.row-amount{ font-size:13px; color:var(--secondary); font-weight:500; white-space:nowrap; }

.sort-search-row{ display:flex; justify-content:space-between; align-items:center; margin-bottom:14px; gap:10px; flex-wrap:wrap; }
.sort-search-row select, .sort-search-row input{ font-size:12px; padding:6px 10px; border-radius:var(--radius-veld); border:none; background:var(--gray); color:#000; }
.section-header-row{ display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; }

/* ---------- Sales / TV dashboard ---------- */
/* .sales-view is nu het volledige-scherm "letterbox"-kader (wit), en
   .tv-canvas is een vaste 16:9-resolutie die via JS (fitTvCanvas in app.js)
   geschaald wordt om precies in dat kader te passen — op elk schermformaat
   (ook ultrawide) blijft de verhouding zo altijd exact 16:9, met witruimte
   aan weerszijden in plaats van een uitgerekte layout. */
.sales-view{ position:fixed; inset:0; background:var(--gray); align-items:center; justify-content:center; overflow:hidden; }
.tv-canvas{
  width:960px; height:540px; flex-shrink:0;
  background:var(--gray); position:relative; overflow:hidden;
  display:flex; flex-direction:column;
  transform-origin: center center;
}
/* Feedback: "de hoeken onderaan ook afronden zodat dit mooi oogt met de rest
   van de afgeronde hoeken. Bovenaan mag rechte hoeken houden want dat vult
   het scherm mooi uit met blauw" — enkel de onderste twee hoeken ronden,
   bovenkant blijft vlak tegen de rand van de 16:9-canvas aan. */
.tv-header{ background:var(--primary); padding:10px 16px; display:flex; align-items:center; justify-content:space-between; flex-shrink:0; z-index:2; border-radius:0 0 14px 14px; }
.tv-nav-btn{ background:#fff; border:none; color:var(--primary); width:32px; height:32px; border-radius:var(--radius-knop); display:flex; align-items:center; justify-content:center; cursor:pointer; font-size:17px; }
.tv-header-center{ text-align:center; }
.tv-title-row{ display:flex; align-items:center; justify-content:center; gap:5px; }
.tv-title-row span:first-child{ font-size:16px; font-weight:500; color:#fff; }
.adv-waarschuwing{ display:none; color:#FFD166; font-size:13px; position:relative; cursor:help; }
.adv-waarschuwing.show{ display:inline-flex; }
/* Bugfix (3x gemeld): de native browser-title-tooltip bleek niet
   betrouwbaar zichtbaar (traag/onopvallend, werkt niet overal goed op een
   TV/kiosk-scherm). Eigen, altijd-zichtbare CSS-tooltip i.p.v. title. */
.adv-waarschuwing[data-tooltip]:hover::after{
  content: attr(data-tooltip);
  position: absolute;
  top: 130%;
  left: 50%;
  transform: translateX(-50%);
  background: #17223A;
  color: #fff;
  font-size: 11px;
  line-height: 1.5;
  white-space: pre-line;
  padding: 10px 10px;
  border-radius:var(--radius-kaart);
  width: max-content;
  max-width: 280px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
  z-index: 20;
  text-align: left;
  pointer-events: none;
}
.adv-waarschuwing[data-tooltip]:hover::before{
  content: '';
  position: absolute;
  top: 108%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-bottom-color: #17223A;
  z-index: 20;
}
.period-pill{ background:rgba(255,255,255,0.16); border:none; color:#fff; font-size:10px; padding:3px 10px; border-radius:999px; cursor:pointer; margin-top:3px; }
.page-dots{ display:flex; gap:4px; justify-content:center; margin-top:5px; }
.page-dots span{ width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,0.4); }
.page-dots span.active{ background:#fff; }

.scroll-area{ flex:1; min-height:0; overflow-y:auto; scroll-snap-type:y mandatory; overscroll-behavior:contain; scrollbar-width:none; }
.scroll-area::-webkit-scrollbar{ display:none; }
.primary-section, .secondary-section{ min-height:100%; scroll-snap-align:start; padding:16px 16px; box-sizing:border-box; display:flex; flex-direction:column; }
.data-view{ display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,1fr); gap:14px; flex:1; min-height:0; }
.col-left, .col-right{ display:flex; flex-direction:column; gap:10px; min-height:0; min-width:0; }
.col-right{ gap:16px; }
.metrics-grid{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:8px; flex-shrink:0; }
.metric-card{ background:#fff; border-radius:var(--radius-kaart); padding:10px 10px; box-shadow:var(--schaduw-kaart); }
.metric-label{ font-size:9.5px; color:var(--tekst-uitleg); }
.metric-value{ font-size:15px; font-weight:500; color:var(--secondary); }
.flex-card{ padding:10px 10px; flex:1; min-height:0; min-width:0; overflow:hidden; }
.card-label{ font-size:11px; color:var(--tekst-uitleg); margin-bottom:5px; }
.list{ display:flex; flex-direction:column; gap:4px; font-size:11px; min-width:0; }
.order-row{ display:flex; align-items:center; gap:5px; }
.order-row.border{ border-bottom:0.5px solid #f0f1f2; padding-bottom:4px; }
.badge-col{ display:inline-flex; align-items:center; width:32px; flex-shrink:0; }
.badge-col img{ display:block; object-fit:contain; }
.country-flag{ font-size:12px; flex-shrink:0; margin-right:2px; }
.order-name{ flex:1; min-width:0; color:var(--secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.order-right{ text-align:right; flex-shrink:0; max-width:118px; }
.order-amount{ color:var(--secondary); font-weight:500; }
/* Bugfix (feedback): datum+tijd stonden op 2 losse regels boven elkaar,
   waardoor de rij hoger werd dan verwacht en de scroll bij bv. de 7-dagen-
   periode brak. Nu op 1 regel ("07-08-26 | 17:51") met white-space:nowrap. */
.order-time{ color:var(--tekst-uitleg); font-size:9.5px; display:flex; flex-direction:row; gap:4px; align-items:baseline; justify-content:flex-end; white-space:nowrap; }
.order-date{ font-size:8.5px; color:#b5bac1; }
.order-sep{ color:#d7dade; }
.thumb-icon{ width:19px; height:19px; border-radius:999px; background:var(--gray); display:flex; align-items:center; justify-content:center; color:var(--tekst-uitleg); flex-shrink:0; font-size:10px; }
.chart-row{ display:flex; align-items:center; gap:6px; min-width:0; }
/* Bugfix (feedback: "Bij het 30 dagen overzicht wordt orders per week de
   week afgesneden"): 50px was te smal zodra labels langer waren dan een
   paar tekens (bv. "Deze week", "Week 28-07") — die werden met ellipsis
   afgekapt tot onleesbare fragmenten ("Deze w...", "Week 2..."). Verbreed
   naar 74px; de wat kortere labels (bv. "Ma", "00–06u") hebben hier geen
   last van, .chart-track vult de resterende ruimte toch al op (flex:1). */
.chart-label-plain{ color:var(--secondary); width:74px; flex-shrink:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* Bugfix: winkelnamen (bv. "Bol Ibley COMBI") werden hier te agressief
   afgekapt binnen 108px — verbreed zodat volledige namen beter passen. */
.chart-label-badge{ display:flex; align-items:center; gap:4px; width:150px; flex-shrink:0; overflow:hidden; }
.chart-label-badge span{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.chart-track{ background:#F1F2F4; border-radius:4px; height:7px; flex:1; min-width:0; overflow:hidden; position:relative; }
.chart-fill{ height:7px; border-radius:4px; background:var(--primary); max-width:100%; position:relative; z-index:1; }
.chart-value{ text-align:right; color:var(--tekst-uitleg); flex-shrink:0; min-width:18px; }
/* Feedback (interactie-voorstel, "vergelijkingsmodus"): "vorige week"-balkje
   als vaag "schaduw"-balkje áchter de huidige-waarde-balk, zodat je in 1 oog-
   opslag ziet of de huidige dag hoger/lager uitkomt dan dezelfde dag vorige
   week — zonder de bestaande .chart-row-layout om te hoeven bouwen. */
.chart-fill-ghost{ position:absolute; top:0; left:0; height:7px; border-radius:4px; background:rgba(107,114,128,.4); max-width:100%; z-index:0; }
/* Feedback: "kan je bij hovers op grafieken een balkje laten kleuren...
   makkelijker af te lezen" — puur CSS (:hover), geen JS nodig: elke
   .chart-row (Bruto omzet per land, Sales per dag, Orders per kanaal, en
   overal elders waar dit component hergebruikt wordt) is al een los
   hoverbaar element. !important nodig om de inline background-kleur (per
   rij een andere kleur, bv. bij Orders per kanaal) te overstemmen. */
.chart-row:hover .chart-fill{ background:var(--secondary) !important; }
/* Feedback: "orders per uur, van links naar rechts beginnend bij 0 en
   eindigend bij 23... staafdiagram, met hover voor precieze aantallen" —
   een verticaal staafdiagram (i.p.v. de horizontale .chart-row hierboven,
   die past niet bij "links naar rechts"). Native title-attribuut per staaf
   voor de hover-waarde: bewust gekozen boven een custom CSS-tooltip, want
   met 24 smalle staven naast elkaar zou een custom tooltip bij de staven
   aan de randen (uur 0/23) buiten de kaart kunnen vallen. */
/* .hbar-wrap krijgt zijn hoogte via een expliciete inline height op de
   plek van gebruik (zie renderDashboardTab in app.js) i.p.v. flex:1 — die
   laatste bleek (live gecontroleerd) geen effect te hebben toen dit
   staafdiagram eerst op het TV-dashboard stond, want .flex-card is zelf
   geen flex-container voor zijn kinderen. Een expliciete hoogte is hier
   simpeler en werkt overal, ook buiten een flex-context.
   position:relative zodat de .euro-chart-tooltip erbinnen (position:
   absolute) t.o.v. deze kaart positioneert i.p.v. t.o.v. de hele pagina
   (feedback: "ik mis het hoveren over de orders per uur grafiek" — eerst
   met native title geprobeerd, maar dat patroon is elders in de app al
   eens bewust losgelaten wegens onbetrouwbaar/onopvallend, dus nu dezelfde
   custom tooltip als de andere grafieken). */
.hbar-wrap{ position:relative; }
.hbar-chart{ display:flex; align-items:flex-end; gap:2px; height:100%; }
.hbar-col{ flex:1; min-width:0; height:100%; display:flex; flex-direction:column; align-items:center; justify-content:flex-end; cursor:default; }
.hbar-track{ width:100%; flex:1; min-height:0; display:flex; align-items:flex-end; }
.hbar-fill{ width:100%; background:var(--primary); border-radius:2px 2px 0 0; min-height:1px; }
/* Zelfde "makkelijker af te lezen"-feedback als bij .chart-row hierboven,
   nu voor het verticale staafdiagram (Orders per uur). */
.hbar-col:hover .hbar-fill{ background:var(--secondary); }
/* 10 px is de ondergrens uit de ontwerpprincipes (§5b); op 7,5 px pasten er
   vierentwintig, maar dan las je ze niet. Er staan er nu vijf (0, 6, 12, 18,
   23) en de rest komt bij hover — zie de tooltip per kolom. */
.hbar-label{ font-size:10px; color:var(--tekst-uitleg); margin-top:2px; line-height:1.3; height:13px; }
.best-row{ display:flex; align-items:center; gap:6px; }
.best-name{ flex:1; color:var(--secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.best-count{ color:var(--tekst-uitleg); flex-shrink:0; }

.scroll-hint{ display:flex; align-items:center; justify-content:center; gap:4px; padding-top:5px; color:#b7bac0; flex-shrink:0; font-size:9.5px; }

.secondary-title{ font-size:11px; color:var(--tekst-uitleg); margin-bottom:6px; }
.secondary-grid{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:14px; flex:1; min-height:0; }
.center-card{ padding:10px 10px; display:flex; flex-direction:column; justify-content:center; }
.big-number{ font-size:24px; font-weight:500; color:var(--secondary); }
.muted-note{ font-size:9.5px; color:var(--tekst-uitleg); }
.stock-row{ display:flex; align-items:center; gap:6px; font-size:10.5px; }
.stock-badge{ font-size:8.5px; font-weight:500; padding:2px 6px; border-radius:999px; flex-shrink:0; }
.cost-row{ display:flex; justify-content:space-between; gap:5px; font-size:10.5px; color:var(--tekst-uitleg); }
.cost-row.total{ color:var(--secondary); font-weight:500; }
.cost-row.profit{ border-top:0.5px solid #eee; padding-top:4px; margin-top:2px; font-weight:500; }
.adv-melding{ background:#FAECE7; color:#993C1D; font-size:9.5px; border-radius:var(--radius-kaart); padding:6px 10px; margin-bottom:4px; }
/* Feedback: "foutmeldingen... eigen tab zodat het geen correcte data
   vervuilt" — kleine, klikbare chip die op de plek van de vroegere volle
   waarschuwingsbalken staat en doorlinkt naar de nieuwe Foutmeldingen-tab
   (zie goToFoutmeldingen in app.js). tab-badge is het bijpassende rode
   telbadge naast de tabnaam zelf. foutmelding-row/-warn/-info zijn de
   regelstijlen binnen de Foutmeldingen-tab (rood/oranje/grijs, matcht de
   bestaande Snel-bijbestellen-kleuren).*/
.err-chip{ display:inline-block; background:#FAECE7; color:#993C1D; font-size:9.5px; border-radius:999px; padding:6px 10px; cursor:pointer; }
/* Feedback: "klik op een staaf = doorlinken" — verwijderbaar chipje voor een
   filter dat vanuit een grafiek (bv. Orders per uur) is aangezet, zodat
   duidelijk is dat er iets actief staat wat niet in de gewone dropdowns
   zichtbaar is. */
.tag-chip{ display:inline-flex; align-items:center; background:#EAF0F8; color:var(--primary); font-size:12px; border-radius:999px; padding:6px 10px; font-weight:500; }
.err-chip:hover{ text-decoration:underline; }
/* Feedback (interactie-voorstel, "klikbare legenda"): land aan/uit klikken
   in de Verzending-grafiek legenda. */
.ship-legend-item{ cursor:pointer; user-select:none; transition:opacity .12s; }
.ship-legend-item:hover{ opacity:.7; }
.ship-legend-item.dimmed{ opacity:.35; text-decoration:line-through; }
/* Wit op #F70103 gaf 4,23 — en juist bij een telbadge van 9px moet je in één
   oogopslag kunnen zien wat er staat. #C40002 is dezelfde rode signaalkleur,
   maar dan op 6,27. */
.tab-badge{ display:inline-block; background:#C40002; color:#fff; font-size:9px; font-weight:600; border-radius:999px; padding:1px 6px; margin-left:3px; vertical-align:middle; }
.foutmelding-row{ display:flex; align-items:flex-start; gap:6px; font-size:10.5px; padding:4px 2px; border-bottom:0.5px solid #f1f1f1; }
.foutmelding-row:last-child{ border-bottom:none; }
.foutmelding-row.error{ color:#993C1D; }
.foutmelding-row.warn{ color:#8A6116; }
.foutmelding-row.info{ color:var(--tekst-uitleg); }

/* Feedback: "Ik mis nog wel de lijngrafiek erboven... De tabel is iets
   anders dan de lijngrafiek." — losse mini-lijngrafiek (SVG, geen library
   nodig) boven de bestaande top-5-tabel, plus korte kolomkoppen erboven
   ("titel, Percentage en vertoningen" / "iets in die trend"). */
.conversion-chart-wrap{ margin-bottom:8px; position:relative; }
.conversion-chart-svg{ width:100%; height:58px; display:block; cursor:crosshair; }
/* Bugfix (Twan: "de hover blijft voor de grafiek zelf zitten, nog steeds
   niet bruikbaar"): dit kaartje op het TV-dashboard is van zichzelf al heel
   klein (~230x70px vóór schaling) — de standaard .euro-chart-tooltip-stijl
   (bedoeld voor de veel grotere Advertentie/Verzending-kaarten) was daar met
   volledige koppelingsnamen per rij vaak breder én hoger dan de hele kaart,
   waardoor de tooltip altijd bovenop het gehoverde punt zelf viel, ongeacht
   waar je hoverde. Compacte override hier: kleiner lettertype/padding en een
   max-breedte die ruim binnen de kaart past (de JS in renderConversionSection
   toont hier ook bewust geen koppelingsnaam meer per rij, enkel kleurbolletje
   + percentage — de naam staat al in de legenda vlak erboven). */
.conversion-chart-wrap .euro-chart-tooltip{ font-size:9px; line-height:1.4; padding:6px 6px; max-width:90px; }
.conversion-chart-empty{ font-size:10px; color:var(--tekst-uitleg); padding:4px 0; }
.conversion-table-head{ display:flex; justify-content:space-between; font-size:9.5px; color:var(--tekst-uitleg); padding:0 2px 3px; }
/* Advertentie-tabblad: Kosten-vs-Omzet-trendlijn (zelfde zero-dependency
   SVG-aanpak als .conversion-chart-svg hierboven, maar in echte €-bedragen
   i.p.v. percentages en dus met een eigen, iets hogere vaste hoogte). */
/* Bugfix (feedback + screenshot: "die grafiek zelf ziet er nog steeds niet
   goed uit" — op Twans brede scherm rekte width:100% de grafiek uit tot ver
   voorbij een leesbare breedte/hoogte-verhouding, ver breder dan de tabel
   eronder). max-width houdt 'm nu binnen een normale kaart-breedte, ook op
   een ultrawide monitor — zelfde soort probleem als eerder bij de
   Bestellingen-tabel op een 3440px-scherm (zie notitie bij .data-table). */
/* De hoogte volgt nu de viewBox in plaats van vastgezet te zijn op 130px.
   Met een vaste hoogte én preserveAspectRatio="none" werd de tekening per as
   apart uitgerekt — zie de toelichting bij euroLineChartSvg in app.js. */
/* Geen max-width meer. Twan (05-09-2026): "De grafiek is nog steeds niet de
   volledige breedte." Ik had de kaart eromheen wel losgelaten maar deze cap
   over het hoofd gezien — de lijn stopte op 1150px terwijl de kaart doorliep
   tot 1970. De hoogte volgt uit de viewBox, dus breder betekent hier ook
   platter; dat is precies wat je wilt bij veertien dagen naast elkaar. */
.euro-chart-svg{ width:100%; height:auto; display:block; cursor:crosshair; }
/* Feedback: "op een bepaalde dag kan hoveren om precies informatie van die
   dag te hebben" — zwevend tooltip-blok, normaal verborgen, gepositioneerd
   binnen #adChartWrap (position:relative) via JS in renderAdvertisingTab. */
.euro-chart-tooltip{ display:none; position:absolute; z-index:20; background:#1c2129; color:#fff; font-size:10.5px; line-height:1.5; padding:10px 10px; border-radius:var(--radius-kaart); box-shadow:0 8px 20px rgba(20,24,31,0.25); pointer-events:none; white-space:nowrap; }
/* Feedback (interactie-voorstel, "tooltip vastzetten"): klik op een punt in
   de Advertentie/Verzending-grafiek zet er een blijvend notitie-blokje bij
   (zie advPins/shipPins) — zelfde donkere stijl als .euro-chart-tooltip,
   maar altijd zichtbaar (geen display:none) en wél klikbaar (voor het
   sluitknopje), dus pointer-events hier bewust WEL aan. */
.pin-note{ position:absolute; top:8px; transform:translateX(-50%); z-index:21; background:#1c2129; color:#fff; font-size:10.5px; line-height:1.5; padding:10px 24px 10px 10px; border-radius:var(--radius-kaart); box-shadow:0 8px 20px rgba(20,24,31,0.3); white-space:nowrap; pointer-events:auto; }
.pin-note-close{ position:absolute; top:6px; right:6px; cursor:pointer; font-size:12px; color:var(--tekst-uitleg); }
.pin-note-close:hover{ color:#fff; }
/* Feedback (interactie-voorstel, "sleepbare periode-selectie"): sleepvak dat
   meebeweegt terwijl je over de Advertentie-grafiek sleept, zie advDragState
   hierboven. Niet pixel-perfect uitgelijnd op de exacte grafiek-as (dat zou
   een aparte scale-berekening voor de hoogte vergen) — bewust een simpele
   band die de kaart-hoogte volgt, genoeg om de gekozen breedte te tonen. */
.drag-select-overlay{ display:none; position:absolute; top:24px; bottom:20px; background:rgba(40,100,174,.14); border-left:1px solid var(--primary); border-right:1px solid var(--primary); pointer-events:none; z-index:14; }
/* Feedback: "die tabel is nogal samengedrukt in de hoogte en uitgerekt in de
   breedte" — de generieke .data-table (table-layout:auto, 6 brede kolommen)
   gaf bij dit specifieke tabblad een onbalans: te weinig kolommen om de
   volle breedte netjes te vullen. .adv-tabel is een vaste (colgroup-
   gestuurde) kolomindeling met iets meer verticale ademruimte per rij, en
   is bewust een APARTE klasse i.p.v. wijziging aan .data-table zelf — een
   eerdere table-layout:fixed-poging op de algemene Bestellingen-tabel werd
   teruggedraaid na Twans feedback dat het daar juist slechter werd (zie
   notitie hierboven bij .data-table); hier is de kolomcontext heel anders
   (10 vaste, voorspelbare kolommen i.p.v. vrije tekst) dus geen risico op
   diezelfde regressie. */
/* WAAROM DEZE KLASSEN 'adv-' HETEN EN NIET 'ad-' (31-08-2026).
   Twan meldde dat het advertentieoverzicht niet laadde: "Zowel normale
   advertenties als de branded shelfs." Op de server stond alle data (2150
   regels), de tabellen zaten gewoon in de DOM (106 en 7 rijen), en op een
   testbrowser zonder uitbreidingen renderden ze prima.

   In zijn eigen Chrome stonden ze op display:none, zonder dat ook maar één
   CSS-regel in de pagina dat deed en zonder inline style. De oorzaak: zijn
   ADBLOCKER, die elementen verbergt waarvan de klassenaam op reclame lijkt.

   Bewezen, niet aangenomen: de klasse in de DOM weghalen liet de tabel meteen
   op 7676px hoogte springen, terugzetten verborg hem weer. Daarna met
   proefelementen gemeten welke namen geblokkeerd worden:

       ad-table     -> display:none        adv-tabel      -> zichtbaar
       ads-banner   -> display:none        campagne-tabel -> zichtbaar
       ads-warning  -> display:none

   Deze app TOONT advertentiecijfers, hij is er geen. Een klassenaam die met
   'ad-' of 'ads-' begint is hier dus een valstrik: onzichtbaar voor iedereen
   met een adblocker, en niet te vinden zonder zo'n blocker in je
   testopstelling. Alle betrokken klassen zijn daarom hernoemd naar 'adv-'.
   tests/adblocker-klassenamen.test.js bewaakt dat er geen nieuwe bijkomen. */
.adv-tabel{ table-layout:fixed; }
.adv-tabel td, .adv-tabel th{ padding:10px 10px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.adv-tabel td:nth-child(2){ white-space:normal; }
/* Feedback: "Kan je dat direct in de headers bouwen zoals het voorbeeld van
   Bol doormiddel van pijltjes" — klikbare kolomkoppen met sorteer-pijltje,
   zelfde idee als bol.com's eigen campagneoverzicht. Dof "⇅"-icoon als de
   kolom niet actief is, blauw en gericht (▲/▼) als 'm de sortering bepaalt. */
.adv-th-sortable{ cursor:pointer; user-select:none; }
.adv-th-sortable:hover{ color:var(--secondary); }
.adv-sort-arrow{ font-size:9px; color:var(--tekst-zwak); margin-left:2px; }
.adv-sort-arrow.active{ color:var(--primary); }

.settings-view{ display:none; flex:1; flex-direction:column; align-items:center; justify-content:center; gap:12px; }
.settings-view.active{ display:flex; }
.settings-name{ font-size:15px; color:var(--secondary); font-weight:500; }
.settings-refresh{ font-size:12px; color:var(--tekst-uitleg); margin-bottom:4px; }
/* Feedback (2e ronde, na verkeerd scherm aangepast): "dit bedoelde ik bij
   het dashboard in instellingen [= de backoffice Dashboard-statkaarten, zie
   .stat-cards]... het hele tv-gedeelte is eigenlijk goed en hoef je niet
   aan te komen" — de 3x2-grid + 2 extra snelkoppelingen (Foutmeldingen/
   Verzending) die hier stonden zijn teruggedraaid naar de oorspronkelijke
   1-koloms lijst. Alleen de eerdere randstijl-fix (border i.p.v. schaduw,
   zie feedback "knoppen niet in lijn met de rest") blijft staan. */
.settings-actions{ display:flex; flex-direction:column; gap:8px; width:240px; }
/* Feedback: "waarom zijn de knoppen van het instellingen dashboard niet in
   lijn met de rest?" — deze knoppen waren als kaart gestyled (witte vlak +
   schaduw, geen rand), terwijl KNOPPEN in de rest van de app (.btn-primary/
   .btn-outline/.period-row button/...) nergens een schaduw hebben en juist
   een dunne rand gebruiken. Zelfde randstijl/kleur als .btn-outline
   hergebruikt, schaduw weg — nu voelt dit aan als knoppen i.p.v. kaartjes. */
.settings-btn{ display:flex; align-items:center; gap:9px; background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-knop); padding:10px 16px; cursor:pointer; font-size:13px; color:var(--secondary); }
.settings-btn i{ font-size:16px; color:var(--primary); }
.settings-btn-danger{ color:#993C1D; }
.settings-btn-danger i{ color:#993C1D; }
.settings-hint{ font-size:9.5px; color:#b7bac0; text-align:center; margin-top:2px; }

.toast{ position:absolute; top:12px; right:12px; background:#fff; border-radius:var(--radius-kaart); padding:10px 10px; box-shadow:0 4px 16px rgba(22,34,58,0.18); display:flex; align-items:flex-start; gap:8px; opacity:0; transform:translateY(-6px); transition:opacity .25s, transform .25s; z-index:20; pointer-events:none; max-width:300px; }
.toast.show{ opacity:1; transform:translateY(0); }
/* Feedback: bij meerdere artikelen in 1 bestelling de productfoto's links
   gestapeld tonen (op volgorde van producttitel, zie showToast in app.js) —
   i.p.v. voorheen 1 los icoontje voor enkel het eerste artikel. */
.toast-images{ display:flex; flex-direction:column; gap:4px; flex-shrink:0; }
.toast-thumb{ width:26px; height:26px; border-radius:var(--radius-veld); background:var(--gray); display:flex; align-items:center; justify-content:center; color:var(--tekst-uitleg); flex-shrink:0; overflow:hidden; }
.toast-top{ display:flex; align-items:center; gap:5px; }
.toast-top span:last-child{ font-size:11px; color:var(--secondary); font-weight:500; }
.toast-datetime{ font-size:9.5px; color:var(--tekst-uitleg); margin-top:1px; }
.toast-items{ margin-top:3px; }
.toast-item-row{ font-size:11px; color:var(--secondary); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:230px; line-height:1.4; }
.toast-amount{ font-size:11px; color:var(--tekst-uitleg); font-weight:600; margin-top:3px; }

/* ============================================================
   WMS (pick & pack) — nieuwe hoofdtab, zie app.js (wmsActive/renderWmsTab)
   en mobile.js (mActiveSection 'wms'). Klassen/kleuren hergebruiken zoveel
   mogelijk bestaande tokens (var(--primary)/var(--secondary)/var(--gray) en
   dezelfde tint-paren als .status-ok/.status-warn/.status-bad hierboven)
   i.p.v. een nieuw palet te verzinnen — 1-op-1 overgenomen uit het door
   Twan goedgekeurde ontwerp/prototype (wms-ui-prototype.html: "Het
   WMS-ontwerp en de klikbare mockup zijn nu definitief en naar mijn wens").
   ============================================================ */
.wms-subnav{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:16px; }
.wms-subnav button{ background:#fff; color:var(--tekst-uitleg); border:none; box-shadow:var(--schaduw-kaart); font-size:12.5px; font-weight:500; padding:10px 16px; border-radius:var(--radius-knop); cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.wms-subnav button i{ font-size:14px; }
.wms-subnav button.active{ background:var(--primary); color:#fff; border-color:var(--primary); }
.wms-subnav button .cnt{ background:rgba(0,0,0,0.08); border-radius:999px; padding:1px 6px; font-size:10.5px; }
/* Wit op een lichte vulling over blauw gaf 3,53 — precies dezelfde valkuil
   als bij het actieve hoofdtabblad. Donker vullen in plaats van licht. */
.wms-subnav button.active .cnt{ background:rgba(0,0,0,0.22); }

.wms-banner{ display:flex; align-items:center; gap:8px; border-radius:var(--radius-kaart); padding:10px 16px; font-size:12.5px; margin-bottom:16px; }
.wms-banner.ok{ background:#EAF3DE; color:#3B6D11; }
.wms-banner.error{ background:#FAECE7; color:#993C1D; }
.empty-state{ padding:40px 24px; text-align:center; color:var(--tekst-uitleg); font-size:12.5px; }
.empty-state i{ font-size:26px; display:block; margin-bottom:8px; color:#d5d8dd; }
.status-info{ background:#E6F1FB; color:#0C447C; font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; }

.wms-thumb{ width:40px; height:40px; border-radius:var(--radius-veld); background:var(--gray); display:flex; align-items:center; justify-content:center; color:#B9BEC7; font-size:17px; flex:none; }
.wms-thumb.sm{ width:28px; height:28px; font-size:13px; border-radius:var(--radius-veld); }

/* #242 (Twan: "handiger om met rijen te werken ipv de huidige kaarten
   structuur... maximale breedte van 1300px aanhouden"): Te verwerken ging
   van een multi-kolom kaartengrid (elke combinatie een eigen doos, wat op
   bredere schermen erg wisselende/soms te brede kaarten gaf) naar 1
   doorlopende, smallere rijenlijst met een vaste maximumbreedte — zelfde
   dichte rij-taal als .wms-order-row elders in het WMS.
   #251 (Twan, vervolgfeedback: "ik mis een witte achtergrond met schaduw
   tegen het grijze [...] wat ruimte tussen de blokken [...] want nu is het
   1 massief blok"): de eerste versie van .pick-row had geen eigen
   achtergrond/schaduw (enkel een dunne rand tussen rijen), waardoor de hele
   lijst optisch samensmolt met de grijze paginaondergrond. Elke rij is nu
   een eigen losse witte kaart (zelfde .card-look als de rest van de app,
   zie .card hierboven) met marge ertussen i.p.v. gedeelde randen. */
/* ÉÉN BREEDTE VOOR HET HELE SCHERM (23-09-2026).
   Twan: "Verzendklaar is ook scheef." Klopte: .pick-list stond op max-width
   1300 en gecentreerd, .bulk-bar eronder had geen maximum en liep dus over de
   volle breedte. Op een breed scherm stond de balk zichtbaar buiten de kaarten
   die erbij horen. Twee losse getallen is precies hoe dat ontstaat, dus het is
   er nu één. */
.pick-list{ display:flex; flex-direction:column; gap:12px; max-width:var(--wms-lijst-breed); margin:0 auto; }
.pick-row{ background:var(--white); border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:16px; display:flex; flex-direction:column; gap:6px; border-left:3px solid transparent; }
/* #259 (Twan: "kan je het 'te verwerken' scherm dezelfde stijl geven als
   'verzendklaar'? Dus ook die witte achtergrond met schaduw..."):
   Verzendklaar's groepskaarten zijn altijd effen wit, maar .pick-row.done/
   .blocked overschreven hier de achtergrond met een groene/rode tint —
   daardoor oogde Te verwerken minder "wit" dan Verzendklaar. De
   kleurstatus blijft zichtbaar via de linkerrand, de achtergrond blijft nu
   consequent wit zoals overal elders. */
.pick-row.done{ border-left-color:#3B6D11; }
.pick-row.blocked{ border-left-color:#993C1D; }
.pick-row-top{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.deadline-chip{ font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; background:var(--gray); color:var(--tekst-uitleg); display:inline-flex; align-items:center; gap:4px; }
.deadline-chip.soon{ background:#FAEEDA; color:#854F0B; }
.deadline-chip.urgent{ background:#FAECE7; color:#993C1D; }
/* .pick-grid/.pick-card* (oude kaartenlayout) verwijderd — vervangen door
   .pick-list/.pick-row hierboven, zie #242/#251. */
.pick-actions{ display:flex; gap:6px; align-items:center; }
.pick-actions button{ flex:1; }
.stepper-btn{ flex:none; width:34px; padding:10px 0; text-align:center; font-weight:700; }
.pick-orders-toggle{ font-size:10.5px; color:var(--primary); background:none; border:none; cursor:pointer; text-align:left; padding:0; }
.pick-orders{ display:flex; flex-direction:column; gap:4px; margin-top:4px; }
.pick-orders .oc{ background:var(--gray); border-radius:var(--radius-kaart); padding:6px 10px; font-size:10.5px; color:var(--tekst-uitleg); display:flex; justify-content:space-between; align-items:center; cursor:pointer; }
.pick-orders .oc:hover{ background:#EAF0F8; }
.pick-orders .oc.done{ background:#EAF3DE; color:#3B6D11; }
.done-check{ color:#3B6D11; font-size:16px; }

/* ---- Verwerken: kiezen, dan pas verwerken (31-08-2026) ---- */
.verw-stuur{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; background:#fff;
  border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:10px 16px; margin-bottom:14px; }
.verw-label{ font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--tekst-uitleg); }
.verw-f{ font-size:12.5px; font-weight:600; padding:6px 10px; border-radius:999px; cursor:pointer;
  background:var(--gray); color:#4E5866; border:1px solid transparent; }
.verw-f.aan{ background:var(--primary); color:#fff; }
.verw-f .n{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; opacity:.75; margin-left:5px; }

.verw-blok{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  margin-bottom:11px; overflow:hidden; }
.verw-kop{ display:grid; grid-template-columns:56px minmax(0,1fr) auto; gap:14px; align-items:center; padding:16px 16px; }
.verw-kop .wms-pick-thumb{ width:56px; height:56px; }
.verw-titel{ font-size:14.5px; font-weight:600; line-height:1.3; }
.verw-meta{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-top:5px; font-size:12px; }
.verw-ean{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; color:#3B6D11; }
/* Een locatiechip breekt nooit af (01-09-2026). Twan: "Locatie en status
   kappen af op een regel en dat is erg onduidelijk." B-04-0004 brak op de
   koppeltekens en werd twee regels — een locatiecode die je moet oplopen hoort
   in één stuk leesbaar te zijn. inline-block zodat de padding klopt als hij
   toch de enige inhoud van een cel is. */
/* De locatieknop in het pickscherm stond op 23 punten. Dit is een knop die je
   met een doos in je hand aanklikt; 28 is hier het minimum. */
.verw-loc{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-weight:600; font-size:12px;
  padding:2px 10px; border-radius:5px; background:#EAF1F9; color:var(--primary);
  white-space:nowrap; display:inline-block;  min-height:28px; display:inline-flex; align-items:center;}
.verw-loc.geen{ background:#FAECE7; color:#B3271A; font-family:inherit; }
.verw-cijfers{ color:var(--tekst-uitleg); }
.verw-cijfers b{ color:var(--secondary); }
.verw-tekort{ display:flex; gap:8px; align-items:flex-start; padding:10px 16px;
  background:#FDF3E3; color:#B45309; font-size:12.5px; }
/* DE ORDERREGELS HOREN BIJ DE KAART, NIET IN EEN BAK ERNAAST (23-09-2026).
   Twan: "Waar het artikel staat is het wel wit maar de orderregel zelf niet."
   Klopte: dit blok stond op --gray terwijl .verw-blok erboven wit is, waardoor
   de orders eruitzagen als iets anders dan het artikel waar ze bij horen. Het
   is een kaart; de scheiding doet de lijn. */
.verw-orders{ border-top:1px solid var(--border); background:var(--white); padding:6px 6px 6px; }
.verw-orij{ display:flex; align-items:center; gap:11px; flex-wrap:wrap; padding:6px 10px; border-radius:8px; font-size:13px; }
.verw-orij + .verw-orij{ border-top:1px solid var(--border); }
.verw-orij.gekozen{ background:#EAF1F9; }
/* GROTER KLIKVLAK OP DE VINKJES (01-09-2026).
   Gemeten: 17 bij 17 beeldpunten. De richtlijn is minimaal 24; voor iets dat
   je met een doos in je andere hand aanklikt is dat aan de krappe kant.

   Het vinkje zelf gaat naar 20 en krijgt een klikvlak van 32 eromheen via
   padding — je klikt dan ook raak als je er net naast zit. `flex:none` blijft
   staan, anders krimpt het vinkje weer mee in de rij. */
.verw-orij input[type=checkbox]{
  width:20px; height:20px; accent-color:var(--primary); cursor:pointer; flex:none;
  padding:6px; box-sizing:content-box; margin:-6px;
}
/* Zelfde maat voor de selectievinkjes in de andere lijsten (Verzendklaar,
   Orders) en voor "Terug in voorraad" bij een retour — dezelfde handeling met
   een doos in je hand, dus hetzelfde klikvlak. Dat laatste vinkje bepaalt of
   de voorraad opgehoogd wordt; ernaast klikken is daar geen kleine fout. */
.retour-terug input[type=checkbox],
input[type=checkbox].bulk-select{
  width:20px; height:20px; accent-color:var(--primary); cursor:pointer;
  padding:6px; box-sizing:content-box; margin:-6px;
}
.verw-nr{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-weight:600; }
.verw-klant{ color:#4E5866; }
.verw-qty{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; font-weight:600;
  background:#fff; color:#4E5866; padding:1px 10px; border-radius:5px; }
.verw-rechts{ margin-left:auto; display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.verw-tijd{ font-size:11.5px; color:var(--tekst-uitleg); }
.verw-groepkop{ display:flex; align-items:center; gap:10px; font-size:11px; font-weight:600;
  letter-spacing:.09em; text-transform:uppercase; color:var(--tekst-uitleg); margin:20px 0 9px; }
.verw-groepkop .lijn{ flex:1; height:1px; background:var(--border); }
.verw-multi{ padding:6px 2px; }
.verw-multi + .verw-multi{ border-top:1px solid var(--border); }
.verw-multi-art{ display:flex; gap:16px; flex-wrap:wrap; padding:4px 10px 2px; }
.verw-mi{ display:inline-flex; align-items:center; gap:7px; font-size:12.5px; }

.verw-onder{ position:sticky; bottom:0; background:#fff; border-top:1px solid var(--border);
  box-shadow:0 -2px 10px rgba(0,15,30,.05); padding:10px 16px; display:flex; align-items:center;
  gap:12px; flex-wrap:wrap; margin-top:14px; border-radius:0 0 var(--radius-kaart) var(--radius-kaart); }
.verw-tel{ font-size:13.5px; color:#4E5866; }
.verw-tel b{ color:var(--secondary); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
/* Ook deze pil stond op var(--gray) (#F8F9FA), wat op de nu witte balk vrijwel
   niet meer te zien is. Een randje houdt hem herkenbaar als pil zonder er een
   tweede accentkleur bij te halen. */
.verw-modus{ display:inline-flex; align-items:center; gap:8px; font-size:12.5px; font-weight:600;
  padding:6px 10px; border-radius:8px; background:var(--gray); color:#4E5866;
  border:1px solid #E3E7EC; }
.verw-modus.bulk{ background:#EAF1F9; color:var(--primary); }
.verw-modus em{ font-style:normal; font-weight:400; opacity:.8; }
/* PICKEN: een looproute langs locaties (01-09-2026). Naar het model van
   Twans vorige WMS: een regel per artikel, gegroepeerd per rij, met een
   schakelaar en het aantal dat je moet pakken. */
.pik-balk{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; background:#fff;
  border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:10px 16px; margin-bottom:14px; }
.pik-scan{ flex:1; min-width:220px; display:flex; gap:6px; }
.pik-scan input{ flex:1; }
.pik-gang{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:11px; }
.pik-gang-kop{ display:flex; align-items:center; gap:10px; margin-bottom:9px; }
.pik-gang-code{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; font-weight:660;
  letter-spacing:.07em; padding:3px 10px; border-radius:5px; background:#EAF1F9; color:var(--primary); }
.pik-gang-code.geen{ background:#FAECE7; color:#B3271A; }
.pik-regel{ display:flex; align-items:center; gap:12px; padding:10px 4px; border-top:1px solid var(--border); }
.pik-regel:first-of-type{ border-top:0; }
.pik-regel.af{ opacity:.55; }
.pik-toggle{ width:42px; height:24px; border-radius:999px; border:none; background:#D3DAE4;
  cursor:pointer; position:relative; flex:none; transition:background .15s; }
.pik-toggle span{ position:absolute; top:3px; left:3px; width:18px; height:18px; border-radius:50%;
  background:#fff; transition:transform .15s; }
.pik-toggle.aan{ background:#3B6D11; }
.pik-toggle.aan span{ transform:translateX(18px); }
.pik-aantal{ min-width:28px; height:28px; border-radius:50%; background:#B3271A; color:#fff;
  font-weight:700; font-size:13px; display:flex; align-items:center; justify-content:center; flex:none; }
.pik-aantal.af{ background:#3B6D11; }
.pik-ean{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:var(--tekst-uitleg); }
.pik-naam{ flex:1; min-width:0; font-size:13.5px; font-weight:560; }
.pik-loc{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; font-weight:600;
  color:var(--primary); background:#EAF1F9; padding:3px 10px; border-radius:5px; }
.pik-manden{ display:flex; gap:4px; }
.pik-mand{ min-width:22px; height:22px; border-radius:5px; background:var(--gray); color:#4E5866;
  font-size:11px; font-weight:600; display:flex; align-items:center; justify-content:center; }
.pik-mand.meer{ background:#EAF1F9; color:var(--primary); }
.pik-onder{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; padding:10px 16px; background:#fff;
  border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); }

/* INPAKKEN: de artikeltabel en het labelblok. */
.pak-tabel{ width:100%; border-collapse:collapse; font-size:13px; margin-bottom:12px; }
.pak-tabel th{ text-align:left; font-size:10.5px; font-weight:600; letter-spacing:.07em;
  text-transform:uppercase; color:var(--tekst-uitleg); padding:0 10px 6px; border-bottom:1px solid var(--border); }
.pak-tabel td{ padding:10px; border-bottom:1px solid var(--border); vertical-align:middle; }
.pak-tabel tr:last-child td{ border-bottom:0; }
.pak-tabel.compact td, .pak-tabel.compact th{ padding:6px 10px; font-size:12.5px; }
.pak-n{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:15px; font-weight:660; }
.pak-n span{ color:#9AA3AF; font-weight:400; font-size:12px; }
.pak-titel{ font-weight:560; }
.pak-ean{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; color:var(--tekst-uitleg); }
.pak-label{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; display:flex; flex-direction:column; gap:9px; }
.pak-label-regel{ display:flex; justify-content:space-between; gap:10px; font-size:13px; color:#4E5866; }
.pak-label-regel b{ color:var(--secondary); }
.pak-label-regel .mono{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; }
.pak-voorstel{ font-size:12px; color:#4E5866; }
.pak-knoppen{ display:flex; gap:7px; flex-wrap:wrap; }
.pak-compact{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:10px; }
.pak-compact-kop{ display:flex; align-items:center; gap:11px; flex-wrap:wrap; margin-bottom:9px; }
.pak-compact-body{ display:grid; grid-template-columns:minmax(0,1fr) 260px; gap:14px; align-items:start; }
@media (max-width:900px){ .pak-compact-body{ grid-template-columns:minmax(0,1fr); } }

.btn-soft.btn-xs{ display:inline-flex; }
/* De blokkop is zelf de knop geworden (01-09-2026). Twan: "Alle 2 selecteren
   zijn dus niet nodig als knop" — klikken op de kop selecteert alle orders van
   dat artikel. */
.verw-kop.klikbaar{ cursor:pointer; border-radius:var(--radius-kaart); transition:background .12s; }
.verw-kop.klikbaar:hover{ background:#F4F7FB; }
.verw-kop.aan{ background:#EAF1F9; }
.verw-kop-hint{ font-size:11.5px; color:var(--tekst-uitleg); white-space:nowrap; }
.verw-kop.klikbaar:hover .verw-kop-hint{ color:var(--primary); }
/* En een orderregel kan meteen naar het inpakscherm. */
.verw-direct{ border:none; background:#EAF0F8; color:var(--primary); cursor:pointer;
  font-family:inherit; font-size:11.5px; font-weight:600; padding:4px 10px;
  border-radius:var(--radius-veld); display:inline-flex; align-items:center; gap:5px; }
.verw-direct:hover{ background:#DCE7F5; }
/* De foto in de artikeltabel groter, met de hover-zoom die het pakscherm al
   had. Twan wilde extra zekerheid dat hij het juiste artikel pakt. */
.pak-tabel .wms-pick-thumb{ width:52px; height:52px; }

/* Kolommen kiezen in de artikeltabel, en de stepper in de aantalkolom. */
.pak-kolommen{ position:relative; display:inline-block; margin-bottom:8px; }
.pak-kolommen-menu{ position:absolute; z-index:20; top:calc(100% + 5px); left:0; min-width:190px;
  background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-zwevend, 0 10px 30px rgba(0,15,30,.14));
  border:1px solid var(--border); padding:10px 10px; display:flex; flex-direction:column; gap:6px; }
.pak-kolommen-menu label{ display:flex; align-items:center; gap:8px; font-size:12.5px; color:#4E5866; cursor:pointer; }
.pak-kolommen-voet{ font-size:11px; color:var(--tekst-uitleg); border-top:1px solid var(--border); padding-top:6px; margin-top:2px; }
.pak-stap{ display:inline-flex; align-items:center; gap:5px; }
.pak-tabel tr.af td{ opacity:.6; }
.verw-overslaan{ display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:#4E5866;
  cursor:pointer; background:var(--gray); padding:6px 10px; border-radius:var(--radius-knop); }
.verw-overslaan input{ accent-color:var(--primary); }

/* De afrondregel bij order voor order: zonder ordernummer, want dat staat al
   in de kop erboven. Twee keer hetzelfde ordernummer las als twee orders. */
.wms-order-row.compact{ background:var(--gray); border-radius:var(--radius-kaart); box-shadow:none;
  padding:10px 16px; align-items:center; }
.afronden-label{ font-size:10.5px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--tekst-uitleg); white-space:nowrap; }
.verw-ovo-af{ margin-top:12px; padding-top:12px; border-top:1px solid var(--border); }
.verw-ovo-acties{ display:flex; gap:7px; flex-wrap:wrap; margin-top:10px; }

/* Het verzendadres (01-09-2026). Twan: "dat bepaald de verzendmethode" —
   dus hoort het in beeld en niet twee klikken verderop in het orderdetail. */
.verw-ovo-info{ display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr)); gap:11px; margin-bottom:12px; }
.wms-adres{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; display:flex; flex-direction:column; gap:8px; }
.wms-adres-kop{ font-size:10.5px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--tekst-uitleg); }
.wms-adres-regels{ display:flex; flex-direction:column; gap:2px; font-size:13px; color:#4E5866; line-height:1.45; }
.wms-adres-regels b{ color:var(--secondary); }
.wms-adres button{ align-self:flex-start; }
.wms-adres-kort{ font-size:12px; color:var(--tekst-uitleg); white-space:nowrap; }

/* De verwerkstap: bulk per artikel, of order voor order (01-09-2026).
   De tweede weergave — order groot, rij ernaast — is degene die Twan het
   duidelijkst vond toen er niets te bundelen valt. */
/* De TRACK van de voortgangsbalk was wit. Dat werkte toen .verw-runbalk nog
   blauw was, maar op de witte balk van nu is wit-op-wit onzichtbaar en lijkt
   een lege voortgang op een ontbrekende balk. Zelfde grijs als .dash-balk. */
.verw-voortgang{ flex:1; min-width:120px; max-width:260px; height:6px; border-radius:4px;
  background:#E8EAEE; overflow:hidden; }
.verw-voortgang i{ display:block; height:100%; background:var(--primary); transition:width .3s cubic-bezier(.22,1,.36,1); }
.verw-pak{ text-align:right; }
.verw-pak-n{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:20px; font-weight:680;
  line-height:1; color:var(--secondary); }
.verw-pak-n span{ color:#9AA3AF; font-weight:500; font-size:14px; }
.verw-pak-l{ font-size:10px; color:var(--tekst-uitleg); text-transform:uppercase; letter-spacing:.07em; margin-top:3px; }
.verw-pak-knoppen{ display:flex; gap:6px; align-items:center; }
.verw-orders-af{ border-top:1px solid var(--border); background:var(--gray); padding:10px 10px 10px; }
.verw-bulkacties{ display:flex; gap:7px; flex-wrap:wrap; margin-top:9px; padding-top:9px;
  border-top:1px solid var(--border); }
.verw-art{ display:grid; grid-template-columns:56px minmax(0,1fr) auto auto; gap:13px; align-items:center;
  background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:8px; }
.verw-art .wms-pick-thumb{ width:56px; height:56px; }

.verw-ovo{ display:grid; grid-template-columns:minmax(0,1fr) 250px; gap:14px; align-items:start; }
/* HET ORDERBLOK IS EEN KAART, GEEN GAT IN DE PAGINA (01-09-2026).
   Twan, voor de derde keer: "hier is nog steeds de grijze achtergrond terwijl
   ik al 3x om een wit vlak als achtergrond heb gevraagd. Grijze achtergrond is
   enkel bedoeld als backdrop om contrast te creeren."
   Dat is de regel, en deze container hield zich er als enige niet aan: hij had
   helemaal GEEN achtergrond, dus de paginakleur (--gray) scheen erdoorheen —
   terwijl de kolom ernaast (.verw-ovo-rij) wél een wit vlak had. Vandaar dat
   het zo opviel. Nagelopen: van de containers in de verwerkstap was dit de
   enige zonder eigen vlak. */
.verw-ovo-order{ background:#fff; border-radius:var(--radius-kaart);
  box-shadow:var(--schaduw-kaart); padding:16px 16px; }
@media (max-width:900px){ .verw-ovo{ grid-template-columns:minmax(0,1fr); } }
.verw-ovo-kop{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  flex-wrap:wrap; margin-bottom:12px; }
.verw-ovo-nr{ font-size:16px; font-weight:600; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.verw-ovo-sub{ font-size:12.5px; color:var(--tekst-uitleg); margin-top:4px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.verw-ovo-af{ margin-top:10px; padding-top:10px; border-top:1px solid var(--border); }
.verw-ovo-rij{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:16px; }
.verw-rij-kop{ font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--tekst-uitleg); margin-bottom:9px; }
.verw-rij-item{ display:flex; align-items:center; gap:8px; width:100%; text-align:left; cursor:pointer;
  border:none; background:var(--gray); border-radius:var(--radius-veld); padding:6px 10px;
  margin-bottom:4px; font-family:inherit; font-size:12.5px; color:#4E5866; }
.verw-rij-item:hover{ background:#EAF0F8; }
.verw-rij-item.nu{ background:#EAF1F9; color:var(--primary); font-weight:600; }
.verw-rij-item.af{ opacity:.55; }
.verw-rij-item .nr{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
.verw-rij-item .st{ margin-left:auto; }
.verw-rij-nav{ display:flex; gap:6px; margin-top:10px; }

/* Orders: openstaand en verzonden onder één kop (01-09-2026). */
.orders-tabs{ display:inline-flex; gap:4px; background:var(--gray); border-radius:var(--radius-knop); padding:3px; }
.orders-tabs button{ border:none; background:none; cursor:pointer; font-family:inherit;
  font-size:12.5px; font-weight:600; color:var(--tekst-uitleg); padding:6px 16px; border-radius:calc(var(--radius-knop) - 2px); }
.orders-tabs button.aan{ background:#fff; color:var(--secondary); box-shadow:var(--schaduw-kaart); }
.orders-tabs .n{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; opacity:.7; }

/* Een retour afhandelen (01-09-2026). De gevolgen staan op de knop zelf,
   want "afgekeurd" betekent dat de klant zijn geld niet terugkrijgt. */
.retour-afhandel{ margin-top:12px; padding-top:12px; border-top:1px solid var(--border); }
.retour-afhandel-kop{ display:flex; align-items:center; gap:10px; font-size:12.5px; margin-bottom:9px; }
.retour-keuzes{ display:flex; flex-wrap:wrap; gap:7px; margin-bottom:10px; }
.retour-keuze{ display:flex; flex-direction:column; align-items:flex-start; gap:2px; cursor:pointer;
  background:#fff; border:1px solid var(--border); border-radius:var(--radius-veld);
  padding:6px 10px; text-align:left; font-family:inherit; }
.retour-keuze b{ font-size:12.5px; color:var(--secondary); }
.retour-keuze span{ font-size:11px; color:var(--tekst-uitleg); }
.retour-keuze:hover{ border-color:var(--primary); }
.retour-keuze.ok:hover{ border-color:#3B6D11; }
.retour-keuze.warn{ border-color:#E8D6C4; }
.retour-keuze.warn:hover{ border-color:#B3271A; }
.retour-keuze:disabled{ opacity:.5; cursor:not-allowed; }
.retour-terug{ display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:#4E5866; }

.verw-samen{ display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:600;
  padding:2px 10px; border-radius:5px; background:#F1E9FA; color:#6B2FA8; white-space:nowrap; }

/* WMS-dashboard (01-09-2026) */
.dash-cijfers{ display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:12px; }
.dash-kaart{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:16px 16px; }
.dash-kaart.let-op{ box-shadow:0 0 0 2px #B45309, var(--schaduw-kaart); }
.dash-n{ font-size:28px; font-weight:680; letter-spacing:-.02em; line-height:1;
  font-variant-numeric:tabular-nums; color:var(--secondary); }
.dash-l{ font-size:12.5px; font-weight:600; color:#4E5866; margin-top:6px; }
.dash-s{ font-size:11.5px; color:var(--tekst-uitleg); margin-top:2px; }
.dash-badge{ display:inline-block; min-width:26px; text-align:center; font-weight:700; font-size:12.5px;
  padding:2px 10px; border-radius:999px; background:var(--gray); color:#4E5866; }
.dash-badge.hoog{ background:#FAECE7; color:#B3271A; }
.dash-badge.midden{ background:#FDF3E3; color:#B45309; }
.dash-badge.laag{ background:var(--gray); color:#4E5866; }

/* Verzendregels: de artikelen die aan een methode hangen (31-08-2026). */
.ean-regels{ margin-top:12px; padding-top:12px; border-top:1px solid var(--border); }
.ean-chips{ display:flex; flex-wrap:wrap; gap:6px; margin:8px 0 10px; }
.ean-chip{ display:inline-flex; align-items:center; gap:7px; background:var(--gray);
  border-radius:var(--radius-veld); padding:4px 6px 4px 10px; font-size:12px; }
.ean-chip b{ font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-weight:600; }
.ean-chip span{ color:var(--tekst-uitleg); max-width:190px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ean-x{ border:none; background:none; cursor:pointer; color:var(--tekst-uitleg); font-size:15px; line-height:1; padding:0 2px; }
.ean-x:hover{ color:#B3271A; }
.ean-toevoegen{ display:flex; gap:7px; align-items:center; flex-wrap:wrap; }

/* Hoeveelheid bijwerken: twee gekoppelde velden (31-08-2026, Twans opzet). */
.bijwerk-blok{ background:var(--gray); border-radius:var(--radius-kaart); padding:16px 16px; }
.bijwerk-titel{ font-size:13px; font-weight:600; color:var(--secondary); margin-bottom:11px; }
.bijwerk-velden{ display:flex; gap:12px; flex-wrap:wrap; margin-bottom:11px; }
.bijwerk-velden label{ display:flex; flex-direction:column; gap:4px; }
.bijwerk-velden label span{ font-size:10.5px; font-weight:600; letter-spacing:.07em;
  text-transform:uppercase; color:var(--tekst-uitleg); }
.bijwerk-velden input{ width:110px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:17px; font-weight:600; }
.bijwerk-velden em{ font-style:normal; font-size:11px; color:var(--tekst-uitleg); }
.bijwerk-onder{ display:flex; gap:9px; align-items:center; flex-wrap:wrap; }
.wms-cutoff{ display:inline-flex; align-items:center; gap:5px; font-size:11.5px; font-weight:600;
  padding:4px 10px; border-radius:6px; background:var(--gray); color:#4E5866; }
.wms-cutoff.krap{ background:#FDF3E3; color:#B45309; }
.wms-cutoff.voorbij{ background:#FAECE7; color:#B3271A; }
.verw-verzoekbalk{ flex-basis:100%; display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  margin:6px -9px -7px; padding:10px 10px; background:#FAECE7; color:#B3271A;
  border-radius:0 0 8px 8px; font-size:12.5px; }
/* Twan, 01-09-2026: "Ook de bovenkant van deze schermen zie ik liever in wit."
   Deze balk was #EAF1F9 en stak daarmee blauw af tegen de witte kaarten
   eronder. Nu wit met dezelfde kaartschaduw als .pik-balk hierboven, zodat de
   twee balken van het verwerkscherm er als één ding uitzien. De accentkleur
   zat op de hele balk; die hoort op de onderdelen die hem verdienen (de
   modus-pil en de voortgangsbalk), niet op alle tekst. */
.verw-runbalk{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; background:#fff;
  border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:14px; font-size:13px; }

/* Annuleringsverzoek: een waarschuwing, geen etiket. Rood en met een icoon,
   zodat je hem niet per ongeluk mee de deur uit doet. */
.wms-verzoek{ display:inline-flex; align-items:center; gap:5px; font-size:11px; font-weight:650;
  padding:2px 10px; border-radius:5px; background:#FAECE7; color:#B3271A; white-space:nowrap; }
.wms-verzoek i{ font-size:12px; }

.wms-qty-badge{ font-weight:700; padding:2px 10px; border-radius:999px; font-size:12px; display:inline-block; line-height:1.4; }
.wms-qty-tier-1{ background:#EAF3DE; color:#3B6D11; }
.wms-qty-tier-2{ background:#FAEEDA; color:#854F0B; }
.wms-qty-tier-3{ background:#F1E9FA; color:#6B2FA8; }
.wms-qty-tier-4{ background:#EEF0F3; color:#17223A; }

.loc-chip{ background:#EAF0F8; color:var(--primary); font-size:10.5px; font-weight:500; padding:3px 10px; border-radius:999px; display:inline-flex; align-items:center; gap:4px; }
.loc-chip.none{ background:#FAECE7; color:#993C1D; }
.lvb-fallback-badge{ background:#FFF7EC; color:#854F0B; font-size:10px; font-weight:500; padding:3px 6px; border-radius:999px; display:inline-flex; align-items:center; gap:4px; }

/* #251: zelfde witte-kaart-met-schaduw behandeling als .pick-row hierboven —
   Verzendklaar en Openstaande orders gebruiken dit als top-level rij binnen
   .pick-list (geen omliggende .card meer nodig), dus geen gedeelde
   randjes/:first-child-uitzondering meer, gewoon een eigen losse kaart. */
.wms-order-row{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); display:flex; align-items:center; gap:14px; padding:16px 16px; flex-wrap:wrap; }
/* #253: Verzendklaar groepeert orders nu per EAN/itemcombinatie (net als Te
   verwerken) — de groepskaart zelf is een .pick-row (witte kaart+schaduw),
   dus de losse orderregels erbinnen mogen geen eigen kaart-in-kaart meer
   zijn. .nested valt terug op een dunne scheidingslijn, zoals de
   item-regels bij Te verwerken. */
.wms-order-row.nested{ background:transparent; box-shadow:none; border-radius:0; padding:10px 0; border-top:0.5px solid #f0f1f2; }
.wms-order-row.nested:first-child{ border-top:none; padding-top:4px; }
.wms-order-meta{ flex:1; min-width:200px; }
.wms-order-meta .num{ font-size:13px; font-weight:500; color:var(--secondary); display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.wms-order-meta .sub{ font-size:11.5px; color:var(--tekst-uitleg); margin-top:2px; }
.wms-row-click{ cursor:pointer; }
.wms-row-click:hover{ background:var(--gray); }

.status-track{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:18px; }
.status-pill{ display:flex; align-items:center; gap:6px; font-size:11.5px; padding:6px 10px; border-radius:999px; background:var(--gray); color:var(--tekst-uitleg); }
.status-pill .dot{ width:7px; height:7px; border-radius:50%; background:#e3e4e6; flex:none; }
.status-pill.ok{ background:#EAF3DE; color:#3B6D11; }
.status-pill.ok .dot{ background:#3B6D11; }
.status-pill.warn{ background:#FAEEDA; color:#854F0B; }
.status-pill.warn .dot{ background:#854F0B; }
.status-pill.bad{ background:#FAECE7; color:#993C1D; }
.status-pill.bad .dot{ background:#993C1D; }

.wms-detail-section{ border-top:0.5px solid #f0f1f2; padding-top:16px; margin-top:16px; }
.wms-detail-section:first-of-type{ border-top:none; padding-top:0; margin-top:0; }
.wms-detail-section h4{ font-size:12px; font-weight:500; color:var(--tekst-uitleg); margin:0 0 4px; text-transform:uppercase; letter-spacing:.03em; }
.item-pick-row{ display:flex; align-items:center; gap:12px; padding:10px 0; border-top:0.5px solid #f0f1f2; flex-wrap:wrap; }
.item-pick-row:first-child{ border-top:none; }
.item-pick-info{ flex:1; min-width:200px; }
.item-pick-info .t{ font-size:12.5px; font-weight:500; color:var(--secondary); }
.item-pick-info .m{ font-size:10.5px; color:var(--tekst-uitleg); margin-top:2px; display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.item-pick-progress{ font-size:12px; color:var(--tekst-uitleg); min-width:100px; }
.item-pick-progress b{ color:var(--secondary); }
.item-pick-actions{ display:flex; gap:5px; }
select.wms-select{ border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-veld); padding:10px 10px; font-size:13px; color:var(--secondary); background:#fff; min-width:220px; }
select.wms-select:disabled{ opacity:.6; background:var(--gray); }
.label-box{ display:flex; align-items:center; gap:14px; background:var(--gray); border-radius:var(--radius-kaart); padding:16px; flex-wrap:wrap; }
.label-icon{ width:44px; height:56px; background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-knop); display:flex; align-items:center; justify-content:center; color:var(--primary); font-size:20px; flex:none; }
.label-box .lb-info{ flex:1; font-size:12px; color:var(--tekst-uitleg); min-width:200px; }
.label-box .lb-info b{ color:var(--secondary); font-weight:500; display:block; font-size:13px; margin-bottom:2px; }
.dupe-note{ font-size:11px; color:var(--tekst-uitleg); display:flex; align-items:center; gap:5px; margin-top:8px; }
.tracking-share-list{ display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.tsl-row{ display:flex; align-items:center; gap:8px; font-size:12px; }
.tsl-row.yes{ color:#3B6D11; }
.tsl-row.no{ color:var(--tekst-uitleg); }
.vvb-deadline-box{ background:#FFF7EC; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-kaart); padding:10px 16px; margin-top:12px; font-size:12px; color:#854F0B; }
.vvb-deadline-box.expired{ background:#FAECE7; border-color:#F3C9B8; color:#993C1D; }
.vvb-deadline-box.ok{ background:#F7FBF3; border-color:#DCEBCB; color:#3B6D11; }
.vvb-deadline-box .row{ display:flex; justify-content:space-between; margin-top:4px; gap:10px; flex-wrap:wrap; }
.vvb-deadline-box b{ font-weight:600; }
.vvb-offer-row{ display:flex; align-items:center; gap:10px; padding:10px 0; border-top:0.5px solid #f0f1f2; font-size:12.5px; }
.vvb-offer-row:first-child{ border-top:none; }
.final-ship-box{ display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; border-radius:var(--radius-kaart); padding:16px; }
.final-ship-box .txt{ font-size:12.5px; color:var(--tekst-uitleg); }

.bulk-bar{ background:#EAF0F8; border:0.5px solid #cfe0f2; border-radius:var(--radius-kaart); padding:10px 16px; display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin:0 auto 12px; max-width:var(--wms-lijst-breed); }
.bulk-bar .txt{ font-size:12.5px; color:var(--primary); font-weight:500; flex:1; min-width:160px; }
.bulk-select{ width:16px; height:16px; flex:none; cursor:pointer; }
.wms-row-method{ min-width:200px; }
.wms-row-method select{ width:100%; }
.bulk-progress{ background:var(--gray); border-radius:var(--radius-veld); padding:10px 16px; font-size:11.5px; color:var(--tekst-uitleg); margin-bottom:12px; }
.bulk-progress .line{ display:flex; justify-content:space-between; padding:3px 0; }
.bulk-progress .line.ok{ color:#3B6D11; }

.wms-switch{ position:relative; width:36px; height:20px; flex:none; display:inline-block; }
.wms-switch input{ opacity:0; width:0; height:0; }
.wms-switch .slider{ position:absolute; inset:0; background:#e3e4e6; border-radius:999px; cursor:pointer; transition:.15s; }
.wms-switch .slider:before{ content:''; position:absolute; width:16px; height:16px; left:2px; top:2px; background:#fff; border-radius:50%; transition:.15s; }
.wms-switch input:checked + .slider{ background:#3B6D11; }
.wms-switch input:checked + .slider:before{ transform:translateX(16px); }
.switch-row{ display:flex; align-items:center; gap:8px; margin-top:10px; font-size:11.5px; color:var(--tekst-uitleg); }

.method-card{ padding:16px; margin-bottom:12px; }
.method-top{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.method-name{ font-size:13.5px; font-weight:500; }
.method-badges{ display:flex; gap:6px; flex-wrap:wrap; margin-top:6px; align-items:center; }
.conn-matrix{ display:flex; gap:7px; flex-wrap:wrap; margin-top:12px; }
/* EEN UITGEVINKTE CHIP MOET ER OOK ALS CHIP UITZIEN (01-09-2026).
   Twan: "jij had een mooier veld met vinkjes voorgesteld wat overzichtelijker
   is" — terwijl de chips er al waren. Gemeten in de browser: de AAN-stand was
   groen en duidelijk, maar de UIT-stand stond op #fff met alleen een vage
   schaduw. Op een witte kaart is dat wit-op-wit; wat overblijft is een naam met
   een rondje ervoor, en dat leest als losse tekst in plaats van als iets
   aanklikbaars. Zelfde klasse fout als de balk en het orderblok eerder.
   Nu een eigen vlak en een rand, zodat je ziet dat er iets te kiezen valt. */
/* Twan (04-09-2026): "de schakelaars of ze aan of uit staan kan je niet zien."
   Klopt: aan was bleekgroen op bleekgroen, uit bleekgrijs op bleekgrijs, en het
   verschil in het icoon was een leeg rondje tegen een rondje met een vinkje.
   Twee lichte pasteltinten naast elkaar in een lijst van vier connecties per
   methode lees je niet.
   Nu is aan echt gevuld — donkergroen met witte tekst (6,21:1) — en uit een
   gedempt grijs vlak met rand (4,59:1). Het groen is #3B6D11, dezelfde tint
   die de app al gebruikt voor "gelukt"; er komt dus geen kleur bij.
   De uit-stand houdt bewust een eigen vlak: een witte chip op een witte kaart
   was precies het probleem dat hiervóór al eens is opgelost. */
.conn-chip{ font-size:11px; padding:6px 10px; border-radius:999px;
  border:1px solid #D4DAE2; box-shadow:none; background:var(--gray); color:#6B7280;
  cursor:pointer; display:inline-flex; align-items:center; gap:5px; transition:background .12s, border-color .12s; }
.conn-chip:hover{ background:#EEF1F6; border-color:#B9C2CE; }
.conn-chip.on{ background:#3B6D11; border-color:#3B6D11; color:#fff; font-weight:500; }
.conn-chip.on:hover{ background:#33600E; border-color:#33600E; }
.conn-matrix-label{ font-size:10.5px; color:var(--tekst-uitleg); text-transform:uppercase; letter-spacing:.03em; margin-top:12px; margin-bottom:4px; }

.loc-two-col{ display:grid; grid-template-columns:340px 1fr; gap:16px; align-items:start; }
@media (max-width:1000px){ .loc-two-col{ grid-template-columns:1fr; } }
.loc-add-form{ display:flex; gap:8px; padding:16px; border-bottom:0.5px solid #f0f1f2; flex-wrap:wrap; }
.loc-add-form input{ flex:1; min-width:90px; }
/* #254 (Twan: "kan je bij 'locaties' ook een manier toevoegen hoe ik daar
   kan zien welk artikel bij een locatie hoort?"): elke locatierij is nu
   opgevouwen in een .loc-row-wrap zodat er een uitklapbare productenlijst
   (hergebruikt .item-pick-row, zelfde look als Te verwerken) onder de rij
   kan komen — de rand-tussen-rijen verhuist daarom van .loc-row zelf naar
   de wrapper (anders zou elke .loc-row weer "eerste van zijn soort" zijn
   binnen zijn eigen wrapper en dus geen randje meer tonen). */
.loc-row-wrap{ border-top:0.5px solid #f0f1f2; }
.loc-row-wrap:first-child{ border-top:none; }
.loc-row{ display:flex; align-items:center; gap:10px; padding:10px 16px; }
.loc-row .code{ font-size:12.5px; font-weight:500; background:var(--gray); padding:3px 10px; border-radius:var(--radius-veld); }
.loc-row .om{ flex:1; font-size:12px; color:var(--tekst-uitleg); }
.loc-row-toggle{ display:inline-flex; align-items:center; gap:3px; font-size:10.5px; color:var(--tekst-uitleg); background:none; border:none; cursor:pointer; padding:0; }
.loc-row-toggle:hover{ color:var(--primary); }
.loc-row-products{ padding:0 16px 10px 16px; }
.zv-row{ display:flex; align-items:center; gap:10px; padding:10px 16px; border-top:0.5px solid #f0f1f2; flex-wrap:wrap; }
.zv-row:first-child{ border-top:none; }

.corr-form{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; padding:10px 0; }
.hist-list{ display:flex; flex-direction:column; gap:4px; font-size:11.5px; color:var(--tekst-uitleg); max-height:170px; overflow:auto; margin-top:8px; }
.hist-list .pos{ color:#3B6D11; font-weight:600; }
.hist-list .neg{ color:#993C1D; font-weight:600; }
.wms-input{ border:0.5px solid #e3e4e6; border-radius:var(--radius-veld); padding:10px 10px; font-size:12.5px; color:var(--secondary); }
.voorraad-expand{ background:var(--gray); }
.section-gap{ margin-top:22px; }

/* #310 (Twan, 18-08): zoekbare locatiekiezer bij "Producten zonder locatie"
   — vervangt de <select> met ~300 opties. Compacte combobox: 1 tekstveld,
   dropdown eronder verschijnt enkel als deze rij "open" staat
   (wmsLocPickerOpen in app.js), zodat het scherm niet onnodig groeit. */
.wms-locpick{ position:relative; min-width:180px; }
.wms-locpick-list{
  position:absolute; top:calc(100% + 4px); left:0; right:0; z-index:20;
  background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-kaart);
  box-shadow:0 6px 18px rgba(0,0,0,.08); max-height:220px; overflow:auto;
  padding:4px;
}
.wms-locpick-opt{ display:flex; align-items:center; gap:8px; padding:6px 10px; border-radius:var(--radius-veld); cursor:pointer; font-size:12px; }
.wms-locpick-opt:hover{ background:var(--gray); }
.wms-locpick-opt .code{ font-weight:500; background:var(--gray); padding:2px 6px; border-radius:var(--radius-veld); font-size:11px; }
.wms-locpick-opt .om{ flex:1; color:var(--tekst-uitleg); }
.wms-locpick-empty{ padding:10px 10px; font-size:12px; color:var(--tekst-uitleg); text-align:center; }

/* Pakbon: apart printgebied, buiten de normale app-chrome — element wordt
   dynamisch aangemaakt door wmsEnsurePrintArea() in app.js (index.html zelf
   wordt hier bewust niet voor aangepast, zie de scope-afspraak). */
#pakbonPrintArea{ display:none; }
@media print{
  body > *:not(#pakbonPrintArea){ display:none !important; }
  #pakbonPrintArea{ display:block !important; }
}

/* Productprestaties (taak #412) — compacte inline-verschilindicator naast een
   getal in een tabel. De bestaande .stat-card-delta is een blok-element voor de
   grote statkaarten en past niet in een tabelcel. */
.prest-delta{ display:inline-block; margin-left:6px; font-size:10.5px; font-weight:600; white-space:nowrap; }
.prest-delta.goed{ color:#2E7D32; }
.prest-delta.slecht{ color:#993C1D; }
.prest-delta.vlak{ color:var(--tekst-uitleg); }
.prest-rij:hover{ background:#f7f8fa; }
.prest-detailrij td{ border-top:0; }

/* Productprestaties ronde 2: tooltip onder de dagverloop-grafiek. Bewust een
   vast blok onder de grafiek en niet zwevend — dan verspringt de layout niet
   en blijft 'ie ook op een smal scherm leesbaar. */
.prest-tooltip{ margin-top:8px; padding:10px 10px; background:#fff; border:none; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-kaart); font-size:12px; min-height:38px; max-width:320px; }
.prest-tooltip > div{ line-height:1.5; }

/* PIM ronde 2: statuslabel boven een kanaalveld. Vertelt of dit kanaal de
   centrale content volgt of een eigen waarde heeft — zonder dat je eerst een
   keuze hoeft te maken voordat je kunt typen. */
.pim-veldstatus{ display:inline-flex; align-items:center; gap:5px; font-size:11px; padding:3px 10px; border-radius:999px; }
.pim-veldstatus.centraal{ background:var(--gray); color:#6B7488; }
.pim-veldstatus.eigen{ background:#E7E7F7; color:#0000A4; font-weight:600; }

/* Productprestaties ronde 3: kengetallen per stuk/bestelling, en de dagtabel
   onder de grafiek. Die tabel bestaat zodat de dagcijfers ook zonder hoveren
   te lezen zijn — een grafiek alleen laat de lezer gokken. */
.prest-kengetallen{ display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:1px; background:#e3e4e6; border:0.5px solid #e3e4e6; border-radius:var(--radius-kaart); overflow:hidden; margin:4px 0 14px; }
.prest-kengetal{ background:#fff; padding:10px 10px; }
.prest-kengetal .l{ font-size:10.5px; color:var(--tekst-uitleg); line-height:1.3; }
.prest-kengetal .w{ font-size:15px; font-weight:600; color:var(--secondary); font-variant-numeric:tabular-nums; }
.prest-kengetal .v{ font-size:10px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; }
.prest-dagtabel{ font-size:11.5px; }
.prest-dagtabel td, .prest-dagtabel th{ padding:4px 10px; font-variant-numeric:tabular-nums; }
.prest-dagtabel tfoot td{ border-top:1px solid #e3e4e6; background:#fafbfc; }

/* Punt 1 (PIM-vervolgronde): wat bol.com aan een beschrijving verandert, in
   plaats van twee keer dezelfde tekst naast elkaar waar je zelf het verschil
   in moet zoeken. Alleen zichtbaar als er echt iets verandert. */
.pim-bol-verschil{ border-left:3px solid #B45309; background:#FBF0E1; padding:10px 10px; border-radius:0 6px 6px 0; color:#7c3d0a; }

/* Askeuze bij de Branded Shelves-grafiek. Twan: "Daarin kan ik de X en Y as
   zelf instellen met een van de opties." — zie bsAsKiezersHtml in app.js. */
.bs-as-keuze{
  width:100%; padding:6px 10px; border:none; border-radius:var(--radius-veld);
  background:#fff; font-size:12.5px; color:var(--secondary); font-family:inherit;
  box-shadow:var(--schaduw-kaart);
}
/* Focus moet zichtbaar blijven zonder een permanente rand: een ring die er
   alleen is als je er met het toetsenbord bent. */
.bs-as-keuze:focus{ outline:none; box-shadow:0 0 0 2px var(--primary); }

/* ---------- inhoud in een wit kader ----------
   Twan (24-08-2026): "op veel pagina's [staat] te veel tekst tegen de grijze
   achtergrond (#F8F9FA). In de webshop van ibley hebben we dan vaak eerst een
   wit kader waar de content in geplaatst wordt. Enkel wat kopteksten en korte
   beschrijvingen blijven op het grijs."

   Dezelfde regel als op ibley.nl: titels en één korte zin mogen op het grijs,
   al het andere — tabellen, lange uitleg, formulieren — hoort in een kader.
   `.card` bestond al voor de KPI-kaartjes; dit zijn de varianten voor grotere
   inhoudsblokken. */
.content-card{
  background:#fff; border-radius:var(--radius-kaart); padding:16px 16px; margin-bottom:14px;
  box-shadow:var(--schaduw-kaart);
}
.content-card > .data-table{ margin-top:0; }
/* Een tabel vult zijn kader tot de rand: een tabel heeft zijn eigen
   celpadding, dus dubbele witruimte oogt slordig. */
.content-card--table{ padding:6px 10px; }

/* Lange uitleg hoort niet permanent een half scherm te vullen. Ingeklapt is
   het één regel; wie het wil lezen klapt het open. Bewust <details> en geen
   eigen JavaScript — dat werkt ook als er iets misgaat in de rest van de app. */
.uitleg-card{
  background:#fff; border-radius:var(--radius-kaart); margin-bottom:14px;
  box-shadow:var(--schaduw-kaart);
}
.uitleg-card > summary{
  cursor:pointer; padding:10px 16px; font-size:12px; color:var(--tekst-uitleg);
  list-style:none; display:flex; align-items:center; gap:7px;
}
.uitleg-card > summary::-webkit-details-marker{ display:none; }
.uitleg-card > summary::after{
  content:'▾'; margin-left:auto; font-size:10px; color:var(--tekst-uitleg); transition:transform .15s;
}
.uitleg-card[open] > summary::after{ transform:rotate(180deg); }
.uitleg-card > summary:hover{ color:var(--secondary); }
.uitleg-card .uitleg-body{
  padding:0 16px 16px; font-size:12px; line-height:1.55; color:var(--tekst-uitleg);
  border-top:1px solid #F0F1F3; padding-top:11px;
}

/* ---------- geen kaart in een kaart ----------
   Twan (24-08-2026): "LVB heeft 3 witte achtergronden op elkaar gestapeld.
   Aanvuladvies heeft 2 witte achtergronden op elkaar gestapeld."

   Gemeten op LVB: .card.flex-card ín .card.flex-card (die stapeling bestond
   al), en daar kwam mijn .content-card om de tabel als derde laag bovenop.
   Drie witte vlakken op elkaar met elk hun eigen schaduw — precies de
   rommeligheid die het kader moest voorkomen.

   Dit lost het op waar het ook voorkomt, in plaats van per scherm te zoeken:
   een kaart binnen een kaart houdt zijn indeling maar tekent geen eigen wit
   vlak en geen tweede schaduw. Op ibley.nl gebeurt hetzelfde — daar ligt een
   productkaart óók niet op een tweede kaart. */
.card .card,
.card .content-card,
.content-card .content-card,
.content-card .card{
  background:transparent;
  box-shadow:none;
  border-radius:0;
}
/* Een tabelkader binnen een kaart heeft ook zijn eigen randpadding niet meer
   nodig: de kaart eromheen zorgt al voor de witruimte. */
.card .content-card--table,
.content-card .content-card--table{ padding:0; margin-bottom:0; }

/* De productkiezer in het inkoopscherm klapt naar beneden uit, maar zat in een
   .table-wrap met overflow-x:auto — en die knipt hem af. Voor deze ene tabel
   dus niet klippen. Hij hoeft ook niet te schuiven: de kolommen passen. */
.inkoop-regels .table-wrap{ overflow:visible; }
.inkoop-regels td{ overflow:visible; }

/* De productkiezer in het inkoopscherm toont rijen met een afbeelding en twee
   regels tekst; in de 220px van de locatiekiezer passen er dan maar vijf.
   Twan zag daardoor "5 producten" en dacht dat de rest ontbrak. */
.inkoop-regels .wms-locpick-list{ max-height:340px; }

/* ---------- Dashboard: antwoord, aandacht, verloop ----------
   Zie de toelichting in renderDashboardTab. De kop is bewust ongelijk
   verdeeld: het hoofdcijfer krijgt de meeste ruimte omdat het de vraag
   beantwoordt, de andere twee geven context. Zes gelijke kaarten gaven die
   aandacht geen richting. */
.dash-kop{
  display:grid; grid-template-columns:1.5fr 1fr 1.3fr; gap:12px; margin-bottom:14px; align-items:stretch;
}
@media (max-width:1100px){ .dash-kop{ grid-template-columns:1fr 1fr; } }
@media (max-width:760px){ .dash-kop{ grid-template-columns:1fr; } }

.dash-hoofdcijfer{ border-left:3px solid var(--primary); }
.dash-groot{
  font-size:34px; font-weight:600; line-height:1.08; letter-spacing:-0.02em;
  color:var(--secondary); margin-top:2px; font-variant-numeric:tabular-nums;
}
.dash-marge{ font-size:11.5px; color:var(--tekst-uitleg); margin-top:2px; }
.dash-opbouw{ margin-top:12px; display:flex; flex-direction:column; gap:4px; }
.dash-opbouw-rij{
  display:flex; align-items:baseline; gap:8px; font-size:12px; color:var(--tekst-uitleg);
}
.dash-opbouw-rij .num{ margin-left:auto; color:var(--secondary); font-variant-numeric:tabular-nums; font-weight:500; }
/* De delta staat achter het getal en mag de rij niet uit elkaar duwen. */
.dash-opbouw-rij .delta-good, .dash-opbouw-rij .delta-bad{ font-size:10.5px; flex:0 0 auto; }
.dash-balk{ height:5px; border-radius:3px; background:#E8EAEE; overflow:hidden; margin-top:7px; }
.dash-balk i{ display:block; height:100%; background:var(--primary); }

/* Wat aandacht vraagt is een lijst met knoppen, geen losse getallen: elk item
   brengt je naar het scherm waar je er iets aan kunt doen. */
.dash-aandacht{
  font-size:11.5px; padding:4px 10px; border-radius:999px; border:none; cursor:pointer;
  background:rgba(180,70,14,.11); color:#B4460E; font-family:inherit; text-align:left;
}
.dash-aandacht:hover{ background:rgba(180,70,14,.18); }

/* NIET PLATGEDRUKT (08-09-2026)
   Twan: "Ook deze grafiek is ingedrukt in de hoogte: Verloop (winst per uur)."
   De viewBox is 420 breed en wordt met preserveAspectRatio="none" uitgerekt
   naar de volle kaartbreedte (bij hem ruim 600 px), terwijl de hoogte op 132
   bleef staan. Alles wordt dan horizontaal opgerekt en verticaal
   samengedrukt — de pieken worden vlakker dan ze zijn, en dat is bij een
   winstgrafiek niet alleen lelijk maar ook misleidend.
   Hoger dus, in de CSS én in de viewBox (zie dashVerloopSvg in app.js). */
.dash-verloop-svg{ width:100%; height:190px; display:block; margin-top:6px; }
.dash-verloop-hit{ cursor:crosshair; }

/* De tweede rij van het Dashboard: winst per product naast omzet per kanaal. */
.dash-rij2{ display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-bottom:14px; }
@media (max-width:860px){ .dash-rij2{ grid-template-columns:1fr; } }

/* ---------- Breedte begrenzen ----------
   Twan (25-08-2026): "Is het ook een idee om globaal de breedte te beperken
   net als het 'Naar sales dashboard'? Want ik werk op een ultra wide monitor
   dus alles staat wel heel breed en schaalt niet helemaal lekker."

   Terecht, en het is meer dan smaak: op een ultrawide worden tabelrijen zo
   lang dat je oog bij het teruglopen de regel kwijtraakt. Dezelfde reden
   waarom een krant kolommen heeft.

   DE KOLOM WORDT GECENTREERD, NIET ELK ELEMENT APART.
   Eerste poging was `.panel > * { max-width:1600px; margin-inline:auto; }`.
   Dat brak drie schermen: elementen die zélf al een smallere max-width hebben
   (de grafiekkaart op Advertentie staat op 1200px, een kaart op Klantvragen op
   705px) werden daardoor in het midden gezet in plaats van links uitgelijnd,
   en stonden dus niet meer in lijn met de kop erboven.

   Met padding op het paneel schuift de hele kolom naar het midden en blijft
   alles daarbinnen links uitgelijnd — precies zoals het stond, alleen smaller.
   Onder 1600px verandert er niets, want dan wint de 22px. */
/* ---------- de winkelkiezer (02-09-2026) ----------
   Twan: "Ik zou dat eerder in een dropdown doen. Bijvoorbeeld 'alle winkels'
   en daarna per connectie of wellicht zelfs in instellingen je eigen weergave
   maken. Voor mij kan het handig zijn om alle 3 de bol winkels te bekijken
   zonder shopify data."

   Rondjes naast elkaar werken tot een stuk of drie keuzes; hij heeft er vier
   en straks vijf. Dan is het geen filterrij meer maar een tweede menubalk. */
.winkel-kiezer{ position:relative; }
.wk-knop{
  display:inline-flex; align-items:center; gap:8px;
  background:rgba(0,0,0,0.20); color:#fff; border:none;
  font:inherit; font-size:12.5px; padding:6px 10px; border-radius:var(--radius-knop);
  cursor:pointer; max-width:260px;
}
.wk-knop:hover{ background:rgba(0,0,0,0.28); }
.wk-knop .wk-naam{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.wk-menu{
  display:none; position:absolute; left:0; top:calc(100% + 6px);
  background:#fff; border-radius:var(--radius-kaart); box-shadow:0 10px 30px rgba(0,0,0,0.16);
  min-width:280px; z-index:60; padding:6px; max-height:70vh; overflow-y:auto;
}
.winkel-kiezer.open .wk-menu{ display:block; }
.wk-kop{
  font-size:10px; text-transform:uppercase; letter-spacing:.04em;
  color:var(--tekst-uitleg); font-weight:600; padding:10px 10px 4px;
}
.wk-rij{
  display:flex; align-items:center; gap:8px; width:100%;
  background:none; border:none; font:inherit; font-size:12.5px;
  color:var(--secondary); padding:6px 10px; border-radius:var(--radius-knop);
  cursor:pointer; text-align:left;
}
.wk-rij:hover{ background:var(--gray); }
.wk-rij.aan{ background:#EAF0F8; color:var(--primary); font-weight:500; }
.wk-rij .wk-vink{ width:14px; flex:none; }
.wk-rij .wk-tag{
  margin-left:auto; font-size:10px; color:var(--tekst-uitleg);
  border:1px solid var(--border); border-radius:999px; padding:1px 6px;
}

/* ==========================================================================
   DE ZIJBALK (02-09-2026)
   ==========================================================================
   Twan: "Wellicht moeten wij ook wat meer subgroepen maken net als
   MarktMentor aangezien het menu nu al klein is en wij ook Shopify functies
   hebben."

   Gemeten aanleiding: veertig schermen achter twaalf knoppen op één rij. Die
   balk had 1832 punten nodig; op elk laptopscherm schoof hij over het
   accountmenu heen, en het "Meer"-menu dat dat opving verstopte de helft van
   de navigatie.

   DE VORM IS EEN ACCORDEON, GEEN LIJST MET KOPJES. Twan, met een schermafdruk
   erbij: "het WMS is een onderdeel van het hoofdmenu. Ik wil eigenlijk zoiets
   als het screenshot van MarktMentor." Elke groep is dus zelf een rij met een
   pijltje. Dicht is de normale toestand — daarmee is "vandaag heb ik Verkoop
   volgen niet nodig" geen functie maar gewoon hoe het werkt.

   INGEKLAPT TOT ICOONTJES, UITKLAPPEN BIJ HOVER. Twan: "Dan hoeft het menu
   niet helemaal links te staan in het scherm maar kan het bij de content in
   het midden." Op een ultrawide staat een menu aan de schermrand ruim 900
   punten van waar je kijkt; 52 punten naast de inhoud is 1,5% en scheelt die
   reis. Uitklappen legt zich ÓVER de inhoud (nooit ernaast, want dan
   verspringt je scherm) met de rest gedimd, Twans idee. */
/* HET LIJF HOUDT ALTIJD 52 PUNTEN VRIJ VOOR DE BALK.
   Eerst stond de balk als flex-item in de stroom en werd hij bij uitklappen
   absoluut. Gevolg: op het moment van uitklappen viel hij uit de stroom en
   schoof het paneel 52 punten naar links — precies het verspringen dat het
   overheen leggen moest voorkomen. Nu staat de balk ALTIJD buiten de stroom en
   houdt het lijf de ruimte vrij met padding. Dan beweegt er nooit iets. */
/* Twan (02-09-2026): "De balk staat alsnog erg ver naar links. Die zou direct
   naast de content komen toch?" Klopt — gemeten op zijn ultrawide (2646 punten
   na de zoom) begon de inhoud op 549 en eindigde de rail op 52: 497 punten
   niemandsland ertussen.
   De oorzaak zat in het paneel: dat centreerde de kolom zelf met een grote
   binnenmarge, terwijl de rail aan de rand van het LIJF hing. Nu centreert het
   lijf de hele kolom — rail inbegrepen — en houdt het paneel gewoon 22 punten
   over. Eén variabele schakelt tussen de twee breedtes, zodat de vastgespelde
   balk net zo goed tegen de inhoud aan blijft staan. */
.office-body{
  position:relative; flex:1; min-height:0;
  --zb-breedte: 52px;
  --zb-inspring: max(0px, calc((100% - var(--zb-breedte) - 1648px) / 2));
  padding-left: calc(var(--zb-breedte) + var(--zb-inspring));
  padding-right: var(--zb-inspring);
}
/* Vastgespeld: de rail is 250 in plaats van 52. Deze klasse staat op
   .office-view, zodat de kopbalk én het lijf hem allebei zien — anders zou de
   balk op 52 blijven staan en de inhoud eronder wegschuiven. */
.office-body.menu-vast{ --zb-breedte: 250px; }
.office-view.menu-vast .office-header{ --zb-breedte: 250px; }

/* Twan (02-09-2026): "Ik zou het menu ook meer vormgeven als een vrijstaande
   balk ipv de zijkant wat hij nu doet."
   Hij hing als een wand aan de rand: volledige hoogte en een scheidingslijn
   rechts. Nu is het een kaart die op de bladzijde ligt — ronde hoeken rondom,
   een lijn rondom in plaats van alleen rechts, en hij is zo hoog als zijn
   inhoud in plaats van zo hoog als het scherm. Ingeklapt zijn dat negen
   icoontjes, dus dan is het echt een klein blokje.
   De 24 boven is dezelfde als de binnenmarge van het paneel, zodat de bovenkant
   van de kaart precies uitlijnt met de eerste regel inhoud ernaast. */
/* Twan (02-09-2026): "Het menu loopt er doorheen." De kopbalk is sticky en
   staat op z-index 30; de kaart stond op 45 en schoof er bij het scrollen dus
   overheen. Twee dingen daaraan:
   1. De kopbalk gaat boven de kaart staan (46, nog steeds onder de modals op 50).
   2. De kaart SCROLLT NIET MEER WEG. Alleen z-index repareren zou hem netjes
      onder de balk laten verdwijnen, en dan moet je terugscrollen om te kunnen
      navigeren. Hij plakt nu op dezelfde hoogte als de kopbalk hoog is.
   De kolom eromheen is nodig omdat `position:sticky` een normale plek in de
   stroom vereist; hij loopt van boven tot onder door het lijf en geeft de
   kaart dus de volle hoogte om in te plakken. `pointer-events:none` erop,
   anders vangt die lege kolom klikken op de bladzijde eronder af. */
.zijbalk-kolom{
  /* Twan (03-09-2026): "Die staat stijf tegen de topbar." Klopt: .zijbalk is
     sticky met een top-offset, maar die geldt pas als je scrolt. Bovenaan de
     pagina viel de balk dus samen met de onderkant van de kopbalk. Dezelfde
     24 punten als de sticky-offset, zodat hij bij het scrollen niet verspringt. */
  position:absolute; left:var(--zb-inspring); top:24px; bottom:0; width:52px;
  z-index:45; pointer-events:none;
}
.zijbalk{
  position:sticky; top:calc(var(--kopbalk-hoogte, 54px) + 24px); width:52px;
  pointer-events:auto;
  background:#fff;
  border:1px solid var(--border); border-radius:14px;
  box-shadow:0 1px 2px rgba(20,26,34,.06), 0 8px 24px rgba(20,26,34,.07);
  padding:6px 0; display:flex; flex-direction:column; gap:2px;
  /* Alle groepen open is ruim 40 regels; dan mag de kaart zelf schuiven in
     plaats van onder de bladzijde uit te lopen. overflow-x apart op hidden:
     tijdens het uitklappen steekt de tekst even buiten de smalle kaart. */
  /* 100vh telt de zoom niet mee en alles hieromheen wel, vandaar de deling.
     Zo past de kaart altijd tussen de kopbalk en de onderkant van het beeld,
     ook met alle groepen open. */
  max-height:calc(100vh / var(--office-zoom, 1) - var(--kopbalk-hoogte, 54px) - 48px);
  overflow-y:auto; overflow-x:hidden;
  transition:width .16s ease;
}
/* Uitgeklapt ligt hij over de inhoud, die tegelijk gedimd wordt: een diepere
   schaduw hoort daarbij. Er verschuift niets. */
.zijbalk.uit{
  width:250px;
  box-shadow:0 16px 44px rgba(20,26,34,.20);
}
/* Vastgespeld blijft hij breed, met de gewone rustschaduw en zonder dimlaag —
   dan hoort hij bij de bladzijde in plaats van erover. Het lijf schuift dan
   één keer op (zie .menu-vast hierboven), en dat is precies wat vastzetten
   betekent. */
.zijbalk.vast{
  width:250px;
  box-shadow:0 1px 2px rgba(20,26,34,.06), 0 8px 24px rgba(20,26,34,.07);
}

/* De dimlaag hoort bij het lijf en niet bij het hele venster: de kopbalk
   blijft leesbaar, want daar schuift het menu ook niet overheen. */
.zijbalk-scherm{
  position:absolute; inset:0; background:rgba(20,27,43,.42);
  opacity:0; pointer-events:none; transition:opacity .16s ease; z-index:44;
}
.zijbalk-scherm.aan{ opacity:1; pointer-events:auto; }
@media (prefers-reduced-motion: reduce){
  .zijbalk, .zijbalk-scherm{ transition:none; }
}

.zb-rij{
  display:flex; align-items:center; gap:10px;
  min-height:28px;
  padding:6px 16px; margin:0 6px; border-radius:var(--radius-knop);
  background:none; border:none; width:calc(100% - 12px);
  font:inherit; font-size:13px; font-weight:500; color:var(--secondary);
  cursor:pointer; text-align:left; white-space:nowrap;
}
.zb-rij:hover{ background:var(--gray); }
.zb-rij.aan{ background:#EAF0F8; color:var(--primary); }
.zb-rij i.ti{ font-size:17px; flex:none; width:20px; text-align:center; }
/* HET PIJLTJE EN DE TELLER OP ÉÉN REGEL.
   Twan (05-09-2026): "Het menu gaat ook niet lekker als er meldingen zijn."
   Klopte: allebei stond op `margin-left:auto`. Bij een groep met én een
   pijltje én een teller duwde de eerste auto-marge het pijltje naar rechts en
   de tweede de teller nóg verder — met het pijltje los in het midden.
   Nu neemt de tekst de vrije ruimte (flex:1) en staan pijltje en teller er
   gewoon naast, met een vaste tussenruimte. */
.zb-rij .zb-tekst{ overflow:hidden; text-overflow:ellipsis; flex:1 1 auto; min-width:0; }
.zb-rij .zb-chev{ font-size:12px; color:var(--tekst-uitleg); flex:none; }
.zb-rij .zb-tel{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:9.5px; background:#C40002; color:#fff; border-radius:999px;
  padding:1px 6px; flex:none;
}
/* Staat de teller vóór het pijltje in de opmaak? Nee — het pijltje komt
   eerst. Een beetje lucht ertussen zodat ze niet aan elkaar plakken. */
.zb-rij .zb-chev + .zb-tel{ margin-left:2px; }
/* Hier stond een bolletje vóór elk subitem, in de kolom van de icoontjes.
   Twan (03-09-2026), na het gezien te hebben: "Dit is niet zoals ik bedoelde
   dus haal maar weg." Weg dus. Het echte probleem — dat een opengeklapte groep
   open bleef en alles eronder verschoof — is opgelost door de groepen weer in
   te klappen zodra je de balk verlaat of iets aanklikt; zie zbSluit in app.js. */
.zb-kind{
  display:flex; align-items:center; gap:8px;
  min-height:28px;
  padding:6px 16px 6px 42px; margin:0 6px; border-radius:var(--radius-knop);
  background:none; border:none; width:calc(100% - 12px);
  font:inherit; font-size:12.5px; color:var(--tekst-uitleg);
  cursor:pointer; text-align:left; white-space:nowrap;
}
.zb-kind:hover{ background:var(--gray); }
.zb-kind.aan{ color:var(--primary); font-weight:500; background:#EAF0F8; }
/* Bij een subregel is er geen pijltje, dus daar mag de teller wél helemaal
   naar rechts. */
.zb-kind .zb-tel{ margin-left:auto; }
.zb-scheid{ height:1px; background:var(--border); margin:10px 16px; }

/* INGEKLAPT: alleen icoontjes. De tellers blijven staan — dat is het halve
   doel van de balk: zonder iets aan te raken zien dat er drie orders wachten.
   Een groep draagt dan de OPGETELDE teller van wat eronder zit. */
.zijbalk:not(.uit):not(.vast) .zb-tekst,
.zijbalk:not(.uit):not(.vast) .zb-chev,
.zijbalk:not(.uit):not(.vast) .zb-kind{ display:none; }
.zijbalk:not(.uit):not(.vast) .zb-rij{ justify-content:center; padding:6px 0; gap:0; position:relative; }
.zijbalk:not(.uit):not(.vast) .zb-rij .zb-tel{
  position:absolute; top:1px; right:3px; margin:0; font-size:8.5px; padding:0 4px;
}
.zb-speld{
  margin-top:auto; color:var(--tekst-uitleg); font-size:12px;
}
.zijbalk:not(.uit):not(.vast) .zb-speld .zb-tekst{ display:none; }

.panel{
  /* De 1600-punts kolom wordt sinds 02-09-2026 door .office-body gecentreerd
     (zie daar), zodat de zijbalk aan diezelfde kolom hangt in plaats van aan
     de vensterrand. Hier blijft alleen de gewone binnenmarge over. */
  padding:24px;
  flex:1; box-sizing:border-box;
  /* GEEN overflow-y hier. Dat stond er wel, maar het paneel scrolt in de
     praktijk nooit — gemeten is zijn scrollHeight gelijk aan zijn
     clientHeight, de PAGINA scrolt. Zo'n scroll-omgeving die stilstaat maakt
     wel `position:sticky` kapot: de tabelkop klampt zich er dan aan vast en
     schuift gewoon mee omhoog. Zonder deze regel plakt de kop aan de pagina,
     wat is wat je wilt. */
}

.secondary-grid{ margin-top:14px; margin-bottom:14px; }

/* Een melding zonder waarschuwingskarakter krijgt een neutrale kleur: niet
   alles wat je aandacht vraagt is een probleem. */
.dash-aandacht.info{ background:rgba(40,100,174,.10); color:var(--primary); }
.dash-aandacht.info:hover{ background:rgba(40,100,174,.17); }


/* ---------- Tabelkoppen blijven staan ----------
   Twan (25-08-2026): "Kan verder de header sticky gemaakt worden? Sommige
   schermen is nogal een eind terug naar boven scrollen."

   Bij 5.873 bestellingen ben je na een paar schermen kwijt welke kolom wat is.
   Het paneel is de scrollende laag (overflow-y:auto), dus `top:0` plakt tegen
   de bovenkant daarvan.

   De achtergrond MOET expliciet: een sticky element zonder eigen achtergrond
   laat de rijen eronder er dwars doorheen schuiven. Dezelfde reden voor de
   onderrand — zonder die lijn zweeft de kop los boven de eerste rij. */
/* WAAROM DIT NIET METEEN WERKTE.
   `.table-wrap` heeft `overflow-x:auto` om brede tabellen te kunnen schuiven.
   Daarmee wordt dat element de scroll-omgeving, en klampt `position:sticky`
   zich dááraan vast in plaats van aan de pagina — de kop schoof dus gewoon
   mee omhoog. Een CSS-beperking, geen instelfout: `overflow-x:auto` met
   `overflow-y:visible` bestaat niet, de browser maakt daar `auto` van.

   Nu de breedte op 1600px is begrensd passen de tabellen daarbinnen (gemeten:
   1584px tabel in 1584px ruimte). Op een scherm dat breed genoeg is mag de
   omhulling dus gewoon meeschuiven met de pagina, en dan plakt de kop wel.
   Op een smal scherm blijft de horizontale schuif bestaan en plakt de kop
   niet — daar is de zijwaartse schuif het nuttiger van de twee. */
@media (min-width:1200px){
  .table-wrap{ overflow:visible; }
}
.data-table thead th,
.data-table > tbody > tr:first-child > th,
.data-table > tr:first-child > th{
  position:sticky; top:0; z-index:5;
  background:#fff;
  box-shadow:inset 0 -1px 0 #EDEEF0;
}
/* In een kaart met eigen achtergrond moet de kop diezelfde kleur aanhouden. */
.content-card .data-table thead th,
.content-card .data-table > tbody > tr:first-child > th,
.content-card .data-table > tr:first-child > th{ background:#fff; }

/* ---------- De menubalk blijft staan ----------
   Twan (25-08-2026): "Kan verder de header sticky gemaakt worden? Sommige
   schermen is nogal een eind terug naar boven scrollen."

   Bij 5.873 bestellingen is dat inderdaad een reis. De balk plakt nu bovenaan,
   zodat je vanaf elke plek in de lijst naar een ander scherm kunt zonder eerst
   terug te scrollen.

   z-index hoger dan de tabelkoppen (die staan op 5): de menubalk hoort er
   overheen te schuiven, niet eronder.

   De tabelkop krijgt zijn `top` van deze balk mee, anders zou hij eronder
   verdwijnen. --kopbalk-hoogte wordt in app.js gezet zodra de balk is
   getekend, want zijn hoogte hangt af van de zoomfactor. */
.office-header{
  /* 46 en niet 30: de menukaart staat op 45 en schoof er anders bij het
     scrollen overheen (Twan, 02-09-2026: "Het menu loopt er doorheen").
     Onder de modals (50), want die horen over alles heen te liggen. */
  position:sticky; top:0; z-index:46;
}
.data-table thead th,
.data-table > tbody > tr:first-child > th,
.data-table > tr:first-child > th{
  top:var(--kopbalk-hoogte, 0px);
}

/* ...BEHALVE IN EEN TABEL MET ZIJN EIGEN SCHUIFVAK (13-09-2026)
   De regel hierboven duwt de plakkende kolomkop omlaag met de hoogte van de
   menubalk, en dat klopt zolang de PAGINA schuift. In een blok met een eigen
   `overflow:auto` (de artikelkiezer bij Productfamilies) schuift dat blok, en
   dan plakt de kop een rij of twee ín de lijst — je ziet "Artikel / EAN /
   Merk" dan tussen de artikelen zweven in plaats van erboven. Gemeten in de
   draaiende app, na de uitrol van 13-09.
   Binnen zo'n vak is de bovenkant gewoon de bovenkant. */
.eigen-schuifvak .data-table thead th,
.eigen-schuifvak .data-table > tbody > tr:first-child > th,
.eigen-schuifvak .data-table > tr:first-child > th{
  top:0;
}

/* ===================== PRODUCTVENSTER (25-08-2026) =====================
   Twan: "1 venster is prima." De kosten- en bewerken-pop-ups zijn samen één
   productvenster geworden. Gemeten aanleiding: de kostenpop-up was 1.642px
   hoog op een venster van 1.262px, met 2 invulbare velden tussen 52 regels
   leestekst — het veld waarvoor je 'm opende stond ná de catalogusinformatie.
   Vandaar deze indeling: invullen boven de vouw, opzoeken eronder ingeklapt.
   Geen randen, alleen haarlijnen als scheiding — zelfde regel als de rest
   van de app. */
.pv-kop{ display:flex; align-items:flex-start; gap:16px; padding-bottom:14px; border-bottom:1px solid var(--gray); }
.pv-kop-tekst{ flex:1; min-width:0; }
.pv-naam{ font-weight:600; font-size:14.5px; line-height:1.35; color:var(--secondary); }
.pv-subtitel{ font-size:12px; color:var(--tekst-uitleg); margin-top:4px; font-variant-numeric:tabular-nums; }
.pv-basis{ padding:16px 0; }
.pv-basis-grid{ display:grid; grid-template-columns:auto minmax(0,1fr); gap:3px 10px; font-size:12px; color:#4b5563; }
.pv-basis-label{ color:var(--tekst-uitleg); }
.pv-basis-waarde{ min-width:0; }
.pv-invul{ margin-top:14px; }
/* Verkoopprijs per koppeling: read-only, met de brutomarge die meerekent
   terwijl je de inkoopprijs typt (zie pvHerberekenMarge). */
.pv-prijzen{ margin:4px 0 12px; }
.pv-prijsrij{ display:grid; grid-template-columns:minmax(0,1fr) 84px 74px; gap:10px; align-items:baseline;
  font-size:12px; padding:6px 0; border-bottom:1px solid rgba(23,34,58,0.06); }
.pv-prijsrij:last-child{ border-bottom:none; }
.pv-prijsrij--kop{ font-size:11px; color:var(--tekst-uitleg); border-bottom:1px solid rgba(23,34,58,0.09); }
.pv-prijsrij--kop span:not(:first-child){ text-align:right; }
.pv-prijs-naam{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#4b5563; }
.pv-prijs-bedrag{ text-align:right; font-variant-numeric:tabular-nums; color:var(--secondary); }
.pv-marge{ text-align:right; font-variant-numeric:tabular-nums; color:#3B6D11; }
.pv-marge-laag{ color:#993C1D; }
.pv-velden{ margin-top:12px; }
/* Inklapbare secties. Standaard dicht: dit is de informatie die je opzoekt,
   niet die je invult — de samenvatting op de balk beantwoordt de meeste
   vragen al zonder klik. */
.pv-detail{ border-top:1px solid var(--gray); }
.pv-detail > summary{ list-style:none; cursor:pointer; display:flex; align-items:center; gap:8px;
  padding:10px 2px; font-size:12.5px; color:var(--secondary); }
.pv-detail > summary::-webkit-details-marker{ display:none; }
.pv-detail > summary:hover{ color:var(--primary); }
.pv-pijl{ font-size:14px; color:var(--tekst-uitleg); transition:transform .15s; flex-shrink:0; }
.pv-detail[open] .pv-pijl{ transform:rotate(90deg); }
.pv-detail-titel{ font-weight:500; }
.pv-detail-samenvatting{ margin-left:auto; font-size:11.5px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pv-detail-body{ padding:2px 0 16px; }
/* Chip met een geselecteerd product op het verwijderscherm. */
.pv-chip{ display:inline-flex; align-items:center; gap:2px; background:var(--gray); border-radius:var(--radius-knop);
  padding:3px 4px 3px 10px; margin:0 3px 4px 0; font-size:11.5px; font-variant-numeric:tabular-nums; }
.pv-chip .icon-btn{ padding:0 3px; font-size:12px; color:var(--tekst-uitleg); }
/* BUGFIX (25-08-2026, zichtbaar geworden in het nieuwe productvenster, maar
   bestond al even lang in het "+ Nieuw product"-formulier): een checkbox
   binnen een .field-col werd door de descendant-selector `.field-col input`
   op width:100% gezet. Het vinkje rekte dan over de hele regel en duwde het
   label ("Bol.com" / "Shopify") naar de rechterrand. Zelfde soort valkuil als
   eerder bij het inkoopprijsveld in de kosten-pop-up. */
.field-col input[type="checkbox"], .field-col input[type="radio"]{ width:auto; margin-top:0; }
/* Een uitgeschakelde knop moet er ook uitgeschakeld uitzien. De rode
   "Verwijder geselecteerde"-knop was zonder selectie wel disabled, maar zag
   er precies zo dringend uit als wanneer hij wél iets doet. */
.btn-danger:disabled, .btn-primary:disabled, .btn-soft:disabled{ opacity:.42; cursor:not-allowed; }

/* ================= BESTELLINGEN (25-08-2026) =================
   Het scherm opende op alles (5.876 bestellingen, 25 schermen scrollen),
   toonde geen enkel totaal, en de kolom die verraadt dat een openstaande
   bestelling te laat is bestond niet. Zie renderOrdersTab voor de metingen. */
.order-totalen{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px; margin-bottom:12px; }
.order-totaal{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:10px 16px; }
.order-totaal-label{ font-size:11px; color:var(--tekst-uitleg); }
.order-totaal-cijfer{ font-size:19px; font-weight:600; color:var(--secondary);
  font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
@media (max-width:820px){ .order-totalen{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

.order-openstaand{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:12px; }
/* Alleen een gekleurd vlak zodra er ook echt iets te laat is — anders is een
   openstaande bestelling gewoon werk in uitvoering, geen waarschuwing. */
.order-openstaand--laat{ background:#FAECE7; box-shadow:none; }
.order-openstaand-kop{ font-size:12px; font-weight:600; color:var(--secondary); margin-bottom:4px; }
.order-openstaand--laat .order-openstaand-kop{ color:#993C1D; }
.order-openstaand-tabel td{ padding:6px 10px 6px 0; font-size:12px; }
.order-openstaand--laat .order-openstaand-tabel td{ border-bottom-color:rgba(153,60,29,.12); }
.order-openstaand-tabel tr:last-child td{ border-bottom:none; }

/* Titel op één regel. De volledige titel zit in de title-tooltip en in de
   detailweergave; gemiddeld 132 tekens over drie regels is geen kolom maar
   een muur. */
.order-titel{ max-width:340px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.order-totaal-bij{ font-size:10px; color:var(--tekst-zwak); font-weight:400; }

/* ================= AANVULLEN (25-08-2026) =================
   LVB en Aanvuladvies samengevoegd. Zie renderAanvullenView voor de
   metingen; kort: LVB was 15,9 schermen met 380 rijen in drie identieke
   tabellen, waarvan er 58 een advies hadden. */
.aanvullen-instellingen{ display:flex; flex-wrap:wrap; gap:8px 18px; align-items:center;
  background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  padding:10px 16px; margin-bottom:12px; }
.aanvullen-instellingen label{ font-size:12px; color:#4b5563; display:inline-flex; align-items:center; gap:6px; }
.aanvullen-instellingen .tag-muted{ font-size:10.5px; }
.aanvullen-grafiek{ width:100%; max-width:1180px; height:auto; margin-top:4px; }
/* Het advies is waar je voor komt, dus dat mag het grootste getal op de regel
   zijn. Twan: "Titel neemt onnodig veel ruimte in terwijl de adviezen
   belangrijker zijn." */
.aanvullen-advies{ font-size:13px; font-weight:600; color:var(--secondary); font-variant-numeric:tabular-nums; }
.badge-onderweg{ background:#E6EEF8; color:#2864AE; font-size:10.5px; font-weight:500;
  padding:3px 10px; border-radius:999px; }
.badge-oranje{ background:#FAEEDA; color:#8A5A11; font-size:10.5px; font-weight:500;
  padding:3px 10px; border-radius:999px; }
/* Kanaalscheiding zonder aparte tabellen. Twan: "Scheiding tussen kanalen is
   bijna niet te zien." */
.kanaalstreep{ display:inline-block; width:3px; height:13px; border-radius:2px; vertical-align:-2px; margin-right:6px; }

/* ================= INKOOP: kaart per order ================= */
.inkoop-kaart{ padding:16px 16px; margin-bottom:10px; }
.inkoop-kaart-kop{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-bottom:2px; }
.inkoop-lev{ font-size:14px; font-weight:600; color:var(--secondary); }
.inkoop-tijdlijn{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px; margin-top:12px; }
.inkoop-stap{ position:relative; padding-top:16px; font-size:11px; }
/* De lijn loopt door de bollen heen; een afgeronde stap kleurt zichzelf én
   het stuk lijn dat ernaartoe leidt. */
.inkoop-stap::before{ content:''; position:absolute; left:0; right:0; top:5px; height:2px; background:rgba(23,34,58,0.10); }
.inkoop-stap.gedaan::before{ background:var(--primary); }
.inkoop-stap:last-child::before{ right:calc(100% - 12px); }
.inkoop-bol{ position:absolute; left:0; top:0; width:12px; height:12px; border-radius:50%;
  background:#fff; box-shadow:inset 0 0 0 2px rgba(23,34,58,0.16); }
.inkoop-stap.gedaan .inkoop-bol{ background:var(--primary); box-shadow:none; }
.inkoop-stap-titel{ display:block; color:var(--secondary); font-weight:500; }
.inkoop-stap-sub{ display:block; color:var(--tekst-uitleg); font-size:10.5px; margin-top:1px; }
.inkoop-stap.gedaan .inkoop-stap-sub{ color:var(--tekst-uitleg); }
.inkoop-bijna{ color:#2864AE; font-weight:500; }
.inkoop-melding{ background:rgba(40,100,174,0.07); border-radius:var(--radius-veld); padding:10px 10px;
  margin-top:11px; font-size:11.5px; display:flex; align-items:center; gap:7px; color:var(--secondary); }
.inkoop-kaart-knoppen{ display:flex; gap:6px; margin-top:11px; }

/* Wat er in de bestelling zit, licht. Twan: "Al die leveranciers namen lijken
   hetzelfde in china" — de leveranciersnaam bovenaan de kaart onderscheidt zijn
   orders niet, de producten wel. Geen bedragen: die staan in de kop. */
.inkoop-regels-licht{ display:flex; flex-direction:column; gap:6px; margin-top:10px; }
.inkoop-regel-licht{ display:flex; align-items:center; gap:10px; min-width:0; }
.inkoop-regel-tekst{ display:flex; flex-direction:column; min-width:0; flex:1; }
/* De titel op één regel met een beletselteken: een lange Chinese producttitel
   mag de kaart niet twee keer zo hoog maken. */
.inkoop-regel-naam{ font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.inkoop-regel-aantal{ font-size:12px; font-variant-numeric:tabular-nums; color:var(--tekst-uitleg);
  white-space:nowrap; flex:0 0 auto; }
.inkoop-regel-meer{ font-size:11.5px; color:var(--tekst-uitleg); padding-left:40px; }

/* Het advies onder een orderregel — alles wat de app al wist over dit EAN,
   op het moment dat je het nodig hebt. */
.inkoop-advies-rij td{ padding-top:0 !important; }
.inkoop-advies{ background:rgba(180,70,14,0.07); border-radius:var(--radius-veld); padding:10px 10px;
  font-size:11.5px; display:flex; align-items:center; gap:10px; flex-wrap:wrap; color:#4b5563; }
.inkoop-advies strong{ color:#993C1D; }
.inkoop-advies .btn-xs{ margin-left:auto; }
.inkoop-marge{ background:var(--gray); border-radius:var(--radius-veld); padding:6px 10px;
  margin-top:6px; font-size:11.5px; color:#4b5563; }
.inkoop-marge strong{ color:#3B6D11; }

/* ================= PRODUCTPRESTATIES: waterval en kerngetallen ================= */
.prestaties-waterval{ padding:16px 16px; margin-bottom:10px; }
.prest-kerngetallen{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:10px; margin-bottom:10px; }
@media (max-width:820px){ .prest-kerngetallen{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.prest-kern{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:10px 16px; }
.prest-kern-label{ font-size:11px; color:var(--tekst-uitleg); }
.prest-kern-waarde{ font-size:19px; font-weight:600; color:var(--secondary);
  font-variant-numeric:tabular-nums; letter-spacing:-.01em; display:flex; align-items:baseline; gap:8px; }
.prest-kern-waarde .badge{ font-size:10px; font-weight:500; padding:2px 6px; border-radius:999px; }
.prest-bewegingen{ padding:16px 16px; margin-bottom:10px; }
.prest-bewegingen-kolommen{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:22px; margin-top:6px; }
@media (max-width:700px){ .prest-bewegingen-kolommen{ grid-template-columns:1fr; } }
.prest-beweging{ display:flex; align-items:baseline; gap:10px; font-size:12.5px; padding:4px 0;
  border-bottom:1px solid rgba(23,34,58,0.05); }
.prest-beweging:last-child{ border-bottom:none; }
.prest-beweging-naam{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#4b5563; }
.prest-beweging-bedrag{ font-variant-numeric:tabular-nums; font-weight:600; white-space:nowrap; }

/* ================= RETOUREN (26-08-2026) =================
   De retourreden stond alleen achter een informatie-icoon van 42px breed,
   uiterst rechts. Nu een kolom, met de klanttoelichting in de hover en alle
   acht bekende velden in een uitklapregel. Zie renderReturnsTab. */
.retour-rij:hover{ background:var(--gray); }
.retour-onbekend{ background:#FAECE7; }
.retour-pijl{ color:var(--tekst-uitleg); font-size:11px; }
.retour-heeft-notitie{ font-size:10px; color:var(--tekst-uitleg); margin-top:1px; }
.retour-detailrij td{ padding:0 10px 10px !important; }
.retour-detail{ background:var(--gray); border-radius:var(--radius-kaart); padding:10px 16px; }
.retour-detail-grid{ display:grid; grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr);
  gap:5px 16px; font-size:11.5px; align-items:baseline; }
@media (max-width:820px){ .retour-detail-grid{ grid-template-columns:auto minmax(0,1fr); } }
.retour-detail-grid .lbl{ color:var(--tekst-uitleg); white-space:nowrap; }
/* De letterlijke tekst van de klant. Bij 295 van de 551 retouren staat hier
   iets, en dat is vaak het enige dat vertelt wat er echt mis was. */
.retour-citaat{ background:#fff; border-radius:var(--radius-veld); padding:10px 10px; margin-top:9px;
  font-size:12px; font-style:italic; color:#4b5563; box-shadow:var(--schaduw-kaart); }
.tag-chip{ background:var(--gray); color:#4b5563; font-size:10.5px; font-weight:500;
  padding:3px 10px; border-radius:999px; }
/* Waar ging advertentiegeld heen zonder omzet — zie adGeldVerdweenHtml. */
/* Geen vaste 1200px meer. Twan (05-09-2026): "waarom zie ik loze ruimte
   rechts naast de grafiek en de uitgaves zonder omzet" — de tabel eronder
   liep wél door tot de rand, dus die strook viel op als een gat. */
.adv-zonder-omzet{ padding:16px 16px; margin-bottom:12px; }
.adv-zonder-omzet--kort{ background:#FAECE7; box-shadow:none; }
.adv-zonder-lijst{ display:flex; flex-direction:column; gap:2px; margin-top:4px; }
.adv-zonder-rij{ display:flex; align-items:baseline; gap:12px; font-size:12.5px;
  padding:4px 0; border-bottom:1px solid rgba(23,34,58,0.05); }
.adv-zonder-rij:last-child{ border-bottom:none; }
.adv-zonder-naam{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#4b5563; }
.adv-zonder-bedrag{ font-variant-numeric:tabular-nums; font-weight:600; color:#993C1D; white-space:nowrap; }

/* ================= REVIEWS (26-08-2026) =================
   Het scherm toonde 30 sterrenwijzigingen en geen enkele score. Nu twee
   blokken: wat er net binnenkwam (met status, voor het belwerk bij bol) en
   alle 228 producten met hun score. Zie renderReviewsTab. */
.review-verdeling{ width:200px; max-width:100%; height:10px; display:block; }
.review-negatief{ background:#FAECE7; }
.review-negatief:hover{ background:#F7E2DA; }
.review-status{ font-size:11.5px; padding:4px 6px; border-radius:var(--radius-veld);
  border:none; background:var(--gray); color:#000; max-width:150px; }
.product-thumb-img{ width:28px; height:28px; object-fit:contain; border-radius:4px; flex-shrink:0; background:#fff; }
.klantbeoordeling-vlaggen{ display:flex; flex-wrap:wrap; gap:6px 16px; align-items:center;
  margin-top:9px; padding-top:9px; border-top:1px solid var(--gray); font-size:12px; }

/* ============ ADVERTENTIE-KENGETALLEN IN DRIE GROEPEN (26-08-2026) ============
   Alle elf cijfers blijven, ROAS incluis — Twan: "Niet ieder cijfer hoeft een
   grafiek te hebben of iets." Het probleem was rangorde: elf gelijke kaartjes
   in twee rijen, waarin omzet en zichtbare vertoningen er even zwaar uitzagen.
   Nu drie groepen met per groep één hoofdcijfer. */
.kpi-groepen{ display:grid; grid-template-columns:1.15fr 1fr 1fr; gap:10px; margin-bottom:10px; }
@media (max-width:900px){ .kpi-groepen{ grid-template-columns:1fr; } }
.kpi-groep{ background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart); padding:10px 16px; }
.kpi-groepkop{ font-size:10px; letter-spacing:.07em; text-transform:uppercase; color:var(--tekst-uitleg); margin-bottom:8px; }
.kpi-hoofd, .kpi-tweede{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.kpi-hoofd .kpi-getal{ font-size:25px; font-weight:600; letter-spacing:-.015em; color:var(--secondary); }
.kpi-tweede{ margin-top:2px; }
.kpi-tweede .kpi-getal{ font-size:15px; font-weight:600; color:#4b5563; }
.kpi-getal{ font-variant-numeric:tabular-nums; }
.kpi-naam{ font-size:11px; color:var(--tekst-uitleg); }
/* De bestaande deltabadge past hier gewoon in; die kleuren klopten al. */
.kpi-hoofd .metric-delta, .kpi-tweede .metric-delta, .kpi-steun .metric-delta{ font-size:10px; margin:0; }
.kpi-steun{ display:flex; gap:18px; margin-top:10px; padding-top:9px;
  border-top:1px solid rgba(23,34,58,0.07); flex-wrap:wrap; }
.kpi-steun > div{ min-width:62px; }
.kpi-steun-label{ font-size:9.5px; color:var(--tekst-uitleg); }
.kpi-steun-waarde{ font-size:13.5px; font-weight:600; color:var(--secondary); font-variant-numeric:tabular-nums; }


/* ---------- Prijssterren & offline-risico (herbouwd 27-08-2026) ---------- */
/* De offline-redenen zijn klikbare staven: de breedte is relatief aan de
   grootste reden, niet aan het totaal — de tellingen overlappen namelijk
   (410 redenen over 272 offers), dus optellen tot 100% zou liegen. */
.prijsster-redenen{display:flex;flex-direction:column;gap:4px}
.prijsster-reden{
  display:grid;grid-template-columns:190px 1fr 46px 210px;gap:10px;align-items:center;
  background:none;border:0;padding:4px 6px;border-radius:6px;cursor:pointer;text-align:left;width:100%;
}
.prijsster-reden:hover{background:var(--hover-bg,#f5f6f8)}
.prijsster-reden.on{background:#f1e9e4;box-shadow:inset 0 0 0 1px #d9bcae}
.prijsster-reden-naam{font-size:12px;color:var(--secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.prijsster-reden-bak{height:14px;background:#eceef1;border-radius:3px;overflow:hidden}
.prijsster-reden-staaf{display:block;height:100%;background:#993C1D;opacity:.75;border-radius:3px}
.prijsster-reden.on .prijsster-reden-staaf{opacity:1}
.prijsster-reden-getal{font-size:12px;text-align:right;color:var(--secondary);font-variant-numeric:tabular-nums}

.prijsster-alarm{
  border:1px solid #d9bcae;background:#fbf3ef;border-radius:10px;padding:10px 16px;margin-bottom:14px;
}
.prijsster-alarm-kop{font-weight:600;color:#993C1D;display:flex;align-items:center;gap:7px;font-size:13.5px}
.prijsster-alarm-tekst{font-size:12px;color:var(--secondary);margin:3px 0 8px}
.prijsster-alarm-rij{font-size:12.5px;padding:6px 0;border-top:1px solid #ecdcd4}
.prijsster-alarm-rij b{margin-right:7px}
.prijsster-alarm-reden{font-size:11px;color:var(--secondary);margin-top:2px}

/* Versheidsstip: de metingen komen in porties van 30 binnen, dus een rij kan
   dagen oud zijn zonder dat je dat aan het cijfer ziet. */
.prijsster-stip{
  display:inline-block;width:6px;height:6px;border-radius:50%;
  background:#c98a2e;margin-right:5px;vertical-align:middle;
}

.prijsster-reden-actie{font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.prijsster-reden-staaf.urgent{background:#7d2b12;opacity:1}
.prijsster-redenpil{
  display:inline-block;font-size:10.5px;padding:1px 6px;border-radius:20px;
  background:#f2f3f5;color:var(--secondary);border:0.5px solid #e3e4e6;white-space:nowrap;
  cursor:help;margin:1px 0;
}
.prijsster-redenpil.urgent{background:#f7e7e0;color:#993C1D;border-color:#d9bcae;font-weight:600}
@media(max-width:900px){.prijsster-reden{grid-template-columns:130px 1fr 40px}.prijsster-reden-actie{display:none}}

/* Eén product beslaat meerdere rijen (één per koppeling). De titel bovenaan
   uitlijnen i.p.v. verticaal centreren: gecentreerd leest hij als bij de
   verkeerde koppeling te horen. De lijn markeert waar een nieuw product start. */
.prijsster-productcel{vertical-align:top!important;padding-top:10px!important}
tr.prijsster-groepstart > td{border-top:1px solid #e3e4e6}


/* ---------- Zoekpositie: dekking en advertentiewinst ---------- */
.zoekpos-dek-bak{display:flex;height:16px;border-radius:4px;overflow:hidden;background:#eceef1;width:100%}
.zoekpos-dek-deel{display:block;height:100%}
.zoekpos-dek-deel.heeft{background:#2864AE}
.zoekpos-dek-deel.leeg{background:#B9CDE6}
.zoekpos-paar{padding:10px 0;border-top:1px solid #f0f1f3}
.zoekpos-paar:first-of-type{border-top:0}
.zoekpos-paar-kop{font-size:12.5px}
/* De band loopt van positie 1 (links) tot 40+ (rechts): links is beter. */
.zoekpos-band{position:relative;height:22px;background:#f2f3f5;border-radius:4px;margin:5px 0 3px}
.zoekpos-stip{
  position:absolute;top:50%;transform:translate(-50%,-50%);width:16px;height:16px;border-radius:50%;
  font-size:9px;font-weight:600;color:#fff;display:flex;align-items:center;justify-content:center;cursor:help;
}
.zoekpos-stip.ads{background:#2864AE}
.zoekpos-stip.org{background:#8a9099}
.zoekpos-paar-uitleg{font-size:11.5px;color:var(--secondary)}


/* ---------- Kansen vinden: trechter ---------- */
/* Elke trap toont wat er ná die stap overblijft, met de breedte als aandeel
   van het totaal. Zo zie je of een filter werk doet — het nichefilter haalt
   er 86% af, het merkfilter een paar procent. */
.kansen-trechter{display:flex;flex-direction:column;gap:5px}
.kansen-trap{display:flex;align-items:center;gap:9px;height:22px}
.kansen-trap-balk{display:block;height:100%;background:#2864AE;opacity:.8;border-radius:4px;min-width:3px;flex:none}
.kansen-trap-tekst{font-size:11.5px;color:var(--secondary);white-space:nowrap;font-variant-numeric:tabular-nums}
.kansen-trap-tekst b{color:var(--primary)}

/* ---------- Beoordeelstapel (27-08-2026) ---------- */
/* Eén kandidaat tegelijk naast je eigen product. De tabelvorm leverde 41
   oordelen op 7.984 kandidaten op; het knelpunt was de handeling, niet de
   data. Drie toetsen, en de volgende staat er al. */
.stapel-voortgang{height:4px;background:#eceef1;border-radius:2px;overflow:hidden;margin-bottom:5px}
.stapel-voortgang > span{display:block;height:100%;background:#2864AE;border-radius:2px;transition:width .18s ease}
.stapel-teller{font-size:11.5px;color:var(--muted);margin-bottom:12px}

.stapel-kaart{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:760px){.stapel-kaart{grid-template-columns:1fr}}
.stapel-kant{border:0.5px solid #e3e4e6;border-radius:10px;padding:16px;background:#fff}
.stapel-label{
  font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  margin-bottom:9px;display:flex;align-items:center;gap:7px;
}
.stapel-foto{width:100%;height:130px;object-fit:contain;border-radius:8px;background:#f7f8fa}
.stapel-foto.leeg{background:#f2f3f5;display:block}
.stapel-titel{font-size:13px;line-height:1.4;margin-top:9px;color:var(--primary)}
.stapel-prijs{font-size:16px;font-weight:600;margin-top:6px;font-variant-numeric:tabular-nums}
.pil-tracker{
  font-size:9.5px;font-weight:600;padding:1px 6px;border-radius:20px;
  background:#e8eef7;color:#2864AE;text-transform:none;letter-spacing:0;
}
.pil-klasse{
  font-size:11px;padding:1.5px 10px;border-radius:20px;background:#f2f3f5;
  border:0.5px solid #e3e4e6;margin:0 6px;
}
.stapel-ai{
  margin-top:12px;padding:10px 16px;background:#f7f8fa;border-radius:9px;font-size:12.5px;
}

.stapel-knoppen{display:flex;gap:9px;margin-top:14px;flex-wrap:wrap}
.stapel-knop{
  flex:1;min-width:130px;padding:16px 10px;border-radius:9px;border:0.5px solid #e3e4e6;
  background:#fff;font-size:13.5px;font-weight:600;cursor:pointer;color:var(--primary);
}
.stapel-knop:hover:not(:disabled){border-color:#c9ccd2;background:#fafbfc}
.stapel-knop:disabled{opacity:.5;cursor:default}
.stapel-knop.concurrent{border-color:#d9bcae;color:#993C1D;background:#fdf7f4}
.stapel-knop.concurrent:hover:not(:disabled){background:#faeee8}
.stapel-knop.over{flex:0 0 auto;min-width:auto;font-weight:400;color:var(--muted)}
.stapel-toets{display:block;font-size:10px;font-weight:400;color:var(--muted);margin-top:2px}


/* ---------- Zoekopdrachten, ingedeeld naar wat je ermee doet ---------- */
/* Kleur volgt de actie, niet de ernst: inkoopkans is blauw (iets te winnen),
   synoniem groen (zo verholpen), merk en overig neutraal. */
.zoekgroep{border:0.5px solid #e3e4e6;border-left:3px solid #c9ccd2;border-radius:9px;padding:10px 16px;margin-bottom:9px;background:#fff}
.zoekgroep.inkoop{border-left-color:#2864AE}
.zoekgroep.synoniem{border-left-color:#2F6B4F}
.zoekgroep-kop{font-size:13px;display:flex;align-items:center;gap:8px}
.zoekgroep-aantal{font-size:11px;color:var(--muted);background:#f2f3f5;border-radius:20px;padding:1px 10px}
.zoekgroep-uitleg{font-size:11.5px;color:var(--secondary);margin:3px 0 8px}
.zoekgroep-rijen{display:flex;flex-direction:column;gap:3px}
.zoekgroep-rij{display:flex;align-items:baseline;gap:8px;font-size:12.5px;flex-wrap:wrap}
.zoekgroep-term{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--primary)}
.zoekgroep-keer{font-size:10.5px;color:var(--muted);background:#f2f3f5;border-radius:3px;padding:0 6px}


/* ---------- Overlap per webshop ---------- */
.winkel-rij{border:0.5px solid #e3e4e6;border-radius:10px;padding:10px 16px;margin-bottom:9px;background:#fff}
.winkel-kop{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;font-size:13px}
.winkel-overlap{display:flex;align-items:center;gap:10px;margin-top:8px}
.winkel-overlap-bak{flex:0 0 190px;height:14px;background:#eceef1;border-radius:3px;overflow:hidden}
.winkel-overlap-staaf{display:block;height:100%;background:#2864AE;opacity:.8;border-radius:3px}
.winkel-overlap-tekst{font-size:11.5px;color:var(--secondary)}
/* Volgorde van links naar rechts: jij goedkoper, gelijk, zij goedkoper. Het
   rode deel rechts is wat je moet weten. */
.winkel-prijsbalk{display:flex;height:14px;border-radius:3px;overflow:hidden;margin-top:8px;background:#eceef1}
.winkel-prijsbalk .deel{display:block;height:100%}
.winkel-prijsbalk .deel.jij{background:#2F6B4F}
.winkel-prijsbalk .deel.gelijk{background:#c9ccd2}
.winkel-prijsbalk .deel.zij{background:#993C1D}
.winkel-prijstekst{font-size:11.5px;color:var(--secondary);margin-top:5px}
.winkel-detail{margin-top:10px;border-top:0.5px solid #e3e4e6;padding-top:8px}
.winkel-detail-rij{display:flex;justify-content:space-between;gap:14px;padding:6px 0;border-bottom:1px solid #f3f4f6;font-size:12.5px}
.winkel-detail-rij:last-child{border-bottom:0}


/* ---------- Kandidaatkaart (27-08-2026) ---------- */
/* Twan: "Kunnen wij dit ook kaartvorm zetten en er maximaal 1 tegelijk laten
   zien ... nu kan ik zomaar de verkeerde rij nog aandrukken." En over de
   prijs: "3,85 goedkoper is belangrijk net als gratis verzending maar die
   verschillen komen nauwelijks naar voren in 1 groot blok met tekst."
   Vandaar: het verschil is het grootste getal, de twee prijzen staan eronder
   als onderbouwing, en levering staat in losse blokjes. */
.kk-blader{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.kk-teller{font-size:11.5px;color:var(--muted)}
.kk-pijl{
  width:30px;height:30px;border-radius:8px;border:0.5px solid #e3e4e6;background:#fff;
  cursor:pointer;color:var(--secondary);display:inline-flex;align-items:center;justify-content:center;
}
.kk-pijl:hover:not(:disabled){background:#f5f6f8}
.kk-pijl:disabled{opacity:.35;cursor:default}

.kk-kaart{border:0.5px solid #e3e4e6;border-radius:12px;padding:16px 16px;background:#fff}
.kk-kop{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
.kk-titel{font-size:14px;line-height:1.4;color:var(--primary);text-decoration:none}
.kk-titel:hover{text-decoration:underline}

.kk-vergelijk{display:grid;grid-template-columns:minmax(190px,240px) 1fr;gap:18px;align-items:start}
@media(max-width:640px){.kk-vergelijk{grid-template-columns:1fr}}
.kk-verschil-cijfer{font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1.15}
.kk-verschil-cijfer.slecht{color:#993C1D}
.kk-verschil-cijfer.goed{color:#2F6B4F}
.kk-verschil-cijfer.neutraal{color:var(--secondary)}
.kk-verschil-geen{font-size:14px;color:var(--muted)}
.kk-verschil-sub{font-size:11px;color:var(--muted);margin-top:3px}
.kk-prijzen{display:flex;align-items:baseline;gap:8px;margin-top:7px;font-size:13.5px}
.kk-prijs{display:inline-flex;align-items:baseline;gap:5px;font-variant-numeric:tabular-nums}
.kk-prijs.let-op{font-weight:600}
.kk-prijs-label{font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.kk-prijs-pijl{font-size:11px;color:var(--muted)}

.kk-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.kk-chip{
  font-size:11.5px;padding:3px 10px;border-radius:20px;background:#f2f3f5;
  border:0.5px solid #e3e4e6;color:var(--secondary);white-space:nowrap;
}
/* Gratis verzending of morgen in huis kan de doorslag geven naast een paar
   euro verschil; die krijgen daarom nadruk in plaats van dezelfde grijstint. */
.kk-chip.let-op{background:#e8f0ea;border-color:#c3d9ca;color:#2F6B4F;font-weight:600}
.kk-jouw{font-size:11.5px}

.kk-oordeel{margin-top:14px;padding-top:12px;border-top:1px solid #f0f1f3}
.kk-oordeel-regel{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:12px}
.kk-knoppen{display:flex;gap:8px;margin-top:13px;flex-wrap:wrap}
.kk-knop{
  flex:1;min-width:120px;padding:10px 10px;border-radius:9px;border:0.5px solid #e3e4e6;
  background:#fff;font-size:13px;font-weight:600;cursor:pointer;color:var(--primary);
}
.kk-knop:hover:not(:disabled){border-color:#c9ccd2;background:#fafbfc}
.kk-knop:disabled{opacity:.5;cursor:default}
.kk-knop.concurrent{border-color:#d9bcae;color:#993C1D;background:#fdf7f4}
.kk-knop.gekozen{box-shadow:inset 0 0 0 1.5px currentColor}
.kk-knop.wis{flex:0 0 auto;min-width:auto;font-weight:400;color:var(--muted)}

.winkel-detail-eigen{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.winkel-detail-thumb{width:38px;height:38px;object-fit:contain;border-radius:6px;background:#f7f8fa;border:0.5px solid #e3e4e6}

/* De koopblokregel gaat over JOUW kant en stond direct onder de
   bezorgblokjes van de kandidaat — dan leest hij als een vierde blokje. */
.kk-jouw{margin-top:9px;padding-top:8px;border-top:1px solid #f3f4f6}
.kk-jouw-label{font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);display:block;margin-bottom:2px}

.winkel-aiwissel{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.winkel-aiwissel .btn-soft.on{background:#e8eef7;border-color:#c3d3e8;color:#2864AE;font-weight:600}

/* De twee kolommen van de vergelijking: links het verschil met de prijzen,
   rechts wat er verder aan hangt (levering, jouw koopblok). */
.kk-verschil{min-width:0}
.kk-kant{min-width:0}


/* ---------- Twee weergaven: overzicht en één-tegelijk ---------- */
/* Twan: "overzicht wanneer er niks te beoordelen valt (of wat er al beoordeeld
   is). Enkele kaart voor tijdens het beoordelen." De standaard volgt dat: is
   er nog iets te doen, dan opent de kaart. */
.kk-weergave{display:flex;gap:7px;margin-bottom:10px;flex-wrap:wrap}
.kk-weergave .btn-soft.on{background:#e8eef7;border-color:#c3d3e8;color:#2864AE;font-weight:600}
tr.ko-vraagt > td{background:#FFFBF2}
.ko-verschil{white-space:nowrap}
/* Na een oordeel verdween de kaart zonder spoor. Nu staat er wat je vastlegde,
   met de knoppen eronder om het te wijzigen of te wissen. */
.kk-vastgelegd{
  margin-top:12px;padding:10px 10px;border-radius:8px;background:#e8f0ea;
  color:#2F6B4F;font-size:12.5px;display:flex;align-items:center;gap:7px;
}


/* ---------- De concurrentenlijst (27-08-2026) ---------- */
/* Twan: "Zodra een concurrent is geidentificeerd komen er geen gegevens voor
   mij om te vergelijken." Dit is die tweede stap: per artikel wat de
   concurrenten vragen en waar jij in dat rijtje staat. */
.conc-art{border:0.5px solid #e3e4e6;border-radius:10px;margin-bottom:9px;background:#fff;overflow:hidden}
.conc-art-kop{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:10px 16px;cursor:pointer;
}
.conc-art-kop:hover{background:#fafbfc}
.conc-art-thumb{width:34px;height:34px;object-fit:contain;border-radius:5px;background:#f7f8fa;border:0.5px solid #e3e4e6;flex-shrink:0;display:inline-block}
.conc-art-rechts{display:flex;align-items:center;gap:12px;flex-shrink:0;font-size:12.5px}
/* De positie is het eerste wat je wilt zien: 8e van 9 zegt meer dan een prijs. */
.conc-positie{font-size:17px;font-weight:600;font-variant-numeric:tabular-nums}
.conc-positie.laag{color:#993C1D}
.conc-positie.hoog{color:#2F6B4F}
.conc-positie .tag-muted{font-size:11px;font-weight:400;margin-left:2px}
.conc-jouwprijs{font-variant-numeric:tabular-nums;color:var(--secondary)}
.pil-onder{font-size:11px;padding:2px 10px;border-radius:20px;background:#f7e7e0;color:#993C1D;font-weight:600;white-space:nowrap}

/* De prijsladder: elke stip een concurrent, de blauwe is jij. Links goedkoop,
   rechts duur — één blik en je weet of je onderin of bovenin zit. */
.ladder{padding:0 16px 10px}
.ladder-balk{position:relative;height:8px;background:#eceef1;border-radius:4px}
.ladder-stip{
  position:absolute;top:50%;transform:translate(-50%,-50%);width:9px;height:9px;
  border-radius:50%;background:#a9b0bd;border:1.5px solid #fff;cursor:help;
}
.ladder-stip.jij{background:#2864AE;width:13px;height:13px;z-index:2}
.ladder-schaal{display:flex;justify-content:space-between;font-size:10px;color:var(--muted);margin-top:3px}

.conc-art-detail{padding:0 16px 16px;border-top:1px solid #f0f1f3}
.conc-art-detail .data-table{margin-top:10px}
.conc-buiten{margin-top:10px;padding:10px 10px;background:#f7f8fa;border-radius:8px;font-size:12px}

.prijsfactor{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:14px}
.prijsfactor-label{font-size:12px;color:var(--secondary);font-weight:600}
.prijsfactor .btn-soft.on{background:#e8eef7;border-color:#c3d3e8;color:#2864AE;font-weight:600}

/* Ligt het koopblok bij het andere verkoopaccount, dan is de prijs die de klant
   ziet niet die van dit account. Twan: "Cleanyx heeft het koopblok en verkoopt
   actief. Via ibley verkoop ik dat artikel sinds januari eigenlijk al niet meer." */
.pil-anderaccount{font-size:10.5px;padding:2px 10px;border-radius:20px;background:#e8eef7;color:#2864AE;white-space:nowrap}
.pil-inactief{font-size:10.5px;padding:2px 10px;border-radius:20px;background:#f2f3f5;color:var(--muted);border:0.5px solid #e3e4e6;white-space:nowrap}
.conc-jouwkant{background:#f7f8fa;border-radius:8px;padding:10px 10px;margin-top:10px;font-size:12px}
.conc-jouwkant-rij{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:2px 0}
.conc-jouwkant-label{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);min-width:120px}


/* ---------- Google Ads (27-08-2026) ---------- */
/* Apart blok onder de bol-cijfers, niet ertussen: het is een ander kanaal.
   Twan: "Google ads is uitsluitend voor shopify en andere webshop platformen." */
.ga-instel{margin-top:16px;padding-top:12px;border-top:1px solid #e3e4e6}
.ga-velden{margin-top:11px;max-width:520px}
.ga-veld{display:block;margin-bottom:9px}
.ga-veld span{display:block;font-size:11.5px;color:var(--secondary);margin-bottom:3px}
.ga-veld input{width:100%;font-size:12.5px;padding:6px 10px;border:0.5px solid #e3e4e6;border-radius:7px}
.ga-klant{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:12.5px;padding:6px 0;border-bottom:1px solid #f3f4f6}
.ga-klant-nieuw{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}
.ga-klant-nieuw input,.ga-klant-nieuw select{font-size:12.5px;padding:6px 10px;border:0.5px solid #e3e4e6;border-radius:7px}
.gemeten-ok{background:#e8f0ea;color:#2F6B4F;border-radius:8px;padding:10px 10px;font-size:12.5px}

/* Uitleg boven het uitnodigingsformulier op het inlogscherm. */
.login-uitleg{font-size:13px;color:var(--secondary);margin-bottom:12px;line-height:1.5;text-align:center;max-width:280px}


/* ---------- Gebruikersbeheer (27-08-2026) ---------- */
.beheer-nieuw{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.beheer-nieuw input,.beheer-nieuw select{font-size:12.5px;padding:10px 10px;border:0.5px solid #e3e4e6;border-radius:8px}
.beheer-nieuw input{min-width:240px}
/* De link staat er één keer. Daarna is hij weg — in de opslag zit alleen een
   hash, net als bij een wachtwoord. Vandaar de nadruk. */
.beheer-link{border:1px solid #c3d9ca;background:#e8f0ea;border-radius:10px;padding:10px 16px;margin-bottom:14px}
.beheer-link-kop{font-size:13.5px;color:#2F6B4F;display:flex;align-items:center;gap:7px;margin-bottom:3px}
.beheer-link-rij{display:flex;gap:7px;margin-top:8px}
.beheer-link-rij input{flex:1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;padding:6px 10px;border:0.5px solid #c3d9ca;border-radius:7px;background:#fff}

/* Productafbeelding in een pakrij, met uitvergroting bij hover.
   Twan (31-08-2026): "dat is hard nodig voor het identificeren of ik het
   juiste artikel gepakt heb". Bij een schap vol op elkaar lijkende artikelen
   is de foto het enige dat snel uitsluitsel geeft. */
.wms-pick-thumb{ width:56px; height:56px; border-radius:8px; }
.wms-thumb-hover{ position:relative; display:inline-flex; flex:none; }
.wms-thumb-groot{
  position:absolute; left:0; top:calc(100% + 8px); z-index:60;
  width:260px; height:260px; padding:10px; border-radius:12px;
  background:#fff; border:1px solid var(--border);
  box-shadow:0 18px 44px rgba(20,26,34,.26);
  display:none; align-items:center; justify-content:center;
}
.wms-thumb-groot img{ max-width:100%; max-height:100%; object-fit:contain; }
.wms-thumb-hover:hover .wms-thumb-groot,
.wms-thumb-hover:focus-within .wms-thumb-groot{ display:flex; }
/* Onderaan de lijst zou de uitvergroting buiten beeld vallen; dan klapt hij
   naar boven open. */
.wms-thumb-hover.omhoog .wms-thumb-groot{ top:auto; bottom:calc(100% + 8px); }

/* ---- WMS pakscherm, herbouw 31-08-2026 (voorstellen 1, 2, 4 en 6) ---- */

/* De rij: locatie links, dan de inhoud, dan het aantal en de knoppen.
   Bewust RUIM opgezet. Twan: "Het is beter om wat extra pixels te hebben zodat
   je niks mist. Het is geen data waarbij we bulk moeten verwerken want alles
   wordt per EAN verwerkt." */
/* GRIJZE RIJEN, TWEEDE POGING (31-08-2026).
   ---------------------------------------------------------------------------
   Twan: "Te verwerken zie ik nog steeds een grijze achtergrond bij de orders
   ipv wit."

   Twee fouten van mijn kant, allebei gisteren gemaakt bij de herbouw:

   1. `.pick-loc` kreeg `background:var(--gray)`. Maar --gray is #F8F9FA en dat
      is EXACT de paginaachtergrond (html,body bovenin dit bestand). De
      locatiekolom viel dus weg in de pagina en het leek of er een hap uit de
      kaart was. Gezien op een proefweergave met deze stylesheet, niet bedacht.

   2. Ik gaf deze rij een RAND terwijl elke andere kaart in het WMS een
      schaduw heeft (.pick-row, .wms-order-row). Dat is precies wat #259 al
      eens opleverde: "kan je het 'te verwerken' scherm dezelfde stijl geven
      als 'verzendklaar'? Dus ook die witte achtergrond met schaduw". Nu
      dezelfde behandeling, zodat de twee soorten rijen naast elkaar niet uit
      twee verschillende ontwerpen lijken te komen.

   --card bestaat trouwens nergens in dit bestand; die var() viel altijd al
   terug op #fff. Weggehaald in plaats van een token te verzinnen die verder
   niemand gebruikt. */
.pick-rij{
  display:grid; grid-template-columns:108px minmax(0,1fr) auto auto;
  align-items:stretch; background:#fff;
  border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  margin-bottom:10px; overflow:visible; position:relative;
}
.pick-rij::before{ content:''; position:absolute; left:0; top:0; bottom:0; width:4px;
  border-radius:var(--radius-kaart) 0 0 var(--radius-kaart); background:var(--border); }
/* De tiernamen komen uit wmsShipByInfo (app.js): urgent / soon / normal.
   Niet zelf verzinnen, anders kleurt de streep nooit. */
.pick-rij.tier-urgent::before{ background:#B3271A; }
.pick-rij.tier-soon::before{ background:#B45309; }
.pick-rij.tier-normal::before{ background:#3B6D11; }
.pick-rij.done{ opacity:.62; }

/* De locatiekolom: dit is waar je heen loopt, dus groot en links. */
.pick-loc{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:3px; padding:16px 10px 16px 10px; border-right:1px solid var(--border);
  background:#fff; border-radius:var(--radius-kaart) 0 0 var(--radius-kaart); text-align:center;
}
.pick-loc-code{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:15px; font-weight:650; letter-spacing:-.01em; color:var(--secondary); }
.pick-loc-om{ font-size:10.5px; color:var(--tekst-uitleg); }
.pick-loc-geen{ font-size:11.5px; font-weight:600; color:#B3271A; line-height:1.25; }
.pick-loc-geen i{ display:block; font-size:15px; margin-bottom:2px; }

.pick-body{ padding:16px 16px; min-width:0; }
.pick-kop{ display:flex; align-items:flex-start; gap:12px; }
.pick-kop-tekst{ min-width:0; flex:1; }
.pick-titel{ font-size:13.5px; font-weight:560; line-height:1.4; }
.pick-meta{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:5px; }
.pick-ean{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:11.5px; color:var(--tekst-uitleg); }
.pick-chip{ display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:600;
  padding:2px 10px; border-radius:5px; background:var(--gray, #F3F5F8); color:#4E5866; }

/* De orders: altijd zichtbaar (voorstel 1), en alleen wat afwijkt (voorstel 2). */
.pick-orders-vast{ display:flex; flex-direction:column; gap:4px; margin-top:11px;
  padding-top:10px; border-top:1px solid var(--border); }
.pick-order{ display:flex; align-items:center; gap:9px; font-size:12.5px;
  padding:3px 6px; border-radius:6px; cursor:pointer; }
.pick-order:hover{ background:var(--gray, #F3F5F8); }
.pick-order.done{ opacity:.6; }
.pick-order .o-aantal{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:11.5px; font-weight:650; background:var(--gray, #F3F5F8); color:#4E5866;
  padding:1px 6px; border-radius:4px; min-width:28px; text-align:center; }
.pick-order .o-nr{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight:600; letter-spacing:-.01em; }
.pick-order .o-rest{ color:var(--tekst-uitleg); }
.pick-order .o-klaar{ margin-left:auto; color:#3B6D11; font-weight:600; font-size:11.5px; }

.pick-aantal{ display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:16px 16px; border-left:1px solid var(--border); min-width:88px; }
.pick-aantal-groot{ font-size:21px; font-weight:680; letter-spacing:-.02em; line-height:1;
  font-variant-numeric:tabular-nums; color:var(--secondary); }
.pick-aantal-groot span{ color:#9AA3AF; font-weight:500; }
.pick-aantal-label{ font-size:10px; color:var(--tekst-uitleg); margin-top:4px;
  text-transform:uppercase; letter-spacing:.08em; }

.pick-acties{ display:flex; align-items:center; gap:6px; padding:16px 16px;
  border-left:1px solid var(--border); }

/* Gangen: een looproute in plaats van heen en weer (voorstel 4). */
.pick-gang{ display:flex; align-items:center; gap:10px; margin:22px 0 9px; }
.pick-gang:first-child{ margin-top:4px; }
.pick-gang-code{ font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:12px; font-weight:660; letter-spacing:.07em; padding:3px 10px; border-radius:5px;
  background:var(--primary-soft, #EAF1F9); color:var(--primary, #2864AE); }
.pick-gang-code.geen{ background:#FAECE7; color:#B3271A; }
.pick-gang-tel{ font-size:12px; color:var(--tekst-uitleg); }
.pick-gang-lijn{ flex:1; height:1px; background:var(--border); }

/* Voortgangsbalk bovenaan (voorstel 6). */
.wms-voortgang{ display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  background:var(--card, #fff); border:1px solid var(--border); border-radius:10px;
  padding:16px 16px; margin-bottom:16px; }
.wms-v-cijfer{ font-size:20px; font-weight:680; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; color:var(--secondary); }
.wms-v-cijfer span{ color:var(--tekst-uitleg); font-weight:500; font-size:14px; }
.wms-v-balk{ flex:1; min-width:180px; height:8px; border-radius:5px;
  background:var(--gray, #F3F5F8); overflow:hidden; display:flex; }
.wms-v-balk i{ display:block; height:100%; }
.wms-v-legenda{ display:flex; gap:14px; flex-wrap:wrap; font-size:12px; color:#4E5866; }
.wms-v-legenda span{ display:inline-flex; align-items:center; gap:6px; }
.wms-vpunt{ width:8px; height:8px; border-radius:3px; display:inline-block; }

@media (max-width: 980px){
  .pick-rij{ grid-template-columns:92px minmax(0,1fr); }
  .pick-aantal, .pick-acties{ border-left:0; border-top:1px solid var(--border);
    grid-column:1 / -1; flex-direction:row; justify-content:flex-start; gap:12px; }
}

/* ---- PIM: het Te doen-scherm en de nieuwe lijstkolommen (31-08-2026) ----
   Twan: "Het systeem moet meer een invulveld/formulier worden ipv wat het nu
   is." De statuskolommen zijn vervangen door wat er te doen staat. */
.pim-voortgang{
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  background:var(--card,#fff); border:1px solid var(--border); border-radius:10px;
  padding:16px 16px; margin-bottom:14px;
}
.pim-v-cijfer{ font-size:20px; font-weight:680; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums; color:var(--secondary); }
.pim-v-cijfer span{ color:var(--tekst-uitleg); font-weight:500; font-size:14px; }
.pim-v-balk{ flex:1; min-width:180px; height:8px; border-radius:5px;
  background:var(--gray,#F3F5F8); overflow:hidden; }
.pim-v-balk i{ display:block; height:100%; background:#3B6D11; }

/* De voortgang telt sinds 02-09-2026 velden en geen artikelen; het aantal
   complete artikelen staat er als tweede getal naast, zodat je nog steeds
   ziet hoeveel er écht af is. */
.pim-v-naast{ font-size:12.5px; color:var(--tekst-uitleg); width:100%; }

/* Het merkblok. De drie GPSR-velden horen bij een merk en niet bij een
   artikel, dus staan ze hier apart bovenaan in plaats van als drie taken van
   479 in de lijst eronder. */
.pim-merkblok{
  background:var(--card,#fff); border:1px solid var(--primary,#2864AE);
  border-radius:10px; padding:16px 16px; margin-bottom:10px;
}
.pim-merkblok-kop{ display:flex; gap:12px; align-items:flex-start; margin-bottom:10px; }
.pim-merkblok-kop i{ font-size:20px; color:var(--primary,#2864AE); flex:none; margin-top:2px; }
.pim-merkrij{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto auto; gap:10px;
  align-items:center; padding:10px 0; border-top:1px solid var(--border);
}
.pim-merkrij-naam{ font-size:14px; font-weight:600; color:var(--secondary); min-width:0; }
.pim-merkrij-n{ font-size:12.5px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; white-space:nowrap; }
@media (max-width:760px){
  .pim-merkrij{ grid-template-columns:minmax(0,1fr) auto; }
  .pim-merkrij-st{ grid-column:1; }
}

.pim-taak{
  display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:16px; align-items:center;
  background:var(--card,#fff); border:1px solid var(--border); border-radius:10px;
  padding:16px 16px; margin-bottom:10px;
}
.pim-taak.accent{ border-color:var(--primary,#2864AE); }
.pim-taak.bezig{ border-color:#B45309; }
.pim-taak-getal{
  min-width:56px; height:48px; padding:0 10px; border-radius:10px;
  background:var(--primary-soft,#EAF1F9); color:var(--primary,#2864AE);
  display:flex; align-items:center; justify-content:center;
  font-size:19px; font-weight:700; font-variant-numeric:tabular-nums;
}
.pim-taak-tekst{ min-width:0; }
.pim-taak-titel{ font-size:15px; font-weight:600; color:var(--secondary); }
.pim-taak-sub{ font-size:13px; color:#4E5866; margin-top:3px; }
.pim-balk{ height:6px; border-radius:4px; background:var(--gray,#F3F5F8); overflow:hidden; margin-top:8px; max-width:340px; }
.pim-balk i{ display:block; height:100%; background:#B45309; }

/* Chips in de lijst: wat ontbreekt (rood) en waar het product klaar voor is. */
.pim-gat{
  display:inline-block; font-size:11px; font-weight:600; padding:3px 10px;
  border-radius:5px; background:#FAECE7; color:#B3271A; margin:1px 2px 1px 0;
}
.pim-klaar{
  display:inline-block; font-size:11px; font-weight:600; padding:3px 10px;
  border-radius:5px; background:#E7F1E0; color:#3B6D11; margin:1px 2px 1px 0;
}

/* Velden naast elkaar (02-09-2026). Twan: "Ook de dingen die naast elkaar
   passen lijkt me handig", met bol's eigen scherm als maatstaf — daar staan
   Product breedte en Product hoogte op één regel. Elk veld had hier een eigen
   tabelrij, waardoor een formulier van 62 velden 62 regels lang werd. */
.pim-veldraster{
  display:grid; grid-template-columns:1fr 1fr; gap:16px;
  padding:16px 0 0;
}
/* Een specificatieveld vult zijn kolom. Zonder dit blijft een invoerveld op
   zijn eigen breedte staan en wordt de knop ernaast naar de rechterrand
   geduwd, met een gat ertussen. De eenheid-keuze zit een niveau dieper en
   blijft dus wel klein. */
/* GEMETEN, 05-09-2026: dit greep niet. De opmaak is `.pim-veld-inv > div
   (flex) > div (de kolom) > input`, dus de input is een KLEINKIND en viel
   buiten `> div > input`. Zolang er een Opslaan-knop naast stond viel dat niet
   op — die vulde de rest van de regel. Nu die knop naar de voet van het
   gedeelte is verhuisd, stond er een invoerveld van 154 punten in een vak van
   406 en oogde het formulier stuk. De eenheid-keuze en de vinkjes houden hun
   eigen maat. */
.pim-veld-inv input:not([type=checkbox]):not([type=radio]),
.pim-veld-inv > div > select{ width:100%; }
.pim-veld-inv select:not([id$="_eenheid"]){ width:100%; }
.pim-veld-inv .pim-keuze-zoek{ width:100%; }
/* Een maat met een eenheid ernaast: het getal deelt de regel met de
   eenheid-keuze en heeft daar al een `flex:1` voor. Zou het ook nog 100%
   willen zijn, dan krimpen ze allebei evenveel en wordt het getalvak even
   smal als de eenheid — terwijl het getal is wat je intypt. */
.pim-veld-inv input[type=number]{ width:auto; }

/* De Opslaan-knop van een specificatieveld bestaat pas zodra er iets te
   bewaren is. Zie pimMarkeerVeldGewijzigd in app.js. */
.pim-veld .pim-veld-opslaan{ display:none; }
.pim-veld.wordt-gewijzigd .pim-veld-opslaan{ display:inline-flex; }
.pim-veld.breed{ grid-column:1 / -1; }
.pim-veld.inactief{ opacity:.55; }
.pim-veld-kop{ font-size:12.5px; color:var(--secondary); margin-bottom:6px; }
/* Op de kolom van 1600 wordt een halve kolom 756 punten breed. Een invoerveld
   van 160 punten in zo'n vak geeft een formulier dat half leeg oogt; bol's
   eigen velden vullen hun kolom wel. Vandaar: het invoerveld rekt mee, met een
   bovengrens zodat een tekstveld niet absurd lang wordt. */
.pim-veld-inv{ min-width:0; max-width:520px; }
.pim-veld-inv input:not([type=checkbox]):not([type=radio]),
.pim-veld-inv select,
.pim-veld-inv textarea{ flex:1 1 auto; min-width:0; }
.pim-veld.breed .pim-veld-inv{ max-width:none; }
/* Onder de 900 punten past twee kolommen niet meer naast elkaar zonder dat de
   invoervelden te smal worden. */
@media (max-width:900px){
  .pim-veldraster{ grid-template-columns:1fr; }
}

/* Het voortgangsblok (02-09-2026). Bol toont drie niveaus met bolletjes en één
   regel per niveau; wij openden met een rode opsomming van alles wat er mis
   was. Twan: "het PIM systeem moet zo veel mogelijk gelijk zijn met de
   connectie waar het naartoe gepubliceerd wordt". */
.pim-vg{ margin-bottom:16px; }
.pim-vg-kop{ display:flex; align-items:baseline; gap:10px; margin-bottom:10px; flex-wrap:wrap; }
.pim-vg-titel{ font-size:14px; font-weight:600; color:var(--secondary); }
.pim-vg-telling{ margin-left:auto; font-size:12px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; }
.pim-vg-trap{ display:flex; border-radius:6px; overflow:hidden; margin-bottom:10px; }
.pim-vg-trap div{ flex:1; padding:6px 10px; text-align:center; font-size:12px; border-right:1px solid #fff; }
.pim-vg-trap div:last-child{ border-right:none; }
.pim-vg-trap .uit{ background:var(--gray,#F3F5F8); color:var(--tekst-uitleg); }
.pim-vg-trap .aan{ color:#fff; font-weight:600; }
.pim-vg-trap .aan.rood{ background:var(--danger); }
.pim-vg-trap .aan.geel{ background:#8A5B00; }
.pim-vg-trap .aan.groen{ background:#3B6D11; }
.pim-vg-nivo{
  display:grid; grid-template-columns:130px 1fr; gap:10px; align-items:baseline;
  padding:6px 0; border-top:1px solid var(--border); font-size:13px;
}
.pim-vg-nivo:first-of-type{ border-top:none; }
.pim-vg-nivo p{ margin:0; color:var(--tekst-uitleg); }
.pim-vg-nivo.nu p{ color:var(--secondary); }
.pim-vg-naam{ display:flex; align-items:center; gap:6px; font-weight:600; color:var(--tekst-uitleg); }
.pim-vg-nivo.nu .pim-vg-naam.n-onvolledig{ color:var(--danger); }
.pim-vg-nivo.nu .pim-vg-naam.n-voldoende{ color:#8A5B00; }
.pim-vg-nivo.nu .pim-vg-naam.n-compleet{ color:#3B6D11; }
.pim-vg-stip{ display:inline-flex; gap:3px; }
.pim-vg-stip i{ width:6px; height:6px; border-radius:50%; background:var(--border); display:block; }
.pim-vg-nivo.nu .pim-vg-stip i.vol{ background:currentColor; }
.pim-vg-los{
  margin-top:10px; padding:10px; border-radius:6px;
  background:var(--gray,#F3F5F8); color:var(--tekst-uitleg); font-size:12.5px;
}

/* De bol-veldsecties (02-09-2026). Twan legde ons scherm naast bol's eigen
   productinformatiepagina: "Dat van ons is onrustig, veel te veel irrelevante
   informatie en te veel meldingen... Bol zelf is vele malen beter momenteel."
   Bol groepeert in drie inklapbare blokken met een teller (3/3, 20/21, 20/33)
   en een kleur die zegt of het af is. Dat is precies wat hier ontbrak. */
.pim-bolsectie{
  border:1px solid var(--border); border-radius:10px;
  margin-top:14px; overflow:hidden; background:var(--card,#fff);
}
.pim-bolsectie.compleet{ border-left:3px solid #3B6D11; }
.pim-bolsectie.open-punten{ border-left:3px solid var(--danger); }
.pim-bolsectie-kop{
  display:flex; align-items:center; gap:10px; width:100%;
  background:none; border:none; cursor:pointer; text-align:left;
  padding:10px 16px; font:inherit; color:var(--secondary);
}
.pim-bolsectie-kop:hover{ background:var(--gray,#F8F9FA); }
.pim-bolsectie-kop i{ font-size:14px; color:var(--tekst-uitleg); }
.pim-bolsectie-titel{ font-size:14px; font-weight:600; }
.pim-bolsectie-teller{
  margin-left:auto; font-size:12px; font-weight:600;
  background:#FAECE7; color:#B3271A; border-radius:999px; padding:2px 10px;
  font-variant-numeric:tabular-nums;
}
.pim-bolsectie-teller.goed{ background:#E7F1E0; color:#3B6D11; }
.pim-bolsectie-lijf{ padding:0 16px 16px; }

/* ÉÉN OPSLAANKNOP PER GEDEELTE (05-09-2026).
   Twan: "graag niet elke optie een opslaan knop geven maar gewoon voor 1
   gedeelte." De voet blijft onderin het gedeelte in beeld terwijl je door de
   velden scrolt — bij 32 aanvullende specificaties is de knop anders een
   scherm ver weg op het moment dat je hem nodig hebt. */
.pim-sectie-voet{
  position:sticky; bottom:0; z-index:2;
  display:flex; align-items:center; justify-content:flex-end; gap:16px;
  margin-top:16px; padding:10px 0 0;
  border-top:1px solid var(--border);
  background:linear-gradient(to bottom, rgba(255,255,255,0), #fff 40%);
}
.pim-sectie-stand{
  font-size:12px; color:var(--tekst-uitleg);
  display:inline-flex; align-items:center; gap:6px;
  transition:color .15s ease;
}
.pim-sectie-voet.vuil .pim-sectie-stand{ color:#8A5B00; font-weight:600; }
.pim-sectie-voet.vuil .pim-sectie-stand i{ font-size:12px; }
/* Een uitgeschakelde knop hoort er uitgeschakeld uit te zien, niet blauw-maar-
   werkt-niet: dat leest als kapot in plaats van als "er is niets te doen". */
/* Een mislukte opslag blijft staan waar je aan het werk was. */
.pim-sectie-fout{
  margin-right:auto; display:inline-flex; align-items:center; gap:6px;
  font-size:12px; color:var(--danger); font-weight:600;
}
.pim-sectie-knop:disabled{
  background:var(--gray,#F3F5F8); color:var(--tekst-uitleg);
  border-color:var(--border); box-shadow:none; cursor:default;
}

/* WAT BOL ER ZELF VAN ZEGT. Drie standen, en ze moeten van elkaar te
   onderscheiden zijn: online, nog niet online, en "bol zei er niets over".
   Die laatste is geen slecht nieuws maar een leemte, en hoort er dus ook niet
   als slecht nieuws uit te zien. */
.pim-bolstand{
  display:flex; gap:10px; align-items:flex-start;
  padding:10px; border-radius:6px; margin-bottom:16px;
  font-size:12.5px; line-height:1.5;
}
.pim-bolstand i{ font-size:15px; margin-top:1px; flex:none; }
.pim-bolstand.online{ background:#E7F1E0; color:#2F5A0D; }
.pim-bolstand.bezig{ background:#FBF1E2; color:#8A5B00; }
.pim-bolstand.onbekend{ background:var(--gray,#F3F5F8); color:var(--tekst-uitleg); }

/* Het upload-rapport van bol: per veld wat hij ermee deed. Staat open zodra er
   iets afgewezen is, anders dichtgeklapt — je hoeft niet elke keer langs
   veertig gepubliceerde velden te scrollen. */
.pim-rapport .data-table td{ vertical-align:top; }

/* De foutcode van bol: kort, herkenbaar en te noemen in een gesprek
   ("ik krijg BOL-03"). Zie lib/bolFouten.js. */
.fout-code{
  display:inline-block; padding:1px 6px; border-radius:4px;
  background:var(--secondary,#17223A); color:#fff;
  font-size:11px; font-weight:600; letter-spacing:.02em;
}

/* MEERDERE LOSSE TEKSTWAARDEN (Kleur). Bol publiceert voor dit veld geen
   keuzelijst, maar het veld is wél meerwaardig — zie inferField in
   lib/pim/bolDatamodel.js. */
.pim-mt{ display:flex; flex-direction:column; gap:6px; align-items:flex-start; width:100%; }
.pim-mt-regels{ display:flex; flex-direction:column; gap:6px; width:100%; }
.pim-mt-regel{ width:100%; }
.pim-mt-meer{ align-self:flex-start; }

/* INTERACTIE-ONTWERP (05-09-2026, op Twans verwijzing naar Figma's
   interaction-design-uitleg). Drie dingen die overal ontbraken: je ziet niet
   waar je bent, je ziet niet dat iets aanklikbaar is, en niets beweegt mee.
   Toetsenbordfocus krijgt bewust een ANDERE markering dan de muis-hover: wie
   tabt moet kunnen zien waar hij staat, ook midden in een formulier. */
.pim-veld{
  border-radius:6px; padding:6px; margin:-6px;
  transition:background-color .15s ease;
}
.pim-veld:focus-within{ background:var(--gray,#F8F9FA); }
.pim-veld:focus-within .pim-veld-kop{ color:var(--primary); }
.pim-veld-inv input:not([type=checkbox]):not([type=radio]),
.pim-veld-inv select,
.pim-veld-inv textarea{ transition:border-color .15s ease, box-shadow .15s ease; }
.pim-veld-inv input:not([type=checkbox]):not([type=radio]):hover,
.pim-veld-inv select:hover,
.pim-veld-inv textarea:hover{ border-color:#A9B4C2; }
.pim-veld-inv input:not([type=checkbox]):not([type=radio]):focus,
.pim-veld-inv select:focus,
.pim-veld-inv textarea:focus{
  border-color:var(--primary); box-shadow:0 0 0 3px rgba(40,100,174,.15); outline:none;
}
/* De kop van een gedeelte is een knop; dat mag je aan de aanwijzer zien. */
.pim-bolsectie-kop{ cursor:pointer; transition:background-color .15s ease; }
.pim-bolsectie-kop i{ transition:transform .15s ease; }
.pim-bolsectie-kop:focus-visible{ outline:2px solid var(--primary); outline-offset:-2px; }
/* Wie "minder beweging" heeft aanstaan, krijgt geen beweging. */
@media (prefers-reduced-motion:reduce){
  .pim-veld, .pim-sectie-stand, .pim-bolsectie-kop, .pim-bolsectie-kop i,
  .pim-veld-inv input, .pim-veld-inv select, .pim-veld-inv textarea{ transition:none; }
}

/* Een meerkeuzeveld met heel veel opties (02-09-2026). "Personage" bij
   bol.com heeft er 230; als losse regels duwt dat het hele formulier weg.
   Een eigen schuifvak met zoekveld houdt het op de hoogte van een gewoon
   invoerveld, en de vinkjes blijven precies wat ze waren. */
.pim-keuze-veel{ min-width:240px; max-width:340px; }
.pim-keuze-zoek{
  width:100%; font-size:12px; padding:6px 10px; margin-bottom:6px;
  border:1px solid var(--border); border-radius:var(--radius-knop);
}
.pim-keuze-lijst{
  max-height:180px; overflow-y:auto;
  border:1px solid var(--border); border-radius:var(--radius-knop);
  padding:6px 10px; display:flex; flex-direction:column; gap:6px;
}
.pim-keuze-rij{ font-size:12.5px; }
.pim-keuze-rij.verborgen{ display:none; }
.pim-keuze-scheid{ height:1px; background:var(--border); margin:6px 0; }

/* De soortsamenvatting naast de telling in de productenlijst. Grijs en niet
   rood: het is een toelichting bij het getal, geen tweede alarm. */
.pim-soorten{ font-size:11.5px; color:var(--tekst-uitleg); margin-left:6px; }

/* De balk met filters en sortering boven de productenlijst. */
.pim-lijstbalk{
  display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-bottom:10px;
}
.pim-pagineer{
  display:flex; align-items:center; gap:16px; justify-content:center;
  padding:16px 0 0; font-size:13px; color:var(--tekst-uitleg);
}
/* Het merk waar je vandaan kwam even laten oplichten. Een rand en geen
   achtergrondkleur: er staan invoervelden in, en die moeten leesbaar blijven. */
.pim-merk-gemarkeerd{ border-color:var(--primary,#2864AE); box-shadow:0 0 0 3px #EAF0F8; }

/* "Nog invullen" boven het productdetail (voorstel 2) en de doorloop eronder
   (voorstel 3). Twan: "Het systeem moet meer een invulveld/formulier worden."
   Wat er nog moet gebeuren hoort bovenaan te staan, niet verstopt achter een
   tabblad. */
.pim-gaten{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  background:#FDF6F4; border:1px solid #F1DBD5; border-radius:10px;
  padding:10px 16px; margin-top:12px;
}
.pim-gaten-kop{ font-size:13px; font-weight:600; color:#B3271A; }
.pim-gat-knop{
  display:inline-flex; align-items:center; gap:7px; font-family:inherit;
  font-size:12.5px; font-weight:600; color:#B3271A;
  background:#fff; border:1px solid #F1DBD5; border-radius:7px;
  padding:6px 10px; cursor:pointer;
}
.pim-gat-knop:hover{ border-color:#B3271A; }
.pim-gat-kanaal{ font-weight:500; color:#8A6D66; font-size:11px; }

.pim-doorloop{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  flex-wrap:wrap; margin-top:18px; padding:16px 16px;
  background:var(--card,#fff); border:1px solid var(--border); border-radius:10px;
  /* Blijft in beeld tijdens het scrollen: bij een lang formulier wil je niet
     helemaal naar beneden om naar het volgende product te gaan. */
  position:sticky; bottom:12px;
  box-shadow:0 -6px 18px rgba(20,26,34,.06);
}
/* Zonder deze ruimte gaat de balk over de laatste velden van het formulier
   heen — de Opslaan-knop verdween er precies achter. */
.pim-doorloop-ruimte{ height:86px; }

/* ---------- Artikelen koppelen aan een verzendmethode (01-09-2026) ----------
   Twan: "Ook dit zou ik in bulk moeten kunnen instellen ... Dit kan dus beter
   in een apart scherm." Eén EAN per keer intypen is onwerkbaar zodra je meer
   dan een handvol artikelen aan een methode hangt.
   Eigen overlay in plaats van .modal-overlay hierboven: die is 420px breed en
   voor korte formulieren; dit is een lijst waarin je zoekt en aanvinkt. */
.wms-overlay{ position:fixed; inset:0; background:rgba(22,34,58,0.45); z-index:60;
  display:flex; align-items:flex-start; justify-content:center; overflow-y:auto; padding:32px 16px; }
.wms-dialoog{ background:#fff; border-radius:var(--radius-kaart); box-shadow:0 8px 24px rgba(22,34,58,0.2);
  width:720px; max-width:100%; padding:24px 24px; box-sizing:border-box; }
.wms-dialoog-kop{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:14px; }
.wms-dialoog-voet{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:14px; padding-top:12px; border-top:1px solid var(--lijn, #E3E7EC); font-size:12.5px; }
.ean-beheer-stuur{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:10px; }
/* Een vaste hoogte met eigen scroll: de lijst kan honderden artikelen lang zijn
   en mag de knoppen onderaan niet van het scherm duwen. */
.ean-beheer-lijst{ max-height:46vh; overflow-y:auto; border:1px solid var(--lijn, #E3E7EC);
  border-radius:8px; padding:4px; }
.ean-beheer-rij{ display:flex; align-items:center; gap:10px; padding:6px 10px; border-radius:6px;
  font-size:12.5px; cursor:pointer; }
.ean-beheer-rij:hover{ background:var(--gray); }
.ean-beheer-rij.aan{ background:#EAF1F9; }
.ean-beheer-rij .nm{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ean-beheer-plak{ margin-top:12px; font-size:12.5px; }
.ean-beheer-plak summary{ cursor:pointer; color:var(--primary); }

/* Verzendregels: de gekozen rijen (01-09-2026). Zelfde blauw als elders in het
   WMS, zodat een selectie er overal hetzelfde uitziet. */
.data-table tr.gekozen td{ background:#EAF1F9; }

/* De locatie koppelen vanuit het Verwerken-scherm (01-09-2026).
   Twan: "Wellicht ook handig dat ik hier direct de locatie kan instellen of op
   de locatietab kom die gefilterd is om het daar in te stellen." Beide: de
   chip opent de kiezer ter plekke, en er staat een uitweg naar het
   Locaties-scherm voor als de locatie nog aangemaakt moet worden. */
button.verw-loc.geen.klikbaar{ border:none; font:inherit; cursor:pointer; display:inline-flex; align-items:center; gap:5px; }
button.verw-loc.geen.klikbaar .zet{ font-size:10px; text-transform:uppercase; letter-spacing:.05em; opacity:.75; }
button.verw-loc.geen.klikbaar:hover{ filter:brightness(.95); }
.verw-loczet{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 16px; border-top:1px solid var(--lijn, #E3E7EC); background:var(--gray); font-size:12.5px; }
/* De uitklaplijst van de locatiekiezer moet buiten het blok kunnen vallen.
   .verw-blok staat op overflow:hidden voor zijn ronde hoeken; dat knipte de
   lijst volledig weg (gemeten: 70px hoog, 2 opties, onzichtbaar). Alleen
   zolang de kiezer openstaat wordt dat losgelaten. */
.verw-blok.loc-open{ overflow:visible; }

/* EN DE UITVERGROTE PRODUCTFOTO NET ZO GOED (01-09-2026).
   Twan: "de hover over de productfoto die binnen het kader blijft bij het WMS
   verwerken." Precies dezelfde oorzaak als bij de locatiekiezer hierboven:
   .verw-blok staat op overflow:hidden voor zijn ronde hoeken, en de
   uitvergroting is 260 bij 260 en valt dus buiten de regel.

   Waarom hier :has() en geen extra class zoals bij .loc-open: die kiezer wordt
   met een klik geopend, dus daar is JavaScript in de buurt om een class te
   zetten. Deze uitvergroting is puur hover — er is geen moment waarop code
   draait. :has() laat de ouder reageren op de hover van het kind, en dat is
   exact wat hier nodig is. */
.verw-blok:has(.wms-thumb-hover:hover),
.verw-blok:has(.wms-thumb-hover:focus-within){ overflow:visible; }

/* ---- Retouren afhandelen in het WMS (01-09-2026) ----
   Twan: "Het WMS is enkel voor daadwerkelijk verwerken dus orders en retouren."
   Het blok hergebruikt .verw-blok/.verw-kop van het Verwerken-scherm, zodat
   een retour er hetzelfde uitziet als een order — het is dezelfde handeling
   met een doos in je hand. Alleen het actiedeel eronder is nieuw. */
.wms-retour-acties{ padding:0 16px 16px; }
.wms-retour-blok .retour-afhandel{ border:none; padding:0; margin:0; background:none; }
/* Een LVB-retour krijgt geen knoppen (die komt bij bol binnen, niet bij jou);
   in plaats daarvan de reden, in dezelfde rustige toon als de andere uitleg. */
.wms-retour-lvb{
  display:flex; align-items:flex-start; gap:6px;
  background:var(--gray); border-radius:var(--radius-veld);
  padding:10px 16px; font-size:12.5px; color:var(--tekst-uitleg); max-width:70ch;
}
.wms-retour-lvb i{ flex-shrink:0; margin-top:1px; }

/* De hele orderregel is de knop (01-09-2026). Twan: "waarom kan ik bij
   verwerken niet gewoon op de orderregel klikken (...) Een extra knop lijkt me
   niet nodig." Een klikbare regel moet er ook klikbaar uitzien, anders is het
   een verborgen functie. Het vinkje links houdt zijn eigen cursor: dat doet
   iets anders (selecteren voor een bulkronde). */
.verw-orij.klikbaar{ cursor:pointer; }
.verw-orij.klikbaar:hover{ background:#F3F7FC; }
.verw-orij.klikbaar input[type="checkbox"]{ cursor:default; }

/* De smalle kolommen van de paktabel krijgen precies de breedte die ze nodig
   hebben; de artikelkolom slikt de rest. Zonder dit knijpt de tabel Locatie en
   Status samen tot ze afbreken — wat Twan aan het pakstation zag. */
.pak-tabel td, .pak-tabel th{ white-space:nowrap; }
.pak-tabel td.pak-titel, .pak-tabel th.pak-artikel{ white-space:normal; width:100%; }
.pak-tabel .status-ok, .pak-tabel .status-warn, .pak-tabel .status-bad,
.pak-tabel .status-info{ white-space:nowrap; display:inline-block; }

/* De grens van een bol-verzendoptie (01-09-2026): max gewicht en afmetingen,
   zoals bol ze zelf teruggeeft. Klein en terzijde — het is een randvoorwaarde,
   geen keuze. */
.vvb-beperking{ font-size:10.5px; color:var(--tekst-uitleg); white-space:nowrap; margin-left:6px; }

/* De vier stappen van een VVB-labelaanvraag (01-09-2026). Twan vroeg naar
   wachtfeedback; bij VVB is een draaiend icoontje te weinig omdat het vier
   aanroepen achter elkaar zijn, waarvan er een bij bol pollt. Blijft hij
   hangen, dan wil je weten BIJ WELKE stap. */
.vvb-stappen{ display:flex; align-items:center; flex-wrap:wrap; margin-bottom:12px; }
.vvb-stap{ display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--tekst-uitleg); white-space:nowrap; }
.vvb-stap .bol{
  width:20px; height:20px; border-radius:999px; border:2px solid var(--border); background:#fff;
  display:inline-flex; align-items:center; justify-content:center; font-size:11px; flex:none;
}
.vvb-stap.klaar{ color:#3B6D11; }
.vvb-stap.klaar .bol{ border-color:#3B6D11; background:#EAF3DE; color:#3B6D11; }
.vvb-stap.bezig{ color:var(--primary); font-weight:600; }
.vvb-stap.bezig .bol{ border-color:var(--primary); border-top-color:transparent; animation:spin-icon .8s linear infinite; }
.vvb-lijn{ width:30px; height:2px; background:var(--border); margin:0 9px; flex:none; }
@media (prefers-reduced-motion: reduce){ .vvb-stap.bezig .bol{ animation:none; border-top-color:var(--primary); } }

/* De foutmelding bij de knop (01-09-2026), alleen in het inpakscherm.
   Twan: "weten waar ik naar de foutmelding moet zoeken." Sta je aan het
   pakstation naar één order te kijken, dan mis je een balk bovenin. Blijft
   staan tot je hem wegklikt — een melding die na vijf seconden verdwijnt is
   precies weg wanneer je opkijkt. */
.pak-fout{
  display:flex; align-items:flex-start; gap:9px; background:#FAECE7; color:#B3271A;
  border-radius:8px; padding:10px 16px; font-size:13px; margin-bottom:11px; line-height:1.5;
}
.pak-fout span{ flex:1; min-width:0; overflow-wrap:anywhere; }
.pak-fout-x{
  border:none; background:none; color:#B3271A; font-size:17px; line-height:1;
  cursor:pointer; padding:0 2px; flex:none; opacity:.7;
}
.pak-fout-x:hover{ opacity:1; }

/* BTW per land — de optie onder de tariefknoppen (03-09-2026).
   Twan: "Voeg de optie om BTW per land in te stellen maar als optie toe voor
   later." Standaard uit; dan is dit één regel met een vinkje en de uitleg
   waarom het uit mag staan. Aan gezet groeit het naar één regel per land.
   Kolombreedtes vast, zodat de percentages en bedragen recht onder elkaar
   staan i.p.v. te schuiven met de lengte van de landcode. */
.btw-perland { flex-direction: column; align-items: stretch; gap: 6px; }
.btw-perland-schakelaar {
  display: flex; align-items: center; gap: 6px;
  font-weight: 600; cursor: pointer;
}
.btw-land-lijst { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
.btw-land-regel { display: flex; align-items: center; gap: 10px; }
.btw-land-code {
  width: 32px; font-weight: 600;
  /* Cijfers en codes recht onder elkaar; zie de andere tabellen. */
  font-variant-numeric: tabular-nums;
}
.btw-land-tarief {
  width: 72px; text-align: right;
  font-size: 12px; padding: 6px 10px;
  border-radius: var(--radius-veld); border: none;
  background: var(--gray); color: #000;
  font-variant-numeric: tabular-nums;
}
.btw-land-aandeel { font-variant-numeric: tabular-nums; }

/* Shopify-categorievelden in het PIM (03-09-2026).
   Twan: "De Category metafields hebben allemaal al vooraf gedefinieerde opties
   en dus veel meer dan 9 kleuren." Ontwerp goedgekeurd: eigen waarden bovenaan
   (hij maakt ze in het Nederlands aan), Shopify's lijst ingeklapt eronder. */
.pim-cat-hoofd { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.pim-cat-veld { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px; }
.pim-cat-kop { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.pim-cat-label { font-size: 11px; color: var(--tekst-uitleg); margin: 8px 0 4px; }
.pim-cat-rij { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.pim-cat-meer { margin-top: 8px; }

/* Eén waarde. Gekozen is gevuld, beschikbaar is omlijnd, en een waarde die
   nog niet in de winkel bestaat krijgt een stippellijn — die wordt bij het
   kiezen namelijk eerst aangemaakt. */
.pim-cat-waarde {
  font: inherit; font-size: 12px; cursor: pointer;
  padding: 6px 10px; border-radius: var(--radius-veld);
  border: 1px solid var(--border); background: transparent; color: var(--tekst-uitleg);
  display: inline-flex; align-items: center; gap: 5px;
}
.pim-cat-waarde:hover { border-color: var(--secondary); color: inherit; }
.pim-cat-waarde.gekozen { background: var(--primary); border-color: var(--primary); color: #fff; }
.pim-cat-waarde.nieuw { border-style: dashed; }
.pim-cat-waarde.eigen { border-style: dashed; border-color: var(--secondary); color: var(--secondary); }
.pim-cat-stip { width: 9px; height: 9px; border-radius: 50%; border: 1px solid var(--border); display: inline-block; }

.pim-cat-vlag { font-size: 11px; padding: 2px 6px; border-radius: var(--radius-veld); }
.pim-cat-vlag.ingevuld { background: var(--gray); color: var(--tekst-uitleg); }
/* Dezelfde tinten als de analysebanner elders in de app (5,43 op wit), zodat
   dit geen nieuw kleurtje introduceert. */
.pim-cat-vlag.deelt { background: #FAEEDA; color: var(--warning); }
.pim-cat-zoek {
  font-size: 12px; padding: 6px 10px; margin: 6px 0;
  border-radius: var(--radius-veld); border: none; background: var(--gray); color: #000;
  width: 100%; max-width: 320px; box-sizing: border-box;
}
.pim-cat-leeg { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 10px; }

/* Een afgekeurde veldwaarde hoort bij het veld te staan, niet 6 seconden
   bovenaan het scherm (opdrachtgever 04-09). Zelfde rood als de overige
   foutmeldingen in de app. */
.pim-veld-fout{
  font-size: 11px; color: var(--danger); margin-top: 4px; line-height: 1.35;
}

/* De collectielijst van een Shopify-winkel (41 stuks bij Twan) past niet
   zomaar onder elkaar: kolommen die meelopen met de breedte, en een eigen
   schuifbalk zodat de rest van het tabblad bereikbaar blijft. */
.pim-org-collecties{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 4px 14px; max-height: 220px; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-veld); padding: 10px;
}

/* Een gekozen collectie moet je kunnen zien zonder de vinkjes af te speuren
   (opdrachtgever 04-09: "0.0 feedback of iets daadwerkelijk geselecteerd
   is"). Gekozen collecties staan bovenaan en krijgen hier het gewicht. */
.pim-org-collectie.gekozen{ font-weight: 500; }

/* ---------- Afbeeldingen: slepen en uploaden (opdrachtgever 04-09-2026) ----
   Twan: "Afbeeldingen is klein en summier. Kan dat een drag and drop systeem
   worden net als shopify? Ook slepen om afbeeldingen te uploaden en een
   voortgangsbalk zou handig zijn bij de centrale pool." */

/* De voortgangsbalk toont echte bytes (XMLHttpRequest upload.onprogress),
   niet een sprongetje per bestand. */
.pim-upload-balk{
  height: 6px; border-radius: 3px; background: var(--gray); overflow: hidden;
}
.pim-upload-balk-vul{
  height: 100%; background: var(--primary); transition: width .12s linear;
}

/* De centrale pool is in zijn geheel de sleepzone, ook als hij leeg is —
   juist dan wil je er iets in kunnen laten vallen. */
.pim-pool{
  border: 1px dashed var(--border); border-radius: var(--radius-veld);
  padding: 10px; transition: background .12s ease, border-color .12s ease;
}
.pim-pool.sleep{ border-color: var(--primary); background: var(--gray); }
.pim-pool-raster{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px;
}
.pim-pool-kaart{
  border: 1px solid var(--border); border-radius: var(--radius-veld);
  padding: 10px; background: #fff;
}
.pim-pool-hint{
  display: flex; align-items: center; justify-content: center; gap: 8px;
  color: var(--tekst-uitleg); font-size: 12px; padding: 16px 10px 6px;
}
.pim-pool-hint .ti{ font-size: 16px; }

/* Per kanaal: dezelfde kaarten, maar versleepbaar. De pijltjesknoppen blijven
   staan — slepen werkt niet met een toetsenbord. */
.pim-kan-raster{
  display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 12px;
}
.pim-kan-kaart{
  border: 1px solid var(--border); border-radius: var(--radius-veld);
  padding: 10px; background: #fff; cursor: grab; position: relative;
}
.pim-kan-kaart:active{ cursor: grabbing; }
.pim-kan-kaart.sleept{ opacity: .4; }
.pim-kan-kaart.sleep-doel{ border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary) inset; }
/* Het volgnummer: zonder dat zie je bij het slepen niet wat er verschuift. */
.pim-kan-plek{
  font-size: 10.5px; color: var(--tekst-uitleg); margin-bottom: 4px;
}
.pim-kan-knoppen{
  display: flex; gap: 4px; margin-top: 6px; flex-wrap: wrap;
}

/* ---------- Adverteren: sturen op zoekwoorden (opdrachtgever 04-09-2026) ----
   Twan vroeg om overzicht: sorteren, onderbouwing, berekeningen, goede
   knoppen en genoeg witruimte. De maten volgen de ladder 6/10/16/24/32. */
.adv-wissel{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-bottom:16px; }
.adv-tab{ font:inherit; font-size:12.5px; font-weight:500; padding:6px 10px; cursor:pointer;
  border:1px solid var(--border); background:var(--white); color:var(--tekst-uitleg);
  border-radius:var(--radius-knop); }
.adv-tab.aan{ background:var(--secondary); border-color:var(--secondary); color:#fff; }
.adv-ververs{ margin-left:auto; }

.adv-accounts{ display:flex; gap:10px; flex-wrap:wrap; margin-bottom:6px; }
.adv-account{ font:inherit; text-align:left; cursor:pointer; padding:10px 16px; min-width:150px;
  border:1px solid var(--border); background:var(--white); border-radius:var(--radius-veld);
  display:flex; flex-direction:column; gap:1px; }
.adv-account.aan{ border-color:var(--secondary); box-shadow:inset 0 -2px 0 var(--secondary); }
.adv-account .n{ font-size:12px; color:var(--tekst-uitleg); }
.adv-account .a{ font-size:17px; font-weight:600; font-variant-numeric:tabular-nums; }
.adv-account .k{ font-size:11.5px; color:var(--tekst-uitleg); }
.adv-noot{ font-size:12px; color:var(--tekst-uitleg); margin-bottom:16px; }

.adv-doel{ padding:16px 24px; margin-bottom:16px; display:grid;
  grid-template-columns:minmax(0,1fr) auto; gap:24px; align-items:center; }
.adv-doel-kop{ font-size:11.5px; color:var(--tekst-uitleg); text-transform:uppercase; letter-spacing:.04em; margin-bottom:6px; }
.adv-doel-regel{ font-size:15px; }
.adv-doelveld{ width:56px; font:inherit; font-size:15px; font-weight:600; text-align:right;
  border:none; background:var(--gray); border-radius:var(--radius-veld); padding:6px 6px; }
.adv-doel-uit{ font-size:12px; color:var(--tekst-uitleg); margin-top:6px; max-width:62ch; }
.adv-doel-cijfers{ display:flex; gap:24px; flex-wrap:wrap; }
.adv-doel-cijfers > div{ display:flex; flex-direction:column; }
.adv-doel-cijfers .l{ font-size:11.5px; color:var(--tekst-uitleg); }
.adv-doel-cijfers .v{ font-size:18px; font-weight:600; font-variant-numeric:tabular-nums; }
.adv-doel-cijfers .v.over{ color:var(--danger); }

.adv-kaart{ padding:0; margin-bottom:16px; }
.adv-kaart-kop{ padding:16px 24px 10px; display:flex; align-items:baseline; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.adv-kaart-kop h3{ margin:0; font-size:14px; font-weight:600; }

/* Voorstellen: bedrag links, uitleg midden, actie rechts. De rekensom zit in
   een <details>, zodat de lijst kort blijft maar niets verborgen is. */
.adv-voorstel{ display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:16px;
  align-items:start; padding:16px 24px; border-top:1px solid var(--border); }
.adv-bedrag{ font-size:15px; font-weight:600; font-variant-numeric:tabular-nums; text-align:right; min-width:82px; padding-top:1px; }
.adv-bedrag.win{ color:#3B6D11; }
.adv-bedrag.geen{ color:var(--tekst-uitleg); }
.adv-voorstel-kop{ font-size:13px; font-weight:500; }
.adv-voorstel-uitleg{ font-size:12px; color:var(--tekst-uitleg); margin-top:2px; }
.adv-rekening{ margin-top:8px; }
.adv-rekening summary{ font-size:12px; color:var(--primary); cursor:pointer; }
.adv-rekentabel{ margin-top:6px; border-collapse:collapse; font-size:12px; width:100%; }
.adv-rekentabel td{ padding:6px 10px 6px 0; vertical-align:top; color:var(--tekst-uitleg); }
.adv-rekentabel td:first-child{ color:var(--secondary); white-space:nowrap; max-width:280px; overflow:hidden; text-overflow:ellipsis; }
.adv-meer{ font-size:12px; color:var(--tekst-uitleg); padding:10px 24px; }
.adv-leeg{ font-size:12.5px; color:var(--tekst-uitleg); padding:16px 24px; border-top:1px solid var(--border); }

.adv-filters{ display:flex; gap:6px; padding:0 24px 12px; flex-wrap:wrap; align-items:center; }
.adv-zoek{ flex:1 1 240px; min-width:200px; margin:0; max-width:340px; }
.adv-chip{ font:inherit; font-size:11.5px; padding:6px 10px; cursor:pointer;
  border:1px solid var(--border); background:var(--white); color:var(--tekst-uitleg); border-radius:999px; }
.adv-chip.aan{ background:var(--secondary); border-color:var(--secondary); color:#fff; }

.adv-camptabel th.adv-sorteer{ cursor:pointer; user-select:none; }
.adv-camptabel th.adv-sorteer.aan{ color:var(--secondary); }
.adv-rij{ cursor:pointer; }
.adv-rij.open{ background:var(--gray); }
.adv-naam{ font-weight:500; display:block; }
.adv-id{ font-size:11px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; }
.adv-naamcel{ max-width:300px; }
.adv-camptabel td.num{ white-space:nowrap; }
.adv-nwmelding{ margin-top:10px; font-size:var(--tekst-bijschrift); }
.adv-as-invoer{ display:flex; gap:10px; padding:0 24px 10px; }
.adv-as-invoer input{ flex:1 1 auto; margin:0; max-width:none; }
.adv-as-chips{ padding-bottom:16px; }
.adv-as-antwoord{ padding:16px 24px; border-top:1px solid var(--border); font-size:var(--tekst-tabel); }
.adv-as-vraag{ font-weight:600; margin-bottom:6px; }
.adv-as-zin{ margin-bottom:6px; line-height:1.5; }
.adv-as-tabel{ margin-top:10px; }
.adv-as-voorstel{ margin-top:10px; padding:10px 16px; border:1px solid var(--border); border-radius:var(--radius-veld); }
.adv-tw-blok{ padding:16px 24px; border-bottom:1px solid var(--border); }
.adv-tw-kop{ display:flex; gap:10px; align-items:baseline; flex-wrap:wrap; margin-bottom:6px; font-size:var(--tekst-tabel); }
.adv-tw-chips{ padding:10px 0 0; }
.adv-tw-test{ display:flex; gap:6px; align-items:center; padding:6px 10px; border-radius:var(--radius-veld); font-size:var(--tekst-bijschrift);
  background:var(--letop-vlak); color:var(--letop-tekst); }
.adv-sub{ display:block; font-size:var(--tekst-bijschrift); color:var(--tekst-uitleg); font-weight:400; }
.adv-koopblok{ display:inline-flex; align-items:center; gap:4px; margin:4px 0 0; padding:2px 6px; border-radius:var(--radius-veld);
  font-size:var(--tekst-bijschrift); background:var(--letop-vlak); color:var(--letop-tekst); }
.adv-acos{ font-weight:600; font-variant-numeric:tabular-nums; }
.adv-acos.over{ color:var(--danger); }
.adv-acos.onder{ color:#3B6D11; }
.adv-acos.leeg{ color:var(--tekst-uitleg); font-weight:400; }
.adv-doelbij{ font-size:11.5px; color:var(--tekst-uitleg); }
.adv-open > td{ background:var(--gray); padding:0; }
.adv-open-binnen{ padding:16px 24px; }
.adv-open-kop{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
.adv-zw{ background:var(--white); }
.adv-onderbod{ color:#3B6D11; font-weight:600; }

/* ---------------------------------------------------------------------------
   De vijf nieuwe adverteerschermen (ontwerp goedgekeurd 05-09-2026).
   Kleuren komen uit de bestaande tokens; het groen is hetzelfde #3B6D11 dat
   .adv-acos.onder al gebruikt. Geen ingekleurde randen om witte vlakken, zoals
   de regel bovenaan dit bestand voorschrijft. */

.adv-uitleg{ font-size:12.5px; color:var(--tekst-uitleg); line-height:1.55;
  padding:10px 16px; background:var(--gray); border-radius:8px; margin:0 0 12px; }
.adv-uitleg b{ color:var(--tekst); }
.adv-setvraag{ display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; }
.adv-setvraag-tekst .tag-muted{ display:block; }
.adv-setvraag-knoppen{ display:flex; align-items:center; }
.adv-gemist-regel, .adv-gemist-detail{ margin-top:var(--afstand-s, 6px); font-size:inherit; }
.adv-gemist-detail summary{ cursor:pointer; }
.adv-gemist-detail code{ display:block; margin-top:var(--afstand-s, 6px); white-space:pre-wrap; word-break:break-all; color:var(--tekst-zacht); }
.adv-voet{ font-size:12px; color:var(--tekst-uitleg); padding:10px 0 0;
  display:flex; gap:10px; align-items:center; flex-wrap:wrap; }

/* Vlaggetjes: dezelfde drie betekenissen als elders in de app. */
.adv-vlag{ display:inline-block; padding:2px 10px; border-radius:999px; font-size:11px;
  font-weight:500; white-space:nowrap; background:var(--gray); color:var(--tekst-uitleg); }
.adv-vlag.goed{ background:#EAF3DE; color:#3B6D11; }
.adv-vlag.op{ background:#FAEEDA; color:var(--warning); }
.adv-vlag.slecht{ background:#F6E7E1; color:var(--danger); }

/* Status van een campagne: drie toestanden, met een stip ervoor zodat je hem
   in een lange tabel op kleur terugvindt. */
.adv-status{ display:inline-flex; align-items:center; gap:6px; font-size:11.5px; white-space:nowrap; }
.adv-status::before{ content:''; width:7px; height:7px; border-radius:50%; background:#3B6D11; flex:0 0 auto; }
.adv-status.pauze{ color:var(--tekst-uitleg); }
.adv-status.pauze::before{ background:#C9CFD8; }
.adv-status.archief{ color:var(--tekst-uitleg); }
.adv-status.archief::before{ background:transparent; box-shadow:inset 0 0 0 1.5px #C9CFD8; }
.adv-status.beperkt{ color:var(--warning); }
.adv-status.beperkt::before{ background:var(--warning); }

.adv-rij-uit{ opacity:.5; }
.adv-vink{ width:15px; height:15px; }

/* Tijdlijn van het wijzigingslogboek: één verticale lijn, een stip per
   wijziging. Oranje wanneer het buiten dit scherm gebeurde, rood wanneer het
   misging — dat onderscheid is het hele punt van dat scherm. */
.adv-tijdlijn{ position:relative; padding:4px 0 4px 24px; }
.adv-tijdlijn::before{ content:''; position:absolute; left:5px; top:10px; bottom:10px;
  width:1px; background:var(--border); }
.adv-beurt{ position:relative; padding:10px 0; }
.adv-beurt + .adv-beurt{ border-top:1px solid var(--border); }
.adv-beurt::before{ content:''; position:absolute; left:-23px; top:17px; width:9px; height:9px;
  border-radius:50%; background:var(--secondary); box-shadow:0 0 0 3px var(--white); }
.adv-beurt.buiten::before{ background:var(--warning); }
.adv-beurt.mislukt::before{ background:var(--danger); }
.adv-wanneer{ font-size:11px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; }
.adv-wat{ font-size:12.5px; font-weight:500; margin-top:1px; }
.adv-waar{ font-size:12px; color:var(--tekst-uitleg); margin-top:2px; }
.adv-van{ text-decoration:line-through; font-variant-numeric:tabular-nums; }
.adv-naar{ font-weight:600; color:var(--tekst); font-variant-numeric:tabular-nums; }
.adv-bronvlag{ display:inline-block; font-size:10.5px; padding:1px 6px; border-radius:999px;
  margin-left:6px; vertical-align:1px; background:var(--gray); color:var(--tekst-uitleg); }
.adv-bronvlag.voorstel{ background:#E7EEF7; color:var(--secondary); }
.adv-bronvlag.buiten{ background:#FAEEDA; color:var(--warning); }

/* Metriekkiezer boven de advertentiegrafiek: eerst een paar kiezen, dan de
   tegels met de standen. De twee gekozen tegels zijn de twee lijnen. */
.adv-metriekrij{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:10px; }
.adv-metriek{ font:inherit; font-size:12px; padding:6px 10px; cursor:pointer;
  border:1px solid var(--border); background:var(--white); color:var(--tekst-uitleg);
  border-radius:var(--radius-knop, 5px); white-space:nowrap; }
.adv-metriek.aan{ background:var(--tekst); border-color:var(--tekst); color:#fff; }

.adv-tegels{ display:grid; grid-template-columns:repeat(8,minmax(0,1fr)); gap:6px; margin-bottom:16px; }
.adv-tegel{ font:inherit; text-align:left; cursor:pointer; padding:10px;
  border:none; border-bottom:2px solid var(--border); border-radius:6px;
  background:var(--white); box-shadow:inset 0 0 0 1px var(--border); }
.adv-tegel.aan{ border-bottom-color:var(--tegelkleur); box-shadow:inset 0 0 0 1.5px var(--tegelkleur); }
.adv-tegel .w{ display:block; font-size:15px; font-weight:600; color:var(--tekst);
  font-variant-numeric:tabular-nums; }
.adv-tegel .n{ display:block; font-size:11px; color:var(--tekst-uitleg); margin-top:1px; }
.adv-tegel.aan .n{ color:var(--tegelkleur); }
@media (max-width:1100px){ .adv-tegels{ grid-template-columns:repeat(4,minmax(0,1fr)); } }

/* Prioriteitslabel bij een voorstel. Rood = er loopt nu geld weg, oranje = er
   valt geld te halen, grijs = opruimen. De kleur zegt hetzelfde als het cijfer,
   zodat je het ook ziet zonder te lezen. */
.adv-prio{ display:inline-block; font-size:10.5px; font-weight:600; padding:1px 6px;
  border-radius:999px; margin-right:6px; vertical-align:1px; white-space:nowrap; }
.adv-prio.p1{ background:#F6E7E1; color:var(--danger); }
.adv-prio.p2{ background:#FAEEDA; color:var(--warning); }
.adv-prio.p3{ background:var(--gray); color:var(--tekst-uitleg); }

/* ACoS-cel met balkje: groen onder je doel, oranje eroverheen, rood als het
   ver eroverheen is, en apart voor kosten zonder omzet. Het streepje in het
   midden van het balkje is je doel. */
.adv-acos-cel{ display:inline-flex; align-items:center; gap:8px; justify-content:flex-end; }
.adv-acos-cel .b{ width:52px; height:5px; border-radius:3px; background:var(--border);
  position:relative; flex:0 0 auto; overflow:visible; }
.adv-acos-cel .b i{ position:absolute; top:0; bottom:0; left:0; border-radius:3px; }
.adv-acos-cel .b u{ position:absolute; top:-3px; bottom:-3px; width:1px; background:var(--tekst); opacity:.35; }
.adv-acos-cel .v{ font-weight:600; font-variant-numeric:tabular-nums; }
.adv-acos-cel.onder .b i{ background:#3B6D11; } .adv-acos-cel.onder .v{ color:#3B6D11; }
.adv-acos-cel.over .b i{ background:var(--warning); } .adv-acos-cel.over .v{ color:var(--warning); }
.adv-acos-cel.ver-over .b i{ background:var(--danger); } .adv-acos-cel.ver-over .v{ color:var(--danger); }
.adv-acos-cel.geen{ color:var(--danger); font-weight:600; font-size:11.5px; }

/* Nieuwe producten: familie met varianten eronder. De inspringing zegt dat de
   variant bij de familie erboven hoort. */
.adv-artikel{ display:flex; gap:10px; align-items:center; }
.adv-artikel .t{ line-height:1.35; min-width:0; }
.adv-artikel .e{ font-size:11px; color:var(--tekst-uitleg); font-variant-numeric:tabular-nums; }
.adv-familie-kop > td{ background:var(--gray); }
.adv-inspring{ display:inline-block; width:16px; }

/* Aan de slag (opdracht 06-09-2026, onderdeel 1): voortgangsbalk en
   groepskopjes. Hergebruikt verder de bestaande kaarten, tabellen en vlaggen. */
.aandeslag-balk{ height:6px; border-radius:3px; background:var(--border); overflow:hidden; margin-top:10px; }
.aandeslag-balk i{ display:block; height:100%; background:#3B6D11; transition:width .2s; }
.aandeslag-groep{ font-size:12px; font-weight:600; color:var(--tekst-uitleg);
  margin:16px 0 6px; text-transform:uppercase; letter-spacing:.04em; }

/* ---------- Inhoud en prijs per stuk (06-09-2026, onderdeel 3) ----------
   De inhoud is aan te klikken om hem zelf in te vullen; dat moet je zien
   zonder erover te hoeven hoveren. Een onbekende inhoud ("?") krijgt daarom
   een stippellijn: hij vraagt om aandacht zonder als fout te schreeuwen. */
.conc-inhoud{
  background:none; border:1px solid transparent; border-radius:6px;
  padding:2px 6px; font:inherit; color:inherit; cursor:pointer;
  white-space:nowrap;
}
.conc-inhoud:hover{ border-color:var(--border); background:var(--hover-bg); }
.conc-inhoud.leeg{
  border:1px dashed var(--border); color:var(--muted);
  min-width:34px; text-align:center;
}
.conc-inhoud.leeg:hover{ border-style:solid; color:var(--text); }
.conc-inhoud .ti{ font-size:11px; opacity:.55; }
/* Het vraagteken achter een positie die op totaalprijs is berekend. */
.conc-vraag{
  display:inline-block; margin-left:3px; padding:0 4px;
  border-radius:8px; background:var(--hover-bg); color:var(--muted);
  font-size:10.5px; font-weight:600;
}

/* Uitverkochte bestsellers op Aanvullen (06-09-2026, onderdeel 4).
   Rood, want dit kost elke dag geld — maar in de regel zelf en niet als
   losse waarschuwingsbalk: de lijst zelf is de melding. */
.pil-uitverkocht{
  display:inline-block; margin-left:6px; padding:1px 6px;
  border-radius:9px; background:#F6E4DE; color:#993C1D;
  font-size:10.5px; font-weight:600; letter-spacing:.01em;
}

/* Bewust offline (06-09-2026, onderdeel 6).
   Drie toestanden met drie kleuren: door jou gekozen (rustig), voorgesteld
   (aandacht, geen alarm) en weer live (goed nieuws). Geen rood — rood is hier
   al bezet door "onbedoeld offline", en dat is precies wat deze pillen NIET
   zijn. */
.pil-bewust, .pil-voorstel, .pil-weerlive{
  display:inline-block; margin-top:3px; padding:1px 6px;
  border-radius:9px; font-size:10.5px; font-weight:600;
}
.pil-bewust  { background:var(--hover-bg); color:var(--muted); }
.pil-voorstel{ background:#FBF0DC; color:#7A5209; cursor:help; }
.pil-weerlive{ background:#E7F0DE; color:#3B6D11; }

/* ---------- Productpagina per EAN (07-09-2026, onderdeel 2) ----------
   De kop: foto links, gegevens in het midden, uitgaande links rechts. Bij een
   smal scherm klapt hij onder elkaar; de foto blijft dan bovenaan staan omdat
   je daaraan het snelst ziet welk artikel je voor je hebt. */
.artikel-kop{
  display:flex; gap:16px; align-items:flex-start; padding:16px;
}
.artikel-kop-links{ flex:0 0 auto; }
.artikel-kop-midden{ flex:1 1 auto; min-width:0; }
.artikel-kop-rechts{ display:flex; flex-direction:column; gap:6px; align-items:flex-end; flex:0 0 auto; }
.artikel-voortgang{ display:flex; align-items:center; gap:10px; margin-top:10px; max-width:420px; }
.artikel-voortgang .aandeslag-balk{ flex:1 1 auto; margin:0; }
@media (max-width:760px){
  .artikel-kop{ flex-wrap:wrap; }
  .artikel-kop-rechts{ align-items:flex-start; width:100%; flex-direction:row; flex-wrap:wrap; }
}
.kanaal-pil{
  display:inline-block; padding:0 6px; border-radius:8px;
  background:var(--hover-bg); color:var(--muted); font-size:10.5px; font-weight:600;
}

/* Een EAN of productnaam die naar de productpagina gaat. Ziet eruit als een
   link maar is een knop: de app vangt de navigatie zelf af, en een echte
   <a href> zou de hele pagina herladen. */
.artikel-link{
  background:none; border:0; padding:0; margin:0; font:inherit; color:inherit;
  cursor:pointer; text-align:left; text-decoration:none;
  border-bottom:1px dotted var(--border);
}
.artikel-link:hover{ color:var(--primary); border-bottom-color:var(--primary); }

/* ---------------------------------------------------------------------------
   CONCURRENTIETRACKER — overzicht, badges en samenvatting (onderdeel 3,
   07-09-2026). Kleuren uit de bestaande statuspalet van dit bestand, zodat een
   "groen" hier hetzelfde groen is als op het dashboard. */

/* De conclusie in één woord. Vier kleuren, en grijs voor "we weten het niet" —
   dat laatste is bewust kleurloos: een grijze badge nodigt niet uit tot
   handelen, en dat klopt, want eerst moet de inhoud ingevuld worden. */
.conc-badge{display:inline-block;padding:2px 10px;border-radius:11px;font-size:11px;
  font-weight:600;white-space:nowrap;line-height:1.5;}
.conc-badge.groen{background:#E4F3EA;color:#1E7A46;}
.conc-badge.blauw{background:#E7EFFC;color:#2F6FEB;}
.conc-badge.oranje{background:#FFF2DC;color:#8A6410;}
.conc-badge.rood{background:#FAECE7;color:#993C1D;}
.conc-badge.grijs{background:#EFEFEF;color:#666;}

/* De kaarten bovenaan zijn knoppen: erop klikken filtert de lijst eronder.
   Daarom krijgen ze een aanwijzer en een duidelijke actieve staat — een kaart
   die filtert maar er niet klikbaar uitziet wordt niet gevonden. */
.conc-kaarten .conc-kaart{cursor:pointer;text-align:left;font:inherit;border:1px solid transparent;}
.conc-kaarten .conc-kaart:hover{border-color:#D5D5D5;}
.conc-kaarten .conc-kaart.actief{border-color:#2F6FEB;box-shadow:0 0 0 1px #2F6FEB inset;}

.conc-filterbalk{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:12px 0 8px;}
.conc-zoek{flex:0 1 260px;padding:6px 10px;border:1px solid #DDD;border-radius:7px;font-size:12.5px;}

.conc-overzicht .conc-ov-rij{cursor:pointer;}
.conc-overzicht .conc-ov-rij:hover{background:#F7F9FC;}
.conc-overzicht td.num,.conc-overzicht th.num{text-align:right;font-variant-numeric:tabular-nums;}

/* De sparkline erft zijn kleur van deze regel, zodat de lijn met de richting
   meekleurt: omhoog is ruimte in de markt, omlaag is prijsdruk. */
.conc-spark{display:block;color:#8A8A8A;}
.conc-spark.op{color:#1E7A46;}
.conc-spark.neer{color:#993C1D;}

.pil-nieuw{display:inline-block;padding:1px 6px;border-radius:10px;background:#FFF2DC;
  color:#8A6410;font-size:10.5px;font-weight:600;}

/* De detailpagina van één artikel. */
.conc-detail-kop{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;
  background:#FFF;border:1px solid #EAEAEA;border-radius:10px;padding:16px;}
.conc-detail-foto{width:60px;height:60px;object-fit:contain;border-radius:7px;background:#F6F6F6;flex:0 0 auto;}
.conc-detail-titel{flex:1 1 240px;min-width:0;}
.conc-detail-prijs{flex:0 0 auto;text-align:right;min-width:150px;}
.conc-detail-bedrag{font-size:21px;font-weight:650;line-height:1.2;}

/* De samenvatting. Een randje links in plaats van een gevulde blok: hij hoort
   op te vallen als tekst om te lezen, niet als waarschuwing. Het onderscheid
   AI/vast zit in die kleur, en staat er bovendien in woorden bij. */
.conc-samenvatting{margin-top:16px;padding:10px 16px;border-radius:9px;
  border:1px solid #EAEAEA;border-left:3px solid #BBB;background:#FFF;}
.conc-samenvatting.ai{border-left-color:#2F6FEB;}
.conc-samenvatting-kop{display:flex;align-items:center;gap:6px;font-size:11.5px;
  font-weight:600;text-transform:uppercase;letter-spacing:.03em;color:#666;margin-bottom:7px;}
.conc-samenvatting-tekst{margin:0 0 6px;font-size:13.5px;line-height:1.6;max-width:68ch;}

.conc-grafiek{border:1px solid #EAEAEA;border-radius:9px;padding:10px 10px 4px;
  background:#FFF;overflow-x:auto;}

.conc-schakelaar{display:flex;align-items:center;gap:8px;margin:8px 0 4px;font-size:12.5px;cursor:pointer;}
.conc-schakelaar input{margin:0;}


/* Share of voice: twee balken per categorie (onderdeel 4, 07-09-2026).
   Vertoningsaandeel en klikaandeel onder elkaar, zodat het verschil ertussen
   het ding is dat je ziet — dat verschil is namelijk het signaal, niet de
   losse hoogte van een van de twee. */
.sov-lijst{display:flex;flex-direction:column;gap:10px;}
.sov-rij{display:grid;grid-template-columns:minmax(120px,1.4fr) minmax(140px,3fr) minmax(110px,auto);
  gap:10px;align-items:center;}
.sov-naam{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sov-balken{display:flex;flex-direction:column;gap:3px;}
.sov-balk{position:relative;height:10px;background:#F0F1F3;border-radius:5px;}
.sov-vul{position:absolute;inset:0 auto 0 0;border-radius:5px;}
.sov-vul.vert{background:#B9CDE6;}
.sov-vul.klik{background:#2F6FEB;}
.sov-cijfer{position:absolute;right:6px;top:-3px;font-size:9.5px;font-variant-numeric:tabular-nums;color:#555;}
.sov-oordeel{font-size:11.5px;text-align:right;}
.sov-legenda{display:flex;gap:16px;font-size:10.5px;color:#777;margin-top:2px;}
.sov-punt{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:4px;}
.sov-punt.vert{background:#B9CDE6;}
.sov-punt.klik{background:#2F6FEB;}

/* Voorgestelde zoektermen (onderdeel 4, 07-09-2026). Aanvinken, niet
   verslepen: het is een keuze uit een lijst, en een lijst met vinkjes is
   sneller te doorlopen dan losse knoppen. */
.voorstel-lijst{display:flex;flex-direction:column;gap:2px;max-height:320px;overflow-y:auto;}
.voorstel-rij{display:flex;align-items:center;gap:10px;padding:6px;border-radius:6px;cursor:pointer;}
.voorstel-rij:hover{background:#F7F9FC;}
.voorstel-term{font-size:12.5px;font-weight:500;}
.voorstel-bron{font-size:10.5px;margin-left:auto;text-align:right;}

/* Instellingen → Meldingen (onderdeel 5, 07-09-2026). Een vinkje met een
   uitleg eronder: zonder die uitleg weet je bij de helft van de soorten niet
   waar je ja tegen zegt. */
.meld-lijst{display:flex;flex-direction:column;gap:2px;margin-top:6px;}
.meld-rij{display:flex;align-items:flex-start;gap:10px;padding:10px;border-radius:6px;cursor:pointer;}
.meld-rij:hover{background:#F7F9FC;}
.meld-rij input{margin-top:2px;}
.meld-rij > span{display:flex;flex-direction:column;gap:2px;}
.meld-label{font-size:13px;font-weight:600;display:flex;align-items:center;gap:6px;}
.meld-ernst{font-size:10px;font-weight:600;padding:1px 6px;border-radius:10px;text-transform:uppercase;letter-spacing:.03em;}
.meld-ernst.hoog{background:#FAECE7;color:#993C1D;}
.meld-ernst.midden{background:#FFF2DC;color:#8A6410;}
.meld-ernst.laag{background:#EFEFEF;color:#666;}

/* PIM: "Klaar voor" per kanaal en de winst per taak (onderdeel 6, 07-09-2026).
   Twee balken naast elkaar in plaats van één totaalpercentage: compleet voor
   álle kanalen is een eis die niemand stelt, klaar voor bol is dat wel. */
.pim-klaarvoor{display:flex;flex-direction:column;gap:6px;margin:10px 0 16px;}
.pim-kv-rij{display:grid;grid-template-columns:minmax(120px,auto) 1fr minmax(90px,auto);
  gap:10px;align-items:center;font-size:12.5px;}
.pim-kv-naam{font-weight:600;}
.pim-kv-balk{position:relative;height:8px;background:#F0F1F3;border-radius:4px;overflow:hidden;}
.pim-kv-balk i{position:absolute;inset:0 auto 0 0;border-radius:4px;}
.pim-kv-balk i.goed{background:#1E7A46;}
.pim-kv-balk i.half{background:#2F6FEB;}
.pim-kv-balk i.laag{background:#D9AE5A;}
.pim-kv-cijfer{text-align:right;font-variant-numeric:tabular-nums;}
.pim-winst{color:#1E7A46;}

/* PIM: de voorgestelde beschrijving per familie (onderdeel 6, 07-09-2026).
   Een randje links in plaats van een gevuld blok, en het woord "concept" in de
   kop: dit is klanttekst die nog niet ergens staat, en dat moet je zien. */
.pim-voorstel{margin-top:10px;padding:10px 16px;border:1px solid #EAEAEA;
  border-left:3px solid #2F6FEB;border-radius:9px;background:#FFF;}
.pim-voorstel-kop{display:flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;
  text-transform:uppercase;letter-spacing:.03em;color:#666;margin-bottom:7px;}
.pim-voorstel-tekst{margin:0 0 6px;font-size:13.5px;line-height:1.6;max-width:68ch;white-space:pre-wrap;}
.pim-voorstel-droog{margin-top:10px;padding:10px;border-radius:6px;background:#F7F9FC;font-size:12.5px;}

/* "t/m 14:32" naast de periodeknoppen (onderdeel 7, 07-09-2026). Klein en
   grijs: het is een voetnoot bij de cijfers, geen knop. */
.period-tot{margin-left:auto;align-self:center;font-size:11.5px;color:#888;
  font-variant-numeric:tabular-nums;white-space:nowrap;}

/* "Vraagt aandacht": werkruimte en pijl in de knop (onderdeel 7, 07-09-2026).
   De pijl is er om te laten zien dat de regel érgens heen gaat — dat was
   precies wat ontbrak bij de meldingen zonder bestemming. */
.dash-aandacht-wr{margin-left:6px;padding:1px 6px;border-radius:10px;background:rgba(0,0,0,.06);
  font-size:10.5px;font-weight:600;}
.dash-aandacht-pijl{margin-left:6px;opacity:.5;font-size:12px;}
.dash-aandacht{text-align:left;}

/* Een teller die nul mag zijn (onderdeel 7, 07-09-2026). Grijs in plaats van
   gekleurd: "er staat niets klaar" is een antwoord, geen alarm. */
.wms-subnav .cnt.nul{background:rgba(0,0,0,.06);color:#888;}

/* Een teller die nul mag zijn (onderdeel 7, 07-09-2026). Grijs in plaats van
   gekleurd: "er staat niets klaar" is een antwoord, geen alarm. */
.wms-subnav .cnt.nul{background:rgba(0,0,0,.06);color:#888;}

/* Een afgesloten order (onderdeel 7, 07-09-2026). Grijs en met een slotje:
   hij is niet verzonden en ook geen werk meer — een derde toestand die er ook
   als een derde toestand uit moet zien. */
.wms-afgesloten{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;
  border-radius:11px;background:#EFEFEF;color:#666;font-size:12px;}

/* De looproute-schakelaar in de pakvoet (07-09-2026, punt 2). Klein en naast
   de voortgang: je zet hem om terwijl je met een kar in het gangpad staat. */
.pik-looproute{display:inline-flex;align-items:center;gap:6px;margin-left:auto;
  font-size:12px;color:#666;cursor:pointer;white-space:nowrap;}
.pik-looproute input{margin:0;}

/* Het ⋯-menu bij een locatieregel (07-09-2026, punt 3). De prullenbak stond
   direct naast de locatiecode en was te makkelijk per ongeluk te raken; nu
   twee bewuste handelingen. */
.loc-menu-wrap{position:relative;display:inline-flex;}
.loc-menu{position:absolute;right:0;top:100%;z-index:30;min-width:200px;
  background:#fff;border:1px solid #E3E4E6;border-radius:8px;
  box-shadow:0 6px 24px rgba(0,0,0,.12);padding:6px;display:flex;flex-direction:column;}
.loc-menu button{display:flex;align-items:center;gap:8px;padding:6px 10px;border:0;
  background:none;border-radius:6px;font-size:12.5px;cursor:pointer;text-align:left;color:inherit;}
.loc-menu button:hover{background:#F7F9FC;}
.loc-menu button.gevaar{color:#993C1D;}
.loc-menu button.gevaar:hover{background:#FAECE7;}

/* De orderlijst gebruikt de volle contentbreedte (07-09-2026, punt 5). De
   pakschermen houden hun kolombreedte — daar lees je één regel tegelijk — maar
   een overzicht met adres, artikelen en status naast elkaar hoort net zo breed
   te zijn als de andere WMS-tabbladen. */
.pick-list--vol{ max-width:none; margin:0; }

/* LVB of eigen verzending, per koppeling (07-09-2026, punt 8). */
.lvb-veld{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:#666;}
.lvb-veld select,.lvb-veld input{padding:6px 10px;border:1px solid #DDD;border-radius:6px;
  font-size:12.5px;font-family:inherit;min-width:110px;}
.lvb-schrijf{display:flex;align-items:flex-start;gap:10px;margin-top:10px;padding:10px;
  border-radius:6px;background:#F7F9FC;cursor:pointer;font-size:12.5px;}
.lvb-schrijf.aan{background:#E4F3EA;}
.lvb-schrijf input{margin-top:2px;}
.lvb-schrijf > span{display:flex;flex-direction:column;gap:2px;}

/* Hoeveelheid bijwerken: één veld met een schakelaar (07-09-2026, punt 4).
   De uitkomstregel eronder is de eigenlijke bevestiging — je leest wat het
   wordt voordat je opslaat. */
.bijwerk-modus{display:inline-flex;gap:4px;background:#F0F1F3;border-radius:6px;padding:3px;margin:6px 0;}
.bijwerk-modus button{border:0;background:none;padding:6px 10px;border-radius:6px;
  font-size:12px;font-family:inherit;cursor:pointer;color:#666;}
.bijwerk-modus button.aan{background:#fff;color:#1A1A1A;box-shadow:0 1px 3px rgba(0,0,0,.1);font-weight:600;}
.bijwerk-invoer{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.bijwerk-invoer input{width:130px;}
.bijwerk-uitkomst{font-size:13px;color:#666;}
.bijwerk-uitkomst.op{color:#1E7A46;}
.bijwerk-uitkomst.af{color:#993C1D;}
.bijwerk-redenen{margin-top:10px;font-size:11.5px;color:#666;}
.bijwerk-redenen > div{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px;}
.bijwerk-redenen button{border:1px solid #E3E4E6;background:#fff;padding:6px 10px;
  border-radius:16px;font-size:12px;font-family:inherit;cursor:pointer;color:#444;}
.bijwerk-redenen button.aan{background:#2F6FEB;border-color:#2F6FEB;color:#fff;}
.lvb-per-koppeling{margin-top:16px;padding-top:10px;border-top:1px solid #EEE;}

/* MAGAZIJN als startscherm van de inpakdag (07-09-2026, punt 7).
   Eén grote kaart met het antwoord op de vraag die je 's ochtends stelt, en
   een knop om meteen te beginnen. */
.mag-vandaag{display:flex;gap:24px;align-items:center;flex-wrap:wrap;
  background:#fff;border:1px solid #EAEAEA;border-radius:10px;padding:16px;margin-bottom:10px;}
.mag-vandaag-cijfer{min-width:150px;}
.mag-groot{font-size:40px;font-weight:650;line-height:1;}
.mag-label{font-size:13px;font-weight:600;margin-top:2px;}
.mag-sub{font-size:11.5px;color:#888;margin-top:2px;}
.mag-vandaag-midden{flex:1 1 300px;min-width:260px;}
.mag-vandaag-cutoff{margin-left:auto;}
.mag-balk{display:flex;height:10px;border-radius:5px;overflow:hidden;background:#F0F1F3;}
.mag-balk span{display:block;}
.mag-legenda{display:flex;gap:14px;flex-wrap:wrap;margin-top:6px;font-size:11px;color:#666;}
.mag-legenda i{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:5px;}
.mag-knoppen{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px;}

.mag-klein{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px;margin-bottom:16px;}
.mag-kaart{background:#fff;border:1px solid #EAEAEA;border-radius:10px;padding:16px;
  text-align:left;cursor:pointer;font:inherit;color:inherit;}
.mag-kaart:hover{border-color:#D5D5D5;}
.mag-kaart.let-op{border-color:#D9AE5A;background:#FFFCF5;}
.mag-n{font-size:24px;font-weight:650;line-height:1;}
.mag-l{font-size:12.5px;font-weight:600;margin-top:3px;}
.mag-s{font-size:11px;color:#888;margin-top:2px;}

.mag-kolommen{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px;}
.mag-kolom{background:#fff;border:1px solid #EAEAEA;border-radius:10px;padding:16px;}
.mag-blok{border-top:1px solid #F0F1F3;padding-top:10px;margin-top:10px;}
.mag-blok:first-of-type{border-top:0;}
.mag-blok-kop{display:flex;gap:10px;align-items:flex-start;justify-content:space-between;}
.mag-blok-items{display:flex;gap:10px;flex-wrap:wrap;margin-top:10px;}
.mag-item{display:flex;gap:6px;align-items:center;font-size:11.5px;max-width:230px;}
.mag-item.meer{color:#888;padding:6px 10px;background:#F7F9FC;border-radius:6px;}
.mag-balken{display:flex;flex-direction:column;gap:10px;margin-top:10px;}
.mag-balk-rij{display:grid;grid-template-columns:minmax(120px,auto) 1fr minmax(90px,auto);
  gap:10px;align-items:center;font-size:12px;}
.mag-balk-rij .row-sub{grid-column:1 / -1;margin-top:-4px;}
.mag-balk-naam{font-weight:600;}
.mag-balk-bak{position:relative;height:8px;background:#F0F1F3;border-radius:4px;overflow:hidden;}
.mag-balk-bak i{position:absolute;inset:0 auto 0 0;border-radius:4px;}
.mag-balk-bak i.goed{background:#1E7A46;}
.mag-balk-bak i.half{background:#2F6FEB;}
.mag-balk-bak i.laag{background:#D9AE5A;}
.mag-balk-cijfer{text-align:right;font-variant-numeric:tabular-nums;}

/* Verzendkosten als drie kaarten: de prijs per stuk is het getal waar het om
   gaat, dus die staat groot. */
.verz-kaarten{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;}
.verz-kaart{background:#fff;border:1px solid #EAEAEA;border-radius:10px;padding:16px;}
.verz-kaart.stil{opacity:.7;}
.verz-kop{font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:6px;}
.verz-perstuk{font-size:26px;font-weight:650;margin-top:6px;line-height:1.1;}
.verz-perstuk span{font-size:11.5px;font-weight:400;color:#888;margin-left:6px;}
.verz-klein{font-size:11.5px;color:#666;margin-top:2px;}
.verz-lijn{display:block;margin-top:10px;color:#8A8A8A;}
.verz-lijn.op{color:#993C1D;}
.verz-lijn.neer{color:#1E7A46;}
.verz-lijn.leeg{font-size:10.5px;color:#AAA;padding:6px 0;}
.verz-bron{font-size:10.5px;color:#999;margin-top:6px;}

/* De drie bakken voor artikelen met LVB-voorraad op nul (07-09-2026).
   "167 artikelen staan op nul" is waar en onbruikbaar; alleen de middelste bak
   is werk, en die krijgt daarom de aandachtskleur. */
.lvb-bakken{display:flex;flex-direction:column;gap:6px;}
.lvb-bak{border:1px solid #EAEAEA;border-radius:8px;overflow:hidden;background:#fff;}
.lvb-bak.oranje{border-color:#E8D3A8;background:#FFFCF5;}
.lvb-bak-kop{display:flex;gap:10px;align-items:flex-start;width:100%;padding:10px;
  border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;}
.lvb-bak-kop:hover{background:rgba(0,0,0,.02);}
.lvb-bak-kop > span:nth-child(2){display:flex;flex-direction:column;gap:2px;flex:1;}
.lvb-bak-kop i{margin-left:auto;align-self:center;opacity:.5;}
.lvb-bak-n{font-size:20px;font-weight:650;min-width:40px;font-variant-numeric:tabular-nums;}
.lvb-gemist{font-size:11.5px;color:#993C1D;font-weight:600;}

/* De ijkvelden bij de kwaliteitsscore (08-09-2026): zeven kleine invoervelden
   die samen één ijkpunt vormen. Ze wrappen op een smal scherm in plaats van de
   kaart uit te rekken. */
.kwaliteit-ijkvelden{ display:flex; gap:6px; align-items:center; flex-wrap:wrap; margin-top:4px; }
.kwaliteit-ijkvelden input{ margin:0; }

/* ---------------------------------------------------------------------------
   DE TAKENLIJST (08-09-2026, onderdeel 2)

   Eén rij per taak: vinkje, tekst, bedrag, acties. Het bedrag staat rechts en
   uitgelijnd op de komma (tabular-nums), want de lijst is op geld gesorteerd en
   dan hoor je die kolom te kunnen scannen zonder te lezen.
   --------------------------------------------------------------------------- */
.taken-kaart{ display:flex; flex-direction:column; gap:10px; }
.taken-kop{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; }

.taken-invoer{ display:flex; gap:6px; align-items:center; }
.taken-invoer-veld{ flex:1; min-width:0; margin:0; font-size:12.5px; padding:6px 10px;
  border:1px solid var(--border); border-radius:var(--radius-kaart); background:var(--white); }
.taken-invoer-veld:focus{ outline:2px solid var(--primary); outline-offset:-1px; }

.taken-lijst{ display:flex; flex-direction:column; }
.taken-rij{ display:flex; align-items:flex-start; gap:10px; padding:10px 2px;
  border-top:1px solid var(--border); position:relative; }
.taken-rij:first-child{ border-top:none; }
.taken-rij.slaapt{ opacity:.55; }
.taken-rij.gedaan{ opacity:.6; }
.taken-rij.sleept{ opacity:.4; }
.taken-rij.sleepdoel{ box-shadow:inset 0 2px 0 var(--primary); }
.taken-rij[draggable="true"]{ cursor:grab; }

.taken-vink{ background:none; border:none; padding:0; margin-top:1px; cursor:pointer;
  color:var(--tekst-uitleg); font-size:16px; line-height:1; flex-shrink:0; }
.taken-vink:hover{ color:#3B6D11; }
.taken-bronicoon{ color:var(--tekst-uitleg); font-size:15px; margin-top:2px; flex-shrink:0; }

.taken-tekst{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.taken-titel{ font-size:12.5px; color:var(--secondary); display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.taken-reden{ font-size:11.5px; color:var(--tekst-uitleg); }

/* De productfoto's bij een taak die over artikelen gaat: klein, links van de
   naam, en niet meer dan vier — daarna zegt een vijfde miniatuur niets meer. */
.taken-fotos{ display:inline-flex; gap:3px; flex-shrink:0; }
.taken-thumb{ width:32px; height:32px; border-radius:6px; border:1px solid var(--border);
  object-fit:contain; background:#fff; display:inline-block; }
div.taken-thumb{ display:inline-flex; align-items:center; justify-content:center; color:var(--tekst-uitleg); }

.taken-geld{ font-size:12.5px; font-weight:600; font-variant-numeric:tabular-nums;
  color:#993C1D; white-space:nowrap; flex-shrink:0; }
.taken-geld em{ font-style:normal; font-weight:400; font-size:10.5px; color:var(--tekst-uitleg); }

.taken-acties{ display:flex; gap:4px; align-items:center; flex-shrink:0; }
.taken-snooze{ display:flex; gap:6px; align-items:center; flex-basis:100%; padding:6px 0 2px 24px; }
.taken-snooze-datum{ margin:0; font-size:11.5px; padding:4px 6px; }

.taken-leeg{ display:flex; align-items:center; gap:7px; color:#15703D; font-size:12.5px; padding:4px 0; }
.taken-meer{ background:none; border:none; padding:6px 0 0; text-align:left; cursor:pointer;
  font:inherit; font-size:11.5px; color:var(--primary); }
.taken-afgerond .taken-rij{ padding:6px 2px; }

/* De wachtregel bij een labelaanvraag (08-09-2026). Tien seconden stilte leest
   als een kapotte knop; een teller die oploopt zegt dat er iets gebeurt. */
.wms-wacht{ display:flex; align-items:center; gap:8px; margin-top:10px; font-size:12px;
  color:var(--tekst-uitleg); }
.wms-wacht b{ font-variant-numeric:tabular-nums; color:var(--secondary); }

/* De bulkbalk onder de voortgangsbalk (08-09-2026). Bewust een eigen regel:
   de voortgangsbalk zegt waar je bent in de rij, deze zegt wat je met de hele
   rij doet. Op één regel worden het twaalf knoppen om in te zoeken. */
.verw-bulkbalk{ display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  padding:10px 16px; margin:-6px 0 16px; background:#EEF3FA;
  border:1px solid #D4DFEE; border-radius:var(--radius-kaart); }
.verw-bulkbalk::before{ content:"Hele rij"; font-size:10.5px; text-transform:uppercase;
  letter-spacing:.03em; color:var(--tekst-uitleg); margin-right:2px; }
.verw-bulkbalk .wms-select{ margin:0; font-size:12px; }

/* ---------------------------------------------------------------------------
   HET DASHBOARD IN DRIE LAGEN (08-09-2026, onderdeel 3)

   Vier kaarten boven, de alinea eronder, dan het werk. Het "Meer"-blok houdt
   alles bereikbaar zonder dat het meedoet in de eerste blik.
   --------------------------------------------------------------------------- */
/* VIER KAARTEN DIE ONDERAAN GELIJK LOPEN (08-09-2026)
   Twan: "Die 4 secties bovenaan moeten op zn minst de witruimte gelijk
   uitgelijnd hebben onderaan zodat de vlakken netjes recht ogen ongeacht de
   content."
   Hier stond align-items:start, en dan krijgt elke kaart precies de hoogte van
   zijn eigen inhoud — vier verschillende hoogtes dus, en dat leest als scheef.
   Met stretch worden ze allemaal zo hoog als de langste. De kaart zelf is een
   kolom, zodat de inhoud bovenaan blijft staan en de extra ruimte onderaan
   terechtkomt in plaats van uitgerekt te worden. */
.dash-vier{ display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; margin-bottom:14px; align-items:stretch; }
.dash-vier > .card{ display:flex; flex-direction:column; }
@media (max-width:1200px){ .dash-vier{ grid-template-columns:repeat(2, 1fr); } }
@media (max-width:700px){ .dash-vier{ grid-template-columns:1fr; } }

/* De takenlijst krijgt de ruimte: dat is het scherm waar je iets mee doet.
   Rechts staat waar het geld zit — kijkwerk, dus smaller. */
.dash-werk{ display:grid; grid-template-columns:minmax(0,1.6fr) minmax(0,1fr); gap:12px; margin-bottom:14px; align-items:start; }
@media (max-width:1000px){ .dash-werk{ grid-template-columns:1fr; } }
.dash-werk-rechts{ display:flex; flex-direction:column; gap:12px; }

/* Omzet per kanaal als één balk: de verhouding in één oogopslag, de bedragen
   eronder. Een taart met vier bijna gelijke partjes zegt minder. */
.dash-kanaalbalk{ display:flex; height:10px; border-radius:999px; overflow:hidden; margin:10px 0 8px;
  background:var(--gray); }
.dash-kanaalbalk span{ display:block; height:100%; }
.dash-kanaalrijen{ display:flex; flex-direction:column; gap:5px; }
.dash-kanaalrij{ display:flex; align-items:baseline; gap:7px; font-size:12px; }
.dash-kanaalrij .stip{ width:9px; height:9px; border-radius:2px; flex:0 0 auto; }
.dash-kanaalrij .naam{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--secondary); }
.dash-kanaalrij .bedrag{ font-variant-numeric:tabular-nums; font-weight:500; }

.dash-kwaliteitrijen{ display:flex; flex-direction:column; gap:8px; margin-top:9px; }
.dash-kwaliteitrij{ display:grid; grid-template-columns:1fr auto; gap:4px 8px; align-items:baseline; }
.dash-kwaliteitrij .naam{ font-size:12px; color:var(--secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dash-kwaliteitrij .score{ font-size:15px; font-weight:600; font-variant-numeric:tabular-nums; }
.dash-kwaliteitrij .dash-balk{ grid-column:1 / -1; }
.dash-groeibeloning{ margin-top:10px; padding-top:8px; border-top:1px solid var(--border); }

.dash-meer{ margin-bottom:14px; }
.dash-meer > summary{ cursor:pointer; font-size:12.5px; color:var(--primary); padding:10px 2px; }
.dash-meer > summary::marker{ color:var(--tekst-uitleg); }
.dash-meer-inhoud{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; margin-top:10px; }
@media (max-width:900px){ .dash-meer-inhoud{ grid-template-columns:1fr; } }


/* De voortgangsbalk bij langlopende handelingen (08-09-2026). Twan zag alleen
   een draaiend icoontje met een teller die tot 392 opliep; wat je wilt weten is
   hoeveel er nog komt en op wie er gewacht wordt. Zie lib/voortgang.js. */
/* DE BALK VAN EEN LOPENDE TAAK (label maken, droge run, bulkronde).
   Heette .wms-voortgang, net als het verzendklaar-overzicht hierboven op regel
   3208 — een omlijnde kaart met padding. Die rand en die padding sloegen dus
   ook op deze balk, waardoor je een kader zag met een streepje erin in plaats
   van een balk die volloopt. Eigen naam, eigen stijl.

   En de balk is van 6 naar 10 px gegaan met een duidelijker spoor: op 6 px met
   8% zwart is het verschil tussen leeg en vol nauwelijks te zien, en dan is het
   geen voortgang maar een decoratie. */
.taak-voortgang{ display:flex; flex-direction:column; gap:6px; }
.taak-voortgang-balk{ height:10px; border-radius:999px; background:rgba(23,34,58,0.12); overflow:hidden; }
.taak-voortgang-balk span{ display:block; height:100%; background:var(--primary); border-radius:999px;
  transition:width .3s ease; }
/* Zonder bekend totaal geen verzonnen percentage, maar een lopend streepje. */
.taak-voortgang-balk .onbepaald{ width:30%; animation:voortgang-loop 1.2s ease-in-out infinite; }
@keyframes voortgang-loop{ 0%{ margin-left:-30%; } 100%{ margin-left:100%; } }
@media (prefers-reduced-motion: reduce){ .taak-voortgang-balk .onbepaald{ animation:none; width:100%; opacity:.4; } }


/* DE TWEE POP-UPS OP HET DASHBOARD (08-09-2026)
   Twan: "Kunnen we de takenlijst inkorten en de volledige een eigen pagina of
   nog liever pop-up geven" en "Dagoverzicht mag van mij een korte pop-up worden
   de eerste keer dat je inlogt".
   Ze gebruiken de bestaande .modal-overlay/.modal-card; alleen breder en met
   een eigen maximumhoogte, want een takenlijst van dertig regels of een
   dagoverzicht met cijferblokken past niet in 420 pixels. */
/* .modal-body werd al op vier plekken gebruikt (o.a. bevestigVraag) maar stond
   in geen enkele stylesheet — een bestaand gat dat de klassecontrole van
   tests/tracker-scherm-klassen.test.js opmerkte zodra de pop-ups hem ook
   gingen gebruiken. */
.modal-body{ font-size:13px; color:var(--secondary); }
.modal-card.modal-wide.taken-popup{ width:760px; }
.taken-popup-body, .dag-popup-body{ max-height:70vh; overflow-y:auto; }
/* In de pop-up staat de takenkaart al in een kaart: geen dubbele rand,
   geen dubbele padding. */
.taken-popup-body > .card{ border:0; box-shadow:none; padding:0; }


/* WEBWINKELKEUR (08-09-2026) — losse beoordelingen, naast de geaggregeerde
   bol-scores. Zelfde bouwstenen als de rest: .card voor de kaarten,
   .filter-chip voor de filters, .dash-balk voor de deelscores. */
.wwk-lijst{ display:flex; flex-direction:column; gap:8px; }
/* De binnenmarges volgen de spatieladder van de app (6/10/16/24/32), zoals
   tests/knophierarchie.test.js bewaakt. */
.wwk-beoordeling{ border:1px solid var(--rand); border-radius:var(--radius-kaart);
  padding:10px; background:#fff; }
/* Een negatieve beoordeling krijgt een streep, geen vlak: het is werk dat
   wacht, geen storing. */
.wwk-beoordeling.negatief{ border-left:3px solid #B4460E; }
.wwk-kop{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:12px; margin-bottom:4px; }
.wwk-naam{ font-weight:500; color:var(--secondary); }
.wwk-sterren{ color:#B4700E; letter-spacing:1px; }
.wwk-tekst{ font-size:13px; color:var(--secondary); white-space:pre-wrap; }
.wwk-reactie{ margin-top:6px; padding:6px; background:var(--gray);
  border-radius:6px; font-size:12px; color:var(--tekst-uitleg); }
.wwk-acties{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:6px; }
.wwk-concept{ margin-top:6px; display:flex; flex-direction:column; gap:6px; }
.wwk-thumb{ width:28px; height:28px; object-fit:contain; border-radius:4px; }
.wwk-deelscores{ display:flex; flex-direction:column; gap:3px; margin-top:8px; }
.wwk-deelscore{ display:grid; grid-template-columns:96px 1fr 34px; align-items:center; gap:6px;
  font-size:11px; color:var(--tekst-uitleg); }
.wwk-deelscore .waarde{ text-align:right; font-variant-numeric:tabular-nums; }

/* ---------------------------------------------------------------------------
   CONTENTKALENDER (09-09-2026)

   Een week is zeven kolommen; op een smal scherm wordt dat een lijst onder
   elkaar. Verder leunt alles op wat er al staat (card, tag-muted, btw-toggle) —
   dit zijn alleen de vormen die nog niet bestonden. */
/* De postpagina: het doek krijgt de ruimte, het paneel een vaste kolom ernaast.
   Bewust GEEN auto-fit: dan worden doek en paneel even breed en blijft er van
   het beeld een postzegel over. Onder de 1000px gaat het onder elkaar. */
.ck-twee{ display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:12px; align-items:start; }
@media (max-width:1000px){ .ck-twee{ grid-template-columns:1fr; } }

/* Het doek blijft in beeld terwijl je in het paneel naar beneden scrolt — anders
   verzet je een schuif en zie je niet wat er gebeurt. */
.ck-doekkaart{ position:sticky; top:12px; }
.ck-doek{
  width:auto; height:auto; max-width:100%; max-height:48vh;
  border-radius:8px; border:1px solid var(--gray); background:var(--gray);
  display:block; margin:0 auto;
}
/* Het paneel scrolt zelf. Vijf lagen met alle opties erin worden anders zo lang
   dat de pagina eronder onbereikbaar wordt. */
/* Voor welk platform en welke plaatsing deze maat is. Twan: "geef bij de maten
   ook direct aan voor welk platform en welke plaatsing die is". */
.ck-plaatsing{ font-size:11px; color:var(--muted); margin-top:2px; }

.ck-paneel{ max-height:calc(100vh - 24px); overflow-y:auto; position:sticky; top:12px; }
@media (max-width:1000px){
  .ck-doekkaart, .ck-paneel{ position:static; max-height:none; }
}

/* DE WEEK ALS DAGRIJEN (10-09-2026)

   Zeven smalle kolommen voor drie posts per week is vooral leegte. Twan, na het
   ontwerp: "vult het scherm mooier en is daardoor overzichtelijk." Dus: dagen
   worden rijen, en een post krijgt de ruimte die hij nodig heeft — het beeld,
   de kanalen, en de aanleiding als leesbare zin in plaats van als voetnoot. */
/* ---------------------------------------------------------------------------
   BEWEGING EN TERUGKOPPELING (10-09-2026)

   Twan: "wanneer dingen inladen of je van weergave wisselt is het eigenlijk
   flits en de volgende pagina is er. Enorm snel maar te snel eigenlijk. Je
   ontwerpt wel voor mensen."

   Klopt. Een scherm dat er in nul milliseconden staat leest als een sprong: je
   ogen moeten opnieuw zoeken waar ze waren. Een korte overgang zegt "dit is een
   nieuw scherm" en je oog volgt mee.

   WAAROM 160 MS. Figma's eigen stuk over interaction design geeft geen getal —
   ik heb het nagekeken. Wat wél vaststaat in de praktijk: onder ~100 ms zie je
   het niet, boven ~300 ms ga je erop wachten. 160 ms met een lichte vertraging
   aan het eind is genoeg om de beweging te volgen zonder dat het traag wordt.

   EN HET MAG UIT. Wie in zijn systeem "minder beweging" heeft aangezet krijgt
   niets — dat is geen versiering maar een toegankelijkheidsinstelling.
--------------------------------------------------------------------------- */
@keyframes paneel-in {
  from { opacity:0; transform:translateY(6px); }
  to   { opacity:1; transform:none; }
}
.paneel-in{ animation:paneel-in 160ms cubic-bezier(.22,.61,.36,1); }

/* KNOPPEN GEVEN ANTWOORD (11-09-2026)
   Twan: "kan je verder ook kijken hoe de UX beter kan en interactiever? zoals
   hovers wanneer je op een knop hovert?"

   Ik had de overgang en de indruk-beweging wel aangezet, maar de vier knoppen
   waar het hele portaal op draait — btn-primary, btn-outline, btn-soft,
   btn-danger — hadden zelf nog geen hover-toestand. Er viel dus niets over te
   laten lopen. Hetzelfde gold voor de subnavigatie die op het magazijn, de PIM
   en de advertenties boven het scherm staat. */
.btn-primary, .btn-outline, .btn-soft, .btn-danger, .btn-danger-outline,
.btw-toggle-btn, .ck-chip, .wms-subnav button{
  transition:background-color 120ms ease, border-color 120ms ease, color 120ms ease,
             box-shadow 120ms ease, transform 60ms ease;
}
.btn-primary:hover:not(:disabled){ background:#22568F; }
.btn-soft:hover:not(:disabled){ background:#DCE7F5; }
.btn-outline:hover:not(:disabled){ background:#F1F4F8; border-color:#CFD6DF; color:var(--tekst); }
.btn-danger:hover:not(:disabled){ background:#7E3018; }
.btn-primary:active, .btn-outline:active, .btn-soft:active, .btn-danger:active,
.btn-danger-outline:active, .btw-toggle-btn:active, .ck-chip:active,
.wms-subnav button:active{ transform:translateY(1px); }
.btw-toggle-btn:hover:not(.active){ background:var(--gray); color:var(--primary); }
.wms-subnav button:hover:not(.active){ background:#F1F4F8; color:var(--primary); }
.wms-subnav button.active:hover{ background:#22568F; }

@media (prefers-reduced-motion: reduce){
  .paneel-in{ animation:none; }
  .btn-primary, .btn-outline, .btn-soft, .btn-danger, .btn-danger-outline, .btw-toggle-btn,
  .ck-chip, .wms-subnav button,
  .ck-rij, .ck-idee, .ov-kaart, .ov-dag, .ov-rijtje, .gs-tabel tr{ transition:none; }
  .btn-primary:active, .btn-outline:active, .btn-danger:active, .btw-toggle-btn:active,
  .wms-subnav button:active{ transform:none; }
}

/* GRAFIEKEN DIE INLADEN (10-09-2026)
   Twan: "heb je ook nog nagedacht over andere interacties zoals grafieken die
   inladen en placeholders wanneer iets nog niet geladen is?"

   Een balk die er in één keer staat lees je als een plaatje; een balk die
   uitloopt lees je als een hoeveelheid — je oog volgt de lengte. Met scaleX
   hoeft de code de eindbreedte niet te kennen: die staat gewoon in de stijl en
   de animatie loopt ernaartoe.

   Even lang als de schermovergang (160 ms) plus een kleine trapsgewijze
   vertraging, zodat de rij van boven naar beneden opbouwt in plaats van in één
   klap te verschijnen. */
@keyframes balk-uit{ from{ transform:scaleX(0); } to{ transform:scaleX(1); } }
@keyframes staaf-op{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
/* De vertraging per rij komt uit de code (style="--wacht:..."), niet uit
   nth-child: de kop van het vak telt daar mee als eerste kind, en dan begint de
   trap één rij te vroeg. */
.ov-sigbalk i{ transform-origin:left center;
  animation:balk-uit 220ms cubic-bezier(.22,.61,.36,1) both;
  animation-delay:var(--wacht, 0ms); }
.gs-spoor i{ transform-origin:bottom center; animation:staaf-op 200ms cubic-bezier(.22,.61,.36,1) both; }
.gs-spoor i:nth-child(2){ animation-delay:25ms; }
.gs-spoor i:nth-child(3){ animation-delay:50ms; }
.gs-spoor i:nth-child(4){ animation-delay:75ms; }
.gs-spoor i:nth-child(5){ animation-delay:100ms; }
.gs-spoor i:nth-child(6){ animation-delay:125ms; }
.gs-spoor i:nth-child(7){ animation-delay:150ms; }
/* En de dekkingsbalk, van links naar rechts — elk blokje een tikje later, zodat
   je de drie weken ziet opbouwen in plaats van in één klap. */
.ov-dag{ animation:balk-uit 200ms cubic-bezier(.22,.61,.36,1) both; transform-origin:left center;
  animation-delay:var(--wacht, 0ms); }

/* Een duimnagel die nog getekend wordt is een blokje met glans, geen leeg vak.
   Zodra het doek erin staat is de glans weg — dat regelt .ck-duim:has(canvas). */
.ck-duim:not(:has(canvas)), .ov-foto:not(:has(canvas)):not(:has(img)),
.gs-foto:not(:has(canvas)){ background:#E9ECF1; position:relative; overflow:hidden; }
.ck-duim:not(:has(canvas))::after, .gs-foto:not(:has(canvas))::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.62), transparent);
  transform:translateX(-100%); animation:sk-glans 1.25s infinite;
}
.ck-duim .ck-geenbeeld{ display:none; }

@media (prefers-reduced-motion: reduce){
  .ov-sigbalk i, .gs-spoor i, .ov-dag{ animation:none; }
  .ck-duim:not(:has(canvas))::after, .gs-foto:not(:has(canvas))::after{ animation:none; }
}

/* Alles wat je kunt aanklikken zegt dat ook als je erboven hangt. */
.ck-rij, .ck-idee, .ov-kaart, .ov-dag, .ov-rijtje{
  transition:border-color 120ms ease, box-shadow 120ms ease, background-color 120ms ease; }
.ov-dag{ cursor:pointer; }
.ov-dag:hover{ box-shadow:0 0 0 2px var(--primary); }
.ov-rijtje:hover{ background:var(--gray); }
.gs-tabel tr{ transition:background-color 120ms ease; }
.gs-tabel tr:hover td{ background:var(--gray); }
.ck-idee:hover{ box-shadow:var(--schaduw-kaart); }
.ov-kaart:hover{ background:#FCFDFE; }

/* Wat aan het laden is, is niet weg: het staat er gedempt tot het nieuwe er is.
   Dat scheelt de sprong van "leeg" naar "vol". */
.aan-het-laden{ opacity:.55; transition:opacity 120ms ease; pointer-events:none; }

/* MARKETING IN DRIE PAGINA'S (10-09-2026)
   Twan: "de strook boven de kalender mag wel echt een eigen pagina worden met
   gedetailleerde informatie om de contentkalender zijn eigen focus te
   geven/behouden. Net als geschiedenis." Dezelfde tabbladvorm als op de
   postpagina, zodat de drie schermen als één ding aanvoelen. */
.ck-menubalk{ display:flex; gap:2px; border-bottom:1px solid var(--gray); margin-bottom:16px; }
.ck-menu{ border:0; background:none; font:inherit; font-size:13px; font-weight:600; color:var(--muted);
  padding:10px 16px; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; }
.ck-menu:hover{ color:var(--primary); }
.ck-menu.actief{ color:var(--primary); border-bottom-color:var(--primary); }
.ck-menu .tel{ font-size:11px; font-weight:700; background:var(--gray); border-radius:99px;
  padding:1px 10px; margin-left:6px; color:var(--muted); }
.ck-menu .tel.wacht{ background:#FBF1E2; color:#B4700E; }

/* De vier kaarten bovenaan het overzicht. */
/* ÉÉN WIT VLAK, MET BANDEN (11-09-2026)
   Twan: "Ik mis hier ook het witte gedeelte erachter." De vier cijfers stonden
   als losse kaartjes met grijs ertussen; WMS en de kalender zetten alles op één
   wit paneel met scheidingslijnen. Dat is de vorm van dit portaal. */
.ov-rij{ display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:0;
  border-bottom:1px solid var(--gray); }
.ov-kaart{ padding:16px; border-right:1px solid var(--gray); }
.ov-kaart:last-child{ border-right:none; }
.ov-band{ border-bottom:1px solid var(--gray); }
.ov-kolom{ padding-bottom:16px; }
.ov-kolom-rechts{ border-left:1px solid var(--gray); }
@media (max-width:1000px){ .ov-kolom-rechts{ border-left:none; border-top:1px solid var(--gray); } }
.ov-kaart.aandacht{ background:#FBF1E2; }
.ov-kop{ font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); font-weight:600; }
.ov-groot{ font-size:27px; font-weight:600; line-height:1.15; margin-top:6px; letter-spacing:-.01em;
  font-variant-numeric:tabular-nums; }
.ov-groot small{ font-size:14px; font-weight:400; color:var(--muted); }
.ov-kaart.aandacht .ov-groot{ color:#B4700E; }
.ov-kaart.gedaan .ov-groot{ color:#3B6D11; }
.ov-sub{ font-size:12px; color:var(--muted); margin-top:6px; line-height:1.4; }

/* De dekking over drie weken. */
.ov-vakkop{ padding:16px 16px 0; display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
.ov-vakkop b{ font-size:13px; }
.ov-dekking{ display:flex; gap:3px; padding:10px 16px 6px; }
.ov-dag{ flex:1; height:30px; border-radius:3px; position:relative; background:var(--gray); }
.ov-dag.vol{ background:var(--primary); }
.ov-dag.deels{ background:var(--primary-zacht, #EAF1F9); }
/* Een lege dag moet je ZIEN — anders lijkt de balk leeg in plaats van leeg-op-
   die-dagen. Een lichte vulling met een streepjesrand leest als "hier kan iets". */
.ov-dag.leeg{ border:1px dashed #D6DBE4; background:var(--gray); }
.ov-dag.vandaag::after{ content:''; position:absolute; inset:-3px; border:2px solid var(--secondary);
  border-radius:5px; }
.ov-deklabels{ display:flex; justify-content:space-between; font-size:11px; color:var(--muted);
  padding:0 16px 10px; }
.ov-legenda{ display:flex; gap:16px; padding:0 16px 16px; font-size:11.5px; color:var(--muted);
  flex-wrap:wrap; align-items:center; }
.ov-blok{ width:12px; height:12px; border-radius:3px; display:inline-block; margin-right:6px;
  vertical-align:-2px; }

.ov-twee{ display:grid; grid-template-columns:minmax(0,1fr) 340px; gap:0; align-items:stretch; }
@media (max-width:1000px){ .ov-twee{ grid-template-columns:minmax(0,1fr); } }

.ov-rijtje{ display:flex; gap:10px; align-items:center; padding:10px 16px; border-bottom:1px solid var(--gray); }
.ov-rijtje:last-child{ border-bottom:none; }
.ov-foto{ width:40px; height:40px; border-radius:6px; background:var(--gray); flex:none; overflow:hidden; }
.ov-foto canvas, .ov-foto img{ width:100%; height:100%; object-fit:contain; display:block; }
.ov-midden{ flex:1; min-width:0; }
.ov-titel{ font-size:12.5px; font-weight:600; line-height:1.3; overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap; }
.ov-cijfer{ text-align:right; font-variant-numeric:tabular-nums; }

/* Wat werkt per signaal. */
.ov-sig{ display:grid; grid-template-columns:minmax(0,1fr) 62px 70px; gap:10px; align-items:center;
  padding:10px 16px; border-bottom:1px solid var(--gray); font-size:12px; }
.ov-sig:last-of-type{ border-bottom:none; }
.ov-sigbalk{ height:6px; border-radius:3px; background:var(--gray); margin-top:5px; overflow:hidden; }
.ov-sigbalk i{ display:block; height:100%; background:var(--primary); border-radius:3px; }
.ov-pct{ text-align:right; font-weight:600; font-variant-numeric:tabular-nums; }
.ov-pct.omhoog{ color:#3B6D11; }
.ov-pct.omlaag{ color:#993C1D; }
.ov-aantal{ text-align:right; font-size:11px; color:var(--muted); }

/* De geschiedenis. */
.gs-tabel{ width:100%; border-collapse:collapse; font-size:12.5px; }
.gs-tabel th{ text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; padding:10px 16px; border-bottom:1px solid var(--gray); }
.gs-tabel td{ padding:10px 16px; border-bottom:1px solid var(--gray); vertical-align:middle; }
.gs-tabel tr:last-child td{ border-bottom:none; }
.gs-post{ display:flex; gap:10px; align-items:center; min-width:0; }
.gs-foto{ width:44px; height:44px; border-radius:6px; background:var(--gray); flex:none; overflow:hidden; }
.gs-foto canvas{ width:100%; height:100%; object-fit:contain; display:block; }
.gs-metriek{ display:flex; gap:14px; flex-wrap:wrap; }
.gs-mt{ font-size:11.5px; color:var(--muted); }
.gs-mt b{ font-size:13px; color:var(--tekst, #17223A); font-variant-numeric:tabular-nums; }
.gs-mt.geen{ font-style:italic; }
.gs-spoor{ display:inline-flex; align-items:flex-end; gap:2px; height:24px; }
.gs-spoor i{ width:5px; background:var(--primary-zacht, #EAF1F9); border-radius:1px; display:block; }
.gs-spoor i.hoog{ background:var(--primary); }

/* ÉÉN PANEEL, VIER BANDEN (10-09-2026, tweede poging)
//
   De eerste versie zette de kopbalk, de uitleg en de filterrij LOS op de pagina
   en alleen het werkvlak in een kaart met een rand. Twan: "Je hebt 0.0 rekening
   gehouden met de rest van het design van het platform en het design dat je zelf
   gemaakt had." Terecht: het goedgekeurde ontwerp was één kaart met vier banden
   (kopbalk, chipsrij, werkvlak, voetbalk), en de rest van het portaal gebruikt
   .content-card — wit met een schaduw, geen rand. */
.ck-scherm{
  background:#fff; border-radius:var(--radius-kaart); box-shadow:var(--schaduw-kaart);
  overflow:hidden; margin-bottom:14px;
}
.ck-balk{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:16px; border-bottom:1px solid var(--gray); }
.ck-balk-titel{ font-size:14px; font-weight:600; }
.ck-balk-rechts{ margin-left:auto; display:flex; gap:10px; align-items:center; flex-wrap:wrap; }

.ck-chipsrij{ display:flex; gap:6px; align-items:center; flex-wrap:wrap;
  padding:10px 16px; border-bottom:1px solid var(--gray); }
.ck-scheiding{ width:1px; height:18px; background:var(--gray); margin:0 6px; }
.ck-weeknav{ display:flex; align-items:center; gap:6px; }
.ck-weeknav b{ font-size:13px; font-weight:600; min-width:132px; text-align:center; }
.ck-chip{
  font-family:inherit; font-size:12px; padding:6px 10px; border-radius:99px;
  border:1px solid var(--gray); background:#fff; color:var(--muted); cursor:pointer;
  white-space:nowrap; appearance:none; line-height:1.3;
}
.ck-chip:hover{ border-color:var(--primary); color:var(--primary); }
.ck-chip.aan{ background:var(--primary-zacht, #EAF1F9); border-color:var(--primary-zacht, #EAF1F9);
  color:var(--primary); font-weight:500; }
.ck-chip:focus-visible{ outline:2px solid var(--primary); outline-offset:2px; }
/* Een keuzelijst die eruitziet als een chip: hetzelfde beeld, maar hij werkt
   zoals elke andere keuzelijst in het portaal. */
select.ck-chip{ padding-right:24px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M1 1l4 4 4-4' fill='none' stroke='%236B7688' stroke-width='1.5'/></svg>");
  background-repeat:no-repeat; background-position:right 9px center; }

.ck-werkvlak{ display:grid; grid-template-columns:minmax(0,1fr) 300px; align-items:start; }
@media (max-width:1000px){ .ck-werkvlak{ grid-template-columns:minmax(0,1fr); } }

.ck-week{ display:block; }
.ck-dagrij{ display:grid; grid-template-columns:92px minmax(0,1fr); gap:16px;
  padding:10px 16px; border-bottom:1px solid var(--gray); }
.ck-dagrij:last-child{ border-bottom:none; }
.ck-dagrij.ck-vandaag{ background:var(--gray); }
.ck-dagnaam{ font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); }
.ck-dagnr{ font-size:19px; font-weight:600; line-height:1.15; font-variant-numeric:tabular-nums; }
.ck-dagrij.ck-vandaag .ck-dagnr{ color:var(--primary); }
.ck-vandaagmerk{ font-size:11px; color:var(--primary); font-weight:600; }
.ck-kaarten{ display:flex; flex-direction:column; gap:8px; min-width:0; }
.ck-dagrij.ck-sleepdoel{ background:var(--primary-zacht, #EAF1F9); }

/* De postkaart: beeld, midden, acties. */
.ck-rij{ display:grid; grid-template-columns:52px minmax(0,1fr) auto; gap:10px; align-items:center;
  background:var(--card); border:1px solid var(--gray); border-left:3px solid var(--gray);
  border-radius:8px; padding:10px 16px; cursor:grab; min-width:0; text-align:left; width:100%;
  font:inherit; color:inherit; }
.ck-rij:hover{ border-color:var(--primary); }
.ck-rij.ck-gepland{ border-left-color:var(--primary); }
.ck-rij.ck-deels{ border-left-color:#B4700E; }
.ck-rij.ck-gepubliceerd{ border-left-color:#3B6D11; opacity:.75; }
.ck-rij.ck-voorstel{ border-left-color:var(--gray); border-style:dashed; border-left-style:solid; }
.ck-rij.ck-overgeslagen{ opacity:.5; }
.ck-duim{ width:52px; height:52px; border-radius:6px; background:var(--gray); overflow:hidden;
  display:grid; place-items:center; border:1px solid var(--gray); flex:none; }
/* PLATGEDRUKT (10-09-2026). Twan: "Afbeeldingen worden soms platgedrukt zonder
   de juiste verhouding te houden." Een canvas met een vaste breedte ÉN hoogte
   rekt zijn inhoud uit; bij een vierkant zie je dat niet, bij een verhaal
   (1080 × 1920) wel. object-fit:contain houdt de verhouding en laat de rest
   leeg — beter een randje dan een uitgerekt product. */
.ck-duim canvas{ width:100%; height:100%; object-fit:contain; display:block; }
.ck-duim .ck-geenbeeld{ font-size:9px; color:var(--muted); text-align:center; line-height:1.2; padding:2px; }
/* De kaart is een <div> met <span>-kinderen (zodat er een knop in mag staan
   zonder een knop-in-een-knop te maken). Spans zijn inline, dus zonder deze
   display-regels lopen de titel en de aanleiding op één regel door — precies
   wat er op 10-09-2026 mis ging. */
.ck-midden{ min-width:0; display:block; }
.ck-regel{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:2px; }
.ck-tijd{ font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums; }
.ck-titel{ display:block; font-size:13.5px; font-weight:600; line-height:1.3; margin:0 0 2px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ck-reden{ display:block; font-size:12px; color:var(--muted); line-height:1.35;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ck-acties{ display:flex; gap:6px; align-items:center; }
.ck-niets{ border:1px dashed var(--gray); border-radius:8px; padding:10px 16px;
  font-size:12px; color:var(--muted); }

/* Eén post, meerdere kanalen — met een vinkje bij wat al geplaatst is. */
.ck-kanaalgroep{ display:inline-flex; align-items:center; gap:8px; flex-wrap:wrap; }
.ck-kanaalstuk{ display:inline-flex; align-items:center; gap:4px; font-size:11px; font-weight:500;
  color:var(--muted); }
.ck-kanaalstuk.ck-klaar{ color:#3B6D11; }
.ck-staat{ font-size:11px; font-weight:600; padding:2px 10px; border-radius:99px; white-space:nowrap; }
.ck-staat-gepland{ background:#E6EEFB; color:#1A4FBF; }
.ck-staat-deels{ background:#FBF1E2; color:#B4700E; }
.ck-staat-gepubliceerd{ background:#EAF3DE; color:#3B6D11; }
.ck-staat-voorstel{ background:var(--gray); color:var(--muted); }
.ck-staat-overgeslagen{ background:var(--gray); color:var(--muted); }

/* De postpagina in drie tabbladen. */
.ck-tabs{ display:flex; gap:2px; border-bottom:1px solid var(--gray); margin-bottom:16px; }
.ck-tab{ border:0; background:none; font:inherit; font-size:13px; font-weight:600; color:var(--muted);
  padding:10px 16px; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; }
.ck-tab:hover{ color:var(--primary); }
.ck-tab.actief{ color:var(--primary); border-bottom-color:var(--primary); }
.ck-tabtel{ font-size:11px; font-weight:700; background:var(--gray); border-radius:99px;
  padding:2px 6px; margin-left:6px; color:var(--muted); }

/* Plaatsen: een rij per kanaal. */
.ck-plaats{ width:100%; border-collapse:collapse; font-size:12.5px; margin-top:10px; }
.ck-plaats th{ text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; padding:0 10px 6px; border-bottom:1px solid var(--gray); }
.ck-plaats td{ padding:10px; border-bottom:1px solid var(--gray); vertical-align:middle; }
.ck-plaats tr:last-child td{ border-bottom:none; }

/* DE WERKBANK ZOALS IN HET ONTWERP (10-09-2026, tweede poging)
   Doek links met alle ruimte, lagen in een vaste kolom rechts, de kanaalproef
   eronder en de sjabloonstrook onderaan. De eerste versie zette dit als twee
   losse kaarten neer; Twan: "de werkbank klopt totaal niet met hoe je het
   voorbeeld gemaakt had." */
.ck-werkbank{ display:grid; grid-template-columns:minmax(0,1fr) 320px; align-items:start; }
@media (max-width:1000px){ .ck-werkbank{ grid-template-columns:minmax(0,1fr); } }
.ck-doekvak{ padding:16px; display:flex; flex-direction:column; align-items:center; }
/* NIET het doek zelf: die regel gaf het canvas width:100% en dus een hoogte van
   de hele kolom (1080 × 1080 in een kolom van 700 px = 700 px hoog). De
   kanaalproef, de sjabloonstrook en de matenrij stonden daardoor zó ver naar
   beneden dat Twan dacht dat ze er niet waren. */
.ck-doekvak > :not(canvas):not(img){ width:100%; }
.ck-doekregel{ font-size:11px; color:var(--muted); margin-top:6px; text-align:center; }
.ck-lagenvak{ border-left:1px solid var(--gray); padding:16px; }
@media (max-width:1000px){ .ck-lagenvak{ border-left:none; border-top:1px solid var(--gray); } }

.ck-kanaalproef{ display:flex; gap:16px; align-items:flex-end; flex-wrap:wrap;
  padding:16px; border-top:1px solid var(--gray); }
.ck-proef{ text-align:center; }
.ck-proef canvas{ display:block; border-radius:5px; border:1px solid var(--gray);
  background:var(--gray); object-fit:contain; }
.ck-proefnaam{ font-size:11px; color:var(--muted); margin-top:4px; }
.ck-proefmaat{ font-size:10px; color:var(--muted); opacity:.8; }

.ck-sjabloonstrook{ display:flex; gap:10px; overflow-x:auto; padding:16px; border-top:1px solid var(--gray); }
.ck-sjabloon{ flex:0 0 auto; width:74px; text-align:center; background:none; border:1px solid var(--gray);
  border-radius:8px; padding:6px; cursor:pointer; font:inherit; }
.ck-sjabloon.aan{ border-color:var(--primary); box-shadow:0 0 0 2px var(--primary-zacht, #EAF1F9); }
.ck-sjabloon canvas{ width:60px; height:60px; object-fit:contain; display:block; border-radius:5px; background:var(--gray); }
.ck-sjabloon span{ display:block; font-size:10px; color:var(--muted); margin-top:4px; }

/* ÉÉN ONTWERP, VIER MATEN — de rij uit het ontwerp, met zijn eigen balk. */
.ck-matenbalk{ display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 16px; border-top:1px solid var(--gray); }
.ck-matenbalk label.ck-chip{ display:inline-flex; align-items:center; gap:6px; }
.ck-proefwaarschuwing{ font-size:10px; color:#B4700E; }
/* Een kanaal dat nog niet aanstaat is een SUGGESTIE: gedempt, met een knop om
   hem erbij te zetten. */
.ck-proef-uit canvas{ opacity:.55; }
.ck-proef-uit:hover canvas{ opacity:1; }

.ck-matenrij{ display:flex; gap:20px; align-items:flex-end; flex-wrap:wrap;
  padding:16px; border-top:1px solid var(--gray); }
.ck-maat{ text-align:center; background:none; border:0; padding:0; cursor:pointer; font:inherit; }
.ck-maat canvas{ display:block; border-radius:6px; border:1px solid var(--gray);
  background:var(--gray); object-fit:contain; }
.ck-maat.aan canvas{ border-color:var(--primary); box-shadow:0 0 0 2px var(--primary-zacht, #EAF1F9); }
.ck-maatnaam{ display:block; font-size:12px; font-weight:600; margin-top:6px; }
.ck-maatpx{ display:block; font-size:10px; color:var(--muted); font-variant-numeric:tabular-nums; }
.ck-maatwaar{ display:block; font-size:10px; color:var(--muted); max-width:150px; }
.ck-maatrol{ display:inline-block; font-size:10px; font-weight:700; letter-spacing:.05em; margin-top:6px;
  background:var(--gray); color:var(--muted); border-radius:99px; padding:2px 10px; }
.ck-maatrol.isbasis{ background:var(--primary-zacht, #EAF1F9); color:var(--primary); }
.ck-maatrol.isafwijking{ background:#FBF1E2; color:#B4700E; }
.ck-zonelegenda{ display:flex; flex-direction:column; gap:10px; max-width:300px;
  align-self:flex-start; padding-top:4px; }
.ck-lz{ font-size:11px; color:var(--muted); line-height:1.4; padding-left:20px; position:relative; }
.ck-lz b{ color:var(--tekst, #17223A); }
.ck-vlek{ position:absolute; left:0; top:2px; width:13px; height:13px; border-radius:3px;
  border:1px solid var(--gray); }
.ck-vlek.bijsnij{ background:rgba(179,38,30,.20); }
.ck-vlek.knop{ background:rgba(23,34,58,.34); }
.ck-vlek.geen{ background:#fff; border-style:dashed; }

.mk-tabs{ margin-bottom:12px; }
/* .fixed-row is display:flex, dus het hidden-attribuut alleen wint het niet.
   En een KLASSE in plaats van de hidden-eigenschap, zodat je in de opgemaakte
   HTML kunt zien wat er verborgen is — met .hidden stond dat alleen in het
   geheugen van de browser en kon geen test er iets over zeggen. */
.mk-vak.mk-uit{ display:none !important; }

/* PLAATSEN IN EEN SMAL PANEEL (10-09-2026)
   Vijf kolommen passen niet in 396 px: de knoppen breken dan over drie regels.
   In het paneel wordt elke rij een blokje — kanaal en status op één regel, de
   knoppen eronder. Breeduit (de werkbank) blijft het gewoon een tabel. */
.ck-postpaneel .ck-plaats,
.ck-postpaneel .ck-plaats tbody,
.ck-postpaneel .ck-plaats tr,
.ck-postpaneel .ck-plaats td{ display:block; width:auto; }
.ck-postpaneel .ck-plaats thead, .ck-postpaneel .ck-plaats th{ display:none; }
.ck-postpaneel .ck-plaats tr{
  border:1px solid var(--gray); border-radius:8px; padding:10px; margin-bottom:8px;
  display:grid; grid-template-columns:auto 1fr auto; gap:6px 10px; align-items:center;
}
.ck-postpaneel .ck-plaats td{ padding:0; }
.ck-postpaneel .ck-plaats td:nth-child(3){ display:none; }   /* de maat staat al bij het beeld */
.ck-postpaneel .ck-plaats td:last-child{ grid-column:1/-1; display:flex; gap:6px; flex-wrap:wrap; }
.ck-postpaneel .ck-plaats td:last-child .btn-primary,
.ck-postpaneel .ck-plaats td:last-child .btn-outline{ flex:1 1 auto; justify-content:center; }

/* DE POST ALS ZIJPANEEL (10-09-2026)
   Naast de kalender, niet als los scherm — zodat je zicht houdt op de week
   waarin de post staat. Het adres blijft hetzelfde. */
.ck-metpaneel{ display:grid; grid-template-columns:minmax(0,1fr) 396px; gap:14px; align-items:start; }
@media (max-width:1100px){ .ck-metpaneel{ grid-template-columns:minmax(0,1fr); } }
.ck-achterin .ck-rij{ opacity:.75; }
.ck-achterin .ck-rij:hover{ opacity:1; }
.ck-postpaneel{
  /* Het paneel staat IN het kalenderscherm, op de plek van de voorstellenlade —
     Twan: "Zijbalk mag over de voorstellen vallen wanneer je dat aanklikt."
     Vandaar een lijn links in plaats van een eigen kaart met schaduw. */
  border-left:1px solid var(--gray); align-self:stretch;
  max-height:calc(100vh - 24px); overflow-y:auto; background:#fff;
}
.ck-paneelkop{ display:flex; align-items:flex-start; gap:10px; padding:16px;
  border-bottom:1px solid var(--gray); }
.ck-paneelvak{ padding:16px; }
/* KEUZEBALKJES IN EEN SMALLE KOLOM (10-09-2026)
   Twan: "Schaduw selector loopt van het beeld af en de optie om geen schaduw te
   hebben zie ik niet." .btw-toggle is één rij met overflow:hidden — bij zeven
   schaduwsoorten in een kolom van 320 px valt de laatste ("geen") er letterlijk
   buiten. In het lagenpaneel breken ze dus af op meerdere regels. */
.ck-lagenvak .btw-toggle,
.ck-postpaneel .btw-toggle{ flex-wrap:wrap; overflow:visible; flex-shrink:1; }
.ck-lagenvak .btw-toggle-btn,
.ck-postpaneel .btw-toggle-btn{ padding:6px 10px; flex:0 0 auto; }
/* Zonder deze lijnen zien de knoppen op de tweede regel eruit als losse blokjes. */
.ck-lagenvak .btw-toggle-btn{ border-top:0.5px solid #e5e7eb; border-right:0.5px solid #e5e7eb; }

/* De zes voorstellen als klein raster onder het beeld — zoals in het ontwerp.
   Ze stonden als kaarten van 110 px in een paneel van 396: dan passen er drie
   en valt de rest buiten beeld. Twan: "al die varianten staan enorm groot". */
.ck-variantraster{ display:grid; grid-template-columns:repeat(6,1fr); gap:6px; margin-top:10px; }
.ck-variant{ background:none; border:1px solid var(--gray); border-radius:6px; padding:3px;
  cursor:pointer; font:inherit; }
.ck-variant.actief{ border-color:var(--primary); box-shadow:0 0 0 2px var(--primary-zacht, #EAF1F9); }
.ck-variant canvas{ width:100%; aspect-ratio:1/1; object-fit:contain; display:block;
  border-radius:4px; background:var(--gray); }

.ck-paneeldoek{
  width:auto; height:auto; max-width:100%; max-height:300px;
  border-radius:8px; border:1px solid var(--gray); background:var(--gray);
  display:block; margin:0 auto;
}

/* De voorstellenlade rechts van de week. */
.ck-lade{ border-left:1px solid var(--gray); align-self:stretch; }
@media (max-width:1000px){ .ck-lade{ border-left:none; border-top:1px solid var(--gray); } }
.ck-ladekop{ padding:16px 16px 10px; }
.ck-ladelijst{ display:flex; flex-direction:column; gap:8px; padding:0 16px 16px; }
.ck-idee{ border:1px solid var(--gray); border-radius:8px; padding:10px 10px;
  background:var(--card); cursor:grab; }
.ck-idee:hover{ border-color:var(--primary); }
.ck-ideekop{ display:flex; align-items:center; gap:6px; margin-bottom:5px; }
.ck-score{ margin-left:auto; font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums; }
.ck-ideetitel{ font-size:12.5px; font-weight:600; line-height:1.3; margin-bottom:3px; }
.ck-ideereden{ font-size:11.5px; color:var(--muted); line-height:1.35; margin-bottom:8px; }
.ck-ideeacties{ display:flex; gap:6px; }

/* De voetbalk onder de kalender. */
.ck-voet{ padding:10px 16px; border-top:1px solid var(--gray); background:#FCFDFE;
  font-size:12px; color:var(--muted); display:flex; gap:14px; flex-wrap:wrap; align-items:center; }
.ck-voet .ck-stip{ width:5px; height:5px; border-radius:50%; background:var(--muted); }

/* DE WEEK VAN VÓÓR 10-09-2026 STOND HIER.
   Zeven kolommen met een dag per kolom. Die is vervangen door de dagrijen
   hierboven — en dit blok stond er nog ONDER, dus het overschreef ze gewoon:
   .ck-week kreeg alsnog repeat(7,1fr) en elke dagrij werd in een kolom van
   150 px geperst. Twan zag een onleesbaar scherm.
   Wat er nog van over is (.ck-dag-kop voor de vierwekenweergave,
   .ck-kaart-merk verderop) staat op zijn eigen plek; de rest is weg. */
.ck-dag-kop{ font-size:11px; font-weight:600; color:var(--muted); margin-bottom:6px; }

/* De kanaalkleuren: één blik moet genoeg zijn om te zien waar een post heen
   gaat. Instagram paars, Facebook blauw, blog groen, nieuwsbrief oranje. */
.ck-kanaal{ font-weight:600; padding:1px 6px; border-radius:99px; font-size:10px; }
.ck-kanaal-instagram{ background:#F3E8FB; color:#6B2E8F; }
.ck-kanaal-facebook{ background:#E6EEFB; color:#1A4FBF; }
.ck-kanaal-blog{ background:#E4F3EC; color:#0F6E56; }
.ck-kanaal-nieuwsbrief{ background:#FBEFE4; color:#B4700E; }

.ck-maand{ display:flex; flex-direction:column; gap:10px; }
.ck-maandweek{ background:var(--card); border:1px solid var(--gray); border-radius:10px; padding:10px; }
/* De vierwekenweergave toont dezelfde brede kaarten als de week, dus een raster
   van smalle kolommen past er niet meer in: onder elkaar. */
.ck-maandrij{ display:flex; flex-direction:column; gap:8px; }

/* De beeldbibliotheek (beeldgenerator onderdeel 4).
   Tegels van gelijke hoogte met het beeld in een vaste verhouding, zodat een
   staande en een liggende achtergrond naast elkaar niet gaan schuiven. Het
   beeld zelf wordt niet uitgesneden: contain, met de kaartkleur eronder. */
.beeld-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:10px; }
.beeld-tegel{
  background:var(--card); border:1px solid var(--gray); border-radius:8px; padding:10px;
}
.beeld-tegel img{
  width:100%; aspect-ratio:1/1; object-fit:contain; background:var(--gray);
  border-radius:5px; display:block;
}
.beeld-tegel-naam{ font-size:12px; font-weight:600; margin-top:6px; word-break:break-word; }

/* De beeldwerkbank (beeldgenerator onderdeel 5).
   Vijf lagen onder elkaar, elk met zijn eigen knoppen en schuiven. Bewust
   smal: het paneel staat naast het doek, en wat je hier verzet zie je daar
   meteen gebeuren. */
.beeld-lagen{ display:flex; flex-direction:column; gap:10px; margin-top:10px; }
.beeld-laag{ border:1px solid var(--gray); border-radius:8px; padding:10px; }
.beeld-laag-kop{ display:flex; align-items:center; gap:6px; font-size:13px; }
.beeld-schuif{ display:flex; align-items:center; gap:10px; margin-top:6px; font-size:12px; color:var(--muted); }
.beeld-schuif span{ min-width:110px; }
.beeld-schuif input[type=range]{ flex:1; }

/* Dezelfde post in elk sjabloon, om te vergelijken. */
.beeld-strook{ display:flex; gap:10px; overflow-x:auto; padding-bottom:6px; margin-top:10px; }
.beeld-strook-item{
  background:none; border:1px solid var(--gray); border-radius:8px; padding:6px;
  cursor:pointer; flex:0 0 auto; width:110px; text-align:center;
}
.beeld-strook-item.actief{ border-color:var(--primary); }
.beeld-strook-item canvas{ width:96px; height:96px; object-fit:contain; display:block; border-radius:5px; background:var(--gray); }
.beeld-strook-item span{ display:block; font-size:11px; color:var(--muted); margin-top:6px; }
.ck-kaart-merk{ font-size:11px; margin-top:6px; display:flex; align-items:center; gap:6px; }

/* De huisstijl per webshop (beeldgenerator onderdeel 5). */
.beeld-kleuren{ display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:10px; margin-top:10px; }
.beeld-kleur{ display:flex; align-items:center; gap:10px; font-size:12px; }
.beeld-kleur input[type=color]{ width:38px; height:32px; padding:0; border:1px solid var(--gray); border-radius:5px; }
.beeld-uploadrij{ display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:10px; margin-top:16px; }
.beeld-upload{ border:1px solid var(--gray); border-radius:8px; padding:10px; }
.beeld-upload img{ max-width:140px; max-height:60px; object-fit:contain; display:block; margin-top:6px; }
.beeld-eigen-sj{ display:inline-flex; align-items:center; gap:6px; border:1px solid var(--gray); border-radius:5px; padding:6px 10px; }

/* De proef met tien artikelen: origineel naast uitsnede, zodat je zelf ziet
   of het klopt. De uitsnede op een ruitjespatroon, anders is een doorzichtige
   rand niet van een witte te onderscheiden. */
.beeld-proef{ display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:10px; margin-top:10px; }
.beeld-proef-rij{ border:1px solid var(--gray); border-radius:8px; padding:10px; }
.beeld-proef-paar{ display:flex; gap:10px; align-items:center; margin:6px 0; }
.beeld-proef-paar img, .beeld-proef-foto{ width:96px; height:96px; object-fit:contain;
  background:var(--gray); border-radius:5px; }
.beeld-proef-uit{
  background-color:#FFFFFF;
  background-image:linear-gradient(45deg,#E9ECEF 25%,transparent 25%,transparent 75%,#E9ECEF 75%),
                   linear-gradient(45deg,#E9ECEF 25%,transparent 25%,transparent 75%,#E9ECEF 75%);
  background-size:16px 16px; background-position:0 0,8px 8px;
}
/* De kleurstalen uit de productfoto (beeldgenerator stap 2). */
.beeld-staal{
  width:28px; height:28px; border:1px solid var(--gray); border-radius:5px; cursor:pointer; padding:0;
}


/* WANNEER DIT ARTIKEL GEKOCHT WORDT (11-09-2026)
   Vierentwintig staafjes, één per uur, met het venster eruit gelicht. Ze
   groeien van onder op als de kaart verschijnt — dezelfde beweging als de
   grafieken op het overzicht, zodat je ziet dat het een meting is en geen
   plaatje. */
/* Een dag is 24 uur breed, geen volle kolom: over de hele kaartbreedte wordt
   elk uur een blok van 46px en leest het als een staafdiagram met vier items. */
.km-vak{ max-width:560px; }
.km-staven{ display:flex; align-items:flex-end; gap:2px; height:56px; margin-top:10px;
  border-bottom:1px solid var(--gray); }
/* De stille uren moeten zichtbaar blijven: in de grijstint van de bladzijde
   zijn ze op een witte kaart onvindbaar, en dan zweven de drukke uren los. */
.km-staaf{ flex:1; height:var(--hoog,0%); min-height:3px; background:#E4E8EE;
  border-radius:2px 2px 0 0; transform-origin:bottom center;
  animation:staaf-op 260ms cubic-bezier(.22,.61,.36,1) both; animation-delay:var(--wacht,0ms);
  transition:background-color 120ms ease; }
.km-staaf.piek{ background:var(--primary); }
.km-staaf:hover{ background:var(--secondary); }
.km-schaal{ display:flex; justify-content:space-between; font-size:10.5px; color:var(--muted); margin-top:6px; }
@media (prefers-reduced-motion: reduce){ .km-staaf{ animation:none; } }


/* EIGEN DATUMS MET EEN ECHTE KALENDER (11-09-2026)
   Twan: "het toevoegen van een feestdag of belangrijke datum kan makkelijker
   via een echte kalender dan zelf de datum intypen." Maandag vooraan, net als
   de contentkalender zelf. */
.mk-datumrij{ display:flex; gap:6px; flex-wrap:wrap; margin-top:8px; }
.mk-datumchip{ display:inline-flex; align-items:center; gap:6px; background:var(--gray);
  border-radius:999px; padding:6px 6px 6px 10px; font-size:12px; }
.mk-datumchip.jaarlijks{ background:#EAF1F9; }
.mk-datumchip i{ font-size:13px; color:var(--primary); }
.mk-datumchip button{ background:none; border:0; cursor:pointer; color:var(--muted);
  font-size:12px; line-height:1; padding:6px; border-radius:999px;
  transition:background-color 120ms ease, color 120ms ease; }
.mk-datumchip button:hover{ background:#E4E8EE; color:var(--secondary); }
.mk-datumvorm{ display:flex; gap:24px; flex-wrap:wrap; align-items:flex-start; margin-top:12px; }
.mk-kal{ border:1px solid var(--gray); border-radius:var(--radius-kaart); padding:10px; }
.mk-kalkop{ display:flex; align-items:center; justify-content:space-between; gap:10px;
  font-size:12.5px; font-weight:600; margin-bottom:8px; }
.mk-kalraster{ display:grid; grid-template-columns:repeat(7,30px); gap:2px; }
.mk-kaldagkop{ font-size:10.5px; color:var(--muted); text-align:center; padding-bottom:6px; }
.mk-kaldag{ height:30px; border:0; background:none; border-radius:8px; cursor:pointer;
  font-family:inherit; font-size:12px; color:var(--tekst);
  transition:background-color 120ms ease, color 120ms ease; }
.mk-kaldag:hover{ background:var(--gray); }
.mk-kaldag.vandaag{ box-shadow:inset 0 0 0 1px #D6DBE4; }
.mk-kaldag.gekozen{ background:var(--primary); color:#fff; }
.mk-kaldag.gekozen:hover{ background:#22568F; }


/* HET DAGOVERZICHT (11-09-2026, volgens het goedgekeurde ontwerp)
   Vier cijfers in één wit vlak met scheidingslijnen, net als het overzicht van
   de contentkalender. Twan: "relevante cijfers of meldingen in bold (...)
   wanneer een gegeven niet bekend is zoals advertentiekosten zet dat er dan
   eerlijk neer ipv 0." */
/* HERZIEN 11-09-2026. Twan, na de uitrol: "Jouw eigen ontwerp is een stuk
   beter dan wat je nu gemaakt had. Je hebt daar totaal van afgeweken."

   Dat klopte. Het ontwerp is ÉÉN blad met dunne scheidingen — kop, cijfers,
   zin, wat aandacht vraagt, de maand — en wat er stond waren losse kaarten met
   witruimte ertussen, elk met een eigen schaduw. Zelfde inhoud, maar je leest
   het als vijf dingen in plaats van als één dag. De scheiding tussen de delen
   is nu een lijn, geen gat. */
.dag-blad{ padding:0; overflow:hidden; }
.dag-kop{ display:flex; align-items:center; justify-content:space-between; gap:16px;
  flex-wrap:wrap; padding:16px; border-bottom:1px solid var(--border); }
.dag-kop-titel{ font-size:14px; font-weight:600; color:var(--secondary); }
.dag-kop-acties{ display:flex; gap:6px; align-items:center; }
.dag-cijfers{ display:grid; grid-template-columns:repeat(4,1fr); }
.dag-cijfer{ padding:16px; border-right:1px solid var(--border); min-width:0; }
.dag-cijfer:last-child{ border-right:none; }
/* Het schreefloze kopje boven een cijfer of een blok. Klein, gespatieerd, en
   overal hetzelfde — zo herken je de indeling zonder hem te lezen. */
/* `.dag-kaart-kop` en `.dag-kaart-groot` staan er nog bij omdat vijf andere
   schermen (groeibeloning, verloop, eerdere rondes) diezelfde twee vormen
   gebruiken. Dat zijn dezelfde regels onder hun oude naam, geen tweede
   opmaak die uit de pas kan gaan lopen. */
.dag-eyebrow,
.dag-kaart-kop{ font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; }
.dag-groot,
.dag-kaart-groot{ font-size:26px; font-weight:600; line-height:1.15; margin-top:6px;
  letter-spacing:-.01em; font-variant-numeric:tabular-nums; }
.dag-onder{ font-size:11.5px; line-height:1.5; color:var(--tekst-uitleg); margin-top:6px; }
/* Een vak binnen het blad: gescheiden door een lijn, niet door witruimte. */
.dag-vak{ padding:16px; border-top:1px solid var(--border); }
/* "niet bekend" is geen bedrag, dus het hoort er ook niet als bedrag uit te
   zien — anders leest het alsnog als een getal. */
.dag-onbekend{ font-size:17px; font-weight:500; font-style:italic; color:var(--muted); }
.dag-merk{ font-size:10px; font-weight:700; letter-spacing:.04em; padding:2px 6px;
  border-radius:999px; margin-left:6px; text-transform:uppercase; }
.dag-merk.let{ background:#FBF1E2; color:#B4700E; }
.dag-zin{ font-size:14.5px; line-height:1.7; max-width:78ch; color:var(--secondary); }
.dag-zin b{ font-weight:600; }
/* De bron staat achter de bewering waar hij bij hoort, niet op een hoop
   eronder. Alleen bij een geschreven alinea kan dat niet per zin, dan staan ze
   aan het eind. */
.dag-bronnen{ white-space:nowrap; }
.dag-aandacht{ display:flex; gap:10px; align-items:flex-start; padding:10px 0;
  border-top:1px solid var(--gray); }
.dag-aandacht:first-of-type{ border-top:0; padding-top:10px; }
.dag-stip{ width:8px; height:8px; border-radius:50%; flex:none; margin-top:6px; }
.dag-stip.let{ background:#B4700E; }
.dag-stip.fout{ background:#993C1D; }
.dag-maand{ display:flex; align-items:flex-end; gap:2px; height:40px; margin-top:10px;
  border-bottom:1px solid var(--gray); }
.dag-maandbalk{ flex:1; height:var(--hoog,6%); min-height:3px; background:#E4E8EE; border:0;
  border-radius:2px 2px 0 0; cursor:pointer; padding:0; transform-origin:bottom center;
  animation:staaf-op 240ms cubic-bezier(.22,.61,.36,1) both; animation-delay:var(--wacht,0ms);
  transition:background-color 120ms ease; }
.dag-maandbalk:hover{ background:var(--primary); }
.dag-maandbalk.nu{ background:var(--primary); box-shadow:0 0 0 2px var(--secondary); }
@media (prefers-reduced-motion: reduce){ .dag-maandbalk{ animation:none; } }
/* Vier kolommen naast elkaar werkt tot ongeveer 820 punten; daaronder worden de
   onderregels ("na inkoop, commissie en verzending") twee woorden breed. */
@media (max-width:820px){
  .dag-cijfers{ grid-template-columns:repeat(2,1fr); }
  .dag-cijfer:nth-child(2n){ border-right:none; }
  .dag-cijfer:nth-child(n+3){ border-top:1px solid var(--border); }
}
@media (max-width:460px){
  .dag-cijfers{ grid-template-columns:1fr; }
  .dag-cijfer{ border-right:none; }
  .dag-cijfer + .dag-cijfer{ border-top:1px solid var(--border); }
}


/* DE GROEIBELONING PER ACCOUNT, MET DRIE TREDES (11-09-2026)
   Twan: "Omzet excl. btw moet je berekenen en dit gaat per account individueel
   en er zijn 3 tredes van staffel." */
.gb-balk{ height:8px; border-radius:4px; background:var(--gray); overflow:visible; position:relative; }
.gb-balk i{ display:block; height:100%; background:var(--primary); border-radius:4px; }
/* Waar je zou moeten staan om op tijd te zijn. Een balk zonder dit streepje
   zegt hoe ver je bent, niet of je op schema ligt. */
.gb-streep{ position:absolute; top:-3px; width:2px; height:14px; background:var(--secondary); }
.gb-trede{ display:grid; grid-template-columns:28px 1fr 120px 100px; gap:12px; align-items:center;
  padding:10px 16px; border-top:1px solid var(--gray); }
.gb-trede.gehaald{ background:#EAF3DE; }
.gb-trede.dichtbij{ background:#FBF1E2; }
.gb-tredenum{ width:24px; height:24px; border-radius:50%; display:grid; place-items:center;
  font-size:11px; font-weight:700; background:var(--gray); color:var(--muted); }
.gb-trede.gehaald .gb-tredenum{ background:#3B6D11; color:#fff; }
.gb-trede.dichtbij .gb-tredenum{ background:#B4700E; color:#fff; }
.gb-velden{ display:flex; gap:16px; flex-wrap:wrap; align-items:flex-end; }
.gb-velden label{ display:flex; gap:6px; align-items:center; }


/* DE KWALITEITSSCORE DOOR DE TIJD (11-09-2026)
   Twan: "Ook mis ik een kwaliteitscore geschiedenis om in te zien." */
.kw-historie{ margin-top:16px; padding-top:16px; border-top:1px solid var(--gray); }
.kw-staven{ display:flex; align-items:flex-end; gap:6px; height:100px; margin-top:10px;
  border-bottom:1px solid var(--gray); }
.kw-staaf{ flex:1; height:var(--hoog,0%); min-height:6px; background:var(--primary-zacht,#EAF1F9);
  border-radius:3px 3px 0 0; position:relative; transform-origin:bottom center;
  animation:staaf-op 260ms cubic-bezier(.22,.61,.36,1) both; animation-delay:var(--wacht,0ms); }
/* Onder de norm is geen kleurtje maar een mededeling: daar staat de
   groeibeloning stil. */
.kw-staaf.onder{ background:#E6C9BD; }
.kw-staaf b{ position:absolute; top:-17px; left:0; right:0; text-align:center;
  font-size:10.5px; font-weight:600; color:var(--tekst-uitleg,#5A657C); }
@media (prefers-reduced-motion: reduce){ .kw-staaf{ animation:none; } }


/* GOEDERENONTVANGST (11-09-2026, volgens het goedgekeurde ontwerp) */
.ont-scan{ display:flex; gap:10px; align-items:center; border:1px dashed var(--primary);
  border-radius:var(--radius-veld,8px); padding:10px 16px; background:var(--primary-zacht,#EAF1F9);
  font-size:13px; }
.ont-scan i{ font-size:18px; color:var(--primary); }
.ont-tabel{ width:100%; border-collapse:collapse; font-size:13px; }
.ont-tabel th{ text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; padding:10px 16px; border-bottom:1px solid var(--gray); }
.ont-tabel th.num, .ont-tabel td.num{ text-align:right; }
.ont-tabel td{ padding:10px 16px; border-bottom:1px solid var(--gray); vertical-align:middle; }
.ont-tabel tr:last-child td{ border-bottom:none; }
.ont-veld{ font-variant-numeric:tabular-nums; }
.ont-merk{ font-size:10.5px; font-weight:700; letter-spacing:.04em; padding:2px 6px;
  border-radius:999px; text-transform:uppercase; white-space:nowrap; }
.ont-merk.ok{ background:#EAF3DE; color:#3B6D11; }
.ont-merk.let{ background:#FBF1E2; color:#B4700E; }
.ont-merk.fout{ background:#F9EBE6; color:#993C1D; }
.ont-merk.zacht{ background:var(--gray); color:var(--muted); }


/* PIM: "kan niet online" is een waarschuwing, geen blokkade (11-09-2026)
   Twan: "Dan moet je enkel aangeven dat het product niet online verkocht kan
   worden omdat dingen missen maar niet volledig blokkeren." */
.pim-waarschuw{ background:#FBF1E2; border-radius:var(--radius-veld,8px); padding:10px;
  font-size:12px; line-height:1.5; color:#7A4E06; margin-top:6px; }
.pim-waarschuw b{ font-weight:600; }

/* PRODUCTTRACKER (/analyse/tracker)
   Twee kolommen op het detailscherm en op Techniek, zoals ontwerp B en D het
   beschrijven ("Links, breed: … Rechts: …"). Verder geen eigen opmaak: de
   tabbladen, kaarten, badges en tabellen zijn die van Concurrenten. */
.tracker-detail-kolommen{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; align-items:start; }
@media (max-width:980px){ .tracker-detail-kolommen{ grid-template-columns:1fr; } }
.tracker-tabel td.num, .tracker-tabel th.num,
.tracker-groep-tabel td.num, .tracker-groep-tabel th.num{ text-align:right; font-variant-numeric:tabular-nums; }
/* De twee kolommen die de producttracker aan de concurrententabel toevoegt
   (C2). Licht getint, zoals het ontwerp vraagt: het is informatie uit een
   ander systeem dan de rest van de tabel. */
.conc-tracker-kolom{ background:#FAFBFD; }
/* De feitenkaarten boven de producttracker-detailpagina: productinformatie,
   verzendgegevens en kosten naast elkaar. Drie kolommen, want het zijn drie
   soorten feiten en ze horen in één oogopslag te lezen. */
.tracker-feiten{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; margin-bottom:12px; }
@media (max-width:980px){ .tracker-feiten{ grid-template-columns:1fr; } }
/* De drie kaarten op de producttracker-detailpagina (aanvulling 2, onderdeel 4):
   Listingveranderingen, Zichtbaarheidsinzichten en Reviewinzichten naast elkaar. */
.tracker-detail-drie{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; align-items:start; }
@media (max-width:1180px){ .tracker-detail-drie{ grid-template-columns:1fr; } }
.tracker-drie-cijfers{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; text-align:center;
  padding:10px 0; border-top:1px solid #F0F1F3; border-bottom:1px solid #F0F1F3; }
.tracker-cijfer{ font-size:17px; font-weight:600; line-height:1.2; }
.tracker-cijfer.rood{ color:#993C1D; } .tracker-cijfer.oranje{ color:#8A6410; } .tracker-cijfer.groen{ color:#1E7A46; }
/* De balkjes van de positie- en sterrenverdeling. */
.tracker-balkrij{ display:flex; align-items:center; gap:8px; padding:2px 0; font-size:11.5px; }
.tracker-balklabel{ min-width:52px; color:var(--muted); }
.tracker-balk{ flex:1; background:#EFEFEF; border-radius:999px; height:7px; overflow:hidden; }
.tracker-balk > span{ display:block; height:100%; background:#2F6FEB; }
.tracker-balkwaarde{ min-width:82px; text-align:right; font-variant-numeric:tabular-nums; }
/* De totalenbalk boven Gevolgd (aanvulling 2, onderdeel 6): zes cijfers over de
   gekozen selectie, op één regel. */
.tracker-totalen{ display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:16px; margin:10px 0; }
@media (max-width:1100px){ .tracker-totalen{ grid-template-columns:repeat(3,minmax(0,1fr)); } }
@media (max-width:620px){ .tracker-totalen{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* ---------- PRODUCTTRACKER: het blok boven de tabel (16-09-2026, B10/B11) ----------

   Ontwerp A en het prototype tonen één kaart met één regel: links invoeren en
   volgen, rechts filteren. Het stond hier in drie regels, met CSV en Kolommen
   als losse knoppen naast Volgen — vier knoppen van gelijk gewicht, terwijl er
   maar één primaire actie is.

   AFWIJKING VAN HET ONTWERP, BEWUST. Het ontwerp tekent een "⋯"-menu. De app
   heeft geen menu dat op een klik opengaat: .nav-dropdown werkt op hover (en is
   op een aanraakscherm dus onbruikbaar) en .office-account-dropdown is de
   accountknop rechtsboven, met eigen kleuren. Daarom hier een klein eigen
   paneel dat de bestaande kaartvormen aanhoudt: dezelfde radius, dezelfde
   schaduw, dezelfde tekstmaten. */
.tracker-werkbalk{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
/* Binnen een helft NIET afbreken: invoer → keuze → actie is één leesregel, en
   een knop die onder zijn eigen invoerveld belandt hoort er niet meer bij.
   Breekt er iets af, dan breekt de balk tussen links en rechts — dat zijn twee
   verschillende handelingen en die mogen wél onder elkaar. */
.tracker-werkbalk-deel{ display:flex; align-items:center; gap:8px; min-width:0; }
.tracker-werkbalk-deel.rechts{ margin-left:auto; }
.tracker-werkbalk .btn-primary{ white-space:nowrap; }

.tracker-menu{ position:relative; }
.tracker-menu-paneel{ position:absolute; right:0; top:calc(100% + 6px); z-index:40; min-width:240px;
  background:#fff; border:0.5px solid var(--border); border-radius:var(--radius-kaart);
  box-shadow:0 4px 16px rgba(0,0,0,0.12); padding:6px; }
.tracker-menu-kop{ font-size:10px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--tekst-uitleg); font-weight:600; padding:10px 10px 6px; }
.tracker-menu-item{ display:flex; align-items:center; gap:8px; width:100%; background:none; border:none;
  text-align:left; font-size:12.5px; color:var(--secondary); padding:10px; border-radius:var(--radius-knop);
  cursor:pointer; }
.tracker-menu-item:hover{ background:var(--gray); }
.tracker-menu-item i{ font-size:14px; color:var(--tekst-uitleg); width:16px; }
.tracker-menu-regel{ display:flex; align-items:center; gap:6px; font-size:12px; padding:6px 10px; cursor:pointer; }
.tracker-menu-regel.vast{ opacity:.5; cursor:default; }

/* Een bewaarde weergave is een tabblad naast de vier filters, met een kruisje
   om hem weg te halen. Het kruisje zit ín de knop, dus als span: een knop in
   een knop bestaat niet in HTML. */
.tracker-tabweg{ margin-left:7px; opacity:.55; font-style:normal; }
.tracker-tabweg:hover{ opacity:1; }

/* VASTE KOLOMBREEDTES (B11). Zonder table-layout:fixed bepaalt de langste
   producttitel hoe breed de kolom Product wordt, en dan staat de rest verdrukt
   — precies wat Twan op de groepspagina zag. */
/* Vaste breedtes plus een minimumbreedte voor de hele tabel: elf kolommen
   passen niet altijd, en dan is horizontaal schuiven (.table-wrap doet dat al)
   beter dan een kolom Product van zestig punten waar niets in past. De
   minimumbreedte wordt in app.js uit de zichtbare kolommen opgeteld. */
.tracker-tabel, .tracker-groep-tabel{ table-layout:fixed; }
.tracker-tabel th, .tracker-tabel td,
.tracker-groep-tabel th, .tracker-groep-tabel td{ overflow:hidden; }
.tracker-tabel .order-titel, .tracker-groep-tabel .order-titel{ max-width:none; }
/* De regels onder de titel zijn bijzin, geen tweede titel: één regel, afgekapt. */
.tracker-tabel .row-sub, .tracker-groep-tabel .row-sub{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
/* De titel in de groepstabel is een link; die moet net zo hard afkappen. */
.tracker-groep-tabel a.order-titel{ display:block; }

/* ---------- PRODUCTTRACKER: de vrije labels (16-09-2026, D17) ----------
   De labelcel in de tabel is klikbaar en opent het keuzelijstje eronder;
   position:relative zodat dat paneel zich aan deze cel ophangt en niet aan de
   tabel. */
.tracker-labelcel{ position:relative; cursor:pointer; }
.tracker-labelcel:hover{ background:#F3F6FB; }
.tracker-labelcel .conc-badge{ margin:1px 2px 1px 0; }

/* ---------- PRODUCTTRACKER: het grafiekcomponent (16-09-2026, E19/E20) ----------
   Vier grafieken met exact dezelfde hoogte, ook als er nog niets gemeten is.
   Zonder die vaste hoogte loopt de rij scheef zodra één grafiek leeg is, en
   dan lijkt de lege de uitzondering terwijl het aan het begin de regel is. */
.tracker-grafiek{ display:flex; flex-direction:column; }
.tracker-grafiek-svg{ display:block; width:100%; }
.tracker-grafiek-kop{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin-bottom:2px; }
.tracker-grafiek-waarde{ font-size:22px; font-weight:600; line-height:1.1; font-variant-numeric:tabular-nums; }
/* 13 px: een lege staat is tekst die je moet lézen, en die hoort op de
   basisgrootte (ontwerpprincipes §4/§5b), niet op tabelgrootte. */
.tracker-grafiek-leeg{ display:flex; align-items:center; justify-content:center; text-align:center;
  padding:0 24px; font-size:13px; }
/* De vier cijferkaarten op de producttracker-detailpagina staan op één rij
   (E18). .stat-cards is een raster van drie; een vierde kaart zou als wees op
   een tweede rij belanden. */
.stat-cards.tracker-vier{ grid-template-columns:repeat(4,minmax(0,1fr)); }
@media (max-width:1180px){ .stat-cards.tracker-vier{ grid-template-columns:repeat(2,minmax(0,1fr)); } }

/* ---------- HET MELDINGENLOG ONDER EEN BELLETJE (16-09-2026) ----------
   Twan: "kunnen we die niet zoals de webapp onder een icoontje wegdrukken in
   een balk?" Het log stond op het dashboard, in dezelfde vouw als drie
   grafieken. Nu hangt het hier, naast de storingsbalk en de statuspil.

   De badge telt alleen fouten en waarschuwingen. Een badge die "34" zegt over
   34 gewone mededelingen leer je negeren, en dan mis je de ene die telt. */
.meld-bel{ position:relative; display:flex; align-items:center; }
.meld-bel-knop{ background:none; border:none; cursor:pointer; padding:6px; border-radius:var(--radius-knop);
  color:rgba(255,255,255,0.86); display:flex; align-items:center; position:relative; line-height:1; }
.meld-bel-knop:hover{ background:rgba(0,0,0,0.18); color:#fff; }
.meld-bel-knop i{ font-size:18px; }
.meld-bel-knop.heeft-fout i{ color:#FFC9B4; }
.meld-bel-telling{ position:absolute; top:0; right:0; background:#C40002; color:#fff; font-size:9px;
  font-weight:600; border-radius:999px; padding:1px 4px; min-width:16px; text-align:center; }
.meld-bel-paneel{ position:absolute; right:0; top:calc(100% + 8px); z-index:70; width:420px; max-width:90vw;
  background:#fff; border-radius:var(--radius-kaart); box-shadow:0 8px 28px rgba(23,34,58,.18);
  color:var(--secondary); overflow:hidden; }
.meld-bel-kop{ display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:10px 16px; border-bottom:0.5px solid var(--border); font-size:12.5px; font-weight:500; }
.meld-bel-paneel .notif-list{ max-height:min(60vh,460px); overflow:auto; padding:6px 10px; }
.meld-bel-voet{ padding:10px 16px; border-top:0.5px solid var(--border); font-size:11.5px; }
@media (max-width:620px){ .meld-bel-paneel{ position:fixed; right:10px; left:10px; width:auto; } }
/* De labelcel is met Tab te bereiken (ontwerpprincipes §4); dan hoort de focus
   ook zichtbaar te zijn — hover mag nooit de enige aanwijzing zijn. */
.tracker-labelcel:focus-visible{ outline:2px solid var(--primary); outline-offset:-2px; }

/* ---------- EEN SKELET DAT NIET EEUWIG BLIJFT STAAN (16-09-2026) ----------
   Ontwerpprincipes §4: na 10 seconden een uitleg met een knop om opnieuw te
   laden. Zelfde binnenmarges als een kaart, zodat de terugval op de plek van
   het skelet niet opvalt als een ander soort blok. */
.skelet-terugval{ padding:24px 16px; text-align:center; font-size:13px; }
.skelet-terugval .tag-muted{ font-size:12px; margin-top:4px; display:block; }

/* De gele balk van de testomgeving (public/js/omgeving.js). Kleefbalk boven
   alles; het inlogscherm (position:fixed) schuift mee via de klasse op <html>.
   Alleen bestaande waarden: de let-op-kleuren, de
   klikdoelhoogte en de standaardruimte uit de bouwdoos. */
.testomgeving-balk{ position:sticky; top:0; z-index:1000; height:var(--klikdoel); line-height:var(--klikdoel);
  padding:0 var(--ruimte); background:var(--letop-vlak); color:var(--letop-tekst); font-size:var(--tekst-tabel); font-weight:600;
  text-align:center; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.is-testomgeving .sales-view{ top:var(--klikdoel); }
