@import 'swiper/css';
@import 'swiper/css/navigation';
@import 'swiper/css/pagination';
@import '@fortawesome/fontawesome-free/css/all.min.css';

@tailwind base;
@tailwind components;
@tailwind utilities;

/* ========== BASE ========== */
html {
    scroll-behavior: smooth;
    overflow-x: hidden;
}

/* Baseline focus-visible ring so keyboard navigation stays visible even on
   elements with custom hover/focus styling (buttons, cards, form fields). */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid #14B8A6;
    outline-offset: 2px;
    border-radius: 4px;
}

[x-cloak] {
    display: none !important;
}

section[id] {
    scroll-margin-top: 4.5rem;
}

body {
    font-family: 'Inter', sans-serif;
    background: #ffffff;
    color: #1e293b;
    transition: background-color 0.4s ease, color 0.4s ease;
    overflow-x: hidden;
    max-width: 100vw;
}

html.dark body {
    background: #0a1120;
    color: #e2e8f0;
}

h1, h2, h3, h4, h5, h6, .font-heading {
    font-family: 'Poppins', sans-serif;
}

/* ========== PAGE LOADER ========== */
#page-loader {
    position: fixed;
    inset: 0;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ffffff;
    transition: opacity 0.5s ease, visibility 0.5s ease;
}
html.dark #page-loader {
    background: #0a1120;
}
#page-loader.loaded {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}
.loader-ring {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: 3px solid rgba(15, 76, 129, 0.15);
    border-top-color: #0F4C81;
    animation: yc-spin 0.8s linear infinite;
}
html.dark .loader-ring {
    border-color: rgba(20, 184, 166, 0.15);
    border-top-color: #14B8A6;
}

/* ========== SCROLL PROGRESS ========== */
#scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0%;
    background: linear-gradient(90deg, #0F4C81, #14B8A6, #F59E0B);
    z-index: 60;
    transition: width 0.1s linear;
}

/* ========== REVEAL ANIMATIONS ========== */
@layer utilities {
    .reveal {
        opacity: 0;
        transform: translateY(32px);
        transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .reveal.is-visible {
        opacity: 1;
        transform: translateY(0);
    }
    .reveal-left {
        opacity: 0;
        transform: translateX(-40px);
        transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .reveal-left.is-visible {
        opacity: 1;
        transform: translateX(0);
    }
    .reveal-right {
        opacity: 0;
        transform: translateX(40px);
        transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .reveal-right.is-visible {
        opacity: 1;
        transform: translateX(0);
    }
    .reveal-scale {
        opacity: 0;
        transform: scale(0.88);
        transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1), transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
    }
    .reveal-scale.is-visible {
        opacity: 1;
        transform: scale(1);
    }
}

/* ========== 3D FLIP CARD ========== */
.flip-scene {
    perspective: 1400px;
}
.flip-inner {
    position: relative;
    width: 100%;
    height: 100%;
    transition: transform 0.7s cubic-bezier(0.4, 0.2, 0.2, 1);
    transform-style: preserve-3d;
}
.flip-scene:hover .flip-inner,
.flip-scene.is-flipped .flip-inner {
    transform: rotateY(180deg);
}
.flip-face {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}
.flip-face-back {
    transform: rotateY(180deg);
}

/* ========== TILT ========== */
.tilt {
    transform-style: preserve-3d;
    transition: transform 0.15s ease-out, box-shadow 0.3s ease;
    will-change: transform;
}

/* ========== KEYFRAMES ========== */
@keyframes yc-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-14px); }
}
@keyframes yc-marquee {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}
@keyframes yc-pulse-dot {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.35; transform: scale(0.65); }
}
@keyframes yc-spin {
    to { transform: rotate(360deg); }
}
@keyframes yc-blob {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33% { transform: translate(24px, -20px) scale(1.08); }
    66% { transform: translate(-20px, 26px) scale(0.94); }
}
.pulse-dot {
    animation: yc-pulse-dot 2s ease-in-out infinite;
}
.animate-marquee {
    animation: yc-marquee 30s linear infinite;
}
.marquee-pause:hover .animate-marquee {
    animation-play-state: paused;
}
.animate-blob {
    animation: yc-blob 14s ease-in-out infinite;
}

/* ========== TOAST ========== */
#toast {
    position: fixed;
    bottom: 1.75rem;
    right: 1.75rem;
    z-index: 70;
    max-width: 320px;
    transform: translateY(140px);
    opacity: 0;
    pointer-events: none;
    transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.4s ease;
}
#toast.show {
    transform: translateY(0);
    opacity: 1;
    pointer-events: auto;
}

/* ==========================================================================
   APPLE-STYLE PREMIUM CARD
   A floating, tilt-reactive credit-card visual. All motion is driven by
   `transform`, `opacity`, or animated custom properties only, so every
   layer stays on the GPU compositor and never triggers layout/paint churn.
   Tilt itself is applied by resources/js/apple-card.js via inline
   `transform` / `--mx` / `--my` on .apple-card; everything else here is
   ambient, cursor-independent motion (float, border glow, reflection).
   ========================================================================== */

/* "Product stage" the card floats in — a soft light backdrop by default,
   switching to the dark spotlight gradient when the site is in dark mode. */
.apple-card-stage {
    position: relative;
    background: radial-gradient(120% 120% at 50% 0%, #eef4fb 0%, #e4edf9 55%, #f7fafd 100%);
    overflow: hidden;
    isolation: isolate;
}
html.dark .apple-card-stage {
    background: radial-gradient(120% 120% at 50% 0%, #1a2540 0%, #0b1226 55%, #060a16 100%);
}

.apple-card-stage__glow {
    position: absolute;
    border-radius: 9999px;
    filter: blur(60px) hue-rotate(0deg);
    opacity: 0.35;
    animation: yc-blob 14s ease-in-out infinite, yc-aurora-hue 12s ease-in-out infinite;
    pointer-events: none;
}
@keyframes yc-aurora-hue {
    0%, 100% { filter: blur(60px) hue-rotate(0deg); }
    50% { filter: blur(60px) hue-rotate(35deg); }
}

/* Soft diagonal light shafts drifting behind the card — pure opacity/transform */
.card-light-beam {
    position: absolute;
    top: -20%;
    width: 2px;
    height: 140%;
    background: linear-gradient(180deg, transparent, rgba(15, 76, 129, 0.14), transparent);
    filter: blur(2px);
    opacity: 0.5;
    animation: yc-beam-drift 9s ease-in-out infinite;
    pointer-events: none;
}
html.dark .card-light-beam {
    background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.16), transparent);
}
@keyframes yc-beam-drift {
    0%, 100% { transform: translateX(0) rotate(12deg); opacity: 0.35; }
    50% { transform: translateX(18px) rotate(12deg); opacity: 0.65; }
}

/* Positions each dust particle; GSAP applies a small mouse-parallax offset
   (x/y) here so particles drift with the cursor at different depths, while
   the inner .card-particle keeps its own independent ambient float —
   two elements, two transforms, no fighting over the same property. */
.particle-parallax {
    position: absolute;
    pointer-events: none;
}

/* Floating dust particles — ambient float is pure CSS; the parallax offset
   from mouse movement is applied one level up, on .particle-parallax. */
.card-particle {
    display: block;
    border-radius: 9999px;
    background: rgba(15, 76, 129, 0.4);
    filter: blur(0.5px);
    opacity: 0.35;
    animation: yc-particle-float 8s ease-in-out infinite;
    pointer-events: none;
}
html.dark .card-particle {
    background: rgba(255, 255, 255, 0.55);
}
@keyframes yc-particle-float {
    0%, 100% { transform: translate(0, 0); opacity: 0.15; }
    50% { transform: translate(var(--drift-x, 10px), var(--drift-y, -18px)); opacity: 0.6; }
}

/* Shadow shift wrapper — GSAP applies a small translateX here (opposite the
   card's tilt direction, simulating a moving light source). The pulse
   keyframe below stays on the child, so the two transforms never collide. */
.card-shadow-shift {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* Ambient contact shadow beneath the card, breathing in sync with the float */
.card-ambient-shadow {
    position: absolute;
    left: 10%;
    right: 10%;
    bottom: -1rem;
    height: 2rem;
    border-radius: 9999px;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), transparent 72%);
    filter: blur(6px);
    animation: yc-shadow-pulse 5s ease-in-out infinite;
}
@keyframes yc-shadow-pulse {
    0%, 100% { transform: scale(1); opacity: 0.65; }
    50% { transform: scale(0.82); opacity: 0.4; }
}

/* NFC wave pulse — concentric rings expanding from the card's contactless icon */
.nfc-pulse {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.nfc-pulse::before,
.nfc-pulse::after {
    content: '';
    position: absolute;
    inset: -6px;
    border-radius: 9999px;
    border: 1.5px solid rgba(255, 255, 255, 0.55);
    animation: yc-nfc-pulse 2.2s ease-out infinite;
}
.nfc-pulse::after {
    animation-delay: 0.7s;
}
@keyframes yc-nfc-pulse {
    0% { transform: scale(0.6); opacity: 0.9; }
    80%, 100% { transform: scale(2.1); opacity: 0; }
}

/* Card scene: fixed perspective for the tilt transform applied to .apple-card */
.apple-card-scene {
    perspective: 1600px;
}

/* Magnetic pull layer — GSAP sets x/y here to draw the whole card gently
   toward the cursor. Separate from .apple-card (which only ever receives
   rotateX/rotateY), so the two transforms never fight. preserve-3d carries
   the scene's perspective down through every wrapper to .apple-card, so
   its tilt renders as true depth rather than a flat 2D skew. */
.apple-card-magnet {
    will-change: transform;
    transform-style: preserve-3d;
}
.apple-card-magnet .animate-float,
.apple-card-magnet .animate-float-rotate {
    transform-style: preserve-3d;
}

/* The tilting element itself — JS sets `transform: rotateX() rotateY()` and
   the `--mx` / `--my` custom properties (cursor position) directly inline. */
.apple-card {
    position: relative;
    transform-style: preserve-3d;
    border-radius: 1.75rem;
    box-shadow:
        0 30px 60px -15px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(255, 255, 255, 0.06) inset;
    transition: box-shadow 0.4s ease;
    will-change: transform;
    /* Registers this card as a size container so .journey-card-face's type
       scale (cqw units) tracks the card's OWN rendered width, whether it's
       ~384px in the hero, ~220-280px in the journey stage, or mid-flight in
       the hero-journey-bridge — one face, correctly proportioned everywhere. */
    container-type: inline-size;
    container-name: yatra-card;
}
.apple-card-scene.is-active .apple-card {
    box-shadow:
        0 40px 80px -18px rgba(0, 0, 0, 0.65),
        0 0 0 1px rgba(255, 255, 255, 0.1) inset;
    /* `filter` pulses independently of `transform`, which GSAP owns
       exclusively on this element for tilt — no property conflict. */
    animation: yc-card-pulse 1.8s ease-in-out infinite;
}
@keyframes yc-card-pulse {
    0%, 100% { filter: brightness(1) saturate(1); }
    50% { filter: brightness(1.08) saturate(1.15); }
}

/* Animated metallic border ring. @property lets the browser interpolate
   the conic-gradient's start angle smoothly; unsupported browsers simply
   render a static (non-animated) gradient ring — a harmless fallback. */
@property --border-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}
.card-border-glow {
    position: absolute;
    inset: -1.5px;
    border-radius: inherit;
    padding: 1.5px;
    background: conic-gradient(from var(--border-angle), #14B8A6, #F59E0B, #0F4C81, #A78BFA, #14B8A6);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    animation: yc-border-angle 6s linear infinite;
    pointer-events: none;
}
@keyframes yc-border-angle {
    to { --border-angle: 360deg; }
}

/* Cursor-follow glare — position driven by --mx/--my set in apple-card.js */
.card-glare {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: radial-gradient(circle at var(--mx, 50%) var(--my, 30%), rgba(255, 255, 255, 0.55), transparent 45%);
    mix-blend-mode: overlay;
    opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
}
.apple-card-scene.is-active .card-glare {
    opacity: 1;
}

/* Continuous diagonal light sweep, independent of the cursor */
.card-reflection {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    overflow: hidden;
    pointer-events: none;
}
.card-reflection::before {
    content: '';
    position: absolute;
    top: -60%;
    left: -60%;
    width: 220%;
    height: 220%;
    background: linear-gradient(
        115deg,
        transparent 38%,
        rgba(255, 255, 255, 0.14) 48%,
        rgba(255, 255, 255, 0.28) 50%,
        rgba(255, 255, 255, 0.14) 52%,
        transparent 62%
    );
    animation: yc-reflection-sweep 6s ease-in-out infinite;
    will-change: transform;
}
@keyframes yc-reflection-sweep {
    0%, 100% { transform: translate(-8%, -6%); }
    50% { transform: translate(8%, 6%); }
}

/* Frosted glassmorphism panel used for the balance readout on the card face */
.card-glass-panel {
    background: rgba(255, 255, 255, 0.1);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.14);
}

/* ==========================================================================
   HERO → JOURNEY CARD BRIDGE
   A fixed-position clone of the card, invisible and inert until
   resources/js/hero-journey-bridge.js activates it for the scroll range
   between the hero card leaving view and the journey stage pinning. See
   the JS for the FLIP-style rect math; this is just the shell it drives.
   ========================================================================== */
.hero-journey-bridge {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 45;
    opacity: 0;
    pointer-events: none;
    transform-origin: top left;
    will-change: transform, width;
}
.hero-journey-bridge .apple-card {
    width: 100%;
    height: 100%;
    /* The static heavy drop-shadow from .apple-card reads as a smudgy blob
       while this element is scaling and translating every frame, and it
       doubles up visually with the hero card's own ambient shadow right at
       the handoff point. A light, fixed shadow reads cleanly in motion. */
    box-shadow: 0 10px 24px -8px rgba(0, 0, 0, 0.35);
}

/* ==========================================================================
   LUXURY BLACK CARD (variant)
   Reuses every layer of the Apple-style card above (.apple-card-scene,
   .apple-card-magnet, .apple-card, .card-border-glow/reflection/glare) —
   apple-card.js already auto-discovers any .apple-card-scene on the page,
   so this variant gets full mouse tilt, magnetic pull, gyro, and
   scroll-linked rotation for free. Only the finish is different: a black
   metallic gradient, a silver border glow, a film-grain noise layer, and a
   slow ambient auto-rotation blended into the float.
   ========================================================================== */

.apple-card--luxury {
    background: linear-gradient(135deg, #2a2a2e 0%, #131316 45%, #050506 100%);
}

/* Fine grain noise for a brushed-metal, non-flat black surface */
.card-noise {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    opacity: 0.06;
    mix-blend-mode: overlay;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Silver/graphite metallic border, in place of the teal/amber default */
.card-border-glow--silver {
    background: conic-gradient(from var(--border-angle), #e5e7eb, #737373, #f5f5f5, #52525b, #e5e7eb);
}

/* Slow idle rotation blended with the ambient float — a different element
   than .apple-card (which only ever receives JS-driven mouse/gyro tilt),
   so the two never compete for the same transform. */
.animate-float-rotate {
    animation: yc-float-rotate 10s ease-in-out infinite;
}
@keyframes yc-float-rotate {
    0%, 100% { transform: translateY(0) rotateY(-4deg); }
    50% { transform: translateY(-14px) rotateY(4deg); }
}

@media (prefers-reduced-motion: reduce) {
    .animate-float-rotate {
        animation: none !important;
    }
}

/* Respect reduced-motion: freeze ambient motion, keep the card fully legible */
@media (prefers-reduced-motion: reduce) {
    .apple-card,
    .card-particle,
    .card-ambient-shadow,
    .card-border-glow,
    .card-reflection::before,
    .card-light-beam,
    .nfc-pulse::before,
    .nfc-pulse::after,
    .apple-card-stage__glow {
        animation: none !important;
        transition: none !important;
    }
}

/* ==========================================================================
   APPLE KEYNOTE — PRODUCT REVEAL SECTION
   A one-shot, scroll-triggered reveal (fade + scale + rotate) with a light
   streak sweep, a shadow that grows in, and a soft background glow. Card
   motion itself is transform + opacity only; resources/js/product-reveal.js
   just toggles `.is-revealed` via IntersectionObserver — no per-frame JS.
   ========================================================================== */

.product-reveal-stage {
    position: relative;
    overflow: hidden;
    background: radial-gradient(120% 100% at 50% 0%, #101a33 0%, #0b1226 55%, #060a16 100%);
}

/* Soft background glow behind the card, fading/growing in with the reveal */
.product-reveal-glow {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 32rem;
    height: 32rem;
    margin: -16rem 0 0 -16rem;
    border-radius: 9999px;
    background: radial-gradient(circle, rgba(20, 184, 166, 0.35), transparent 70%);
    filter: blur(90px);
    opacity: 0;
    transform: scale(0.6);
    pointer-events: none;
}
.product-reveal-scene.is-revealed .product-reveal-glow {
    animation: yc-glow-in 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes yc-glow-in {
    to { opacity: 1; transform: scale(1); }
}

/* Shadow that "grows" naturally under the card as it settles into place */
.product-reveal-shadow {
    position: absolute;
    left: 12%;
    right: 12%;
    bottom: -1.25rem;
    height: 2rem;
    border-radius: 9999px;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), transparent 72%);
    filter: blur(10px);
    opacity: 0;
    transform: scale(0.55);
    pointer-events: none;
}
.product-reveal-scene.is-revealed .product-reveal-shadow {
    animation: yc-shadow-grow 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes yc-shadow-grow {
    to { opacity: 0.75; transform: scale(1); }
}

/* The card itself — fade + scale(0.85→1) + rotate(15deg→0), pure transform/opacity,
   1.8s Apple-like ease-out, then a subtle continuous float picks up seamlessly
   (both keyframes land on a neutral transform, so the handoff has no visible snap). */
.product-reveal-card {
    position: relative;
    opacity: 0;
    transform: scale(0.85) rotate(15deg);
    will-change: transform, opacity;
}
.product-reveal-scene.is-revealed .product-reveal-card {
    animation:
        yc-product-reveal 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards,
        yc-float 5s ease-in-out infinite 1.8s;
}
@keyframes yc-product-reveal {
    0% { opacity: 0; transform: scale(0.85) rotate(15deg); }
    100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

/* Light streak that sweeps across the card face once, mid-reveal */
.product-reveal-streak {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
}
.product-reveal-streak::before {
    content: '';
    position: absolute;
    top: -20%;
    left: -35%;
    width: 35%;
    height: 140%;
    background: linear-gradient(75deg, transparent, rgba(255, 255, 255, 0.6), transparent);
    transform: translateX(0%) skewX(-18deg);
    opacity: 0;
}
.product-reveal-scene.is-revealed .product-reveal-streak::before {
    animation: yc-streak-sweep 1.1s cubic-bezier(0.4, 0, 0.2, 1) 0.6s forwards;
}
@keyframes yc-streak-sweep {
    0% { transform: translateX(0%) skewX(-18deg); opacity: 0; }
    12% { opacity: 0.9; }
    55% { opacity: 0.9; }
    100% { transform: translateX(430%) skewX(-18deg); opacity: 0; }
}

/* Storyline tags beneath the card, staggering in right as the reveal lands */
.story-tag {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}
.story-tag.is-visible {
    opacity: 1;
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .product-reveal-card,
    .product-reveal-glow,
    .product-reveal-shadow,
    .product-reveal-streak::before {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
    .story-tag {
        opacity: 1 !important;
        transform: none !important;
    }
}

/* ==========================================================================
   THE JOURNEY — cinematic scrollytelling sequence
   resources/js/journey.js pins .journey-stage and scrubs one GSAP timeline
   across .journey-pin-wrapper's height. Below 1024px, or with reduced
   motion, the JS never builds that timeline and instead adds `.journey-static`
   here — everything falls back to plain stacked, IntersectionObserver-revealed
   blocks (see the `.journey-static` overrides threaded through this block).
   Illustrations (skyline, walker, bus, kiosk, phone/app UI) are hand-built
   inline SVG/CSS — no external image assets required.
   ========================================================================== */

/* Theme tokens for every scene in the journey. Light values are the
   default; html.dark overrides them once here rather than duplicating a
   dark-mode override on every individual rule below. Things that are
   meant to look the same either way (the Yatra card's own brand gradient,
   the phone/kiosk "device screen" mockups, the branded bus livery) are
   deliberately left as hardcoded colors, not tokens — same exception
   pattern as the hero's card face. */
.journey-section {
    --j-bg-1: #eef4fb;
    --j-bg-2: #ffffff;
    --j-bg-3: #f3f8ff;
    --j-ink: #0f172a;
    --j-ink-soft: rgba(15, 23, 42, 0.6);
    --j-ink-faint: rgba(15, 23, 42, 0.38);
    --j-glass-bg: rgba(15, 23, 42, 0.045);
    --j-glass-border: rgba(15, 23, 42, 0.14);
    --j-line: rgba(15, 23, 42, 0.22);
    --j-line-faint: rgba(15, 23, 42, 0.14);
    --j-node: #0f172a;
    --j-solid-fill: rgba(15, 23, 42, 0.72);
    background: radial-gradient(120% 100% at 50% 0%, var(--j-bg-1) 0%, var(--j-bg-3) 55%, var(--j-bg-2) 100%);
}
html.dark .journey-section {
    --j-bg-1: #101a33;
    --j-bg-2: #060a16;
    --j-bg-3: #0b1226;
    --j-ink: #ffffff;
    --j-ink-soft: rgba(255, 255, 255, 0.55);
    --j-ink-faint: rgba(255, 255, 255, 0.35);
    --j-glass-bg: rgba(255, 255, 255, 0.06);
    --j-glass-border: rgba(255, 255, 255, 0.12);
    --j-line: rgba(255, 255, 255, 0.2);
    --j-line-faint: rgba(255, 255, 255, 0.15);
    --j-node: #ffffff;
    --j-solid-fill: rgba(255, 255, 255, 0.85);
}

/* Total scroll distance for the whole pinned sequence — short enough that
   the story doesn't overstay its welcome, long enough for each scene to
   read clearly at a normal scroll speed. */
#journey-pin-wrapper {
    height: 320vh;
}
.journey-static #journey-pin-wrapper {
    height: auto;
}

.journey-stage {
    position: relative;
    height: 100vh;
    overflow: hidden;
    isolation: isolate;
}
.journey-static .journey-stage {
    height: auto;
    overflow: visible;
    padding: 2rem 0 4rem;
}

.journey-bg {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(45rem 30rem at 15% 20%, rgba(15, 76, 129, 0.28), transparent 70%),
        radial-gradient(40rem 28rem at 85% 80%, rgba(20, 184, 166, 0.2), transparent 70%);
    pointer-events: none;
}
.journey-static .journey-bg {
    position: fixed;
    z-index: -1;
}

/* Bounded coordinate space every scene's content shares — see the comment
   in journey.blade.php. Without this, percentage-positioned decoration
   scales against the raw browser width instead of a fixed composition. */
.journey-viewport {
    position: absolute;
    inset: 0;
    max-width: 1280px;
    margin: 0 auto;
}
.journey-static .journey-viewport {
    position: relative;
    inset: auto;
    max-width: 42rem;
    margin: 0 auto;
    padding: 0 1.25rem;
}

/* ---------- progress rail ---------- */
.journey-progress {
    position: absolute;
    right: clamp(1rem, 4vw, 3rem);
    top: 50%;
    transform: translateY(-50%);
    z-index: 30;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}
.journey-static .journey-progress {
    display: none;
}
.journey-progress__dot {
    width: 6px;
    height: 6px;
    border-radius: 9999px;
    background: var(--j-line);
    transition: background 0.4s ease, transform 0.4s ease, box-shadow 0.4s ease;
}
.journey-progress__dot.is-active {
    background: #14B8A6;
    transform: scale(1.7);
    box-shadow: 0 0 10px rgba(20, 184, 166, 0.7);
}

/* ---------- caption ledger ---------- */
.journey-caption {
    position: absolute;
    left: 50%;
    bottom: clamp(1.5rem, 6vh, 3rem);
    transform: translateX(-50%);
    z-index: 30;
    max-width: 32rem;
    padding: 0 1.5rem;
    text-align: center;
}
.journey-static .journey-caption {
    display: none;
}
.journey-caption__text {
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: clamp(1rem, 2vw, 1.35rem);
    color: var(--j-ink);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.35s ease, transform 0.35s ease;
}
.journey-caption__text:not(:empty) {
    opacity: 1;
    transform: translateY(0);
}

/* ---------- persistent card anchor ---------- */
.journey-card-anchor {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    will-change: transform;
}
.journey-static .journey-card-anchor {
    display: none;
}
/* Shrink-wraps to the card's own rendered size (not the full stage), so the
   shadow below can be positioned in percentages of the card itself and
   stay correctly placed at every clamp() breakpoint. */
.journey-card-float {
    display: inline-block;
    position: relative;
    animation: yc-float 5s ease-in-out infinite;
}
.journey-card {
    position: relative;
    width: clamp(220px, 20vw, 280px);
    aspect-ratio: 16 / 10;
    border-radius: 1.1rem;
    background: linear-gradient(135deg, #123a63 0%, #0F4C81 55%, #0d6e63 100%);
    box-shadow: 0 20px 45px -12px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.06) inset;
}
.journey-card-shadow {
    position: absolute;
    left: 8%;
    right: 8%;
    bottom: -18%;
    height: 22%;
    border-radius: 9999px;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), transparent 72%);
    filter: blur(6px);
}

/* ---------- card face layout (chip, brand, number, cardholder/expiry) ---------- */
.journey-card-face {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
    padding: 9% 8%;
    transform: translateZ(20px);
}
.journey-card-face__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}
.journey-card-chip {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
    width: clamp(1.9rem, 12%, 2.4rem);
    aspect-ratio: 3 / 2;
    padding: 0 5px;
    border-radius: 0.3rem;
    background: linear-gradient(135deg, #f3d78a 0%, #c99a3f 55%, #8a691f 100%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35) inset;
}
.journey-card-chip span {
    height: 1.5px;
    border-radius: 1px;
    background: rgba(0, 0, 0, 0.4);
}
.journey-card-face__brand {
    margin-top: -4%;
}
.journey-card-face__name {
    font-family: 'Poppins', sans-serif;
    font-weight: 800;
    letter-spacing: -0.01em;
    font-size: clamp(0.95rem, 6.5cqw, 1.15rem);
    color: #fff;
}
.journey-card-face__tag {
    margin-top: 0.15rem;
    font-size: clamp(0.55rem, 3.2cqw, 0.65rem);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.55);
}
.journey-card-face__number {
    font-family: 'Poppins', sans-serif;
    font-size: clamp(0.7rem, 4.6cqw, 0.85rem);
    font-weight: 600;
    letter-spacing: 0.12em;
    color: rgba(255, 255, 255, 0.85);
}
.journey-card-face__meta {
    display: flex;
    justify-content: space-between;
    margin-top: 0.5rem;
}
.journey-card-face__meta div {
    display: flex;
    flex-direction: column;
}
.journey-card-face__meta span {
    font-size: clamp(0.45rem, 2.6cqw, 0.55rem);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(255, 255, 255, 0.45);
}
.journey-card-face__meta b {
    margin-top: 0.1rem;
    font-size: clamp(0.6rem, 3.6cqw, 0.7rem);
    font-weight: 700;
    color: rgba(255, 255, 255, 0.85);
}

/* ---------- static/mobile fallback: one proper card moment up front ---------- */
.journey-static-card-intro {
    display: none;
}
.journey-static .journey-static-card-intro {
    display: flex;
    justify-content: center;
    padding: 0.5rem 0 3rem;
}
.journey-card--intro {
    width: clamp(240px, 62vw, 300px);
}

/* ---------- dock points (invisible measurement targets) ---------- */
.dock-point {
    position: absolute;
    width: 2px;
    height: 2px;
    transform: translate(-50%, -50%);
    pointer-events: none;
    opacity: 0;
}
#dock-corner {
    top: 12%;
    left: 88%;
}

/* ---------- scenes ---------- */
.journey-scene {
    position: absolute;
    inset: 0;
    z-index: 10;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 2rem;
}
.journey-static .journey-scene {
    position: relative;
    inset: auto;
    min-height: 62vh;
    margin: 0 auto;
    max-width: 40rem;
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1), transform 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.journey-static .journey-scene.is-visible {
    opacity: 1;
    transform: translateY(0);
}
.journey-scene__label {
    margin-top: 2.25rem;
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--j-ink-soft);
}
.journey-scene__label--tap,
.journey-scene__label--recharge {
    opacity: 0;
    transform: translateY(6px);
    color: #34d399;
    font-weight: 700;
    transition: opacity 0.4s ease, transform 0.4s ease;
}
.journey-scene[data-scene="tap"].is-active .journey-scene__label--tap,
.journey-scene[data-scene="recharge"].is-active .journey-scene__label--recharge {
    opacity: 1;
    transform: translateY(0);
}

/* ---------- scene: city ---------- */
/* Swappable image slot — see the <img> in journey.blade.php. Sits full-bleed
   behind the moon/glow/beacon overlay, which stays animated regardless of
   what image is here. */
.journey-scene-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.9;
}
.journey-scene-image--bottom {
    object-position: bottom;
}
.journey-city-glow {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
.journey-beacon {
    opacity: 1;
}
.journey-scene[data-scene="city"].is-active .journey-beacon {
    animation: yc-nfc-pulse 1.6s ease-in-out infinite;
}

/* ---------- scene: walk ---------- */
.journey-street {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    pointer-events: none;
}
.journey-street__figure {
    position: absolute;
    bottom: 8%;
    width: 1.1rem;
    height: 3rem;
    border-radius: 9999px 9999px 0 0;
    background: var(--j-glass-bg);
}
.journey-street__figure--1 { left: 20%; }
.journey-street__figure--2 { right: 24%; height: 2.4rem; }

.journey-shelter {
    position: absolute;
    right: 18%;
    bottom: 30%;
    width: 6rem;
    height: 5rem;
}
.journey-shelter__roof {
    position: absolute;
    top: 0;
    left: -0.5rem;
    width: 7rem;
    height: 0.5rem;
    border-radius: 0.25rem;
    background: linear-gradient(90deg, #0F4C81, #14B8A6);
}
.journey-shelter__pole {
    position: absolute;
    top: 0.4rem;
    width: 0.25rem;
    height: 3.6rem;
    background: var(--j-line);
}
.journey-shelter__pole--l { left: 0; }
.journey-shelter__pole--r { right: 0; }
.journey-shelter__bench {
    position: absolute;
    bottom: 1rem;
    left: 0.75rem;
    width: 4.5rem;
    height: 0.4rem;
    border-radius: 0.2rem;
    background: var(--j-glass-border);
}
.journey-shelter__sign {
    position: absolute;
    top: -1.6rem;
    left: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.5rem;
    border-radius: 0.4rem;
    background: #F59E0B;
    color: #1a1206;
    font-size: 0.65rem;
    font-weight: 700;
}

.journey-walk-track {
    position: relative;
    display: flex;
    align-items: flex-end;
    width: min(90%, 24rem);
}
.journey-walker-wrap {
    position: relative;
    width: 3rem;
    flex-shrink: 0;
    z-index: 1;
}
.journey-walker {
    width: 100%;
    height: auto;
    transform: rotate(-4deg);
    filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.4));
}
.journey-step-ping {
    position: absolute;
    bottom: 0.3rem;
    width: 0.7rem;
    height: 0.3rem;
    border-radius: 9999px;
    border: 1px solid var(--j-line);
    opacity: 0;
}
.journey-step-ping--l { left: 0.3rem; }
.journey-step-ping--r { right: 0.3rem; }
.journey-scene[data-scene="walk"].is-active .journey-step-ping--l {
    animation: yc-step-ping 0.6s ease-out infinite;
}
.journey-scene[data-scene="walk"].is-active .journey-step-ping--r {
    animation: yc-step-ping 0.6s ease-out infinite 0.3s;
}
@keyframes yc-step-ping {
    0% { opacity: 0.7; transform: scale(0.4); }
    100% { opacity: 0; transform: scale(1.6); }
}
.journey-scene[data-scene="walk"].is-active .journey-walker-wrap {
    animation: yc-walker-bob 0.6s ease-in-out infinite;
}
@keyframes yc-walker-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-3px); }
}
.journey-walker-shadow {
    display: block;
    width: 2rem;
    height: 0.5rem;
    margin: 0.25rem auto 0;
    border-radius: 9999px;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.5), transparent 75%);
}
.journey-walk-path {
    flex: 1;
    height: 0;
    margin-bottom: 1.5rem;
    border-top: 2px dashed var(--j-line);
}

/* ---------- scene: bus ---------- */
.journey-road {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}
.journey-road__lane {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 18%;
    height: 3px;
    background: repeating-linear-gradient(90deg, var(--j-line) 0 24px, transparent 24px 48px);
}
.journey-scene[data-scene="bus"].is-active .journey-road__lane {
    animation: yc-lane-scroll 1.4s linear infinite;
}
@keyframes yc-lane-scroll {
    to { background-position: -48px 0; }
}
.journey-road__skyline {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 22%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 0.75rem;
    opacity: 0.35;
}
.journey-road__skyline span {
    display: block;
    background: var(--j-glass-bg);
    border-radius: 0.2rem 0.2rem 0 0;
}

.journey-speedlines {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}
.journey-speedlines span {
    position: absolute;
    left: -20%;
    width: 40%;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--j-line), transparent);
    opacity: 0;
}
.journey-speedlines span:nth-child(1) { top: 30%; }
.journey-speedlines span:nth-child(2) { top: 45%; }
.journey-speedlines span:nth-child(3) { top: 58%; }
.journey-speedlines span:nth-child(4) { top: 70%; }
.journey-scene[data-scene="bus"].is-active .journey-speedlines span {
    animation: yc-speedline 1.1s linear infinite;
}
.journey-speedlines span:nth-child(2) { animation-delay: 0.2s; }
.journey-speedlines span:nth-child(3) { animation-delay: 0.05s; }
.journey-speedlines span:nth-child(4) { animation-delay: 0.35s; }
@keyframes yc-speedline {
    0% { transform: translateX(0); opacity: 0; }
    15% { opacity: 0.8; }
    100% { transform: translateX(280%); opacity: 0; }
}

.journey-bus-stage {
    position: relative;
    width: min(90%, 28rem);
}
.journey-bus-illustration {
    width: 100%;
    height: auto;
    filter: drop-shadow(0 16px 22px rgba(0, 0, 0, 0.45));
}
.journey-bus-ground-shadow {
    position: absolute;
    left: 12%;
    right: 12%;
    bottom: -0.4rem;
    height: 1rem;
    border-radius: 9999px;
    background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.5), transparent 75%);
    filter: blur(4px);
}
.journey-scene[data-scene="bus"].is-active .journey-bus-suspension {
    animation: yc-bus-arrive 1.1s cubic-bezier(0.22, 1.4, 0.36, 1) both;
}
.journey-scene[data-scene="bus"].is-active .journey-bus-ground-shadow {
    animation: yc-bus-shadow-squash 1.1s cubic-bezier(0.22, 1.4, 0.36, 1) both;
}
@keyframes yc-bus-arrive {
    0% { transform: translateY(-6px); }
    55% { transform: translateY(4px); }
    75% { transform: translateY(-2px); }
    100% { transform: translateY(0); }
}
@keyframes yc-bus-shadow-squash {
    0% { transform: scaleX(0.94); opacity: 0.5; }
    55% { transform: scaleX(1.04); opacity: 0.7; }
    100% { transform: scaleX(1); opacity: 0.6; }
}
/* ---------- scene: tap / approve ---------- */
.journey-kiosk-stage {
    position: relative;
    width: 10rem;
}
.journey-kiosk {
    width: 100%;
    height: auto;
    filter: drop-shadow(0 14px 18px rgba(0, 0, 0, 0.4));
}
.journey-validator {
    position: absolute;
    top: 8%;
    left: 50%;
    transform: translateX(-50%);
    display: grid;
    place-items: center;
    width: 3.6rem;
    height: 3.6rem;
    border-radius: 1.1rem;
    background: var(--j-glass-bg);
    border: 1px solid var(--j-glass-border);
    transition: background 0.5s ease, border-color 0.5s ease, box-shadow 0.5s ease;
}
.journey-validator__icon {
    position: absolute;
    font-size: 1.2rem;
    color: var(--j-ink-soft);
    transition: opacity 0.3s ease, transform 0.3s ease;
}
.journey-validator__check {
    position: absolute;
    width: 2.1rem;
    height: 2.1rem;
    opacity: 0;
    transform: scale(0.5);
    transition: opacity 0.3s ease, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.check-ring {
    fill: none;
    stroke: #34d399;
    stroke-width: 2;
    stroke-dasharray: 94.2;
    stroke-dashoffset: 94.2;
}
.check-mark {
    fill: none;
    stroke: #34d399;
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 24;
    stroke-dashoffset: 24;
}
.journey-validator.is-approved {
    background: rgba(52, 211, 153, 0.15);
    border-color: rgba(52, 211, 153, 0.5);
    box-shadow: 0 0 40px rgba(52, 211, 153, 0.4);
}
.journey-validator.is-approved .journey-validator__icon { opacity: 0; transform: scale(0.4) rotate(-15deg); }
.journey-validator.is-approved .journey-validator__check { opacity: 1; transform: scale(1); }
.journey-validator.is-approved .check-ring {
    animation: yc-check-draw 0.5s ease-out forwards;
}
.journey-validator.is-approved .check-mark {
    animation: yc-check-draw 0.35s ease-out 0.35s forwards;
}
@keyframes yc-check-draw {
    to { stroke-dashoffset: 0; }
}

/* Ambient contactless waves — read continuously while the tap scene is in
   view, not just at the moment of approval, so the validator feels "live". */
.journey-nfc-waves {
    position: absolute;
    left: 6%;
    width: 42%;
    height: 100%;
    opacity: 0;
}
.nfc-wave {
    fill: none;
    stroke: var(--j-ink-soft);
    stroke-width: 2;
    stroke-linecap: round;
}
.journey-scene[data-scene="tap"].is-active .journey-nfc-waves {
    opacity: 1;
    animation: yc-nfc-wave-fade 2.2s ease-in-out infinite;
}
.journey-scene[data-scene="tap"].is-active .nfc-wave--1 { animation: yc-nfc-wave-radiate 1.8s ease-out infinite; }
.journey-scene[data-scene="tap"].is-active .nfc-wave--2 { animation: yc-nfc-wave-radiate 1.8s ease-out infinite 0.3s; }
@keyframes yc-nfc-wave-fade {
    0%, 100% { opacity: 0.35; }
    50% { opacity: 0.85; }
}
@keyframes yc-nfc-wave-radiate {
    0% { opacity: 0; transform: scale(0.7) translateX(2px); }
    30% { opacity: 1; }
    100% { opacity: 0; transform: scale(1.15) translateX(-3px); }
}
.journey-validator.is-approved .journey-nfc-waves { display: none; }

.journey-screen-flash {
    position: absolute;
    inset: -3rem;
    border-radius: 9999px;
    background: radial-gradient(circle, rgba(52, 211, 153, 0.55), transparent 70%);
    opacity: 0;
    pointer-events: none;
}
.journey-validator.is-approved .journey-screen-flash {
    animation: yc-screen-flash 0.6s ease-out forwards;
}
@keyframes yc-screen-flash {
    0% { opacity: 0.9; transform: scale(0.4); }
    100% { opacity: 0; transform: scale(1.4); }
}
.journey-ripple {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 2px solid rgba(52, 211, 153, 0.55);
    opacity: 0;
}
.journey-validator.is-approved .journey-ripple {
    animation: yc-tap-ripple 1.8s ease-out infinite;
}
.journey-validator.is-approved .journey-ripple--2 {
    animation-delay: 0.6s;
}
@keyframes yc-tap-ripple {
    0% { transform: scale(0.8); opacity: 0.8; }
    100% { transform: scale(1.9); opacity: 0; }
}

.journey-confetti-field {
    position: absolute;
    top: 8%;
    left: 50%;
    width: 0;
    height: 0;
}
.journey-confetti {
    position: absolute;
    width: 5px;
    height: 5px;
    border-radius: 1px;
    background: #34d399;
    opacity: 0;
}
.journey-confetti:nth-child(3n) { background: #F59E0B; }
.journey-confetti:nth-child(3n + 1) { background: #14B8A6; }
.journey-scene[data-scene="tap"].is-active .journey-confetti {
    animation: yc-confetti-burst 1s ease-out forwards;
}
@keyframes yc-confetti-burst {
    0% { transform: rotate(var(--angle)) translate(0, 0) scale(1); opacity: 1; }
    100% { transform: rotate(var(--angle)) translate(46px, -10px) scale(0); opacity: 0; }
}

/* ---------- shared: phone bezel (notify + dashboard) ---------- */
.journey-phone {
    position: relative;
    width: clamp(11rem, 58vw, 13rem);
    aspect-ratio: 0.62;
    border-radius: 2rem;
    background: #0b1226;
    border: 6px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
    overflow: hidden;
}
.journey-phone__notch {
    position: absolute;
    top: 0;
    left: 50%;
    width: 5rem;
    height: 1rem;
    margin-left: -2.5rem;
    border-radius: 0 0 0.75rem 0.75rem;
    background: #060a16;
    z-index: 2;
}
.journey-phone__statusbar {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.4rem 1rem 0.15rem;
    font-size: 0.6rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.8);
}
.journey-phone__statusicons {
    display: flex;
    gap: 0.35rem;
    font-size: 0.55rem;
    color: rgba(255, 255, 255, 0.6);
}
.journey-phone__wallpaper {
    position: absolute;
    inset: 1.6rem 0 0;
    background: radial-gradient(120% 80% at 50% 0%, rgba(15, 76, 129, 0.5), rgba(6, 10, 22, 0.9) 70%);
}

/* ---------- scene: notify ---------- */
.journey-notification {
    position: absolute;
    left: 0.6rem;
    right: 0.6rem;
    top: 1.9rem;
    z-index: 1;
    display: flex;
    gap: 0.6rem;
    padding: 0.75rem;
    border-radius: 1rem;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(8px);
    opacity: 0;
    transform: translateY(-140%);
}
.journey-notification--ghost {
    top: 4.6rem;
    opacity: 0;
    transform: translateY(-80%) scale(0.96);
    background: rgba(255, 255, 255, 0.04);
}
.journey-scene[data-scene="notify"].is-active .journey-notification {
    animation: yc-notif-drop 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.journey-scene[data-scene="notify"].is-active .journey-notification--ghost {
    animation: yc-notif-drop-ghost 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) 0.15s forwards;
}
@keyframes yc-notif-drop {
    to { opacity: 1; transform: translateY(0); }
}
@keyframes yc-notif-drop-ghost {
    to { opacity: 0.6; transform: translateY(0) scale(0.96); }
}
.journey-notification__icon {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    flex-shrink: 0;
    border-radius: 9999px;
    background: linear-gradient(135deg, #0F4C81, #14B8A6);
    color: #fff;
    font-size: 0.75rem;
}
.journey-notification__icon i {
    display: inline-block;
    transform-origin: top center;
}
.journey-scene[data-scene="notify"].is-active .journey-notification__icon i {
    animation: yc-bell-ring 0.7s ease-out 0.6s;
}
@keyframes yc-bell-ring {
    0%, 100% { transform: rotate(0deg); }
    15% { transform: rotate(18deg); }
    35% { transform: rotate(-14deg); }
    55% { transform: rotate(9deg); }
    75% { transform: rotate(-5deg); }
    90% { transform: rotate(2deg); }
}
.journey-notification__title {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    font-weight: 700;
    color: #fff;
}
.journey-notification__title span {
    font-weight: 500;
    color: rgba(255, 255, 255, 0.4);
}
.journey-notification__body {
    font-size: 0.65rem;
    color: rgba(255, 255, 255, 0.55);
    line-height: 1.3;
}

/* ---------- scene: dashboard (mini app UI, reuses .journey-phone) ---------- */
.journey-app {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    height: calc(100% - 1.6rem);
    padding: 0.75rem 0.9rem 0.6rem;
    text-align: left;
}
.journey-app > * {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.5s ease, transform 0.5s ease;
}
.journey-scene[data-scene="dashboard"].is-active .journey-app > * {
    opacity: 1;
    transform: translateY(0);
}
.journey-app__header { transition-delay: 0.05s; display: flex; align-items: center; justify-content: space-between; }
.journey-app__balance { transition-delay: 0.12s; }
.journey-app__actions { transition-delay: 0.2s; }
.journey-app__list { transition-delay: 0.28s; flex: 1; }
.journey-app__tabbar { transition-delay: 0.36s; margin-top: auto; }

.journey-app__greeting { font-size: 0.75rem; font-weight: 700; color: #fff; }
.journey-app__sub { font-size: 0.6rem; color: rgba(255, 255, 255, 0.4); }
.journey-app__avatar {
    display: grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.65rem;
}
.journey-app__balance {
    margin-top: 0.6rem;
    padding: 0.7rem 0.85rem;
    border-radius: 0.9rem;
    background: linear-gradient(135deg, #123a63, #0d6e63);
}
.journey-app__balance p:first-child { font-size: 0.55rem; text-transform: uppercase; letter-spacing: 0.1em; color: rgba(255, 255, 255, 0.5); }
.journey-app__balance-figure { font-family: 'Poppins', sans-serif; font-size: 1.1rem; font-weight: 800; color: #fff; }
.journey-app__actions {
    display: flex;
    justify-content: space-between;
    gap: 0.4rem;
    margin-top: 0.55rem;
}
.journey-app__actions span {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.4rem 0.2rem;
    border-radius: 0.6rem;
    background: rgba(255, 255, 255, 0.05);
    font-size: 0.5rem;
    color: rgba(255, 255, 255, 0.7);
}
.journey-app__actions i { color: #14B8A6; font-size: 0.75rem; }
.journey-app__list { margin-top: 0.6rem; }
.journey-app__row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 0.62rem;
}
.journey-app__row i { color: #F59E0B; width: 1.2rem; text-align: center; }
.journey-app__row p { color: rgba(255, 255, 255, 0.85); font-weight: 600; }
.journey-app__row span { color: rgba(255, 255, 255, 0.4); font-size: 0.55rem; }
.journey-app__row b { margin-left: auto; color: rgba(255, 255, 255, 0.5); font-weight: 700; }
.journey-app__tabbar {
    display: flex;
    justify-content: space-around;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.3);
    font-size: 0.75rem;
}
.journey-app__tabbar i.is-on { color: #14B8A6; }

/* ---------- scene: recharge ---------- */
.journey-recharge {
    position: relative;
    display: grid;
    place-items: center;
    width: 7rem;
    height: 7rem;
}
.journey-recharge__ring {
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    border: 2px solid rgba(245, 158, 11, 0.4);
    opacity: 0;
}
.journey-scene[data-scene="recharge"].is-active .journey-recharge__ring {
    animation: yc-tap-ripple 2s ease-out infinite;
}
.journey-scene[data-scene="recharge"].is-active .journey-recharge__ring--2 {
    animation-delay: 0.8s;
}
.journey-recharge__pad {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 9999px;
    background: linear-gradient(135deg, #F59E0B, #14B8A6);
    color: #fff;
    font-size: 1.25rem;
    box-shadow: 0 0 30px rgba(245, 158, 11, 0.4);
}
.journey-coin {
    position: absolute;
    bottom: 0.5rem;
    left: 50%;
    display: grid;
    place-items: center;
    width: 1.1rem;
    height: 1.1rem;
    margin-left: -0.55rem;
    border-radius: 9999px;
    background: #F59E0B;
    color: #1a1206;
    font-size: 0.55rem;
    font-weight: 800;
    opacity: 0;
}
.journey-scene[data-scene="recharge"].is-active .journey-coin {
    animation: yc-coin-rise 1.6s cubic-bezier(0.33, 0, 0.2, 1) infinite;
}
@keyframes yc-coin-rise {
    0% { opacity: 0; transform: translate(0, 0) rotate(0deg); }
    15% { opacity: 1; }
    55% { transform: translate(calc(var(--coin-x) * 0.55), -3.4rem) rotate(150deg); }
    100% { opacity: 0; transform: translate(var(--coin-x), -6.5rem) rotate(300deg); }
}
.journey-scene[data-scene="recharge"].is-active .journey-recharge__pad i {
    animation: yc-pad-glow 2s ease-in-out infinite;
}
@keyframes yc-pad-glow {
    0%, 100% { filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.3)); transform: scale(1); }
    50% { filter: drop-shadow(0 0 8px rgba(255, 255, 255, 0.9)); transform: scale(1.12); }
}

/* ---------- scene: map ---------- */
.journey-map-wrap {
    position: relative;
    width: min(100%, 26rem);
}
.journey-map {
    width: 100%;
    height: auto;
}
.journey-route {
    stroke: #14B8A6;
    stroke-width: 2.5;
    stroke-linecap: round;
    fill: none;
}
.journey-route--alt {
    stroke: #F59E0B;
}
.journey-map__base {
    stroke: var(--j-line);
}
.journey-map__node {
    fill: var(--j-node);
    opacity: 0.8;
}
.journey-map__node--hub {
    fill: #14B8A6;
}
.journey-scene[data-scene="map"].is-active .journey-map__node--hub {
    animation: yc-shadow-pulse 2s ease-in-out infinite;
}
.journey-map-bus {
    position: absolute;
    top: 0;
    left: 0;
    display: grid;
    place-items: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 9999px;
    background: #14B8A6;
    color: #060a16;
    font-size: 0.55rem;
    opacity: 0;
    offset-rotate: 0deg;
}
.journey-map-bus--1 { offset-path: path('M45 70 L115 40 L190 55 L260 60'); background: #14B8A6; }
.journey-map-bus--2 { offset-path: path('M45 70 L80 100 L150 85 L225 95 L310 110'); background: #F59E0B; }
.journey-scene[data-scene="map"].is-active .journey-map-bus {
    opacity: 1;
    animation: yc-map-travel 3.4s linear infinite;
}
.journey-map-bus--2 {
    animation-delay: 0.6s;
}
@keyframes yc-map-travel {
    0% { offset-distance: 0%; opacity: 0; }
    8% { opacity: 1; }
    92% { opacity: 1; }
    100% { offset-distance: 100%; opacity: 0; }
}
.journey-map-legend {
    display: flex;
    gap: 1rem;
    margin-top: 0.75rem;
    font-size: 0.7rem;
    color: var(--j-ink-soft);
}
.journey-map-legend span {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.journey-map-legend i {
    font-size: 0.5rem;
}

/* ---------- scene: ecosystem ---------- */
.journey-orbit {
    --orbit-radius: 8rem;
    position: relative;
    width: 16rem;
    height: 16rem;
}
/* Narrow screens: shrink the whole ring rather than let it overflow the
   scene padding — one variable drives the ring, spokes, and all 5 items. */
@media (max-width: 460px) {
    .journey-orbit {
        --orbit-radius: 5.4rem;
        width: 11rem;
        height: 11rem;
    }
    .journey-orbit__ring--2 {
        inset: 1.5rem;
    }
}
.journey-orbit__ring {
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    border: 1px dashed var(--j-line-faint);
}
.journey-orbit__ring--2 {
    inset: 2.25rem;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__ring--1 {
    animation: yc-spin 40s linear infinite;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__ring--2 {
    animation: yc-spin 28s linear infinite reverse;
}
.journey-orbit__spoke {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--orbit-radius);
    height: 1px;
    background: linear-gradient(90deg, var(--j-line), transparent);
    transform-origin: 0 50%;
}
/* Positional wrapper — transform is ONLY ever the fixed placement on the
   circle (rotate/translate/counter-rotate), so it never fights with the
   entrance/idle animations living on .journey-orbit__item-inner. */
.journey-orbit__item {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 2.75rem;
    height: 2.75rem;
    margin: -1.375rem;
}
.journey-orbit__item--1 { transform: rotate(0deg) translate(var(--orbit-radius)) rotate(0deg); }
.journey-orbit__item--2 { transform: rotate(72deg) translate(var(--orbit-radius)) rotate(-72deg); }
.journey-orbit__item--3 { transform: rotate(144deg) translate(var(--orbit-radius)) rotate(-144deg); }
.journey-orbit__item--4 { transform: rotate(216deg) translate(var(--orbit-radius)) rotate(-216deg); }
.journey-orbit__item--5 { transform: rotate(288deg) translate(var(--orbit-radius)) rotate(-288deg); }

.journey-orbit__item-inner {
    position: relative;
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    border-radius: 0.9rem;
    border: 1px solid var(--j-glass-border);
    color: #fff;
    font-size: 1rem;
    backdrop-filter: blur(8px);
    overflow: hidden;
    opacity: 0;
    transform: scale(0.4);
    transition: opacity 0.45s ease, transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__item-inner {
    opacity: 1;
    transform: scale(1);
}
.journey-orbit__item--1 .journey-orbit__item-inner { background: linear-gradient(135deg, #0F4C81, #14B8A6); transition-delay: 0s; }
.journey-orbit__item--2 .journey-orbit__item-inner { background: linear-gradient(135deg, #14B8A6, #0F4C81); transition-delay: 0.08s; }
.journey-orbit__item--3 .journey-orbit__item-inner { background: linear-gradient(135deg, #F59E0B, #14B8A6); transition-delay: 0.16s; }
.journey-orbit__item--4 .journey-orbit__item-inner { background: linear-gradient(135deg, #0F4C81, #F59E0B); transition-delay: 0.24s; }
.journey-orbit__item--5 .journey-orbit__item-inner { background: var(--j-glass-bg); color: var(--j-ink); transition-delay: 0.32s; }

/* Per-icon micro-animations — distinct motion language for each category
   rather than one generic loop repeated five times. */
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__item--1 i {
    animation: yc-orbit-bus-shake 3.2s ease-in-out infinite;
}
@keyframes yc-orbit-bus-shake {
    0%, 82%, 100% { transform: translateX(0) rotate(0deg); }
    85% { transform: translateX(-1px) rotate(-4deg); }
    88% { transform: translateX(1px) rotate(4deg); }
    91% { transform: translateX(-1px) rotate(-2deg); }
    94% { transform: translateX(0) rotate(0deg); }
}
.journey-orbit__item--2 .journey-orbit__item-inner::after {
    content: '';
    position: absolute;
    top: -60%;
    left: -60%;
    width: 220%;
    height: 220%;
    background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.35) 50%, transparent 60%);
    transform: translate(-30%, -30%);
    opacity: 0;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__item--2 .journey-orbit__item-inner::after {
    animation: yc-orbit-shine 3s ease-in-out infinite;
}
@keyframes yc-orbit-shine {
    0%, 60% { opacity: 0; transform: translate(-30%, -30%); }
    70% { opacity: 0.9; }
    85%, 100% { opacity: 0; transform: translate(30%, 30%); }
}
.journey-orbit__pulse-ring {
    position: absolute;
    inset: 0.4rem;
    border-radius: 9999px;
    border: 1.5px solid rgba(255, 255, 255, 0.7);
    opacity: 0;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__pulse-ring {
    animation: yc-tap-ripple 2.4s ease-out infinite;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__item--4 i {
    transform-origin: top center;
    animation: yc-orbit-bag-swing 2.4s ease-in-out infinite;
}
@keyframes yc-orbit-bag-swing {
    0%, 100% { transform: rotate(0deg); }
    25% { transform: rotate(10deg); }
    75% { transform: rotate(-10deg); }
}
.journey-orbit__item-inner--dots {
    display: flex;
    align-items: center;
    gap: 0.2rem;
}
.journey-orbit__dot {
    width: 0.3rem;
    height: 0.3rem;
    border-radius: 9999px;
    background: var(--j-ink);
    opacity: 0.3;
}
.journey-scene[data-scene="ecosystem"].is-active .journey-orbit__dot {
    animation: yc-orbit-dot-pulse 1.2s ease-in-out infinite;
}
.journey-orbit__dot:nth-child(2) { animation-delay: 0.15s; }
.journey-orbit__dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes yc-orbit-dot-pulse {
    0%, 100% { opacity: 0.3; transform: scale(1); }
    50% { opacity: 1; transform: scale(1.3); }
}

/* ---------- scene: finale ---------- */
.journey-finale-backdrop {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 30%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 0.6rem;
    padding: 0 8%;
    opacity: 0.25;
}
.journey-finale-backdrop span {
    width: clamp(1.5rem, 6%, 3rem);
    border-radius: 0.25rem 0.25rem 0 0;
    background: linear-gradient(180deg, var(--j-glass-border), var(--j-glass-bg));
}
.journey-confetti-field--finale {
    top: 44%;
}
.journey-scene[data-scene="finale"].is-active .journey-confetti-field--finale .journey-confetti {
    animation: yc-confetti-burst-wide 1.4s ease-out forwards;
}
@keyframes yc-confetti-burst-wide {
    0% { transform: rotate(var(--angle)) translate(0, 0) scale(1); opacity: 1; }
    100% { transform: rotate(var(--angle)) translate(90px, -20px) scale(0); opacity: 0; }
}
.journey-finale-copy {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 9%;
    padding: 0 2rem;
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.6s ease 0.3s, transform 0.6s ease 0.3s;
}
.journey-scene[data-scene="finale"].is-active .journey-finale-copy {
    opacity: 1;
    transform: translateY(0);
}
.journey-static .journey-finale-copy {
    position: relative;
    bottom: auto;
    opacity: 1;
    transform: none;
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
    .journey-card-float,
    .journey-beacon,
    .journey-walker-wrap,
    .journey-road__lane,
    .journey-speedlines span,
    .journey-ripple,
    .journey-confetti,
    .journey-recharge__ring,
    .journey-coin,
    .journey-map__node--hub,
    .journey-map-bus,
    .journey-orbit__ring--1,
    .journey-orbit__ring--2,
    .journey-notification,
    .journey-notification--ghost,
    .journey-notification__icon i,
    .journey-app > *,
    .journey-nfc-waves,
    .nfc-wave--1,
    .nfc-wave--2,
    .check-ring,
    .check-mark,
    .journey-screen-flash,
    .journey-step-ping--l,
    .journey-step-ping--r,
    .journey-bus-suspension,
    .journey-bus-ground-shadow,
    .journey-recharge__pad i,
    .journey-orbit__item--1 i,
    .journey-orbit__item--2 .journey-orbit__item-inner::after,
    .journey-orbit__pulse-ring,
    .journey-orbit__item--4 i,
    .journey-orbit__dot,
    .journey-orbit__item-inner {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
    .check-ring,
    .check-mark {
        stroke-dashoffset: 0 !important;
    }
}

/* ==========================================================================
   FEATURE ICON MOTION
   Every feature-icon-badge[data-motion] gets its own hand-tuned hover
   gesture instead of one generic bounce copy-pasted across the grid —
   see resources/views/partials/home/features.blade.php for the mapping.
   ========================================================================== */
.feature-icon-badge {
    position: relative;
    overflow: hidden;
}
.feature-icon-badge__shine {
    position: absolute;
    top: -60%;
    left: -60%;
    width: 220%;
    height: 220%;
    background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.55) 50%, transparent 60%);
    transform: translate(-30%, -30%);
    opacity: 0;
    pointer-events: none;
}
.group:hover .feature-icon-badge__shine {
    animation: yc-feature-shine 0.9s ease-out;
}
@keyframes yc-feature-shine {
    0% { opacity: 0; transform: translate(-30%, -30%); }
    30% { opacity: 1; }
    100% { opacity: 0; transform: translate(30%, 30%); }
}
.feature-icon-badge__ring {
    position: absolute;
    inset: -2px;
    border-radius: inherit;
    border: 1.5px solid currentColor;
    opacity: 0;
    pointer-events: none;
}
.feature-icon-badge__glyph {
    position: relative;
    z-index: 1;
    display: inline-block;
}

/* Tap In / Tap Out — a quick left-right ping-pong, like the icon's own arrows */
.group:hover [data-motion="tap"] .feature-icon-badge__glyph {
    animation: yc-feature-tap 0.7s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes yc-feature-tap {
    0%, 100% { transform: translateX(0); }
    35% { transform: translateX(-3px) scale(0.92); }
    70% { transform: translateX(3px) scale(1.05); }
}

/* NFC — radiating contactless waves */
.group:hover [data-motion="nfc"] .feature-icon-badge__ring {
    animation: yc-tap-ripple 1.1s ease-out infinite;
}
.group:hover [data-motion="nfc"] .feature-icon-badge__glyph {
    animation: yc-feature-pulse 1.1s ease-in-out infinite;
}
@keyframes yc-feature-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.12); }
}

/* Instant Fare Deduction — an electric strike/flicker */
.group:hover [data-motion="bolt"] .feature-icon-badge__glyph {
    animation: yc-feature-bolt 0.5s ease-in-out;
}
@keyframes yc-feature-bolt {
    0%, 100% { transform: scale(1) rotate(0deg); filter: brightness(1); }
    20% { transform: scale(0.85) rotate(-8deg); filter: brightness(1.6); }
    45% { transform: scale(1.15) rotate(6deg); filter: brightness(1.3); }
    70% { transform: scale(0.95) rotate(-3deg); filter: brightness(1.1); }
}

/* Multi-Route Support — travels a short path back and forth */
.group:hover [data-motion="route"] .feature-icon-badge__glyph {
    animation: yc-feature-route 1s ease-in-out infinite;
}
@keyframes yc-feature-route {
    0%, 100% { transform: translateX(-3px) rotate(-4deg); }
    50% { transform: translateX(3px) rotate(4deg); }
}

/* Recharge Easily — a "topping up" bounce with overshoot */
.group:hover [data-motion="wallet"] .feature-icon-badge__glyph {
    animation: yc-feature-wallet 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes yc-feature-wallet {
    0% { transform: translateY(0) scale(1); }
    40% { transform: translateY(-4px) scale(1.1); }
    100% { transform: translateY(0) scale(1); }
}

/* Digital Transaction History — a subtle scrolling-list feed */
.group:hover [data-motion="history"] .feature-icon-badge__glyph {
    animation: yc-feature-history 0.8s ease-in-out infinite;
}
@keyframes yc-feature-history {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-2px); }
}

/* Balance Inquiry — a scanning sweep tilt */
.group:hover [data-motion="search"] .feature-icon-badge__glyph {
    animation: yc-feature-search 0.9s ease-in-out infinite;
}
@keyframes yc-feature-search {
    0%, 100% { transform: rotate(0deg) translate(0, 0); }
    25% { transform: rotate(-12deg) translate(-1px, 1px); }
    75% { transform: rotate(12deg) translate(1px, -1px); }
}

/* Electronic Ticket — a light perforated wobble, like tearing a stub */
.group:hover [data-motion="ticket"] .feature-icon-badge__glyph {
    animation: yc-feature-ticket 0.6s ease-in-out;
}
@keyframes yc-feature-ticket {
    0%, 100% { transform: rotate(0deg); }
    30% { transform: rotate(-10deg); }
    60% { transform: rotate(8deg); }
    80% { transform: rotate(-4deg); }
}

/* Secure Transactions — a lock "click" squeeze */
.group:hover [data-motion="lock"] .feature-icon-badge__glyph {
    animation: yc-feature-lock 0.4s ease-in-out;
}
@keyframes yc-feature-lock {
    0%, 100% { transform: scale(1); }
    40% { transform: scale(0.82) translateY(1px); }
    70% { transform: scale(1.08); }
}

/* Lost Card Protection — a protective pulse ring */
.group:hover [data-motion="shield"] .feature-icon-badge__ring {
    animation: yc-tap-ripple 1.2s ease-out infinite;
}
.group:hover [data-motion="shield"] .feature-icon-badge__glyph {
    animation: yc-feature-pulse 1.2s ease-in-out infinite;
}

/* Student Discount — a graduation-cap toss */
.group:hover [data-motion="grad"] .feature-icon-badge__glyph {
    animation: yc-feature-grad 0.7s ease-in-out;
    transform-origin: bottom center;
}
@keyframes yc-feature-grad {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    40% { transform: translateY(-5px) rotate(-14deg); }
    70% { transform: translateY(-2px) rotate(8deg); }
}

/* Senior Citizen Discount — a gentle, steady sway */
.group:hover [data-motion="cane"] .feature-icon-badge__glyph {
    animation: yc-feature-sway 1.4s ease-in-out infinite;
    transform-origin: bottom center;
}
@keyframes yc-feature-sway {
    0%, 100% { transform: rotate(-4deg); }
    50% { transform: rotate(4deg); }
}

@media (prefers-reduced-motion: reduce) {
    .feature-icon-badge__shine,
    .feature-icon-badge__ring,
    .feature-icon-badge__glyph {
        animation: none !important;
    }
}

