/* Light 3D depth, site-wide.
 *
 * Loaded LAST (immediately before </head>) on every root page, because each
 * page carries its own inline <style> block and several rules here are
 * equal-specificity overrides of it (.js-enabled .animate-on-scroll,
 * .btn-primary:hover, .timeline-card:hover, .timeline-number). Only source
 * order can win those, so the link position is load-bearing.
 *
 * The whole vocabulary is six tokens. Everything composes from them -- that
 * constraint is the difference between institutional depth and "someone found
 * a tilt library".
 */

:root {
    --lift-1: 6px;
    --lift-2: 14px;
    --lift-3: 28px;
    --ease-out-quint: cubic-bezier(0.22, 1, 0.36, 1);
    --tilt-max: 6deg;
    --yaw-max: 8deg;
}

/* Scroll entrances gain depth -------------------------------------------- */
/* site.js already tags .card, .timeline-item, .feature-item, .section-header
   children, .numbered-list li and the hero children; this is CSS-only.
   perspective() must appear in BOTH states or the transform will not
   interpolate and the elements snap. */
.js-enabled .animate-on-scroll {
    opacity: 0;
    transform: perspective(1200px) translate3d(0, 26px, -50px) rotateX(0deg);
}
/* Only card-shaped things get rotateX. Rotating every heading and paragraph of
   a text-dense page would rasterise the type at an angle for 800ms. */
.js-enabled .card.animate-on-scroll,
.js-enabled .timeline-item.animate-on-scroll,
.js-enabled .feature-item.animate-on-scroll {
    transform: perspective(1200px) translate3d(0, 26px, -60px) rotateX(6deg);
}
.js-enabled .animate-on-scroll.is-visible {
    opacity: 1;
    transform: perspective(1200px) translate3d(0, 0, 0) rotateX(0deg);
}
/* A resting perspective() keeps the element composited forever. site.js drops
   this class on transitionend so the layer is released and the type
   re-rasterises crisp. */
.js-enabled .animate-on-scroll.is-settled {
    transform: none;
}

/* Parallax cards ---------------------------------------------------------- */
/* site.js writes --pz (viewport-relative, not absolute page scroll); the pose
   lives here so index.html and who-can-use.html share it. The per-element
   perspective() avoids having to add a wrapper class to two files. */
.parallax-element {
    transform:
        perspective(1200px)
        translate3d(0, var(--pz, 0px), calc(var(--pz, 0px) * 0.6))
        rotateY(var(--pr, -7deg));
}
.parallax-element:nth-of-type(2n) { --pr: 5deg; }
.parallax-element:nth-of-type(3n) { --pr: -10deg; }

/* Buttons: a physical press ------------------------------------------------ */
/* Replaces `transition: all .2s` (a latent repaint hazard once the element is
   also transformed) and the opacity-only hover. Depth rather than scale is the
   difference between "fintech" and "consumer app". */
.btn {
    transition:
        background-color 0.2s ease,
        color 0.2s ease,
        border-color 0.2s ease,
        box-shadow 0.18s ease,
        transform 0.18s var(--ease-out-quint);
}
.btn-primary:hover {
    opacity: 1;
    transform: perspective(600px) translateZ(var(--lift-1));
    box-shadow: 0 12px 24px -10px rgba(11, 38, 24, 0.45);
}
.btn-primary:active {
    transform: perspective(600px) translateZ(-4px) translateY(1px);
    box-shadow: 0 3px 8px -4px rgba(11, 38, 24, 0.5);
}
.btn-secondary:hover {
    transform: perspective(600px) translateZ(var(--lift-1));
    box-shadow: 0 10px 20px -12px rgba(11, 38, 24, 0.3);
}

/* Pointer tilt: opt-in, product + timeline cards only ---------------------- */
/* Deliberately NOT applied to every .card. Capped at 6/8 degrees: past ~10 it
   stops looking like expensive furniture and starts looking like a template.
   The inner lift is what sells it -- contents moving at a different rate than
   the card face is the parallax a generic tilt does not have.
   The hover gate also neutralises iOS sticky-:hover. */
@media (hover: hover) and (pointer: fine) {
    .card-3d {
        transform-style: preserve-3d;
        transition:
            transform 0.35s var(--ease-out-quint),
            box-shadow 0.35s ease,
            border-color 0.35s ease;
    }
    /* Every card here is also an .animate-on-scroll target, and the entrance
       rules above resolve at (0,3,0). The second selector exists purely to
       out-specify them -- without it the tilt never applies. */
    .card-3d:hover,
    .js-enabled .card-3d.animate-on-scroll:hover {
        transform:
            perspective(1000px)
            rotateX(calc((0.5 - var(--my, 0.5)) * var(--tilt-max)))
            rotateY(calc((var(--mx, 0.5) - 0.5) * var(--yaw-max)))
            translateZ(var(--lift-2));
        box-shadow:
            0 28px 56px -20px rgba(11, 38, 24, 0.24),
            0 8px 18px -10px rgba(11, 38, 24, 0.16);
    }
    .card-3d .product-icon {
        transform: translateZ(var(--lift-3));
    }
    .card-3d h3 {
        transform: translateZ(var(--lift-2));
    }
    /* ...but the entrance must still win while the card is arriving. */
    .js-enabled .card-3d.animate-on-scroll:not(.is-visible):hover {
        transform: perspective(1200px) translate3d(0, 26px, -60px) rotateX(6deg);
    }
}

/* Timeline number spheres -------------------------------------------------- */
/* Pure static shading: no animation, no layer promotion, no runtime cost.
   A bright top inset and a dark bottom inset turn a flat disc into a chip. */
.timeline-number {
    background: radial-gradient(circle at 34% 28%, #2C7A50 0%, #1A5C3A 52%, #123F28 100%);
    box-shadow:
        0 8px 20px -6px rgba(26, 92, 58, 0.32),
        inset 0 1px 1px rgba(255, 255, 255, 0.35),
        inset 0 -3px 6px rgba(0, 0, 0, 0.18);
}

/* One shared light source -------------------------------------------------- */
/* The hero already has drifting glow blobs. Two 3D moments lit by the same
   source read as one page; two lit differently read as two templates stitched
   together. The wrapper clips, so the blobs can never widen the page. */
.section-glow {
    position: relative;
    isolation: isolate;
}
.section-glow > .container {
    position: relative;
    z-index: 1;
}
.section-glows {
    position: absolute;
    inset: 0;
    overflow: hidden;
    z-index: 0;
    pointer-events: none;
}
.section-glow-blob {
    position: absolute;
    border-radius: 50%;
    filter: blur(90px);
    opacity: 0.5;
    pointer-events: none;
}
.section-glow-blob-a {
    width: 620px;
    height: 520px;
    left: -8%;
    top: -14%;
    background: radial-gradient(circle at 42% 42%, rgba(26, 92, 58, 0.20), rgba(26, 92, 58, 0) 70%);
    animation: depth-drift-a 40s ease-in-out infinite alternate;
}
.section-glow-blob-b {
    width: 660px;
    height: 560px;
    right: -10%;
    bottom: -16%;
    background: radial-gradient(circle at 58% 58%, rgba(196, 184, 150, 0.30), rgba(196, 184, 150, 0) 70%);
    animation: depth-drift-b 46s ease-in-out infinite alternate;
}
@keyframes depth-drift-a {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(50px, 36px, 0) scale(1.1); }
}
@keyframes depth-drift-b {
    from { transform: translate3d(0, 0, 0) scale(1.06); }
    to   { transform: translate3d(-60px, -26px, 0) scale(0.95); }
}
@media (max-width: 768px) {
    .section-glow-blob-a,
    .section-glow-blob-b {
        width: 360px;
        height: 360px;
    }
}

/* Trust-strip logos: a restrained lift for client marks. */
.trust-logo {
    transition: opacity 0.2s ease, transform 0.28s var(--ease-out-quint);
}
.trust-logo:hover {
    transform: perspective(600px) translateZ(var(--lift-1));
}

/* Reduced motion: one guard covering every addition above. Static shading (the
   timeline spheres, the button shadows) is not motion and stays. */
@media (prefers-reduced-motion: reduce) {
    .js-enabled .animate-on-scroll,
    .js-enabled .animate-on-scroll.is-visible {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .card-3d,
    .card-3d:hover,
    .btn-primary:hover,
    .btn-primary:active,
    .btn-secondary:hover,
    .trust-logo:hover,
    .parallax-element {
        transform: none !important;
        transition: none !important;
    }
    .card-3d .product-icon,
    .card-3d h3 {
        transform: none !important;
    }
    .section-glow-blob {
        animation: none !important;
    }
}
