/* ==========================================================================
   Site v2 — onderdelen die al zijn overgezet naar het nieuwe ontwerp

   Geladen door de echte site, na navbar.css zodat overgezette onderdelen
   winnen van de oude regels die er nog liggen.

   Er was even een aparte voorbeeldschil onder /admin/ontwerp bedacht, maar dat
   zou betekenen dat elk onderdeel twee keer wordt overgezet — één keer in de
   schil en één keer echt. Nu gaat het direct de site in, en mag de site er
   tussentijds onaf uitzien. De branch hoort daarom niet naar master tot het
   geheel klopt.

   Overzetten gaat per onderdeel, en een onderdeel sleept zijn omgeving mee:
   de balk uit het ontwerp is een glazen pil, en glas veronderstelt een
   ondergrond. Daarom draagt de body hier ook de themakleuren.

   Alle kleuren komen uit de themalaag onderaan variables.css en zijn dus
   afhankelijk van `data-theme` op <html>. Geen enkele waarde staat hier hard.
   ========================================================================== */

/* --------------------------------------------------------------------------
   De ondergrond
   -------------------------------------------------------------------------- */

.v2 {
    min-height: 100vh;
    background-color: var(--surface);
    color: var(--ink);
    font-family: var(--font-tekst);
    -webkit-font-smoothing: antialiased;
    /* Zacht, want het thema wisselt met een klik en een harde omslag leest
       als een herlaadbeurt. */
    transition: background-color 0.4s ease, color 0.4s ease;
}

@media (prefers-reduced-motion: reduce) {
    .v2 {
        transition: none;
    }
}

/* De gekleurde lichtvlekken uit het ontwerp. Puur decoratief en daarom
   aria-hidden in de markup; `--mesh` tempert het geheel met één waarde. */
.v2-mesh {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: var(--mesh);
    background:
        radial-gradient(48rem 32rem at 18% -8%, var(--mesh-1), transparent 65%),
        radial-gradient(42rem 30rem at 88% 4%, var(--mesh-2), transparent 62%),
        radial-gradient(38rem 28rem at 62% 92%, var(--mesh-3), transparent 60%);
}

.v2-page {
    position: relative;
    z-index: 1;
}

/* --------------------------------------------------------------------------
   De balk

   Zwevend en afgerond, niet doorlopend: dat is de meest zichtbare wijziging
   ten opzichte van de huidige navbar en het bepaalt de hele bovenrand.
   -------------------------------------------------------------------------- */

.v2-nav {
    position: sticky;
    top: 0;
    z-index: 90;
    padding: 14px 24px 0;
}

.v2-nav-inner {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 26px;
    padding: 10px 12px 10px 18px;
    background-color: var(--glass-fill);
    /* Twee schrijfwijzen: Safari ondersteunt alleen de voorvoegselvorm. */
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    /* De binnenste lijn is de glans bovenop het glas. Op het lichte thema is
       `--spec` doorzichtig, want wit op wit is ruis. */
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
}

/* Vervalt de vervaging, dan wordt de balk dekkend. Zonder deze regel staat
   lopende tekst dwars door het menu heen — dezelfde reden als de mobiele
   terugval in de huidige navbar. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .v2-nav-inner {
        background-color: var(--panel);
    }
}

.v2-brand {
    display: inline-flex;
    align-items: center;
    flex: none;
    /* Voedt `currentColor` in het merkteken: de letters volgen het thema, de
       accolades en de "D" houden hun merkkleur. Zie elements/logo.html.twig. */
    color: var(--ink);
}

.v2-brand img,
.v2-brand .v2-merk {
    display: block;
    height: 40px;
    width: auto;
}

.v2-nav-links {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2-nav-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    /* 44px raakvlak conform WCAG 2.5.8, ook al oogt de tekst kleiner. */
    min-height: 44px;
    padding: 0 12px;
    font-size: 15px;
    font-weight: 500;
    color: var(--ink-2);
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
    text-decoration: none;
    transition: color 0.18s ease, background-color 0.18s ease;
}

.v2-nav-link:hover,
.v2-nav-link:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

.v2-nav-link[aria-current='page'] {
    color: var(--ink);
}

.v2-nav-link[aria-expanded='true'] {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

/* Het pijltje draait mee, zodat open en dicht ook zonder kleurverschil te
   zien is — kleur alleen is nooit genoeg om toestand aan te geven. */
.v2-caret {
    display: inline-block;
    font-size: 10px;
    transition: transform 0.18s ease;
}

.v2-nav-link[aria-expanded='true'] .v2-caret {
    transform: rotate(180deg);
}

/* --------------------------------------------------------------------------
   Uitklapmenu
   -------------------------------------------------------------------------- */

.v2-drop {
    position: relative;
}

.v2-drop-menu {
    position: absolute;
    top: calc(100% + 10px);
    left: -6px;
    min-width: 15rem;
    margin: 0;
    padding: 8px;
    list-style: none;
    background-color: var(--panel);
    backdrop-filter: blur(30px) saturate(180%);
    -webkit-backdrop-filter: blur(30px) saturate(180%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
    /* Verborgen met visibility en niet met display:none, zodat er een
       overgang mogelijk is en de inhoud vindbaar blijft voor zoekfuncties. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}

.v2-drop[data-open='true'] .v2-drop-menu {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

.v2-drop-item {
    display: block;
    padding: 9px 12px;
    font-size: 14.5px;
    color: var(--ink-2);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: color 0.15s ease, background-color 0.15s ease;
}

.v2-drop-item:hover,
.v2-drop-item:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

.v2-drop-item strong {
    color: var(--ink);
}

/* --------------------------------------------------------------------------
   Rechterkant: taal, thema, oproep tot actie
   -------------------------------------------------------------------------- */

.v2-nav-side {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: none;
}

/* Taal en thema in één omlijnd vak, zoals het ontwerp het doet. Losse
   knoppen met een streepje ertussen lezen als twee dingen; dit leest als één
   voorkeurenblok, en dat is het ook. */
.v2-prefs {
    display: flex;
    align-items: center;
    height: 44px;
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.v2-prefs-lang {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 100%;
    padding: 0 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.05em;
    color: var(--ink-3);
    text-decoration: none;
    transition: color 0.18s ease, background-color 0.18s ease;
}

.v2-prefs-lang[aria-current='true'] {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
    font-weight: 600;
}

.v2-prefs-lang:hover {
    color: var(--ink);
}

.v2-prefs-sep {
    width: 1px;
    height: 20px;
    background-color: var(--line);
    flex-shrink: 0;
}

.v2-theme-toggle {
    width: 46px;
    height: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    color: var(--ink-2);
    background: transparent;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    transition: color 0.18s ease, background-color 0.18s ease;
}

.v2-theme-toggle:hover,
.v2-theme-toggle:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

.v2-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 18px;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--on-accent);
    background-color: var(--accent);
    border-radius: var(--radius-md);
    text-decoration: none;
    white-space: nowrap;
    transition: filter 0.18s ease;
}

.v2-cta:hover,
.v2-cta:focus-visible {
    filter: brightness(1.08);
}

/* --------------------------------------------------------------------------
   Mobiel
   -------------------------------------------------------------------------- */

.v2-burger {
    display: none;
    width: 44px;
    height: 44px;
    align-items: center;
    justify-content: center;
    color: var(--ink);
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
}

.v2-mobile {
    display: none;
    max-width: 1280px;
    margin: 10px auto 0;
    padding: 10px;
    background-color: var(--panel);
    backdrop-filter: blur(30px) saturate(180%);
    -webkit-backdrop-filter: blur(30px) saturate(180%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
}

.v2-mobile a {
    display: block;
    min-height: 44px;
    padding: 11px 14px;
    font-size: 15px;
    color: var(--ink-2);
    text-decoration: none;
    border-radius: var(--radius-md);
}

.v2-mobile a:hover,
.v2-mobile a:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

@media (max-width: 1080px) {
    .v2-nav-links,
    .v2-cta {
        display: none;
    }

    .v2-burger {
        display: inline-flex;
    }

    .v2-nav[data-menu='open'] .v2-mobile {
        display: block;
    }
}


.v2-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 22px 0;
}

/* --------------------------------------------------------------------------
   Hero

   Twee kolommen die op tablet naar één vallen. De rechterkolom is een
   beeldvlak; zolang daar geen beeld voor is, staat er het verloop uit het
   ontwerp. Weglaten zou de kolom laten inklappen en de hele opbouw veranderen.
   -------------------------------------------------------------------------- */

.v2-hero {
    position: relative;
    z-index: 10;
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(34px, 5vw, 58px) clamp(20px, 4vw, 40px) clamp(56px, 8vw, 88px);
}

.v2-hero-grid {
    display: grid;
    grid-template-columns: 1.02fr 0.98fr;
    gap: clamp(34px, 5vw, 56px);
    align-items: center;
}

@media (max-width: 1080px) {
    .v2-hero-grid {
        grid-template-columns: 1fr;
    }
}

/* Het beschikbaarheidsplaatje. Bewust geen animatie op de stip zelf via
   `animation` maar via een schaduw die pulseert — een bewegend element in de
   eerste seconde van de pagina trekt de aandacht weg van de kop. */
.v2-pill {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 8px 15px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--line);
    border-radius: var(--radius-full);
    font-family: var(--font-mono);
    /* 12px met normale regelhoogte geeft precies de 32px uit het ontwerp; met
       11,5px werd de pil 35 hoog. Nagemeten tegen het gerenderde ontwerp. */
    font-size: 12px;
    line-height: normal;
    /* 0.13em en kapitalen, zoals het sectielabel — nagemeten op het ontwerp:
       1,56px letterafstand, text-transform uppercase, en de accentkleur.
       Met 0.04em en gewone kapitalisatie las de pil als bijschrift in plaats
       van als markering. */
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--accent-ink);
}

.v2-pill-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 10px var(--accent);
}

/* De statuskleuren blijven uit de bestaande tokens komen: beschikbaarheid is
   inhoud, geen vormgeving, en die betekenis mag niet per thema verschuiven. */
.v2-pill-dot.availability-available {
    background: var(--color-status-available, #22c55e);
    box-shadow: 0 0 10px var(--color-status-available, #22c55e);
}

.v2-pill-dot.availability-limited {
    background: var(--color-status-limited, #f59e0b);
    box-shadow: 0 0 10px var(--color-status-limited, #f59e0b);
}

.v2-pill-dot.availability-unavailable {
    background: var(--color-status-unavailable, #ef4444);
    box-shadow: 0 0 10px var(--color-status-unavailable, #ef4444);
}

.v2-h1 {
    /* base.css centreert elke h1 — dat past bij de huidige opzet en niet bij
       deze. Expliciet linksuitlijnen in plaats van die regel weghalen: die
       geldt nog voor elke pagina die nog niet is overgezet. */
    text-align: left;
    margin: 26px 0 0;
    font-family: var(--font-kop);
    font-weight: 600;
    /* Vloeiend van 38 naar 66px. Een vaste maat zou op 1280px klein ogen en
       op 380px over drie regels breken. */
    font-size: clamp(38px, 6.4vw, 66px);
    line-height: 1.02;
    letter-spacing: -0.03em;
    color: var(--ink);
    /* Expliciet géén `balance` hier, in tegenstelling tot de andere koppen.

       Let op: weglaten is niet genoeg. `base.css` zet `text-wrap: balance` op
       de gedeelde koppenregel, dus zonder deze regel erft deze kop hem alsnog.

       De regelval van deze kop staat in de vertaling zelf: `welcome.content.title`
       draagt een `|` waar de regel hoort te breken, en het sjabloon maakt daar
       een `<br>` van. `balance` herberekent dat vervolgens over de ontstane
       regels, en dan vechten twee partijen om dezelfde beslissing.

       Op precies 1440 verloor de vertaling: de tekstkolom is daar 583,4px en
       "Bedrijfssoftware die" heeft er 608,0px nodig. Vierentwintig pixels
       tekort, dus brak `balance` hem alsnog — en met de harde `<br>` erachter
       werd het "Bedrijfssoftware / die / blijft werken". Een los woordje "die"
       in een kop van 66px, als eerste wat een bezoeker op een breed scherm
       ziet.

       Wie de regelval opschrijft, hoort hem ook te krijgen. */
    text-wrap: wrap;
}


.v2-lead {
    max-width: 520px;
    margin: 24px 0 0;
    font-size: 19.5px;
    line-height: 1.6;
    color: var(--ink-2);
    text-wrap: pretty;
}

.v2-cta-row {
    display: flex;
    align-items: center;
    gap: 13px;
    flex-wrap: wrap;
    margin-top: 36px;
}

.v2-btn {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    /* Padding in plaats van een vaste hoogte: het ontwerp gebruikt 16px boven
       en onder, wat op 16px tekst een knop van 51 hoog geeft. De
       minimumhoogte blijft als bodem voor het raakvlak. */
    min-height: 44px;
    padding: 16px 27px;
    font-size: 16px;
    /* `normal`, niet 1.2. Zonder eigen regelhoogte erft de knop die van de
       body (1,62) en wordt hij 58 hoog; met 1.2 wordt hij 51. Het ontwerp
       laat hem op `normal` staan en meet 53 — dat verschil van twee pixels
       liep door in elke knop op de site. */
    line-height: normal;
    font-weight: 600;
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: filter 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.v2-btn-primary {
    color: var(--on-accent);
    background-color: var(--accent);
    /* Geen rand: die telde 2px bij de hoogte op en het ontwerp heeft hem niet
       — een gevulde knop heeft geen omlijning nodig. */
    border: 0;
}

.v2-btn-primary:hover,
.v2-btn-primary:focus-visible {
    filter: brightness(1.08);
}

.v2-btn-ghost {
    /* 24 in plaats van 27 aan de zijkanten: het ontwerp geeft de spookknop
       smallere flanken dan de primaire, zodat die laatste optisch zwaarder
       weegt in de rij. */
    padding-inline: 24px;
    color: var(--ink);
    background-color: var(--glass-fill);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid var(--line);
}

.v2-btn-ghost:hover,
.v2-btn-ghost:focus-visible {
    background-color: var(--glass-fill-hi);
}

.v2-microcopy {
    margin: 14px 0 0;
    font-size: 13.5px;
    color: var(--ink-3);
}

.v2-hero-media {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-xl);
    overflow: hidden;
    border: 1px solid var(--line);
    background-color: var(--surface-2);
    box-shadow: var(--shadow-deep);
}

.v2-hero-media-glow {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 30% 25%, var(--accent-2), transparent 55%),
        radial-gradient(ellipse at 75% 70%, var(--accent), transparent 58%);
    opacity: 0.55;
}

/* Het raster erbovenop. Geeft het vlak schaal zonder dat er een beeld is —
   en maakt tegelijk zichtbaar dat het een plaatshouder is en geen mislukte
   afbeelding. */
.v2-hero-media-grid {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(var(--mesh-4) 1px, transparent 1px),
        linear-gradient(90deg, var(--mesh-4) 1px, transparent 1px);
    background-size: 44px 44px;
    opacity: 0.6;
}

/* Onder 1080 gaat het beeld onder de tekst, niet weg.

   Hier stond `display: none`. Daarmee zag niemand op tablet of telefoon het
   échappement — het duurste beeld van de site, meetkundig nagerekend, met vijf
   formaten ernaast — en bleef er een hero met een lege rechterhelft over. Wie
   op de telefoon binnenkomt kreeg zo de zwakste versie van de sterkste pagina.

   `.v2-hero-grid` klapt op dit breekpunt al naar één kolom, dus het beeld valt
   vanzelf onder de tekst; het hoeft alleen de volle breedte te krijgen. */
@media (max-width: 1080px) {
    .v2-hero-media {
        width: 100%;
        max-width: none;
        margin-top: 34px;
    }
}

/* --------------------------------------------------------------------------
   Secties

   Eén vorm die overal terugkeert: een bovenlijn met een klein monolabel, een
   kop, en rechts een doorverwijzing. Die herhaling is het ritme van de pagina
   — daarom staat het hier één keer en niet per sectie opnieuw.
   -------------------------------------------------------------------------- */

.v2-section {
    position: relative;
    z-index: 10;
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(72px, 9vw, 104px) clamp(20px, 4vw, 40px);
}

/* Een sectie met randen erboven en eronder, voor het ritme tussen blokken.

   Alléén randen, geen vulling: zo doet het ontwerp het bij diensten en
   veiligheid. Ik had er een gevulde band van gemaakt en hem bovendien op de
   verkeerde secties gezet — werkwijze en contact hebben er in het ontwerp
   geen.

   De randen lopen van schermrand tot schermrand terwijl de inhoud binnen de
   1280px blijft. Dat kan niet met een rand op het element zelf, want dat
   element ís de inhoudsbreedte. Vandaar een pseudo-element dat uitbreekt naar
   de volle vensterbreedte. */
.v2-section-band {
    position: relative;
}

.v2-section-band::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 100vw;
    transform: translateX(-50%);
    border-top: 1px solid var(--line-2);
    border-bottom: 1px solid var(--line-2);
    pointer-events: none;
    z-index: -1;
}

.v2-section-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 30px;
    flex-wrap: wrap;
    margin-bottom: 44px;
}

/* De kop krimpt, de link niet.

   Zonder dit klapt de link naar een eigen regel zodra de kop breed genoeg is,
   want `flex-wrap` kijkt naar de ínhoudsbreedte van elk item en een kop van 44px
   over 66 tekens meet ruim 1500px. In het ontwerp gebeurt dat niet, maar dat is
   geluk: de ontwerpkoppen zijn 45 en 32 tekens en passen nét binnen de 1200px.
   Onze vertaalsleutels zijn beschrijvender — "Software die werkt — gebouwd en
   onderhouden zonder bureau-overhead" — en dan zakte "Alle diensten →" eronder,
   op twee van de drie secties.

   `flex: 1 1 0` laat de kop krimpen en over twee regels lopen in plaats van de
   rij te forceren. Dat is wat het ontwerp zou doen bij dezelfde tekstlengte, en
   het houdt de link waar hij hoort: rechtsonder, op één lijn met de onderkant
   van de kop. */
.v2-section-head > :first-child {
    flex: 1 1 0;
    min-width: 0;
}

.v2-section-head > .v2-section-link {
    flex: 0 0 auto;
}

.v2-eyebrow {
    display: block;
    margin: 0 0 12px;
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    /* Accentkleur, niet grijs. Nagemeten tegen het gerenderde ontwerp: dat
       zet het sectielabel op --accTx. Grijs maakte het een bijschrift; oranje
       maakt het een markering. */
    color: var(--accent-ink);
}

.v2-h2 {
    /* Zelfde reden als bij .v2-h1: base.css centreert koppen. */
    text-align: left;
    margin: 0;
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: clamp(30px, 4.6vw, 44px);
    line-height: 1.06;
    letter-spacing: -0.025em;
    color: var(--ink);
    text-wrap: balance;
}

.v2-section-link {
    font-size: 15px;
    font-weight: 600;
    color: var(--accent-ink);
    text-decoration: none;
    white-space: nowrap;
}

.v2-section-link:hover,
.v2-section-link:focus-visible {
    text-decoration: underline;
}

.v2-section-intro {
    max-width: 62ch;
    margin: 0 0 40px;
    font-size: 17px;
    line-height: 1.65;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   Kaarten
   -------------------------------------------------------------------------- */

.v2-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

.v2-grid-2 {
    grid-template-columns: repeat(2, 1fr);
}

/* De kaart moet zijn rasterhokje vullen, niet zijn eigen inhoud.

   In het ontwerp zijn de kaarten zélf de rasteritems. Hier zit er een `<li>`
   tussen — nodig, want een lijst van diensten is een lijst — en dan rekt het
   raster wél die `<li>` uit maar niet de kaart erin. Gevolg: binnen één rij
   werd een kaart met vier regels tekst 239px en een met drie regels 215px, en
   dan staat de onderrand van elke rij te dansen.

   Dit trof `diensten` en `insights` op de homepage en dezelfde constructie op
   de teampagina. Vandaar hier, op het raster, en niet per sectie. */
.v2-grid > li,
.v2-grid-2 > li {
    display: flex;
}

.v2-grid > li > *,
.v2-grid-2 > li > * {
    flex: 1;
}

/* Een laatste kaart die alleen op zijn rij belandt, vult de rij.

   Het ontwerp rekent op zes diensten, er zijn er zeven — Visualisatie stond
   daardoor als enige onderaan met twee gaten ernaast, en dat leest als een
   fout in plaats van als een dienst.

   `:last-child:nth-child(3n+1)` betekent letterlijk: de laatste, en hij begint
   een nieuwe rij. Wordt er een achtste dienst toegevoegd, dan klopt de regel
   vanzelf niet meer en verdwijnt hij — precies goed, want dan is er ook geen
   gat meer. Bij twee kolommen geldt dezelfde redenering met 2n+1. */
.v2-grid > li:last-child:nth-child(3n + 1) {
    grid-column: 1 / -1;
}

@media (max-width: 1080px) {
    .v2-grid > li:last-child:nth-child(3n + 1) {
        grid-column: auto;
    }

    .v2-grid > li:last-child:nth-child(2n + 1) {
        grid-column: 1 / -1;
    }
}

@media (max-width: 1080px) {
    .v2-grid,
    .v2-grid-2 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 680px) {
    .v2-grid,
    .v2-grid-2 {
        grid-template-columns: 1fr;
    }
}

.v2-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 28px 26px 30px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    transition: border-color 0.25s ease, transform 0.25s ease;
}

a.v2-card:hover,
a.v2-card:focus-visible {
    border-color: var(--accent);
    transform: translateY(-3px);
}

/* --- De sectorkaart is paars, niet oranje ---

   Het ontwerp werkt met twee accentfamilies: oranje voor wat wij doen
   (diensten, oproepen tot actie) en paars voor waar we het doen (sectoren).
   Dat is geen versiering maar een leeswijzer — je ziet aan de kleur of een
   kaart een dienst of een sector is, nog voor je de tekst leest.

   De sectorkaarten waren gebouwd door de dienstkaart te hergebruiken, en
   daarmee viel dat onderscheid weg: beide reeksen stonden in hetzelfde grijs
   met dezelfde oranje zweefkleur. Het ontwerp geeft de sector bovendien een
   iets kleinere titel (19px tegen 22px), want daar staat een sectornaam en
   geen dienstnaam. */
.v2-card-sector .v2-card-num {
    color: var(--accent-2-ink);
}

.v2-card-sector .v2-card-title {
    font-size: 19px;
}

a.v2-card-sector:hover,
a.v2-card-sector:focus-visible {
    border-color: var(--accent-2);
}

/* Hetzelfde voorbehoud als elders in dit project: wie beweging heeft
   uitgezet, krijgt ook geen verschuiving bij het zweven. */
@media (prefers-reduced-motion: reduce) {
    .v2-card,
    a.v2-card:hover,
    a.v2-card:focus-visible {
        transition: none;
        transform: none;
    }
}

.v2-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.v2-card-title {
    margin: 0;
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 22px;
    line-height: 1.2;
    /* base.css geeft elke kop -0.02em mee; het ontwerp doet dat alleen op h1
       en h2, niet op kaartkoppen. Op 22px is dat zichtbaar als te krappe
       letters. */
    letter-spacing: normal;
    color: var(--ink);
    text-align: left;
}

.v2-card-num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    color: var(--ink-3);
    flex: none;
}

.v2-card-body {
    margin: 0 0 20px;
    font-size: 14.5px;
    line-height: 1.62;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* Duwt de voet naar beneden zodat kaarten van ongelijke lengte toch één lijn
   houden — anders zweeft het label van de korte kaart in het midden. */
.v2-card-foot {
    margin-top: auto;
    display: flex;
    align-items: center;
    /* 7px komt uit het ontwerp, niet uit de spatiëringsschaal. */
    gap: 7px;
    flex-wrap: wrap;
}

.v2-tag {
    display: inline-flex;
    align-items: center;
    padding: 5px 9px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
}

/* Lijsten die als raster dienen dragen geen opsommingstekens. Apart van
   .v2-grid, want een raster is niet altijd een lijst. */
.v2-bare {
    list-style: none;
    margin: 0;
    padding: 0;
}


@media (prefers-color-scheme: light) {
    :root:not([data-theme]) .v2-logo-slot img {
        --logo-filter: none;
    }
}


@media (max-width: 1080px) {
    .v2-steps {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 680px) {
    .v2-steps {
        grid-template-columns: 1fr;
    }
}


@media (max-width: 680px) {
    .v2-ai-list {
        grid-template-columns: 1fr;
    }
}


/* --------------------------------------------------------------------------
   Veelgestelde vragen

   Met <details>: werkt zonder JavaScript en is van zichzelf toegankelijk.
   Meerdere tegelijk open mogen is hier een voordeel — wie drie vragen heeft,
   wil ze naast elkaar kunnen lezen in plaats van heen en weer klikken.
   -------------------------------------------------------------------------- */

.v2-faq {
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-width: 76ch;
}


@media (max-width: 1080px) {
    .v2-entity {
        grid-template-columns: 1fr;
    }
}


.v2-techs {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 44px;
}

.v2-techs a {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;
    padding: 0 16px;
    font-size: 14px;
    color: var(--ink-2);
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    text-decoration: none;
    transition: color 0.18s ease, border-color 0.18s ease;
}

.v2-techs a:hover,
.v2-techs a:focus-visible {
    color: var(--ink);
    border-color: var(--line);
}

/* Citaten. Geen aanhalingstekens in de tekst zelf: die staan in de opmaak,
   zodat een quote die al met een aanhalingsteken begint er geen twee krijgt. */
.v2-quote {
    margin: 0;
}

/* --------------------------------------------------------------------------
   Contactformulier

   Bewust alleen de vormgeving overgezet en niet de markup. Dit formulier
   draagt CSRF, Turnstile, een honeypot, per-veld foutmeldingen met aria-live
   en een reeks id's waar contact.js op vertrouwt. Dat contract herbouwen om
   klassenamen levert niets op en kan stil breken — en een contactformulier
   dat stil breekt, kost aanvragen zonder dat iemand het merkt.

   Daarom hangen deze regels aan de bestaande Bootstrap-klassen.
   -------------------------------------------------------------------------- */

.custom-contact-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(56px, 7vw, 88px) clamp(20px, 4vw, 40px);
}

.custom-contact-container .card {
    max-width: 46rem;
    margin: 0 auto;
    background-color: var(--glass-fill);
    backdrop-filter: blur(26px) saturate(170%);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
}

.custom-contact-container .card-body {
    padding: clamp(26px, 3.4vw, 36px);
    /* components.css legt hier een warm verloop overheen; dat vulde de hele
       kaart wit terwijl de kaart zelf al glas was. `background` en niet
       `background-color`, want het is een gradient en die zit in
       background-image — alleen de kleur overschrijven laat hem staan. */
    background: transparent;
}

.custom-contact-container .form-label {
    display: block;
    margin-bottom: 7px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-2);
}

.custom-contact-container .form-control,
.custom-contact-container .form-select {
    width: 100%;
    /* 44px hoog: een invoerveld is een raakvlak. */
    min-height: 46px;
    padding: 12px 14px;
    font-family: inherit;
    font-size: 15.5px;
    color: var(--ink);
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    transition: border-color 0.18s ease, background-color 0.18s ease;
}

.custom-contact-container textarea.form-control {
    min-height: 8rem;
    resize: vertical;
}

.custom-contact-container .form-control::placeholder {
    color: var(--ink-3);
}

.custom-contact-container .form-control:focus,
.custom-contact-container .form-select:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
    background-color: var(--glass-fill-hi);
}

/* De foutkleur komt niet uit het thema: een fout hoort in beide thema's
   dezelfde betekenis te dragen, en betekenis mag niet meebewegen met smaak. */
.custom-contact-container .form-control.is-invalid,
.custom-contact-container .form-select.is-invalid {
    border-color: #ef4444;
}

.custom-contact-container .invalid-feedback {
    display: block;
    min-height: 1.2em;
    margin-top: 6px;
    font-size: 13px;
    color: #f87171;
}

.custom-contact-container .btn,
.custom-contact-container button[type='submit'] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    min-height: 52px;
    padding: 0 27px;
    font-size: 16px;
    font-weight: 600;
    color: var(--on-accent);
    background-color: var(--accent);
    background-image: none;
    border: 1px solid var(--accent);
    border-radius: var(--radius-md);
    cursor: pointer;
}

.custom-contact-container button[type='submit']:hover:not(:disabled) {
    filter: brightness(1.08);
}

.custom-contact-container button[type='submit']:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Voettekst

   Ook hier de markup ongemoeid: er zit een terug-naar-boven-knop in, een
   voorwaardelijke bloglink en de sociale verwijzingen met rel-attributen die
   niet per ongeluk moeten sneuvelen.
   -------------------------------------------------------------------------- */

.custom-footer {
    background-color: var(--surface-2);
    background-image: none;
    border-top: 1px solid var(--line-2);
    color: var(--ink-2);
}

.custom-footer a {
    color: var(--ink-2);
    text-decoration: none;
}

.custom-footer a:hover,
.custom-footer a:focus-visible {
    color: var(--ink);
    text-decoration: underline;
}

.custom-footer h3,
.custom-footer .footer-heading {
    color: var(--ink);
}

.footer-brand-mark {
    font-family: var(--font-kop);
    font-weight: 600;
    color: var(--ink);
}

.footer-brand-accent {
    color: var(--accent-ink);
}

.footer-brand-tagline {
    color: var(--ink-3);
}

.footer-cta {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    min-height: 48px;
    padding: 0 22px;
    font-weight: 600;
    color: var(--on-accent) !important;
    background-color: var(--accent);
    border-radius: var(--radius-md);
}

.footer-cta:hover,
.footer-cta:focus-visible {
    filter: brightness(1.08);
    text-decoration: none !important;
}

/* De knop draagt icoon én tekst; die tekst is nuttig, dus hij mag breed zijn.
   Een vaste 44 bij 44 perste het label eruit. */
.back-to-top {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    min-height: 44px;
    padding: 0 16px;
    font-size: 13.5px;
    color: var(--ink-2);
    background-color: var(--glass-fill);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

/* De golfvormige scheiding hoort bij de vorige vormgeving: die sneed een
   lichte pagina van een donkere voet. Nu zijn beide donker en tekent hij een
   rand die er niet is. */
.footer-svg-divider {
    display: none;
}

/* De losse tekst in het formulier — akkoordregel, privacynotitie, hulptekst.
   Die kleuren komen uit base.css en zijn voor een lichte ondergrond gemaakt;
   op glas staat donkergrijs op donkergrijs. */
.custom-contact-container,
.custom-contact-container p,
.custom-contact-container label,
.custom-contact-container .form-check-label,
.custom-contact-container .small,
.custom-contact-container small {
    color: var(--ink-2);
}

.custom-contact-container a {
    color: var(--accent-ink);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Het aankruisvakje zelf. Zonder accent-color tekent de browser hem in zijn
   eigen blauw, wat naast het oranje als een fout leest. */
.custom-contact-container input[type='checkbox'] {
    width: 20px;
    height: 20px;
    accent-color: var(--accent);
}

/* De bouwregel onderin. Erfde de oude linkkleur, die op deze ondergrond
   paars oplichtte alsof het een verwijzing was. */
.custom-footer .version,
.custom-footer .footer-built-with {
    color: var(--ink-3);
}

/* ==========================================================================
   Overgangslaag: de bestaande bouwstenen in de nieuwe kleuren

   De ruim twintig resterende sjablonen — diensten, sectoren, klanten,
   use-cases, initiatieven, blog, juridisch — delen één woordenschat:
   `.page-header`, `.custom-container`, `.card`, `.prose`, `.sidebar-heading`,
   `.accordion`, `.breadcrumb`. Die woordenschat hier omzetten maakt alle
   pagina's in één keer samenhangend, zonder markup aan te raken.

   Dat is geen bezuiniging maar de veiligere weg: in die sjablonen zitten
   structuurdata, kruimelpaden, zijbalken met relatiedata en de
   laatst-bijgewerkt-badge. Twintig bestanden herschrijven om klassenamen zou
   dat allemaal in beweging brengen voor precies nul zichtbare winst.

   Waar het ontwerp structureel iets anders doet dan de huidige opbouw, komt
   dat per pagina alsnog aan de beurt — maar dan met een reden.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Paginakoppen
   -------------------------------------------------------------------------- */

.page-header,
.welcome-page-header {
    position: relative;
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(40px, 5vw, 64px) clamp(20px, 4vw, 40px) clamp(28px, 4vw, 44px);
    background: none;
    color: var(--ink);
}

.page-header .header-text,
.header-text {
    text-align: left;
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: clamp(32px, 5vw, 52px);
    line-height: 1.05;
    letter-spacing: -0.025em;
    color: var(--ink);
}

.page-payoff {
    max-width: 62ch;
    font-size: 18px;
    line-height: 1.6;
    color: var(--ink-2);
}

/* --------------------------------------------------------------------------
   Containers en secties
   -------------------------------------------------------------------------- */

.custom-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(48px, 6vw, 80px) clamp(20px, 4vw, 40px);
    background: none;
}

/* De oude achtergrondvarianten. Die tekenden lichte banen op een lichte
   pagina; hier worden het glasbanen op een donkere. */
.bg-light,
.bg-surface-alt,
.bg-surface-cool {
    background-color: var(--glass-fill-2) !important;
    background-image: none !important;
    border-top: 1px solid var(--line-2);
    border-bottom: 1px solid var(--line-2);
}

/* --------------------------------------------------------------------------
   Kaarten uit de oude opbouw
   -------------------------------------------------------------------------- */

.card {
    background-color: var(--glass-fill);
    background-image: none;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    color: var(--ink-2);
    box-shadow: none;
}

.card-header {
    background: transparent;
    border-bottom: 1px solid var(--line-2);
    color: var(--ink);
}

.card-body {
    background: transparent;
    color: var(--ink-2);
}

.card-footer {
    background: transparent;
    border-top: 1px solid var(--line-2);
}

.card h2,
.card h3,
.card h4,
.card .card-title {
    color: var(--ink);
    text-align: left;
}

/* --------------------------------------------------------------------------
   Lopende tekst
   -------------------------------------------------------------------------- */

.prose,
.service-content,
.section-intro,
.entity-intro {
    color: var(--ink-2);
}

.prose h2,
.prose h3,
.prose h4,
.service-content h2,
.service-content h3,
.section-intro h2 {
    color: var(--ink);
    text-align: left;
    font-family: var(--font-kop);
}

/* De uitzonderingslijst in base.css zet links op --color-secondary omdat de
   globale linkkleur op wit onder de 4,5:1 zakt. Op deze ondergrond geldt dat
   andersom, dus die lijst wordt hier overschreven — met een kleur die in
   beide thema's gemeten is. */
.prose a,
.service-content a,
.section-intro a,
.entity-intro a,
.card-body a:not(.btn),
.accordion-body a {
    color: var(--accent-ink);
}

/* --------------------------------------------------------------------------
   Zijbalken, kruimelpad, badge
   -------------------------------------------------------------------------- */

.sidebar-heading {
    color: var(--ink);
    font-family: var(--font-kop);
    text-align: left;
}

.breadcrumb,
.breadcrumb a,
.breadcrumb-item,
.breadcrumb-item a {
    color: var(--ink-3);
}

.breadcrumb a:hover,
.breadcrumb-item a:hover {
    color: var(--ink);
}

.last-updated,
.text-muted,
.stat-label,
.small {
    color: var(--ink-3) !important;
}

/* --------------------------------------------------------------------------
   Uitklapvragen op detailpagina's

   Die draaien nog op Bootstrap; de homepage gebruikt <details>. Beide in de
   lucht houden is de prijs van stapsgewijs overzetten — zie de
   afwijkingenlijst.
   -------------------------------------------------------------------------- */

.accordion,
.accordion-item {
    background-color: transparent;
    border-color: var(--line-2);
}

.accordion-button {
    background-color: transparent;
    color: var(--ink);
    font-family: var(--font-kop);
    font-weight: 600;
    box-shadow: none;
}

.accordion-button:not(.collapsed) {
    background-color: var(--glass-fill-2);
    color: var(--accent-ink);
    box-shadow: none;
}

.accordion-body {
    background-color: transparent;
    color: var(--ink-2);
}

/* --------------------------------------------------------------------------
   Knoppen
   -------------------------------------------------------------------------- */

.btn-primary,
.btn.btn-primary {
    color: var(--on-accent);
    background-color: var(--accent);
    background-image: none;
    border-color: var(--accent);
    border-radius: var(--radius-md);
}

.btn-primary:hover,
.btn.btn-primary:hover {
    filter: brightness(1.08);
    background-color: var(--accent);
    border-color: var(--accent);
}

.btn:not(.btn-primary):not(.custom-primary-btn) {
    color: var(--ink);
    background-color: var(--glass-fill);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
}

.btn:not(.btn-primary):not(.custom-primary-btn):hover {
    background-color: var(--glass-fill-hi);
    color: var(--ink);
}

/* --------------------------------------------------------------------------
   Beeld op detailpagina's
   -------------------------------------------------------------------------- */

.figure-img,
.sector-card-image,
.blog-hero-image img,
.service-illustration {
    border-radius: var(--radius-lg);
    border: 1px solid var(--line-2);
}

/* De golvende scheidingen hoorden bij het snijden van lichte en donkere
   vlakken. Alles is nu donker; ze tekenen een rand die er niet is. */
.services-svg-divider,
.client-svg-divider {
    display: none;
}

/* --------------------------------------------------------------------------
   Paginakoppen per paginasoort

   Elke paginasoort heeft zijn eigen kopklasse met een eigen paars verloop en
   een achtergrondafbeelding. Die zijn gemaakt om boven een lichte pagina te
   zitten; op deze ondergrond zijn het losse paarse blokken.

   Allemaal in één regel: het onderscheid tussen die tien koppen zat in de
   achtergrond, en die vervalt hier.
   -------------------------------------------------------------------------- */

.about-page-header,
.case-page-header,
.clients-page-header,
.contact-page-header,
.initiatives-page-header,
.sectors-page-header,
.services-page-header,
.usecases-page-header,
.blog-page-header,
.legal-page-header {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(40px, 5vw, 68px) clamp(20px, 4vw, 40px) clamp(24px, 3vw, 36px);
    background: none !important;
    color: var(--ink);
    text-align: left;
    min-height: 0;
}

/* De koppen stonden gecentreerd met de tekst; die uitlijning hoort bij de
   oude opzet. */
.about-page-header.text-center,
.case-page-header.text-center,
.clients-page-header.text-center,
.contact-page-header.text-center,
.initiatives-page-header.text-center,
.sectors-page-header.text-center,
.services-page-header.text-center,
.usecases-page-header.text-center {
    text-align: left;
}

/* --------------------------------------------------------------------------
   Losse blokken uit de oude opbouw
   -------------------------------------------------------------------------- */

/* De definitie-alinea bovenaan een dienstpagina. Kreeg zijn kleur uit
   --color-text, dat voor een witte ondergrond is gemaakt. */
.service-definition,
.lead,
blockquote {
    color: var(--ink-2);
}

/* Het afsluitende contactblok op detailpagina's. Wit vlak, want het was
   bedoeld als lichte kaart op een lichte pagina. */
.meta-container {
    background-color: var(--glass-fill) !important;
    background-image: none !important;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    color: var(--ink-2);
}

.meta-container h2,
.meta-container h3,
.meta-container p {
    color: var(--ink);
}

/* Zijbalkkaders en overige vlakken die op wit rekenden. */
.sidebar,
.sidebar-block,
.ideal-for,
.geo-statement,
.testimonial-card {
    background-color: var(--glass-fill-2);
    background-image: none;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-lg);
    color: var(--ink-2);
}

/* De koppen dragen hun paars niet zelf maar via ::before (een verloop) en
   ::after (een ruispatroon). Die overlays waren nodig om witte tekst leesbaar
   te houden op een foto; er is nu geen foto meer, dus ze leggen alleen een
   paars vlak op een donkere pagina.

   Dit kostte drie rondes omdat een scan over elementen pseudo-elementen niet
   ziet — het element zelf was al schoon. */
.about-page-header::before,
.about-page-header::after,
.case-page-header::before,
.case-page-header::after,
.clients-page-header::before,
.clients-page-header::after,
.contact-page-header::before,
.contact-page-header::after,
.initiatives-page-header::before,
.initiatives-page-header::after,
.sectors-page-header::before,
.sectors-page-header::after,
.services-page-header::before,
.services-page-header::after,
.welcome-page-header::before,
.welcome-page-header::after {
    display: none !important;
}

/* --------------------------------------------------------------------------
   Tekstkleuren die zich niet lieten overschrijven

   De overgangslaag hierboven heeft dezelfde specificiteit als de regels die
   hij vervangt, en verliest dan van elke selector met één klasse extra. In
   plaats van overal !important te strooien krijgt deze groep één niveau meer
   gewicht via `.v2` op de body — dat is precies genoeg en blijft leesbaar.

   Tijdelijk: zodra een sjabloon zelf is overgezet, verdwijnt zijn regel hier.
   -------------------------------------------------------------------------- */

.v2 .lead,
.v2 .service-definition,
.v2 .prose,
.v2 .prose p,
.v2 .prose li,
.v2 .service-content,
.v2 .service-content p,
.v2 .service-content li,
.v2 .section-intro p,
.v2 .entity-intro,
.v2 .card-body p,
.v2 .card-body li,
.v2 blockquote {
    color: var(--ink-2);
}

.v2 .prose h1,
.v2 .prose h2,
.v2 .prose h3,
.v2 .prose h4,
.v2 .service-content h2,
.v2 .service-content h3,
.v2 .service-content h4,
.v2 .card-body h2,
.v2 .card-body h3,
.v2 .card-body h4,
.v2 .sidebar-heading,
.v2 .header-text,
.v2 h1,
.v2 h2,
.v2 h3,
.v2 h4 {
    color: var(--ink);
}

/* Vet gedrukte tekst binnen lopende tekst mag iets sterker staan dan de
   alinea eromheen — anders valt de nadruk weg die de schrijver bedoelde. */
.v2 .prose strong,
.v2 .service-content strong,
.v2 .card-body strong {
    color: var(--ink);
}

/* Het afsluitende contactblok. De kop erin viel weg omdat hij zijn kleur uit
   een eigen regel haalt, niet uit de erfelijke lijn. */
.v2 .meta-container h2,
.v2 .meta-container h3,
.v2 .meta-container .header-text {
    color: var(--ink);
}

.v2 .meta-container p,
.v2 .meta-container .small {
    color: var(--ink-2);
}

/* --------------------------------------------------------------------------
   Uitklapmenu's: openen op zweven én op focus

   Het ontwerp opent op `mouseenter` en sluit op `mouseleave`, en doet
   hetzelfde op `focus` en `blur`. Die tweede helft is niet optioneel: wie met
   het toetsenbord navigeert heeft geen muisaanwijzer, en een menu dat alleen
   op zweven opent is voor hen dicht.

   Zweven doet de CSS, focus doet de CSS ook (:focus-within). JavaScript hoeft
   daardoor alleen nog Escape en de pijltjes af te handelen — en op een
   aanraakscherm, waar zweven niet bestaat, de klik.
   -------------------------------------------------------------------------- */

/* Focus staat BUITEN de mediaquery. Toetsenbordbediening mag niet afhangen
   van de aanwezigheid van een muis — dat was de fout in de eerste versie: op
   een apparaat zonder muisaanwijzer verdween daarmee ook het openen op focus. */
.v2-drop[data-hoverable]:focus-within > .v2-drop-menu {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

.v2-drop[data-hoverable]:focus-within > .v2-nav-link {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

.v2-drop[data-hoverable]:focus-within .v2-caret {
    transform: rotate(180deg);
}

/* Zweven alleen waar het bestaat. Op een aanraakscherm zou `:hover` blijven
   plakken na een tik, en dan staat het menu open tot je ergens anders tikt. */
@media (hover: hover) and (pointer: fine) {
    .v2-drop[data-hoverable]:hover > .v2-drop-menu {
        visibility: visible;
        opacity: 1;
        transform: translateY(0);
    }

    .v2-drop[data-hoverable]:hover > .v2-nav-link {
        color: var(--ink);
        background-color: var(--glass-fill-hi);
    }

    .v2-drop[data-hoverable]:hover .v2-caret {
        transform: rotate(180deg);
    }
}

/* Op een aanraakscherm bestaat zweven niet; daar blijft de klik het middel.
   `data-open` komt dan van v2-nav.js. */
.v2-drop[data-open='true'] > .v2-drop-menu {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
}

/* Een onzichtbare brug tussen knop en menu. Zonder die 10px valt de muis in
   het gat en klapt het menu dicht terwijl je ernaartoe beweegt — de klassieke
   reden dat zweefmenu's als kapot voelen. */
.v2-drop[data-hoverable]::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 12px;
}

/* Meerdere groepen naast elkaar: initiatieven heeft er twee (producten en
   Labs), en dat onderscheid is de reden dat het menu bestaat. */
.v2-drop-menu {
    display: flex;
    gap: 22px;
    padding: 16px 14px 12px;
    min-width: max-content;
}

.v2-drop-group {
    min-width: 12rem;
}

.v2-drop-head {
    display: block;
    margin: 0 0 8px;
    padding: 0 12px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
    text-decoration: none;
}

.v2-drop-head:hover {
    color: var(--accent-ink);
}

/* --------------------------------------------------------------------------
   Hero: metaregel en beeldchip
   -------------------------------------------------------------------------- */

.v2-hero-meta {
    display: flex;
    align-items: center;
    /* 14 tussenruimte, 12,5px en geen extra letterafstand — nagemeten op het
       ontwerp. Met 11,5px en 0.06em paste de regel niet meer op één lijn en
       brak hij op 1440 breed in tweeën. */
    gap: 14px;
    flex-wrap: wrap;
    margin: 30px 0 0;
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: normal;
    letter-spacing: normal;
    color: var(--ink-3);
}

/* Scheidingstekens uit de opmaak. Bij afbreken blijft er zo geen punt aan het
   regeleinde hangen, en een schermlezer leest ze niet voor. */
.v2-hero-meta li + li::before {
    content: '·';
    margin-right: 10px;
    opacity: 0.4;
}

.v2-hero-meta li {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.v2-status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    /* Statuskleuren blijven uit de bestaande tokens komen: beschikbaarheid is
       inhoud, en die betekenis mag niet per thema verschuiven. */
    background: var(--color-status-available, #22c55e);
}

.v2-status-dot.availability-limited {
    background: var(--color-status-limited, #f59e0b);
}

.v2-status-dot.availability-unavailable {
    background: var(--color-status-unavailable, #ef4444);
}

/* De chip die zegt wat het beeldvlak is. Eerlijk over een plaatshouder is
   beter dan een plaatshouder die zich voordoet als beeld. */
.v2-hero-chip {
    position: absolute;
    top: 16px;
    left: 18px;
    display: inline-flex;
    align-items: center;
    padding: 7px 11px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* --------------------------------------------------------------------------
   Gewerkt voor — de doorlopende band

   Twee identieke rijen die samen 200% breed zijn en over -50% schuiven: op het
   moment dat de eerste rij eruit loopt, staat de tweede precies op zijn plek.
   Daardoor is er geen sprong bij het herhalen.
   -------------------------------------------------------------------------- */

.v2-marquee-band {
    position: relative;
    z-index: 10;
    border-top: 1px solid var(--line-2);
    border-bottom: 1px solid var(--line-2);
    background-color: var(--glass-fill-2);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    overflow: hidden;
}

.v2-marquee-wrap {
    display: flex;
    align-items: center;
    gap: 28px;
    max-width: 1280px;
    margin: 0 auto;
    padding: 20px clamp(20px, 4vw, 40px);
}

.v2-marquee-label {
    flex: none;
    margin: 0;
}

.v2-marquee {
    position: relative;
    display: flex;
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

/*
   De vervaagde randen zaten hier als `mask-image` op dezelfde laag die de
   lopende rij bevat. In Chromium werkt dat; in Safari herstart een animatie
   binnen een gemaskeerde laag zodra de speelstaat wisselt — dus sprong de
   band bij zweven terug naar het begin in plaats van stil te staan. Het
   gedrag was daardoor alleen zichtbaar in Safari, en niet in de meting.

   Twee verlopen over de randen doen hetzelfde zonder die bijwerking. Ze
   liggen boven de rij en vangen geen muis, zodat zweven blijft werken.
*/
.v2-marquee::before,
.v2-marquee::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    width: 6%;
    z-index: 1;
    pointer-events: none;
}

.v2-marquee::before {
    left: 0;
    background: linear-gradient(90deg, color-mix(in srgb, #fff 3%, var(--surface)), transparent);
}

.v2-marquee::after {
    right: 0;
    background: linear-gradient(270deg, color-mix(in srgb, #fff 3%, var(--surface)), transparent);
}

.v2-marquee-row {
    display: flex;
    align-items: center;
    gap: 40px;
    flex: none;
    padding-right: 40px;
    white-space: nowrap;
    /* De duur hoort bij de lengte van de rij, niet bij een vast getal. Het
       ontwerp loopt 34s over zijn eigen rij, wat neerkomt op ongeveer 45 pixels
       per seconde. Onze rij draagt dertien namen twee keer en is 3912 breed;
       met 34s zou de band 2,6 keer zo snel lopen als bedoeld. 87s houdt
       dezelfde snelheid aan. Verandert de lijst, dan verandert dit getal mee. */
    animation: v2-marquee 87s linear infinite;
}

.v2-marquee-row a {
    font-family: var(--font-kop);
    font-size: 19px;
    font-weight: 600;
    color: var(--ink-3);
    text-decoration: none;
    transition: color 0.18s ease;
}

.v2-marquee-row a:hover,
.v2-marquee-row a:focus-visible {
    color: var(--ink);
}

@keyframes v2-marquee {
    from { transform: translateX(0); }
    to { transform: translateX(-100%); }
}

/* Stilstaan bij zweven: wie een naam wil lezen of aanklikken, moet dat kunnen
   zonder het te moeten timen. */
.v2-marquee:hover .v2-marquee-row,
.v2-marquee:focus-within .v2-marquee-row {
    animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
    .v2-marquee-row {
        animation: none;
    }

    /* Zonder beweging is de tweede rij dubbele inhoud; die verdwijnt, en de
       eerste mag dan gewoon scrollen op aanraking. */
    .v2-marquee-row[aria-hidden='true'] {
        display: none;
    }

    .v2-marquee {
        overflow-x: auto;
    }
}

@media (max-width: 680px) {
    .v2-marquee-wrap {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    /* In een kolom begrenst `flex: 1` de breedte niet meer — die stuurt dan de
       hoogte. Zonder deze regel groeide het venster mee met zijn inhoud
       (2719px in een omhulsel van 680) en werd het pas een stuk hogerop
       afgeknipt, met de vervaagde randen op de verkeerde plek. */
    .v2-marquee {
        width: 100%;
    }

    .v2-marquee-row a {
        font-size: 16px;
    }
}

/* --------------------------------------------------------------------------
   Werkwijze-demo

   Een terminalvenster met drie tabbladen. De code is geen decoratie: hij laat
   zien wat er gebeurt, en dat overtuigt waar een opsomming dat niet doet.
   -------------------------------------------------------------------------- */

.v2-demo {
    margin: 0 0 44px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(26px) saturate(180%);
    -webkit-backdrop-filter: blur(26px) saturate(180%);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
    overflow: hidden;
}

.v2-demo-tabs {
    display: flex;
    gap: 2px;
    padding: 10px 10px 0;
    border-bottom: 1px solid var(--line-2);
}

.v2-demo-tab {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* 44px raakvlak, ook al oogt een tabblad kleiner. */
    min-height: 44px;
    padding: 0 16px;
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.06em;
    color: var(--ink-3);
    background: transparent;
    border: 0;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    cursor: pointer;
    transition: color 0.18s ease, background-color 0.18s ease;
}

.v2-demo-tab:hover {
    color: var(--ink-2);
    background-color: var(--glass-fill-2);
}

/* Het geselecteerde tabblad draagt zijn toestand in aria-selected, en de
   opmaak leest die uit. Eén bron voor wat er open staat, geen aparte klasse
   die ernaast kan gaan lopen. */
.v2-demo-tab[aria-selected='true'] {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
}

.v2-demo-tab-num {
    color: var(--accent-ink);
}

.v2-demo-panel {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    gap: 0;
}

@media (max-width: 1080px) {
    .v2-demo-panel {
        grid-template-columns: 1fr;
    }
}

.v2-demo-code {
    margin: 0;
    padding: 24px 26px;
    font-family: var(--font-mono);
    font-size: 13px;
    line-height: 1.75;
    /* Vaste hoogte over de drie tabbladen, anders springt de pagina bij het
       wisselen — en dan verlies je je plek in de tekst eronder. */
    min-height: 17rem;
    overflow-x: auto;
    background-color: var(--surface-2);
    border-right: 1px solid var(--line-2);
}

@media (max-width: 1080px) {
    .v2-demo-code {
        border-right: 0;
        border-bottom: 1px solid var(--line-2);
        min-height: 0;
    }
}

.v2-code-line {
    display: block;
    white-space: pre;
}

.v2-code-line.is-dim { color: var(--ink-3); }
.v2-code-line.is-body { color: var(--ink-2); }
.v2-code-line.is-strong { color: var(--ink); }
.v2-code-line.is-accent { color: var(--accent-ink); }
.v2-code-line.is-violet { color: var(--accent-2-ink); }
.v2-code-line.is-ok { color: var(--ok); }

.v2-demo-aside {
    padding: 26px 28px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.v2-demo-aside .v2-card-body {
    margin: 12px 0 0;
}

/* --------------------------------------------------------------------------
   Veiligheid: twee kolommen met een gelaagd vlak
   -------------------------------------------------------------------------- */

.v2-split {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: clamp(34px, 5vw, 60px);
    align-items: center;
}

@media (max-width: 1080px) {
    .v2-split {
        grid-template-columns: 1fr;
    }
}

.v2-checks {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0 0 24px;
}

.v2-checks li {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    font-size: 15.5px;
    line-height: 1.55;
    color: var(--ink-2);
}

.v2-check {
    flex: none;
    margin-top: 1px;
    color: var(--ok);
    font-weight: 700;
}

/* Het gelaagde vlak. In het ontwerp is dit een render-slot voor eigen
   3D-beeld; tot dat er is dragen vier gestapelde vlakken de boodschap. De
   stapeling is de boodschap: beveiliging zit in elke laag, niet in een schil
   eromheen. */
.v2-layers {
    position: relative;
    /* Zonder perspectief blijft de kanteling een platte isometrie: de lagen
       liggen dan even groot achter elkaar in plaats van naar achteren weg te
       lopen. 1300px komt uit het ontwerp. */
    perspective: 1300px;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--surface-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--shadow-deep);
}

.v2-layers::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 30% 20%, var(--accent-2), transparent 58%),
        radial-gradient(ellipse at 72% 78%, var(--accent), transparent 60%);
    opacity: 0.32;
}

/* De isometrische stapel.

   Dit is wat het ontwerp bedoelt met "gelaagde beveiliging": vier vlakken die
   in de diepte achter elkaar liggen, niet vier balken onder elkaar. De
   waarden komen letterlijk uit het ontwerp — perspectief 1300px, de stapel
   gekanteld met rotateX(54deg) rotateZ(-32deg), en elk vlak op zijn eigen
   translateZ.

   De labels worden teruggedraaid met precies de omgekeerde hoeken. Zonder dat
   staat de tekst mee gekanteld en is hij onleesbaar. */
.v2-layers-stack {
    position: absolute;
    /* Iets verder naar binnen dan het ontwerp (12%): onze labels staan links
       op elke laag, en na het terugdraaien steken ze linksboven uit. Met 18%
       vallen ze binnen het vlak zonder dat de stapel kleiner oogt. */
    top: 16%;
    left: 20%;
    width: 68%;
    height: 68%;
    transform-style: preserve-3d;
    transform: rotateX(54deg) rotateZ(-32deg);
}

.v2-layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 100%;
    display: flex;
    align-items: flex-end;
    padding: 0;
    border-radius: var(--radius-lg);
    transform-style: preserve-3d;
    background-color: var(--glass-fill-hi);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--line);
}

/* Van boven naar onder: Applicatie ligt het hoogst, Data het diepst. Dat is
   de boodschap — de gegevens liggen onderop en alles erboven beschermt ze.

   Elke laag heeft een eigen kleur, en dat is geen versiering. Ze stonden alle
   vier op hetzelfde glas, en dan zijn vier vlakken die veertien pixels naar
   elkaar toe bewegen domweg niet te zien: er is niets om de beweging aan af te
   lezen. De parallax wérkte dus wel, hij was alleen onzichtbaar. De kleuren
   komen uit het ontwerp en stonden hier al als `--mesh-1` tot en met
   `--mesh-4`; ze waren alleen nooit op de lagen gezet.

   De volgorde loopt tegengesteld aan de nummering: het ontwerp geeft de
   bovenste laag `--l4` (wit) en de onderste `--l1` (paars), zodat de data
   onderop het zwaarst gekleurd is. De diepte en de parallax staan verderop bij
   elkaar; hier alleen de kleur. */
.v2-layer:nth-child(1) { background-color: var(--mesh-4); }
.v2-layer:nth-child(2) { background-color: var(--mesh-3); }
.v2-layer:nth-child(3) { background-color: var(--mesh-2); }
.v2-layer:nth-child(4) { background-color: var(--mesh-1); }

.v2-layer span {
    display: inline-block;
    /* Onderaan, niet bovenaan — gemeten en niet gekozen, en bewust anders dan
       het ontwerp.

       De lagen liggen 46px uit elkaar in de diepte, wat op het scherm neerkomt
       op zo'n 36 pixels verspringing, terwijl een laag ruim 300 pixels hoog is.
       Van elke laag is dus alléén die onderste strook vrij; al het andere gaat
       schuil onder de laag erboven.

       Het ontwerp zet het label op 16px vanaf de bovenkant, en daar is het
       overdekt: render `docs/design/website-v2.html` op 1440 en alle vier de
       labels vallen weg — óók Applicatie. Dat is dus geen omissie bij het
       overzetten maar een gebrek in het ontwerp zelf, en die nemen we niet over.
       De platte variant van het ontwerp (onder 1081px, of met een aanraakscherm)
       heeft dit niet, en dát is de weergave waarin de labels wél te zien zijn.

       Te toetsen met `document.elementFromPoint` op het midden van elk label:
       daar hoort de span zelf te liggen en geen `.v2-layer`. */
    position: absolute;
    left: 6%;
    bottom: 2%;
    margin: 0;
    transform: rotateZ(32deg) rotateX(-54deg);
    transform-origin: left bottom;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    /* Op het glas van de laag zelf, dus lichter dan gewone bijschrifttekst. */
    color: var(--ink);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* Zonder 3D-ondersteuning — of met beweging uit — vallen de vlakken terug op
   een gewone stapel. Het beeld is dan minder sterk maar nog steeds waar. */
@media (prefers-reduced-motion: reduce) {
    .v2-layers-stack {
        position: relative;
        top: auto;
        left: auto;
        width: 100%;
        height: auto;
        display: flex;
        flex-direction: column;
        gap: 12px;
        transform: none;
    }

    .v2-layer {
        position: relative;
        height: auto;
        padding: 16px 18px;
        transform: none !important;
    }

    .v2-layer span {
        margin: 0;
        transform: none;
    }
}

@media (max-width: 1080px) {
    .v2-layers {
        aspect-ratio: 4 / 3;
    }
}

/* Kop links, inleiding rechts. Houdt de kop groot zonder de alinea eronder te
   duwen — bij een kop van veertig pixels scheelt dat een halve schermhoogte. */
.v2-section-head.is-split {
    align-items: flex-end;
}

/* Onder 1080 naast elkaar zetten kán niet meer.

   `.v2-section-head > :first-child` krijgt hierboven `flex: 1 1 0` zodat de kop
   krimpt in plaats van de link naar een eigen regel te duwen. Dat klopt zolang
   het tweede kind een korte link is. Bij `.is-split` is het tweede kind de
   inleiding met `flex: 1 1 22rem`, en basis 0 tegen 22rem verliest altijd: op
   640px kreeg de kop een kolom van 103px, brak over acht regels, en de langste
   regel mat 199px — bijna dubbel zijn eigen doos. De laatste regel drukte
   zichtbaar over de inleiding heen.

   Dit is de derde keer dat dezelfde vorm terugkomt: een correctie op een raster
   mét breekpunt hoort zelf ook een breekpunt te hebben. */
@media (max-width: 1080px) {
    .v2-section-head.is-split {
        display: block;
    }

    .v2-section-head.is-split > .v2-head-intro {
        margin-top: 16px;
        max-width: none;
    }
}

.v2-head-intro {
    flex: 1 1 22rem;
    max-width: 34rem;
    margin: 0;
    font-size: 16.5px;
    line-height: 1.62;
    color: var(--ink-2);
    text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   Demo-omlijsting
   -------------------------------------------------------------------------- */

.v2-demo-chrome {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 10px 16px 0;
    border-bottom: 1px solid var(--line-2);
}

/* De drie stippen. Puur teken: dit is een venster waarin iets draait. */
.v2-demo-dots {
    display: inline-flex;
    gap: 6px;
    flex: none;
    padding-bottom: 10px;
}

.v2-demo-dots span {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background-color: var(--line);
}

.v2-demo-hint {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-left: auto;
    padding-bottom: 10px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-3);
    white-space: nowrap;
}

@media (max-width: 680px) {
    .v2-demo-hint {
        display: none;
    }
}

.v2-demo-tabs {
    border-bottom: 0;
    padding: 0;
}

.v2-demo-meta {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 22px 0 0;
}

.v2-demo-meta > div {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 14px;
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
}

.v2-demo-meta dt {
    margin: 0;
    font-size: 13.5px;
    color: var(--ink-2);
}

.v2-demo-meta dd {
    margin: 0;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 12.5px;
    color: var(--ink);
}

/* De drie pijlers onder de demo. Het nummer boven de kop in plaats van ernaast:
   ze horen bij elkaar als een genummerde uitspraak, niet als een kaart met een
   telling in de hoek. */
.v2-pillars {
    margin: 0 0 44px;
    /* De drie pijlers staan in het ontwerp 18px uit elkaar en niet op de 16px
       van de kaartrasters. Twee pixels, maar het is een ander raster met een
       andere rol — drie stellingen, geen zes kaarten. */
    gap: 18px;
}

.v2-pillar-num {
    display: block;
    margin-bottom: 14px;
    color: var(--accent-ink);
}

/* --------------------------------------------------------------------------
   Artikelen op de homepage
   -------------------------------------------------------------------------- */

.v2-article {
    padding: 0;
    overflow: hidden;
}

.v2-article-image {
    position: relative;
    aspect-ratio: 16 / 10;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--surface-2);
    border-bottom: 1px solid var(--line-2);
}

/* Zonder artikelbeeld een strook, geen vlak.

   Het ontwerp geeft hier 120px; wij maakten er 16:10 van omdat
   `blogPost.heroImage` bestaat en het beeld dan goed zou vallen. Dat veld is
   alleen op geen van de 46 stukken gevuld, dus die afweging kon niet kloppen:
   de kaarten werden 551px hoog en ruim 700px van de homepage ging op aan drie
   tegels met hetzelfde sierraster.

   De strook blijft bestaan — zonder verdwijnt de kaartkop en worden de drie
   kaarten ongelijk hoog. Zodra er artikelbeelden zijn kan `is-leeg` niet meer
   voorkomen en staat 16:10 er vanzelf weer. */
.v2-article-image.is-leeg {
    aspect-ratio: auto;
    height: 120px;
}

.v2-article-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Het beeldslot staat middenin in plaats van linksboven: bij een leeg vlak is
   het de enige inhoud, en dan hoort het in het midden. */
.v2-article-image .v2-hero-chip {
    position: static;
}

.v2-article-body {
    padding: 22px 24px 26px;
}

.v2-article-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--ink-3);
}

.v2-article-body .v2-card-title {
    margin-bottom: 10px;
}

/* --------------------------------------------------------------------------
   Contactgegevens naast de uitnodiging
   -------------------------------------------------------------------------- */

.v2-contact-rows {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
}

.v2-contact-rows > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
    padding: 16px 4px;
    border-top: 1px solid var(--line-2);
}

.v2-contact-rows > div:last-child {
    border-bottom: 1px solid var(--line-2);
}

.v2-contact-rows dt {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.v2-contact-rows dd {
    margin: 0;
    font-size: 15px;
    color: var(--ink);
    text-align: right;
}

.v2-contact-rows a {
    color: var(--accent-ink);
    text-decoration: none;
}

.v2-contact-rows a:hover {
    text-decoration: underline;
}

.v2-contact-status {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 18px;
}

/* ==========================================================================
   Subpagina's — overzicht en detail

   Het ontwerp bouwt beide op uit dezelfde onderdelen: een kruimelpad boven de
   kop, een inleidende zin eronder, en op detailpagina's een zijkolom met
   gegroepeerde verwijzingen plus een afsluitend contactblok.

   De markup van die tien sjablonen blijft staan — daar zitten structuurdata,
   relatiegegevens en de laatst-bijgewerkt-badge in. Wat hier gebeurt is de
   vorm gelijktrekken met het ontwerp.
   ========================================================================== */

/* Kruimelpad: klein, mono, boven de kop. In het ontwerp is het een
   padaanduiding en geen navigatiebalk — vandaar de schuine strepen. */
.v2 .breadcrumb-nav {
    max-width: 1280px;
    margin: 0 auto;
    padding: 18px clamp(20px, 4vw, 40px) 0;
}

.v2 .breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
    background: none;
    font-family: var(--font-mono);
    font-size: 11.5px;
    letter-spacing: 0.06em;
}

.v2 .breadcrumb-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--ink-3);
}

.v2 .breadcrumb-item + .v2 .breadcrumb-item::before,
.v2 .breadcrumb-item:not(:first-child)::before {
    content: '/';
    opacity: 0.45;
}

.v2 .breadcrumb-item a {
    color: var(--ink-3);
    text-decoration: none;
}

.v2 .breadcrumb-item a:hover {
    color: var(--accent-ink);
}

.v2 .breadcrumb-item.active {
    color: var(--ink-2);
}

/* Bootstrap zet er zijn eigen scheidingsteken tussen; dat zou naast het onze
   staan. */
.v2 .breadcrumb-item + .breadcrumb-item::before {
    content: '/';
    float: none;
    padding: 0;
    color: inherit;
    opacity: 0.45;
}

/* --------------------------------------------------------------------------
   Zijkolom op detailpagina's

   Het ontwerp groepeert de verwijzingen onder een klein monokopje, in een
   glazen vak. Bij ons zijn dat losse blokken met een gewone kop — zelfde
   inhoud, andere vorm.
   -------------------------------------------------------------------------- */

.v2 .service-option-col,
.v2 .sidebar-block {
    padding: 20px 22px;
    margin-bottom: 14px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}

.v2 .service-option-col .sidebar-heading,
.v2 .sidebar-block .sidebar-heading {
    margin: 0 0 12px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 400;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.v2 .service-option-col ul,
.v2 .sidebar-block ul {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2 .service-option-col li a,
.v2 .sidebar-block li a {
    display: block;
    /* 44px raakvlak: een lijst met verwijzingen is navigatie. */
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 8px 10px;
    margin-inline: -10px;
    font-size: 14.5px;
    color: var(--ink-2);
    text-decoration: none;
    border-radius: var(--radius-sm);
}

.v2 .service-option-col li a:hover,
.v2 .sidebar-block li a:hover,
.v2 .service-option-col li a:focus-visible,
.v2 .sidebar-block li a:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-hi);
    text-decoration: none;
}

/* --------------------------------------------------------------------------
   Beeld op detailpagina's

   Het ontwerp opent de inhoudskolom met een 16:9-vlak. Onze illustraties zijn
   vierkant en staan inline; dit trekt ze naar dezelfde vorm zonder de markup
   te raken.
   -------------------------------------------------------------------------- */

.v2 .service-illustration,
.v2 .sector-illustration,
.v2 .figure-img {
    width: 100%;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line-2);
}

/* Het afsluitende contactblok krijgt de vorm van het ontwerp: één glazen vak
   met de vraag en twee knoppen, niet een witte kaart midden op de pagina. */
.v2 .meta-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(26px, 3.4vw, 36px);
}

/* De inleidende zin hoort onder de kop, niet ernaast. De oude sjablonen zetten
   kop en zin in een Bootstrap-rij met `text-center`; die rij wordt hier één
   kolom. Zo staat het ook in het ontwerp: kruimelpad, kop, zin — onder elkaar,
   links uitgelijnd. */
.v2 .about-page-header > .row,
.v2 .case-page-header > .row,
.v2 .clients-page-header > .row,
.v2 .contact-page-header > .row,
.v2 .initiatives-page-header > .row,
.v2 .sectors-page-header > .row,
.v2 .services-page-header > .row,
.v2 .usecases-page-header > .row,
.v2 .about-page-header,
.v2 .case-page-header,
.v2 .clients-page-header,
.v2 .contact-page-header,
.v2 .initiatives-page-header,
.v2 .sectors-page-header,
.v2 .services-page-header,
.v2 .usecases-page-header {
    display: block;
}

.v2 [class*='-page-header'] .page-payoff,
.v2 [class*='-page-header'] .header-text {
    max-width: 62ch;
    margin-inline: 0;
    text-align: left;
}

.v2 [class*='-page-header'] .page-payoff {
    margin-top: 14px;
    font-size: 18px;
    color: var(--ink-2);
}

/* Bootstrap-kolommen binnen die koppen krijgen anders nog hun eigen breedte
   en zweven naast elkaar. */
.v2 [class*='-page-header'] > .col,
.v2 [class*='-page-header'] > [class^='col-'],
.v2 [class*='-page-header'] .row > .col,
.v2 [class*='-page-header'] .row > [class^='col-'] {
    flex: none;
    width: 100%;
    max-width: none;
    text-align: left;
}

/* --------------------------------------------------------------------------
   Over: kerncijfers en eerdere rollen

   Het ontwerp toont de eerdere rollen als tijdlijn met de jaartallen in een
   eigen kolom. Bij ons staan ze in de lopende tekst, binnen een lijst die in
   april regel voor regel tegen het LinkedIn-profiel is geverifieerd. Die
   inhoud herschikken naar jaar/rol/omschrijving is contentwerk met
   vergissingsrisico, geen opmaakkwestie — zie de afwijkingenlijst.

   Wat hier gebeurt: de lijst krijgt de vorm van een tijdlijn (een lijn links,
   de rolnaam eruit gelicht) zonder de tekst aan te raken.
   -------------------------------------------------------------------------- */

.v2 .prose ul {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin: 22px 0;
    padding: 0 0 0 22px;
    list-style: none;
    border-left: 1px solid var(--line);
}

.v2 .prose ul li {
    position: relative;
    font-size: 15px;
    line-height: 1.65;
    color: var(--ink-2);
}

/* De stip op de lijn. Alleen in lopende tekst — een opsomming in een
   zijbalkje moet geen tijdlijn worden. */
.v2 .prose ul li::before {
    content: '';
    position: absolute;
    left: -26px;
    top: 0.6em;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background-color: var(--accent);
}

.v2 .prose ul li strong {
    display: block;
    margin-bottom: 3px;
    font-family: var(--font-kop);
    font-size: 16px;
    color: var(--ink);
}

/* De kerncijfers bovenaan Over. Zelfde vorm als op de homepage, zodat "20+
   jaar" er op beide plekken hetzelfde uitziet. */
.v2 .about-page-header + section .row,
.v2 #about > .container > .row.justify-content-center {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

@media (max-width: 1080px) {
    .v2 .about-page-header + section .row,
    .v2 #about > .container > .row.justify-content-center {
        grid-template-columns: repeat(2, 1fr);
    }
}

.v2 .stat-value {
    display: block;
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 30px;
    line-height: 1.1;
    color: var(--ink);
}

/* De foto van de oprichter. Het ontwerp zet hem in de zijkolom in een rond
   vlak; hier blijft hij zweven in de tekst, maar wel met dezelfde vorm. */
.v2 .founder-photo {
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
}

.v2 .figure-caption {
    margin-top: 8px;
    font-size: 13px;
    color: var(--ink-3);
}

/* --------------------------------------------------------------------------
   Teampagina

   Het ontwerp toont twee gelijkwaardige kaarten naast elkaar: initialen, naam,
   rol, een alinea, en daaronder een lijst met vinkjes. Bij ons zijn het twee
   rijen met een foto links en tekst rechts.

   De markup blijft: daar hangen structuurdata aan (AboutPage- en
   Person-schema, plus het HowTo-blok uit team.workflow). Wat hier gebeurt is
   de vorm gelijktrekken — twee kaarten, gelijke hoogte, dezelfde glazen
   behandeling als elders.
   -------------------------------------------------------------------------- */

.v2 #team .row.mb-5 {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: clamp(20px, 3vw, 34px);
    align-items: start;
    margin-bottom: 18px !important;
    padding: 28px 30px 30px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}

@media (max-width: 1080px) {
    .v2 #team .row.mb-5 {
        grid-template-columns: 1fr;
    }
}

/* De volgorde-omkering van Bootstrap (order-md-2) laat de foto bij Claude
   rechts staan. In een raster werkt dat niet meer, en het is ook niet nodig:
   twee kaarten met dezelfde indeling lezen als gelijkwaardig, en dat is
   precies de boodschap van deze pagina. */
.v2 #team .row.mb-5 > .order-md-1,
.v2 #team .row.mb-5 > .order-md-2 {
    order: 0;
}

.v2 #team .row.mb-5 > [class^='col-'] {
    width: auto;
    max-width: none;
    flex: none;
    padding: 0;
    text-align: left;
}

.v2 #team .row.mb-5 img,
.v2 #team .claude-profile-card {
    width: 100%;
    max-width: 13rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line-2);
    background-color: var(--surface-2);
}

.v2 #team .row.mb-5 h2 {
    margin-top: 16px !important;
    font-size: 22px;
}

.v2 #team .row.mb-5 h3 {
    font-family: var(--font-kop);
    font-size: 19px;
    color: var(--ink);
}

/* De vaardighedenlabels. Bootstrap zet ze licht met donkere tekst — precies
   omgekeerd aan wat hier nodig is. */
.v2 .badge.bg-light {
    background-color: var(--glass-fill-2) !important;
    color: var(--ink-2) !important;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   Voettekst — de kolommen uit het ontwerp
   -------------------------------------------------------------------------- */

.v2 .custom-footer {
    max-width: none;
    padding: clamp(48px, 6vw, 72px) 0 32px;
}

.v2 .custom-footer > .container,
.v2 .custom-footer > div {
    max-width: 1280px;
    margin: 0 auto;
    padding-inline: clamp(20px, 4vw, 40px);
}

.v2 .footer-brand-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
    padding-bottom: 30px;
    margin-bottom: 30px;
    border-bottom: 1px solid var(--line-2);
}

.v2 .footer-brand-mark {
    font-size: clamp(20px, 2.6vw, 26px);
}

/* Kolomkopjes in mono, zoals elk ander kopje van dat soort op de site. Ze
   stonden als gewone koppen — dat leest als inhoud in plaats van als label. */
.v2 .custom-footer h3,
.v2 .custom-footer .footer-heading,
.v2 .custom-footer h4 {
    margin-bottom: 14px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 400;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.v2 .custom-footer ul {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 0;
    list-style: none;
}

.v2 .custom-footer li a,
.v2 .custom-footer address a {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    font-size: 14.5px;
    color: var(--ink-2);
}

.v2 .custom-footer .social-links a,
.v2 .custom-footer .footer-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
}

.v2 .custom-footer .social-links a:hover,
.v2 .custom-footer .footer-social a:hover {
    background-color: var(--glass-fill-hi);
    color: var(--ink);
}

/* Inleidingen op subpagina's staan gecentreerd uit de oude opzet. In het
   ontwerp is alles links uitgelijnd; gecentreerde lopende tekst leest boven
   de vijftig tekens ook meetbaar trager. */
.v2 #team .text-center,
.v2 #about .text-center,
.v2 .section-intro.text-center {
    text-align: left;
}

.v2 #team .entity-intro,
.v2 #about .entity-intro {
    max-width: 62ch;
    margin-inline: 0;
}

/* --------------------------------------------------------------------------
   Gloed die de muis volgt

   Het ontwerp zet dit als `data-r="glow"` met een `style-before`-attribuut —
   een mechanisme van de ontwerpomgeving, niet van HTML zelf. Hier is het
   gewone CSS met twee variabelen die v2-glow.js bijwerkt.

   Waarom de moeite: dit is het verschil tussen kaarten die reageren en
   kaarten die stilstaan. Zonder dit voelt de pagina vlakker dan het ontwerp,
   en dat viel meteen op.
   -------------------------------------------------------------------------- */

.v2-card,
.v2-layers,
.v2-demo {
    position: relative;
}

.v2-card::before,
.v2-layers::after {
    content: '';
    position: absolute;
    inset: 0;
    /* De gloed staat waar de muis is; zonder muis in het midden, zodat een
       aanraking of toetsenbordfocus ook iets zichtbaars oplevert. */
    background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
        rgba(232, 132, 59, 0.14), transparent 60%);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
    z-index: 1;
}

/* De gloed volgt dezelfde tweedeling als de rand: paars op een sector. */
.v2-card-sector::before {
    background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
        rgba(155, 125, 255, 0.15), transparent 60%);
}

.v2-card:hover::before,
.v2-card:focus-within::before,
.v2-layers:hover::after {
    opacity: 1;
}

/* De inhoud moet boven de gloed staan, anders ligt er een oranje waas over
   de tekst. */
.v2-card > * {
    position: relative;
    z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
    .v2-card::before,
    .v2-layers::after {
        transition: none;
    }
}

/* Het afsluitende blok op subpagina's. Een band met een rand erboven, zodat
   het losstaat van de inhoud die je net gelezen hebt. */
/* De afsluitende oproep is in het ontwerp geen band over de volle breedte
   maar een glazen paneel binnen de kolom, met een oranje gloed rechtsboven.
   Bij ons was het een vlakke strook — dat leest als nog een sectie in plaats
   van als de afsluiting, en het staat op elke subpagina. */
.v2-cta-band {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
    border-top: 0;
    background-color: transparent;
}

.v2-cta-panel {
    position: relative;
    background-color: var(--glass-fill);
    backdrop-filter: blur(26px) saturate(170%);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
    overflow: hidden;
}

/* De gloed rechtsboven in het paneel. Puur decoratief. */
.v2-cta-glow {
    position: absolute;
    top: -150px;
    right: -70px;
    width: 480px;
    height: 480px;
    background: radial-gradient(circle, var(--accent), transparent 62%);
    opacity: 0.16;
    filter: blur(40px);
    pointer-events: none;
}

.v2-cta-band .v2-split {
    position: relative;
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: clamp(30px, 4vw, 48px);
    padding: clamp(32px, 4.2vw, 48px);
}

@media (max-width: 1080px) {
    .v2-cta-band .v2-split {
        grid-template-columns: 1fr;
    }
}

.v2-cta-band .v2-h2 {
    font-size: clamp(28px, 3.6vw, 38px);
    line-height: 1.06;
    letter-spacing: -0.025em;
    margin: 0 0 16px;
}

.v2-cta-band .v2-section-intro {
    font-size: 17px;
    line-height: 1.6;
    max-width: 420px;
    margin: 0 0 28px;
}

.v2-cta-band .v2-cta-row {
    gap: 12px;
    margin-top: 0;
}

/* De vinkjes staan rechts, verticaal gecentreerd naast de tekst. */
.v2-cta-points {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 15px;
    margin: 0;
}


/* --------------------------------------------------------------------------
   Statuspaneel in de hero

   Ligt onderin het beeldvlak, als glazen strook over het verloop heen. In het
   ontwerp toont het vier waarden over ons eigen werk; die zijn vervangen door
   wat de bouwstraat afdwingt vóór elke deploy. Zie de toelichting bij het blok
   in home.html.twig.
   -------------------------------------------------------------------------- */

.v2-status {
    position: absolute;
    left: 18px;
    right: 18px;
    bottom: 18px;
    z-index: 2;
    padding: 16px 18px;
    background-color: var(--glass-fill);
    backdrop-filter: blur(26px) saturate(180%);
    -webkit-backdrop-filter: blur(26px) saturate(180%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: inset 0 1px 0 var(--spec);
}

.v2-status-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 12px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.v2-status-live {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--ink-2);
}

.v2-status-build {
    color: var(--ink-3);
    white-space: nowrap;
}

.v2-status-cells {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin: 0;
}

.v2-status-cells > div {
    padding: 12px 14px;
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
}

.v2-status-cells dt {
    margin: 0 0 4px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
}

.v2-status-cells dd {
    display: flex;
    align-items: baseline;
    gap: 7px;
    margin: 0;
    font-family: var(--font-kop);
    font-weight: 600;
    /* 15,5 in plaats van 19. De waarden zijn concreter geworden — "1.143 groen"
       waar eerst "groen" stond — en op 19px liepen die over twee regels. Daardoor
       groeide het paneel van 134 naar 178 pixels en dekte het 62% van het beeld
       af in plaats van 48%, precies de strook waarvoor de hero gekaderd is.
       Kleiner corps: langere tekst, lager paneel, méér beeld. */
    font-size: 15.5px;
    color: var(--ink);
}

.v2-status-check {
    color: var(--ok);
    font-size: 14px;
}

/* Op smalle schermen valt het beeldvlak weg, maar bij tussenbreedtes wordt de
   strook anders hoger dan het vlak eronder. */
@media (max-width: 1080px) {
    .v2-status-cells dd {
        font-size: 14px;
    }

    .v2-status {
        padding: 12px 14px;
    }
}

/* ==========================================================================
   Beweging

   Zeven animaties in het ontwerp, waarvan ik er tot nu toe één had overgezet
   (de logoband). De rest is wat het scherm laat leven: de achtergrondvlekken
   drijven langzaam, statusstippen pulseren, een lichtstreep loopt over het
   beeldvlak, en de hero komt getrapt binnen.

   Alles hieronder valt weg bij `prefers-reduced-motion`. Dat is geen extraatje:
   drie van deze animaties draaien oneindig door, en dat is voor sommige mensen
   letterlijk misselijkmakend.
   ========================================================================== */

@keyframes v2-drift {
    0%   { transform: translate(0, 0) scale(1); }
    33%  { transform: translate(4%, -3%) scale(1.08); }
    66%  { transform: translate(-3%, 4%) scale(0.96); }
    100% { transform: translate(0, 0) scale(1); }
}

@keyframes v2-drift-2 {
    0%   { transform: translate(0, 0) scale(1); }
    50%  { transform: translate(-5%, 3%) scale(1.12); }
    100% { transform: translate(0, 0) scale(1); }
}

@keyframes v2-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: 0.3; transform: scale(0.75); }
}

@keyframes v2-scan {
    from { transform: translateY(-100%); }
    to   { transform: translateY(1200%); }
}

@keyframes v2-fade-up {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* De achtergrondvlekken. Elk met een eigen duur, zodat ze uit de pas raken en
   het geheel nooit een herkenbaar rondje draait — dat is precies waarom het
   ontwerp 26, 32 en 38 seconden gebruikt en niet drie keer dezelfde. */
.v2-mesh {
    background: none;
}

.v2-mesh::before,
.v2-mesh::after,
.v2-mesh > span {
    content: '';
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}

.v2-mesh::before {
    top: -20vw;
    left: -15vw;
    width: 70vw;
    height: 70vw;
    background: radial-gradient(circle, var(--mesh-2), transparent 60%);
    filter: blur(90px);
    opacity: 0.3;
    animation: v2-drift 26s ease-in-out infinite;
}

.v2-mesh::after {
    top: 10vh;
    right: -18vw;
    width: 62vw;
    height: 62vw;
    background: radial-gradient(circle, var(--mesh-1), transparent 62%);
    filter: blur(100px);
    opacity: 0.26;
    animation: v2-drift-2 32s ease-in-out infinite;
}

/* De derde vlek heeft een eigen element nodig: een element heeft maar twee
   pseudo-elementen, en drie vlekken is wat het ontwerp voorschrijft. */
.v2-mesh > span {
    bottom: -20vw;
    left: 25vw;
    width: 48vw;
    height: 48vw;
    background: radial-gradient(circle, var(--mesh-3), transparent 65%);
    filter: blur(110px);
    opacity: 0.16;
    animation: v2-drift 38s ease-in-out infinite reverse;
}

/* Statusstippen ademen. Twee tempo's, zoals in het ontwerp: de stip in de
   hero-pil iets trager dan die in het statuspaneel. */
.v2-pill-dot {
    animation: v2-pulse 2.4s ease-in-out infinite;
}

.v2-status-dot,
.v2-demo-hint .v2-status-dot {
    animation: v2-pulse 2s ease-in-out infinite;
}

/* Een lichtstreep die traag over het beeldvlak zakt. Dit is het effect dat het
   vlak van een plaatje in een scherm verandert. */
.v2-hero-media::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(180deg, transparent, var(--accent), transparent);
    opacity: 0.14;
    filter: blur(14px);
    pointer-events: none;
    animation: v2-scan 7s linear infinite;
}

/* Het verloop binnen het beeldvlak drijft ook, maar sneller dan de
   achtergrond — anders lijkt het stil te staan tegen de beweging erachter. */
.v2-hero-media-glow {
    animation: v2-drift 22s ease-in-out infinite;
}

/* De hero komt getrapt binnen: label, kop, inleiding, knoppen, metaregel. De
   vertragingen komen uit het ontwerp en lopen van 0,1 tot 0,5 seconde. */
.v2-pill        { opacity: 0; animation: v2-fade-up 0.7s cubic-bezier(0.22, 0.8, 0.3, 1) 0.1s both; }
.v2-h1          { opacity: 0; animation: v2-fade-up 0.7s cubic-bezier(0.22, 0.8, 0.3, 1) 0.2s both; }
.v2-lead        { opacity: 0; animation: v2-fade-up 0.7s cubic-bezier(0.22, 0.8, 0.3, 1) 0.3s both; }
.v2-cta-row     { opacity: 0; animation: v2-fade-up 0.7s cubic-bezier(0.22, 0.8, 0.3, 1) 0.4s both; }
.v2-hero-meta   { opacity: 0; animation: v2-fade-up 0.7s cubic-bezier(0.22, 0.8, 0.3, 1) 0.5s both; }
.v2-hero-media  { opacity: 0; animation: v2-fade-up 0.8s cubic-bezier(0.22, 0.8, 0.3, 1) 0.35s both; }

/* De getrapte binnenkomst geldt alleen in de hero. Elders zou het betekenen
   dat inhoud onder de vouw pas verschijnt nadat iemand er al is. */
.v2-hero .v2-cta-row {
    animation-delay: 0.4s;
}

.v2-cta-band .v2-cta-row,
.v2-section .v2-cta-row {
    opacity: 1;
    animation: none;
}

@media (prefers-reduced-motion: reduce) {
    .v2-mesh::before,
    .v2-mesh::after,
    .v2-mesh > span,
    .v2-pill-dot,
    .v2-status-dot,
    .v2-hero-media::after,
    .v2-hero-media-glow,
    .v2-pill,
    .v2-h1,
    .v2-lead,
    .v2-cta-row,
    .v2-hero-meta,
    .v2-hero-media {
        animation: none;
        opacity: 1;
    }

    /* De lichtstreep is puur decoratief en zou stilstaand als een balk over
       het beeld liggen. */
    .v2-hero-media::after {
        display: none;
    }
}

/* De contactsectie start dichter op wat eraan voorafgaat: het ontwerp zet
   40px boven en de volle ruimte onder. Dat leest als "en dan nu de vraag"
   in plaats van als een nieuw hoofdstuk. */
#contact-intro.v2-section {
    padding-top: 40px;
}

/* ==========================================================================
   Subpagina's, nagemeten

   De meting van de detailpagina legde vier dingen bloot die met kijken niet
   opvallen: de inhoud liep door tot de schermrand in plaats van tot 1280px,
   de zijkolom bleef staan waar het ontwerp hem laat meelopen, hij was 368
   breed in plaats van 336, en het kruimelpad had geen ruimte onder zich.
   ========================================================================== */

/* De inhoudskolom en de zijkolom als raster, met de vaste zijkolombreedte uit
   het ontwerp. Bootstrap's rij is flex met percentages; dat gaf 784/392 waar
   het 1fr/336 hoort te zijn. */
.v2 .service-content > .row,
.v2 .row.mt-4:has(> .col-md-8),
.v2 .row:has(> .col-md-8):has(> .col-md-4) {
    display: grid;
    grid-template-columns: 1fr 336px;
    gap: clamp(36px, 5vw, 60px);
    align-items: start;
    max-width: 1280px;
    margin-inline: auto;
    padding: clamp(44px, 6vw, 68px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
}

.v2 .row:has(> .col-md-8) > .col-md-8,
.v2 .row:has(> .col-md-8) > .col-md-4 {
    width: auto;
    max-width: none;
    flex: none;
    padding: 0;
}

@media (max-width: 1080px) {
    .v2 .service-content > .row,
    .v2 .row.mt-4:has(> .col-md-8),
    .v2 .row:has(> .col-md-8):has(> .col-md-4) {
        grid-template-columns: 1fr;
    }
}

/* De zijkolom loopt mee tijdens het scrollen. 104px vanaf de bovenkant, zodat
   hij vrij blijft van de zwevende balk. */
.v2 .row:has(> .col-md-8) > .col-md-4 {
    position: sticky;
    top: 104px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

@media (max-width: 1080px) {
    .v2 .row:has(> .col-md-8) > .col-md-4 {
        position: static;
    }
}

/* De zijbalkvakken staan al in een raster met gap; hun eigen ondermarge zou
   die verdubbelen. */
.v2 .row:has(> .col-md-8) > .col-md-4 .service-option-col,
.v2 .row:has(> .col-md-8) > .col-md-4 .sidebar-block {
    margin-bottom: 0;
}

/* Paginakoppen: het ontwerp gebruikt 1,03 en −0,028em, wij hadden 1,05 en
   −0,025em. Dezelfde soort afwijking als op de homepage. */
.v2 [class*='-page-header'] .header-text,
.v2 .page-header .header-text,
.header-text {
    font-size: clamp(34px, 5.2vw, 52px);
    line-height: 1.03;
    letter-spacing: -0.028em;
}

/* Kruimelpad: 12px in plaats van 11,5, en 22px ruimte eronder. Zonder die
   ruimte plakt het pad tegen de kop. */
.v2 .breadcrumb {
    font-size: 12px;
    margin-bottom: 22px;
}

/* De Bootstrap-container eromheen begrenst op 1200px met 24px binnenmarge, dus
   1152px inhoud waar het ontwerp 1280 vraagt. Die container mag hier los: de
   rij eronder draagt zijn eigen breedte en marges al.

   Alleen waar hij een detailrij omsluit — elders doet de container nog wel
   werk. */
.v2 .container:has(.col-md-8) {
    max-width: none;
    padding-inline: 0;
}

/* Nadruk in de hero-inleiding.

   Het ontwerp markeert de slotzinsnede met een helderdere kleur en iets meer
   gewicht, niet met cursief: <span style="color:var(--ink);font-weight:500">.
   Semantisch is <em> hier juist — het is nadruk, geen opmaak — dus de
   schuinstand wordt teruggedraaid en de ontwerpwaarden komen ervoor in de
   plaats. */
.v2-lead em {
    font-style: normal;
    font-weight: 500;
    color: var(--v2-ink);
}

/* ==========================================================================
   Subpagina's — de gedeelde kopband

   Elke subpagina in het ontwerp begint met dezelfde band: kruimelpad in mono,
   kop, inleiding, lijn eronder. Alle waarden hieronder komen letterlijk uit
   website-v2.html en zijn niet geschat.
   ========================================================================== */

.v2-page-head {
    position: relative;
    border-bottom: 1px solid var(--line-2);
}

.v2-page-head-inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(48px, 6vw, 72px) clamp(20px, 4vw, 40px) clamp(56px, 7vw, 80px);
}

.v2-crumbs ol {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 0 0 22px;
    padding: 0;
    list-style: none;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--ink-3);
}

.v2-crumbs li {
    display: flex;
    align-items: center;
    gap: 8px;
}

.v2-crumbs a {
    color: inherit;
    text-decoration: none;
    transition: color 0.18s ease;
}

.v2-crumbs a:hover,
.v2-crumbs a:focus-visible {
    color: var(--ink-2);
}

.v2-crumb-sep {
    opacity: 0.45;
}

.v2-crumbs [aria-current="page"] {
    color: var(--ink-2);
}

.v2-page-title {
    font-family: var(--font-kop);
    text-wrap: balance;
    /* `base.css` centreert élke h1. Die regel stamt uit het oude ontwerp en
       stond in `afwijkingen.md` als punt 8, met als voorwaarde dat hij pas weg
       kon als alle sjablonen waren overgezet. Dat is sinds 26 augustus zo — de
       voorwaarde verliep, de regel niet.

       Gevolg was op ongeveer veertig pagina's te zien: kruimelpad op 120,
       inleiding op 120, en de kop begon op 211 tot 612. Het grootste element
       op de pagina stond als enige niet in de lijn, en hoe korter de titel hoe
       erger het opviel.

       De basisregel blijft staan omdat hij ook buiten v2 nog h1's raakt (de
       Studio-schermen, de foutpagina's); hier wordt hij gericht ongedaan
       gemaakt. */
    text-align: left;
    font-weight: 600;
    font-size: clamp(34px, 5.2vw, 52px);
    line-height: 1.03;
    letter-spacing: -0.028em;
    margin: 0;
    color: var(--ink);
}

.v2-page-lead {
    font-size: 19px;
    line-height: 1.6;
    color: var(--ink-2);
    max-width: 580px;
    margin: 22px 0 0;
    text-wrap: pretty;
}

/* ==========================================================================
   Contactpagina — formulier links, gegevens rechts
   ========================================================================== */

.v2-contact-grid {
    display: grid;
    grid-template-columns: 1.12fr 0.88fr;
    gap: clamp(32px, 4vw, 48px);
    align-items: start;
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(44px, 6vw, 68px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
}

@media (max-width: 1080px) {
    .v2-contact-grid {
        grid-template-columns: 1fr;
    }
}

/* --- Het formulierpaneel --- */

.v2-form-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(26px) saturate(170%);
    -webkit-backdrop-filter: blur(26px) saturate(170%);
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
    box-shadow: inset 0 1px 0 var(--spec), var(--shadow-deep);
    padding: clamp(26px, 3.4vw, 36px);
}

.v2-form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

@media (max-width: 680px) {
    .v2-form-row {
        grid-template-columns: 1fr;
    }
}

.v2-field {
    margin-bottom: 16px;
    min-width: 0;
}

.v2-fieldset {
    border: 0;
    padding: 0;
    margin-inline: 0;
}

.v2-label {
    display: block;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
    /* `normal`, niet de regelhoogte van de pagina. Het ontwerp meet hier 12px
       hoog; met de geërfde 1.5 wordt dat 16px en schuift elk veld eronder mee.
       Dezelfde fout zat eerder in de knoppen — geërfde regelhoogte is in dit
       ontwerp de meest voorkomende oorzaak van een paar pixel verschil. */
    line-height: normal;
    margin-bottom: 9px;
    padding: 0;
}

.v2-input {
    width: 100%;
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    padding: 13px 15px;
    color: var(--ink);
    font-family: inherit;
    font-size: 15px;
    line-height: normal;
    outline: none;
    transition: border-color 0.18s ease;
}

.v2-input::placeholder {
    color: var(--ink-3);
}

.v2-input:focus-visible {
    border-color: var(--accent);
}

.v2-textarea {
    resize: vertical;
    line-height: 1.6;
}

/* Bootstrap toont `.invalid-feedback` alleen naast een `.form-control`. Die
   klasse is hier weg, dus de koppeling met `.is-invalid` moet opnieuw — anders
   staan de foutmeldingen er wel maar zie je ze nooit. */
.v2-input.is-invalid {
    border-color: var(--color-status-unavailable);
}

.v2-input.is-invalid ~ .invalid-feedback,
.v2-checkbox.is-invalid ~ .invalid-feedback {
    display: block;
    margin-top: 7px;
    font-size: 13px;
    color: var(--color-status-unavailable);
}

/* --- Het onderwerp als knoppenrij --- */

.v2-topic-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.v2-topic-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.v2-topic-pill {
    display: inline-flex;
    align-items: center;
    /* 44px hoog, zodat de rij op een telefoon aanraakbaar blijft (WCAG 2.5.8);
       het ontwerp tekent ze kleiner maar tekent ook geen vingers. */
    min-height: 44px;
    padding: 10px 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background-color: var(--glass-fill-2);
    color: var(--ink-2);
    font-size: 14px;
    cursor: pointer;
    transition: border-color 0.18s ease, color 0.18s ease, background-color 0.18s ease;
}

.v2-topic-pill:hover {
    border-color: var(--accent);
    color: var(--ink);
}

.v2-topic-input:checked + .v2-topic-pill {
    border-color: var(--accent);
    background-color: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
}

.v2-topic-input:focus-visible + .v2-topic-pill {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* --- Toestemming en voettekst --- */

.v2-consent {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 10px;
    align-items: start;
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink-2);
}

.v2-consent .invalid-feedback {
    grid-column: 1 / -1;
}

.v2-checkbox {
    width: 18px;
    height: 18px;
    margin-top: 2px;
    accent-color: var(--accent);
}

.v2-consent a {
    color: var(--accent);
}

.v2-form-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
    margin-top: 20px;
}

.v2-form-note {
    font-size: 13.5px;
    color: var(--ink-3);
    max-width: 320px;
    line-height: 1.5;
    margin: 0;
}

/* --- De gegevenskaarten rechts --- */

.v2-contact-aside {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.v2-data-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
}

.v2-data-key {
    display: block;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-bottom: 6px;
}

.v2-data-value {
    display: block;
    font-size: 15px;
    color: var(--ink);
    line-height: 1.5;
    word-break: break-word;
}

.v2-data-value a {
    color: inherit;
}

.v2-data-card:first-child .v2-data-value a {
    color: var(--accent);
}

.v2-data-sub {
    color: var(--ink-3);
}

/* --- De beschikbaarheidskaart --- */

.v2-status-card {
    border-radius: var(--radius-lg);
    padding: 20px;
    border: 1px solid var(--line);
    background-color: var(--glass-fill);
}

.v2-status-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 9px;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
}

.v2-status-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: none;
}

.v2-status-text {
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--ink-2);
    margin: 0;
}

.v2-status-available {
    background-color: color-mix(in srgb, var(--color-status-available) 7%, transparent);
    border-color: color-mix(in srgb, var(--color-status-available) 28%, transparent);
}

.v2-status-available .v2-status-head {
    color: var(--color-status-available);
}

.v2-status-available .v2-status-dot {
    background-color: var(--color-status-available);
    box-shadow: 0 0 9px var(--color-status-available);
}

.v2-status-limited {
    background-color: color-mix(in srgb, var(--color-status-limited) 7%, transparent);
    border-color: color-mix(in srgb, var(--color-status-limited) 28%, transparent);
}

.v2-status-limited .v2-status-head {
    color: var(--color-status-limited);
}

.v2-status-limited .v2-status-dot {
    background-color: var(--color-status-limited);
    box-shadow: 0 0 9px var(--color-status-limited);
}

.v2-status-unavailable {
    background-color: color-mix(in srgb, var(--color-status-unavailable) 7%, transparent);
    border-color: color-mix(in srgb, var(--color-status-unavailable) 28%, transparent);
}

.v2-status-unavailable .v2-status-head {
    color: var(--color-status-unavailable);
}

.v2-status-unavailable .v2-status-dot {
    background-color: var(--color-status-unavailable);
}

/* ==========================================================================
   Overzichtspagina's — kaartraster van twee

   Zes pagina's delen deze vorm: diensten, sectoren, opdrachten,
   initiatieven, praktijkvoorbeelden en insights. Waarden uit de tak
   `isOverview` van het ontwerp.
   ========================================================================== */

.v2-overview {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(48px, 6vw, 72px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
}

.v2-overview-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 18px;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (max-width: 1080px) {
    .v2-overview-grid {
        grid-template-columns: 1fr;
    }
}

.v2-ocard {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 30px 28px 32px;
    overflow: hidden;
    text-decoration: none;
    transition: border-color 0.25s ease, transform 0.25s ease;
}

/* De lichtvlek die de muis volgt. Dezelfde behandeling als de
   dienstenkaarten op de homepage: v2-glow.js zet --mx en --my. */
.v2-ocard::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%),
        color-mix(in srgb, var(--accent) 13%, transparent), transparent 60%);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

.v2-ocard:hover,
.v2-ocard:focus-visible {
    border-color: var(--accent);
    transform: translateY(-3px);
}

.v2-ocard:hover::before {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .v2-ocard,
    .v2-ocard::before {
        transition: none;
    }

    .v2-ocard:hover,
    .v2-ocard:focus-visible {
        transform: none;
    }
}

.v2-ocard-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 13px;
}

.v2-ocard-title {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 23px;
    line-height: normal;
    letter-spacing: -0.015em;
    margin: 0;
    color: var(--ink);
}

.v2-ocard-meta {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 11.5px;
    color: var(--ink-3);
    white-space: nowrap;
}

.v2-ocard-text {
    font-size: 15.5px;
    line-height: 1.62;
    color: var(--ink-2);
    margin: 0 0 22px;
    text-wrap: pretty;
}

.v2-ocard-tags {
    margin: auto 0 0;
    padding: 0;
    list-style: none;
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
}

.v2-tag {
    font-family: var(--font-mono);
    font-size: 11px;
    line-height: normal;
    color: var(--ink-3);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    padding: 4px 8px;
}

/* ==========================================================================
   Detailpagina's — inhoud links, zijkolom rechts
   ========================================================================== */

.v2-detail {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(44px, 6vw, 68px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
    display: grid;
    grid-template-columns: 1fr 336px;
    gap: clamp(36px, 5vw, 60px);
    align-items: start;
}

@media (max-width: 1080px) {
    .v2-detail {
        grid-template-columns: 1fr;
    }
}

/* Het beeldvlak bovenaan. Staat er ook zonder afbeelding: het ontwerp toont
   dan het slot met een aanduiding, en een leeg vlak vertelt dat er beeld hoort
   te komen. Zodra er een afbeelding is vult die het vlak. */
/* Het beeldblok is een montuur, geen venster.

   Hier stond `background: linear-gradient(145deg, var(--surface-2),
   var(--surface))` — een grond die met het thema meewisselt. Op donker klopt
   dat, op licht kwam een donkere render daardoor rechtstreeks op een lichte
   pagina te liggen en las hij als een gat in het vel papier.

   Dat is geen kleurprobleem. In druk krijgt een donkere foto een passe-partout
   en dan valt niemand erover; wat het op het web stukmaakt is dat er geen
   montuur omheen zit. `--podium` wisselt daarom bewust niet mee: het beeld
   houdt in beide standen dezelfde grond, en op een lichte pagina leest het als
   een gemonteerde opname in plaats van als een fout.

   Waarom dat de enige weg is: een render kun je opnieuw belichten, een
   opname niet. Een nachtvlucht laat zich niet licht graderen zonder een
   slechte nachtvlucht te worden. Hiermee vervalt de keuze "veertien scènes
   opnieuw uitvoeren of de themawissel schrappen".

   De marge zit op het blok en de inhoud krijgt dezelfde marge als `inset`,
   want die staat absoluut en trekt zich van padding niets aan. */
.v2-detail-media {
    position: relative;
    aspect-ratio: 16 / 9;
    padding: var(--podium-marge);
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    background: var(--podium);
    box-shadow: var(--podium-schaduw);
    margin-bottom: 44px;
}

/* De maten moeten expliciet, en dat is geen slordigheid maar hoe de standaard
   werkt: bij een vervángen element (een `img`) lost `width: auto` op naar de
   éigen breedte van het bestand, niet naar de ruimte tussen de insets. Met
   `auto` stond hier een render van 1600 breed in een blok van 804. Een `div`
   doet dat wél goed — vandaar dat de doorsnede-laag hieronder geen maten
   nodig heeft. */
.v2-detail-media img,
.v2-detail-video {
    position: absolute;
    inset: var(--podium-marge);
    width: calc(100% - var(--podium-marge) * 2);
    height: calc(100% - var(--podium-marge) * 2);
    object-fit: cover;
    border-radius: calc(var(--radius-lg) - var(--podium-marge) / 2);
}

/* --- Het tweede beeld op een dienstpagina, met bijschrift ---

   Zelfde vorm als het herobeeld erboven, maar zonder `aspect-ratio`: dit is een
   opname met een eigen verhouding en die hoort niet bijgesneden te worden.
   Vandaar `object-fit` hier niet, en een `figcaption` eronder in plaats van
   eromheen. */
.v2-detail-figure {
    margin: 0 0 44px;
}

/* Het anker om het béeld, niet om de figuur.

   De doorsnede ligt absoluut over zijn positioneringsanker heen
   (`.v2-bouw-beeld` heeft `inset: 0`). Dat anker stond eerst op de `<figure>`
   zelf, en die omvat ook het bijschrift — het eindbeeld mat daardoor 804×453
   en de doorsnede 804×512. Elf procent verschil, en juist bij deze schakelaar
   is dat fataal: de hele kracht zit erin dat het object niet beweegt en alleen
   zijn afwerking verliest.

   Het anker moet er wél zijn. Zonder een positioneringsvoorouder zoekt het
   overlay-vlak er een verderop en landt het buiten het kader; de schakelaar
   lijkt dan niets te doen. */
.v2-detail-figure-beeld {
    position: relative;
}

.v2-detail-figure img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
}

.v2-detail-figure figcaption {
    margin-top: 14px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--ink-3);
    text-wrap: pretty;
}

/* Wie beweging heeft uitgezet krijgt de poster te zien. Het beeld blijft dan
   dezelfde uitsnede, dus er valt niets weg — alleen de beweging. */
@media (prefers-reduced-motion: reduce) {
    .v2-detail-video {
        display: none;
    }

    .v2-detail-media:has(.v2-detail-video) {
        background-image: var(--detail-video-poster);
        background-size: cover;
        background-position: center;
    }
}

.v2-detail-media-glow {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at 32% 30%, var(--accent-2), transparent 58%),
        radial-gradient(ellipse at 74% 72%, var(--accent), transparent 58%);
    opacity: 0.4;
    filter: blur(30px);
}

.v2-detail-media-grid {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(var(--spec) 1px, transparent 1px),
        linear-gradient(90deg, var(--spec) 1px, transparent 1px);
    background-size: 44px 44px;
}

.v2-detail-block {
    padding: 0 0 34px;
}

.v2-detail-block h2,
.v2-detail-faq > h2 {
    font-family: var(--font-kop);
    text-wrap: balance;
    font-weight: 600;
    font-size: clamp(24px, 3vw, 28px);
    line-height: normal;
    letter-spacing: -0.018em;
    margin: 0 0 14px;
    color: var(--ink);
}

.v2-detail-block p,
.v2-detail-block li {
    font-size: 17px;
    line-height: 1.72;
    color: var(--ink-2);
    max-width: 700px;
    text-wrap: pretty;
}

.v2-detail-block p {
    margin: 0 0 14px;
}

.v2-detail-block p:last-child {
    margin-bottom: 0;
}

.v2-detail-faq {
    border-top: 1px solid var(--line-2);
    padding-top: 38px;
}

.v2-detail-faq > h2 {
    margin-bottom: 22px;
}

.v2-faq-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2-faq-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    padding: 20px 22px;
}

.v2-faq-card h3 {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 17px;
    line-height: normal;
    margin: 0 0 9px;
    color: var(--ink);
}

.v2-faq-card p {
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--ink-2);
    margin: 0;
    text-wrap: pretty;
}

/* --- De zijkolom --- */

.v2-aside {
    position: sticky;
    top: 104px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

@media (max-width: 1080px) {
    .v2-aside {
        position: static;
    }
}

.v2-aside-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 22px;
}

.v2-aside-head {
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin: 0 0 14px;
}

.v2-aside-links {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2-aside-links a {
    display: block;
    font-size: 14.5px;
    color: var(--ink-2);
    padding: 7px 9px;
    margin: 0 -9px;
    border-radius: var(--radius-sm);
    text-decoration: none;
    transition: color 0.18s ease, background-color 0.18s ease;
}

.v2-aside-links a:hover,
.v2-aside-links a:focus-visible {
    color: var(--ink);
    background-color: var(--glass-fill-2);
}

.v2-aside-cta {
    background-color: color-mix(in srgb, var(--accent) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-radius: var(--radius-lg);
    padding: 22px;
}

.v2-aside-cta-title {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 17.5px;
    line-height: normal;
    color: var(--ink);
    margin: 0 0 8px;
}

.v2-aside-cta p {
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--ink-2);
    margin: 0 0 18px;
}

.v2-aside-cta .v2-btn {
    font-size: 14.5px;
    padding: 12px 20px;
    border-radius: var(--radius-md);
}

.v2-aside-updated {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--ink-3);
    padding: 0 4px;
    margin: 0;
}

/* De vragenlijst op een overzichtspagina staat verder van het raster af dan
   op een detailpagina, waar hij direct op de tekstblokken volgt. */
.v2-overview-faq {
    margin-top: 56px;
}

/* De regel over het werkgebied. Feitelijk en klein — hij hoort bij het raster
   en niet in de inleiding, want hij gaat over waar we werken en niet over wat
   we doen. */
.v2-overview-note {
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--ink-3);
    margin: 28px 0 0;
    max-width: 700px;
}

/* Het ontwerp geeft kop en inleiding per paginasoort een eigen maximale
   breedte: overzicht 800/600, detail 820/640, over 620 op de inleiding.
   Contact heeft geen begrenzing op de kop en 580 op de inleiding — dat is de
   basiswaarde hierboven. Kleine verschillen, maar ze bepalen waar een kop
   afbreekt en dus hoeveel regels hij krijgt. */
.v2-page-head--overview .v2-page-title { max-width: 800px; }
.v2-page-head--overview .v2-page-lead  { max-width: 600px; }
.v2-page-head--detail   .v2-page-title { max-width: 820px; }
.v2-page-head--detail   .v2-page-lead  { max-width: 640px; }
.v2-page-head--over     .v2-page-lead  { max-width: 620px; }

/* Labs staat als tweede groep op het initiatieven-overzicht. Het ontwerp kent
   maar één raster per overzicht, maar de scheiding tussen wat er is en wat in
   besloten bèta staat is inhoudelijk — die verdwijnt niet voor de vorm. */
.v2-overview-labs {
    margin-top: 64px;
    border-top: 1px solid var(--line-2);
    padding-top: 44px;
}

.v2-overview-labs > h2 {
    font-family: var(--font-kop);
    text-wrap: balance;
    font-weight: 600;
    font-size: clamp(24px, 3vw, 28px);
    line-height: normal;
    letter-spacing: -0.018em;
    margin: 0 0 14px;
    color: var(--ink);
}

.v2-overview-labs .v2-overview-note {
    margin: 0 0 26px;
}

/* De lichtere tweede verwijzing onder de knop in het zijkolomblok — het
   tweede opvangpunt voor wie nog geen project heeft maar wel op de hoogte
   wil blijven. Bewust geen tweede knop: dan concurreren ze. */
.v2-aside-cta-secondary {
    display: inline-block;
    margin-top: 14px;
    font-size: 13.5px;
    color: var(--ink-2);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.v2-aside-cta-secondary:hover,
.v2-aside-cta-secondary:focus-visible {
    color: var(--ink);
}

/* De opsomming in een zijkolomvak dat geen verwijzingen draagt maar feiten —
   "ideaal voor" op een dienstpagina bijvoorbeeld. */
.v2-aside-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 9px;
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--ink-2);
}

/* Referenties onder de tekstkolom. Het ontwerp kent ze niet — ze staan uit
   tenzij de instelling aan gaat — maar als ze verschijnen horen ze in
   dezelfde glazen vorm als de rest. */
.v2-quotes {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (max-width: 680px) {
    .v2-quotes {
        grid-template-columns: 1fr;
    }
}

.v2-quote {
    background-color: var(--glass-fill);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    padding: 22px;
    margin: 0;
}

.v2-quote p {
    font-size: 15.5px;
    line-height: 1.65;
    color: var(--ink-2);
    margin: 0 0 12px;
}

.v2-quote footer {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    font-style: normal;
}

/* De definitiezin bovenaan een detailpagina. Het ontwerp kent geen apart
   niveau tussen inleiding en lopende tekst, maar deze zin doet wel iets
   eigens: hij zegt in één regel wat de dienst is, en dat is precies wat een
   spraakassistent voorleest — vandaar ook de speakable-selector. */
.v2-detail-lead {
    font-size: 19px;
    line-height: 1.6;
    color: var(--ink);
    margin: 0 0 22px;
    max-width: 700px;
    text-wrap: pretty;
}

/* De lopende tekst uit de vertaalbestanden draagt eigen opmaak: koppen,
   opsommingen, links. Die krijgen hier de maatvoering van het ontwerp, want
   ze komen als één blok binnen en kunnen geen klassen dragen. */
.v2-detail-block h3 {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 19px;
    line-height: normal;
    margin: 26px 0 10px;
    color: var(--ink);
}

.v2-detail-block ul,
.v2-detail-block ol {
    margin: 0 0 14px;
    padding-left: 22px;
    max-width: 700px;
}

.v2-detail-block li {
    margin-bottom: 7px;
}

/* Niet op knoppen: `.v2-detail-block a` won van `.v2-btn-primary` op
   specificiteit, en dan staat er oranje tekst op een oranje vlak. De knop op
   Over was daardoor in beide themas onleesbaar. */
.v2-detail-block a:not(.v2-btn) {
    color: var(--accent-ink);
}

.v2-detail-block strong {
    color: var(--ink);
    font-weight: 600;
}

/* Kerncijfers op een opdrachtpagina. Bij de meeste opdrachten staat dit blok
   leeg — de contentwaarheidsronde van april heeft de verzonnen cijfers
   verwijderd — en dan verschijnt het niet. Cijferuitlijning, want ze staan
   naast elkaar en moeten dan ook echt uitlijnen. */
.v2-metrics {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin: 0 0 34px;
    padding: 0;
    list-style: none;
}

.v2-metrics li {
    flex: 1 1 150px;
    background-color: var(--glass-fill);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-md);
    padding: 20px 22px;
}

.v2-metric-value {
    display: block;
    font-family: var(--font-kop);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 27px;
    line-height: 1.1;
    color: var(--ink);
    margin-bottom: 5px;
}

.v2-metric-label {
    display: block;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-3);
}

/* Zustermerken en de privacyregel in het trechterblok van een initiatief. */
.v2-aside-sisters,
.v2-aside-privacy {
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-3);
    margin: 14px 0 0;
}

.v2-aside-sisters a {
    color: var(--ink-2);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* ==========================================================================
   Over — de band met kerngetallen en de portretkaart

   Waarden uit de tak `isOver` van het ontwerp.
   ========================================================================== */

.v2-statband {
    border-bottom: 1px solid var(--line-2);
}

.v2-statband-inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: 36px clamp(20px, 4vw, 40px);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 28px;
}

@media (max-width: 1080px) {
    .v2-statband-inner {
        grid-template-columns: repeat(2, 1fr);
    }
}

.v2-stat-value {
    display: block;
    font-family: var(--font-kop);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: clamp(30px, 3.6vw, 38px);
    letter-spacing: -0.02em;
    color: var(--accent);
    line-height: 1;
}

/* De vierde is geen getal maar een opsomming; op dezelfde grootte breekt hij
   over drie regels en duwt hij de band uit model. */
.v2-stat-value-text {
    font-size: clamp(17px, 1.9vw, 21px);
    line-height: 1.25;
}

.v2-stat-label {
    display: block;
    font-size: 14.5px;
    color: var(--ink-2);
    margin-top: 8px;
}

/* --- De portretkaart in de zijkolom --- */

.v2-portret-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 14px;
}

.v2-portret {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: linear-gradient(145deg, var(--surface-2), var(--surface));
    border: 1px solid var(--line-2);
    margin-bottom: 16px;
}

.v2-portret img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.v2-portret-glow {
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 40% 35%, var(--accent-2), transparent 60%);
    opacity: 0.3;
    filter: blur(26px);
}

.v2-portret-naam {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 18px;
    color: var(--ink);
    padding: 0 8px;
}

.v2-portret-naam a {
    color: inherit;
    text-decoration: none;
}

.v2-portret-naam a:hover,
.v2-portret-naam a:focus-visible {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.v2-portret-rol {
    font-size: 14px;
    color: var(--ink-2);
    margin-top: 4px;
    padding: 0 8px 6px;
}

/* --- Profiel in het kort --- */

.v2-profiel {
    display: flex;
    flex-direction: column;
    gap: 13px;
    margin: 0;
}

.v2-profiel dt {
    font-size: 12.5px;
    color: var(--ink-3);
    margin-bottom: 3px;
    font-weight: 400;
}

.v2-profiel dd {
    font-size: 14.5px;
    color: var(--ink);
    line-height: 1.45;
    margin: 0;
}

/* ==========================================================================
   Team — twee gelijkwaardige kaarten en het slotpanel

   Waarden uit de tak `isTeam` van het ontwerp.
   ========================================================================== */

.v2-team-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
    margin-top: 8px;
}

@media (max-width: 1080px) {
    .v2-team-grid {
        grid-template-columns: 1fr;
    }
}

.v2-team-card {
    background-color: var(--glass-fill);
    backdrop-filter: blur(22px) saturate(160%);
    -webkit-backdrop-filter: blur(22px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 30px 28px 32px;
}

.v2-team-head {
    display: flex;
    align-items: center;
    gap: 15px;
    margin-bottom: 22px;
}

/* Het ontwerp zet hier initialen in een vakje van 52. Hier zit het portret en
   de illustratie erin — dezelfde vorm, eigen inhoud. */
.v2-team-badge {
    position: relative;
    width: 52px;
    height: 52px;
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    background-color: var(--glass-fill-2);
    overflow: hidden;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.v2-team-badge img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* De illustratie is geen foto maar een tekening op transparante achtergrond;
   die moet passen in plaats van vullen, anders wordt hij bijgesneden. */
.v2-team-badge-plain img {
    width: 72%;
    height: 72%;
    object-fit: contain;
}

.v2-team-name {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 20px;
    line-height: normal;
    color: var(--ink);
    margin: 0;
}

.v2-team-role {
    font-size: 14px;
    color: var(--ink-2);
    margin: 3px 0 0;
}

.v2-team-text {
    font-size: 15.5px;
    line-height: 1.66;
    color: var(--ink-2);
    margin: 0 0 22px;
    text-wrap: pretty;
}

.v2-team-text p {
    margin: 0 0 12px;
}

.v2-team-text p:last-child {
    margin-bottom: 0;
}

.v2-team-card .v2-aside-head {
    margin-bottom: 12px;
}

.v2-team-block {
    margin-top: 64px;
}

.v2-team-block > h2 {
    font-family: var(--font-kop);
    text-wrap: balance;
    font-weight: 600;
    font-size: clamp(24px, 3vw, 28px);
    line-height: normal;
    letter-spacing: -0.018em;
    margin: 0 0 14px;
    color: var(--ink);
}

.v2-team-block .v2-overview-note {
    margin: 0 0 26px;
}

/* Het slotpanel. In het ontwerp een glazen vlak van 34/32 met een kop en één
   alinea van hooguit 760 breed — de belangrijkste alinea van de pagina, want
   hij zegt wat er níét gebeurt. */
.v2-panel {
    background-color: var(--glass-fill);
    backdrop-filter: blur(22px);
    -webkit-backdrop-filter: blur(22px);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 34px 32px;
    margin-top: 64px;
}

.v2-panel > h2 {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: clamp(24px, 3vw, 28px);
    line-height: normal;
    letter-spacing: -0.018em;
    margin: 0 0 14px;
    color: var(--ink);
}

.v2-panel > p {
    font-size: 17px;
    line-height: 1.72;
    color: var(--ink-2);
    margin: 0;
    max-width: 760px;
    text-wrap: pretty;
}

.v2-panel .v2-btn {
    margin-top: 24px;
}

/* Paginering onder een kaartraster. Het ontwerp kent geen gepagineerde lijst —
   de Insights-strook op de homepage toont er drie — dus dit is de vormtaal
   toegepast op iets wat er nog niet was: mono cijfers in glazen vakjes, en de
   huidige pagina in de accentkleur. */
.v2-pagination {
    margin-top: 44px;
}

.v2-pagination ul {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2-pagination a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background-color: var(--glass-fill-2);
    color: var(--ink-2);
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 13px;
    text-decoration: none;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.v2-pagination a:hover,
.v2-pagination a:focus-visible {
    border-color: var(--accent);
    color: var(--ink);
}

.v2-pagination a.is-current {
    border-color: var(--accent);
    background-color: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
}

/* De regel met auteur, categorie en datum onder de kop van een artikel. Het
   ontwerp toont die gegevens op de Insights-kaarten; op het artikel zelf staan
   ze als losse regel, want ze horen bij het stuk en niet bij de belofte erboven. */
.v2-byline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--ink-3);
    margin: 0 0 26px;
}

.v2-byline a {
    color: var(--ink-2);
}

.v2-article-tags {
    margin: 0 0 34px;
}

/* Een pagina die uit niets dan tekst bestaat — de juridische pagina's, de
   bevestigingen van de nieuwsbrief. Eén kolom van 760, dezelfde breedte als
   het slotpanel; wijder leest niet meer, smaller maakt van een alinea een
   kolommetje. */
.v2-tekstpagina {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(44px, 6vw, 68px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
}

.v2-tekstpagina > * {
    max-width: 760px;
}

.v2-tekstpagina .v2-detail-block:last-child {
    padding-bottom: 0;
}

/* Een korte melding midden op de pagina — bevestigd, uitgeschreven, of een
   foutpagina. Die hoort niet links uitgelijnd onderaan een lege pagina te
   staan. */
.v2-melding {
    max-width: 640px;
    margin: 0 auto;
    padding: clamp(56px, 8vw, 96px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
    text-align: center;
}

.v2-melding h1 {
    font-family: var(--font-kop);
    text-wrap: balance;
    font-weight: 600;
    font-size: clamp(30px, 4.4vw, 44px);
    line-height: 1.05;
    letter-spacing: -0.025em;
    margin: 0 0 18px;
    color: var(--ink);
}

.v2-melding p {
    font-size: 17px;
    line-height: 1.72;
    color: var(--ink-2);
    margin: 0 0 28px;
    text-wrap: pretty;
}

.v2-melding .v2-cta-row {
    justify-content: center;
}

/* De verwijzingen onder een 404. Iemand die hier belandt zocht iets; dan is
   een lijst nuttiger dan een verontschuldiging. */
.v2-melding-suggesties {
    margin-top: 48px;
    padding-top: 32px;
    border-top: 1px solid var(--line-2);
}

.v2-melding-suggesties ul {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.v2-melding-suggesties a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 10px 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background-color: var(--glass-fill-2);
    color: var(--ink-2);
    font-size: 14px;
    text-decoration: none;
    transition: border-color 0.18s ease, color 0.18s ease;
}

.v2-melding-suggesties a:hover,
.v2-melding-suggesties a:focus-visible {
    border-color: var(--accent);
    color: var(--ink);
}

/* Een pagina die uit één formulier bestaat — aanmelden voor de nieuwsbrief,
   toegang tot een besloten bèta. Smaller dan het contactformulier, want daar
   staan de gegevens ernaast en hier staat het formulier alleen. */
.v2-formpagina {
    max-width: 720px;
    margin: 0 auto;
    padding: clamp(44px, 6vw, 68px) clamp(20px, 4vw, 40px) clamp(72px, 9vw, 104px);
}

/* Toelichting onder een veld — waarom we het vragen, of wat er daarna gebeurt.
   Kleiner dan het veld zelf en in de gedempte tint, zodat hij leest als
   bijschrift en niet als foutmelding. */
.v2-veldhulp {
    font-size: 13px;
    line-height: 1.5;
    color: var(--ink-3);
    margin-top: 7px;
}

/* Het inschrijfblok midden in een artikel. Het staat waar iemand net iets
   nuttigs heeft gelezen — dat is het moment waarop de vraag gerechtvaardigd
   is, en niet onderaan in een voettekst. */
.v2-inline-nieuwsbrief {
    background-color: color-mix(in srgb, var(--accent) 7%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
    border-radius: var(--radius-lg);
    padding: 26px 24px;
    margin: 44px 0;
    max-width: 700px;
}

.v2-inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-start;
    margin-top: 16px;
}

.v2-inline-form .v2-input {
    flex: 1 1 15rem;
    width: auto;
}

.v2-inline-turnstile {
    flex-basis: 100%;
}

.v2-inline-nieuwsbrief .v2-veldhulp {
    margin-top: 14px;
}

/* ==========================================================================
   De voettekst

   Waarden uit het ontwerp: raster van 1.7fr en drie gelijke kolommen, glazen
   ondergrond met een lijn erboven, en onderaan een balk met de bedrijfsregel.
   ========================================================================== */

.v2-footer {
    position: relative;
    z-index: 10;
    border-top: 1px solid var(--line-2);
    background-color: var(--glass-fill-2);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

.v2-footer-inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: clamp(48px, 7vw, 60px) clamp(20px, 4vw, 40px) 28px;
    display: grid;
    grid-template-columns: 1.7fr 1fr 1fr 1fr;
    gap: clamp(30px, 4vw, 44px);
}

@media (max-width: 1080px) {
    .v2-footer-inner {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 680px) {
    .v2-footer-inner {
        grid-template-columns: 1fr;
    }
}

.v2-footer-logo {
    display: block;
}

.v2-footer-logo img,
.v2-footer-logo .v2-merk {
    height: 70px;
    width: auto;
    display: block;
    filter: var(--logo-filter, none);
}

/* Voedt `currentColor` in het merkteken, net als in de balk. Zonder dit erft
   de SVG de tekstkleur van de voettekst-container en dat is niet per se
   `--ink`. */
.v2-footer-logo {
    color: var(--ink);
}

.v2-footer-name {
    font-family: var(--font-kop);
    font-weight: 600;
    font-size: 17px;
    line-height: normal;
    color: var(--ink);
    margin: 18px 0 0;
}

.v2-footer-tagline {
    font-size: 14px;
    line-height: 1.6;
    color: var(--ink-3);
    margin: 9px 0 0;
    max-width: 300px;
    text-wrap: pretty;
}

.v2-footer-address {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 20px 0 0;
    font-style: normal;
    font-size: 14px;
    line-height: 1.5;
    color: var(--ink-2);
}

.v2-footer-address a {
    color: var(--ink-2);
    text-decoration: none;
}

.v2-footer-address a:hover,
.v2-footer-address a:focus-visible {
    color: var(--ink);
}

/* De sociale verwijzingen als woorden en niet als pictogrammen. Font Awesome
   hoort niet bij deze vormtaal, en een woord is bovendien voorleesbaar zonder
   dat er een verborgen tekst naast hoeft. */
.v2-footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin: 18px 0 0;
    font-size: 13.5px;
}

.v2-footer-social a {
    color: var(--ink-3);
    text-decoration: none;
    transition: color 0.18s ease;
}

.v2-footer-social a:hover,
.v2-footer-social a:focus-visible {
    color: var(--ink);
}

.v2-footer-head {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin: 0 0 16px;
}

.v2-footer-links {
    display: flex;
    flex-direction: column;
    gap: 11px;
    font-size: 14.5px;
    margin: 0;
}

.v2-footer-links a {
    color: var(--ink-2);
    text-decoration: none;
    transition: color 0.18s ease;
}

.v2-footer-links a:hover,
.v2-footer-links a:focus-visible {
    color: var(--ink);
}

.v2-footer-zakelijk {
    font-size: 13px;
    line-height: 1.7;
    color: var(--ink-3);
    margin: 20px 0 0;
}

.v2-footer-subscribe {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 clamp(20px, 4vw, 40px) 24px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px;
    font-size: 14px;
    color: var(--ink-2);
}

.v2-footer-subscribe a {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.v2-footer-subscribe a:hover,
.v2-footer-subscribe a:focus-visible {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.v2-footer-bottom {
    max-width: 1280px;
    margin: 0 auto;
    padding: 22px clamp(20px, 4vw, 40px);
    border-top: 1px solid var(--line-2);
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 13px;
    color: var(--ink-3);
}

.v2-footer-meta {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    opacity: 0.7;
}

/* ==========================================================================
   De mobiele oproepbalk

   Waarden uit het ontwerp. Verschijnt zodra de hero uit beeld raakt; het
   omschakelen doet enhancements.js, dat `aria-hidden` en `inert` samen
   omzet — die twee moeten het eens zijn, anders klaagt axe-core over
   focusbare elementen binnen aria-hidden.
   ========================================================================== */

.v2-mobile-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 80;
    display: none;
    align-items: center;
    gap: 10px;
    padding: 10px 16px;
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
    background-color: var(--panel);
    backdrop-filter: blur(26px) saturate(180%);
    -webkit-backdrop-filter: blur(26px) saturate(180%);
    border-top: 1px solid var(--line);
    box-shadow: 0 -12px 34px -20px rgba(0, 0, 0, 0.5);
    transform: translateY(100%);
    transition: transform 0.28s ease;
}

@media (max-width: 1080px) {
    .v2-mobile-cta {
        display: flex;
    }
}

.v2-mobile-cta.visible {
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .v2-mobile-cta {
        transition: none;
    }
}

.v2-mobile-cta-icon {
    width: 52px;
    height: 52px;
    flex-shrink: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background-color: var(--glass-fill-2);
    color: var(--ink);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
    text-decoration: none;
    transition: border-color 0.18s ease;
}

.v2-mobile-cta-icon:hover,
.v2-mobile-cta-icon:focus-visible {
    border-color: var(--accent);
}

.v2-mobile-cta-main {
    flex: 1;
    height: 52px;
    background-color: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
    font-size: 16px;
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    white-space: nowrap;
    text-decoration: none;
}

/* ==========================================================================
   Correcties uit de visuele steekproef van 2026-08-12

   Alle waarden nagemeten op het gerenderde ontwerp, met beide kanten in
   dezelfde lettertypes.
   ========================================================================== */

/* Het ontwerp geeft de drie kaartsoorten drie formaten: pijlers 21, diensten
   22, artikelen 20. Wij gebruikten overal 22 — dat maakt de pijlers te zwaar
   en de artikelen te log, en beide staan op dezelfde pagina naast elkaar. */
.v2-pillars .v2-card-title {
    font-size: 21px;
    margin-bottom: 11px;
}

.v2-article .v2-card-title {
    font-size: 20px;
    letter-spacing: -0.015em;
    margin-bottom: 11px;
}

/* De kop van het contactblok op de homepage is in het ontwerp groter dan de
   andere sectiekoppen — 46 tegen 44 — en heeft een eigen ondermarge. Dat is
   geen slordigheid in het ontwerp: dit blok is de laatste vraag op de pagina
   en mag zwaarder wegen dan de secties erboven. */
#contact-intro .v2-h2 {
    font-size: clamp(32px, 4.8vw, 46px);
    line-height: 1.03;
    letter-spacing: -0.028em;
    margin-bottom: 18px;
}

#contact-intro .v2-eyebrow {
    margin-bottom: 18px;
}

/* Het ontwerp scheidt de secties om en om met een haarlijn: opdrachten,
   diensten en veiligheid krijgen er een boven én onder, de secties ertussen
   niet. Dat wisselen is de reden dat de pagina niet als één lange kolom leest.
   Bij ons stond alleen de opdrachtenband omlijnd. */
#diensten,
#veiligheid {
    border-top: 1px solid var(--line-2);
    border-bottom: 1px solid var(--line-2);
}

/* ==========================================================================
   Correcties uit steekproefronde 4 — de codedemo en het veiligheidsblok

   De opmaak van de tabbladen staat in het ontwerp niet in de HTML maar in het
   script van de ontwerpomgeving (`t.style`). Vandaar dat die tot nu toe buiten
   de metingen viel: in de HTML staat alleen `style="{{ t.style }}"`. De
   waarden hieronder komen uit dat script.
   ========================================================================== */

/* Het ontwerp tekent de tabbladen als pillen, niet als browsertabs: rondom
   afgerond, een rand om het actieve blad, en zwaarder gezet. Bovenhoeken
   afronden liet ze vastzitten aan het venster eronder. */
.v2-demo-tab {
    min-height: 34px;
    padding: 7px 13px;
    font-size: 12.5px;
    letter-spacing: normal;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    transition: all 0.18s ease;
}

.v2-demo-tab[aria-selected="true"],
.v2-demo-tab[aria-pressed="true"] {
    border-color: var(--line);
    font-weight: 600;
}

/* Op een aanraakscherm blijft 44px de bodem: het ontwerp tekent geen vingers. */
@media (hover: none) {
    .v2-demo-tab {
        min-height: 44px;
    }
}

/* --- Drie correcties die achter een ondergrens moeten ---

   Deze drie stonden onder in het bestand zonder mediaquery, en overstemden
   daardoor de omklap op 1080 — bij de twee met een ID zelfs ongeacht volgorde,
   want een ID wint altijd van een klasse. Gevolg: het demopaneel en de twee
   splitsingen bleven op 900px in twee kolommen staan terwijl het ontwerp ze
   onder elkaar zet. Dat was op een tablet meteen te zien en in de code niet,
   want elke regel op zich klopte.

   Regel voor wat hier nog bij komt: een correctie op een raster dat een
   breekpunt heeft, hoort zelf ook een breekpunt te hebben. */
@media (min-width: 1081px) {
    /* Het rechterpaneel is in het ontwerp een vaste kolom van 300, geen
       breukdeel. Met 1.35fr/1fr kromp de codekolom mee op smallere schermen en
       brak de code af op plekken waar dat de leesbaarheid kostte. */
    .v2-demo-panel {
        grid-template-columns: 1fr 300px;
    }
}

.v2-demo-panel {
    min-height: 302px;
}

.v2-demo-code {
    padding: 22px 24px 26px;
    line-height: 1.85;
}

.v2-demo-aside {
    padding: 22px 24px;
}

@media (min-width: 1081px) {
    /* Twee gelijke kolommen, niet 1.1/0.9: het ontwerp geeft de tekst en het
       gelaagde vlak evenveel ruimte. */
    #veiligheid .v2-split {
        grid-template-columns: 1fr 1fr;
        gap: 64px;
    }
}

/* Het contactblok op de homepage staat bijna in evenwicht, niet op 1.1/0.9.
   Nagemeten in het ontwerp: 1.05fr/.95fr met een tussenruimte tot 52px, wat op
   1440 neerkomt op 602/546 in plaats van onze 627/513. Klein op papier, maar de
   rechterkolom draagt het paneel met de contactgegevens en die werd zo 33px
   smaller dan bedoeld. */
@media (min-width: 1081px) {
    #contact-intro .v2-split {
        grid-template-columns: 1.05fr 0.95fr;
        gap: clamp(36px, 5vw, 52px);
    }
}

/* ==========================================================================
   Steekproefronde 5 — de responsieve laag

   Het ontwerp bewaart zijn breekpunten niet in het script maar onderin het
   bestand, in twee blokken: 1080 en 680. Daar stond ook wat er op elk punt
   precies omklapt. Wij hadden elf eigen breekpunten verzonnen, waardoor
   onderdelen op verschillende momenten wisselden en de pagina tussen 680 en
   1080 nergens hetzelfde deed.

   Hieronder staat wat er in die twee blokken van het ontwerp stond en bij ons
   nog ontbrak.
   ========================================================================== */

@media (max-width: 1080px) {
    /* De mobiele oproepbalk verschijnt in het ontwerp al bij 1080, niet pas
       bij 768 — en de pagina krijgt dan onderaan ruimte zodat de balk niets
       afdekt. */
    .v2-mobile-cta {
        display: flex;
    }

    body:has(.v2-mobile-cta.visible) {
        padding-bottom: 84px;
    }

    /* De zijkolom stopt met meescrollen en wordt begrensd, zodat hij onder de
       tekst niet de volle breedte inneemt. */
    .v2-aside {
        position: static;
        max-width: 420px;
    }

    /* De scheiding tussen code en toelichting draait mee: verticaal wordt
       horizontaal. Zonder dit staat er een lijn langs de zijkant van niets. */
    .v2-demo-code {
        border-right: 0;
    }

    .v2-demo-aside {
        border-left: 0;
        border-top: 1px solid var(--line-2);
    }

    /* Drie kolommen worden er twee, niet meteen één. */
    .v2-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .v2-footer-inner {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 680px) {
    .v2-grid,
    .v2-grid-2,
    .v2-footer-inner {
        grid-template-columns: 1fr;
    }

    /* De logostrook loopt trager op een klein scherm: dezelfde snelheid over
       minder breedte leest als jachtig. */
    .v2-marquee-row {
        /* Dezelfde verhouding als hierboven: het ontwerp vertraagt onder 680 met
           een factor 1,5, dus 87 wordt 134. */
        animation-duration: 134s;
    }

    /* Minder gekleurd licht en een lichtere vervaging. Het eerste is smaak,
       het tweede is snelheid: blur over de volle breedte kost op een telefoon
       merkbaar meer dan op een laptop. */
    .v2-mesh {
        opacity: 0.26;
    }

    .v2-form-card,
    .v2-cta-panel,
    .v2-nav-inner {
        backdrop-filter: blur(16px) saturate(150%);
        -webkit-backdrop-filter: blur(16px) saturate(150%);
    }

    .v2-nav {
        padding: 10px 12px 0;
    }
}

/* ==========================================================================
   Steekproefronde 6 — de bewegingslaag

   Vier gedragingen die het ontwerp niet in zijn HTML zet maar in het script
   van zijn eigen omgeving. Ze waren daardoor onzichtbaar in elke meting die
   we op het bestand deden. Aansturing: public/js/v2-motion.js.
   ========================================================================== */

/* --- De balk krimpt na 40px scrollen --- */

.v2-nav[data-scrolled="1"] {
    padding-top: 8px;
}

.v2-nav[data-scrolled="1"] .v2-nav-inner {
    padding: 5px 8px 5px 14px;
    background-color: var(--glass-fill-hi);
    border-radius: var(--radius-lg);
}

.v2-nav[data-scrolled="1"] .v2-brand img {
    height: 34px;
}

.v2-nav,
.v2-nav-inner,
.v2-brand img {
    transition: padding 0.28s ease, background-color 0.28s ease,
                border-radius 0.28s ease, height 0.28s ease;
}

@media (prefers-reduced-motion: reduce) {
    .v2-nav,
    .v2-nav-inner,
    .v2-brand img {
        transition: none;
    }
}

/* --- De laag waarin het herobeeld zit ---

   Was overmaats (-8%) omdat hij met de scroll meeschoof; die parallax is eruit,
   want hij zette een tweede beweging over een lus die juist een stilstaande
   camera heeft. Nu sluitend, zodat het beeld precies het vlak vult en er niets
   onnodig buiten het kader wordt gerenderd. */

.v2-hero-media-inner {
    position: absolute;
    inset: 0;
}

/* --- Onderdelen komen getrapt in beeld ---

   De vertraging en de duur per onderdeel zet v2-motion.js; hier staat alleen
   waar ze vandaan komen en waar ze heen gaan. */

[data-rv] {
    opacity: 0;
    transform: translateY(26px);
    transition:
        opacity 0.82s cubic-bezier(0.16, 0.84, 0.28, 1),
        transform 0.82s cubic-bezier(0.16, 0.84, 0.28, 1);
}

[data-rv="in"] {
    opacity: 1;
    transform: none;
}

/* Zonder JavaScript blijft er anders een lege pagina staan. */
html:not(.js) [data-rv] {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    [data-rv] {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* --- De gelaagde stapel kantelt mee ---

   `--t` loopt van -1 tot 1 en komt uit de scrollpositie. De twee bovenste
   vlakken komen naar je toe terwijl de onderste terugwijken; dat is wat het
   perspectief laat draaien zonder dat er iets roteert. */

.v2-layers-stack {
    --t: 0;
}

.v2-layer:nth-child(1) { transform: translateZ(calc(138px + var(--t, 0) * 14px)); }
.v2-layer:nth-child(2) { transform: translateZ(calc(92px + var(--t, 0) * 6px)); }
.v2-layer:nth-child(3) { transform: translateZ(calc(46px - var(--t, 0) * 6px)); }
.v2-layer:nth-child(4) { transform: translateZ(calc(0px - var(--t, 0) * 14px)); }

/* Het ontwerp toont de stapel alleen boven 1080 met een muis. Op een
   aanraakscherm valt hij terug op vier vlakken onder elkaar: een gekantelde
   stapel die niet kan kantelen is een plaatje dat scheef staat. */
@media (max-width: 1080px), (hover: none) {
    .v2-layers {
        perspective: none;
    }

    /* Dit is de platte variant uít het ontwerp, niet een eigen noodoplossing.

       Het ontwerp heeft dit onderdeel twee keer: gekanteld boven 1081px met een
       muis, en hieronder vier vlakken die steeds bréder worden — 78, 52, 26 en 0
       inspringing — met het label links in elk vlak. Daar staat dus niets in de
       weg en zijn alle vier de namen gewoon te lezen.

       Hier stond een gewone lijst van vier balkjes. Dat draagt de boodschap ook,
       maar het is niet wat er ontworpen is, en het is minder: de trapvorm ís de
       boodschap — elke laag ligt óm de vorige heen.

       Maten als percentage van het vierkante vlak, zodat het meeschaalt; het
       ontwerp rekent ze in pixels op een vak van 460. */
    .v2-layers-stack {
        position: absolute;
        inset: 0;
        width: auto;
        height: auto;
        transform: none;
    }

    .v2-layer {
        position: absolute;
        height: 25.7%;
        border-radius: var(--radius-lg);
        transform: translateY(calc(var(--t, 0) * var(--drift, 0px))) !important;
        display: flex;
        align-items: center;
        padding: 0 20px;
    }

    .v2-layer:nth-child(1) { top: 9.6%;  left: 17%;   right: 17%;   --drift: -13px; }
    .v2-layer:nth-child(2) { top: 28.3%; left: 11.3%; right: 11.3%; --drift: -4px; }
    .v2-layer:nth-child(3) { top: 47%;   left: 5.7%;  right: 5.7%;  --drift: 4px; }
    .v2-layer:nth-child(4) { top: 65.7%; left: 0;     right: 0;     --drift: 13px; }

    .v2-layer span {
        position: static;
        transform: none;
        margin: 0;
    }
}

/* --- De gloed in het oproeppaneel drijft --- */

.v2-cta-glow {
    animation: v2-drift 28s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
    .v2-cta-glow {
        animation: none;
    }
}

/* ==========================================================================
   Contrast van links en statustekst — nagemeten 2026-08-12

   De site is per element doorgerekend in beide themas. Wat eruit kwam is de
   valkuil die in CLAUDE.md staat: de standaard linkkleur (#94a3b8) haalt
   2,56:1 op een lichte ondergrond en werkt alleen op de donkere balk en
   voettekst. Elke nieuwe lichte container met lopende links moet zijn eigen
   kleur zetten.

   Deze v2-containers stonden nog niet in die lijst: de inleiding onder een
   paginakop, de toelichting onder een formulier, en de kaarttekst. Ze halen nu
   --accent-ink, dat per thema is afgesteld — 6,18:1 op licht.
   ========================================================================== */

.v2-page-lead a,
.v2-form-note a,
.v2-veldhulp a,
.v2-ocard-text a,
.v2-consent a,
.v2-status-text a,
.v2-team-text a {
    color: var(--accent-ink);
}

/* De statuskop is groen op een groen getinte kaart. In het donkere thema klopt
   dat; op licht haalde het volle groen 1,88:1. Deze drie tinten zijn de
   donkere varianten, alleen voor het lichte thema — het bolletje ernaast houdt
   zijn volle kleur, want dat draagt geen tekst. */
[data-theme="light"] .v2-status-available .v2-status-head { color: #0a7047; }
[data-theme="light"] .v2-status-limited .v2-status-head { color: #8a5a00; }
[data-theme="light"] .v2-status-unavailable .v2-status-head { color: #a4231b; }

@media (prefers-color-scheme: light) {
    :root:not([data-theme="dark"]) .v2-status-available .v2-status-head { color: #0a7047; }
    :root:not([data-theme="dark"]) .v2-status-limited .v2-status-head { color: #8a5a00; }
    :root:not([data-theme="dark"]) .v2-status-unavailable .v2-status-head { color: #a4231b; }
}

/* Inline code in lopende tekst haalde 3,71 op licht en 4,42 op donker; beide
   onder de eis van 4,5. De tekstkleur volgt nu de gewone tekstkleur en de
   herkenbaarheid komt van het vlak eromheen, niet van een lichtere letter. */
.v2-detail-block code,
.v2-team-text code,
.v2-page-lead code {
    color: var(--ink);
    background-color: var(--glass-fill-2);
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    padding: 1px 5px;
    font-family: var(--font-mono);
    font-size: 0.92em;
}

/* De deelknoppen onder een artikel stonden op 3,49 in het donkere thema. Ze
   dragen tekst, dus 4,5 is de eis en niet 3. */
.blog-share-link,
.blog-share-link span {
    color: var(--ink-2);
}

.blog-share-link:hover,
.blog-share-link:focus-visible,
.blog-share-link:hover span,
.blog-share-link:focus-visible span {
    color: var(--ink);
}

/* Het logo van een opdrachtgever in de zijkolom. Klein en op wit, want de
   meeste logos zijn voor een lichte ondergrond gemaakt en verdwijnen op het
   donkere thema. Passen in plaats van vullen: uitrekken vervormt een merk. */
.v2-logo-card {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px 20px;
    background-color: #ffffff;
}

.v2-logo-card img {
    max-width: 100%;
    max-height: 56px;
    width: auto;
    height: auto;
    object-fit: contain;
}

/* ── Doorsnede van het beeld ────────────────────────────────────────────────
   Een beeld dat wij zelf gebouwd hebben is alleen als zodanig herkenbaar als je
   het kunt laten zien. De doorsnede is dezelfde scène, dezelfde camera, in klei
   met de randen erop — van een gegenereerd beeld bestaat die niet.

   Geen JavaScript: een verborgen selectievakje plus `:checked` doet hetzelfde.
   Dat werkt met toetsenbord en schermlezer, en het scheelt een script op een
   site waarvan de CSP alleen eigen scripts toestaat. */
.v2-detail-media { position: relative; }

.v2-bouw-beeld {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity .45s ease;
}
.v2-bouw-beeld img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }

/* Binnen een montuur moet de doorsnede dezelfde marge aanhouden als het
   eindbeeld, anders dekt hij de rand van het podium af en springt het object
   bij het omschakelen. Alleen hier gescoped: op de dienstpagina zit de
   schakelaar in een wikkel zónder montuur. */
.v2-detail-media .v2-bouw-beeld {
  inset: var(--podium-marge);
  border-radius: calc(var(--radius-lg) - var(--podium-marge) / 2);
  overflow: hidden;
}
.v2-bouw-schakelaar:checked ~ .v2-bouw-beeld { opacity: 1; }

/* Onzichtbaar, maar wél te focussen.

   Het vakje droeg eerst het `hidden`-attribuut. Dat is `display: none`, en wat
   niet weergegeven wordt kan de focus niet krijgen — het label evenmin, want
   dat verwijst naar een element dat er voor de browser niet is. De schakelaar
   ontbrak daardoor volledig in de tabvolgorde: WCAG 2.1.1 Keyboard, niveau A,
   op zestien pagina's.

   Deze vorm houdt hem uit beeld zonder hem uit de boom te halen. Géén
   `visibility: hidden` of `display: none` — die maken hem opnieuw
   onbereikbaar. De `:focus-visible`-regel hieronder zet de rand vervolgens op
   de knop, want dáár kijkt de gebruiker. */
.v2-bouw-schakelaar {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.v2-bouw-knop {
  position: absolute;
  right: var(--space-3, 1rem);
  bottom: var(--space-3, 1rem);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;              /* WCAG 2.5.8, net als de andere knoppen */
  padding: .55rem 1rem;
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--radius-full);
  background: rgba(10, 10, 18, .62);
  backdrop-filter: blur(14px);
  color: #f3f4f6;
  font-family: var(--font-mono);
  font-size: .78rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .25s ease, border-color .25s ease;
}
.v2-bouw-knop:hover { background: rgba(10, 10, 18, .82); border-color: rgba(255, 255, 255, .3); }
.v2-bouw-schakelaar:focus-visible ~ .v2-bouw-knop {
  outline: 2px solid var(--color-primary, #fcb15c);
  outline-offset: 2px;
}

/* Eén label, twee teksten: welke er staat hangt af van waar je nu naar kijkt. */
.v2-bouw-uit { display: none; }
.v2-bouw-schakelaar:checked ~ .v2-bouw-knop .v2-bouw-aan { display: none; }
.v2-bouw-schakelaar:checked ~ .v2-bouw-knop .v2-bouw-uit { display: inline; }

.v2-bouw-bijschrift {
  margin: .75rem 0 0;
  /* `--color-details` (#94a3b8) haalde op de lichte pagina 2,11:1 waar 4,5
     moet. Dat token hoort bij de donkere balk en voettekst en faalt op elke
     lichte ondergrond — het staat zo in CLAUDE.md én twintig regels hierboven
     in dit bestand, en werd hier alsnog gepakt.

     `--ink-2` is per thema afgesteld en haalt beide kanten ruim. */
  color: var(--ink-2);
  font-size: .85rem;
  line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
  .v2-bouw-beeld, .v2-bouw-knop { transition: none; }
}

/* De lus in de hero-slot, sluitend in `.v2-hero-media-inner`. */
.v2-hero-video {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Een sluier over de lus. Zonder deze is het beeldvlak duidelijk feller dan de
   rest van de hero en trekt het de aandacht weg van de kop — terwijl het
   statuspaneel er ook nog overheen moet blijven staan. Naar onderen toe donkerder,
   want daar zit dat paneel. */
.v2-hero-video-sluier {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(10, 10, 18, 0.20), rgba(10, 10, 18, 0.58));
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   Kaartdiepte

   Eén regel, en met opzet één regel: hij is tegelijk de lijst van wat op deze
   site een kaart ís. Stond de schaduw bij elk onderdeel apart, dan was er geen
   plek waar dat te overzien viel en zou de zesde kaart hem missen.

   Waarom dit nodig is staat bij `--shadow-card` in `variables.css`: de
   kaart-tegen-pagina-verhouding was in beide thema's 1,11:1, en dat is
   symmetrisch maar niet gelijkwaardig. Op donker leest die stap als een vlak,
   op licht als niets. In het donkere thema is dit token `none`, dus daar
   verandert deze regel niets — hij bestaat alleen om de lichte kant terug te
   geven wat ze miste.

   `.v2-nav-inner` staat er bewust niet bij: die draagt al `--shadow-deep` en
   hoort te zweven, niet te liggen.
   -------------------------------------------------------------------------- */
.v2-aside-card,
.v2-cta-panel,
.v2-form-card,
.v2-contact-aside,
.v2-data-card,
.v2-status-card,
.v2-ocard,
.v2-faq-card,
.v2-quote,
.v2-portret-card,
.v2-team-card,
.v2-panel {
    box-shadow: var(--shadow-card);
}

/* --------------------------------------------------------------------------
   Ontwerpsysteem (/nl/ontwerpsysteem)

   De monsters gebruiken de tokens die ze tonen — een vlak dat `--surface`
   laat zien ís `--surface`. Daarom staat hier geen enkele kleurwaarde: zodra
   die er wél stond, kon de pagina afwijken van de site, en dat is precies wat
   de vorige versie vier maanden deed.

   De twee helften van elk monster tonen het donkere én het lichte thema naast
   elkaar, ongeacht in welk thema je kijkt. Dat kan alleen met vaste waarden
   uit het sjabloon, dus die staan daar inline — de enige plek waar dat mag.
   -------------------------------------------------------------------------- */

.v2-ds-groep {
    margin: var(--space-5) 0 var(--space-2);
    font-family: var(--font-kop);
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
}

.v2-ds-rooster {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 14px;
}

.v2-ds-token {
    padding: 12px;
    background: var(--glass-fill);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

/* Twee helften, gescheiden door een haarlijn: links donker, rechts licht.
   Een dambordondergrond zodat doorzichtige tokens als doorzichtig lezen en
   niet als een egale kleur. */
.v2-ds-monsters {
    display: flex;
    height: 46px;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background-image:
        linear-gradient(45deg, var(--line-2) 25%, transparent 25%),
        linear-gradient(-45deg, var(--line-2) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--line-2) 75%),
        linear-gradient(-45deg, transparent 75%, var(--line-2) 75%);
    background-size: 12px 12px;
    background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}

.v2-ds-monster {
    flex: 1 1 50%;
}

.v2-ds-monster.is-licht {
    border-left: 1px solid var(--line);
}

.v2-ds-naam {
    display: block;
    margin-top: 10px;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--accent-ink);
    word-break: break-all;
}

.v2-ds-waarden {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 10px;
    margin: 8px 0 0;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink-2);
}

.v2-ds-waarden dt {
    color: var(--ink-3);
}

.v2-ds-waarden dd {
    margin: 0;
    word-break: break-all;
}

/* Brede inhoud scrollt in zijn eigen doos; de pagina zelf nooit zijwaarts. */
.v2-ds-tabelwikkel {
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--glass-fill);
    box-shadow: var(--shadow-card);
}

.v2-ds-tabel {
    width: 100%;
    min-width: 34rem;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.v2-ds-tabel th,
.v2-ds-tabel td {
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--line-2);
}

.v2-ds-tabel thead th {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 400;
    color: var(--ink-3);
}

.v2-ds-tabel tbody th {
    font-weight: 600;
    color: var(--ink);
}

.v2-ds-tabel tr:last-child th,
.v2-ds-tabel tr:last-child td {
    border-bottom: 0;
}

.v2-ds-tabel code {
    font-size: 0.82em;
    color: var(--ink-2);
}

/* Cijfers onder elkaar uitlijnen; anders is een kolom getallen niet te
   vergelijken en is de tabel alleen sier. */
.v2-ds-getal {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

.v2-ds-getal.is-goed { color: var(--ok); }
.v2-ds-getal.is-fout { color: var(--accent-ink); font-weight: 600; }
.v2-ds-getal.is-eis  { color: var(--ink-3); }

.v2-ds-noot {
    margin: 14px 0 0;
    max-width: 62ch;
    font-size: 0.88rem;
    color: var(--ink-2);
}

.v2-ds-uitleg {
    margin: 10px 0 0;
    max-width: 66ch;
    color: var(--ink-2);
}

.v2-ds-schaal {
    display: grid;
    gap: 10px;
}

.v2-ds-schaal li {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 8px 12px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
}

.v2-ds-schaal code {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--accent-ink);
    flex: 0 0 8.5rem;
}

.v2-ds-maat {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    color: var(--ink-3);
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

.v2-ds-proef {
    font-family: var(--font-kop);
    line-height: 1;
    color: var(--ink);
    flex: 0 0 4.5rem;
}

.v2-ds-hoek {
    display: block;
    width: 46px;
    height: 34px;
    flex: none;
    background: var(--glass-fill-hi);
    border: 1px solid var(--line);
}

.v2-ds-ruimte {
    display: block;
    height: 14px;
    flex: none;
    background: var(--accent);
    border-radius: var(--radius-sm);
}

.v2-ds-onderdelen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: 16px;
}

.v2-ds-rij {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}

/* Een schaduwtoken laat zich niet als vlak tonen. Een klein wit plaatje mét
   de schaduw eronder wél — op de lichte waarde, want in het donker is het
   token `none` en zou er niets te zien zijn. */
.v2-ds-monsters.is-schaduw {
    background: var(--glass-fill-2);
    align-items: center;
    justify-content: center;
}

.v2-ds-schaduwproef {
    display: block;
    width: 62px;
    height: 26px;
    background: #fff;
    border-radius: var(--radius-sm);
}

/* Ontwerpsysteem — letters, beeldregels en de stiltes.

   De letterproef zet elke stapel op zichzelf: `style="font-family: {{ stapel }}"`
   in het sjabloon, uit het token. Zo toont de pagina de letter die er wérkelijk
   staat en niet de letter waarvan iemand ooit opschreef dat hij er stond. */
.v2-ds-letters {
    display: grid;
    gap: 10px;
    margin-top: 14px;
}

.v2-ds-letters li {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 12px 14px;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
}

/* De oude laag gedempt: hij hoort erbij als feit, niet als voorbeeld. */
.v2-ds-letters li.is-legacy {
    opacity: 0.62;
}

.v2-ds-letterproef {
    flex: 0 0 3.4rem;
    font-size: 2.1rem;
    line-height: 1;
    color: var(--ink);
}

.v2-ds-letters code {
    display: block;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--accent-ink);
}

.v2-ds-stapel {
    display: block;
    margin-top: 3px;
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--ink-3);
    word-break: break-word;
}

.v2-ds-merk {
    margin-left: auto;
    flex: none;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.25em 0.5em;
}

/* Het montuur op deze pagina is het echte blok, met twee verschillen: geen
   44px marge eronder (de regels komen er direct achteraan) en begrensd in
   breedte. Op volle sectiebreedte werd het 1200 en ging het als hero lezen —
   het is een demonstratie van een onderdeel, niet het onderwerp. */
.v2-ds-montuur {
    max-width: 44rem;
    margin-bottom: 22px;
}

.v2-ds-regels {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
    gap: 14px;
    margin-top: 18px;
}

.v2-ds-regels li {
    padding: 14px 16px;
    background: var(--glass-fill);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.v2-ds-regels b {
    display: block;
    font-family: var(--font-kop);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
}

.v2-ds-regels span {
    display: block;
    margin-top: 6px;
    font-size: 0.9rem;
    line-height: 1.58;
    color: var(--ink-2);
}

/* ─── Bewegend artikelbeeld ────────────────────────────────────────────────
   De clip ligt óver de still en is aanvankelijk doorzichtig. Twee gevolgen die
   allebei bedoeld zijn: de afbeelding is en blijft het element dat de
   laadtijd bepaalt, en als de clip nooit komt is er niets te zien van een
   mislukking — er staat gewoon een plaatje.

   Geen `display: none` op de video: dan telt hij niet mee voor de hoogte en
   springt het blok bij het verschijnen. Nu ligt hij absoluut in dezelfde doos.

   `pointer-events: none` houdt de contextmenu-op-video weg. Een artikelbeeld
   is geen mediaspeler en hoort zich er ook niet als één te gedragen. */
.v2-media-beweegt {
    position: relative;
    display: block;
}

.v2-media-beweegt > picture,
.v2-media-beweegt > picture > img {
    display: block;
    width: 100%;
    height: auto;
}

/* Binnen een montuur neemt de houder exact de plek in die de afbeelding daar
   zelf innam — anders schuift er een laag tussen met hoogte nul en zakt het
   montuur in elkaar. Precies dat gebeurde: de still stond er nog (die is
   absoluut gepositioneerd en pakte de figure als anker) terwijl de video nul
   hoog was, dus het zag eruit alsof de clip niet werkte terwijl hij gewoon
   speelde. De maten staan er expliciet om dezelfde reden als hierboven bij
   `.v2-detail-media img`. */
.v2-detail-media > .v2-media-beweegt {
    position: absolute;
    inset: var(--podium-marge);
    width: calc(100% - var(--podium-marge) * 2);
    height: calc(100% - var(--podium-marge) * 2);
}

.v2-detail-media > .v2-media-beweegt > picture > img,
.v2-detail-media > .v2-media-beweegt > .v2-media-clip {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: calc(var(--radius-lg) - var(--podium-marge) / 2);
}

.v2-media-clip {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 420ms ease;
    pointer-events: none;
}

.v2-media-beweegt.speelt .v2-media-clip { opacity: 1; }

/* Twee vangnetten bovenop de vier poorten in `beweging.js`. Die poorten worden
   één keer gedraaid, bij het laden; wie daarná zijn venster versmalt of in het
   besturingssysteem beweging uitzet, houdt anders een lopende clip. */
@media (max-width: 767.98px) {
    .v2-media-clip { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .v2-media-clip { display: none; }
}

/* ------------------------------------------------------------------
   Plugin-familiepagina's — Lite en Pro als twee vlakken in de tekstkolom.

   Het anker #pro is het adres waar de beheerkaart in de plugins zelf naar
   wijst; de plakkende navigatie mag die kop niet bedekken, vandaar de
   scroll-marge. Het Pro-vlak krijgt de accentkleur licht mee, zoals het
   oproepvak in de zijkolom — hetzelfde signaal met dezelfde middelen.
   ------------------------------------------------------------------ */
.v2-editie {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 22px 24px;
    scroll-margin-top: 96px;
}

.v2-editie--pro {
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
    background-color: color-mix(in srgb, var(--accent) 6%, transparent);
}

.v2-editie .v2-eyebrow {
    margin-bottom: 6px;
}

.v2-editie h3 {
    margin-top: 0;
}

.v2-editie-code {
    margin: 14px 0;
    padding: 12px 16px;
    overflow-x: auto;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-sm);
    background-color: var(--glass-fill-2);
    font-family: var(--font-mono);
    font-size: 14px;
    line-height: 1.5;
}

/* De code-opmaak van de tekstkolom zet een kader om elk <code>; binnen het
   codevlak is dat kader dubbelop. */
.v2-detail-block .v2-editie-code code {
    border: 0;
    padding: 0;
    background-color: transparent;
    font-size: inherit;
}

.v2-editie-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
}

.v2-editie-cta {
    margin-top: 18px;
}

/* Het kopje boven het raster met de andere families staat in een eigen
   tekstblok; zonder deze regel houdt dat blok zijn volle ondermarge en zweeft
   het raster los van zijn kop. */
.v2-editie-anderen {
    margin-bottom: 0;
}
