/* Slotenmaker Van Beek — animaties & visuele elementen (19-09-2026)
   Eigen werk, geen libraries. Kleuren volgen de huisstijl (BLAUW_CSS in bouw.py):
   navy #0f1f3a, knopblauw #1a5fc8, lichtblauw #7fb2ff. Alles uit bij prefers-reduced-motion.
   Geen layout-verschuiving: er wordt alleen met opacity / transform / translate / scale geanimeerd. */
:root{--vb-navy:var(--navy,#0f1f3a);--vb-blauw:#1a5fc8;--vb-blauw2:#1f6fe0;--vb-licht:#7fb2ff;--vb-aan:#22c55e;--vb-lijn:var(--lijn,#e3e7ec)}

/* ---------- 1. Belknop-puls: ring die 3x uitdijt en dan stopt ---------- */
.vb-puls{position:relative;isolation:isolate}
.vb-puls::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 0 rgba(26,95,200,.55);pointer-events:none;z-index:-1;
  animation:vb-ring 1.8s cubic-bezier(.2,.7,.3,1) 1.2s 3 both}
.vb-puls svg{animation:vb-tril 1.8s ease-in-out 1.2s 3 both;transform-origin:50% 50%}
.zweef .vb-puls::after,.zweef .vb-puls svg{animation-play-state:paused}
.zweef.aan .vb-puls::after,.zweef.aan .vb-puls svg{animation-play-state:running}
.vb-puls.vb-klaar::after,.vb-puls.vb-klaar svg{animation:none}
@keyframes vb-ring{0%{box-shadow:0 0 0 0 rgba(26,95,200,.55)}70%{box-shadow:0 0 0 16px rgba(26,95,200,0)}100%{box-shadow:0 0 0 16px rgba(26,95,200,0)}}
@keyframes vb-tril{0%,40%,100%{transform:none}8%{transform:rotate(-13deg)}16%{transform:rotate(11deg)}24%{transform:rotate(-8deg)}32%{transform:rotate(5deg)}}

/* ---------- 2. "Nu bereikbaar"-indicator (nacht 22-7 u: extra zichtbaar) ---------- */
.vb-bereik{display:inline-flex;align-items:center;gap:9px;font-size:.84rem;font-weight:700;line-height:1.2;border-radius:999px;padding:7px 14px 7px 11px;
  background:#e8f7ee;color:#14532d;border:1px solid #bfe8cf;transition:background .4s,border-color .4s,box-shadow .4s}
.vb-bereik.donker{background:rgba(255,255,255,.1);color:#fff;border-color:rgba(255,255,255,.22)}
.vb-stip{position:relative;flex:none;width:10px;height:10px;border-radius:50%;background:var(--vb-aan)}
.vb-stip::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:2px solid var(--vb-aan);opacity:0;animation:vb-adem 2.6s ease-out infinite}
@keyframes vb-adem{0%{transform:scale(.55);opacity:.8}80%,100%{transform:scale(1.5);opacity:0}}
/* beide teksten staan in dezelfde cel: de breedte is altijd die van de langste, dus niets verspringt */
.vb-bt{display:grid;align-items:center;justify-items:start;white-space:nowrap}.vb-bt>span{grid-area:1/1;transition:opacity .3s}
.vb-bereik{justify-self:start;max-width:100%}
.vb-bt .vb-nt{opacity:0;visibility:hidden}
.vb-bereik.vb-nacht .vb-bt .vb-nt{opacity:1;visibility:visible}.vb-bereik.vb-nacht .vb-bt .vb-dt{opacity:0;visibility:hidden}
.vb-bereik.vb-nacht{background:#0f1f3a;color:#fff;border-color:rgba(127,178,255,.55);box-shadow:0 0 0 4px rgba(127,178,255,.16),0 6px 22px rgba(15,31,58,.35)}
.vb-bereik.donker.vb-nacht{background:rgba(26,95,200,.35);border-color:var(--vb-licht);box-shadow:0 0 0 4px rgba(127,178,255,.18),0 0 28px rgba(127,178,255,.35)}
.vb-bereik.vb-nacht .vb-stip{width:12px;height:12px;background:#4ade80;box-shadow:0 0 10px #4ade80}
.vb-bereik.vb-nacht .vb-stip::after{border-color:#4ade80;animation-duration:1.9s}
.vb-maan{display:none;width:15px;height:15px;color:var(--vb-licht);flex:none}.vb-bereik.vb-nacht .vb-maan{display:block}

/* ---------- 3 & 6. Inschuiven bij scrollen (stappen, dienstkaarten, tellers) ---------- */
/* Alleen elementen die bij het laden ONDER de vouw staan krijgen vb-wacht (door animaties.js):
   wat al in beeld is, knippert dus nooit. `translate` i.p.v. `transform` botst niet met :hover-transforms. */
.vb-wacht{opacity:0;translate:0 26px}
.vb-zien{animation:vb-op .7s cubic-bezier(.2,.7,.2,1) calc(var(--vb-i,0) * 110ms) both}
@keyframes vb-op{from{opacity:0;translate:0 26px}to{opacity:1;translate:0 0}}
.vb-zien .dic{animation:vb-pop .55s cubic-bezier(.3,1.6,.5,1) calc(var(--vb-i,0) * 110ms + .3s) both}
@keyframes vb-pop{from{scale:.3;opacity:0}to{scale:1;opacity:1}}

/* ---------- 3. Stappenplan "Buitengesloten, wat nu?" ---------- */
.vb-plan{list-style:none;margin:0;padding:0;display:grid;gap:0;max-width:760px;counter-reset:vb}
.vb-plan>li{position:relative;display:grid;grid-template-columns:52px 1fr;gap:0 18px;padding-bottom:26px}
.vb-plan>li:last-child{padding-bottom:0}
.vb-plan>li::before{content:"";position:absolute;left:25px;top:52px;bottom:4px;width:2px;background:var(--vb-lijn);border-radius:2px}
.vb-plan>li::after{content:"";position:absolute;left:25px;top:52px;bottom:4px;width:2px;background:var(--vb-blauw);border-radius:2px;transform-origin:top;transform:scaleY(0)}
.vb-plan>li:last-child::before,.vb-plan>li:last-child::after{display:none}
.vb-plan>li.vb-zien::after{transition:transform .9s ease .45s;transform:scaleY(1)}
html:not(.vb-anim) .vb-plan>li::after{transform:scaleY(1)}
.vb-pnr{grid-row:span 2;display:grid;place-items:center;width:52px;height:52px;border-radius:50%;background:var(--vb-navy);color:var(--vb-licht);font-weight:800;font-size:1.1rem;box-shadow:0 0 0 6px #fff}
.sectie.grijs .vb-pnr{box-shadow:0 0 0 6px var(--grijs,#f3f5f8)}
.vb-plan h3{margin:12px 0 4px;font-size:1.08rem}.vb-plan p{margin:0;color:var(--muted,#5b6674);font-size:.96rem}
.vb-plan .vb-tip{display:inline-block;margin-top:8px;font-size:.86rem;font-weight:700;color:var(--vb-blauw)}
.vb-zien .vb-pnr{animation:vb-pop .5s cubic-bezier(.3,1.6,.5,1) .15s both}
@media (min-width:900px){.vb-plan-wrap{display:grid;grid-template-columns:1fr 300px;gap:56px;align-items:start}}
.vb-plan-zij{background:var(--vb-navy);color:rgba(255,255,255,.86);border-radius:18px;padding:26px;display:grid;gap:14px;justify-items:start;margin-top:32px}
.vb-plan-zij b{color:#fff;font-size:1.1rem}
@media (min-width:900px){.vb-plan-zij{margin-top:0;position:sticky;top:100px}}

/* ---------- 4. Sleutel die draait (inline SVG, geen library) ---------- */
.vb-sleutel{display:block;width:100%;max-width:220px;height:auto;aspect-ratio:1;margin-inline:auto}
.vb-sleutel .vb-draai{transform-box:view-box;transform-origin:100px 124px}
.vb-sleutel .vb-schoot{transform-box:view-box}
.vb-sleutel .vb-pijl,.vb-sleutel .vb-vink{opacity:0}
.vb-sleutel.vb-speel .vb-draai{animation:vb-draai 3.6s cubic-bezier(.55,0,.25,1) 3 both}
.vb-sleutel.vb-speel .vb-schoot{animation:vb-schoot 3.6s cubic-bezier(.55,0,.25,1) 3 both}
.vb-sleutel.vb-speel .vb-pijl{animation:vb-pijl 3.6s ease 3 both}
.vb-sleutel.vb-speel .vb-vink{animation:vb-vink 3.6s ease 3 both}
@keyframes vb-draai{0%,12%{transform:rotate(0)}38%,72%{transform:rotate(90deg)}94%,100%{transform:rotate(0)}}
@keyframes vb-schoot{0%,14%{transform:translateX(0)}38%,72%{transform:translateX(-30px)}94%,100%{transform:translateX(0)}}
@keyframes vb-pijl{0%,10%{opacity:0}18%,34%{opacity:1}42%,100%{opacity:0}}
@keyframes vb-vink{0%,38%{opacity:0;scale:.6}46%,70%{opacity:1;scale:1}78%,100%{opacity:0;scale:1}}
.vb-sleutel .vb-vink{transform-box:fill-box;transform-origin:center}
/* in de hero (donker vlak): lichte variant */
.vb-sleutel-hero{display:flex;align-items:center;gap:14px;margin:0 0 22px;color:rgba(255,255,255,.86);font-size:.95rem}
.vb-sleutel-hero .vb-sleutel{width:84px;margin:0;flex:none}

/* ---------- 5. Regiokaart Nederland ---------- */
.vb-kaart{position:relative;max-width:460px;margin-inline:auto}
.vb-kaart svg{display:block;width:100%;height:auto;aspect-ratio:400/473}
.vb-land{fill:#e8eef8;stroke:#c5d4ec;stroke-width:1.2;stroke-linejoin:round}
.donker .vb-land,.vb-kaart.donker .vb-land{fill:#1b3155;stroke:#2c4a7a}
.vb-glow{fill:url(#vb-gloed);opacity:0;transition:opacity 1.2s ease .3s}
.vb-kaart.vb-aan .vb-glow,html:not(.vb-anim) .vb-glow{opacity:1}
.vb-stad circle.vb-dot{fill:var(--vb-blauw);stroke:#fff;stroke-width:1.6}
.vb-stad circle.vb-halo{fill:var(--vb-blauw);opacity:0}
.vb-stad text{font:700 12.5px/1 Jakarta,system-ui,sans-serif;fill:var(--vb-navy);paint-order:stroke;stroke:#fff;stroke-width:3.2px;stroke-linejoin:round}
.donker .vb-stad text,.vb-kaart.donker .vb-stad text{fill:#fff;stroke:#0f1f3a}
.vb-stad a:hover circle.vb-dot,.vb-stad a:focus-visible circle.vb-dot{fill:#0f1f3a;r:6}
.vb-stad.vb-hier circle.vb-dot{fill:#f5b400;stroke:#0f1f3a;stroke-width:2}
.vb-stad.vb-hier text{font-size:13px}
/* animatie: stippen gaan één voor één aan, met één lichtflits */
.vb-anim .vb-kaart .vb-stad{opacity:0;transform-box:fill-box;transform-origin:center}
.vb-anim .vb-kaart.vb-aan .vb-stad{animation:vb-stad .55s cubic-bezier(.3,1.5,.5,1) calc(var(--vb-i,0) * 90ms + .2s) both}
.vb-anim .vb-kaart.vb-aan .vb-stad circle.vb-halo{transform-box:fill-box;transform-origin:center;animation:vb-halo 1.4s ease-out calc(var(--vb-i,0) * 90ms + .35s) both}
.vb-anim .vb-kaart.vb-aan .vb-stad.vb-hier circle.vb-halo{animation:vb-halo 2.4s ease-out 2s 4 both}
@keyframes vb-stad{from{opacity:0;scale:.2}to{opacity:1;scale:1}}
@keyframes vb-halo{0%{opacity:.5;scale:.4}100%{opacity:0;scale:3.4}}
.vb-kaart-bron{margin:8px 0 0;font-size:.72rem;color:var(--muted,#5b6674);text-align:center}.donker .vb-kaart-bron{color:rgba(255,255,255,.6)}

/* ---------- 6. Tellers ---------- */
.vb-tellers{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.vb-tellers li{background:#fff;border:1px solid var(--vb-lijn);border-radius:var(--r,14px);padding:22px 20px;display:grid;gap:4px;align-content:start}
.vb-tellers .vb-ti{width:46px;height:46px;border-radius:12px;background:#e6effc;color:var(--vb-blauw);display:grid;place-items:center;margin-bottom:10px}
.vb-tellers b{font-size:clamp(1.7rem,4vw,2.3rem);font-weight:800;color:var(--vb-navy);line-height:1.05;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.vb-tellers small{color:var(--muted,#5b6674);font-size:.92rem;line-height:1.4}
.vb-tel{display:inline-block;text-align:right;min-width:var(--vb-w,2ch)}
.donker .vb-tellers li{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.14)}.donker .vb-tellers b{color:#fff}.donker .vb-tellers small{color:rgba(255,255,255,.72)}
.donker .vb-tellers .vb-ti{background:rgba(127,178,255,.16);color:var(--vb-licht)}
@media (max-width:900px){.vb-tellers{grid-template-columns:1fr 1fr}}
@media (max-width:380px){.vb-tellers{gap:12px}.vb-tellers li{padding:18px 14px}}

/* ---------- Toegankelijkheid: minder beweging = geen beweging ---------- */
@media (prefers-reduced-motion:reduce){
  .vb-puls::after,.vb-puls svg,.vb-stip::after,.vb-zien,.vb-zien .dic,.vb-zien .vb-pnr,
  .vb-sleutel *,.vb-kaart *{animation:none!important;transition:none!important}
  .vb-wacht{opacity:1;translate:none}
  .vb-plan>li::after{transform:scaleY(1)}
  .vb-kaart .vb-stad{opacity:1!important}.vb-glow{opacity:1}
}
/* wat bij het laden al in beeld stond: meteen tonen, zonder inschuiven (geen knipper) */
.vb-direct,.vb-direct .dic,.vb-direct .vb-pnr{animation:none!important}

/* KAART-KNOPPEN-BINNEN-20260920 — de knoppen in de spoedkaart kregen hun eigen (max-content) breedte
   door justify-items:start op de grid, en staken daardoor rechts BUITEN de donkere kaart (gemeten op
   1280 px, stadspagina Zeist). Nu vullen ze de kaart en breekt lange tekst netjes af. */
.vb-plan-zij > *{max-width:100%}
.vb-plan-zij .knop{width:100%;justify-self:stretch;white-space:normal;text-align:center;line-height:1.25}
