/**
 * ZevsHost — fluid-motion.css
 * Additive motion layer (Apple-fluid standard). Load AFTER css/style.css.
 * Companion runtime: js/fluid.js. Materials live in fluid-material.css (not here).
 *
 * Nothing here redefines existing tokens; overrides win only by source order
 * (this file loads later) or a minimal specificity bump where an inline
 * <style> would otherwise win (cookie banner). No !important anywhere.
 */

/* ===== 1. MOTION TOKENS =====
   Reusable curves for future authors. Values mirror Apple's UIKit springs:
   - --spring-response: critically damped "settle" (sheet/drawer feel, no bounce)
   - --spring-bounce:   slight overshoot (pop-in of small surfaces)
   - quart pair:        fast-out decelerate / symmetric move                */
:root {
    --spring-response: cubic-bezier(0.32, 0.72, 0, 1);
    --spring-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
    --ease-in-out-quart: cubic-bezier(0.76, 0, 0.24, 1);
}

/* ===== 2. SCROLL POLISH =====
   scroll-behavior:smooth already set (style.css:81). scroll-padding makes
   BOTH native anchor jumps and scrollIntoView() clear the fixed header
   (style.css:179) — no JS offset math needed anywhere.                     */
html {
    scroll-padding-top: 96px;
}

/* ===== 3. TAP-DOWN FEEDBACK =====
   Apple principle: feedback on PRESS, not release — the interface must feel
   physically attached to the finger/cursor. 100ms down; release springs back
   through each element's own existing transition.
   (.plan-card-cta / a.plan-card have no styles in the codebase yet — kept
   here additively for future markup; they match nothing today.)            */
.btn:active,
button:active,
.nav-drop-item:active,
.feature-card[href]:active,
a.plan-card:active,
.plan-card-cta:active,
.promo-code-btn:active {
    transform: scale(0.97);
    transition: transform 100ms ease-out;
}

/* ===== 4. FOCUS-VISIBLE RINGS =====
   Soft brand glow instead of the browser default: 2px gap (bg-body layer)
   then a 3px --primary-glow halo. :is() keeps added specificity at one
   pseudo-class. The transparent outline stays for forced-colors mode,
   where box-shadow is stripped but outline is repainted.                   */
:is(a, button, input, select, textarea, [tabindex], summary):focus-visible {
    outline: 2px solid transparent;
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--bg-body), 0 0 0 5px var(--primary-glow), 0 0 0 6px var(--primary);
    border-radius: var(--radius-xs);
}
/* Pills / rounded controls keep their own radius on the ring */
.btn:focus-visible { border-radius: 50px; }
.nav-drop-item:focus-visible { border-radius: 10px; }

/* ===== 5. NAV DROPDOWN — SPRING POP-IN =====
   style.css:307/326 toggles display:none/block — untransitionable. We flip
   the hiding mechanism to visibility+opacity (same a11y result: hidden from
   tree, unfocusable, no hit-testing) so open AND close both animate.
   transform-origin anchors growth to the trigger (spatial consistency).
   OPEN: slight overshoot (--spring-bounce). CLOSE: quick ease-in reversal.  */
.nav-drop-panel {
    display: block; /* overrides style.css:308 by source order */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: scale(0.96) translateY(4px);
    transform-origin: top center;
    transition:
        opacity 140ms cubic-bezier(0.4, 0, 0.6, 1),
        transform 140ms cubic-bezier(0.4, 0, 0.6, 1),
        visibility 0s 140ms;
}
.nav-has-drop.open .nav-drop-panel {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
    transition:
        opacity 180ms var(--ease-out-quart),
        transform 320ms cubic-bezier(0.34, 1.56, 0.64, 1),
        visibility 0s;
}

/* ===== 6. COOKIE BANNER — CRITICALLY DAMPED SLIDE =====
   footer.php:125 sets `animation: slideUp .3s ease` from an inline <style>
   that loads after us; [id] bumps specificity to (1,1,0) so this wins.
   Same distance, spring decel — arrives fast, settles softly, no bounce.   */
@keyframes fluidSlideUp {
    from { transform: translateY(100%); }
    to { transform: translateY(0); }
}
#cookieBanner[id] {
    animation: fluidSlideUp 300ms cubic-bezier(0.32, 0.72, 0, 1) both;
}

/* ===== 7. CARD HOVER — EASING REFINEMENT ONLY =====
   Lift + glow already exist (style.css:678: translateY(-4px) + shadow-glow).
   We keep the property list (`transition: all`) intact and retune only
   duration/curve: a longer decelerating out-curve reads as weightless lift
   rather than a linear-ish slide. Applies to hover-in AND settle-back.     */
.feature-card,
.pricing-card {
    transition-duration: 0.45s;
    transition-timing-function: var(--ease-out-quart);
}

/* ===== 8. MOBILE DRAWER — SPRING EASING =====
   #mobDrawer (style.css:1475) animates transform:translateX with a standard
   material curve. We swap ONLY the transition (never the transform pattern —
   app.js toggles .is-open and header.php:104 pre-hides it). Critically
   damped + slightly longer = the iOS sheet feel. Overlay timing untouched:
   its visibility-delay choreography (style.css:1493) is already correct.   */
#mobDrawer {
    transition: transform 420ms var(--spring-response);
}

/* ===== 9. STAGGERED REVEAL =====
   Existing system: .reveal + .visible via IO in app.js:227 — untouched.
   a) `.reveal-fluid` on a PARENT staggers its .reveal children; authors (or
      fluid.js) supply --i per child. Cap/reset of --i is done by fluid.js
      (index % 8) so long lists don't cascade forever.
   b) `[data-reveal]` is the new opt-in for fluid.js ("is-revealed"). Hidden
      state is gated on html.fluid-ready — set by fluid.js at eval time — so
      if the script ever fails to load, content stays visible (fail-safe).  */
.reveal-fluid > .reveal {
    transition-delay: calc(var(--i, 0) * 60ms);
    animation-delay: calc(var(--i, 0) * 60ms);
}
html.fluid-ready [data-reveal] {
    opacity: 0;
    transform: translateY(24px);
    transition:
        opacity 0.6s var(--ease-out-quart) calc(var(--i, 0) * 60ms),
        transform 0.6s var(--ease-out-quart) calc(var(--i, 0) * 60ms);
}
html.fluid-ready [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
}

/* ===== 10. RIPPLE PLUMBING =====
   Containment for the pointer-down ripple spawned by fluid.js. currentColor
   makes it self-tinting: white on filled buttons, ink on light ones.       */
.btn-primary,
.plan-card-cta,
.promo-code-btn {
    position: relative;
    overflow: hidden;
}
.fluid-ripple {
    position: absolute;
    border-radius: 50%;
    background: currentColor;
    pointer-events: none;
    will-change: transform, opacity;
}

/* ===== 11. REDUCED MOTION =====
   Cross-fade only: every transform-driven move is removed, overshoot curves
   are gone with them, opacity changes stay short. Tap-down feedback is kept
   (it is information, not decoration) but becomes instant.                 */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
    .btn:active,
    button:active,
    .nav-drop-item:active,
    .feature-card[href]:active,
    a.plan-card:active,
    .plan-card-cta:active,
    .promo-code-btn:active {
        transition: none;
    }
    .nav-drop-panel {
        transform: none;
        transition: opacity 100ms linear, visibility 0s 100ms;
    }
    .nav-has-drop.open .nav-drop-panel {
        transform: none;
        transition: opacity 100ms linear, visibility 0s;
    }
    #cookieBanner[id] {
        animation: none;
    }
    .feature-card,
    .pricing-card,
    .feature-card:hover,
    .pricing-card:hover {
        transform: none;
        transition-duration: 0.15s;
        transition-timing-function: ease;
    }
    #mobDrawer {
        transition-duration: 0s;
    }
    .reveal-fluid > .reveal {
        transition-delay: 0s;
        animation-delay: 0s;
    }
    html.fluid-ready [data-reveal] {
        transform: none;
        transition: opacity 0.25s linear;
    }
    .fluid-ripple {
        display: none;
    }
}
