/* ═══════════════════════════════════════════════════════════
   KSM × TECH — MOTION SYSTEM
   Award-grade, zero-JS, CSS-native motion.
   Atmospheric, never navigational.
   ═══════════════════════════════════════════════════════════ */

/* ─── MOTION TOKENS ──────────────────────────────────────── */
:root {
    --m-reveal:     0.65s;
    --m-transition:  0.4s;
    --m-ease:        cubic-bezier(0.16, 1, 0.3, 1);
    --m-ease-smooth: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* ─── PREFERS-REDUCED-MOTION ─────────────────────────────── */
/* Non-negotiable. The studio builds for people in heavy
   mental moments. Motion that cannot be turned off would
   contradict the product philosophy.                        */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ─── VIEW TRANSITIONS (page-to-page morph) ──────────────── */
/* Smooth, cinematic cross-fade. No shared-element morphs —
   titles differ too radically between pages; a clean dissolve
   feels intentional while a morph feels glitchy.            */
@view-transition {
    navigation: auto;
}

/* Old page fades out gently */
::view-transition-old(root) {
    animation: vtFadeOut 0.35s cubic-bezier(0.4, 0, 1, 1) both;
}

/* New page fades in with a whisper of upward drift */
::view-transition-new(root) {
    animation: vtFadeIn 0.45s cubic-bezier(0, 0, 0.2, 1) 0.1s both;
}

/* Prevent the old and new snapshots from blending on top
   of each other — the old page fully exits before the new
   one begins to appear. This removes the "double image"
   flash that causes the glitch feeling.                     */
::view-transition-old(root),
::view-transition-new(root) {
    mix-blend-mode: normal;
}

/* Stack: new page always on top during transition */
::view-transition-new(root) {
    z-index: 1;
}
::view-transition-old(root) {
    z-index: 0;
}

@keyframes vtFadeOut {
    from { opacity: 1; filter: blur(0); }
    to   { opacity: 0; filter: blur(1px); }
}

@keyframes vtFadeIn {
    from { opacity: 0; transform: translateY(4px); filter: blur(1px); }
    to   { opacity: 1; transform: translateY(0);   filter: blur(0); }
}

/* ─── SCROLL-DRIVEN SECTION REVEALS ──────────────────────── */
/* Replaces IntersectionObserver JS entirely on supported
   browsers. Runs on compositor thread: 60fps, zero
   main-thread cost.                                         */

@supports (animation-timeline: view()) {
    .reveal-scroll {
        animation: revealUp linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 35%;
    }

    @keyframes revealUp {
        from { opacity: 0;   transform: translateY(36px); }
        to   { opacity: 1;   transform: translateY(0); }
    }

    /* ─── SCROLL-LINKED BUILD CARD LIFT ──────────────────── */
    .product {
        animation: cardLift linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 40%;
    }

    @keyframes cardLift {
        from { opacity: 0.3; transform: translateY(48px) scale(0.97); }
        to   { opacity: 1;   transform: translateY(0)    scale(1); }
    }

    /* ─── SCROLL-LINKED COLOUR-FIELD SHIFT PER BUILD ─────── */
    /* Uses ::after to avoid conflicting with the ::before
       hover-glow already defined in home.css.               */

    .product-byf::after,
    .product-margadarshak::after,
    .product-krishna::after {
        content: '';
        position: fixed;
        inset: 0;
        pointer-events: none;
        z-index: -1;
        animation: colourFieldIn linear both;
        animation-timeline: view();
        animation-range: contain 0% contain 100%;
    }

    .product-byf::after {
        background: radial-gradient(ellipse at 50% 50%, rgba(105, 84, 141, 0.06), transparent 70%);
    }

    .product-margadarshak::after {
        background: radial-gradient(ellipse at 50% 50%, rgba(168, 72, 79, 0.05), transparent 70%);
    }

    .product-krishna::after {
        background: radial-gradient(ellipse at 50% 50%, rgba(45, 85, 86, 0.06), transparent 70%);
    }

    @keyframes colourFieldIn {
        0%   { opacity: 0; }
        20%  { opacity: 1; }
        80%  { opacity: 1; }
        100% { opacity: 0; }
    }
}

/* ─── @SUPPORTS FALLBACK NOTE ────────────────────────────── */
/* ~16% of browsers lack animation-timeline support.
   They get:
   1. The existing IntersectionObserver JS (kept in index.html)
   2. Clean, static, instant-visible content
   3. No broken layout — every element still appears           */

/* ─── CURSOR-PARALLAX ON PRODUCT ART (desktop only) ──────── */
/* Lightweight: mousemove sets --mx, --my custom props.
   CSS applies transform. Max ±6px.                          */
@media (pointer: fine) {
    .product-visual {
        transition: transform 0.5s var(--m-ease-smooth);
    }

    .product:hover .product-visual {
        transform:
            translate(
                calc((var(--mx, 0.5) - 0.5) * 12px),
                calc((var(--my, 0.5) - 0.5) * 12px)
            );
    }
}

/* ─── HERO WORD CASCADE — CSS-DRIVEN ─────────────────────── */
/* The JS word-split in index.html sets the structure;
   the animation itself is pure CSS keyframes (already
   defined in home.css as wordReveal). This section
   adds stagger via nth-child for when JS structure is
   present.                                                  */
.word-wrap:nth-child(1)  .word { animation-delay: 0.00s; }
.word-wrap:nth-child(2)  .word { animation-delay: 0.06s; }
.word-wrap:nth-child(3)  .word { animation-delay: 0.12s; }
.word-wrap:nth-child(4)  .word { animation-delay: 0.18s; }
.word-wrap:nth-child(5)  .word { animation-delay: 0.24s; }
.word-wrap:nth-child(6)  .word { animation-delay: 0.30s; }
.word-wrap:nth-child(7)  .word { animation-delay: 0.36s; }
.word-wrap:nth-child(8)  .word { animation-delay: 0.42s; }
.word-wrap:nth-child(9)  .word { animation-delay: 0.48s; }
.word-wrap:nth-child(10) .word { animation-delay: 0.54s; }

/* Second line starts later */
.hero-title .line:nth-child(2) .word-wrap:nth-child(1)  .word { animation-delay: 0.40s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(2)  .word { animation-delay: 0.46s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(3)  .word { animation-delay: 0.52s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(4)  .word { animation-delay: 0.58s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(5)  .word { animation-delay: 0.64s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(6)  .word { animation-delay: 0.70s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(7)  .word { animation-delay: 0.76s; }
.hero-title .line:nth-child(2) .word-wrap:nth-child(8)  .word { animation-delay: 0.82s; }
