/* ══════════════════════════════════════════════════════════════════
   LIVING UI — extra motion layer (background, cursor, cards, buttons)
   ══════════════════════════════════════════════════════════════════ */

/* background aurora + grid drift (slow, GPU-friendly) */
@keyframes auroraDrift{
  0%{transform:translate3d(-2%,-1%,0) scale(1.06)}
  50%{transform:translate3d(2%,2%,0) scale(1.13)}
  100%{transform:translate3d(-1%,1%,0) scale(1.07)}
}
.bg-glow{animation:auroraDrift 24s ease-in-out infinite}
@keyframes gridPan{to{background-position:56px 56px}}
.bg-grid{animation:gridPan 36s linear infinite}

/* cursor spotlight (desktop only) */
.spot{
  position:fixed;inset:0;z-index:1;pointer-events:none;opacity:0;
  transition:opacity .6s ease;
  background:radial-gradient(460px circle at var(--mx,50%) var(--my,18%),rgba(37,99,235,.10),transparent 60%);
}
@media (hover:hover) and (pointer:fine){ .spot{opacity:1} }

/* brand logo breathing glow */
@keyframes logoGlow{0%,100%{box-shadow:0 0 12px rgba(37,99,235,.22)}50%{box-shadow:0 0 26px rgba(96,165,250,.55)}}
.brand img{animation:logoGlow 4.6s ease-in-out infinite}

/* availability dot ping */
.status-dot{position:relative}
.status-dot::after{
  content:"";position:absolute;inset:-3px;border-radius:50%;
  background:var(--success,#22c55e);animation:ping 1.9s cubic-bezier(0,0,.2,1) infinite;
}
@keyframes ping{0%{transform:scale(.6);opacity:.85}75%,100%{transform:scale(2.4);opacity:0}}

/* nav link sliding underline */
.nav-link{position:relative}
.nav-link::after{
  content:"";position:absolute;left:14px;right:14px;bottom:6px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,var(--accent),var(--accent-3));
  transform:scaleX(0);transform-origin:left;transition:transform .32s cubic-bezier(.16,1,.3,1);
}
.nav-link:hover::after,.nav-link.active::after{transform:scaleX(1)}

/* button shine sweep + lift */
.btn{position:relative;overflow:hidden;transition:transform .25s cubic-bezier(.16,1,.3,1),box-shadow .25s ease,background .25s ease}
.btn::after{
  content:"";position:absolute;top:0;left:0;width:42%;height:100%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.32),transparent);
  transform:translateX(-160%) skewX(-18deg);pointer-events:none;
}
.btn:hover::after{animation:shine .85s cubic-bezier(.16,1,.3,1)}
@keyframes shine{to{transform:translateX(320%) skewX(-18deg)}}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0) scale(.985)}

/* cards / skills / terms / prices — lift + border glow on hover */
.card,.skill,.term,.price,.game{transition:transform .35s cubic-bezier(.16,1,.3,1),border-color .35s ease,box-shadow .35s ease}
.card:hover,.skill:hover,.term:hover,.price:hover,.game:hover{
  transform:translateY(-6px);
  border-color:rgba(59,130,246,.45);
  box-shadow:0 18px 40px -18px rgba(37,99,235,.55),0 0 0 1px rgba(59,130,246,.18) inset;
}

/* code window: scanline + subtle glow pulse */
.window{position:relative}
.window::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(rgba(59,130,246,.05) 1px,transparent 1px);
  background-size:100% 4px;opacity:.35;
}
@keyframes scan{0%{transform:translateY(-40%)}100%{transform:translateY(340%)}}
.window-bar::after{
  content:"";position:absolute;left:0;right:0;height:38%;top:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(96,165,250,.10),transparent);
  animation:scan 5.5s linear infinite;
}

/* floating hero cards get a slow bob with different phases */
.float-card{will-change:transform}
.fc-clock{animation:floaty 6.2s ease-in-out infinite}
.fc-avail{animation:floaty 7.4s ease-in-out infinite reverse}

/* section headings: animated gradient sweep */
.page-head h2,.hero-title .grad{
  background-size:220% auto;
  animation:gradientShift 7s ease infinite;
}

/* skill index number glow pulse */
@keyframes idxGlow{0%,100%{text-shadow:0 0 0 rgba(59,130,246,0)}50%{text-shadow:0 0 18px rgba(59,130,246,.55)}}
.skill-idx{animation:idxGlow 5s ease-in-out infinite}


/* ═══════════ NEW MOTION LAYER (driven by js/core/fx.js) ═══════════ */
html{scroll-behavior:smooth}

/* entrance: staggered fade-up. `backwards` (not `both`) so the finished
   element is released and hover transforms work. */
.card,.price,.game,.term{animation:fadeInUp .6s cubic-bezier(.16,1,.3,1) backwards;animation-delay:calc(var(--i,0)*.05s)}

/* scroll reveal — only hidden when the motion engine is running */
.js-fx [data-rv]{opacity:0;transform:translate3d(0,26px,0);
  transition:opacity .8s cubic-bezier(.16,1,.3,1),transform .8s cubic-bezier(.16,1,.3,1);
  transition-delay:calc(var(--i,0)*.06s);will-change:opacity,transform}
.js-fx [data-rv].rv-in{opacity:1;transform:none}

/* scroll progress bar + compact nav */
.scroll-progress{position:fixed;top:0;left:0;height:3px;width:100%;z-index:800;pointer-events:none;
  background:linear-gradient(90deg,var(--accent),var(--accent-3));
  transform:scaleX(var(--sp,0));transform-origin:left;box-shadow:0 0 12px rgba(59,130,246,.6)}
.nav{transition:box-shadow .35s ease}
.nav .nav-inner{transition:height .35s cubic-bezier(.16,1,.3,1)}
.nav.scrolled{box-shadow:0 10px 30px -14px rgba(0,0,0,.7)}
@media (min-width:961px){.nav.scrolled .nav-inner{height:60px}}

/* 3D tilt + glare */
@media (hover:hover) and (pointer:fine){
  .card.is-tilt,.price.is-tilt,.game.is-tilt{
    transform:translateY(-6px) perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
    transition:transform .12s ease-out,border-color .35s ease,box-shadow .35s ease}
  .card.is-tilt::before,.price.is-tilt::before,.game.is-tilt::before{
    content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:2;
    background:radial-gradient(260px circle at var(--gx,50%) var(--gy,0%),rgba(255,255,255,.09),transparent 65%)}
}

/* click ripple + magnetic buttons */
.ripple{position:absolute;border-radius:50%;pointer-events:none;background:rgba(255,255,255,.35);
  transform:scale(0);animation:rippleOut .6s cubic-bezier(.16,1,.3,1) forwards}
@keyframes rippleOut{to{transform:scale(1);opacity:0}}
.mag{transition:transform .3s cubic-bezier(.16,1,.3,1),box-shadow .25s ease}

/* particle canvas, typing caret, cursor ring */
.live-canvas{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.9}
.caret{display:inline-block;width:.55em;height:1.05em;vertical-align:-.15em;margin-left:1px;
  background:var(--accent-3);box-shadow:0 0 10px rgba(96,165,250,.8);animation:caretBlink 1s steps(1) infinite}
@keyframes caretBlink{50%{opacity:0}}
.cursor-ring{position:fixed;left:0;top:0;width:36px;height:36px;border-radius:50%;z-index:900;pointer-events:none;
  border:1.5px solid rgba(96,165,250,.55);background:rgba(59,130,246,.06);opacity:0;mix-blend-mode:screen;will-change:transform;
  transition:opacity .3s ease,width .25s cubic-bezier(.16,1,.3,1),height .25s cubic-bezier(.16,1,.3,1),margin .25s cubic-bezier(.16,1,.3,1),background .25s ease,border-color .25s ease}
.cursor-ring.on{opacity:1}
.cursor-ring.hot{width:56px;height:56px;margin:-10px 0 0 -10px;background:rgba(59,130,246,.14);border-color:rgba(147,197,253,.9)}
.cursor-ring.press{width:26px;height:26px;margin:5px 0 0 5px}
@media (hover:none),(pointer:coarse){.cursor-ring{display:none}}
.hero-title .grad{filter:drop-shadow(0 0 22px rgba(59,130,246,.35))}

/* keyboard focus */
:focus-visible{outline:2px solid var(--accent-3);outline-offset:3px;border-radius:6px}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
  html{scroll-behavior:auto}
  .live-canvas,.cursor-ring,.scroll-progress{display:none}
}

/* safety net: never let the loading cover stick if scripts fail */
.loading{animation:loaderOut .5s ease 8s forwards}
@keyframes loaderOut{to{opacity:0;visibility:hidden;pointer-events:none}}
