/*
 * TranspoLink Guest Motion — repeatable edition
 * No layout, text, colors or form changes.
 */

html.guest-motion {
    --reveal-dist: 60px;
    --reveal-up: -40px;
    --reveal-dur: 800ms;
    --exit-dur: 180ms;
    --stagger: 100ms;
    --guest-blur: 6px;
    --parallax-strength: 18;
    --ease-out: cubic-bezier(.22, 1, .36, 1);
}

/*
 * Visible by default.
 * Hidden states require successfully initialized JavaScript.
 */
html.js.guest-motion .gm-target {
    opacity: 1;
    translate: 0 0;
    scale: 1;
    filter: none;

    transition:
        opacity var(--reveal-dur) var(--ease-out),
        translate var(--reveal-dur) var(--ease-out),
        scale var(--reveal-dur) var(--ease-out),
        filter var(--reveal-dur) var(--ease-out),
        clip-path var(--reveal-dur) var(--ease-out);

    transition-delay: var(--gm-delay, 0ms);
}

html.js.guest-motion .gm-target:not(.is-visible) {
    opacity: 0;
    translate: 0 var(--gm-entry, var(--reveal-dist));
    scale: .98;
    filter: blur(var(--guest-blur));
    transition-duration: var(--exit-dur);
    transition-delay: 0ms;
}

/* Individual transform properties preserve original transforms. */
html.js.guest-motion .gm-target.gm-image:not(.is-visible) {
    scale: .94;
}

html.js.guest-motion .gm-target.gm-mask {
    clip-path: inset(-12px -12px -12px -12px);
}

html.js.guest-motion .gm-target.gm-mask:not(.is-visible) {
    clip-path: inset(0 0 100% 0);
}

/* White bus enters horizontally without changing its position. */
html.js.guest-motion .gm-target.gm-bus:not(.is-visible) {
    translate: var(--gm-bus-x, -70px) var(--gm-entry, 20px);
}

/* Wipes reveal left to right, including stripes and dividers. */
html.js.guest-motion .gm-target.gm-wipe:not(.is-visible) {
    clip-path: inset(0 100% 0 0);
    translate: 0 0;
    scale: 1;
}

html.js.guest-motion .gm-target.gm-wipe.is-visible {
    clip-path: inset(0 0 0 0);
}

/* Temporary rendering hint, removed after settling. */
html.js.guest-motion .gm-entering {
    will-change: opacity, translate, scale, filter, clip-path;
}

/* Replace only the previous entrance animations. */
html.js.guest-motion #tl-hero
:is(.tl-header, .tl-title, .tl-tracking,
    .tl-orb-position, .tl-advisory-position,
    .tl-search, .tl-bottom-copy) {
    animation: none !important;
}

/* Underlines replay with their containing line. */
html.js.guest-motion #tl-about .journey::after,
html.js.guest-motion #tl-about .about-eyebrow::after,
html.js.guest-motion #tl-features .accent::after {
    clip-path: inset(0 100% 0 0);
    transition: clip-path 700ms var(--ease-out);
    transition-delay: 0ms;
}

html.js.guest-motion #tl-about
.is-visible .journey::after,
html.js.guest-motion #tl-about
.about-eyebrow.is-visible::after,
html.js.guest-motion #tl-features
.is-visible .accent::after {
    clip-path: inset(0 0 0 0);
    transition-delay: calc(var(--gm-delay, 0ms) + 200ms);
}

/* Card icon entrance follows the card. */
html.js.guest-motion #tl-features .feature-card svg {
    opacity: 0;
    scale: .85;
    transition: opacity 350ms ease, scale 350ms var(--ease-out);
    transition-delay: 0ms;
}

html.js.guest-motion #tl-features .feature-card.is-visible svg {
    opacity: 1;
    scale: 1;
    transition-delay: calc(var(--gm-delay, 0ms) + 550ms);
}

/* Ground shadow belongs to the existing wrapper. */
html.js.guest-motion #tl-features .features-bus-wrap::after {
    opacity: 0;
    transition: opacity 500ms ease;
}

html.js.guest-motion #tl-features
.features-bus-wrap.gm-landed::after {
    opacity: 1;
}

/* Scroll-linked transform on separate wrappers. */
html.js.guest-motion .gm-drift {
    translate: 0 var(--gm-drift-y, 0px);
}

/* Pause CSS loops without changing their progress. */
html.js.guest-motion .gm-offscreen,
html.js.guest-motion .gm-offscreen *,
html.js.guest-motion .gm-offscreen *::before,
html.js.guest-motion .gm-offscreen *::after {
    animation-play-state: paused !important;
}

/* Existing scroll cue retains its layout transform. */
html.js.guest-motion #tl-hero .tl-scroll {
    animation: gm-arrow 2400ms ease-in-out infinite;
}

@keyframes gm-arrow {
    0%, 100% { translate: 0 0; }
    50% { translate: 0 6px; }
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    html.js.guest-motion #tl-features .feature-card:hover {
        transform: translateY(-6px);
    }
}

@media (max-width: 760px) {
    html.guest-motion {
        --reveal-dist: 28px;
        --reveal-up: -24px;
        --guest-blur: 0px;
        --parallax-strength: 0;
    }

    html.js.guest-motion .gm-drift {
        translate: none;
    }
}

/* Safety if initialization fails or reduced motion is enabled. */
@media (prefers-reduced-motion: reduce) {
    html.js.guest-motion .gm-target,
    html.js.guest-motion .gm-target:not(.is-visible),
    html.js.guest-motion .gm-drift {
        opacity: 1 !important;
        translate: none !important;
        scale: 1 !important;
        filter: none !important;
        clip-path: none !important;
        transition: none !important;
        will-change: auto !important;
    }

    html.js.guest-motion #tl-features .feature-card svg,
    html.js.guest-motion #tl-features .features-bus-wrap::after {
        opacity: 1 !important;
        scale: 1 !important;
        transition: none !important;
    }

    html.js.guest-motion #tl-about .journey::after,
    html.js.guest-motion #tl-about .about-eyebrow::after,
    html.js.guest-motion #tl-features .accent::after {
        clip-path: none !important;
        transition: none !important;
    }

    html.js.guest-motion
    :is(#tl-hero, #tl-about, #tl-features, #tl-footer) *,
    html.js.guest-motion
    :is(#tl-hero, #tl-about, #tl-features, #tl-footer) *::before,
    html.js.guest-motion
    :is(#tl-hero, #tl-about, #tl-features, #tl-footer) *::after {
        animation: none !important;
    }
}