/* ============================================================
   HALLOWEEN IN DE WIJK, de stijl van de voorpagina
   ============================================================

   Dit stond eerst als één blok in index.php, maar dat bestand
   werd onleesbaar groot. Alles wat statisch is staat nu hier en
   wordt door de browser gecachet; wat per instelling verschilt
   (het kaartschema en de toegankelijkheidsregels) zet index.php
   nog altijd zelf in een klein <style>-blok.

   Het versienummer achter de link in index.php komt uit
   filemtime(), dus dit bestand opslaan is genoeg om elke cache
   te verversen.
   ============================================================ */

/* ============================================================
   DESIGN TOKENS: afgeleid van de flyer
   ============================================================ */
:root{
  --night-900:#140d1c;
  --night-800:#1a1024;
  --night-700:#241631;
  --night-600:#33203f;
  --plum-500:#4a3358;
  --plum-400:#6b4a7d;
  --ribbon:#a98cbf;
  --orange-600:#d9741f;
  --orange-500:#e8842a;
  --orange-400:#f5993c;
  --orange-300:#ffb347;
  --cream:#f5e7c8;
  --cream-dim:#d9c9a6;
  --moon:#f4e4b6;
  --ghost:#f7f3ea;
  --ok:#7bc96f;

  --font-display:'Bungee', 'Impact', sans-serif;
  --font-slab:'Rye', 'Georgia', serif;
  --font-body:'Nunito', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Hoogte van de vaste balk bovenaan. Ankers houden die vrij; zie SECTIES. */
  --balk:62px;

  --radius:18px;
  --radius-sm:12px;
  --shadow-glow:0 0 40px rgba(245,153,60,.35);
  --maxw:1180px;
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;overflow-x:hidden;overflow-x:clip}
body{
  margin:0;
  font-family:var(--font-body);
  color:var(--cream);
  background:var(--night-800);
  /* clip schuift niets opzij en maakt geen scrollcontainer, hidden is de
     terugval voor oudere Safari. Vangnet: verticaal scrollen blijft, zijwaarts niet. */
  overflow-x:hidden;
  overflow-x:clip;
  -webkit-font-smoothing:antialiased;
}
img,svg{max-width:100%;display:block}
a{color:var(--orange-300)}
h1,h2,h3{margin:0;line-height:1.05}
p{margin:0 0 1em}
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:clamp(16px,4vw,32px)}

/* filmische korrel/textuur over de hele pagina */
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:9999;
  opacity:.055;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
}

/* ============================================================
   SKIP LINK + NAV
   ============================================================ */
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;z-index:10000;background:var(--orange-500);color:#1a1024;padding:10px 16px;border-radius:8px}

.nav{
  position:fixed;inset-inline:0;top:0;z-index:900;
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:12px clamp(16px,4vw,32px);
  background:linear-gradient(180deg,rgba(20,13,28,.92),rgba(20,13,28,0));
  backdrop-filter:blur(6px);
  transition:background .3s ease, box-shadow .3s ease;
}
.nav.solid{background:rgba(20,13,28,.96);box-shadow:0 6px 24px rgba(0,0,0,.5)}
.nav__brand{display:flex;align-items:center;gap:10px;font-family:var(--font-display);font-size:clamp(.8125rem,2.6vw,1rem);letter-spacing:.04em;color:var(--orange-300);text-decoration:none}
.nav__brand svg{width:30px;height:30px;flex:none}
.nav__links{display:flex;align-items:center;gap:6px}
.nav__links a{
  font-weight:700;font-size:.875rem;color:var(--cream);text-decoration:none;
  padding:8px 12px;border-radius:999px;transition:background .2s,color .2s;
}
.nav__links a:hover{background:rgba(169,140,191,.22)}
.nav__links .btn{margin-left:6px}

/* De kaartknop naast de aanmeldknop: zelfde vorm, andere kleur. Paars uit het
   eigen palet, met dezelfde 3D-rand als de oranje knop maar een slag zachter,
   zodat meteen leesbaar is welke van de twee de hoofdknop is. */
.nav__links .nav__kaart{
  font-family:var(--font-display);font-size:.8125rem;letter-spacing:.03em;
  color:#fff2d8;background:linear-gradient(180deg,var(--plum-400),var(--plum-500));
  padding:10px 18px;margin-left:6px;
  border:1px solid rgba(169,140,191,.55);
  box-shadow:0 4px 0 #33203f, 0 8px 18px rgba(0,0,0,.35);
  transition:transform .12s ease, box-shadow .12s ease, filter .2s;
}
.nav__links .nav__kaart:hover{background:linear-gradient(180deg,var(--plum-400),var(--plum-500));
  transform:translateY(-1px);filter:brightness(1.12)}
.nav__links .nav__kaart:active{transform:translateY(2px);box-shadow:0 1px 0 #33203f}

/* Alleen zichtbaar voor beheerders. Groen, zodat je in één oogopslag ziet dat
   dit geen gewone menu-ingang is maar iets wat de rest van de buurt niet ziet. */
.nav__beheer{color:#7bc96f !important;border:1px solid rgba(123,201,111,.45)}
/* De teller naast de beheerknop: zelfde groen, maar geen link. Het getal loopt
   live mee met het klopje van de kaart; zie site.js. */
.nav__kijkers{display:inline-flex;align-items:center;gap:6px;
  padding:7px 12px;border-radius:999px;font-weight:800;font-size:.875rem;
  color:#7bc96f;border:1px solid rgba(123,201,111,.45);background:rgba(123,201,111,.1)}
.nav__kijkers svg{width:15px;height:15px;fill:currentColor;flex:none}
.nav__kijkers{text-decoration:none}
.nav__kijkers:hover{background:rgba(123,201,111,.2);border-color:rgba(123,201,111,.75)}
/* Alleen voor schermlezers: het getal alleen zegt niets zonder dit woordje. */
.vpb{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.nav__beheer:hover{background:rgba(123,201,111,.18) !important}
/* Er ligt werk: dan geen omlijning maar een gevulde knop, zodat hij opvalt
   tussen de andere links. */
.nav__beheer--werk{background:#7bc96f !important;border-color:#7bc96f !important;
  color:#12300c !important;font-weight:800}
.nav__beheer--werk:hover{background:#96d98c !important}
/* Het tandwiel is alleen voor admins: instellingen wijzigen, niet modereren. */
.nav__gear{display:inline-flex;align-items:center;padding:8px 10px}
.nav__gear svg{width:17px;height:17px;fill:currentColor;display:block}

/* Snelkoppeling naar je eigen aanmelding, een uur na het klikken op de link uit
   je mail. Omlijnd en niet gevuld: de oranje knop ernaast is voor wie nog moet
   beginnen, en die moet de aandacht houden. */
.nav__mijn{border:1px solid rgba(245,153,60,.55);color:var(--orange-300) !important}
.nav__mijn:hover{background:rgba(245,153,60,.16) !important}

/* Op smalle schermen valt het menu weg, maar de beheerlink blijft: die is er
   juist om snel bij de wachtrij te kunnen, ook vanaf een telefoon. Hetzelfde
   geldt voor de snelkoppeling naar je eigen aanmelding: die is er juist om je
   het opzoeken van de mail te besparen. */
@media(max-width:760px){
  .nav__links a:not(.btn):not(.nav__beheer):not(.nav__gear):not(.nav__mijn){display:none}
}

/* Over ons staat achteraan en is wat gedempt: het is de enige ingang die de
   pagina verlaat, en je leest hem één keer. Bij krapte gaat hij dan ook als
   eerste weg; de drie andere brengen je naar iets waar je nú iets mee doet. */
.nav__links .nav__over{color:#a3947a}
.nav__links .nav__over:hover{color:var(--cream)}
@media(max-width:900px){ .nav__over{display:none} }

/* De knop in de balk moet één pil blijven. Naast de merknaam, en voor beheerders
   ook nog naast Beheer en het tandwiel, past de volle tekst niet meer op een
   telefoon: dan brak hij in vier regels. Daarom hier een kortere variant. */
.btn__kort{display:none}
@media(max-width:600px){
  .nav__links .btn{padding:11px 16px;font-size:.75rem;white-space:nowrap}
  .nav__links .btn .btn__lang{display:none}
  .nav__links .btn .btn__kort{display:inline}
  /* Het tandwiel valt weg: te druk naast Beheer, en de instellingen zijn vanaf
     het beheerscherm gewoon te bereiken. */
  .nav__gear{display:none}
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn{
  --bg:linear-gradient(180deg,var(--orange-400),var(--orange-600));
  display:inline-flex;align-items:center;justify-content:center;gap:10px;text-align:center;
  font-family:var(--font-display);font-size:clamp(.8125rem,1.4vw,.9375rem);letter-spacing:.03em;
  color:#221226;text-decoration:none;background:var(--bg);
  padding:13px 22px;border:0;border-radius:999px;cursor:pointer;
  box-shadow:0 6px 0 #a4551a, 0 12px 26px rgba(0,0,0,.45);
  transition:transform .12s ease, box-shadow .12s ease, filter .2s;
}
.btn:hover{transform:translateY(-2px);filter:brightness(1.06)}
.btn:active{transform:translateY(3px);box-shadow:0 2px 0 #a4551a, 0 6px 14px rgba(0,0,0,.4)}
.btn--ghost{
  --bg:transparent;color:var(--cream);
  border:2px solid rgba(245,231,200,.45);box-shadow:none;
}
.btn--ghost:hover{background:rgba(245,231,200,.1);box-shadow:none}

/* ============================================================
   HERO
   ============================================================ */
.hero{
  /* start center in plaats van place-items:center: de inhoud hangt nu aan de
     bovenkant. Bij centreren schuift het midden mee zodra je padding weghaalt,
     waardoor de inhoud maar de helft omhoog komt van wat je instelt. */
  position:relative;min-height:100svh;display:grid;place-items:start center;
  padding:64px 0 clamp(150px,21vh,250px);overflow:hidden;isolation:isolate;
  background:
    radial-gradient(120% 80% at 50% 8%, #4a3358 0%, #2b1a38 42%, #1a1024 76%, #140d1c 100%);
}
/* sterren */
.stars{position:absolute;inset:0;z-index:0}
.star{position:absolute;width:2px;height:2px;border-radius:50%;background:var(--cream);opacity:.7;
  animation:twinkle var(--dur,3s) ease-in-out infinite var(--delay,0s)}
@keyframes twinkle{0%,100%{opacity:.15;transform:scale(.7)}50%{opacity:.95;transform:scale(1.25)}}

/* maan */
.moon{
  /* Negatieve top: de maan loopt bewust boven de rand uit en wordt door de
     overflow:hidden van .hero afgesneden. */
  position:absolute;z-index:1;top:clamp(-80px,-5vw,-26px);left:50%;transform:translateX(-50%);
  width:clamp(150px,22vw,265px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 38% 34%, #fdf6dc 0%, var(--moon) 55%, #d9c48c 100%);
  box-shadow:0 0 70px 24px rgba(244,228,182,.28), 0 0 160px 60px rgba(244,228,182,.14);
  animation:moonPulse 7s ease-in-out infinite;
}
.moon::before,.moon::after{content:"";position:absolute;border-radius:50%;background:rgba(197,175,124,.35)}
.moon::before{width:22%;height:22%;top:26%;left:22%}
.moon::after{width:14%;height:14%;top:58%;left:58%;background:rgba(197,175,124,.28)}
@keyframes moonPulse{0%,100%{filter:brightness(1)}50%{filter:brightness(1.09)}}

/* wolken */
.cloud{position:absolute;z-index:2;height:auto;opacity:.5;filter:blur(1px);
  animation:drift linear infinite}
@keyframes drift{from{transform:translateX(-30vw)}to{transform:translateX(130vw)}}

/* boom + huizen silhouet */
.skyline{position:absolute;z-index:3;inset-inline:-1px;bottom:-2px;width:calc(100% + 2px);
  height:clamp(200px,30vh,360px);pointer-events:none;
  filter:drop-shadow(0 -2px 0 rgba(169,140,191,.35))}
/* zachte gloed achter de daken zodat de silhouetten uitkomen */
.skyline-glow{position:absolute;z-index:2;inset-inline:0;bottom:0;height:clamp(240px,36vh,420px);
  pointer-events:none;background:linear-gradient(180deg,transparent,rgba(107,74,125,.55) 45%,rgba(20,13,28,.9) 100%)}

/* ---- Leven achter de ramen ------------------------------------------------
   Twee lagen. De onderlaag draait op CSS en loopt altijd, ook zonder
   JavaScript: het tv-raampje flakkert en in één huis gaat het licht af en toe
   uit. Daarboven staat een repertoire aan eenmalige acts (iemand loopt langs
   het grote raam, een figuurtje komt voor een raampje staan, een spinnetje
   zakt af, een pompoen valt op de vensterbank, een spookje, de kat op het hek,
   een extra raam dat meeflakkert) die een regisseur in JavaScript op
   willekeurige momenten start. Elke act eindigt exact in de begintoestand,
   dus met animaties uit is de gevel gewoon stil. */
.raam-tv{animation:raamTv 13s linear infinite}
@keyframes raamTv{
  0%,52%,63%,100%{opacity:.85}
  54%{opacity:.4} 56%{opacity:.74} 58%{opacity:.32} 61%{opacity:.68}
}
.raam-uit{animation:raamUit 29s linear infinite}
@keyframes raamUit{
  0%,56%{opacity:.8}
  58.5%,84%{opacity:.05}
  86%,100%{opacity:.8}
}

/* De voorbijloper in het grote raam: gewoon doorlopen, of even blijven
   staan. De regisseur kiest, en meestal wordt het de korte. */
.wandelaar.loopt{animation:wandelEens 7s linear}
@keyframes wandelEens{
  0%{transform:translateX(0)}
  30%{transform:translateX(52px)}
  40%{transform:translateX(56px)}
  75%,100%{transform:translateX(110px)}
}
.wandelaar.looptLang{animation:wandelLang 14s linear}
@keyframes wandelLang{
  0%{transform:translateX(0)}
  16%{transform:translateX(50px)}
  20%,78%{transform:translateX(54px)}   /* lang voor het raam blijven staan */
  92%,100%{transform:translateX(110px)}
}

/* Figuurtjes die voor een klein raampje komen staan. Het schuiven doet een
   transition; wanneer en hoe lang bepaalt de regisseur met willekeur. */
.figuur{transform:translateX(-36px);transition:transform 1.6s ease}
.figuur.binnen{transform:translateX(0)}

/* Spinnetje aan een draadje, in het grote raam. De draad loopt tot ver boven
   het raam door, dus onderweg naar beneden zie je nooit een los uiteinde. */
.spin{transform:translateY(-135px)}
.spin.act{animation:spinZakt 14s ease-in-out}
@keyframes spinZakt{
  0%{transform:translateY(-135px)}
  14%{transform:translateY(0)}
  20%{transform:translateY(-5px)}       /* even naveren aan de draad */
  25%,78%{transform:translateY(0)}
  100%{transform:translateY(-135px)}
}

/* De pompoen valt bínnen in huis: als silhouet langs het verlichte raam,
   stuitert op de vensterbank, ligt daar ruim twintig tellen en zakt dan
   langzaam onder de rand. De raamknip doet de rest: boven en onder het glas
   bestaat hij niet. */
.pompoen{opacity:0}
.pompoen.act{animation:pompoenValt 27s linear}
@keyframes pompoenValt{
  0%{opacity:1;transform:translateY(-50px)}
  2.5%{opacity:1;transform:translateY(0)}
  3.5%{transform:translateY(-6px)}      /* stuitert heel even */
  4.5%,82%{opacity:1;transform:translateY(0)}
  99%{opacity:1;transform:translateY(26px)}
  100%{opacity:0;transform:translateY(26px)}
}

/* Het spookje komt achter de dakrand van het grote huis omhoog, hangt daar
   even te deinen en zakt weer weg. */
.spookje{opacity:0}
.spookje.act{animation:spookOp 10s ease-in-out}
@keyframes spookOp{
  0%{opacity:0;transform:translateY(0)}
  18%{opacity:.5;transform:translateY(-44px)}
  38%{transform:translateY(-37px)}
  58%{opacity:.5;transform:translateY(-45px)}
  78%{transform:translateY(-38px)}
  100%{opacity:0;transform:translateY(0)}
}

/* De kat trippelt over de rechterdakrand van het grote huis, hoog en vrij
   tegen de lucht, zodat hij ook echt te zien is. */
.kat{opacity:0}
.kat.act{animation:katLoopt 11s linear}
@keyframes katLoopt{
  0%{opacity:0;transform:translate(700px,118px)}
  8%{opacity:1}
  45%{transform:translate(736px,118px)}
  53%{transform:translate(738px,118px)}   /* even blijven zitten kijken */
  92%{opacity:1}
  100%{opacity:0;transform:translate(772px,118px)}
}

/* Elk verlicht raampje kan één keer meeflakkeren als de regisseur het aanwijst. */
.flakkert{animation:flakkerEens 1.7s linear}
@keyframes flakkerEens{
  0%,100%{opacity:.8}
  18%{opacity:.35} 34%{opacity:.7} 52%{opacity:.3} 70%{opacity:.65}
}

/* De bliksem die heel af en toe in de boom slaat. De flits ligt achter de
   huizen (z-index 1, boven de sterren): de hele lucht licht op terwijl de
   silhouetten zwart blijven, precies zoals echt onweer eruitziet. De schicht
   staat op dezelfde laag als de boom maar eerder in de tekenvolgorde, dus de
   punt verdwijnt ín de kruin. */
.flits{position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  background:radial-gradient(55% 65% at 13% 28%, rgba(240,230,255,.55), rgba(178,148,228,.2) 55%, transparent 78%)}
.flits.act{animation:flitsLicht 1.5s linear}
@keyframes flitsLicht{
  0%,100%{opacity:0}
  4%{opacity:1} 9%{opacity:.15} 14%{opacity:.85} 30%{opacity:.25} 60%{opacity:0}
}
.bliksem{position:absolute;z-index:4;pointer-events:none;opacity:0;width:30px;
  left:calc(-2vw + clamp(180px,30vw,420px)*.5 - 15px);
  top:-30px;
  /* Een svg met height:auto rekt niet mee tussen top en bottom maar houdt zijn
     eigen verhouding, dus de hoogte moet uitgerekend: van boven het beeld tot
     in de kruin van de boom. */
  height:calc(100% + 30px - clamp(180px,30vw,420px)*1.02);
  filter:drop-shadow(0 0 9px rgba(205,175,255,.95)) drop-shadow(0 0 26px rgba(160,120,255,.6))}
.bliksem path{fill:#f1eaff}
.bliksem.act{animation:bliksemFlits 1.5s linear}
@keyframes bliksemFlits{
  0%,100%{opacity:0}
  3%{opacity:1} 8%{opacity:.1} 12%{opacity:1} 26%{opacity:.65} 42%{opacity:0}
}
/* De boom schrikt: één korte siddering, daarna wiegt hij gewoon weer verder. */
.tree.schrik{animation:boomSchrik .9s ease-out}
@keyframes boomSchrik{
  0%{transform:rotate(0)} 16%{transform:rotate(2.6deg)}
  45%{transform:rotate(-1.8deg)} 74%{transform:rotate(.9deg)} 100%{transform:rotate(0)}
}

/* Animaties uit betekent: de hele gevel meteen stil, ook een act die net
   bezig was, en de figuurtjes schuiven zonder overgang. */
.motion-off .skyline *{animation:none !important;transition:none !important}
.motion-off .bliksem,.motion-off .flits{animation:none !important;opacity:0 !important}
.motion-off .tree{animation:none}
.tree{position:absolute;z-index:4;bottom:0;left:-2vw;width:clamp(180px,30vw,420px);pointer-events:none;
  transform-origin:bottom center;animation:sway 9s ease-in-out infinite}
@keyframes sway{0%,100%{transform:rotate(-.7deg)}50%{transform:rotate(.7deg)}}

/* lantaarn */
.lamp{position:absolute;z-index:5;bottom:0;right:2vw;width:clamp(90px,15vw,190px);pointer-events:none}
.lamp .flame{animation:flicker 2.6s infinite steps(1)}
.lamp .halo{transform-origin:center;animation:halo 2.6s infinite ease-in-out}
@keyframes flicker{
  0%,100%{opacity:1}8%{opacity:.55}12%{opacity:.95}30%{opacity:.7}
  34%{opacity:1}58%{opacity:.5}62%{opacity:.9}80%{opacity:1}86%{opacity:.65}
}
@keyframes halo{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:.85;transform:scale(1.12)}}

/* mist */
.fog{position:absolute;z-index:6;inset-inline:-10%;bottom:-4%;height:44%;pointer-events:none;opacity:.5;
  background:radial-gradient(60% 100% at 20% 100%, rgba(169,140,191,.55), transparent 70%),
             radial-gradient(50% 100% at 65% 100%, rgba(245,231,200,.28), transparent 70%);
  filter:blur(18px);animation:fogMove 16s ease-in-out infinite alternate}
@keyframes fogMove{from{transform:translateX(-6%) scaleY(1)}to{transform:translateX(6%) scaleY(1.15)}}

/* spinnenwebben in de hoeken */
.web{position:absolute;z-index:7;width:clamp(90px,16vw,190px);opacity:.5;pointer-events:none}
.web--tl{top:52px;left:0}
.web--tr{top:52px;right:0;transform:scaleX(-1)}
.spider{position:absolute;z-index:8;top:52px;left:clamp(60px,13vw,150px);width:26px;
  transform-origin:top center;animation:dangle 5s ease-in-out infinite}
@keyframes dangle{0%,100%{transform:translateY(0) rotate(-6deg)}50%{transform:translateY(26px) rotate(6deg)}}

/* vliegende dieren-laag */
.flyers{position:fixed;inset:0;z-index:850;pointer-events:none;overflow:hidden}
.flyer{position:absolute;will-change:transform}
.flyer .wingL,.flyer .wingR{transform-origin:right center;animation:flap .34s ease-in-out infinite alternate}
.flyer .wingR{transform-origin:left center;animation-delay:.02s}
@keyframes flap{from{transform:rotate(-16deg) scaleY(1)}to{transform:rotate(22deg) scaleY(.82)}}
/* De laag zelf vangt geen klikken (pointer-events:none), maar de spookjes wel:
   erop klikken laat ze schrikken en zet daarna de animaties uit. */
.flyer--ghost{animation:bobGhost 2.6s ease-in-out infinite;pointer-events:auto;cursor:pointer}
@keyframes bobGhost{0%,100%{transform:translateY(-7px) rotate(-3deg)}50%{transform:translateY(8px) rotate(3deg)}}

/* hero-inhoud */
.hero__inner{position:relative;z-index:20;text-align:center;padding-top:clamp(14px,3vw,30px)}
/* scrim zodat de letters altijd leesbaar blijven boven maan en huizen */
.hero__inner::before{
  content:"";position:absolute;z-index:-1;left:50%;top:6%;transform:translateX(-50%);
  width:min(1000px,124%);height:96%;pointer-events:none;
  background:radial-gradient(60% 52% at 50% 44%, rgba(16,10,22,.86) 0%, rgba(16,10,22,.62) 46%, rgba(16,10,22,0) 78%);
}
.hero__kicker{
  display:inline-block;font-family:var(--font-body);font-weight:800;letter-spacing:.34em;
  text-transform:uppercase;font-size:clamp(.625rem,2.2vw,.8125rem);color:var(--ribbon);
  margin-bottom:14px;
}
.title{position:relative;display:block;margin:0}
.title__img{
  display:block;margin:0 auto;
  width:min(760px,88vw);height:auto;
  /* zachte slagschaduw: een harde offset zou de gerafelde uitsnede uitvergroten */
  filter:drop-shadow(0 3px 7px rgba(0,0,0,.55)) drop-shadow(0 0 44px rgba(232,132,42,.35));
  animation:titleIn 1s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes titleIn{from{opacity:0;transform:translateY(26px) scale(.94)}to{opacity:1;transform:none}}

.ribbon{
  display:inline-block;margin-top:14px;padding:8px 30px;
  background:var(--ribbon);color:#2a1b33;
  font-family:var(--font-body);font-weight:800;letter-spacing:.18em;text-transform:uppercase;
  font-size:clamp(.75rem,2.7vw,1.15rem);
  clip-path:polygon(3% 0,97% 0,100% 50%,97% 100%,3% 100%,0 50%);
  animation:titleIn .9s .28s cubic-bezier(.2,.8,.2,1) both;
}
.meta{display:flex;flex-wrap:wrap;justify-content:center;gap:10px 26px;margin:26px 0 8px;
  animation:titleIn .9s .36s cubic-bezier(.2,.8,.2,1) both}
.meta__item{display:flex;align-items:center;gap:10px;font-family:var(--font-display);
  font-size:clamp(.95rem,3.4vw,1.5rem);color:var(--cream)}
.meta__item svg{width:1.3em;height:1.3em;color:var(--orange-400);flex:none}
.hero__cta{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin-top:26px;
  animation:titleIn .9s .44s cubic-bezier(.2,.8,.2,1) both}
.hero__note{margin-top:18px;font-size:.875rem;color:var(--cream-dim)}

.scroll-hint{position:absolute;bottom:18px;left:50%;transform:translateX(-50%);z-index:20;
  color:var(--cream-dim);font-size:.75rem;letter-spacing:.2em;text-transform:uppercase;
  display:grid;justify-items:center;gap:6px;animation:bounce 2s ease-in-out infinite}
@keyframes bounce{0%,100%{transform:translate(-50%,0)}50%{transform:translate(-50%,8px)}}

/* ============================================================
   SECTIES
   ============================================================ */
/* ---- Waar een anker uitkomt --------------------------------------
   De balk bovenaan staat vast en is 62px hoog. Springt een link naar
   een anker, dan legt de browser de bovenkant van dat element op
   hoogte nul, en dus achter die balk. Hoeveel je daarvan merkt hangt
   af van wat er in het element bovenaan staat.

   De secties beginnen met 56 tot 104px bovenruimte, dus daar viel het
   niet op; alleen op een smal scherm (56px ruimte tegen een balk van
   62) werd de eerste regel net afgesneden. Een kleine marge is genoeg.

   De tipskaart heeft dat probleem wel, en zwaar: die begint na zijn
   eigen padding meteen met de kop 'Veilig op pad', op 22 tot 34px van
   boven. Die kop verdween daardoor volledig onder de balk, en het zag
   eruit alsof de pagina te ver doorschoof.

   Onder aan de streep: de balk vrijhouden plus een marge, zodat het
   doel niet tegen de onderrand van de balk aan plakt. */
.section{position:relative;padding:clamp(56px,9vw,104px) 0;scroll-margin-top:16px}
#map{scroll-margin-top:calc(var(--balk) + 16px)}

/* Waar je landt als je op "Kaart" klikt.

   Het anker zit op de kaart zelf, niet op de kop erboven. Op een laptopscherm
   kwam je namelijk keurig bij "De Halloweenkaart van ..." uit en zag je van de
   kaart alleen de bovenrand, terwijl het juist om die kaart gaat. Nu staat de
   kaart bovenaan, vlak onder de balk, en scrolt de kop er boven weg.

   Boven een bepaalde hoogte past alles samen en laten we de kop wél staan. Waar
   die grens ligt is te rekenen: balk 62 + kop 300 + kaart 660 (de bovengrens
   van de 70vh hieronder) + de knoppenrij eronder, pakweg 68. Dat is 1090, dus
   vanaf 1100 past het. Op een laptop van 800 hoog zou de kop de knop "Waar ben
   ik" eruit duwen, en dat is precies wat we niet willen. */
.map-shell{scroll-margin-top:calc(var(--balk) + 16px)}

@media (min-height:1100px){
  .map-shell{scroll-margin-top:calc(var(--balk) + 300px)}
}
.section--alt{background:linear-gradient(180deg,var(--night-700),var(--night-800))}
.section__head{text-align:center;max-width:720px;margin:0 auto clamp(30px,5vw,54px)}
.section__eyebrow{font-weight:800;letter-spacing:.3em;text-transform:uppercase;font-size:.75rem;color:var(--ribbon);margin-bottom:10px}
.section__title{font-family:var(--font-slab);font-size:clamp(1.7rem,6vw,3rem);color:var(--cream)}
.section__title em{color:var(--orange-400);font-style:normal}
.section__lead{margin-top:14px;color:var(--cream-dim);font-size:clamp(1rem,2.4vw,1.12rem)}
/* Zelfde maat als de uitleg boven het formulier: een terzijde, geen lead.
   Geen eigen bovenmarge, en de zin erboven levert zijn ondermarge grotendeels
   in, zodat de twee regels bij elkaar horen in plaats van los te staan. */
.section__klein{margin:0;color:var(--cream-dim);font-size:.875rem}
.section__lead:has(+ .section__klein){margin-bottom:6px}

/* golvende scheidingslijn */
.divider{display:block;width:100%;height:auto;color:var(--night-700)}

/* stappen */
.steps{display:grid;gap:clamp(16px,3vw,26px);grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.step{
  position:relative;background:linear-gradient(180deg,rgba(74,51,88,.55),rgba(36,22,49,.85));
  border:1px solid rgba(169,140,191,.28);border-radius:var(--radius);
  padding:28px 24px 26px;text-align:center;overflow:hidden;
  transition:transform .25s cubic-bezier(.2,.8,.2,1), border-color .25s, box-shadow .25s;
}
.step:hover{transform:translateY(-6px);border-color:var(--orange-400);box-shadow:var(--shadow-glow)}
.step__num{position:absolute;top:10px;right:16px;font-family:var(--font-display);font-size:2.6rem;color:rgba(169,140,191,.22)}
.step__icon{width:74px;height:74px;margin:0 auto 16px;animation:bobSlow 3.4s ease-in-out infinite}
.step:nth-child(2) .step__icon{animation-delay:.4s}
.step:nth-child(3) .step__icon{animation-delay:.8s}
@keyframes bobSlow{0%,100%{transform:translateY(-5px)}50%{transform:translateY(5px)}}
.step h3{font-family:var(--font-display);font-size:1.15rem;color:var(--orange-300);margin-bottom:10px}
.step p{color:var(--cream-dim);font-size:.98rem;margin:0}

/* teller */
.counters{display:flex;flex-wrap:wrap;justify-content:center;gap:clamp(14px,4vw,44px);margin-top:clamp(30px,5vw,48px)}
.counter{text-align:center;min-width:130px}
.counter__num{font-family:var(--font-display);font-size:clamp(2rem,7vw,3.2rem);color:var(--orange-400);line-height:1}
.counter__label{font-size:.8125rem;letter-spacing:.14em;text-transform:uppercase;color:var(--cream-dim);margin-top:6px}

/* ============================================================
   KAART
   ============================================================ */
.map-shell{
  position:relative;border-radius:var(--radius);overflow:hidden;
  border:3px solid var(--orange-600);
  box-shadow:0 24px 60px rgba(0,0,0,.55), inset 0 0 90px rgba(20,13,28,.6);
}
/* De scroll-margin voor de kaart staat bij de secties, samen met die van de
   andere ankers, zodat er één plek is waar de hoogte van de balk in staat. */
#map{height:clamp(400px,70vh,660px);width:100%}

/* Schermvullend zonder de Fullscreen API: die werkt op een iPhone niet voor
   gewone elementen, alleen voor video. Vastgezet met CSS werkt overal hetzelfde. */
.map-vol{position:absolute;top:10px;right:10px;z-index:500;display:grid;place-items:center;
  width:38px;height:38px;border:1px solid rgba(169,140,191,.5);border-radius:10px;
  background:rgba(20,13,28,.85);color:var(--cream);cursor:pointer;padding:0}
.map-vol:hover{border-color:var(--orange-400);color:var(--orange-300)}
/* Zelfde knop, links van schermvullend: 38 breed plus 8 tussenruimte. */
.map-vol--thuis{right:56px}
.map-vol svg{width:17px;height:17px;fill:currentColor}
.map-shell--vol{position:fixed;inset:0;z-index:930;border:0;border-radius:0}
.map-shell--vol #map{height:100%}
body.kaart-vol{overflow:hidden}
.leaflet-container{font-family:var(--font-body)}
/* kaart in flyer-sfeer trekken */
/* Het paarse schema haalt de straatnamen als losse laag binnen, zodat de
   ondergrond donker kan blijven terwijl de letters crème blijven. Bij de lichte
   schema's is dat niet nodig: die tegels hebben hun namen al ingebakken. */

.map-legend{
  position:absolute;z-index:600;bottom:14px;left:14px;
  display:flex;flex-direction:column;gap:8px;
  background:rgba(20,13,28,.88);border:1px solid rgba(169,140,191,.35);
  border-radius:var(--radius-sm);padding:12px 14px;backdrop-filter:blur(4px);
}
.map-legend div{display:flex;align-items:center;gap:9px;font-size:.8125rem;font-weight:700}
.map-legend svg{width:26px;height:26px;flex:none}
/* De stip krijgt dezelfde breedte toebedeeld als de pompoen ernaast, anders
   springt de tekst van die twee regels naar links. */
.legenda-stip{width:26px;flex:none;display:grid;place-items:center}
.legenda-stip .loc-stip{width:13px;height:13px;top:0;margin:0}

.map-acties{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:12px;margin-top:18px}
/* Als de kaart nog leeg is: een uitnodiging in plaats van stilte. */
.map-leeg{text-align:center;color:var(--cream-dim);margin:16px 0 0;font-size:1.0625rem}
.map-leeg a{color:var(--orange-300);font-weight:800}
.map-acties__uitleg{font-size:.8125rem;color:var(--cream-dim);min-height:1.2em;max-width:44ch;text-align:center}
/* Vaste uitleg onder de knop; de regel erboven is de wisselende status. */
.map-acties__zin{margin:8px 0 0;font-size:.8125rem;color:var(--cream-dim);text-align:center}
.map-acties__fout{color:var(--orange-300);font-weight:700}

/* Stipjes in de statusregel, in dezelfde kleuren als de puntjes op de kaart:
   blauw ben jij, oranje zijn de anderen. In em, zodat ze meegroeien als iemand
   zijn browser op een grotere letter heeft staan. */
/* De ring eromheen komt uit een box-shadow en telt dus niet mee voor de breedte.
   Zonder marge plakt de stip daardoor tegen de woorden aan, ook al staat er in
   de tekst een spatie. Vandaar de ruimte hier en niet in de zin zelf: zo is hij
   links en rechts even groot. */
.loc-stip{display:inline-block;width:.62em;height:.62em;border-radius:50%;
  vertical-align:baseline;position:relative;top:.02em;margin-inline:.42em}
/* Dezelfde opbouw als de puntjes op de kaart: blauw met een witte rand eromheen
   en een zachte gloed, oranje met een dun crèmerandje. De rand komt uit een
   box-shadow en niet uit border, want dan zou hij van de vulling afsnoepen en
   blijft er op deze maat te weinig kleur over. In em, zodat het meeschaalt. */
.loc-stip--ik{background:#3b82f6;
  box-shadow:0 0 0 .16em #fff, 0 0 0 .22em rgba(59,130,246,.45), 0 0 .5em rgba(59,130,246,.7)}
.loc-stip--ander{background:var(--orange-400);
  box-shadow:0 0 0 .08em rgba(255,225,190,.75)}
/* In een contrastthema worden achtergrondkleuren vervangen en zijn de twee niet
   meer uit elkaar te houden. Ze mogen daarom hun eigen kleur houden. */
@media (forced-colors: active){ .loc-stip{forced-color-adjust:none} }

/* Waar ben ik?: venster met uitleg vóór er iets gevraagd wordt.
   Boven de 1000 van Leaflet: die zet zijn eigen hoeken (.leaflet-top en
   .leaflet-bottom, met daarin de bronvermelding) daarop, en die kwam anders
   dwars door dit venster heen. In schermvullende weergave viel dat niet op,
   want dan maakt .map-shell--vol een eigen stapelcontext. */
.loc-overlay{position:fixed;inset:0;z-index:1100;display:none;place-items:center;padding:20px;
  background:rgba(10,6,16,.78);backdrop-filter:blur(3px)}
.loc-overlay.open{display:grid}
.loc-venster{width:100%;max-width:31rem;background:linear-gradient(180deg,#2b1a38,#1c1128);
  border:2px solid var(--orange-500);border-radius:var(--radius);padding:26px 26px 22px;
  box-shadow:0 24px 60px rgba(0,0,0,.6);animation:titleIn .35s both}
.loc-venster h3{font-family:var(--font-display);font-size:clamp(1.3rem,4vw,1.7rem);
  color:var(--orange-400);margin:0 0 10px}
.loc-venster p{font-size:.9375rem;line-height:1.6;color:var(--cream)}
.loc-venster p.loc-klein{color:var(--cream-dim);font-size:.875rem;margin-bottom:.7em}
.loc-venster p.loc-klein:last-of-type{margin-bottom:22px}
.loc-knoppen{display:flex;flex-wrap:wrap;gap:10px;justify-content:flex-end}

/* De eigen stip en die van anderen zijn duidelijk verschillend, zodat je jezelf
   meteen terugvindt in een groepje puntjes. */
.loc-ik{border-radius:50%;background:#3b82f6;border:3px solid #fff;
  box-shadow:0 0 0 2px rgba(59,130,246,.5), 0 0 18px rgba(59,130,246,.9)}
/* Oranje en kleiner, zodat de blauwe stip onmiskenbaar jíj bent. */
.loc-ander{border-radius:50%;background:var(--orange-400);border:1px solid rgba(255,225,190,.75);
  box-shadow:0 0 8px rgba(245,153,60,.65)}
/* Onderaan en niet bovenaan: een popup opent boven de pin en botste daar
   tegen deze hint aan. */
.map-hint{
  position:absolute;z-index:600;bottom:14px;left:50%;transform:translateX(-50%);
  background:rgba(20,13,28,.88);border:1px solid rgba(169,140,191,.35);
  padding:8px 16px;border-radius:999px;font-size:.8125rem;color:var(--cream-dim);
  white-space:nowrap;pointer-events:none;
}
/* De legenda blijft ook op een telefoon linksonder staan, alleen iets opgetild:
   op een smal scherm valt de attributiebalk van Leaflet naar links en botste de
   legenda daar met een hoekje tegenaan. Vandaar bottom:32px in plaats van 14px. */
@media(max-width:600px){ .map-hint{display:none} .map-legend{bottom:32px;left:10px;padding:9px 11px;gap:6px} .map-legend div{font-size:.6875rem} .map-legend svg{width:20px;height:20px} }

/* markers */
.marker{position:relative;display:grid;place-items:center;cursor:pointer;
  filter:drop-shadow(0 6px 8px rgba(0,0,0,.6));
  animation:markerBob 3s ease-in-out infinite;transition:transform .2s ease}
.marker:hover{transform:scale(1.22)}
/* Op een lichte kaart verdwijnt een crèmekleurig spookje, dus een dunne donkere
   contour eromheen. Daarnaast een brede, lichte grondschaduw: veel vervaging en
   weinig dekking, want een korte harde schaduw wordt op licht papier een vlek in
   plaats van diepte. */
.kaart--licht .marker{filter:drop-shadow(0 6px 16px rgba(30,15,45,.18))
  drop-shadow(0 0 1px rgba(30,15,45,.7))}
.kaart--licht .marker__glow{display:none}
.kaart--licht .leaflet-control-attribution{background:rgba(255,255,255,.85)!important;color:#4a3358!important}
.kaart--licht .leaflet-control-attribution a{color:#b3560f!important}
.marker svg{width:100%;height:100%}
@keyframes markerBob{0%,100%{transform:translateY(-4px)}50%{transform:translateY(4px)}}
.marker--new{animation:markerDrop .7s cubic-bezier(.2,1.5,.4,1) 1, markerBob 3s ease-in-out infinite .7s}
@keyframes markerDrop{0%{transform:translateY(-90px) scale(.4);opacity:0}70%{opacity:1}100%{transform:translateY(0) scale(1)}}
.marker__glow{position:absolute;inset:-30%;border-radius:50%;z-index:-1;
  background:radial-gradient(circle,rgba(255,179,71,.5),transparent 68%);animation:glowPulse 2.6s ease-in-out infinite}
.marker--ghost .marker__glow{background:radial-gradient(circle,rgba(232,226,255,.45),transparent 68%)}
@keyframes glowPulse{0%,100%{opacity:.4;transform:scale(.9)}50%{opacity:.95;transform:scale(1.15)}}

/* popup */
.leaflet-popup-content-wrapper{
  background:linear-gradient(180deg,#2b1a38,#1c1128);color:var(--cream);
  border:2px solid var(--orange-500);border-radius:var(--radius-sm);
  box-shadow:0 14px 40px rgba(0,0,0,.6)}
.leaflet-popup-content{margin:14px 16px;font-size:.875rem;line-height:1.5}
.leaflet-popup-tip{background:#1c1128;border-right:2px solid var(--orange-500);border-bottom:2px solid var(--orange-500)}
.leaflet-popup-close-button{color:var(--cream-dim)!important}
.pop__type{display:inline-block;font-family:var(--font-display);font-size:.6875rem;letter-spacing:.08em;
  padding:3px 10px;border-radius:999px;margin-bottom:8px}
.pop__type--snoep{background:var(--orange-500);color:#221226}
.pop__type--spook{background:var(--ribbon);color:#221226}
.pop__name{font-family:var(--font-slab);font-size:1.1rem;margin-bottom:2px}
.pop__addr{color:var(--cream-dim);font-size:.8125rem;margin-bottom:8px}
.pop__note{margin:0}
.leaflet-control-attribution{background:rgba(20,13,28,.8)!important;color:var(--cream-dim)!important}
.leaflet-control-attribution a{color:var(--orange-300)!important}
.leaflet-bar a{background:#2b1a38!important;color:var(--cream)!important;border-color:#4a3358!important}
.leaflet-bar a:hover{background:var(--plum-500)!important}

/* ============================================================
   FORMULIER
   ============================================================ */
.form-grid{display:grid;gap:clamp(20px,4vw,40px);grid-template-columns:1.15fr .85fr;align-items:start}
@media(max-width:860px){ .form-grid{grid-template-columns:1fr} }
/* Het aanmeldblok heeft nog maar één kaart. Over de volle breedte wordt dat een
   heel breed formulier met korte velden, dus die krijgt een eigen maat. */
.form-smal{max-width:34rem;margin-inline:auto}
.card__kop{font-family:var(--font-display);font-size:1rem;color:var(--orange-300);margin-bottom:14px}
.card p{margin:0 0 14px}
.card p:last-child{margin-bottom:0}
.card{
  background:linear-gradient(180deg,rgba(74,51,88,.5),rgba(28,17,40,.9));
  border:1px solid rgba(169,140,191,.3);border-radius:var(--radius);
  padding:clamp(22px,4vw,34px);
}
.field{margin-bottom:16px}
.field label{display:block;font-weight:800;font-size:.8125rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ribbon);margin-bottom:7px}
.field input,.field textarea,.field select{
  width:100%;font-family:var(--font-body);font-size:1rem;color:var(--cream);
  background:rgba(20,13,28,.75);border:2px solid rgba(169,140,191,.6);
  border-radius:var(--radius-sm);padding:13px 15px;transition:border-color .2s,box-shadow .2s;
}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--orange-400);box-shadow:0 0 0 4px rgba(232,132,42,.18)}
.field textarea{min-height:92px;resize:vertical}
.choice{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:12px}
/* De radio's zijn onzichtbaar maar moeten focusbaar blijven. Zonder eigen maat
   erven ze de width:100% van .field input; als absolute box zonder gepositioneerde
   ouder is dat 100% van het venster, en dat duwt de pagina horizontaal open. */
.choice input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.choice label{
  display:grid;justify-items:center;gap:8px;text-align:center;cursor:pointer;
  background:rgba(20,13,28,.6);border:2px solid rgba(169,140,191,.6);border-radius:var(--radius-sm);
  padding:16px 10px;margin:0;text-transform:none;letter-spacing:0;font-size:.875rem;color:var(--cream);
  transition:border-color .2s,background .2s,transform .2s}
.choice label svg{width:46px;height:46px}
.choice label:hover{transform:translateY(-3px)}
.choice input:checked + label{border-color:var(--orange-400);background:rgba(232,132,42,.16);box-shadow:var(--shadow-glow)}
.choice input:focus-visible + label{outline:3px solid var(--orange-300);outline-offset:2px}
.veld-uitleg{font-size:.875rem;color:var(--cream-dim);margin:0 0 18px}
/* Dezelfde tekst, maar onder de knop: daar hoort lucht boven en niet onder. */
.veld-uitleg--na{margin:18px 0 0;padding-top:16px;border-top:1px solid rgba(169,140,191,.25)}

/* Wat doen we met jouw gegevens? Dichtgeklapt, want wie het niet leest wordt er
   niet mee lastiggevallen, en wie het wél wil weten vindt alles in één klik. */
.privacy{margin:18px 0 20px;border:1px solid rgba(169,140,191,.3);border-radius:var(--radius-sm);
  background:rgba(20,13,28,.5)}
.privacy summary{cursor:pointer;padding:12px 15px;font-weight:800;font-size:.875rem;color:var(--ribbon)}
.privacy summary:hover{color:var(--orange-300)}
.privacy ul{margin:0;padding:0 18px 14px 34px;font-size:.84375rem;line-height:1.55;color:var(--cream-dim)}
.privacy li{margin-bottom:7px}

.form-msg{margin-top:14px;padding:13px 16px;border-radius:var(--radius-sm);font-weight:700;display:none}
.form-msg--fout{background:rgba(232,132,42,.16);border:1px solid var(--orange-400);color:#ffd9a8}
.form-msg.show{display:block;animation:titleIn .4s both}
.form-msg--ok{background:rgba(123,201,111,.16);border:1px solid var(--ok);color:#cdeec8}
.tips li{margin-bottom:12px;color:var(--cream-dim)}
.tips h3{font-family:var(--font-display);font-size:1rem;color:var(--orange-300);margin-bottom:14px}

/* ============================================================
   FOOTER
   ============================================================ */
.footer{background:var(--night-900);padding:clamp(40px,6vw,64px) 0 30px;text-align:center;position:relative}
.footer__cta{font-family:var(--font-slab);font-size:clamp(1.2rem,4.4vw,2rem);color:var(--cream);margin-bottom:16px}
/* Bovenmarge is hier nodig: p heeft er standaard geen, dus zonder dit plakt
   de kleine tekst tegen de knop erboven. */
.footer__small{font-size:.75rem;color:#8b7d9c;line-height:1.7;margin-top:30px}
.footer__pumpkins{display:flex;justify-content:center;gap:18px;margin-bottom:22px}
.footer__pumpkins svg{width:42px;height:42px;animation:bobSlow 3s ease-in-out infinite}
.footer__pumpkins svg:nth-child(2){animation-delay:.35s}
.footer__pumpkins svg:nth-child(3){animation-delay:.7s}

/* toegankelijkheid: minder beweging */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .flyers{display:none}
}
.motion-off .flyers{display:none}
.motion-off .fog,.motion-off .star{animation:none}
