@import url('https://fonts.googleapis.com/css2?family=Sora:wght@500;600;700;800&family=Inter:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

/*
  Ontwerprichting: een HUB is letterlijk een zendertje -- RS485-bus,
  MQTT-publish/subscribe, een lichtsensor die continu meet. Het "spannender"
  maken van deze portal leunt daarom op een zend/ontvangst-motief (puls-dot
  op "online", een concentrische broadcast-icoon als merk, richting-pijltjes
  op in/uit-badges) in plaats van willekeurige decoratie -- vorm die iets
  echts over de staat van het systeem zegt, geen versiering.
*/

:root{
  --bg:            #f3f1ec;
  --panel:         #ffffff;
  --line:          #e6e0d5;
  --ink:           #221f1b;
  --ink-soft:      #857a6d;
  --teal:          #f2761a;
  --teal-deep:     #c1450a;
  --teal-soft:     #fce8d4;
  --green:         #3f9d63;
  --green-soft:    #e1f3e7;
  --amber:         #b8901a;
  --amber-soft:    #f7f0d9;
  --red:           #c65b4e;
  --red-soft:      #f7e1de;
  --radius:        12px;
  --radius-lg:     18px;
  --shadow-sm:     0 1px 2px rgba(34,31,27,.05), 0 1px 1px rgba(34,31,27,.04);
  --shadow-md:     0 12px 28px -12px rgba(34,31,27,.22);
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}

*{ box-sizing: border-box; }
html{ scroll-behavior: smooth; }
body{
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 14.5px;
  line-height: 1.5;
}
h1,h2,h3,h4{ font-family: 'Sora', 'Inter', sans-serif; font-weight: 700; margin: 0 0 .5em; color: var(--ink); text-wrap: balance; letter-spacing: -.01em; }
h1{ font-size: 1.7rem; }
a{ color: var(--teal); text-decoration: none; }
a:hover{ text-decoration: underline; }
code, .mono{ font-family: var(--mono); }
:focus-visible{ outline: 2px solid var(--teal); outline-offset: 2px; border-radius: 4px; }

/* -- zendbalk: dunne gradient-streep bovenaan de pagina, als een signaalindicator -- */
body::before{
  content:''; display:block; position: sticky; top:0; height:3px; z-index: 20;
  background: linear-gradient(90deg, var(--teal-deep), var(--teal) 45%, #ffb066 75%, var(--teal));
  background-size: 200% 100%;
  animation: zend-sweep 7s linear infinite;
}
@keyframes zend-sweep{ to{ background-position: -200% 0; } }

/* -- topbar -- */
.topbar{
  display:flex; align-items:center; gap: 1.5rem;
  background: var(--panel); border-bottom: 1px solid var(--line);
  padding: .7rem 1.5rem; position: sticky; top:3px; z-index: 10;
  box-shadow: var(--shadow-sm);
}
.topbar-brand{ display:flex; align-items:center; gap:.7rem; flex-shrink:0; }

/* Broadcast-icoon i.p.v. een vlakke stip: middenstip + twee concentrische
   bogen die traag naar buiten pulsen -- letterlijk wat een HUB doet
   (uitzenden). Staat stil onder prefers-reduced-motion, zie hierboven. */
.brand-mark{ position:relative; width:30px; height:30px; flex-shrink:0; display:flex; align-items:center; justify-content:center; }
.brand-mark svg{ width:100%; height:100%; overflow: visible; }
.brand-mark .puls-ring{ transform-origin: center; animation: puls 2.6s ease-out infinite; }
.brand-mark .puls-ring.r2{ animation-delay: .9s; }
@keyframes puls{
  0%   { opacity:.55; transform: scale(.45); }
  70%  { opacity: 0;  transform: scale(1); }
  100% { opacity: 0;  transform: scale(1); }
}
.brand-naam{ font-family:'Sora',sans-serif; font-weight:700; font-size:1.05rem; letter-spacing:-.01em; }
.brand-tag{ font-family: var(--mono); font-size:.7rem; color: var(--ink-soft); letter-spacing:.03em; }

.topbar-zoek{ display:flex; width:100%; max-width: 420px; margin-left:auto; }
.topbar-zoek input{ flex:1; border:1px solid var(--line); border-right:none; border-radius: var(--radius) 0 0 var(--radius); padding:.5rem .8rem; font-size:.9rem; background:#fdfcfa; transition: border-color .15s, background .15s; }
.topbar-zoek input:focus{ outline:none; border-color: var(--teal); background:#fff; }
.topbar-zoek button{
  border:none; background: linear-gradient(135deg, var(--teal), var(--teal-deep)); color:#fff;
  border-radius: 0 var(--radius) var(--radius) 0; padding:.5rem 1.1rem; cursor:pointer; font-weight:600; font-size:.86rem;
  transition: filter .15s;
}
.topbar-zoek button:hover{ filter: brightness(1.08); }

.topbar-gebruiker{ display:flex; gap:.6rem; align-items:center; font-size:.85rem; color: var(--ink-soft); flex-shrink:0; }
.topbar-gebruiker strong{ color: var(--ink); }
.topbar-gebruiker form{ display:inline; }
.topbar-gebruiker button{ border:none; background:none; color: var(--teal); font-size:.85rem; font-weight:600; cursor:pointer; padding:0; }
.topbar-gebruiker button:hover{ text-decoration:underline; }

/* -- login-scherm (staat los van base.html/topbar, eigen kale pagina) -- */
.login-scherm{ min-height:100vh; display:flex; align-items:center; justify-content:center; padding:1.5rem; }
.login-kaart{ width:100%; max-width:360px; }
.login-merk{ display:flex; align-items:center; gap:.7rem; margin-bottom:1.3rem; }

/* -- tabs -- */
.tabs{ display:flex; gap: .3rem; background: var(--panel); border-bottom: 1px solid var(--line); padding: .5rem 1.3rem; }
.tabs a{ display:inline-flex; align-items:center; padding: .5rem 1rem; color: var(--ink-soft); font-weight:600; font-size:.88rem; border-radius: 99px; transition: background .15s, color .15s; }
.tabs a:hover{ text-decoration:none; color: var(--ink); background: var(--bg); }
.tabs a.actief{ color: var(--teal); background: var(--teal-soft); }

.inhoud{ max-width: 1180px; margin: 1.8rem auto; padding: 0 1.5rem 3rem; }
.footer{ text-align:center; color: var(--ink-soft); font-size:.78rem; padding: 1.5rem; }

/* -- flash -- */
.flashes{ margin-bottom: 1rem; display:flex; flex-direction:column; gap:.5rem; }
.flash{
  padding:.65rem 1rem; border-radius: var(--radius); font-size:.9rem; border:1px solid transparent;
  animation: flash-in .25s ease-out;
}
@keyframes flash-in{ from{ transform: translateY(-8px); opacity: 0; } to{ transform: translateY(0); opacity: 1; } }
.flash-success{ background: var(--green-soft); color:#265f3f; border-color:#bfe0cc; }
.flash-warning{ background: var(--amber-soft); color:#7a5416; border-color:#eecf9c; }
.flash-danger{ background: var(--red-soft); color:#7c3226; border-color:#e9bcb4; }

/* -- knop-status tijdens het verwerken van een formulier (zie bevestig.js) -- */
button:disabled, .btn:disabled, .btn-icoon:disabled{ opacity:.6; cursor: progress; }

/* -- panels / cards -- */
.panel{ background: var(--panel); border:1px solid var(--line); border-radius: var(--radius-lg); padding: 1.3rem 1.5rem; margin-bottom: 1.2rem; box-shadow: var(--shadow-sm); }
.panel-hoofd{ display:flex; align-items:center; justify-content:space-between; margin-bottom: .8rem; }

.grid-kaarten{ display:grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap: 1rem; }
.kaart{
  position:relative; overflow:hidden;
  background: var(--panel); border:1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.1rem 1.2rem 1rem; box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease;
}
.kaart::before{
  content:''; position:absolute; top:0; left:0; right:0; height:3px;
  background: linear-gradient(90deg, var(--teal), var(--teal-deep));
  opacity:.85;
}
.kaart:hover{ transform: translateY(-3px); box-shadow: var(--shadow-md); }
.kaart-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:.5rem; }
.kaart-icoon{ color: var(--teal); opacity:.75; flex-shrink:0; }
.kaart-icoon svg{ width:19px; height:19px; }
.kaart .getal{
  font-family:'Sora',sans-serif; font-size: 1.9rem; font-weight:800; letter-spacing:-.02em;
  font-variant-numeric: tabular-nums; margin-top:.35rem;
  background: linear-gradient(135deg, var(--ink) 35%, var(--teal-deep));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.kaart .label{ color: var(--ink-soft); font-size: .8rem; font-weight:500; }

/* -- tabellen -- */
table{ width:100%; border-collapse: collapse; font-size: .88rem; }
th, td{ text-align:left; padding: .6rem .65rem; border-bottom: 1px solid var(--line); vertical-align: top; }
th{ color: var(--ink-soft); font-weight:600; font-size:.74rem; text-transform:uppercase; letter-spacing:.05em; font-family: var(--mono); }
/* 260821, gevonden via een echte layout-bug: `position:relative` op <tr> +
   een absoluut gepositioneerde ::before erin (de vorige aanpak voor de
   hover-accentstreep) bleek in de praktijk kolommen van thead/tbody te
   kunnen laten desynchroniseren (headers stonden een kolom naast hun
   waarden) -- <tr> is een table-internal display-type en gedraagt zich
   onvoorspelbaar als positioneringscontext voor een pseudo-element. Een
   inset box-shadow op de eerste cel geeft hetzelfde accentstreepje puur
   als paint-effect, zonder dat er een extra box aan de tabel-layout
   meedoet. */
tbody tr{ transition: background .12s; }
tbody tr td:first-child{ box-shadow: inset 3px 0 0 0 transparent; transition: box-shadow .15s ease; }
tr:hover td{ background: #faf8f5; }
tbody tr:hover td:first-child{ box-shadow: inset 3px 0 0 0 var(--teal); }

/* -- status badges -- */
.badge{ display:inline-flex; align-items:center; gap:.35rem; padding: .18rem .6rem .18rem .5rem; border-radius: 99px; font-size:.75rem; font-weight:600; }
.badge::before{ content:''; width:6px; height:6px; border-radius:50%; flex-shrink:0; background: currentColor; }
.badge-online, .badge-ok{ background: var(--green-soft); color:#265f3f; }
.badge-online::before{ animation: badge-puls 1.8s ease-out infinite; }
@keyframes badge-puls{
  0%   { box-shadow: 0 0 0 0 rgba(63,157,99,.55); }
  70%  { box-shadow: 0 0 0 5px rgba(63,157,99,0); }
  100% { box-shadow: 0 0 0 0 rgba(63,157,99,0); }
}
.badge-offline, .badge-fout{ background: var(--red-soft); color:#7c3226; }
.badge-onbekend{ background:#ece7dd; color: var(--ink-soft); }
.badge-in::before{ content:'\2193'; width:auto; height:auto; border-radius:0; background:none; font-size:.85em; line-height:1; }
.badge-uit::before{ content:'\2191'; width:auto; height:auto; border-radius:0; background:none; font-size:.85em; line-height:1; }
.badge-in{ background: var(--teal-soft); color:#8a4a10; }
.badge-uit{ background: var(--amber-soft); color:#7a5416; }
.badge-waarschuwing{ background: var(--amber-soft); color:#7a5416; }

/* 260821, op gebruikersverzoek: een knalrood bolletje vóór de displaynaam i.p.v. de hele
   tabelrij rood te kleuren -- leest rustiger op een dichte tabel, en verbreedt de rij niet. */
.stip-onbereikbaar{
  display:inline-block; width:8px; height:8px; border-radius:50%;
  background: var(--red); margin-right:.4rem; flex-shrink:0;
}

/* -- LDR licht->helderheid: vier gelijke kaarten --
   260821, op gebruikersverzoek: drempels en niveaus stonden als losse,
   ongerelateerde invoervelden in twee aparte rijtjes -- niet in één
   oogopslag te zien welk raw-ADC-bereik bij welk helderheidsniveau hoort.
   Elke situatie (donker/schemer/bewolkt/zonnig) is nu één kaart met haar
   eigen niveau- en drempelveld samen. Bewust GEEN achtergrondkleur/schaal-
   breedte naar raw-waarde en GEEN sleep-slider (op gebruikersverzoek: in
   het veld werkt getypte invoer + TAB betrouwbaarder dan slepen met een
   muis/trackpad) -- gewone, gelijk-brede kaarten met gewone getalvelden. */
.ldr-kaarten{ display:grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin: 1.2rem 0 1.6rem; }
.ldr-kaart{ background: var(--panel); border:1px solid var(--line); border-radius: var(--radius-lg); padding: 1rem 1.1rem; }
.ldr-kaart-kop{ display:flex; align-items:center; gap:.5rem; margin-bottom:.8rem; }
.ldr-kaart-icoon{ font-size: 1.5rem; line-height:1; }
.ldr-kaart-naam{ font-family:'Sora',sans-serif; font-weight:700; font-size:.92rem; }
.ldr-kaart .form-veld{ margin-bottom:.7rem; }
.ldr-kaart .form-veld:last-child{ margin-bottom:0; }
.ldr-kaart-tot{ display:flex; flex-direction:column; justify-content:flex-end; }

/* -- forms -- */
.form-grid{ display:grid; grid-template-columns: repeat(auto-fit, minmax(220px,1fr)); gap: 1rem; }
.form-veld{ display:flex; flex-direction:column; gap:.3rem; margin-bottom: .9rem; }
.form-veld label{ font-size:.8rem; font-weight:600; color: var(--ink-soft); }
.form-veld input, .form-veld select, .form-veld textarea{
  border:1px solid var(--line); border-radius:9px; padding:.55rem .7rem; font-family: inherit; font-size:.92rem; background:#fdfcfa;
  transition: border-color .15s, background .15s;
}
.form-veld input:focus, .form-veld select:focus, .form-veld textarea:focus{ outline:none; border-color: var(--teal); background:#fff; }
.form-veld input[type=checkbox]{ width:auto; align-self:flex-start; }
textarea{ resize: vertical; }

.btn{ display:inline-block; border:1px solid var(--line); background:#fff; color: var(--ink); border-radius:9px; padding:.55rem 1.05rem; font-size:.86rem; font-weight:600; cursor:pointer; transition: transform .12s, box-shadow .12s, background .12s; }
.btn:hover{ background:#faf8f5; text-decoration:none; transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn-primair{ background: linear-gradient(135deg, var(--teal), var(--teal-deep)); border-color: transparent; color:#fff; }
.btn-primair:hover{ background: linear-gradient(135deg, var(--teal), var(--teal-deep)); color:#fff; filter: brightness(1.06); box-shadow: 0 6px 16px -6px rgba(194,69,10,.55); }
.btn-gevaar{ background:#fff; border-color: var(--red); color: var(--red); }
.btn-gevaar:hover{ background: var(--red-soft); color: var(--red); }
.btn-klein{ padding:.32rem .7rem; font-size:.78rem; }
.knoppenrij{ display:flex; gap:.5rem; flex-wrap:wrap; margin-top:.6rem; }

.subtiel{ color: var(--ink-soft); font-size:.85rem; }
.mac{ font-family: var(--mono); font-size:.85rem; }
.breadcrumb{ font-size:.78rem; color: var(--ink-soft); margin-bottom:.8rem; font-family: var(--mono); text-transform:uppercase; letter-spacing:.04em; }
.breadcrumb a{ color: var(--ink-soft); }
.sectietitel{ display:flex; align-items:center; justify-content:space-between; margin: 1.8rem 0 .7rem; }

.json-blok{ background:#faf8f5; border:1px solid var(--line); border-radius:9px; padding:.7rem .9rem; font-family: var(--mono); font-size:.78rem; white-space:pre-wrap; word-break: break-word; }

.paginering{ display:flex; gap:.6rem; align-items:center; margin-top:1rem; font-size:.85rem; }

.leeg{ color: var(--ink-soft); font-style: italic; padding: 1rem 0; }

/* -- in-pagina subtabs (bijv. Status/Configuratie op een opstelling) --
   Bewust een ander motief dan .tabs hierboven (los-liggende pillen): een
   gesloten, gevulde "segmented control"-groep, zodat direct duidelijk is
   dat dit een lokale weergave-toggle is en geen sitenavigatie. */
.subtabs{
  display:inline-flex; gap:.15rem; background: var(--bg); border:1px solid var(--line);
  border-radius: 999px; padding:.25rem; margin-bottom: 1.2rem;
}
.subtabs button{
  border:none; background:none; cursor:pointer; padding:.5rem 1.15rem; font-size:.86rem; font-weight:600;
  color: var(--ink-soft); border-radius:999px; font-family: inherit; transition: background .15s, color .15s, box-shadow .15s;
}
.subtabs button.actief{ color: var(--teal-deep); background: var(--panel); box-shadow: var(--shadow-sm); }
.subtabs button:hover:not(.actief){ color: var(--ink); background: rgba(34,31,27,.05); }

/* -- compacte tabellen (bijv. display-overzicht) -- */
.tabel-dicht th, .tabel-dicht td{ padding: .4rem .55rem; font-size: .85rem; }
.tabel-dicht td.acties{ white-space: nowrap; }
.tabel-dicht form{ display:inline; }
.tabel-dicht .btn-icoon{
  display:inline-flex; align-items:center; justify-content:center; width:1.8rem; height:1.8rem;
  border:1px solid var(--line); background:#fff; border-radius:7px; cursor:pointer; font-size:.9rem; padding:0;
  transition: transform .12s, background .12s;
}
.tabel-dicht .btn-icoon:hover{ background:#faf8f5; transform: translateY(-1px); }
