/* ============================================================================
   DE SMULSTRAAT - Design system (basis)
   Fris, modern, smaakvol. Tokens, componenten en micro-animaties.
   ========================================================================== */

:root {
  /* Merk */
  --brand: #ea3b2c;
  --brand-600: #cf2620;
  --brand-2: #ff9e2c;
  --brand-grad: linear-gradient(135deg, #ea3b2c 0%, #ff9e2c 100%);
  --brand-grad-soft: linear-gradient(135deg, rgba(234, 59, 44, .14), rgba(255, 158, 44, .14));
  --plum: #2a1830;

  /* Inkt & vlakken */
  --ink: #1c1420;
  --ink-2: #4b4453;
  --ink-3: #726c7b;
  --bg: #fbf5ef;
  --bg-2: #f4ece3;
  --surface: #ffffff;
  --surface-2: #fbf7f3;
  --line: rgba(28, 20, 32, .09);
  --line-2: rgba(28, 20, 32, .14);

  /* Status */
  --open: #15a34a;
  --open-bg: #e7f7ed;
  --closing: #e08a00;
  --closed: #9aa0a6;
  --soon: #6366f1;
  --danger: #e5484d;

  /* Radii */
  --r-xs: 8px;
  --r-sm: 12px;
  --r: 18px;
  --r-lg: 26px;
  --r-xl: 36px;
  --r-pill: 999px;

  /* Schaduw */
  --sh-sm: 0 1px 2px rgba(28, 20, 32, .06), 0 2px 8px rgba(28, 20, 32, .05);
  --sh: 0 6px 18px rgba(28, 20, 32, .08), 0 2px 6px rgba(28, 20, 32, .05);
  --sh-lg: 0 18px 50px rgba(28, 20, 32, .16), 0 6px 16px rgba(28, 20, 32, .08);
  --sh-brand: 0 12px 30px rgba(234, 59, 44, .38);

  /* Typografie */
  --font: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Bricolage Grotesque", var(--font);

  --maxw: 1180px;
  --header-h: 70px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { max-width: 100%; display: block; }
button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-family: var(--display); font-weight: 800; line-height: 1.08; letter-spacing: -.02em; margin: 0; }
p { margin: 0; }
::selection { background: rgba(234, 59, 44, .22); }

.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }
.muted { color: var(--ink-3); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }

/* Scrollbar */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-thumb { background: var(--line-2); border-radius: 99px; border: 3px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); background-clip: padding-box; }

/* ----------------------------- Knoppen ------------------------------------ */
.btn {
  --bg: var(--brand);
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  border: 0; border-radius: var(--r-pill);
  padding: 13px 22px; font-size: 15px; font-weight: 700; color: #fff;
  background: var(--brand-grad); box-shadow: var(--sh-brand);
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1), box-shadow .2s, filter .2s;
  position: relative; white-space: nowrap;
}
.btn:hover { transform: translateY(-2px) scale(1.02); box-shadow: 0 16px 36px rgba(234, 59, 44, .42); }
.btn:active { transform: translateY(0) scale(.98); }
.btn:disabled, .btn[disabled] { filter: grayscale(.5) opacity(.6); box-shadow: none; cursor: not-allowed; transform: none; }
.btn.secondary { background: var(--surface); color: var(--ink); box-shadow: var(--sh-sm); border: 1px solid var(--line-2); }
.btn.secondary:hover { box-shadow: var(--sh); }
.btn.ghost { background: transparent; color: var(--ink); box-shadow: none; }
.btn.ghost:hover { background: rgba(28, 20, 32, .05); transform: translateY(-1px); }
.btn.dark { background: var(--ink); color: #fff; box-shadow: var(--sh); }
.btn.dark:hover { box-shadow: var(--sh-lg); }
.btn.sm { padding: 9px 15px; font-size: 13.5px; }
.btn.lg { padding: 16px 30px; font-size: 16.5px; }
.btn.block { width: 100%; }
.btn .ico { font-size: 1.15em; line-height: 1; }

/* Ronde icoon-knop */
.icon-btn {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--sh-sm);
  font-size: 19px; color: var(--ink); transition: transform .18s cubic-bezier(.34, 1.56, .64, 1), box-shadow .2s, background .2s;
}
.icon-btn:hover { transform: translateY(-2px) scale(1.06); box-shadow: var(--sh); }
.icon-btn:active { transform: scale(.94); }

/* Klant-avatar (signature-dish, migratie 0056). base.css laadt op zowel
   index.html als admin.html, dus hier staat de gedeelde basis. #accountBtn is
   de klantsite-topbar-knop zelf: assets/js/utils.js's vulAvatarGerecht zet de
   <img> rechtstreeks op dat element (er is geen los .avatar-wrapper op
   index.html zoals in de personeels-topbar). Zonder overflow:hidden knipt een
   rechthoekige foto niet rond in het cirkelvormige bolletje. .topbar .avatar
   (personeels-topbar) en .kl-avatar (klantenlijst in het beheerscherm) delen
   dezelfde regels.
   De niveau-rand zelf staat hier NIET meer: sinds migratie 0062 is de kleur
   instelbaar, en base.css wordt live een jaar immutable gecachet - een
   kleurwijziging in het beheer zou bezoekers dan nooit bereiken.
   SMUL.vulAvatarGerecht (utils.js) zet 'm daarom inline als box-shadow uit de
   config. Statische rand, geen animatie - dat verandert niet: de "geen
   box-shadow-animatie"-afspraak geldt voor herhaaldelijk zichtbare BEWEGENDE
   elementen (zoals de status-stip), niet voor een stilstaande rand. */
#accountBtn { overflow: hidden; }
#accountBtn .avatar-img, .topbar .avatar .avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Plus/min stepper */
.stepper { display: inline-flex; align-items: center; gap: 0; background: var(--surface-2); border-radius: var(--r-pill); border: 1px solid var(--line); overflow: hidden; }
.stepper button { width: 34px; height: 34px; border: 0; background: transparent; font-size: 19px; font-weight: 700; color: var(--brand); line-height: 1; transition: background .15s, transform .12s; }
.stepper button:hover { background: rgba(234, 59, 44, .12); }
.stepper button:active { transform: scale(.85); }
.stepper .qty { min-width: 26px; text-align: center; font-weight: 800; font-variant-numeric: tabular-nums; }

/* ------------------------------ Chips/Badges ------------------------------ */
.chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: var(--r-pill);
  background: var(--surface); border: 1px solid var(--line); font-size: 13.5px; font-weight: 600; color: var(--ink-2);
  transition: transform .15s, box-shadow .2s, border-color .2s, color .2s;
}
.chip:hover { transform: translateY(-1px); box-shadow: var(--sh-sm); }
.chip.active { background: var(--ink); color: #fff; border-color: var(--ink); }

.badge {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 800; letter-spacing: .02em; text-transform: uppercase;
}
.badge.populair { background: #fff1ec; color: var(--brand-600); }
.badge.nieuw { background: #eaf6ff; color: #0b6fd0; }
.badge.pittig { background: #ffeaea; color: #d6342c; }
.badge.veggie { background: #e9f9ec; color: #138a3f; }
.badge.deal { background: #fff6e0; color: #b9770a; }
.badge.dieet { background: #e9f9ec; color: #138a3f; }
.allerg { margin-top: 6px; font-size: 12px; color: var(--ink-3); display: flex; align-items: center; gap: 4px; }
.allerg .smul-ic { vertical-align: -0.15em; }

/* ----------------------------- Status-pills ------------------------------- */
.status { display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px; border-radius: var(--r-pill); font-size: 12.5px; font-weight: 700; }
/* .dot zelf is alleen nog de doos; de kern is een ::after-pseudo-element en de
   pulserende ring een ::before. Zo draait de puls op transform en opacity (door
   de GPU samengesteld) in plaats van op box-shadow, dat elk frame opnieuw op de
   hoofdthread moet worden geschilderd. Lighthouse noemde dit als de enige
   niet-samengestelde animatie op de homepagina.
   ::before wordt vóór ::after geschilderd, dus de ring zit netjes achter de
   kern. De ring bestaat bewust ALLEEN op .status.open: bij de grijze en oranje
   statussen zou een groene cirkel onder de kern een randje kunnen geven. */
.status .dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: none; box-shadow: none; }
.status .dot::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: currentColor; }
.status.open { background: rgba(21, 163, 74, .12); color: #0f7a37; }
/* Schaalfactor 2,75 = de oude buitendiameter (8 px kern + 2 x 7 px spread = 22 px) gedeeld door 8. */
.status.open .dot::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: rgba(21, 163, 74, .5); animation: pulse-ring 1.8s infinite; }
.status.closing { background: rgba(224, 138, 0, .14); color: #a05f00; }
.status.opening { background: rgba(99, 102, 241, .14); color: #4548c4; }
.status.closed { background: rgba(120, 120, 130, .14); color: #6b7280; }
.status.soon { background: rgba(99, 102, 241, .12); color: #5457e6; }

/* ------------------------------- Kaarten ---------------------------------- */
.card { background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--sh-sm); border: 1px solid var(--line); }

/* Formulier */
.input, .select, textarea.input {
  width: 100%; padding: 13px 15px; border-radius: var(--r-sm); border: 1.5px solid var(--line-2);
  background: var(--surface); font: inherit; color: var(--ink); transition: border-color .18s, box-shadow .18s;
}
.input:focus, .select:focus, textarea.input:focus { outline: 0; border-color: var(--brand); box-shadow: 0 0 0 4px rgba(234, 59, 44, .14); }
.input.autofilled { border-color: #16a34a; box-shadow: 0 0 0 4px rgba(22, 163, 74, .16); }
label.field { display: block; }
label.field > span { display: block; font-size: 13px; font-weight: 700; color: var(--ink-2); margin-bottom: 6px; }

/* Toggle-switch */
.switch { position: relative; display: inline-block; width: 48px; height: 28px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; background: var(--line-2); border-radius: 99px; transition: background .22s; }
.switch .track::before { content: ""; position: absolute; height: 22px; width: 22px; left: 3px; top: 3px; background: #fff; border-radius: 50%; box-shadow: var(--sh-sm); transition: transform .24s cubic-bezier(.34, 1.56, .64, 1); }
.switch input:checked + .track { background: var(--open); }
.switch input:checked + .track::before { transform: translateX(20px); }

/* --------------------------- Layout helpers ------------------------------- */
.row { display: flex; align-items: center; gap: 12px; }
.between { justify-content: space-between; }
.wrap { flex-wrap: wrap; }
.grow { flex: 1; }
.stack { display: flex; flex-direction: column; }
.section { padding: 64px 0; }
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 26px; }
.eyebrow { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-600); }

/* CLS: reserveer de resthoogte van het scherm voor de SPA-view. Zonder deze
   regel staat <main id="view"> bij de eerste paint op 0 px hoog en plakt de
   footer direct onder de header. Zodra app.js rendert springt die footer
   duizenden pixels omlaag: dat is 0,844 van de 0,861 CLS. Met deze reservering
   staat de footer bij de eerste paint al onder de vouw en telt de verschuiving
   niet mee. Geldt voor alle routes, niet alleen de homepagina.
   Bewust 100vh en niet 100svh/100dvh: in Chrome mobiel is 100vh de LARGE
   viewport (zonder URL-balk), dus altijd groter dan of gelijk aan wat de
   bezoeker echt ziet. Met 100svh kan de footer bij een ingeklapte URL-balk net
   wel in beeld vallen en houd je restschade over. --header-h wordt per
   breakpoint uitgerekend (70 px desktop, 58 px mobiel via mobile.css), dus
   deze ene regel klopt in beide gevallen. */
main#view { min-height: calc(100vh - var(--header-h)); }

/* ------------------------------ Animaties --------------------------------- */
/* pulse-dot blijft bestaan: app.css (.tracker .step.active .ic) en dashboard.css
   (.topbar .live .dot) gebruiken hem ook, en die staan niet op de homepagina. */
@keyframes pulse-dot { 0% { box-shadow: 0 0 0 0 rgba(21, 163, 74, .5); } 70% { box-shadow: 0 0 0 7px rgba(21, 163, 74, 0); } 100% { box-shadow: 0 0 0 0 rgba(21, 163, 74, 0); } }
/* GPU-variant van pulse-dot voor .status.open .dot::before. Geen will-change:
   Chrome promoot een oneindige transform/opacity-animatie zelf al. */
@keyframes pulse-ring { 0% { transform: scale(1); opacity: 1; } 70% { transform: scale(2.75); opacity: 0; } 100% { transform: scale(1); opacity: 0; } }
@keyframes pop-in { 0% { transform: scale(.8); opacity: 0; } 60% { transform: scale(1.06); } 100% { transform: scale(1); opacity: 1; } }
/* Gecentreerde variant: houdt de translate(-50%,-50%) vast tijdens en na de animatie.
   Zonder deze variant overschrijft de scale-animatie de centrering en valt de modal
   rechtsonder (linkerbovenhoek op het scherm-midden). */
@keyframes pop-in-center { 0% { transform: translate(-50%, -50%) scale(.85); opacity: 0; } 60% { transform: translate(-50%, -50%) scale(1.03); } 100% { transform: translate(-50%, -50%) scale(1); opacity: 1; } }
@keyframes slide-up { from { transform: translateY(22px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes float-up { 0% { transform: translateY(0) scale(.6); opacity: 0; } 25% { opacity: 1; transform: translateY(-10px) scale(1.1); } 100% { transform: translateY(-58px) scale(1); opacity: 0; } }
@keyframes cart-bounce { 0%, 100% { transform: scale(1); } 30% { transform: scale(1.32) rotate(-8deg); } 55% { transform: scale(.9) rotate(5deg); } 75% { transform: scale(1.12); } }
@keyframes confetti-fall { 0% { transform: translateY(0) rotateZ(0); opacity: 1; } 100% { transform: translateY(120px) rotateZ(360deg); opacity: 0; } }
@keyframes ring { 0% { transform: scale(.6); opacity: .7; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes wiggle { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-9deg); } 75% { transform: rotate(9deg); } }
@keyframes rise-fade { 0% { transform: translateY(8px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } }

.anim-pop { animation: pop-in .4s cubic-bezier(.34, 1.56, .64, 1) both; }
.anim-pop-center { animation: pop-in-center .4s cubic-bezier(.34, 1.56, .64, 1) both; }
.reveal { opacity: 0; }
.reveal.in { animation: slide-up .6s cubic-bezier(.22, 1, .36, 1) both; }
.cart-bounce { animation: cart-bounce .55s ease; }
.wiggle { animation: wiggle .4s ease; }

/* Vliegend "+1" / punten label */
.float-label { position: fixed; z-index: 9999; pointer-events: none; font-weight: 900; font-size: 15px; color: var(--brand-600); animation: float-up 1s ease forwards; text-shadow: 0 1px 0 #fff; }
.float-label.pts { color: var(--brand-2); }

/* Vliegend item-bolletje naar winkelwagen */
.fly-dot { position: fixed; z-index: 9999; width: 28px; height: 28px; border-radius: 50%; background: var(--brand-grad); box-shadow: var(--sh-brand); display: grid; place-items: center; font-size: 15px; pointer-events: none; }

/* Confetti */
.confetti-piece { position: fixed; z-index: 9998; width: 9px; height: 14px; border-radius: 2px; pointer-events: none; animation: confetti-fall .9s ease-out forwards; }

/* --------------------------------- Skeleton -------------------------------
   Een skeleton is geen versiering maar MAATVOERING. Hij houdt precies de ruimte
   vast die de echte inhoud straks inneemt, zodat er niets verspringt zodra de
   data binnen is - dezelfde CLS-gedachte als main#view { min-height } in dit
   bestand. Een skeleton die kleiner is dan wat erna komt, is erger dan geen
   skeleton.

   De glans loopt over een ::after die op TRANSFORM beweegt, niet op
   background-position zoals hiervoor. Een schuivende background-position laat de
   browser elk frame opnieuw tekenen, en dit staat per definitie op tientallen
   elementen tegelijk. Zie punt 7 in CLAUDE.md: dit is precies het geval waar
   Lighthouse's "niet-samengestelde animatie" op aanslaat.

   De kleuren komen uit de tokens en niet uit een grijs uit een tutorial: de
   achtergrond hier is warm (#fbf5ef), en een koel #eee valt daar als een vlek in. */
.skeleton { position: relative; overflow: hidden; background: var(--bg-2); border-radius: 8px; }
.skeleton::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .72), transparent);
  transform: translateX(-100%);
  animation: skel-glans 1.5s infinite;
}
/* Op een donkere ondergrond (de zijbalk) moet de glans juist lichter zijn dan
   het vlak eronder, anders zie je niets bewegen. */
.skeleton.op-donker { background: rgba(255, 255, 255, .09); }
.skeleton.op-donker::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .16), transparent); }
/* Een tekstregel-skeleton: dezelfde hoogte als een regel tekst, met de laatste
   regel korter zodat het op een alinea lijkt in plaats van op een balk. */
.skel-regel { height: 13px; border-radius: 6px; margin-bottom: 9px; }
.skel-regel:last-child { margin-bottom: 0; width: 62%; }
@keyframes skel-glans { 100% { transform: translateX(100%); } }
/* Wie beweging heeft uitgezet krijgt een stilstaand vlak. Het skeleton blijft
   staan (de ruimte is het punt), alleen de glans verdwijnt. */
@media (prefers-reduced-motion: reduce) {
  .skeleton::after { animation: none; opacity: 0; }
}

/* --------------------------------- Toast ---------------------------------- */
#toast-wrap { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%); z-index: 10000; display: flex; flex-direction: column; gap: 10px; align-items: center; pointer-events: none; }
.toast { background: var(--ink); color: #fff; padding: 13px 20px; border-radius: var(--r-pill); box-shadow: var(--sh-lg); font-weight: 600; font-size: 14.5px; display: flex; align-items: center; gap: 10px; animation: pop-in .4s cubic-bezier(.34, 1.56, .64, 1) both; }
.toast .emo { font-size: 18px; }
.toast.success { background: linear-gradient(135deg, #16a34a, #0f8a3e); }

/* --------------------------- Modal / sheet -------------------------------- */
.backdrop { position: fixed; inset: 0; background: rgba(20, 14, 24, .5); backdrop-filter: blur(4px); z-index: 1000; opacity: 0; transition: opacity .25s; }
.backdrop.show { opacity: 1; }
.modal { position: fixed; z-index: 1001; background: var(--surface); border-radius: var(--r-xl); box-shadow: var(--sh-lg); }

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

/* ------------------------- Toegankelijkheid (WCAG) ------------------------ */
.skip-link { position: absolute; left: 12px; top: -60px; z-index: 10001; background: var(--ink); color: #fff; padding: 10px 16px; border-radius: var(--r-pill); font-weight: 700; transition: top .2s; }
.skip-link:focus { top: 12px; }
:where(a, button, [role="button"], [tabindex="0"], .kcard, .mitem):focus-visible {
  outline: 3px solid var(--brand-600);
  outline-offset: 2px;
  border-radius: 8px;
}

/* --------------------------- Rondleiding (driver.js) -----------------------
   De kaart van driver.js in de stijl van de site. De bibliotheek zelf blijft
   onaangeraakt (assets/vendor/driverjs/driver.css); dit hangt er alleen een
   laagje overheen via popoverClass: "smul-rondleiding". Zo is een nieuwe versie
   van driver.js gewoon te vervangen zonder dat er iets aan de opmaak sneuvelt.

   De pijl van driver.js is een border-truc in wit, dus de kaart moet wit blijven;
   dat sluit een gekleurde achtergrond uit. Vandaar dat het merk hier alleen in de
   knop en de kop zit. */
.driver-popover.smul-rondleiding {
  font-family: inherit;
  border-radius: var(--r-lg, 18px);
  padding: 20px 22px;
  max-width: 340px;
  box-shadow: 0 24px 60px rgba(28, 20, 32, .28);
}
.smul-rondleiding .driver-popover-title {
  font-family: var(--display, inherit);
  font-size: 18px;
  font-weight: 800;
  color: var(--ink, #1c1420);
  line-height: 1.25;
  padding-right: 26px;
}
.smul-rondleiding .driver-popover-description {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2, #4b4453);
  margin-top: 7px;
}
.smul-rondleiding .driver-popover-progress-text {
  font-size: 11.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3, #726c7b);
}
.smul-rondleiding .driver-popover-footer { margin-top: 18px; gap: 10px; }
.smul-rondleiding .driver-popover-footer-btn {
  font: inherit; font-size: 13.5px; font-weight: 700;
  border-radius: var(--r-pill, 999px);
  padding: 8px 16px;
  border: 1px solid var(--line-2, rgba(28, 20, 32, .14));
  background: var(--surface, #fff);
  color: var(--ink-2, #4b4453);
  transition: background .16s, color .16s;
}
.smul-rondleiding .driver-popover-footer-btn:hover { background: var(--bg-2, #f4ece3); color: var(--ink, #1c1420); }
/* De knop die verder gaat is de enige met merkkleur: bij twee even zware knoppen
   moet je lezen welke je wilt. */
.smul-rondleiding .driver-popover-next-btn {
  background: var(--brand-grad, #ea3b2c); border-color: transparent; color: #fff;
  box-shadow: var(--sh-brand, none);
}
.smul-rondleiding .driver-popover-next-btn:hover { background: var(--brand-grad, #ea3b2c); color: #fff; filter: brightness(1.06); }
.smul-rondleiding .driver-popover-close-btn { width: 34px; height: 30px; font-size: 20px; color: var(--ink-3, #726c7b); }
.smul-rondleiding .driver-popover-close-btn:hover { color: var(--ink, #1c1420); }
/* Het aangewezen element krijgt de merkkleur als rand in plaats van de standaard
   witte uitsparing; dat leest als "hier gaat het over" in plaats van als een gat. */
.driver-active .driver-active-element {
  outline: 3px solid var(--brand, #ea3b2c);
  outline-offset: 3px;
  border-radius: 12px;
}

/* ------------------------------ Code-invoer (OTP) --------------------------
   Zes vakjes voor de inlogcode. Het controleren van de code IS de animatie: er
   loopt een lading langs de rand van elk vakje, cijfer voor cijfer, en bij succes
   smelten de vakjes samen tot één zegel. Daarom staat er nergens een spinner -
   die zou hetzelfde wachten een tweede keer tonen.

   Violet naar aqua staat los van het merkrood, en dat is met opzet: dit is het
   enige moment op de site waar iets wordt GECONTROLEERD in plaats van besteld.
   Rood is hier bovendien de kleur van een foutmelding, en dat is precies wat de
   lading niet betekent. */
.otp { --otp-a: #7c5cff; --otp-b: #2ee6c5; display: flex; gap: 10px; justify-content: center; }
/* De omhulling draagt de lading langs de rand. Een <input> is een vervangen
   element en toont geen ::before, dus die animatie kan niet op het vakje zelf. */
.otp-cel { position: relative; display: block; border-radius: 14px; }
.otp-vak {
  width: 52px; height: 64px; padding: 0; text-align: center;
  font-family: var(--display); font-size: 28px; font-weight: 800; color: var(--ink);
  background: var(--surface); border: 2px solid var(--line-2); border-radius: 14px;
  outline: none; transition: border-color .18s, box-shadow .18s, transform .18s;
  caret-color: var(--otp-a);
}
.otp-vak:focus { border-color: var(--otp-a); box-shadow: 0 0 0 4px rgba(124, 92, 255, .16); transform: translateY(-2px); }
.otp-vak:disabled { color: var(--ink); opacity: 1; }   /* uitgeschakeld tijdens het controleren, maar wel leesbaar */

/* De lading langs de rand. Een draaiend conisch verloop achter het vakje, met het
   vakje zelf er als vlak overheen: dan zie je alleen de rand meedraaien. De
   vertraging per vakje wordt in JS gezet (--otp-vertraging), zodat de lading van
   links naar rechts loopt in plaats van overal tegelijk. */
.otp-bezig .otp-vak { border-color: transparent; background: var(--surface); }
.otp-bezig .otp-cel { overflow: hidden; }
.otp-bezig .otp-cel::before {
  content: ""; position: absolute; inset: -60%; z-index: 0;
  background: conic-gradient(from 0deg, transparent 0deg, var(--otp-a) 50deg, var(--otp-b) 110deg, transparent 170deg);
  animation: otp-lading 1s linear infinite;
  animation-delay: var(--otp-vertraging, 0ms);
}
/* Het vakje zelf ligt er als vlak overheen, met 2px lucht rondom: precies die
   2px zie je van de draaiende kegel, en dat is de lading langs de rand. */
.otp-bezig .otp-vak { position: relative; z-index: 1; margin: 2px; width: 48px; height: 60px; }
@keyframes otp-lading { to { rotate: 360deg; } }

/* Geslaagd: de vakjes schuiven tegen elkaar aan tot één doorlopend vlak met een
   verloop - het zegel. De randen tussen de vakjes verdwijnen, zodat het echt één
   ding wordt en niet zes dingen die dicht bij elkaar staan. */
.otp-goed { gap: 0; }
.otp-goed .otp-vak {
  border-color: transparent; border-radius: 0; color: #fff;
  background: linear-gradient(100deg, var(--otp-a), var(--otp-b));
  transition: gap .34s, border-radius .34s, background .34s, color .2s;
  animation: otp-zegel .34s cubic-bezier(.22, 1, .36, 1) both;
  animation-delay: var(--otp-vertraging, 0ms);
}
.otp-goed .otp-cel:first-child .otp-vak { border-radius: 14px 0 0 14px; }
.otp-goed .otp-cel:last-child .otp-vak { border-radius: 0 14px 14px 0; }
@keyframes otp-zegel { from { transform: scale(1); } 50% { transform: scale(1.06); } to { transform: scale(1); } }

/* Fout: één keer schudden. Kort, en op transform zodat het niets herschildert. */
.otp-fout .otp-vak { border-color: var(--danger); animation: otp-schud .34s; }
@keyframes otp-schud { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }

@media (max-width: 420px) {
  .otp { gap: 6px; }
  .otp-vak { width: 44px; height: 56px; font-size: 24px; }
}
/* Wie beweging heeft uitgezet krijgt de uitkomst zonder de show: het zegel en de
   foutkleur blijven, het draaien en schudden niet. */
@media (prefers-reduced-motion: reduce) {
  .otp-bezig .otp-vak::before { animation: none; background: var(--otp-a); }
  .otp-goed .otp-vak, .otp-fout .otp-vak { animation: none; }
}

/* ============================================================================
   "Powered by M&I Multi Media" - de balk onderaan elk scherm.

   Staat in base.css en niet per pagina, omdat alle zes de schermen (klantsite,
   inloggen, admin, keuken, balie, bezorger) dit bestand al laden. Een tweede
   kopie per pagina loopt bij de eerste wijziging uit elkaar.

   HET LOGO KRIJGT EEN WIT CHIPJE. Het bronbestand is zwart-op-wit ZONDER
   alfakanaal, dus rechtstreeks op een donkere ondergrond (inlogscherm, footer
   van de klantsite) zou het een wit blok geven. Een bewust wit rondje leest als
   ontwerp in plaats van als fout, en werkt op de lichte dashboards net zo goed.
   Komt er ooit een transparante versie, dan kan .mi-merk zijn achtergrond
   kwijt en verandert er verder niets.
   ========================================================================== */
.mi-balk {
  display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap;
  padding: 16px 18px; font-size: 13px; line-height: 1.45;
}
.mi-balk .mi-merk { display: flex; align-items: center; gap: 9px; color: inherit; text-decoration: none; }
/* Vaste maten op de afbeelding: zonder width/height reserveert de browser geen
   ruimte en springt de balk bij het laden (de CLS-afspraak in CLAUDE.md). */
.mi-balk img {
  width: 26px; height: 26px; border-radius: 7px; background: #fff;
  padding: 3px; box-sizing: border-box; display: block;
}
.mi-balk .mi-tekst { color: inherit; opacity: .75; }
.mi-balk .mi-tekst b { font-weight: 800; opacity: 1; }
.mi-balk .mi-knop {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px;
  border: 1.5px solid currentColor; border-radius: var(--r-pill); color: inherit;
  text-decoration: none; font-size: 12.5px; font-weight: 700; opacity: .8;
  transition: opacity .18s, background-color .18s;
}
.mi-balk .mi-knop:hover { opacity: 1; background: rgba(127, 127, 127, .14); }
/* Op de lichte dashboards een streepje erboven, zodat de balk niet tegen de
   inhoud aan plakt. De donkere varianten hebben hun eigen scheiding al. */
.mi-balk.mi-licht { border-top: 1px solid var(--line); color: var(--ink); margin-top: 8px; }

/* ---------------------------------------------------------------- oogje ----
   Het "toon mijn wachtwoord"-knopje. Stond eerst alleen als losse opmaak in
   portaal.html; hier zodat de klantsite en het beheer er niet elk een eigen
   kopie van krijgen die stil uit de pas gaat lopen.

   Het knopje staat IN het veld en niet ernaast: naast het veld ontstaat er op
   een smal scherm een tweede kolom en springt de rest van het formulier op.
   De padding-right hieronder houdt de tekst uit het knopje vandaan. */
.pw-veld { position: relative; }
.pw-veld .input { padding-right: 48px; }
.pw-toon {
  position: absolute; top: 0; right: 0; height: 100%; width: 46px;
  display: grid; place-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--muted); border-radius: 0 10px 10px 0;
}
.pw-toon:hover { color: var(--ink); }
.pw-toon:focus-visible { outline: 2px solid var(--brand-2); outline-offset: -3px; }
/* Twee iconen die elkaar afwisselen in plaats van er een omtekenen: geen
   herberekening van de opmaak bij het omschakelen. */
.pw-toon .ic-uit { display: none; }
.pw-toon.aan .ic-aan { display: none; }
.pw-toon.aan .ic-uit { display: block; }
