/*
 * gm-motion.css - de bewegingslaag van core.
 *
 * Core laadt dit bestand zelf (Integrations\Assets, na gm-blokken.css), samen
 * met resources/js/gm-motion.js. Het is de laag boven gm-blokken.css: die doet
 * secties, kaarten en de eenvoudige reveal, deze doet het werk waar een site
 * duur van gaat ogen en dat te veel beurten kost om per site opnieuw te
 * schrijven.
 *
 * Waarom in core: een bouwer die dit zelf in vanilla JS moet uitvinden komt aan
 * zijn budget niet toe, dus sneuvelde de beweging altijd als eerste. Nu staat
 * het er, en gaat de tijd naar het ontwerp.
 *
 * Alles is opt-in via data-attributen, alles werkt zonder JS (dan staat het
 * gewoon stil en zichtbaar) en alles gaat uit bij prefers-reduced-motion.
 *
 * Inhoud:
 *   1. Variabelen
 *   2. Mask-reveal        data-gm-mask
 *   3. Gesplitste tekst   data-gm-split
 *   4. Scroll-scrub       data-gm-scrub  (+ --gm-p en drie hulpclasses)
 *   5. Magnetisch         data-gm-magnetic
 *   6. Kantelen           data-gm-tilt
 *   7. Voortgangsbalk     data-gm-progress
 *   8. Paginawissel       data-gm-wipe
 *   9. Cursor             data-gm-cursor
 *  10. prefers-reduced-motion
 */

/* ---------------------------------------------------------------------------
 * 1. Variabelen
 * ------------------------------------------------------------------------- */

:root {
    --gm-motion-duur: 900ms;
    --gm-motion-curve: cubic-bezier(0.22, 1, 0.36, 1);
    --gm-motion-curve-wipe: cubic-bezier(0.76, 0, 0.24, 1);

    --gm-mask-duur: 1100ms;
    --gm-mask-stap: 90ms;

    --gm-split-stap: 35ms;
    --gm-split-duur: 850ms;

    --gm-wipe-duur: 520ms;
    --gm-wipe-kleur: var(--color-body-active, #111111);

    --gm-cursor-maat: 28px;
    --gm-cursor-kleur: var(--color-primary, currentColor);
}

/* ---------------------------------------------------------------------------
 * 2. Mask-reveal
 *
 *   <img data-gm-mask>                    veegt van onder naar boven open
 *   <div data-gm-mask="onder|links|rechts">
 *   <div data-gm-stagger data-gm-mask>    kinderen veegt hij één voor één open
 * ------------------------------------------------------------------------- */

.gm-js [data-gm-mask] {
    clip-path: inset(100% 0 0 0);
    transition: clip-path var(--gm-mask-duur) var(--gm-motion-curve-wipe);
    transition-delay: calc(var(--gm-i, 0) * var(--gm-mask-stap));
    will-change: clip-path;
}

.gm-js [data-gm-mask="onder"] { clip-path: inset(0 0 100% 0); }
.gm-js [data-gm-mask="links"] { clip-path: inset(0 100% 0 0); }
.gm-js [data-gm-mask="rechts"] { clip-path: inset(0 0 0 100%); }

.gm-js [data-gm-mask].is-zichtbaar {
    clip-path: inset(0 0 0 0);
}

/* ---------------------------------------------------------------------------
 * 3. Gesplitste tekst
 *
 *   <h1 data-gm-split>Occasions met karakter</h1>        per woord
 *   <h1 data-gm-split="teken">IJsselmonde</h1>           per letter
 *
 * De JS zet er per deel een maskertje omheen; de delen komen er van onderen
 * uit. Het origineel blijft als aria-label staan, de losse spans zijn
 * aria-hidden, dus een schermlezer leest gewoon de zin.
 * ------------------------------------------------------------------------- */

.gm-split__masker {
    display: inline-block;
    overflow: hidden;
    vertical-align: bottom;
    /* Ruimte voor staartletters (g, j, p), anders knipt het masker ze af. */
    padding-bottom: 0.14em;
    margin-bottom: -0.14em;
}

.gm-split__deel {
    display: inline-block;
    white-space: pre;
}

.gm-js [data-gm-split] .gm-split__deel {
    opacity: 0;
    transform: translateY(1.05em);
    transition: opacity var(--gm-split-duur) var(--gm-motion-curve),
                transform var(--gm-split-duur) var(--gm-motion-curve);
    transition-delay: calc(var(--gm-i, 0) * var(--gm-split-stap));
    will-change: opacity, transform;
}

.gm-js [data-gm-split].is-zichtbaar .gm-split__deel {
    opacity: 1;
    transform: none;
}

/* ---------------------------------------------------------------------------
 * 4. Scroll-scrub
 *
 * De JS zet --gm-p op 0 zodra het element onderaan het scherm binnenkomt en op
 * 1 als het er bovenaan uit gaat. Daarmee schrijf je zelf wat je wil:
 *
 *   <figure data-gm-scrub><img class="gm-scrub-y" ...></figure>
 *   <div data-gm-scrub="in" style="--gm-scrub-schaal: 0.2">
 *
 * Modus "in" loopt van 0 naar 1 terwijl het element binnenkomt en blijft
 * daarna op 1 staan; dat is de variant voor een zoom of een fade bij entree.
 * ------------------------------------------------------------------------- */

[data-gm-scrub] {
    --gm-p: 0;
}

/* Onder .gm-js: zonder JS blijft --gm-p op 0 staan en zou een scrub-laag
 * permanent verschoven, uitgezoomd of half doorzichtig in beeld staan. */
.gm-js .gm-scrub-y {
    transform: translate3d(0, calc((var(--gm-p) - 0.5) * var(--gm-scrub-afstand, 80px)), 0);
    will-change: transform;
}

.gm-js .gm-scrub-zoom {
    transform: scale(calc(1 + var(--gm-p) * var(--gm-scrub-schaal, 0.12)));
    will-change: transform;
}

.gm-js .gm-scrub-fade {
    opacity: calc(1 - var(--gm-p) * var(--gm-scrub-fade-max, 1));
}

/* ---------------------------------------------------------------------------
 * 5. Magnetisch (knoppen die naar de cursor toe komen)
 *
 *   <a class="btn" data-gm-magnetic>Bekijk het aanbod</a>
 *   <a data-gm-magnetic="0.5">  sterker; standaard 0.3, maximaal 1
 * ------------------------------------------------------------------------- */

[data-gm-magnetic] {
    transition: transform 420ms var(--gm-motion-curve);
    will-change: transform;
}

[data-gm-magnetic].is-magnetisch {
    transition: transform 120ms linear;
}

/* ---------------------------------------------------------------------------
 * 6. Kantelen (kaarten die meedraaien met de cursor)
 *
 *   <article class="gm-kaart" data-gm-tilt>       standaard 7 graden
 *   <article data-gm-tilt="4">                    rustiger
 * ------------------------------------------------------------------------- */

[data-gm-tilt] {
    transition: transform 500ms var(--gm-motion-curve);
    will-change: transform;
}

[data-gm-tilt].is-gekanteld {
    transition: transform 120ms linear;
}

/* ---------------------------------------------------------------------------
 * 7. Voortgangsbalk
 *
 *   <div class="gm-progress"><span data-gm-progress></span></div>
 * ------------------------------------------------------------------------- */

[data-gm-progress] {
    display: block;
    height: 100%;
    width: 100%;
    transform: scaleX(var(--gm-scroll, 0));
    transform-origin: 0 50%;
    background: var(--color-primary, currentColor);
    will-change: transform;
}

/* ---------------------------------------------------------------------------
 * 8. Paginawissel
 *
 *   <body data-gm-wipe>   klikken op een interne link veegt eerst dicht
 *
 * De overlay hangt aan het einde van body en zit alleen in beeld tijdens de
 * wissel. Zonder JS gebeurt er niets en navigeert de link gewoon.
 * ------------------------------------------------------------------------- */

.gm-wipe {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: var(--gm-wipe-kleur);
    transform: scaleY(0);
    transform-origin: 50% 100%;
    pointer-events: none;
    will-change: transform;
}

.gm-wipe.is-dicht {
    transform: scaleY(1);
}

.gm-wipe.is-in {
    transform: scaleY(1);
    transform-origin: 50% 100%;
    transition: transform var(--gm-wipe-duur) var(--gm-motion-curve-wipe);
}

.gm-wipe.is-uit {
    transform: scaleY(0);
    transform-origin: 50% 0;
    transition: transform var(--gm-wipe-duur) var(--gm-motion-curve-wipe);
}

/* ---------------------------------------------------------------------------
 * 9. Cursor
 *
 *   <body data-gm-cursor>            ring die de cursor volgt
 *   <body data-gm-cursor="verberg">  plus de systeemcursor weg
 *
 * Alleen bij een echte muis (pointer: fine); op touch gebeurt er niets.
 * ------------------------------------------------------------------------- */

.gm-cursor {
    position: fixed;
    top: 0;
    left: 0;
    width: var(--gm-cursor-maat);
    height: var(--gm-cursor-maat);
    margin: calc(var(--gm-cursor-maat) / -2) 0 0 calc(var(--gm-cursor-maat) / -2);
    border: 1px solid var(--gm-cursor-kleur);
    border-radius: 999px;
    pointer-events: none;
    z-index: 9998;
    opacity: 0;
    transform: translate3d(-100px, -100px, 0);
    transition: opacity 200ms ease, width 260ms var(--gm-motion-curve),
                height 260ms var(--gm-motion-curve), margin 260ms var(--gm-motion-curve),
                background-color 260ms ease;
    will-change: transform;
}

.gm-cursor.is-actief {
    opacity: 1;
}

.gm-cursor.is-boven-link {
    --gm-cursor-maat: 52px;
    background: color-mix(in srgb, var(--gm-cursor-kleur) 16%, transparent);
}

html[data-gm-cursor-verbergt],
html[data-gm-cursor-verbergt] a,
html[data-gm-cursor-verbergt] button {
    cursor: none;
}

/* ---------------------------------------------------------------------------
 * 10. Wie geen beweging wil, krijgt de eindtoestand
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .gm-js [data-gm-mask],
    .gm-js [data-gm-mask].is-zichtbaar {
        clip-path: none;
        transition: none;
    }

    .gm-js [data-gm-split] .gm-split__deel {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .gm-js .gm-scrub-y,
    .gm-js .gm-scrub-zoom {
        transform: none !important;
    }

    .gm-js .gm-scrub-fade {
        opacity: 1 !important;
    }

    [data-gm-magnetic],
    [data-gm-tilt] {
        transform: none !important;
        transition: none;
    }

    .gm-wipe {
        display: none;
    }

    .gm-cursor {
        display: none;
    }

    html[data-gm-cursor-verbergt],
    html[data-gm-cursor-verbergt] a,
    html[data-gm-cursor-verbergt] button {
        cursor: auto;
    }
}
