    /* ---- brand fonts ---- */
    @font-face {
        font-family: 'Stencilla';
        src: url('/fonts/viper/stencilla.woff2') format('woff2'),
             url('/fonts/viper/stencilla.ttf') format('truetype');
        font-weight: 400;
        font-display: swap;
    }
    @font-face {
        font-family: 'Archivo';
        src: url('/fonts/viper/archivo-var.woff2') format('woff2');
        font-weight: 100 900;
        font-display: swap;
    }
    @font-face {
        font-family: 'Archivo Black';
        src: url('/fonts/viper/archivo-black-400.woff2') format('woff2');
        font-weight: 400;
        font-display: swap;
    }

    .vn-page {
        font-family: 'Archivo', sans-serif;
        --vn-ease: cubic-bezier(.19, 1, .22, 1);
    }
    .vn-display { font-family: 'Stencilla', 'Archivo Black', sans-serif; }
    .vn-black { font-family: 'Archivo Black', 'Archivo', sans-serif; }

    /* ---- subtle grain over everything ---- */
    .vn-grain {
        position: fixed;
        inset: -50%;
        width: 200%;
        height: 200%;
        pointer-events: none;
        z-index: 60;
        opacity: .05;
        background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
        animation: vn-grain-shift 1.2s steps(4) infinite;
    }
    @keyframes vn-grain-shift {
        0% { transform: translate(0, 0); }
        25% { transform: translate(-2%, 1%); }
        50% { transform: translate(1%, -2%); }
        75% { transform: translate(-1%, 2%); }
        100% { transform: translate(0, 0); }
    }

    /* ---- reveals ---- */
    .vn-reveal { opacity: 0; transform: translateY(48px); transition: opacity 1s var(--vn-ease), transform 1.2s var(--vn-ease); }
    .vn-reveal.vn-in { opacity: 1; transform: none; }
    .vn-reveal-line { display: block; overflow: hidden; }
    .vn-reveal-line > span { display: block; transform: translateY(110%); transition: transform 1.1s var(--vn-ease); }
    .vn-in .vn-reveal-line > span { transform: none; }
    .vn-mask { clip-path: inset(0 100% 0 0); transition: clip-path 1.4s var(--vn-ease); }
    .vn-mask.vn-in, .vn-in .vn-mask { clip-path: inset(0 0 0 0); }

    /* staggers */
    .vn-in .vn-s1 > span { transition-delay: .05s; }
    .vn-in .vn-s2 > span { transition-delay: .18s; }
    .vn-in .vn-s3 > span { transition-delay: .31s; }
    .vn-in .vn-s4 > span { transition-delay: .44s; }

    /* ---- hero type ---- */
    .vn-hero-title {
        font-size: clamp(4.2rem, 19vw, 21rem);
        line-height: .82;
        letter-spacing: -.01em;
    }
    .vn-hero-title .vn-line { display: block; overflow: hidden; }
    .vn-hero-title .vn-line > span { display: inline-block; transform: translateY(105%); transition: transform 1.3s var(--vn-ease); }
    .vn-hero-loaded .vn-hero-title .vn-line > span { transform: none; }
    .vn-hero-loaded .vn-hero-title .vn-line:nth-child(2) > span { transition-delay: .15s; }

    /* ghost section labels */
    .vn-ghost {
        font-size: clamp(5rem, 22vw, 24rem);
        line-height: 1;
        color: transparent;
        -webkit-text-stroke: 1px rgba(255, 255, 255, .14);
        user-select: none;
    }
    .vn-ghost-dark { -webkit-text-stroke: 1px rgba(0, 0, 0, .12); }

    /* ---- hover distortion ---- */
    .vn-distort { transition: transform .6s var(--vn-ease), filter .6s var(--vn-ease), letter-spacing .6s var(--vn-ease); }
    .vn-distort:hover { transform: skewX(-4deg) scale(1.015); filter: contrast(1.25); }
    a.vn-distort:hover { letter-spacing: .12em; }
    .vn-img-distort img { transition: transform 1s var(--vn-ease), filter 1s var(--vn-ease); }
    .vn-img-distort:hover img { transform: scale(1.05) skewX(-1.2deg); filter: contrast(1.2) brightness(1.05); }

    /* marquee */
    .vn-marquee-track { display: flex; width: max-content; animation: vn-marquee 26s linear infinite; }
    @keyframes vn-marquee { to { transform: translateX(-50%); } }

    /* slider */
    .vn-slide-track { display: flex; transition: transform .85s var(--vn-ease); }
    .vn-thumb { filter: grayscale(1) contrast(1.1); transition: opacity .4s, outline-color .4s, transform .4s var(--vn-ease); outline: 2px solid transparent; outline-offset: 3px; }
    .vn-thumb:hover { transform: translateY(-4px); }
    .vn-thumb.vn-active { outline-color: currentColor; opacity: 1 !important; }

    html { scroll-behavior: smooth; }

    @media (prefers-reduced-motion: reduce) {
        .vn-grain { animation: none; }
        .vn-marquee-track { animation-duration: 80s; }
        .vn-reveal, .vn-reveal-line > span, .vn-mask, .vn-hero-title .vn-line > span { transition-duration: .01s !important; }
    }
    /* calmer on mobile */
    @media (max-width: 640px) {
        .vn-grain { opacity: .035; }
        .vn-distort:hover { transform: none; }
    }

/* ---- global width limit: the experience is a capped canvas, the void continues beyond ---- */
.vn-page {
    max-width: 1680px;
    margin-inline: auto;
}

/* ---- failsafe: geen enkel reveal-element mag ooit verborgen blijven.
   Als de IntersectionObserver (of JS zelf) niet vuurt, forceert deze
   animatie na 2.8s de zichtbare eindtoestand. ---- */
@keyframes vn-failsafe {
    to {
        opacity: 1;
        transform: none;
        clip-path: inset(0 0 0 0);
    }
}
/* alleen wanneer JS het element NIET onder observatie nam (vn-armed ontbreekt) */
.vn-reveal:not(.vn-armed),
.vn-mask:not(.vn-armed) {
    animation: vn-failsafe .8s var(--vn-ease) 2.8s forwards;
}
.vn-reveal-line > span,
.vn-hero-title .vn-line > span {
    animation: vn-failsafe .8s var(--vn-ease) 2.2s forwards;
}
