:root{
  --navy-950:#050b1a;
  --navy-900:#0a1330;
  --blue-800:#123a9e;
  --blue-700:#123a9e;
  --blue-600:#1547c9;
  --blue-500:#1d5fe0;
  --blue-100:#e6efff;
  --ink:#0b1327;
  --gray-700:#33415e;
  --gray-600:#5a6a8c;
  --gray-500:#7c88a8;
  --gray-300:#c7d0e2;
  --gray-100:#eef1f8;
  --gray-50:#f5f7fc;
  --bg-light:#f3f6fc;
  --white:#ffffff;
  --radius:14px;
  --shadow:0 14px 34px rgba(10,19,48,0.12);
  --green:#16a34a;
  --amber:#d97706;
  --red:#dc2626;
}

/* Donkere modus: overschrijft alleen de kleur-variabelen hierboven. Omdat
   vrijwel alle componenten in dit bestand via var(--xxx) werken (panels,
   tabellen, knoppen, sidebar, modals, kalender...) volstaat dit voor het
   overgrote deel van de UI, zonder elke losse regel te hoeven aanpassen.
   Een klein aantal losse, inline gekleurde meldingsboxen in de templates
   (groene/rode succes-/foutmeldingen) gebruikt geen variabelen en blijft
   dus zijn eigen vaste kleur houden -- die blijven prima leesbaar, maar
   zijn geen exacte thema-match. [data-theme="dark"] staat op <html>, zodat
   dit overal cascadeert zonder dat elke pagina zijn eigen class nodig heeft. */
[data-theme="dark"]{
  --navy-950:#03060f;
  --navy-900:#070d1e;
  --blue-800:#3b6fe0;
  --blue-700:#4c7ce8;
  --blue-600:#3f7ae0;
  --blue-500:#5a8ff0;
  --blue-100:#16264d;
  --ink:#e7ecf7;
  --gray-700:#c2cbe3;
  --gray-600:#9aa6c4;
  --gray-500:#8892b3;
  --gray-300:#2b3556;
  --gray-100:#182142;
  --gray-50:#141b38;
  --bg-light:#080d1c;
  --white:#101833;
  --shadow:0 14px 34px rgba(0,0,0,0.45);
  --green:#22c55e;
  --amber:#f59e0b;
  --red:#f87171;
}
[data-theme="dark"] body{background:var(--bg-light);}
/* Statuspillen (groen/amber/rood/paars) en de zon/maan-iconen gebruiken
   vaste pastelkleuren, niet de bovenstaande variabelen -- die worden hier
   apart iets gedimd zodat ze niet te fel afsteken tegen de donkere achtergrond. */
[data-theme="dark"] .pill-green{background:#0f2e1c;color:#4ade80;}
[data-theme="dark"] .pill-amber{background:#3a2708;color:#fbbf24;}
[data-theme="dark"] .pill-red{background:#3a1212;color:#fca5a5;}
[data-theme="dark"] .pill-purple{background:#241a42;color:#c4b5fd;}
[data-theme="dark"] .pill-blue{background:var(--blue-100);color:#9db8f5;}

/* Functiebadges (rol-labels), notificatie-iconen, overdracht-banner en de
   gemarkeerde logboek-rij gebruiken dezelfde vaste-pastelkleur-aanpak --
   ook hier alleen gedimd voor donkere modus, niet vervangen. */
[data-theme="dark"] .role-beheerder{background:#241a42;color:#c4b5fd;}
[data-theme="dark"] .role-regiecentralist{background:#16264d;color:#93b4f5;}
[data-theme="dark"] .role-planner{background:#0d3339;color:#67e8f9;}
[data-theme="dark"] .role-teamleider{background:#0f2e1c;color:#4ade80;}
[data-theme="dark"] .role-projectleider{background:#3a2708;color:#fbbf24;}
[data-theme="dark"] .role-controleur{background:#3a1230;color:#f472b6;}
[data-theme="dark"] .role-klant{background:#0c2a3d;color:#7dd3fc;}
[data-theme="dark"] .role-onderaannemer{background:#3a2010;color:#fdba74;}
[data-theme="dark"] .notif-item.unread{background:#12193a;}
[data-theme="dark"] .notif-ico.green{background:#0f2e1c;}
[data-theme="dark"] .notif-ico.red{background:#3a1212;}
[data-theme="dark"] .notif-ico.amber{background:#3a2708;}
[data-theme="dark"] .notif-ico.purple{background:#241a42;}
[data-theme="dark"] .handover-banner{background:#2b1d08;border-color:#5c3d0f;}
[data-theme="dark"] .handover-banner-head h3,[data-theme="dark"] .handover-meta{color:#fbbf24;}
[data-theme="dark"] .handover-text,[data-theme="dark"] .handover-history-item{color:#fcd9a8;}
[data-theme="dark"] .handover-history{border-color:#5c3d0f;}
[data-theme="dark"] .handover-history-item{border-color:#4a3110;}
[data-theme="dark"] .handover-history summary{color:#fbbf24;}
[data-theme="dark"] .numlist-row.heeft-logboek{background:#1c1533;border-left-color:#a78bfa;}
[data-theme="dark"] .modal-danger-btn{background:#dc2626;}
[data-theme="dark"] .modal-danger-btn:hover{background:#b91c1c;}

/* Losse inline gekleurde meldingsboxen (succes/fout/waarschuwing/info) in de
   templates zelf -- die gebruiken geen variabelen, dus deze substring-
   attribuutselectors vangen ze allemaal in één keer af zonder dat elk van
   de tientallen templates aangepast hoeft te worden. !important is hier
   bewust nodig: een inline style wint anders altijd van een los stylesheet,
   ongeacht specificiteit. */
[data-theme="dark"] [style*="background:#dcfce7"]{background:#0f2e1c !important;color:#4ade80 !important;}
[data-theme="dark"] [style*="background:#fef3c7"]{background:#3a2708 !important;color:#fbbf24 !important;}
[data-theme="dark"] [style*="background:#fee2e2"]{background:#3a1212 !important;color:#fca5a5 !important;}
[data-theme="dark"] [style*="background:#fef2f2"]{background:#3a1212 !important;color:#fca5a5 !important;}
[data-theme="dark"] [style*="background:#eef2ff"]{background:#1c2145 !important;color:#a5b4fc !important;}
[data-theme="dark"] [style*="background:#ede9fe"]{background:#241a42 !important;color:#c4b5fd !important;}

/* De bel en de thema-schakelaar staan altijd in de donkere navy sidebar
   (ook in donkere modus): een net iets lichter, duidelijk begrensd cirkeltje
   houdt hier meer contrast dan de algemene --white/--gray-100-variabelen. */
[data-theme="dark"] .notif-bell,[data-theme="dark"] .theme-toggle{
  background:#182142;border-color:#2b3556;color:#c2cbe3;
}
[data-theme="dark"] .notif-bell:hover,[data-theme="dark"] .theme-toggle:hover{
  border-color:var(--blue-500);color:var(--blue-500);
}

*{box-sizing:border-box;}
body{
  margin:0;font-family:"Inter",Arial,Helvetica,sans-serif;color:var(--ink);
  background:var(--bg-light);line-height:1.6;-webkit-font-smoothing:antialiased;
}
a{color:inherit;text-decoration:none;}
ul{margin:0;padding:0;list-style:none;}
h1,h2,h3,h4{margin:0 0 .4em;font-weight:800;}
p{margin:0;color:var(--gray-600);}
img{max-width:100%;display:block;}

.proto-banner{
  background:var(--navy-950);color:#ffd580;font-size:12.5px;font-weight:700;
  text-align:center;padding:8px 16px;letter-spacing:.02em;
}

/* App shell */
.app-shell{display:flex;min-height:100vh;}
.sidebar{
  width:320px;flex:none;background:var(--navy-950);color:#93a4c9;
  display:flex;flex-direction:column;padding:20px 16px;
}
/* Logo + de 3 topbar-knoppen (zoeken/thema/bel) op 1 rij naast elkaar --
   de sidebar is met opzet verbreed naar 320px (was 230px) om hier ruimte
   voor te maken. De knoppen zelf zijn iets kleiner gemaakt (34px i.p.v.
   38px, kleinere tussenruimte) en de merknaam krijgt ellipsis (...) i.p.v.
   lelijk af te breken/over te lopen als het toch een keer krap wordt, bijv.
   bij een extra lange rolnaam. De brand-blok had voorheen een extra grote
   padding-bottom (22px), waardoor hij hoger was dan de knoppen-rij en de
   knoppen (door align-items:center) lager uitkwamen dan de logo -- nu
   gelijke padding rondom zodat alles op 1 lijn staat. */
.sidebar-topbar{display:flex;align-items:center;justify-content:space-between;gap:8px;}
.sidebar .brand{display:flex;align-items:center;gap:10px;padding:6px 8px;flex:1;min-width:0;}
.sidebar .brand img{width:34px;height:34px;border-radius:9px;flex:none;}
.sidebar .brand-name{color:#fff;font-weight:800;font-size:14.5px;line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sidebar .brand-sub{font-size:9px;letter-spacing:.08em;color:#6e7ea3;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.sidebar-topbar-icons{display:flex;align-items:center;gap:6px;flex:none;}
/* Hamburger-menuknop: alleen zichtbaar op mobiel (zie media query onderaan).
   Op desktop blijft de volledige navigatie altijd zichtbaar, dus daar is
   geen knop nodig -- display:none hier zorgt dat 'ie het middelste kind van
   .sidebar-topbar niet meetelt in de flex-verdeling op desktop. */
.mobile-menu-toggle{
  display:none;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:9px;border:1px solid #2b3556;background:#141d3d;
  color:#c2cbe3;cursor:pointer;flex:none;
}
.mobile-menu-toggle svg{width:19px;height:19px;}
/* display:contents = deze wrapper telt niet mee in de layout: sidebar-nav
   en sidebar-foot gedragen zich op desktop precies als vóór deze wrapper
   werd toegevoegd (rechtstreekse flex-children van .sidebar, verticaal
   gestapeld). Pas in de mobiele media query wordt dit een echt in-/uitklap-
   paneel. */
.mobile-menu-panel{display:contents;}
.sidebar-legal-links{margin-top:10px;font-size:10.5px;line-height:1.8;}
.sidebar-legal-links a{color:#8792a8;}
/* Rodapé met juridische links -- staat wel altijd in de DOM (voor SEO/
   toegankelijkheid), maar is op desktop verborgen omdat diezelfde links
   daar al in de sidebar-voet staan (.sidebar-legal-links hierboven). */
.mobile-legal-footer{display:none;}
.sidebar-nav{flex:1;display:flex;flex-direction:column;gap:4px;}
.sidebar-nav a{
  display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:9px;
  font-size:13.5px;font-weight:600;color:#93a4c9;
}
.sidebar-nav a svg{width:18px;height:18px;flex:none;}
.sidebar-nav a:hover{background:rgba(255,255,255,.06);color:#fff;}
.sidebar-nav a.active{background:var(--blue-600);color:#fff;}

/* Submenu's (Rooster/Personeel/Klanten/Uren & financieel/Beheer) -- het
   beheerder-menu was uitgegroeid naar ~19 losse items, dit groepeert ze
   thematisch. De toggle-knop hergebruikt exact de opmaak van .sidebar-nav a
   (zelfde padding/kleur/hover), maar is een <button> i.p.v. <a> omdat hij
   niets navigeert. */
.sidebar-group{display:flex;flex-direction:column;}
.sidebar-group-toggle{
  display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border-radius:9px;
  font-size:13.5px;font-weight:600;color:#93a4c9;background:none;border:none;cursor:pointer;
  font-family:inherit;text-align:left;
}
.sidebar-group-toggle svg:first-child{width:18px;height:18px;flex:none;}
.sidebar-group-toggle:hover{background:rgba(255,255,255,.06);color:#fff;}
.sidebar-group-label{flex:1;}
.sidebar-group-chevron{flex:none;transition:transform .15s;}
.sidebar-group.open > .sidebar-group-toggle .sidebar-group-chevron{transform:rotate(180deg);}
.sidebar-subnav{
  display:none;flex-direction:column;gap:2px;margin:2px 0 4px 25px;padding-left:11px;
  border-left:1px solid #1c2740;
}
.sidebar-group.open .sidebar-subnav{display:flex;}
.sidebar-subnav a{padding:8px 10px;font-size:12.8px;}
.sidebar-foot{border-top:1px solid #1c2740;padding-top:14px;margin-top:14px;}
.sidebar-user{display:flex;align-items:center;gap:10px;padding:6px 8px;}
.avatar{
  width:34px;height:34px;border-radius:50%;background:var(--blue-600);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12.5px;flex:none;
}
/* Profielfoto i.p.v. initialen (zie gebruiker_dossier.html) -- zelfde
   afmeting/vorm als .avatar, maar dan een <img> met object-fit zodat een
   niet-vierkante foto toch netjes rond bijgesneden wordt. */
.avatar-foto{object-fit:cover;background:var(--gray-100);}
.sidebar-user-name{color:#fff;font-size:13px;font-weight:700;}
.sidebar-user-role{font-size:11px;color:#6e7ea3;}
.logout-link{display:block;margin-top:10px;font-size:12.5px;color:#93a4c9;padding:6px 8px;}
.logout-link:hover{color:#fff;}

.main{flex:1;min-width:0;display:flex;flex-direction:column;}
.topbar-app{
  background:var(--white);border-bottom:1px solid var(--gray-100);padding:16px 28px;
  display:flex;align-items:center;justify-content:space-between;
}
.topbar-app h1{font-size:19px;margin:0;}
.topbar-app .sub{font-size:12.5px;color:var(--gray-600);margin-top:2px;}
.topbar-right{display:flex;align-items:center;gap:14px;}
/* Optionele wrapper voor kop-actieknoppen die op mobiel anders geordend
   moeten worden (zie rooster.html + de @media-regel onderaan dit bestand).
   display:contents = op desktop volledig onzichtbaar/transparant, de
   knoppen erin gedragen zich gewoon als rechtstreekse kinderen van
   .topbar-right, exact zoals vóór deze wrapper bestond. */
.topbar-actions-mobile{display:contents;}
.content{padding:26px 28px 60px;}

/* client env banner */
.client-banner{
  background:var(--blue-100);color:var(--blue-800);border:1px solid #c7d9fb;
  border-radius:var(--radius);padding:14px 18px;font-size:13.5px;font-weight:600;
  display:flex;align-items:center;gap:10px;margin-bottom:22px;
}

/* stat cards */
.stat-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:26px;}
.stat-card{background:var(--white);border:1px solid var(--gray-100);border-radius:var(--radius);padding:18px 20px;}
.stat-card .label{font-size:12.5px;color:var(--gray-600);font-weight:600;margin-bottom:8px;}
.stat-card .value{font-size:26px;font-weight:800;color:var(--ink);}
.stat-card .delta{font-size:11.5px;color:var(--green);font-weight:700;margin-top:4px;}
@media (max-width:1000px){.stat-cards{grid-template-columns:1fr 1fr;}}

/* panels */
.panel{background:var(--white);border:1px solid var(--gray-100);border-radius:var(--radius);padding:22px 24px;margin-bottom:22px;}
.panel-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;}
.panel-head h3{font-size:15.5px;margin:0;}

/* buttons */
.pbtn{
  display:inline-flex;align-items:center;gap:8px;padding:10px 18px;border-radius:9px;
  font-weight:700;font-size:13.5px;border:1px solid transparent;cursor:pointer;
}
.pbtn-primary{background:var(--blue-600);color:#fff;}
.pbtn-primary:hover{background:var(--blue-800);}
.pbtn-outline{background:var(--white);border:1px solid var(--gray-300);color:var(--ink);}
.pbtn-outline:hover{border-color:var(--blue-500);color:var(--blue-700,#123a9e);}

/* table */
.ptable{width:100%;border-collapse:collapse;font-size:13.5px;}
.ptable th{text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--gray-600);padding:10px 12px;border-bottom:1px solid var(--gray-100);}
.ptable td{padding:12px;border-bottom:1px solid var(--gray-100);color:var(--ink);}
.ptable tr:last-child td{border-bottom:none;}

/* badges / pills */
.pill{display:inline-flex;align-items:center;padding:4px 11px;border-radius:20px;font-size:11.5px;font-weight:700;}
.pill-blue{background:var(--blue-100);color:var(--blue-800);}
.pill-green{background:#dcfce7;color:#15803d;}
.pill-amber{background:#fef3c7;color:#92400e;}
.pill-red{background:#fee2e2;color:#b91c1c;}
.pill-gray{background:var(--gray-100);color:var(--gray-700);}
.pill-purple{background:#ede9fe;color:#5b21b6;}

/* klantcontact / ticketsysteem (item 4/5) */
.conv-list{border:1px solid var(--gray-100);border-radius:12px;overflow:hidden;}
.conv-list-item{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid var(--gray-100);
  text-decoration:none;color:inherit;transition:background .12s;}
.conv-list-item:last-child{border-bottom:none;}
.conv-list-item:hover{background:var(--gray-50);}
.conv-list-item .conv-body{flex:1;min-width:0;}
.conv-list-item .conv-onderwerp{font-weight:700;font-size:13.5px;color:var(--ink);}
.conv-list-item .conv-meta{font-size:11.5px;color:var(--gray-600);margin-top:3px;}
.conv-unread-dot{width:8px;height:8px;border-radius:50%;background:var(--blue-600);flex:none;}
.chat-thread{display:flex;flex-direction:column;gap:14px;margin-bottom:22px;}
.chat-msg{max-width:76%;border-radius:14px;padding:12px 15px;font-size:13px;line-height:1.6;}
.chat-msg.van-klant{align-self:flex-start;background:var(--gray-100);color:var(--ink);border-bottom-left-radius:4px;}
.chat-msg.van-intern{align-self:flex-end;background:var(--blue-600);color:#fff;border-bottom-right-radius:4px;}
.chat-msg-meta{font-size:11px;font-weight:700;margin-bottom:5px;opacity:.75;}
.chat-msg.van-intern .chat-msg-meta{color:#dbe6ff;}
.chat-bijlagen{margin-top:8px;display:flex;flex-direction:column;gap:4px;}
.chat-bijlage{font-size:11.5px;text-decoration:underline;display:inline-block;}
.chat-msg.van-intern .chat-bijlage{color:#fff;}
.chat-msg.van-klant .chat-bijlage{color:var(--blue-600);}
.chat-msg-systeem{align-self:center;max-width:90%;background:none;color:var(--gray-500);font-size:11.5px;
  font-style:italic;padding:2px 10px;text-align:center;}
.chat-typing{align-self:flex-start;font-size:11.5px;color:var(--gray-500);font-style:italic;padding:0 4px;}
.chat-deelnemers{display:flex;flex-wrap:wrap;gap:6px;align-items:center;margin-bottom:14px;}
.chat-deelnemer-pill{background:var(--gray-100);color:var(--gray-700);border-radius:999px;padding:4px 10px;font-size:11.5px;font-weight:600;}
.chat-closed-banner{background:var(--gray-100);color:var(--gray-700);border-radius:10px;padding:12px 16px;
  font-size:13px;font-weight:600;text-align:center;}

.factuurstatus-select{
  border:1px solid var(--gray-300,#d7deee);border-radius:999px;padding:5px 26px 5px 12px;
  font-size:12px;font-weight:700;background:var(--gray-100) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%235a6a8c" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>') no-repeat right 8px center/12px;
  color:var(--gray-700);cursor:pointer;appearance:none;-webkit-appearance:none;
}
.factuurstatus-select.is-verzonden{background-color:#dcfce7;color:#15803d;}
.factuurstatus-select:focus{outline:2px solid var(--blue-500);outline-offset:1px;}

/* notificatiecentrum (bel) */
.notif-wrap{position:relative;}
.notif-bell{
  position:relative;display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:10px;border:1px solid var(--gray-100);background:var(--white);
  cursor:pointer;color:var(--gray-700);
}
.notif-bell:hover{border-color:var(--blue-500);color:var(--blue-600);}
.notif-bell svg{width:18px;height:18px;}

/* Globale zoekbalk -- zelfde toggle-icoon-knop + dropdown-paneel-patroon als
   .notif-wrap/.notif-panel hierboven, maar met alleen een tekstveld erin.
   Het paneel hangt rechts uitgelijnd (right:0 i.p.v. left:0) omdat de
   zoekknop zelf al rechts in de topbar staat -- met left:0 zou een breed
   paneel voorbij de rechterrand van het scherm steken op smalle telefoons.
   De breedte is begrensd op de daadwerkelijke viewportbreedte min marge
   (calc(100vw - 32px)) zodat 'ie nooit buiten beeld kan vallen, ongeacht
   schermgrootte. Het tekstveld krijgt hier expliciet dezelfde stijl als
   .pfield input (die klasse geldt alleen binnen een formulier-veld-wrapper,
   dit veld staat daar los van). */
.zoek-wrap{position:relative;}
/* Op desktop is de sidebar zelf maar 320px breed en het zoekknopje zit
   links in de knoppenrij (niet uiterst rechts) -- een paneel dat met
   right:0 aan de knop hangt, viel daardoor deels links van het scherm af.
   Gecentreerd onder de knop (left:50% + translateX(-50%)) blijft altijd
   volledig in beeld. Op mobiel (zie media query onderaan) werkte right:0
   al goed, want daar staat de knop dicht bij de echte rechterrand van het
   scherm -- dat gedrag blijft daar dus ongewijzigd. */
.zoek-panel{
  position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%);
  width:320px;max-width:calc(100vw - 32px);
  background:var(--white);border-radius:14px;box-shadow:0 20px 50px rgba(0,0,0,.22);border:1px solid var(--gray-100);
  z-index:200;display:none;padding:10px;
}
.zoek-panel.open{display:block;}
.zoek-panel input{
  width:100%;border:1px solid var(--gray-300);border-radius:8px;padding:10px 12px;font-size:13.5px;
  font-family:inherit;color:var(--ink);background:#fbfcfe;
}
.zoek-panel input:focus{outline:2px solid var(--blue-500);outline-offset:1px;}

/* Donkere/lichte modus-schakelaar -- zelfde formaat/stijl als .notif-bell
   hierboven, staat in dezelfde rij naast het logo, altijd zichtbaar voor
   elke rol (in tegenstelling tot de bel, die alleen voor 3 rollen geldt). */
.theme-toggle{
  position:relative;display:flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:10px;border:1px solid var(--gray-100);background:var(--white);
  cursor:pointer;color:var(--gray-700);flex:none;
}
.theme-toggle:hover{border-color:var(--blue-500);color:var(--blue-600);}
.theme-toggle svg{width:18px;height:18px;}
.theme-toggle .theme-icon-moon{display:none;}
[data-theme="dark"] .theme-toggle .theme-icon-sun{display:none;}
[data-theme="dark"] .theme-toggle .theme-icon-moon{display:block;}
.notif-badge{
  position:absolute;top:-5px;right:-5px;min-width:17px;height:17px;padding:0 4px;border-radius:99px;
  background:#dc2626;color:#fff;font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center;
  line-height:1;display:none;
}
.notif-badge.show{display:flex;}
.notif-panel{
  position:absolute;top:calc(100% + 10px);left:0;width:380px;max-width:90vw;max-height:70vh;
  background:var(--white);border-radius:14px;box-shadow:0 20px 50px rgba(0,0,0,.22);border:1px solid var(--gray-100);
  z-index:200;display:none;flex-direction:column;overflow:hidden;
}
.notif-panel.open{display:flex;}
.notif-panel-head{padding:14px 16px;border-bottom:1px solid var(--gray-100);}
.notif-panel-head h4{margin:0 0 10px;font-size:14px;}
.notif-panel-actions{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:8px;}
.notif-panel-actions button{background:none;border:1px solid var(--gray-100);border-radius:8px;padding:5px 10px;font-size:11px;font-weight:700;color:var(--gray-700);cursor:pointer;}
.notif-panel-actions button:hover{border-color:var(--blue-500);color:var(--blue-600);}
.notif-filters{display:flex;gap:6px;flex-wrap:wrap;}
.notif-filters select, .notif-filters input[type=text]{
  border:1px solid var(--gray-100);border-radius:8px;padding:5px 8px;font-size:11.5px;font-family:inherit;background:#fbfcfe;
}
.notif-filters input[type=text]{flex:1;min-width:110px;}
.notif-filters label{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--gray-600);white-space:nowrap;}
.notif-list{overflow-y:auto;flex:1;}
.notif-item{display:flex;gap:10px;padding:12px 16px;border-bottom:1px solid var(--gray-100);cursor:pointer;text-decoration:none;color:inherit;}
.notif-item:hover{background:var(--gray-50);}
.notif-item.unread{background:#f5f8ff;}
.notif-item .notif-ico{width:30px;height:30px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:14px;flex:none;}
.notif-item .notif-body{flex:1;min-width:0;}
.notif-item .notif-titel{font-size:12.5px;font-weight:700;color:var(--ink);}
.notif-item .notif-desc{font-size:12px;color:var(--gray-600);margin-top:2px;}
.notif-item .notif-time{font-size:10.5px;color:var(--gray-600);margin-top:3px;}
.notif-item .notif-dot{width:7px;height:7px;border-radius:50%;background:var(--blue-600);flex:none;margin-top:5px;}
.notif-empty{padding:30px 16px;text-align:center;color:var(--gray-600);font-size:12.5px;}
.notif-ico.blue{background:var(--blue-100);}
.notif-ico.green{background:#dcfce7;}
.notif-ico.red{background:#fee2e2;}
.notif-ico.amber{background:#fef3c7;}
.notif-ico.gray{background:var(--gray-100);}
.notif-ico.purple{background:#f3e8ff;}

/* role badges */
.role-badge{display:inline-flex;padding:3px 9px;border-radius:6px;font-size:11px;font-weight:700;margin:2px 3px 2px 0;}
.role-beheerder{background:#ede9fe;color:#5b21b6;}
.role-regiecentralist{background:#dbeafe;color:#1d4ed8;}
.role-planner{background:#cffafe;color:#0e7490;}
.role-teamleider{background:#dcfce7;color:#15803d;}
.role-projectleider{background:#fef3c7;color:#92400e;}
.role-controleur{background:#fce7f3;color:#a3195b;}
.role-verkeersregelaar{background:var(--gray-100);color:var(--gray-700);}
.role-klant{background:#e0f2fe;color:#0369a1;}
.role-onderaannemer{background:#ffedd5;color:#9a3412;}
.role-zzp{background:#fce7e7;color:#b91c1c;}

/* upload dropzone -- STANDAARD component voor ELK bestand-upload-veld in het
   portaal (nooit een kale native <input type="file">, die toont het lelijke
   browser-default "Bestand kiezen"-knopje). Markup-patroon:
     <div class="upload-box" id="xBox" style="padding:10px;">
       <span class="thumb" style="width:36px;height:36px;">...svg icoon...</span>
       <span class="txt" id="xTxt"><strong>Bestand kiezen</strong>Klik om te uploaden</span>
       <input type="file" ... style="display:none;">
     </div>
   plus een klein stukje JS dat op click() van de box het verborgen input-
   element opent, en bij verandering de bestandsnaam in .txt toont (zie
   wireUploadBox() in rooster.html of de losse voorbeelden in
   organisatie_dossier.html / medewerker_dossier.html / onderaannemer_
   bedrijf.html / klant_contact*.html voor het exacte patroon om te
   hergebruiken). Elk nieuw formulier met een bestand-upload moet dit
   patroon gebruiken, niet een onopgemaakte <input type="file">. */
.upload-box{
  border:1.5px dashed var(--gray-300);border-radius:10px;padding:16px;
  display:flex;align-items:center;gap:12px;background:#fbfcfe;cursor:pointer;
}
.upload-box:hover{border-color:var(--blue-500);}
.upload-box .thumb{
  width:52px;height:52px;border-radius:8px;background:var(--gray-100);flex:none;
  display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--gray-600);
}
.upload-box .thumb img{width:100%;height:100%;object-fit:cover;}
.upload-box .txt{font-size:12.5px;color:var(--gray-600);}
.upload-box .txt strong{display:block;font-size:13.5px;color:var(--ink);margin-bottom:2px;}

/* modal - eigen systeem-vensters (nooit native alert/confirm/prompt). Blijft
   altijd display:flex (voor centrering) en gebruikt opacity/visibility/
   transform voor een vloeiende animatie bij openen/sluiten via de .open klasse. */
.modal-overlay{
  display:flex;position:fixed;inset:0;background:rgba(5,11,26,.55);
  align-items:center;justify-content:center;z-index:100;padding:20px;
  opacity:0;visibility:hidden;pointer-events:none;transition:opacity .16s ease;
}
.modal-overlay.open{opacity:1;visibility:visible;pointer-events:auto;}
.modal-box{
  background:var(--white);border-radius:16px;padding:28px;max-width:480px;width:100%;
  box-shadow:0 24px 60px rgba(0,0,0,.3);position:relative;
  transform:translateY(12px) scale(.98);transition:transform .16s ease;
}
.modal-overlay.open .modal-box{transform:translateY(0) scale(1);}
.modal-box h3{font-size:17px;margin-bottom:6px;}
.modal-box p.sub{font-size:13px;margin-bottom:18px;}
.modal-actions{display:flex;gap:10px;margin-top:20px;flex-wrap:wrap;}
.modal-close{position:absolute;top:14px;right:14px;background:none;border:none;font-size:18px;cursor:pointer;color:var(--gray-600);line-height:1;padding:4px;}
.modal-close:hover{color:var(--ink);}
.modal-danger-btn{background:#dc2626;color:#fff;border:none;}
.modal-danger-btn:hover{background:#b91c1c;}

/* dienst cards (rooster) */
.dienst-card{background:var(--white);border:1px solid var(--gray-100);border-radius:var(--radius);padding:20px 22px;margin-bottom:16px;}
.dienst-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:14px;padding-bottom:14px;border-bottom:1px solid var(--gray-100);}
.dienst-title{font-size:15.5px;font-weight:800;margin-bottom:4px;}
.dienst-meta{font-size:12.5px;color:var(--gray-600);display:flex;gap:14px;flex-wrap:wrap;}
.dienst-meta span{display:inline-flex;align-items:center;gap:5px;}
.dienst-meta svg{width:14px;height:14px;}
.medewerker-row{display:flex;align-items:center;justify-content:space-between;padding:9px 0;border-bottom:1px solid #f4f6fb;}
.medewerker-row:last-child{border-bottom:none;}
.medewerker-left{display:flex;align-items:center;gap:10px;}
.avatar-sm{width:30px;height:30px;border-radius:50%;background:var(--blue-600);color:#fff;
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:11px;flex:none;}
.medewerker-name{font-size:13.5px;font-weight:700;}
.medewerker-sub{font-size:11.5px;color:var(--gray-600);}

/* Compacte datumbalk boven de dienstenlijst (Rooster/onderaannemer-rooster)
   -- verving het altijd-zichtbare maandrooster naast de lijst, dat te veel
   verticale ruimte innam en de lijst kunstmatig versmalde. Het maandgrid
   (.cal-box) bestaat nog steeds (zie hieronder), maar zit nu in een
   popover die pas opent via het kalender-icoon. */
.rooster-datebar{
  display:flex;align-items:center;gap:10px;background:var(--white);
  border:1px solid var(--gray-100);border-radius:var(--radius);
  padding:10px 14px;margin-bottom:20px;flex-wrap:wrap;
}
.rooster-datebar-arrow{
  width:32px;height:32px;flex:none;border-radius:8px;border:1px solid var(--gray-100);
  background:var(--white);font-size:18px;font-weight:700;color:var(--gray-700);cursor:pointer;
}
.rooster-datebar-arrow:hover{border-color:var(--blue-500);color:var(--blue-700,#123a9e);}
.rooster-datebar-label{
  border:none;background:none;font-size:15px;font-weight:800;color:var(--ink);
  cursor:pointer;padding:6px 10px;border-radius:8px;
}
.rooster-datebar-label:hover{background:var(--gray-100);}
.rooster-datebar-calwrap{position:relative;margin-left:auto;}
.rooster-datebar-calbtn{
  width:38px;height:38px;border-radius:8px;border:1px solid var(--gray-100);background:var(--white);
  display:flex;align-items:center;justify-content:center;color:var(--gray-700);cursor:pointer;
}
.rooster-datebar-calbtn:hover{border-color:var(--blue-500);color:var(--blue-700,#123a9e);}
.rooster-cal-popover{display:none;position:absolute;top:calc(100% + 8px);right:0;z-index:40;}
.rooster-cal-popover .cal-box{box-shadow:0 14px 32px rgba(0,0,0,.16);}
@media(max-width:560px){
  .rooster-cal-popover{right:auto;left:0;}
}

/* calendar */
.cal-wrap{display:flex;gap:22px;align-items:flex-start;flex-wrap:wrap;}
.cal-box{background:var(--white);border:1px solid var(--gray-100);border-radius:var(--radius);padding:18px 20px;width:320px;flex:none;}
.cal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;}
.cal-head .month-label{font-weight:800;font-size:14.5px;}
.cal-nav{display:flex;gap:4px;}
.cal-nav button{width:28px;height:28px;border-radius:7px;border:1px solid var(--gray-300);background:var(--white);cursor:pointer;color:var(--gray-700);font-size:13px;}
.cal-nav button:hover{border-color:var(--blue-500);color:var(--blue-700,#123a9e);}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;}
.cal-dow{font-size:10.5px;color:var(--gray-600);text-align:center;font-weight:700;padding-bottom:4px;}
.cal-day{
  aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  border-radius:8px;font-size:12.5px;cursor:pointer;color:var(--ink);position:relative;background:#fbfcfe;
  border:1px solid transparent;
}
.cal-day:hover{border-color:var(--blue-500);}
.cal-day.other-month{color:var(--gray-300);background:transparent;}
.cal-day.has-shift::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--blue-600);margin-top:2px;}
.cal-day.selected{background:var(--blue-600);color:#fff;font-weight:800;}
.cal-day.selected::after{background:var(--white);}
.cal-day.today{border-color:var(--blue-500);font-weight:800;}
.cal-summary{flex:1;min-width:280px;}
.cal-summary-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;flex-wrap:wrap;gap:10px;}
.cal-summary-head h3{font-size:16px;margin:0;}

/* numbered list */
.numlist-row{display:flex;gap:14px;padding:14px 0;border-bottom:1px solid var(--gray-100);align-items:flex-start;}
.numlist-row:last-child{border-bottom:none;}
.numlist-row.heeft-logboek{background:#f5f3ff;border-left:4px solid #7c3aed;padding-left:10px;margin-left:-14px;border-radius:6px;}
.numlist-badge{
  width:26px;height:26px;border-radius:50%;background:var(--gray-100);color:var(--gray-700);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:11.5px;flex:none;margin-top:2px;
}
/* Losse badge voor het dienstnummer (bijv. "D-00039") in de zoekresultaten
   -- dit is geen los cijfer zoals .numlist-badge (vaste ronde 26x26px-cirkel),
   maar een tekst van 7-8 tekens die daar niet in paste en lelijk afbrak. */
.dienstnr-badge{
  font-family:monospace;font-weight:700;font-size:11px;color:var(--gray-700);
  background:var(--gray-100);border-radius:6px;padding:5px 8px;flex:none;
  white-space:nowrap;align-self:flex-start;margin-top:2px;
}
.numlist-body{flex:1;}
.numlist-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:4px;}
.numlist-title{font-weight:700;font-size:13.5px;}
.numlist-meta{font-size:12px;color:var(--gray-600);display:flex;gap:12px;flex-wrap:wrap;margin-top:3px;}
.numlist-empty{padding:30px 0;text-align:center;color:var(--gray-600);font-size:13.5px;}

/* Kolomweergave van een dienstregel (i.p.v. losse tags): vaste kolommen op
   desktop, label:waarde-paren op mobiel. Zelfde 10-koloms indeling voor
   zowel het beheerder- als het onderaannemer/zzp-rooster (Dienst/Project/
   Locatie/Klant/Toegewezen/Begin tijd/Pauze/Eindtijd/Totaal uren/Bemenst),
   zodat er nog maar één grid-definitie bijgehouden hoeft te worden. Alles
   moet op één regel passen, ook op smallere desktop-schermen -- vandaar de
   extra breakpoints hieronder die stapsgewijs lettertype/gap verkleinen
   i.p.v. de kolombreedtes zelf te veranderen (die zijn al percentage-
   gebaseerd en dus vloeiend schaalbaar). Pas onder de 880px-breakpoint
   springt het om naar de mobiele 2-koloms label:waarde-weergave. */
.numlist-cols{
  display:grid;
  /* fr i.p.v. % -- fr-eenheden verdelen de ruimte die OVERBLIJFT na de
     gap hieronder, % telt daarnaast nog eens op, wat de kolommen (met
     name de laatste, "Bemenst") buiten het paneel liet steken. Zelfde
     onderlinge verhouding als voorheen (6:15:12:12:15:7:7:7:9:10), dus de
     kolombreedtes zien er ongewijzigd uit, alleen zonder overloop. */
  grid-template-columns:6fr 15fr 12fr 12fr 15fr 7fr 7fr 7fr 9fr 10fr;
  gap:6px 8px;
  font-size:12.5px;line-height:1.5;margin-bottom:6px;
}
.numlist-cols .dienstnr{font-family:monospace;font-weight:700;color:var(--gray-700);}
.numlist-cols .tel{color:var(--gray-500);font-size:11.5px;}
.numlist-cols .col-label{display:none;}
@media(max-width:1500px){
  .numlist-cols{font-size:11.5px;gap:5px 7px;}
}
@media(max-width:1200px){
  .numlist-cols{font-size:10.5px;gap:4px 6px;}
}
@media(max-width:880px){
  /* Eén kolom i.p.v. twee: bij twee kolommen liep de layout scheef zodra
     één cel (bijv. "Project", met een extra regel functie eronder) hoger
     was dan zijn buurcel op dezelfde rij -- op elk telefoonformaat een
     andere combinatie, dus niet met een vaste breakpoint te fixen. Eén
     kolom is device-onafhankelijk altijd netjes uitgelijnd. */
  .numlist-cols{grid-template-columns:1fr;gap:8px;font-size:13px;}
  .numlist-cols .col-label{display:inline;color:var(--gray-500);}
}

/* Tabbladen in het organisatiedossier (Bedrijfsgegevens/Contactpersonen/
   Documenten/...). Voorheen inline flex:1 per tab -- op smalle schermen
   overschreed de som van de minimale (niet-afbrekende) tekstbreedtes de
   containerbreedte en werd de laatste tab door het "overflow:hidden" van
   het paneel afgesneden. Daarna kort een horizontaal scrollbare balk, maar
   niet iedereen weet dat je opzij moet vegen om de rest te zien. Een kale
   <select> bleek op sommige mobiele browsers niet betrouwbaar te openen --
   dus nu een eigen knop + uitklapmenu (gewone <a>-links), die altijd
   gewoon klikbaar zijn, ongeacht toestel of browser. */
.dossier-tabs-panel{padding:0;overflow:visible;}
.dossier-tabs{display:flex;border-bottom:1px solid var(--gray-100);}
.dossier-tab{flex:1;text-align:center;padding:14px;font-size:13px;font-weight:700;color:var(--gray-600);white-space:nowrap;}
.dossier-tab.active{color:var(--blue-600);border-bottom:2px solid var(--blue-600);}
.dossier-tabs-mobile-wrap{display:none;position:relative;}
.dossier-tabs-mobile-btn{
  width:100%;box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;
  border:none;background:#fff;padding:16px;font-size:14.5px;font-weight:800;color:var(--blue-600);
  cursor:pointer;border-radius:16px;
}
.dossier-tabs-mobile-menu{
  display:none;position:absolute;top:100%;left:0;right:0;background:#fff;
  border:1px solid var(--gray-100);border-radius:12px;box-shadow:0 10px 24px rgba(0,0,0,.12);
  z-index:30;overflow:hidden;margin-top:6px;
}
.dossier-tabs-mobile-menu a{display:block;padding:14px 16px;font-size:13.5px;font-weight:700;color:var(--gray-700);border-top:1px solid var(--gray-100);}
.dossier-tabs-mobile-menu a:first-child{border-top:none;}
.dossier-tabs-mobile-menu a.active{color:var(--blue-600);background:#eff6ff;}
@media(max-width:680px){
  .dossier-tabs-panel{overflow:visible;}
  .dossier-tabs{display:none;}
  .dossier-tabs-mobile-wrap{display:block;}
}

/* Vaste kolomkoppen (Dienst/Locatie&tijd/Uitvoerder/Klant/Toegewezen/
   Bemenst) boven de dienstenlijst, los van de losse dienst-boxen -- werkt
   als tabel-header en blijft (samen met de titelbalk en het filterpaneel
   hieronder) zichtbaar tijdens het scrollen. De inhoud wordt in JS gebouwd
   (buildNumlistHeader() in rooster.html) zodat de uitlijning altijd exact
   overeenkomt met de echte rijen. */
.numlist-header-row{
  position:sticky;z-index:35;background:var(--white);
  border-bottom:2px solid var(--gray-100);
}
.numlist-header-row .numlist-row{padding:8px 0;border-bottom:none;}
.numlist-cols-header > div{
  font-weight:800;color:var(--gray-700);font-size:10.5px;
  text-transform:uppercase;letter-spacing:.03em;
}

/* Titelbalk + filterpaneel van het rooster blijven zichtbaar bij het
   scrollen (position:sticky, top-offset wordt door JS berekend zodat het
   klopt ongeacht hoe hoog de titelbalk precies is). Alleen op desktop --
   zie media-query onderaan, op mobiel zou dit te veel schermruimte kosten. */
#roosterTopbar{position:sticky;top:0;z-index:37;}
#roosterFilterPanel{position:sticky;z-index:36;}
@media(max-width:880px){
  #roosterTopbar, #roosterFilterPanel{position:static;}
  .numlist-header-row{display:none;}
}

/* auto-calc readout */
.autocalc-box{background:var(--blue-100);border-radius:10px;padding:12px 14px;font-size:12.5px;color:var(--blue-800);display:flex;gap:22px;flex-wrap:wrap;margin-top:4px;}
.autocalc-box b{display:block;font-size:15px;}

/* forms */
.pform-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px;}
.pfield{display:flex;flex-direction:column;gap:6px;}
.pfield label{font-size:12.5px;font-weight:700;color:var(--gray-700);}
.pfield input,.pfield select,.pfield textarea{
  border:1px solid var(--gray-300);border-radius:8px;padding:10px 12px;font-size:13.5px;
  font-family:inherit;color:var(--ink);background:#fbfcfe;
}
.pfield input:focus,.pfield select:focus,.pfield textarea:focus{outline:2px solid var(--blue-500);outline-offset:1px;}
@media (max-width:880px){.pform-row{grid-template-columns:1fr;}}

/* Losse input/select-velden buiten een .pfield-wrapper (bijv. regels binnen
   een .ptable, of een losstaande <select> in een knoppenrij) -- zonder deze
   regel vallen die terug op de kale browserstijl, wat lelijk afsteekt tegen
   de rest van de site (zie o.a. de offerteregels en de tarievenselectie). */
.ptable td input,.ptable td select,.select-inline{
  border:1px solid var(--gray-300);border-radius:8px;padding:8px 10px;font-size:13px;
  font-family:inherit;color:var(--ink);background:#fbfcfe;
}
.ptable td input:focus,.ptable td select:focus,.select-inline:focus{outline:2px solid var(--blue-500);outline-offset:1px;}

/* eigen datumkiezer (Tarefa 5) -- vervangt de native input[type=date] */
.tp-date-wrap{position:relative;display:block;width:100%;}
.tp-date-input{
  border:1px solid var(--gray-300);border-radius:8px;padding:10px 34px 10px 12px;font-size:13.5px;
  font-family:inherit;color:var(--ink);background:#fbfcfe;width:100%;cursor:pointer;
}
.tp-date-input:focus{outline:2px solid var(--blue-500);outline-offset:1px;}
.tp-date-input:disabled{cursor:not-allowed;opacity:.6;}
.tp-date-input.tp-date-error{border-color:var(--red);outline:2px solid rgba(220,38,38,.25);}
.tp-date-icon{
  position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--gray-600);pointer-events:none;
}
.tp-date-panel{
  position:absolute;top:calc(100% + 6px);left:0;z-index:60;background:var(--white);border:1px solid var(--gray-100);
  border-radius:12px;box-shadow:var(--shadow);padding:14px;width:280px;
}
.tp-date-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;}
.tp-date-month{font-weight:800;font-size:13.5px;text-transform:capitalize;}
.tp-date-nav{
  width:26px;height:26px;border-radius:7px;border:1px solid var(--gray-300);background:var(--white);cursor:pointer;
  color:var(--gray-700);font-size:14px;line-height:1;
}
.tp-date-nav:hover{border-color:var(--blue-500);color:var(--blue-600);}
.tp-date-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;}
.tp-date-dow{font-size:10px;color:var(--gray-600);text-align:center;font-weight:700;padding-bottom:4px;}
.tp-date-day{
  aspect-ratio:1;display:flex;align-items:center;justify-content:center;border-radius:7px;font-size:12px;
  cursor:pointer;color:var(--ink);background:#fbfcfe;border:1px solid transparent;
}
.tp-date-day:hover{border-color:var(--blue-500);}
.tp-date-day.other{color:var(--gray-300);background:transparent;cursor:default;}
.tp-date-day.today{border-color:var(--blue-500);font-weight:800;}
.tp-date-day.selected{background:var(--blue-600);color:#fff;font-weight:800;}
.tp-date-day.disabled{color:var(--gray-300);background:transparent;cursor:not-allowed;}
.tp-date-foot{display:flex;justify-content:space-between;margin-top:10px;padding-top:10px;border-top:1px solid var(--gray-100);}
.tp-date-quick{
  background:none;border:none;color:var(--blue-600);font-size:12px;font-weight:700;cursor:pointer;padding:4px 2px;
}
.tp-date-quick:hover{text-decoration:underline;}
@media (max-width:480px){
  .tp-date-panel{position:fixed;left:16px;right:16px;top:auto;bottom:16px;width:auto;}
}

/* eigen dropdown (TPSelect) -- vervangt de native <select>, die altijd de
   systeemkleuren van het besturingssysteem gebruikt (bijv. donkergrijs in
   macOS-donkere modus) en niet met CSS te stylen is. */
.tp-select-wrap{position:relative;display:inline-block;width:100%;}
.tp-select-native{display:none;}
.tp-select-btn{
  display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;
  border:1px solid var(--gray-300);border-radius:8px;padding:10px 12px;font-size:13.5px;
  font-family:inherit;color:var(--ink);background:#fbfcfe;cursor:pointer;text-align:left;
}
.tp-select-btn:hover{border-color:var(--blue-500);}
.tp-select-btn:focus{outline:2px solid var(--blue-500);outline-offset:1px;}
.tp-select-btn:disabled{cursor:not-allowed;opacity:.6;}
.tp-select-btn.tp-select-error{border-color:var(--red);outline:2px solid rgba(220,38,38,.25);}
.tp-select-open .tp-select-btn{border-color:var(--blue-500);}
.tp-select-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.tp-select-btn.tp-select-placeholder .tp-select-label{color:var(--gray-500);}
.tp-select-caret{width:16px;height:16px;flex:none;color:var(--gray-600);transition:transform .15s;}
.tp-select-open .tp-select-caret{transform:rotate(180deg);}
.tp-select-panel{
  display:none;position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:60;background:var(--white);
  border:1px solid var(--gray-100);border-radius:12px;box-shadow:var(--shadow);padding:6px;
  max-height:280px;overflow-y:auto;min-width:180px;
}
.tp-select-panel.open{display:block;}
.tp-select-panel.tp-select-panel-up{top:auto;bottom:calc(100% + 6px);}
.tp-select-opt{
  padding:9px 10px;border-radius:7px;font-size:13.5px;color:var(--ink);cursor:pointer;
}
.tp-select-opt.highlighted{background:var(--gray-100);}
.tp-select-opt.selected{background:var(--blue-100);color:var(--blue-800);font-weight:700;}
.tp-select-opt.disabled{color:var(--gray-300);cursor:not-allowed;}

/* logboek timeline */
.log-entry{display:flex;gap:16px;padding:16px 0;border-bottom:1px solid var(--gray-100);}
.log-entry:last-child{border-bottom:none;}
.log-time{width:110px;flex:none;font-size:12px;color:var(--gray-600);font-weight:600;}
.log-body{flex:1;}
.log-title-row{display:flex;align-items:center;gap:10px;margin-bottom:4px;flex-wrap:wrap;}
.log-title{font-weight:700;font-size:14px;}
.log-desc{font-size:13.5px;color:var(--gray-600);}
.log-author{font-size:11.5px;color:var(--gray-600);margin-top:6px;}

/* aandachtspunten (waarschuwingsbox) */
.warning-box{
  background:#fef2f2;border:1px solid #fecaca;border-radius:var(--radius);
  padding:20px 22px;margin-bottom:22px;
}
.warning-box-head{display:flex;align-items:center;gap:8px;margin-bottom:14px;}
.warning-box-head svg{width:18px;height:18px;color:#dc2626;flex:none;}
.warning-box-head h3{font-size:15px;margin:0;color:#b91c1c;}
.warning-item{padding:12px 0;border-bottom:1px solid #fecaca;}
.warning-item:last-child{border-bottom:none;padding-bottom:0;}
.warning-item-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;}
.warning-item-titel{font-weight:800;font-size:13.5px;color:#b91c1c;}
.warning-item-periode{font-size:12px;color:#b91c1c;font-weight:700;margin-top:1px;}
.warning-item-desc{font-size:13px;color:#991b1b;margin-top:6px;line-height:1.5;}
.warning-item-del{background:none;border:none;color:#b91c1c;font-size:11.5px;font-weight:700;cursor:pointer;text-decoration:underline;flex:none;}
.warning-empty{font-size:13px;color:#b91c1c;}
.warning-item-badges{display:inline-flex;gap:5px;margin-left:8px;vertical-align:middle;}
.warning-item-actions{display:flex;align-items:center;gap:4px;flex:none;}
.warning-item-move{background:var(--white);border:1px solid #fecaca;color:#b91c1c;font-size:12px;font-weight:800;cursor:pointer;border-radius:6px;width:24px;height:24px;line-height:1;padding:0;}
.warning-item-move:hover{background:#fee2e2;}
.warning-item-move:disabled{opacity:.35;cursor:default;}
.warning-item-edit{background:none;border:none;color:#1547c9;font-size:11.5px;font-weight:700;cursor:pointer;text-decoration:underline;flex:none;}
.warning-add-btn{background:var(--white);border:1px solid #fecaca;color:#b91c1c;font-size:12px;font-weight:700;cursor:pointer;padding:7px 14px;border-radius:8px;margin-top:14px;}
.warning-add-btn:hover{background:#fee2e2;}

/* overdracht (dienstoverdracht-banner) */
.handover-banner{
  background:#fff7ed;border:1px solid #fed7aa;border-radius:var(--radius);
  padding:18px 22px;margin-bottom:22px;
}
.handover-banner-head{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:wrap;justify-content:space-between;}
.handover-banner-head h3{font-size:14.5px;margin:0;color:#9a3412;display:flex;align-items:center;gap:8px;}
.handover-banner-head svg{width:17px;height:17px;color:#c2410c;flex:none;}
.handover-meta{font-size:11.5px;color:#9a3412;font-weight:700;}
.handover-text{font-size:13.5px;color:#7c2d12;line-height:1.55;}
.handover-history{margin-top:14px;padding-top:14px;border-top:1px solid #fed7aa;}
.handover-history summary{font-size:12px;font-weight:700;color:#9a3412;cursor:pointer;}
.handover-history-item{padding:10px 0;border-bottom:1px solid #fde6d0;font-size:12.5px;color:#7c2d12;}
.handover-history-item:last-child{border-bottom:none;}

/* financieel: verborgen bedragen achter een oog-toggle */
.fin-mask{filter:blur(6px);user-select:none;transition:filter .15s;}
.fin-mask.fin-visible{filter:none;}
.fin-eye-btn{
  display:inline-flex;align-items:center;gap:8px;padding:9px 16px;border-radius:9px;
  font-weight:700;font-size:13px;border:1px solid var(--gray-300);background:var(--white);cursor:pointer;color:var(--ink);
}
.fin-eye-btn:hover{border-color:var(--blue-500);}
.fin-eye-btn svg{width:16px;height:16px;}
.fin-summary-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:22px;}
@media (max-width:900px){.fin-summary-cards{grid-template-columns:1fr;}}

/* Opvallende banner voor het "aanstellingspas nog niet gecontroleerd"-
   conflict in het toewijzen-conflictmodal (Rooster) -- i.p.v. een gewone
   bullet-tekstregel, zodat deze compliance-blokkade meteen opvalt tussen
   de andere (routinematige) conflictmeldingen. */
.pas-block-banner{
  display:flex;gap:12px;align-items:flex-start;
  background:linear-gradient(135deg,#fff7ed,#fef3c7);
  border:1px solid #fcd34d;border-radius:12px;padding:14px 16px;color:#92400e;
  margin:2px 0 10px;
}
.pas-block-banner svg{flex:none;margin-top:1px;color:#d97706;}
.pas-block-banner strong{display:block;font-size:13.5px;color:#78350f;margin-bottom:3px;}
.pas-block-banner span{font-size:12.5px;line-height:1.5;display:block;}

/* Uren analyse: eenvoudig staafdiagram (kolommen), server-side opgebouwd
   met Jinja + CSS -- geen externe chart-library, in lijn met de rest van
   het portaal dat verder nergens een JS-dependency van buitenaf laadt. */
.barchart{display:flex;align-items:flex-end;gap:14px;height:220px;padding:10px 8px 0;overflow-x:auto;border-bottom:2px solid var(--gray-200);}
.barchart-col{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;flex:none;width:60px;height:100%;}
.barchart-value{font-size:11px;font-weight:700;color:var(--gray-700);margin-bottom:4px;}
.barchart-bar{width:30px;background:var(--blue-600);border-radius:4px 4px 0 0;min-height:2px;}
.barchart-bar-green{background:var(--green);}
.barchart-bar-purple{background:#7c3aed;}
.barchart-label{margin-top:8px;font-size:10.5px;color:var(--gray-600);text-align:center;max-width:64px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* login page */
.login-shell{min-height:100vh;display:flex;}
.login-brand{
  flex:1;background:linear-gradient(135deg,var(--navy-900) 0%,var(--blue-800) 60%,var(--blue-500) 100%);
  color:#fff;display:flex;flex-direction:column;justify-content:center;padding:60px;
}
.login-brand .brand{display:flex;align-items:center;gap:12px;margin-bottom:40px;}
.login-brand .brand img{width:44px;height:44px;border-radius:12px;}
.login-brand h2{font-size:28px;line-height:1.3;max-width:420px;}
.login-brand p{color:#c3d3f5;max-width:380px;margin-top:10px;}
.login-form-wrap{
  flex:1;display:flex;align-items:center;justify-content:center;background:var(--white);padding:40px;
}
.login-card{
  position:relative;width:100%;max-width:400px;background:#fff;border-radius:26px;
  border:1px solid var(--gray-300);padding:40px 34px;
  box-shadow:0 30px 60px rgba(11,19,39,.10),0 10px 22px rgba(21,71,201,.08);
  animation:loginCardIn .55s cubic-bezier(.2,.8,.25,1) both;
  perspective:1200px;
}
.login-flip-wrap{width:100%;}
.forgot-back-link{
  display:inline-flex;align-items:center;gap:6px;background:none;border:none;padding:0;
  margin-bottom:16px;font-size:12px;font-weight:700;color:var(--blue-600);cursor:pointer;
}
.forgot-back-link:hover{text-decoration:underline;}
.login-card::before{
  content:"";position:absolute;top:0;left:26px;right:26px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,rgba(143,178,255,0),#8fb2ff,rgba(143,178,255,0));
}
.login-badge{
  display:inline-flex;align-items:center;gap:6px;background:#c3d3f5;color:var(--ink);
  padding:5px 10px;border-radius:20px;margin-bottom:18px;font-size:10px;font-weight:800;
  letter-spacing:.08em;
}
.login-badge svg{flex:none;}
.login-card h1{font-size:23px;margin-bottom:8px;font-weight:800;letter-spacing:-.01em;}
.login-card p.sub{font-size:13px;color:var(--gray-600);margin-bottom:24px;line-height:1.5;}
.login-card .pfield{margin-bottom:16px;position:relative;}
.login-card .pfield-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.login-card .pfield-row label{margin:0;}
.login-card .forgot-link{font-size:11.5px;color:var(--blue-600);font-weight:700;text-decoration:none;}
.login-card .forgot-link:hover{text-decoration:underline;}
.login-card .field-icon{
  position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--gray-600);
  pointer-events:none;z-index:2;display:flex;align-items:center;
}
.login-card input[type="email"],.login-card input[type="password"]{
  position:relative;z-index:1;width:100%;box-sizing:border-box;height:52px;background:#fbfcfe;
  border:1.5px solid var(--gray-300);border-radius:10px;padding:0 42px;font-size:13.5px;
  color:var(--ink);outline:none;transition:border-color .2s,box-shadow .2s,transform .2s;
}
.login-card input[type="email"]:hover,.login-card input[type="password"]:hover{border-color:#8fb2ff;}
.login-card input[type="email"]:focus,.login-card input[type="password"]:focus{
  border-color:var(--blue-600) !important;outline:none !important;
  box-shadow:0 0 0 3px rgba(143,178,255,.28),0 6px 16px rgba(21,71,201,.12);
  transform:translateY(-1px);
}
.login-btn{
  width:100%;height:54px;background:linear-gradient(135deg,var(--blue-600),var(--navy-900));
  color:#fff;border:none;border-radius:10px;font-size:14px;font-weight:700;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:8px;
  box-shadow:0 10px 22px rgba(21,71,201,.28);
  transition:transform .18s ease,box-shadow .2s ease,filter .2s ease;
}
.login-btn:hover{transform:translateY(-2px);box-shadow:0 14px 28px rgba(21,71,201,.34);filter:brightness(1.05);}
.login-btn:hover .login-btn-arrow{transform:translateX(3px);}
.login-btn:active{transform:scale(.98);}
.login-btn:disabled{opacity:.85;cursor:default;transform:none;}
.login-btn-arrow{transition:transform .2s ease;flex:none;}
.login-btn-spinner{width:14px;height:14px;display:none;}
.login-btn-spinner svg{animation:loginSpin .8s linear infinite;}
.login-footer{
  margin-top:22px;padding-top:16px;border-top:1px solid #e7ecf7;
  display:flex;align-items:center;justify-content:space-between;font-size:10.5px;color:var(--gray-600);
}
.login-footer a{color:var(--gray-600);text-decoration:underline;}
@keyframes loginCardIn{from{opacity:0;transform:translateY(16px) scale(.97)}to{opacity:1;transform:translateY(0) scale(1)}}
@keyframes loginSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){
  .login-card{animation:none !important;}
}
.demo-note{
  background:var(--blue-100);color:var(--blue-800);border-radius:10px;padding:12px 14px;
  font-size:12.5px;margin-top:22px;
}
@media (max-width:900px){.login-brand{display:none;}}
@media (max-width:880px){
  .app-shell{flex-direction:column;}
  .sidebar{width:100%;flex-direction:column;align-items:stretch;padding:10px 14px;}
  /* Menubalk blijft zichtbaar tijdens het scrollen op mobiel -- de sidebar
     bevat hier alleen de topbar (logo+knoppen) plus het uitklappaneel, dus
     'm helemaal sticky maken pint beide als één geheel bovenaan. Als het
     paneel open staat en de navigatielijst toch langer is dan het scherm,
     scrollt hij intern (max-height+overflow) i.p.v. van het scherm af te
     lopen. */
  .sidebar{position:sticky;top:0;z-index:100;}
  .mobile-menu-panel.open{max-height:calc(100vh - 64px);overflow-y:auto;}
  .sidebar .brand{padding:4px 0;}
  .mobile-menu-toggle{display:flex;}
  /* De logo-op-eigen-rij + knoppenrij-eronder-regel geldt nu al standaard
     (zie .sidebar-topbar hierboven, buiten deze media query) -- hier alleen
     nog een iets ruimere rij-afstand voor de vinger-vriendelijkere mobiele
     weergave. */
  .sidebar-topbar{row-gap:10px;}

  /* Op mobiel is de sidebar de volle schermbreedte, dus het zoekknopje zit
     wel degelijk dicht bij de echte rechterrand van het scherm -- daar
     werkt de oude right:0-aanpak (in plaats van gecentreerd onder de knop)
     beter, want dan opent het paneel netjes naar links in plaats van half
     buiten het scherm te centreren op een heel brede viewport-breedte. */
  .zoek-panel{left:auto;right:0;transform:none;}

  /* Het uitklappaneel: dicht = helemaal niet in de layout (geen lege
     ruimte), open = een gewoon blok onder de topbar-rij. De knop zelf
     (mobileMenuToggle in base.html) zet de klasse .open erop. */
  .mobile-menu-panel{display:none;margin-top:10px;padding-top:10px;border-top:1px solid #1c2740;}
  .mobile-menu-panel.open{display:block;}

  .sidebar-nav{flex-direction:column;overflow-x:visible;}
  .sidebar-foot{border-top:1px solid #1c2740;margin-top:10px;padding-top:10px;}
  .sidebar-foot .sidebar-user{display:flex;}
  /* Op mobiel staan de juridische links in de echte pagina-footer
     (.mobile-legal-footer), niet meer in het uitklapmenu. */
  .sidebar-legal-links{display:none;}
  .mobile-legal-footer{
    display:block;text-align:center;padding:18px 16px 26px;font-size:11px;
    line-height:1.9;color:var(--gray-600);border-top:1px solid var(--gray-100);
  }
  .mobile-legal-footer a{color:var(--gray-600);text-decoration:underline;}

  .stat-cards{grid-template-columns:1fr 1fr;}

  /* Kop-actieknoppen (Exporteren/Importeren/+Nieuw...) mogen nooit
     horizontaal overlopen: vouw ze naar de volgende regel i.p.v. het
     scherm uit te laten steken. Specifieke pagina's (zoals Rooster) kunnen
     dit verder verfijnen met .topbar-actions-mobile hieronder. */
  .topbar-right{flex-wrap:wrap;justify-content:flex-start;gap:8px;}
  .topbar-app{padding:14px 16px;flex-wrap:wrap;gap:10px;}
  .topbar-app h1{font-size:17px;}
  .content{padding:16px 14px 40px;}

  /* Generiek patroon voor een primaire knop vol-breed bovenaan + de
     overige knoppen ernaast in een rij van 2 (i.p.v. 3+ knoppen plat naast
     elkaar die niet passen). De DOM-volgorde blijft ongewijzigd (dus ook
     ongewijzigd op desktop, waar .topbar-actions-mobile via display:contents
     hierboven onzichtbaar is) -- op mobiel wordt de primaire knop met
     order:-1 + grid-column:1/-1 vol-breed bovenaan geplaatst. */
  .topbar-actions-mobile{display:grid;grid-template-columns:1fr 1fr;gap:8px;width:100%;}
  .topbar-actions-mobile .pbtn{width:100%;justify-content:center;}
  .topbar-actions-mobile .pbtn-primary{grid-column:1 / -1;order:-1;}

  /* Tabellen -> kaarten (zie mobile-tables.js voor de attributen/klassen
     die hier op leunen). thead blijft technisch in de DOM voor de
     kolomlabels van de JS, maar is visueel verborgen op mobiel. */
  .panel{padding:16px;}
  table.ptable[data-mobile-enhanced="1"]{display:block;width:100%;}
  table.ptable[data-mobile-enhanced="1"] thead{display:none;}
  table.ptable[data-mobile-enhanced="1"] tbody{display:block;}
  table.ptable[data-mobile-enhanced="1"] tr{
    display:block;border:1px solid var(--gray-100);border-radius:10px;
    padding:12px 14px;margin-bottom:10px;
  }
  table.ptable[data-mobile-enhanced="1"] tr:last-child{margin-bottom:0;}
  table.ptable[data-mobile-enhanced="1"] td{
    display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:5px 0;border:none;text-align:right;
  }
  table.ptable[data-mobile-enhanced="1"] td[colspan]{justify-content:center;text-align:center;}
  table.ptable[data-mobile-enhanced="1"] td::before{
    content:attr(data-label);font-size:11px;font-weight:700;color:var(--gray-600);
    text-align:left;flex:none;text-transform:uppercase;letter-spacing:.02em;
  }
  table.ptable[data-mobile-enhanced="1"] td.ptable-primary{font-size:14px;font-weight:700;color:var(--ink);}
  table.ptable[data-mobile-enhanced="1"] td.ptable-primary::before{display:none;}
  table.ptable[data-mobile-enhanced="1"] td.ptable-primary:first-child{padding-top:0;}
  table.ptable[data-mobile-enhanced="1"] td.ptable-hidden{display:none;}
  table.ptable[data-mobile-enhanced="1"] tr.ptable-open td.ptable-hidden{display:flex;}
  table.ptable[data-mobile-enhanced="1"] .ptable-toggle-cell{
    display:block;text-align:left;padding-top:8px;margin-top:4px;border-top:1px solid var(--gray-100);
  }
  table.ptable[data-mobile-enhanced="1"] .ptable-toggle-cell::before{display:none;content:none;}
  table.ptable[data-mobile-enhanced="1"] .ptable-toggle-btn{
    background:none;border:none;padding:0;color:var(--blue-600);font-size:12.5px;font-weight:700;cursor:pointer;
  }
}
/* .ptable-toggle-cell/.ptable-hidden hebben buiten de mobiele media query
   geen effect nodig -- data-mobile-enhanced staat alleen aan onder de
   breakpoint (mobile-tables.js voegt de klassen wel altijd toe, maar zonder
   de media query hierboven blijft de tabel gewoon een normale desktoptabel;
   de toggle-cel is standaard verborgen zodat hij op desktop geen extra
   lege kolom toont). */
.ptable-toggle-cell{display:none;}
/* Veld dat alleen op mobiel zichtbaar hoeft te zijn (bijv. de functiekiezer
   boven de rechtenmatrix). Standaard verborgen, zichtbaar gemaakt in de
   @media-regel hieronder. */
.mobile-only-field{display:none;}
@media (max-width:880px){
  .mobile-only-field{display:block;}
  #rechtenMatrix th:first-child,#rechtenMatrix td:first-child{min-width:0;}
}

/* Knop "terug naar boven" -- verschijnt pas na wat scrollen (zie
   back-to-top.js), rechtsonder in beeld op elke pagina van het portaal. */
.back-to-top{
  position:fixed;right:20px;bottom:20px;width:44px;height:44px;border-radius:50%;
  background:var(--blue-600);color:#fff;border:none;display:flex;align-items:center;justify-content:center;
  box-shadow:0 10px 24px rgba(10,19,48,.28);cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .2s,transform .2s,visibility .2s;z-index:150;
}
.back-to-top.visible{opacity:1;visibility:visible;transform:translateY(0);}
.back-to-top:hover{background:var(--blue-700);}

/* Waarschuwingsbalk tijdens impersonatie ("inloggen als een andere
   gebruiker") -- moet altijd opvallen, ongeacht licht/donker thema. */
.impersonatie-banner{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  background:#fef3c7;color:#92400e;border-bottom:2px solid #f59e0b;
  padding:10px 20px;font-size:13px;font-weight:600;
}
.impersonatie-banner form{margin:0;}
.impersonatie-banner .pbtn{padding:6px 14px;font-size:12.5px;background:#fff;}
.back-to-top svg{width:20px;height:20px;}
@media (max-width:880px){
  .back-to-top{right:16px;bottom:16px;}
}

/* Tarieven-tabellen (Klanten / Onderaannemers): het zijn twee losse
   <table>-elementen, dus zonder vaste kolombreedtes berekent elke tabel
   zijn kolommen onafhankelijk op basis van de eigen inhoud (namen van
   verschillende lengte) -- daardoor stonden Aanpassen/Verwijderen in de
   ene tabel net iets anders uitgelijnd dan in de andere. table-layout:fixed
   + gelijke width% op de th's in beide tabellen (zie financieel_tarieven.html)
   forceert identieke kolombreedtes, zodat de acties netjes onder elkaar
   staan tussen de twee tabellen. */
table.ptable-tarieven{table-layout:fixed;}
