/* ==========================================================================
   NUPLUS CORP — Interactive depth (nuplus-depth.css)
   --------------------------------------------------------------------------
   3D lives on the things people actually touch — buttons, cards, tiers —
   rather than in the background. Ambient decoration competes with content;
   depth on a control *communicates* something: this is raised, this is
   pressable, this responded to you.

   The physical model, applied consistently:
     * Every raised surface has a light edge on top and a shadow below, as if
       lit from above. That single cue is what reads as "real".
     * Hover LIFTS (shadow grows and softens, surface brightens).
     * Press DEPRESSES (shadow tightens, surface moves down 1px). Without a
       press state a button feels like a picture of a button.
     * Light tracks the pointer across the surface.
     * Timings are short on press (~90ms, must feel instant) and longer on
       release (~450ms, settles gracefully).

   Customer-facing only — admin pages get calm, flat, fast controls.
   Everything degrades to the existing flat styling if unsupported.
   ========================================================================== */

/* ---- Tokens ----------------------------------------------------------- */

:root {
    --np-d-green: var(--accent-green, #22c55e);
    --np-d-purple: var(--accent-purple, #a855f7);

    /* Layered shadows read as real depth; a single shadow reads as a sticker.
       Close+tight for contact, wide+soft for ambient occlusion. */
    --np-shadow-rest:
        0 1px 2px rgba(0, 0, 0, 0.30),
        0 4px 12px rgba(0, 0, 0, 0.28);
    --np-shadow-lift:
        0 2px 6px rgba(0, 0, 0, 0.32),
        0 14px 34px rgba(0, 0, 0, 0.42);
    --np-shadow-press:
        0 1px 2px rgba(0, 0, 0, 0.40);

    /* Top highlight / bottom shade — the "lit from above" cue. */
    --np-edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.16);
    --np-edge-dark: inset 0 -1px 0 rgba(0, 0, 0, 0.35);

    --np-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --np-ease-press: cubic-bezier(0.4, 0, 0.2, 1);
}

.light-mode {
    --np-shadow-rest:
        0 1px 2px rgba(16, 24, 20, 0.08),
        0 4px 12px rgba(16, 24, 20, 0.08);
    --np-shadow-lift:
        0 2px 6px rgba(16, 24, 20, 0.10),
        0 14px 34px rgba(16, 24, 20, 0.16);
    --np-shadow-press:
        0 1px 2px rgba(16, 24, 20, 0.14);
    --np-edge-light: inset 0 1px 0 rgba(255, 255, 255, 0.9);
    --np-edge-dark: inset 0 -1px 0 rgba(16, 24, 20, 0.08);
}

/* ==========================================================================
   BUTTONS — .np-btn3d
   Opt-in class so it never hijacks controls that shouldn't move.
   ========================================================================== */

.np-btn3d {
    position: relative;
    isolation: isolate;          /* keep ::before/::after off other layers */
    border-radius: 12px;
    box-shadow:
        var(--np-edge-light),
        var(--np-edge-dark),
        var(--np-shadow-rest);
    transform: translate3d(0, 0, 0);
    transition:
        transform 0.42s var(--np-ease-out),
        box-shadow 0.42s var(--np-ease-out),
        filter 0.42s var(--np-ease-out);
    will-change: transform;
}

/* Pointer-tracking sheen. Sits above the background, below the label. */
.np-btn3d::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 1;
    opacity: 0;
    transition: opacity 0.42s var(--np-ease-out);
    background: radial-gradient(
        220px circle at var(--np-mx, 50%) var(--np-my, 50%),
        rgba(255, 255, 255, 0.20),
        transparent 45%
    );
}

.np-btn3d > * { position: relative; z-index: 2; }

@media (hover: hover) {
    .np-btn3d:hover {
        transform: translate3d(0, -3px, 0);
        box-shadow:
            var(--np-edge-light),
            var(--np-edge-dark),
            var(--np-shadow-lift);
        filter: brightness(1.06);
    }
    .np-btn3d:hover::after { opacity: 1; }
}

/* Press: fast, and it must actually go *down*. */
.np-btn3d:active {
    transform: translate3d(0, 1px, 0) scale(0.988);
    box-shadow:
        var(--np-edge-dark),
        var(--np-shadow-press);
    filter: brightness(0.97);
    transition-duration: 0.09s;
    transition-timing-function: var(--np-ease-press);
}

.np-btn3d:focus-visible {
    outline: 2px solid var(--np-d-green);
    outline-offset: 3px;
}

/* Disabled controls must not pretend to be pressable. */
.np-btn3d:disabled,
.np-btn3d[aria-disabled="true"] {
    transform: none;
    filter: none;
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: var(--np-shadow-press);
}
.np-btn3d:disabled::after { opacity: 0; }

/* ==========================================================================
   CARDS — .np-card3d
   Tilt is driven by JS custom properties so hover and pointer share one
   transform and can never fight each other.
   ========================================================================== */

.np-card3d {
    position: relative;
    transform-style: preserve-3d;
    box-shadow: var(--np-shadow-rest);
    transform:
        perspective(var(--np-persp, 1000px))
        rotateX(var(--np-rx, 0deg))
        rotateY(var(--np-ry, 0deg))
        translate3d(0, var(--np-lift, 0px), 0);
    transition:
        transform 0.5s var(--np-ease-out),
        box-shadow 0.5s var(--np-ease-out),
        border-color 0.5s var(--np-ease-out);
    will-change: transform;
}

/* While the pointer is inside, follow it immediately rather than easing —
   easing here feels like lag, not smoothness. */
.np-card3d.np-tracking {
    transition:
        transform 0.08s linear,
        box-shadow 0.5s var(--np-ease-out),
        border-color 0.5s var(--np-ease-out);
}

@media (hover: hover) {
    .np-card3d:hover {
        box-shadow: var(--np-shadow-lift);
        border-color: var(--np-d-green);
    }
}

/* Light sweeping across the surface. */
.np-card3d::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.45s var(--np-ease-out);
    background: radial-gradient(
        480px circle at var(--np-mx, 50%) var(--np-my, 50%),
        rgba(255, 255, 255, 0.075),
        transparent 46%
    );
}

.np-card3d:hover::after { opacity: 1; }

.light-mode .np-card3d::after {
    background: radial-gradient(
        480px circle at var(--np-mx, 50%) var(--np-my, 50%),
        rgba(34, 197, 94, 0.10),
        transparent 46%
    );
}

/* Content can be pushed forward in Z so it separates from the surface as the
   card tilts — the detail that sells the effect as real depth. */
.np-card3d .np-layer-1 { transform: translateZ(18px); }
.np-card3d .np-layer-2 { transform: translateZ(34px); }

/* ==========================================================================
   ACCESSIBILITY / DEVICE GUARDS
   ========================================================================== */

/* Touch: no hover, and transforms fight scrolling. Keep depth, drop motion. */
@media (pointer: coarse) {
    .np-card3d,
    .np-card3d.np-tracking {
        transform: none !important;
        transition: box-shadow 0.3s ease, border-color 0.3s ease;
    }
    .np-card3d::after { display: none; }
    .np-btn3d:active {
        transform: translate3d(0, 1px, 0) scale(0.99);
    }
}

@media (prefers-reduced-motion: reduce) {
    .np-btn3d,
    .np-card3d,
    .np-card3d.np-tracking {
        transform: none !important;
        transition: box-shadow 0.2s ease, border-color 0.2s ease;
    }
    .np-btn3d::after,
    .np-card3d::after { display: none; }
    /* Keep a non-motion press cue so the control still confirms the tap. */
    .np-btn3d:active { box-shadow: var(--np-shadow-press); filter: brightness(0.95); }
}

/* ==========================================================================
   BUTTON VARIANTS
   Replaces the blurred gradient halos that previously sat behind the CTAs.
   A solid, evenly-lit surface with a real press state reads as a physical
   control; a blurred glow reads as decoration around a flat rectangle.
   ========================================================================== */

.np-btn3d {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    border: 1px solid transparent;
    cursor: pointer;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

/* ---- Primary: solid brand green, one clear action per view ------------ */

.np-btn3d-primary {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--np-d-green) 92%, white) 0%,
        var(--np-d-green) 52%,
        color-mix(in srgb, var(--np-d-green) 88%, black) 100%);
    border-color: color-mix(in srgb, var(--np-d-green) 70%, black);
    color: #04220f;
}

/* color-mix is widely supported but not universal — this fallback keeps the
   button solid and legible in older engines. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .np-btn3d-primary {
        background: var(--np-d-green);
        border-color: var(--np-d-green);
    }
}

.np-btn3d-primary:hover { color: #04220f; }

/* ---- Ghost: quiet secondary, defers to the primary -------------------- */

.np-btn3d-ghost {
    background: var(--bg-secondary, #0a0a0a);
    border-color: var(--border-color, rgba(34, 197, 94, 0.28));
    color: var(--text-primary, #e5e7eb);
}

@media (hover: hover) {
    .np-btn3d-ghost:hover {
        border-color: var(--np-d-green);
        color: var(--text-primary, #e5e7eb);
    }
}

.light-mode .np-btn3d-ghost {
    background: #ffffff;
    border-color: rgba(16, 24, 20, 0.14);
    color: var(--text-primary, #111827);
}

/* The ghost surface is dark/neutral, so a white sheen suits it; the primary
   is already bright, so its sheen is softened to avoid blowing out. */
.np-btn3d-primary::after {
    background: radial-gradient(
        220px circle at var(--np-mx, 50%) var(--np-my, 50%),
        rgba(255, 255, 255, 0.30),
        transparent 45%
    );
}

/* ==========================================================================
   CONFLICT RESOLUTION
   --------------------------------------------------------------------------
   Existing page CSS sets its own hover transform, e.g.
     .holo-card:hover { transform: translateY(-5px); }
   and Tailwind's `hover:scale-105`. Those would replace the composed
   transform below and the card would snap flat the moment it is hovered.
   For cards that opted into 3D, the depth transform must win — the lift is
   already handled by --np-lift inside it.
   ========================================================================== */

.holo-card.np-card3d.np-card3d:hover,
.price-card.np-card3d.np-card3d:hover,
.np-card3d.np-card3d[class*="hover:scale-"]:hover {
    transform:
        perspective(var(--np-persp, 1000px))
        rotateX(var(--np-rx, 0deg))
        rotateY(var(--np-ry, 0deg))
        translate3d(0, var(--np-lift, 0px), 0);
}

/* The old flat glow is replaced by the layered depth shadow; keep a hint of
   brand colour on the border so the card still reads as "active". */
.holo-card.np-card3d:hover {
    box-shadow: var(--np-shadow-lift);
}

/* Cards are clickable here, so give them a press state too.
   Selectors are doubled (.np-card3d.np-card3d) to out-specify the reveal
   rule in nuplus-motion.css, which also targets transform on these elements. */
.np-card3d.np-card3d[onclick]:active,
.np-card3d.np-card3d.cursor-pointer:active {
    transform:
        perspective(var(--np-persp, 1000px))
        rotateX(var(--np-rx, 0deg))
        rotateY(var(--np-ry, 0deg))
        translate3d(0, 0, 0) scale(0.994);
    box-shadow: var(--np-shadow-press);
    transition-duration: 0.09s;
}

/* Touch devices keep the existing flat lift — no tilt to preserve. */
@media (pointer: coarse) {
    .holo-card.np-card3d:hover,
    .price-card.np-card3d:hover {
        transform: translateY(-4px) !important;
    }
}
