/* =========================================================
   CARTX — 3D / FLUID MOTION LAYER
   Loaded on every page alongside app.css. Everything in here is
   additive: if JS never runs (no WebGL, reduced motion, blocked
   script) the page underneath still looks and works exactly like
   the plain app.css version.
   ========================================================= */

:root {
    --fluid-ease: cubic-bezier(.16, 1, .3, 1);
    --tilt-ease: cubic-bezier(.2, .8, .2, 1);
}

/* ---------------------------------------------------------
   AURORA BACKGROUND
   Large, heavily-blurred color blobs drifting slowly behind
   everything — pure CSS (transform + filter, GPU-composited),
   so it's smooth even on modest hardware and needs no JS at all
   to render (only to pause it, for prefers-reduced-motion).
   z-index sits below #webgl-scene, so the glow orbs float over it.
   --------------------------------------------------------- */

#aurora-bg {
    position: fixed;
    inset: 0;
    z-index: -2;
    overflow: hidden;
    pointer-events: none;
}

.aurora-blob {
    position: absolute;
    width: 46vw;
    height: 46vw;
    min-width: 420px;
    min-height: 420px;
    max-width: 780px;
    max-height: 780px;
    border-radius: 50%;
    filter: blur(90px);
    opacity: .28;
    will-change: transform;
}

.aurora-blob-1 {
    top: -12%;
    left: -8%;
    background: radial-gradient(circle, var(--brand-bright, #4caf50), transparent 70%);
    animation: auroraDrift1 26s ease-in-out infinite;
}

.aurora-blob-2 {
    top: 8%;
    right: -12%;
    background: radial-gradient(circle, var(--blue, #247dfe), transparent 70%);
    animation: auroraDrift2 32s ease-in-out infinite;
}

.aurora-blob-3 {
    bottom: -14%;
    left: 18%;
    background: radial-gradient(circle, var(--navy, #13294b), transparent 70%);
    opacity: .22;
    animation: auroraDrift3 38s ease-in-out infinite;
}

.aurora-blob-4 {
    bottom: 4%;
    right: 12%;
    width: 30vw;
    height: 30vw;
    min-width: 280px;
    min-height: 280px;
    max-width: 520px;
    max-height: 520px;
    background: radial-gradient(circle, var(--coral, #ef5b3d), transparent 70%);
    opacity: .16;
    animation: auroraDrift4 22s ease-in-out infinite;
}

@keyframes auroraDrift1 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    33%      { transform: translate(6vw, 8vh) scale(1.12); }
    66%      { transform: translate(-4vw, 5vh) scale(.94); }
}

@keyframes auroraDrift2 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(-7vw, 10vh) scale(1.08); }
}

@keyframes auroraDrift3 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    40%      { transform: translate(5vw, -6vh) scale(1.15); }
    75%      { transform: translate(-6vw, -3vh) scale(.9); }
}

@keyframes auroraDrift4 {
    0%, 100% { transform: translate(0, 0) scale(1); }
    50%      { transform: translate(-5vw, -8vh) scale(1.1); }
}

@media (prefers-reduced-motion: reduce) {
    .aurora-blob {
        animation: none;
    }
}

/* ---------------------------------------------------------
   WEBGL GLOW ORBS
   Fixed, full-viewport, behind every page's content. Rendered
   by fluid3d.js; stays inert (and invisible) if WebGL/JS can't run.
   --------------------------------------------------------- */

#webgl-scene {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: -1;
    display: block;
    pointer-events: none;
    background: transparent;
}

/* ---------------------------------------------------------
   PAGE TRANSITION CURTAIN
   Defaults to invisible/inert so a page never depends on JS
   running to be seen. JS only ever adds ".is-closing" for the
   moment right before it navigates away.
   ---------------------------------------------------------
*/

#page-transition {
    position: fixed;
    inset: 0;
    z-index: 99999;
    background: #0b0b0d;
    opacity: 0;
    pointer-events: none;
    transition: opacity .4s var(--fluid-ease);
}

#page-transition.is-closing {
    opacity: 1;
    pointer-events: all;
}

/* ---------------------------------------------------------
   3D TILT CARDS
   JS sets --rx/--ry/--tz per element on pointer move; the
   transform itself lives here so motion stays GPU-cheap.
   --------------------------------------------------------- */

.tilt-3d {
    --rx: 0deg;
    --ry: 0deg;
    --tz: 0px;
    --px: 0px;
    --py: 0px;
    transform: perspective(1000px) rotateX(var(--rx)) rotateY(var(--ry)) translateZ(var(--tz));
    transition: transform .5s var(--tilt-ease), box-shadow .4s ease;
    transform-style: preserve-3d;
    will-change: transform;
}

.tilt-3d.is-tilting {
    transition: transform .08s linear, box-shadow .4s ease;
}

.tilt-3d > * {
    transform: translateZ(1px);
}

/* True parallax instead of the flat 1px nudge above: the product image
   sits on its own elevated plane and drifts opposite the tilt direction
   (--px/--py, set alongside --rx/--ry in fluid3d.js), so it reads as a
   photo floating above the card rather than the card just tipping over.
   scale(1.08) is a safety margin, not decoration - object-fit:cover
   images are sized exactly to their container, so without overscaling
   the image first, translate() would reveal a sliver of bare container
   background at whichever edge the image drifts away from. Also carries
   the old static hover-zoom (app.css) since both can't set `transform`
   independently on the same element. */
.product-card.tilt-3d .product-image img,
.detail-image.tilt-3d img {
    transform: translateZ(26px) translate(var(--px), var(--py)) scale(1.08);
    transition: transform .5s var(--tilt-ease);
}

.product-card.tilt-3d.is-tilting .product-image img,
.detail-image.tilt-3d.is-tilting img {
    transition: transform .08s linear;
}

/* ---------------------------------------------------------
   SCROLL REVEAL
   Visible by default (safe if JS never loads). Only once
   fluid3d.js confirms it's running (".js-anim" on <html>,
   set synchronously in <head>) do reveal targets start hidden
   and wait for IntersectionObserver to bring them in.
   --------------------------------------------------------- */

.reveal {
    transition: opacity .9s var(--fluid-ease), transform .9s var(--fluid-ease);
}

html.js-anim .reveal {
    opacity: 0;
    transform: translateY(36px) rotateX(6deg);
    transform-origin: bottom center;
}

html.js-anim .reveal.is-visible {
    opacity: 1;
    transform: none;
}

.reveal-stagger.is-visible {
    transition-delay: calc(var(--reveal-index, 0) * 60ms);
}

/* ---------------------------------------------------------
   MAGNETIC BUTTONS
   JS drives translate via GSAP quickTo; this just keeps the
   element a positioned, will-change layer.
   --------------------------------------------------------- */

.magnetic {
    position: relative;
    will-change: transform;
}

/* ---------------------------------------------------------
   FLY-TO-CART GHOST
   --------------------------------------------------------- */

.fly-to-cart {
    position: fixed;
    z-index: 100000;
    border-radius: 12px;
    object-fit: cover;
    pointer-events: none;
    box-shadow: 0 12px 30px rgba(0, 0, 0, .35);
    will-change: transform, opacity;
}

#nav-cart-link.cart-landed {
    animation: cartLanded .5s var(--tilt-ease);
}

@keyframes cartLanded {
    0% { transform: scale(1); }
    35% { transform: scale(1.22) rotate(-4deg); }
    65% { transform: scale(.96) rotate(2deg); }
    100% { transform: scale(1); }
}

/* ---------------------------------------------------------
   AMBIENT DEPTH ON EXISTING SURFACES
   Small additions to app.css's card surfaces so the 3D tilt
   reads as physical depth rather than a flat sheet tipping over.
   --------------------------------------------------------- */

/* app.css gives .product-card:hover its own `transform: translateY(-5px)`.
   That rule is more specific than plain .tilt-3d, so without this override
   it would silently cancel --rx/--ry the moment a card is hovered — exactly
   when the tilt should be visible. This folds the same lift into the tilt
   transform instead of fighting it. */
.product-card.tilt-3d:hover,
.review.tilt-3d:hover,
.cart-item.tilt-3d:hover,
.order-card.tilt-3d:hover {
    transform: perspective(1000px) rotateX(var(--rx)) rotateY(var(--ry)) translateZ(calc(var(--tz) + 4px)) translateY(-5px);
    box-shadow: 0 26px 55px rgba(0, 0, 0, .16);
}

.summary.tilt-3d:hover,
.form-card.tilt-3d:hover,
.auth-card.tilt-3d:hover,
.panel.tilt-3d:hover,
.stats > a.tilt-3d:hover,
.stats > div.tilt-3d:hover {
    box-shadow: 0 30px 60px rgba(0, 0, 0, .12);
}

.hero-section {
    transform-style: preserve-3d;
}

.hero-content > * {
    transform: translateZ(0);
}

/* ---------------------------------------------------------
   REDUCED MOTION / NO-JS FALLBACK
   Anyone who asked their OS for less motion gets the site
   with zero animation, full readability, instantly.
   --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    #webgl-scene { display: none; }
    #page-transition { display: none; }

    .reveal {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }

    .tilt-3d {
        transform: none !important;
        transition: none !important;
    }

    .magnetic {
        transform: none !important;
    }
}
