/* ----- 1. Tokens ------------------------------------------------------- */
:root {
  --pine: #24463A;
  --pine-diep: #1B342B;
  --chalk: #F1F2EE;
  --chalk-warm: #E8EAE3;
  --signaal: #C6D93C;
  --ink: #24463A;          /* body text is pine, never absolute black */
  --ink-zacht: #5B6F65;
  --lijn: rgba(36, 70, 58, 0.18);
  --lijn-sterk: rgba(36, 70, 58, 0.42);

  /* Motion tokens, from demo-template/motion-library.css §1.
     TWO tiers and picking the wrong one silently breaks the rule:
     --curve-* is the bare bezier, for use INSIDE an animation shorthand.
     --beweging-* is duration + curve, for use in transition.
     An animation shorthand takes at most two <time> values, so
     `animation: x 1s var(--beweging-lang) .4s` expands to three and the
     browser drops the whole declaration silently. That shipped three dead
     animations on kanookzo.nl. Delays go in their own animation-delay. */
  --curve-micro: cubic-bezier(0.445, 0.05, 0.55, 0.95);
  --curve-move: cubic-bezier(0.165, 0.84, 0.44, 1);
  --curve-lang: cubic-bezier(0.19, 1, 0.22, 1);
  --beweging-micro: 0.2s var(--curve-micro);
  --beweging-move: 0.4s var(--curve-move);
  --beweging-lang: 0.6s var(--curve-lang);

  --breed: 74rem;
  --rand: clamp(1.15rem, 4vw, 3.5rem);
}

/* ----- 2. Fonts -------------------------------------------------------- */
@font-face { font-family: 'Zilla Slab'; src: url('../fonts/zilla-slab-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Zilla Slab'; src: url('../fonts/zilla-slab-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Zilla Slab'; src: url('../fonts/zilla-slab-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Figtree'; src: url('../fonts/figtree.woff2') format('woff2'); font-weight: 300 900; font-style: normal; font-display: swap; }

/* ----- 3. Reset and base ---------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--chalk);
  color: var(--ink);
  font-family: 'Figtree', system-ui, sans-serif;
  font-size: 1.0625rem;             /* 17px: >=16px gate, and calm at density 7 */
  line-height: 1.6;                 /* the lane's one genuinely useful number */
  font-weight: 400;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--pine); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--pine-diep); }
:focus-visible { outline: 3px solid var(--signaal); outline-offset: 2px; }
h1, h2, h3 { font-family: 'Zilla Slab', Georgia, serif; font-weight: 500; letter-spacing: -0.015em; line-height: 1.04; margin: 0; }
p { margin: 0; }
.wrap { max-width: var(--breed); margin: 0 auto; padding-inline: var(--rand); }
.vp-skip { position: absolute; left: -9999px; min-width: 44px; min-height: 44px; }
.vp-skip:focus { left: 8px; top: 8px; z-index: 99; background: var(--signaal); color: var(--pine); padding: 12px 16px; min-height: 44px; display: inline-flex; align-items: center; }

/* Numbers are the display element on this site, everywhere. */
.cijfer { font-family: 'Zilla Slab', Georgia, serif; font-variant-numeric: tabular-nums; font-weight: 500; }

/* newyorker's four-level grammar: rubric -> hed -> dek -> byline.
   This is what lets density 7 read calm, and it is identical in every
   card-like unit on the site. Its rendition is deliberately NOT the card's
   own (no hairline rules + italic serif + tracked mono = AI cluster 3). */
.rubriek { font-family: 'Figtree', sans-serif; font-size: 1rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-zacht); margin: 0 0 0.5rem; }
.dek { font-size: 1rem; color: var(--ink-zacht); max-width: 42ch; margin: 0.6rem 0 0; }
.byline { font-size: 1rem; color: var(--ink-zacht); margin: 0.8rem 0 0; }

/* ----- 4. Motion primitives (copied from motion-library.css §2) --------
   THE SAFETY CONTRACT: every hiding rule is prefixed .beweegt, set on <html>
   by an inline <head> snippet. No JS, no IntersectionObserver, or reduced
   motion all mean no class, which means no hidden start state and a fully
   readable page. roj-bouw went live with 8 of 8 blocks at opacity 0 without
   this. Do not remove the prefix. */
/* THE OPACITY QUESTION, decided rather than drifted into.
   This site first shipped translate-only reveals, following garage-em's fix
   ("the entrance translates and never fades") after two sections rendered blank
   here on the first render. check-motion.sh then failed it in all three engines:
   its `below-fold starts hidden` test defines hidden as opacity < 0.5, so an
   always-opaque reveal is indistinguishable from no reveal at all, and the gate
   exists to prove motion engages OUTSIDE Chromium.
   Resolved in favour of the library form, because the thing that made opacity
   dangerous is now closed: roj-bouw and garage-em had no dead-man timer. This
   page arms one in the inline <head> snippet, and check-motion verifies it
   directly - "script 404: page recovers, 0 hidden at load -> 6/6 visible after
   the dead-man timer", in Chromium, WebKit and Firefox. Opacity can no longer
   strand content, so the shared gate gets the mechanism it can measure. */
.beweegt .onthul,
.beweegt .onthul-lijst > * {
  opacity: 0;
  transition: opacity var(--beweging-lang), transform var(--beweging-lang);
  transition-delay: calc(var(--n, 0) * 70ms);
}
.beweegt .onthul { transform: translateY(22px); }
.beweegt .onthul-lijst > * { transform: translateX(-12px); }
.beweegt .onthul.is-zichtbaar,
.beweegt .onthul-lijst.is-zichtbaar > * { opacity: 1; transform: none; }

/* Images may still use clip-path: a partly-clipped image is visibly an image,
   and it recovers to inset(0) the moment the observer fires. It never renders
   as nothing. The wrapper stays fully opaque, so do not add .onthul to it. */
.beweegt .onthul-beeld img { clip-path: inset(0 0 100% 0); transition: clip-path var(--beweging-lang); }
.beweegt .onthul-beeld.is-zichtbaar img { clip-path: inset(0 0 0 0); }

/* ----- 5. Header and footer (pine field, on every page) ---------------- */
.vp-kop { background: var(--pine); color: var(--chalk); }
.vp-kop__in { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; padding-block: 1.05rem; flex-wrap: wrap; }
.merk { font-family: 'Zilla Slab', Georgia, serif; font-weight: 600; font-size: 1.15rem; letter-spacing: 0.02em; color: var(--chalk); text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; }
.merk span { color: var(--signaal); }
.vp-nav { display: flex; gap: clamp(0.8rem, 2.4vw, 1.9rem); flex-wrap: wrap; font-size: 0.9rem; }
.vp-nav a { color: var(--chalk); text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; padding-block: 0.55rem; border-bottom: 2px solid transparent; transition: border-color var(--beweging-micro); }
.vp-nav a:hover, .vp-nav a[aria-current="page"] { border-bottom-color: var(--signaal); color: var(--chalk); }

.vp-voet { background: var(--pine-diep); color: var(--chalk); margin-top: 0; }
.vp-voet__in { padding-block: clamp(2.2rem, 5vw, 3.4rem); display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1.8rem 2.4rem; }
.vp-voet h2 { font-size: 1.05rem; color: var(--chalk); }
.vp-voet a { color: var(--chalk); }
.vp-voet .klein { font-size: 0.82rem; color: rgba(241, 242, 238, 0.72); }

/* ----- 6. Buttons ------------------------------------------------------ */
.knop { display: inline-block; font-family: 'Figtree', sans-serif; font-weight: 700; font-size: 0.95rem; border: 0; border-radius: 2px; padding: 0.95rem 1.6rem; cursor: pointer; text-decoration: none; min-height: 44px; }
.knop--hoofd { background: var(--pine); color: var(--chalk); transition: background var(--beweging-micro), transform var(--beweging-move); }
.knop--hoofd:hover { background: var(--pine-diep); color: var(--chalk); }
.knop--licht { background: var(--signaal); color: var(--pine); transition: transform var(--beweging-move); }
.knop--licht:hover { color: var(--pine); }
/* L4: magnetic pill. The runtime sets --mx/--my from the pointer; with no JS
   the custom properties are simply absent and it is an ordinary button. */
.knop--pil { border-radius: 999px; transform: translate(var(--mx, 0), var(--my, 0)); transition: transform var(--beweging-move), background var(--beweging-micro); }
.knop--spook { background: transparent; color: var(--pine); border: 1px solid var(--lijn-sterk); }
.knop--spook:hover { border-color: var(--pine); }
.link-pijl { font-weight: 600; text-decoration: none; border-bottom: 2px solid var(--signaal); padding-bottom: 2px; display: inline-flex; align-items: center; min-height: 44px; }
.link-pijl::after { content: ' \2192'; }

/* ----- 7. Bands and rhythm. Density 7 = whitespace BETWEEN bands, not
   inside them. Hairlines instead of boxes. No card containers anywhere:
   design-taste-frontend bans generic card containers above density 7. --- */
.band { padding-block: clamp(2.6rem, 6vw, 5rem); }
.band--pine { background: var(--pine); color: var(--chalk); }
.band--pine h2, .band--pine h3 { color: var(--chalk); }
.band--pine .rubriek, .band--pine .dek, .band--pine .byline { color: rgba(241, 242, 238, 0.74); }
.band--papier { background: var(--chalk-warm); }
.band--krap { padding-block: clamp(1.6rem, 3.5vw, 2.6rem); }
.bandkop { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; margin-bottom: clamp(1.4rem, 3vw, 2.2rem); }
.bandkop h2 { font-size: clamp(1.5rem, 3.6vw, 2.3rem); }

/* ----- 8. LAYOUT FAMILY A - the hero. The figure is the hero. ----------
   Off-grid editorial: the type column is deliberately wider than the image
   column and the image is small. Variance 7 lives in the 1.55/1 split and the
   negative pull on the figure, not in chaos. */
.held { background: var(--chalk); padding-block: clamp(2rem, 5vw, 3.6rem) clamp(2.2rem, 5vw, 3.4rem); }
.held__in { display: grid; grid-template-columns: 1.55fr 1fr; gap: clamp(1.5rem, 4vw, 3.2rem); align-items: start; }
.held__tarief { display: block; font-size: clamp(4.2rem, 15vw, 9.5rem); line-height: 0.82; margin: 0.2rem 0 0; letter-spacing: -0.04em; }
.held__tarief .eur { font-size: 0.36em; vertical-align: super; margin-right: 0.12em; color: var(--ink-zacht); }
.held__tarief .cent { font-size: 0.3em; color: var(--ink-zacht); }
.held h1 { font-size: clamp(1.35rem, 3vw, 2rem); margin-top: 1.1rem; max-width: 30ch; }
.held__dek { font-size: 1.05rem; color: var(--ink-zacht); max-width: 44ch; margin-top: 0.8rem; }
.held__acties { display: flex; gap: 0.8rem; margin-top: 1.5rem; flex-wrap: wrap; }
.held__beeld { margin: 0; }
.held__beeld img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; }
.held__beeld figcaption { font-size: 1rem; color: var(--ink-zacht); margin-top: 0.5rem; }

/* L2 entrance choreography: seven beats, 0-1.4s. Delays are their own
   property, never a third <time> in the animation shorthand. */
@media (prefers-reduced-motion: no-preference) {
  .beweegt .held .rubriek,
  .beweegt .held__tarief,
  .beweegt .held h1,
  .beweegt .held__dek,
  .beweegt .held__acties,
  .beweegt .held__beeld { animation: beat 0.66s var(--curve-lang) both; }
  .beweegt .held .rubriek   { animation-delay: 0.06s; }
  .beweegt .held__tarief    { animation: beat-cijfer 0.8s var(--curve-lang) both; animation-delay: 0.16s; }
  .beweegt .held h1         { animation-delay: 0.42s; }
  .beweegt .held__dek       { animation-delay: 0.56s; }
  .beweegt .held__acties    { animation-delay: 0.70s; }
  .beweegt .held__beeld     { animation: beat-beeld 0.9s var(--curve-lang) both; animation-delay: 0.30s; }
}
@keyframes beat { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: none; } }
@keyframes beat-cijfer { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes beat-beeld { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

/* ----- 9. LAYOUT FAMILY B - the ruled sheet, and .klopt ----------------
   No boxes. Rules do the work. Alternating row tint is the ledger, and it is
   the reason the paper photography belongs on this site at all. */
.blad { border-top: 2px solid var(--pine); }
.blad__rij { display: grid; grid-template-columns: 1fr auto; gap: 1rem 1.5rem; padding: 0.85rem 0.7rem; border-bottom: 1px solid var(--lijn); align-items: baseline; }
.blad__rij:nth-child(odd) { background: rgba(36, 70, 58, 0.045); }
.blad__rij .wat { font-weight: 500; }
.blad__rij .toelichting { display: block; font-size: 1rem; color: var(--ink-zacht); font-weight: 400; margin-top: 0.15rem; }
.blad__rij .bedrag { font-size: 1.1rem; white-space: nowrap; }
.blad__som { display: grid; grid-template-columns: 1fr auto; gap: 1.5rem; padding: 1rem 0.7rem; border-top: 2px solid var(--pine); font-weight: 700; align-items: baseline; }
.blad__som .bedrag { font-size: 1.3rem; }

/* SIGNATURE MOVE - .klopt. Het klopt: the figures arrive misaligned on the
   decimal and slide into a single column, then the rule lands and the total
   resolves. Bound to .klopt on the sheet; the runtime drives it. */
/* The RESTING state is aligned, and the settle plays as an animation when the
   reveal fires. This is the inverse of the obvious implementation and it is
   deliberate: IntersectionObserver only delivers a callback when the ratio
   CHANGES, so a jump-scroll or an in-page anchor that skips the sheet entirely
   produces no callback at all - measured, not assumed. With the offset held in
   CSS until a class arrives, that left every amount permanently 22px off the
   decimal column, on the one element whose entire point is that it lines up.
   Now a missed observer costs an animation, never correctness. */
.beweegt .klopt.is-klaar .bedrag {
  animation: klopt-in 0.55s var(--curve-move);
}
@keyframes klopt-in {
  from { transform: translateX(var(--schuif, 12px)); }
  to { transform: none; }
}
.beweegt .klopt .blad__som { position: relative; }
.beweegt .klopt .blad__som::after {
  content: ''; position: absolute; left: 0.7rem; right: 0.7rem; bottom: 0.55rem; height: 3px;
  background: var(--signaal); transform: scaleX(0); transform-origin: left;
  transition: transform var(--beweging-lang); transition-delay: 0.5s;
}
.beweegt .klopt.is-klaar .blad__som::after { transform: scaleX(1); }

/* ----- 10. L4 SET PIECE - the tariff calculator ------------------------
   Layered OVER the static sheet, never replacing it. The sheet above is the
   shipped content and reads correctly with no JS; this only appears when the
   runtime is alive. garage-wantij's lesson: a control above a total frozen at
   zero is a page lying to its reader. */
.rekenaar { display: none; }
.js-aan .rekenaar { display: grid; grid-template-columns: 1.1fr 0.9fr; border: 1px solid var(--lijn-sterk); }
.rekenaar__knoppen { padding: clamp(1.2rem, 3vw, 1.9rem); display: grid; gap: 1.15rem; align-content: start; background: var(--chalk); }
.rekenaar__knoppen label { display: block; font-size: 1rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-zacht); }
.rekenaar__knoppen label b { color: var(--pine); font-variant-numeric: tabular-nums; }
.rekenaar__knoppen select { width: 100%; margin-top: 0.5rem; padding: 0.6rem 0.65rem; border: 1px solid var(--lijn-sterk); border-radius: 2px; background: #fff; color: var(--pine); font-family: 'Figtree', sans-serif; font-size: 1rem; min-height: 44px; }
.rekenaar__knoppen input[type="range"] { width: 100%; margin-top: 0.55rem; accent-color: var(--pine); min-height: 44px; }
.rekenaar__vink { display: flex; align-items: center; gap: 0.65rem; text-transform: none; letter-spacing: 0; font-size: 0.95rem; font-weight: 500; color: var(--pine); min-height: 44px; }
.rekenaar__vink input { width: 24px; height: 24px; min-width: 44px; min-height: 44px; accent-color: var(--pine); }
.rekenaar__uit { background: var(--pine); color: var(--chalk); padding: clamp(1.2rem, 3vw, 1.9rem); display: flex; flex-direction: column; justify-content: center; }
.rekenaar__som { font-family: 'Zilla Slab', Georgia, serif; font-weight: 500; font-variant-numeric: tabular-nums; font-size: clamp(2.6rem, 8vw, 4.4rem); line-height: 0.9; margin: 0.3rem 0 0; }
.rekenaar__som .eur { font-size: 0.4em; vertical-align: super; opacity: 0.72; margin-right: 0.1em; }
.rekenaar__som .cent { font-size: 0.34em; opacity: 0.72; }
.rekenaar__som.stuit { animation: stuit 0.42s var(--curve-move); }
@keyframes stuit { from { opacity: 0.4; transform: translateY(7px); } to { opacity: 1; transform: none; } }
.rekenaar__regel { font-size: 1rem; color: rgba(241, 242, 238, 0.76); margin-top: 0.8rem; }
.rekenaar__jaar { font-size: 1rem; margin-top: 0.9rem; padding-top: 0.8rem; border-top: 1px solid rgba(241, 242, 238, 0.24); }
.rekenaar__jaar b { font-variant-numeric: tabular-nums; position: relative; }
.rekenaar__jaar b::after { content: ''; position: absolute; left: -3px; right: -3px; bottom: -4px; height: 3px; background: var(--signaal); transform: scaleX(0); transform-origin: left; transition: transform var(--beweging-lang); }
.rekenaar__jaar.licht b::after { transform: scaleX(1); }
.rekenaar__nb { font-size: 1rem; color: var(--ink-zacht); margin-top: 0.9rem; }

/* ----- 11. LAYOUT FAMILY C - the fiscal calendar, static and complete --
   This was a marquee and it was wrong: a marquee hides half its content at any
   moment, and these dates are the one thing on this fictional site that carries
   a real correctness duty. All six readable at once, no waiting.
   L3 LEVEND ELEMENT: the ruled overlay drifts continuously behind them. Time
   based, decorative, hides nothing, freezes to a static field under reduced
   motion. Content a visitor came to read does not move; texture moves. */
.kalender { position: relative; overflow: hidden; }
.kalender__in { position: relative; z-index: 1; }
.kalender__lijst { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(6, 1fr); gap: 0.3rem 1.3rem; }
.kalender__lijst li { display: flex; flex-direction: column; gap: 0.2rem; border-left: 1px solid rgba(241, 242, 238, 0.28); padding-left: 0.7rem; }
.kalender__lijst .wat { font-size: 0.76rem; color: rgba(241, 242, 238, 0.7); letter-spacing: 0.05em; }
.kalender__lijst .wanneer { font-family: 'Zilla Slab', Georgia, serif; font-weight: 600; font-size: 1.05rem; color: var(--signaal); font-variant-numeric: tabular-nums; }
.kalender__drift { position: absolute; inset: -30% -10%; opacity: 0.15; pointer-events: none;
  background-image: repeating-linear-gradient(90deg, transparent 0 64px, rgba(241, 242, 238, 0.5) 64px 65px),
                    repeating-linear-gradient(0deg, transparent 0 15px, rgba(241, 242, 238, 0.28) 15px 16px); }
@media (prefers-reduced-motion: no-preference) {
  /* A seamless infinite drift must be linear; an eased curve visibly stutters
     at the loop seam, where the transform resets. The marker below must sit on
     the line directly above the declaration: the gate reads only the previous
     two lines, so a marker three lines up is invisible to it. */
  /* eigen-curve: linear is required for a seamless infinite loop */
  .kalender__drift { animation: voer 42s linear infinite; }
}
@keyframes voer { from { transform: translateY(0); } to { transform: translateY(-31px); } }

/* ----- 12. LAYOUT FAMILY D - numbered steps, off-grid ------------------ */
.stappen { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1rem, 2.5vw, 1.8rem); }
.stap { display: flex; flex-direction: column; gap: 0.7rem; min-width: 0; }
.stap:nth-child(even) { margin-block-start: clamp(0.8rem, 2.4vw, 2.2rem); }
.stap__nr { font-family: 'Zilla Slab', Georgia, serif; font-weight: 600; font-size: 2.1rem; line-height: 1; color: var(--ink-zacht); }
.band--pine .stap__nr { color: rgba(241, 242, 238, 0.7); }
.stap img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.stap h3 { font-size: 1.05rem; }
.stap p { font-size: 1rem; color: var(--ink-zacht); }
.band--pine .stap p { color: rgba(241, 242, 238, 0.76); }

/* ----- 13. Two-column prose / inverted classic ------------------------- */
.duo { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(1.5rem, 4vw, 3.4rem); align-items: start; }
.duo--omgekeerd { grid-template-columns: 0.85fr 1.15fr; }
.duo--omgekeerd .duo__beeld { order: -1; }
.duo__beeld img { width: 100%; }
/* A 2.9:1 band becomes an unreadable 323x111 strip at 360px. Crop it
   taller on a phone rather than letting it thin out - the gate caught
   this as a sliver, which is the same defect class Lorenzo found by
   hand on a real handset (doc 05, 2026-07-26). */
@media (max-width: 767px) { .duo__beeld img { aspect-ratio: 3 / 2; object-fit: cover; } }
.lijst-schoon { list-style: none; margin: 1.2rem 0 0; padding: 0; }
.lijst-schoon a { display: inline-flex; align-items: center; min-height: 44px; }
.lijst-schoon li { padding: 0.6rem 0 0.6rem 1.5rem; border-bottom: 1px solid var(--lijn); position: relative; }
.lijst-schoon li::before { content: ''; position: absolute; left: 0; top: 1.15rem; width: 0.7rem; height: 3px; background: var(--lijn-sterk); }
.band--pine .lijst-schoon li { border-bottom-color: rgba(241, 242, 238, 0.22); }

/* ----- 14. LAYOUT FAMILY E - forms ------------------------------------- */
.formulier { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.2rem; margin-top: 1.4rem; }
.veld { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.veld--breed { grid-column: 1 / -1; }
.veld label { font-size: 1rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-zacht); }
.veld input, .veld textarea, .veld select { font-family: 'Figtree', sans-serif; font-size: 1rem; padding: 0.7rem 0.75rem; border: 1px solid var(--lijn-sterk); border-radius: 2px; background: #fff; color: var(--ink); min-height: 44px; width: 100%; }
.veld textarea { min-height: 8rem; resize: vertical; }
.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-klein { font-size: 1rem; color: var(--ink-zacht); margin-top: 0.9rem; }
.band--pine .form-klein { color: rgba(241, 242, 238, 0.72); }
.band--pine .veld label { color: rgba(241, 242, 238, 0.78); }

/* ----- 15. Openingstijden / feit-rijen -------------------------------- */
.feiten { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.feiten li { display: grid; grid-template-columns: 1fr auto; gap: 1rem; padding: 0.6rem 0; border-bottom: 1px solid var(--lijn); }
.band--pine .feiten li { border-bottom-color: rgba(241, 242, 238, 0.22); }
.feiten .waarde { font-variant-numeric: tabular-nums; font-weight: 500; }
.feiten .waarde a { display: inline-flex; align-items: center; min-height: 44px; }

/* ----- 16. Responsive. design-taste-frontend §7 MOBILE OVERRIDE: at
   VARIANCE 4-10 every asymmetric layout must collapse to a strict single
   column below 768px. The even-step offset is removed too, or the stagger
   becomes uneven vertical gaps on a phone. -------------------------------- */
@media (max-width: 860px) {
  .kalender__lijst { grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .stappen { grid-template-columns: repeat(2, 1fr); }
  .js-aan .rekenaar { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
  .blad__som { grid-template-columns: 1fr; gap: 0.3rem; }
  .blad__som .bedrag { font-size: 1.45rem; }
  /* F3: the mandated maker pill is position:fixed 60px off the bottom of the
     viewport, and the hero action block was ending at 621px in a 630px
     viewport, so the pill sat on the secondary CTA. Padding cannot fix it --
     the pill is fixed to the VIEWPORT, so the CTAs have to land higher. The
     phone header was 146px on its own because the nav wrapped to two lines.
     Measured before: acties top=497 bottom=621. Note kadevuur ships this same
     overlap on its PRIMARY CTA, live; that is a shared-element issue and is
     reported separately rather than patched from here. */
  .vp-kop__in { padding-block: 0.45rem; gap: 0.5rem; }
  .vp-nav { gap: 0.7rem; font-size: 0.92rem; }
  /* 44px stays: it is an accessibility floor, and the pill clearance is
     polish. The space comes out of the display figure instead, which is
     still by far the largest element on the page at 3.2rem. */
  .vp-nav a { min-height: 44px; padding-block: 0.25rem; }
  .held__tarief { font-size: clamp(3.2rem, 13vw, 9.5rem); }
  .held { padding-block: 0.6rem 5.5rem; }
  .held .rubriek { margin-bottom: 0.25rem; }
  .held h1 { margin-top: 0.5rem; }
  .held__dek { margin-top: 0.4rem; }
  .held__acties { margin-top: 0.7rem; gap: 0.5rem; }
  .held__acties .knop { padding-block: 0.8rem; }
  .held__in, .duo, .duo--omgekeerd { grid-template-columns: 1fr; }
  .duo--omgekeerd .duo__beeld { order: 0; }
  .held__beeld { max-width: 15rem; }
  .stappen { grid-template-columns: 1fr; }
  .stap:nth-child(even) { margin-block-start: 0; }
  .formulier { grid-template-columns: 1fr; }
  .kalender__lijst { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 380px) {
  .kalender__lijst { grid-template-columns: 1fr; }
}

/* ----- 17. Disclosure banner (doc 05 legal guardrail, wording owned by
   scripts/install-shared-layer.mjs - never reword it here). Required as the
   first element on every page and repeated in the footer. This is a layout
   element, not just a legal string: doc 05's 2026-07-28 log records that
   treating it as an afterthought pushed a CTA below the fold. --------------- */
.demo-banner { position: relative; z-index: 70; background: var(--signaal); color: var(--pine); padding: 0.5rem var(--rand); font-size: 0.76rem; line-height: 1.45; text-align: center; font-weight: 600; }
.demo-banner a { color: inherit; text-underline-offset: 3px; }
.demo-banner--voet { grid-column: 1 / -1; background: transparent; color: rgba(241, 242, 238, 0.72); text-align: left; padding: 1.2rem 0 0; font-weight: 400; border-top: 1px solid rgba(241, 242, 238, 0.22); margin-top: 0.6rem; }
.demo-banner--voet p { margin: 0.15rem 0; }


/* A panel heading inside a component is not a section eyebrow. Separate class
   so the mechanical eyebrow count (taste-skill §14, ceiling = sectionCount/3)
   measures what the rule is actually about: uppercase tracked micro-labels
   stacked above section headlines. karol-v2 shipped 7 against a ceiling of 3
   and garage-em repeated it. */
.paneelkop { font-family: 'Figtree', sans-serif; font-size: 1rem; font-weight: 700; color: var(--pine); margin: 0 0 0.2rem; }
.paneelkop--licht { color: rgba(241, 242, 238, 0.82); }
