/* ============================================================
   RANSOR — motion & micro-interaction layer ("console coming online")
   Refined / restrained. Everything here is opt-in via classes or
   data-attributes, and fully disabled under prefers-reduced-motion.
   Transforms + opacity only (GPU-composited); no layout thrash.
   ============================================================ */

/* ---- No-JS fail-open ----
   Everything below that starts an element hidden is scoped to `.js`, the class
   header.php sets in <head>. If scripts never run, nothing is ever hidden and the
   page renders as plain server HTML — no products vanish, no checkout form goes
   missing. The reveal classes (.st-in / .in) are unscoped, so once JS is present
   they still win on equal specificity by document order. */

/* ---- Staggered reveal groups ----
   A [data-stagger] container's direct children rise in sequence once the
   group scrolls into view. JS sets --sd (per-child delay) + toggles .st-in. */
.js [data-stagger] > *{opacity:0;transform:translateY(26px);transition:opacity .6s cubic-bezier(.22,.8,.24,1) var(--sd,0ms),transform .6s cubic-bezier(.22,.8,.24,1) var(--sd,0ms);will-change:opacity,transform}
[data-stagger].st-in > *{opacity:1;transform:none}

/* Heading mask-wipe: text rises from behind a clip edge (used on .disp in hero
   + section heads that carry .wipe). Pairs with the .reveal .in trigger. */
.js .wipe{clip-path:inset(-10% -10% 105% -10%);opacity:.001;transition:clip-path .9s cubic-bezier(.16,.84,.28,1),opacity .5s ease}
.in .wipe,.wipe.in{clip-path:inset(-10% -10% -10% -10%);opacity:1}

/* ---- Hero "boot-up" sequence (pure CSS, runs on load — no flash, no JS dep) ----
   The active slide's copy settles in like a console initializing. animation-
   fill-mode:both means the 0% (hidden) state IS the initial paint, so there is
   never a visible-then-hidden flash. Replays gently when a slide activates. */
.hero-slide.is-active .hero-copy > *{animation:bootIn .7s cubic-bezier(.2,.8,.24,1) both}
.hero-slide.is-active .hero-copy > :nth-child(1){animation-delay:.15s}
.hero-slide.is-active .hero-copy > :nth-child(2){animation-delay:.30s}
.hero-slide.is-active .hero-copy > :nth-child(3){animation-delay:.46s}
.hero-slide.is-active .hero-copy > :nth-child(4){animation-delay:.62s}
@keyframes bootIn{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
/* kicker scan-line underline draws in after the copy settles */
.hero-slide .kicker{position:relative}
.hero-slide.is-active .kicker::after{content:"";position:absolute;left:0;bottom:-6px;height:1px;width:0;background:linear-gradient(90deg,var(--gold),transparent);animation:scanline .8s ease .7s forwards}
[dir="rtl"] .hero-slide.is-active .kicker::after{left:auto;right:0;background:linear-gradient(270deg,var(--gold),transparent)}
@keyframes scanline{to{width:74px}}

/* ---- Gold button: specular shimmer sweep on hover ---- */
.btn-gold{position:relative;overflow:hidden;isolation:isolate}
.btn-gold::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(110deg,transparent 32%,rgba(255,255,255,.42) 50%,transparent 68%);transform:translateX(-130%)}
.btn-gold:hover::after,.btn-gold:focus-visible::after{animation:btnShine .85s cubic-bezier(.3,.6,.3,1)}
@keyframes btnShine{from{transform:translateX(-130%)}to{transform:translateX(130%)}}
/* Ghost button: gold edge brightens + faint glow on hover */
.btn-ghost{transition:background .25s,color .2s,box-shadow .3s,transform .18s}
.btn-ghost:hover{box-shadow:0 0 0 1px var(--hairline-gold),0 8px 30px -14px rgba(var(--gold-rgb),.5)}

/* ---- Card micro-interactions: lift already exists; add glow + HUD corner brackets ---- */
.pcard,.cat,.al-card{will-change:transform}
.pcard:hover{box-shadow:0 22px 46px -26px rgba(0,0,0,.9),0 0 0 1px var(--hairline-gold),0 0 34px -18px rgba(var(--gold-rgb),.55)}
.cat.has-img:hover,.al-card:hover{box-shadow:0 24px 50px -28px rgba(0,0,0,.9),0 0 30px -16px rgba(var(--gold-rgb),.5)}
/* HUD corner brackets on product cards — draw in on hover */
.pcard{position:relative}
.pcard::before,.pcard::after{content:"";position:absolute;width:14px;height:14px;border:1.5px solid var(--gold);opacity:0;transition:opacity .3s ease,transform .3s ease;pointer-events:none;z-index:3}
.pcard::before{top:9px;left:9px;border-right:0;border-bottom:0;transform:translate(4px,4px)}
.pcard::after{bottom:9px;right:9px;border-left:0;border-top:0;transform:translate(-4px,-4px)}
.pcard:hover::before,.pcard:hover::after{opacity:.9;transform:none}

/* In-stock signal dot: gentle life */
.pcard .stock::before,.sr-stock::before{animation:pulseDot 2.6s ease-in-out infinite}
@keyframes pulseDot{0%,100%{box-shadow:0 0 0 0 rgba(101,188,123,.5)}50%{box-shadow:0 0 0 4px rgba(101,188,123,0)}}

/* Add-to-cart loading/added feedback (WC toggles .loading / .added) */
.woocommerce .button.loading{opacity:.75}
.add_to_cart_button.added::after{content:"✓";margin-inline-start:.4em}

/* Section-head kicker line: subtle continuous shimmer to feel "live" */
.sec-head .kicker::before{background:linear-gradient(90deg,transparent,var(--gold),transparent);background-size:200% 100%;animation:kickerFlow 6s linear infinite}
[dir="rtl"] .sec-head .kicker::before{animation-direction:reverse}
@keyframes kickerFlow{to{background-position:200% 0}}

/* Ambient nebula: very slow breathing so the void isn't dead-static */
.ambient{animation:nebulaDrift 34s ease-in-out infinite alternate}
@keyframes nebulaDrift{from{transform:translate3d(0,0,0) scale(1)}to{transform:translate3d(-1.5%,1%,0) scale(1.05)}}

/* ============================================================
   FLIGHT DECK PASS (2026-11-10) — the page behaves like a console in flight.
   Same rules as above: ambient, never blocking, transforms + opacity + clip
   only, nothing a visitor has to wait for, all of it off under reduced motion.
   Gold is not spent here: the new light is starlight (cool white), so the CTA,
   the active state and the price keep the gold to themselves.
   ============================================================ */

/* ---- Page-to-page: the old view fades, the new one rises in — no white flash,
   the header holds still. Browsers without cross-document view transitions
   simply navigate as before. ---- */
@media (prefers-reduced-motion: no-preference){
  @view-transition{navigation:auto}
  .site-header{view-transition-name:rs-header}
  ::view-transition-old(root){animation:vtOut .16s ease both}
  ::view-transition-new(root){animation:vtIn .34s cubic-bezier(.2,.8,.24,1) both}
}
@keyframes vtOut{to{opacity:0}}
@keyframes vtIn{from{opacity:0;transform:translateY(12px)}}

/* ---- HUD labels type on, in reading direction (a clip, so the text itself is
   never rewritten — screen readers and Arabic shaping are untouched). ---- */
.reveal.in .kicker,.cat-hero .kicker,.woo-head .kicker{animation:hudType .75s steps(20,end) .12s both}
[dir="rtl"] .reveal.in .kicker,[dir="rtl"] .cat-hero .kicker,[dir="rtl"] .woo-head .kicker{animation-name:hudTypeRtl}
@keyframes hudType{from{clip-path:inset(-40% 100% -40% -4%)}to{clip-path:inset(-40% -4% -40% -4%)}}
@keyframes hudTypeRtl{from{clip-path:inset(-40% -4% -40% 100%)}to{clip-path:inset(-40% -4% -40% -4%)}}
/* Catalog headers settle in under their label */
.cat-hero-copy > h1,.woo-head > h1{animation:bootIn .55s cubic-bezier(.2,.8,.24,1) .06s both}
.cat-hero-copy > .woo-head-desc,.woo-head > .woo-head-desc{animation:bootIn .55s cubic-bezier(.2,.8,.24,1) .16s both}

/* ---- Scroll telemetry: a hairline under the header fills as the page is read ---- */
@supports (animation-timeline:scroll()){
  .site-header::after{content:"";position:absolute;inset-inline:0;bottom:-1px;height:1px;pointer-events:none;background:linear-gradient(90deg,transparent,rgba(var(--gold-rgb),.85));transform:scaleX(0);transform-origin:0 50%;animation:hdrProg linear both;animation-timeline:scroll(root block)}
  [dir="rtl"] .site-header::after{transform-origin:100% 50%;background:linear-gradient(270deg,transparent,rgba(var(--gold-rgb),.85))}
}
@keyframes hdrProg{to{transform:scaleX(1)}}

/* ---- Product card: a scan passes over the photo and a soft light follows the
   pointer. Hover-capable pointers only; a phone gets the press state below. ---- */
@media (hover:hover) and (pointer:fine){
  .pcard .ph{position:relative}
  .pcard .ph::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;transition:opacity .35s ease;background:radial-gradient(230px circle at var(--mx,50%) var(--my,40%),rgba(170,200,240,.24),transparent 70%);mix-blend-mode:screen}
  .pcard:hover .ph::before{opacity:1}
  .pcard .ph::after{content:"";position:absolute;inset-inline:0;top:0;height:36%;z-index:1;pointer-events:none;opacity:0;background:linear-gradient(180deg,transparent,rgba(170,200,240,.05) 70%,rgba(214,230,250,.36) 97%,transparent);transform:translateY(-105%)}
  .pcard:hover .ph::after{animation:hudScan 1.2s cubic-bezier(.45,.15,.45,1) 1}
}
@keyframes hudScan{0%{transform:translateY(-105%);opacity:1}85%{opacity:1}100%{transform:translateY(285%);opacity:0}}

/* ---- Press feedback (the hover a touch screen never gets) ---- */
.btn:active{transform:translateY(1px) scale(.985)}
.pcard:active{transform:translateY(-1px) scale(.992)}

/* ---- The hero's primary action catches the light every few seconds, so it
   reads as live on a phone too. Hover keeps the quicker sweep. ---- */
.hero-slide.is-active .hero-cta .btn-gold::after{animation:btnIdle 7s cubic-bezier(.3,.6,.3,1) 2.4s infinite}
.hero-slide.is-active .hero-cta .btn-gold:hover::after,.hero-slide.is-active .hero-cta .btn-gold:focus-visible::after{animation:btnShine .85s cubic-bezier(.3,.6,.3,1)}
@keyframes btnIdle{0%{transform:translateX(-130%)}13%,100%{transform:translateX(130%)}}

/* ---- Footer status lamp beside "All systems nominal." ---- */
.fbar .sys{display:inline-flex;align-items:center;gap:.75em;margin-inline-start:.9em}
.fbar .sys::before{content:"";flex:0 0 auto;width:6px;height:6px;border-radius:50%;background:var(--in-stock);animation:pulseDot 2.6s ease-in-out infinite}

/* ---- Reduced motion: everything static, instant, fully usable ---- */
@media (prefers-reduced-motion: reduce){
  [data-stagger] > *{opacity:1!important;transform:none!important;transition:none!important}
  .wipe{clip-path:none!important;opacity:1!important}
  .hero-slide.is-active .hero-copy > *{opacity:1!important;transform:none!important;animation:none!important}
  .btn-gold::after,.hero-slide.is-active .kicker::after,.pcard::before,.pcard::after{display:none!important}
  .ambient,.sec-head .kicker::before,.pcard .stock::before,.sr-stock::before{animation:none!important}
  .site-header::after,.pcard .ph::before,.pcard .ph::after{display:none!important}
  .fbar .sys::before{animation:none!important}
  .kicker,.cat-hero-copy > *,.woo-head > *{animation:none!important;clip-path:none!important;opacity:1!important;transform:none!important}
}
