: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);
  --radius-knop: 5px;
  --radius-veld: 8px;
  --radius-kaart: 12px;

  /* 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 (.ads-warning::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; }
.login-form input, .login-form select{ font-size:14px; padding:12px 14px; 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:12px 14px; 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). */
.office-header{ background:var(--primary); padding:14px 22px; display:flex; align-items:center; justify-content:space-between; flex-shrink:0; }
.office-incident-bar{ display:none; align-items:center; gap:8px; background:var(--secondary); color:#fff; padding:7px 22px; font-size:12.5px; flex-shrink:0; }
.office-incident-bar.show{ display:flex; }
.office-incident-bar i{ font-size:14px; color:#FFD166; }
.office-incident-link{ background:none; border:none; color:#fff; text-decoration:underline; cursor:pointer; font-size:12.5px; padding:0; margin-left:2px; font-family:inherit; }
.office-header-left{ display:flex; align-items:center; gap:22px; }
.office-brand{ display:flex; align-items:center; gap:9px; }
.office-brand-logo{ width:28px; height:28px; border-radius:8px; background:#fff; color:var(--secondary); font-size:12px; font-weight:700; display:flex; align-items:center; justify-content:center; }
.office-brand-title{ font-size:16px; font-weight:500; color:#fff; }
.tabs{ display:flex; gap:4px; }
.tabs button{ background:transparent; border:none; font-size:13px; font-weight:500; padding:8px 14px; border-radius:var(--radius-knop); cursor:pointer; color:rgba(255,255,255,0.68); }
.tabs button.active{ background:rgba(255,255,255,0.16); 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 5px; 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:#9aa0a8; font-weight:600; padding:8px 10px 4px; }
.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:9px 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:#9aa0a8; width:16px; }
/* 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 14px; font-size:12px; margin-bottom:16px; }
.analyse-demo-banner i{ font-size:15px; flex-shrink:0; }
.niche-chip{ font-size:11.5px; padding:6px 12px; 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; }
.analyse-caveat{ background:#FAECE7; color:#993C1D; border-radius:var(--radius-kaart); padding:10px 14px; 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:8px 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:12px; 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:#6b7280; font-size:11px; padding:4px 9px; 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 14px; font-size:12px; line-height:1.6; margin-top:10px; }
.office-header-right{ display:flex; align-items:center; gap:12px; }
/* .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:5px 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:5px 10px; font-size:12px; }
.btn-soft{ display:flex; align-items:center; gap:7px; background:#EAF0F8; color:var(--primary); border:none; font-size:13px; padding:9px 14px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; }
.office-header .btn-soft{ background:rgba(255,255,255,0.14); color:#fff; }
.account-label{ font-size:12px; color:#6b7280; }
.office-header .account-label{ color:rgba(255,255,255,0.65); }
.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. */
.office-header .avatar{ background:rgba(255,255,255,0.22); 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:9px 12px; 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 12px 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 14px; 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:#9aa0a8; 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. */
.refresh-status-pill{ display:inline-flex; align-items:center; gap:7px; max-width:340px; padding:4px 10px; border-radius:999px; background:rgba(255,255,255,0.14); 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(255,255,255,0.22); }
.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; }
@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:22px 26px; 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); }
.modal-close{ background:transparent; border:none; color:#9aa0a8; cursor:pointer; font-size:18px; }
.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; }
.btn-outline{ background:transparent; border:0.5px solid #e3e4e6; color:#6b7280; font-size:13px; padding:9px 16px; border-radius:var(--radius-knop); cursor:pointer; }
.btn-primary{ background:var(--primary); color:#fff; border:none; font-size:13px; padding:9px 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:9px 16px; border-radius:var(--radius-knop); cursor:pointer; font-weight:500; }
.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:#6b7280; 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 8px; 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:#6b7280; }
.field-col input, .field-col select{ width:100%; box-sizing:border-box; font-size:12px; padding:8px 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:7px 10px; margin-bottom:5px; font-size:12px; }
.auto-row b{ color:var(--secondary); font-weight:500; }
.note{ font-size:10.5px; color:#9aa0a8; 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:#9aa0a8; font-weight:400; font-size:10.5px; }
.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:8px 4px; border-radius:var(--radius-knop); cursor:pointer; background:#fff; color:#6b7280; }
.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:#6b7280; font-size:12px; min-width:30px; height:28px; padding:0 8px; 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 12px; 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 12px; }
/* 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:12px 14px; 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:14px 15px; 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:#6b7280; }
.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:#6b7280; }
/* 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:5px 7px; 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:#9aa0a8; 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:#6b7280; border:none; box-shadow:var(--schaduw-kaart); font-size:12px; padding:7px 14px; 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:11px 13px; 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; }
.notif-dismiss{ flex-shrink:0; opacity:0.45; font-size:15px; line-height:1; padding:2px 4px; }
.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:#6b7280; text-align:left; font-weight:400; padding:8px 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:9px 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:5px 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:#9aa0a8; 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 12px; 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; }
.chan-badge{ font-size:9.5px; font-weight:500; padding:3px 7px; 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". */
.chan-shop{ background:#96BF43; color:#fff; }
.status-ok{ background:#EAF3DE; color:#3B6D11; font-size:10.5px; font-weight:500; padding:3px 8px; border-radius:999px; }
.status-bad{ background:#FAECE7; color:#993C1D; font-size:10.5px; font-weight:500; padding:3px 8px; 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 8px; 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:12px 15px; 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 15px 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:#6b7280; 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:#6b7280; flex-shrink:0; }
.row-title{ font-size:13px; color:var(--secondary); }
.row-sub{ font-size:11px; color:#9aa0a8; }
.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:7px 11px; 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 18px; 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; }
.ads-warning{ display:none; color:#FFD166; font-size:13px; position:relative; cursor:help; }
.ads-warning.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. */
.ads-warning[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: 8px 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;
}
.ads-warning[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:14px 18px; 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:8px 9px; box-shadow:var(--schaduw-kaart); }
.metric-label{ font-size:9.5px; color:#6b7280; }
.metric-value{ font-size:15px; font-weight:500; color:var(--secondary); }
.flex-card{ padding:9px 12px; flex:1; min-height:0; min-width:0; overflow:hidden; }
.card-label{ font-size:11px; color:#6b7280; 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:#9aa0a8; 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:#9aa0a8; 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:#6b7280; 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); }
.hbar-label{ font-size:7.5px; color:#9aa0a8; margin-top:2px; line-height:1; height:8px; }
.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:#6b7280; 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:#9aa0a8; margin-bottom:6px; }
.secondary-grid{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:14px; flex:1; min-height:0; }
.center-card{ padding:11px 12px; 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:#9aa0a8; }
.stock-row{ display:flex; align-items:center; gap:6px; font-size:10.5px; }
.stock-badge{ font-size:8.5px; font-weight:500; padding:2px 5px; border-radius:999px; flex-shrink:0; }
.cost-row{ display:flex; justify-content:space-between; gap:5px; font-size:10.5px; color:#6b7280; }
.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; }
.ads-banner{ background:#FAECE7; color:#993C1D; font-size:9.5px; border-radius:var(--radius-kaart); padding:5px 8px; 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:5px 8px; 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:5px 9px; 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; }
.tab-badge{ display:inline-block; background:#F70103; color:#fff; font-size:9px; font-weight:600; border-radius:999px; padding:1px 5px; 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:#6b7280; }

/* 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:5px 7px; max-width:90px; }
.conversion-chart-empty{ font-size:10px; color:#9aa0a8; padding:4px 0; }
.conversion-table-head{ display:flex; justify-content:space-between; font-size:9.5px; color:#9aa0a8; 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. */
.euro-chart-svg{ width:100%; max-width:1150px; 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:8px 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:8px 22px 8px 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:#9aa0a8; }
.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. .ad-table 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. */
.ad-table{ table-layout:fixed; }
.ad-table td, .ad-table th{ padding:12px 10px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ad-table 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. */
.ad-th-sortable{ cursor:pointer; user-select:none; }
.ad-th-sortable:hover{ color:var(--secondary); }
.ad-sort-arrow{ font-size:9px; color:#c7cad1; margin-left:2px; }
.ad-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:#9aa0a8; 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 14px; 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:8px 11px; 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:#9aa0a8; 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:#9aa0a8; 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:#6b7280; 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:#6b7280; border:none; box-shadow:var(--schaduw-kaart); font-size:12.5px; font-weight:500; padding:8px 14px; 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; }
.wms-subnav button.active .cnt{ background:rgba(255,255,255,0.25); }

.wms-banner{ display:flex; align-items:center; gap:8px; border-radius:var(--radius-kaart); padding:10px 14px; 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 20px; text-align:center; color:#9aa0a8; 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 8px; 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. */
.pick-list{ display:flex; flex-direction:column; gap:12px; max-width:1300px; margin:0 auto; }
.pick-row{ background:#fff; 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 8px; border-radius:999px; background:var(--gray); color:#6b7280; 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:9px 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:5px 8px; font-size:10.5px; color:#6b7280; 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; }

.wms-qty-badge{ font-weight:700; padding:2px 8px; 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 8px; 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 7px; 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:13px 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:#9aa0a8; 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 11px; border-radius:999px; background:var(--gray); color:#9aa0a8; }
.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:#6b7280; margin:0 0 4px; text-transform:uppercase; letter-spacing:.03em; }
.item-pick-row{ display:flex; align-items:center; gap:12px; padding:12px 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:#9aa0a8; margin-top:2px; display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.item-pick-progress{ font-size:12px; color:#6b7280; 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:9px 12px; 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:14px; 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:#6b7280; 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:#9aa0a8; 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:#9aa0a8; }
.vvb-deadline-box{ background:#FFF7EC; box-shadow:var(--schaduw-kaart); border-radius:var(--radius-kaart); padding:12px 14px; 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:9px 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:#6b7280; }

.bulk-bar{ background:#EAF0F8; border:0.5px solid #cfe0f2; border-radius:var(--radius-kaart); padding:12px 16px; display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:12px; }
.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 14px; font-size:11.5px; color:#6b7280; 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:#6b7280; }

.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; }
.conn-chip{ font-size:11px; padding:5px 10px; border-radius:999px; border:none; box-shadow:var(--schaduw-kaart); background:#fff; color:#9aa0a8; cursor:pointer; display:inline-flex; align-items:center; gap:5px; }
.conn-chip.on{ background:#EAF3DE; border-color:#c9e2ae; color:#3B6D11; font-weight:500; }
.conn-matrix-label{ font-size:10.5px; color:#9aa0a8; 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:14px; 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:11px 14px; }
.loc-row .code{ font-size:12.5px; font-weight:500; background:var(--gray); padding:3px 8px; border-radius:var(--radius-veld); }
.loc-row .om{ flex:1; font-size:12px; color:#6b7280; }
.loc-row-toggle{ display:inline-flex; align-items:center; gap:3px; font-size:10.5px; color:#6b7280; background:none; border:none; cursor:pointer; padding:0; }
.loc-row-toggle:hover{ color:var(--primary); }
.loc-row-products{ padding:0 14px 12px 14px; }
.zv-row{ display:flex; align-items:center; gap:10px; padding:10px 14px; 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:12px 0; }
.hist-list{ display:flex; flex-direction:column; gap:4px; font-size:11.5px; color:#6b7280; 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:8px 11px; 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:7px 8px; 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:#6b7280; }
.wms-locpick-empty{ padding:10px 8px; font-size:12px; color:#6b7280; 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:#9aa0a8; }
.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 12px; 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 9px; 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:8px 10px; }
.prest-kengetal .l{ font-size:10.5px; color:#9aa0a8; 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:#9aa0a8; font-variant-numeric:tabular-nums; }
.prest-dagtabel{ font-size:11.5px; }
.prest-dagtabel td, .prest-dagtabel th{ padding:4px 8px; 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:9px 12px; 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:7px 9px; 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 18px; 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 8px; }

/* 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:11px 16px; font-size:12px; color:#6b7280;
  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:#9aa0a8; 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 14px; font-size:12px; line-height:1.55; color:#6b7280;
  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:#6b7280; 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:#6b7280;
}
.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); }

.dash-verloop-svg{ width:100%; height:132px; 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. */
.panel{
  padding:22px max(22px, calc((100% - 1600px) / 2));
  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{
  position:sticky; top:0; z-index:30;
}
.data-table thead th,
.data-table > tbody > tr:first-child > th,
.data-table > tr:first-child > th{
  top:var(--kopbalk-hoogte, 0px);
}

/* ===================== 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:#9aa0a8; margin-top:4px; font-variant-numeric:tabular-nums; }
.pv-basis{ padding:14px 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:#9aa0a8; }
.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:5px 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:#9aa0a8; 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:11px 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:#9aa0a8; 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:#9aa0a8; 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 9px; 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:#9aa0a8; }
/* 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:11px 14px; }
.order-totaal-label{ font-size:11px; color:#9aa0a8; }
.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:12px 14px; 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 8px 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:#b9bec6; 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 14px; 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 8px; border-radius:999px; }
.badge-oranje{ background:#FAEEDA; color:#8A5A11; font-size:10.5px; font-weight:500;
  padding:3px 8px; 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:13px 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:#9aa0a8; font-size:10.5px; margin-top:1px; }
.inkoop-stap.gedaan .inkoop-stap-sub{ color:#6b7280; }
.inkoop-bijna{ color:#2864AE; font-weight:500; }
.inkoop-melding{ background:rgba(40,100,174,0.07); border-radius:var(--radius-veld); padding:8px 11px;
  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; }

/* 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:8px 11px;
  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:7px 11px;
  margin-top:6px; font-size:11.5px; color:#4b5563; }
.inkoop-marge strong{ color:#3B6D11; }

/* ================= PRODUCTPRESTATIES: waterval en kerngetallen ================= */
.prestaties-waterval{ padding:14px 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 14px; }
.prest-kern-label{ font-size:11px; color:#9aa0a8; }
.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 7px; border-radius:999px; }
.prest-bewegingen{ padding:14px 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:#9aa0a8; font-size:11px; }
.retour-heeft-notitie{ font-size:10px; color:#9aa0a8; margin-top:1px; }
.retour-detailrij td{ padding:0 10px 12px !important; }
.retour-detail{ background:var(--gray); border-radius:var(--radius-kaart); padding:12px 14px; }
.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:#9aa0a8; 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:8px 11px; 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 8px; border-radius:999px; }
/* Waar ging advertentiegeld heen zonder omzet — zie adGeldVerdweenHtml. */
.ad-zonder-omzet{ padding:13px 16px; margin-bottom:12px; max-width:1200px; }
.ad-zonder-omzet--kort{ background:#FAECE7; box-shadow:none; }
.ad-zonder-lijst{ display:flex; flex-direction:column; gap:2px; margin-top:4px; }
.ad-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); }
.ad-zonder-rij:last-child{ border-bottom:none; }
.ad-zonder-naam{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:#4b5563; }
.ad-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:12px 15px; }
.kpi-groepkop{ font-size:10px; letter-spacing:.07em; text-transform:uppercase; color:#9aa0a8; 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:#6b7280; }
/* 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:#9aa0a8; }
.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:12px 15px;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 7px;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:9px 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:14px;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 7px;border-radius:20px;
  background:#e8eef7;color:#2864AE;text-transform:none;letter-spacing:0;
}
.pil-klasse{
  font-size:11px;padding:1.5px 8px;border-radius:20px;background:#f2f3f5;
  border:0.5px solid #e3e4e6;margin:0 6px;
}
.stapel-ai{
  margin-top:12px;padding:11px 14px;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:13px 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:11px 14px;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 8px}
.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 5px}


/* ---------- Overlap per webshop ---------- */
.winkel-rij{border:0.5px solid #e3e4e6;border-radius:10px;padding:12px 15px;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 18px;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 9px;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:11px 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:8px 12px;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:11px 14px;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 9px;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 14px 11px}
.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 14px 14px;border-top:1px solid #f0f1f3}
.conc-art-detail .data-table{margin-top:10px}
.conc-buiten{margin-top:10px;padding:9px 12px;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 8px;border-radius:20px;background:#e8eef7;color:#2864AE;white-space:nowrap}
.pil-inactief{font-size:10.5px;padding:2px 8px;border-radius:20px;background:#f2f3f5;color:var(--muted);border:0.5px solid #e3e4e6;white-space:nowrap}
.conc-jouwkant{background:#f7f8fa;border-radius:8px;padding:9px 12px;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:7px 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 9px;border:0.5px solid #e3e4e6;border-radius:7px}
.gemeten-ok{background:#e8f0ea;color:#2F6B4F;border-radius:8px;padding:8px 12px;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:8px 11px;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:12px 15px;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:7px 10px;border:0.5px solid #c3d9ca;border-radius:7px;background:#fff}
