/* ============================================================
   WINE GLASS — "bring it alive" layer (about / home)
   Built to port cleanly to Astro + React + Three.js.
   1) skills marquee   2) stat count-up   3) card spotlight
   4) real-glass GL backdrop (Three.js island)   5) heading ink-fill
   ============================================================ */

/* ---------- 1. SKILLS MARQUEE ---------- */
.skills-marquee{
  margin-top:1.8rem;
  display:flex;flex-direction:column;gap:1rem;
  -webkit-mask:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
}
.sk-row{overflow:hidden;}
.sk-track{
  display:flex;gap:0.7rem;width:max-content;
  animation:sk-scroll var(--sk-dur,70s) linear infinite;
}
.sk-row.is-reverse .sk-track{animation-direction:reverse;--sk-dur:84s;}
.sk-row:hover .sk-track{animation-play-state:paused;}
.sk-track .sk{flex:none;}
@keyframes sk-scroll{from{transform:translateX(0);}to{transform:translateX(-50%);}}
@media(prefers-reduced-motion:reduce){
  .sk-track{animation:none;flex-wrap:wrap;width:auto;}
  .skills-marquee{-webkit-mask:none;mask:none;flex-wrap:wrap;}
}

/* ---------- 2. STAT COUNT-UP ---------- */
.stat-n[data-count]{
  background:var(--grad-head-soft);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  font-variant-numeric:tabular-nums;
}

/* ---------- 3. CURSOR SPOTLIGHT ON GLASS CARDS ---------- */
.glass-card.is-interactive{isolation:isolate;}
.glass-card.is-interactive::after{
  content:"";position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;z-index:0;opacity:0;
  transition:opacity var(--dur-mid) var(--ease-out-expo);
  background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),
    rgba(240,192,204,0.20) 0%,
    rgba(196,116,139,0.10) 34%,
    transparent 62%);
}
.glass-card.is-interactive:hover::after{opacity:1;}
.glass-card.is-interactive > *{position:relative;z-index:1;}
@media(prefers-reduced-motion:reduce){.glass-card.is-interactive::after{transition:none;}}

/* ---------- 4. ASCII GRADIENT BACKDROP + FLOATING BUTTERFLY ---------- */
/* ascii-bg.js paints a dark gradient-bloom + ASCII matrix into #gl-root;
   a single iridescent butterfly (cropped from the photo) floats over it via
   a screen blend. The hero is never touched — its own bg + video stay. */
#gl-root{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;background:#0e0509;}
.ascii-canvas{position:absolute;inset:0;display:block;z-index:0;}
.aurora-canvas{position:absolute;inset:0;display:block;z-index:1;mix-blend-mode:screen;pointer-events:none;}

/* rose-curve loader (math-curve loaders → wine/rose) */
.loader-stage{flex-direction:column;gap:1.4rem;}
.loader-rose{width:150px;height:150px;color:#f7d2dc;filter:drop-shadow(0 0 10px rgba(240,192,204,0.5));}

/* ---------- FLAPPING BUTTERFLY (wings split from the pink ref) ---------- */
.bf-fly{
  position:absolute; top:0; left:0; z-index:1; width:190px;
  will-change:transform;            /* anime.js drives translate / rotate / scale */
}
.bf-glow{
  position:absolute; left:50%; top:45%; width:255%; aspect-ratio:1;
  transform:translate(-50%,-50%);
  background:radial-gradient(closest-side,
    rgba(255,214,246,0.30) 0%,
    rgba(236,150,255,0.22) 20%,
    rgba(188,106,248,0.14) 42%,
    rgba(128,72,224,0.07) 62%,
    transparent 78%);
  filter:blur(var(--bl10)); mix-blend-mode:screen; pointer-events:none;
  animation:bf-glow-pulse 2.6s ease-in-out infinite;
}
.bf-glow::after{
  content:""; position:absolute; inset:32%; border-radius:50%;
  background:radial-gradient(closest-side, rgba(255,240,252,0.4), rgba(255,200,245,0.15) 55%, transparent 72%);
  filter:blur(7px);
}
.bf-bug{
  position:relative; width:100%; aspect-ratio:722 / 590;
  perspective:640px; transform-style:preserve-3d;
  animation:bf-bob 0.95s ease-in-out infinite;
}
.wing{
  position:absolute; top:0; height:100%; width:50%;
  mix-blend-mode:screen; backface-visibility:hidden;
  filter:saturate(1.08) brightness(1.12)
         drop-shadow(0 0 6px rgba(255,156,228,0.32))
         drop-shadow(0 0 16px rgba(214,96,236,0.22));
}
.wl{ left:0;  transform-origin:100% 50%; animation:bf-flap-l 0.95s ease-in-out infinite; }
.wr{ right:0; transform-origin:0% 50%;  animation:bf-flap-r 0.95s ease-in-out infinite; }
/* open glide → fold up → open → brief hold (a real wingbeat rhythm) */
@keyframes bf-flap-l{
  0%  {transform:rotateY(10deg);}
  44% {transform:rotateY(80deg);}
  80% {transform:rotateY(10deg);}
  100%{transform:rotateY(10deg);}
}
@keyframes bf-flap-r{
  0%  {transform:rotateY(-10deg);}
  44% {transform:rotateY(-80deg);}
  80% {transform:rotateY(-10deg);}
  100%{transform:rotateY(-10deg);}
}
/* body lifts on the downbeat, settles on the glide */
@keyframes bf-bob{
  0%,100%{transform:translateY(3%);}
  44%    {transform:translateY(-4%);}
  80%    {transform:translateY(3%);}
}
@keyframes bf-glow-pulse{
  0%,100%{opacity:0.42; transform:translate(-50%,-50%) scale(0.96);}
  50%    {opacity:0.6;  transform:translate(-50%,-50%) scale(1.06);}
}
@media(max-width:760px){.bf-fly{width:132px;}}
@media(prefers-reduced-motion:reduce){
  .wl,.wr,.bf-bug,.bf-glow{animation:none;}
  .wl{transform:rotateY(24deg);} .wr{transform:rotateY(-24deg);}
}

/* ---------- GIRLY NAME REVEAL — sparkle constellation (namefx.js) ---------- */
.hero-name{position:relative;}
.spk-field{position:absolute;inset:0;pointer-events:none;z-index:4;overflow:visible;}
.spk{
  position:absolute;width:var(--s,20px);aspect-ratio:1;opacity:0;
  transform:translate(-50%,-50%) scale(0) rotate(-30deg);
  background:radial-gradient(closest-side,#fff 8%,#ffdcef 42%,#f7a8d0 78%);
  clip-path:polygon(50% 0,59% 41%,100% 50%,59% 59%,50% 100%,41% 59%,0 50%,41% 41%);
  filter:drop-shadow(0 0 7px rgba(255,190,225,0.9));
  animation:spk 1.7s var(--ease-out-back,ease) both;
}
@keyframes spk{
  0%  {opacity:0;   transform:translate(-50%,-50%) scale(0)    rotate(-30deg);}
  22% {opacity:1;   transform:translate(-50%,-50%) scale(1)    rotate(0deg);}
  55% {opacity:0.85;transform:translate(-50%,-50%) scale(0.72) rotate(14deg);}
  100%{opacity:0;   transform:translate(-50%,-50%) scale(0.45) rotate(26deg);}
}
.spk-loop{animation:spk-tw 3s ease-in-out infinite;}
@keyframes spk-tw{
  0%,100%{opacity:0.2;transform:translate(-50%,-50%) scale(0.5) rotate(0deg);}
  50%    {opacity:1;  transform:translate(-50%,-50%) scale(1)   rotate(12deg);}
}
@media(prefers-reduced-motion:reduce){.spk,.spk-loop{animation:none;opacity:0;}}

/* layering: ascii canvas (#gl-root z0) < hero < butterfly sky < lower content.
   the butterfly floats OVER the hero (screen-blended, flush) but tucks BEHIND
   the lower sections, so it never covers body text. */
.hero{position:relative;z-index:1;}
#bf-sky{position:fixed;inset:0;z-index:2;pointer-events:none;}
.stats,.section,.site-footer{position:relative;z-index:3;}
.stats{z-index:5;}

/* the jelly blobs are retired in favour of the gradient backdrop */
.jelly,.jelly-field{display:none!important;}

/* open the lower sections so the bloom + butterfly breathe behind them;
   indigo scrims keep text readable. (hero stays fully opaque) */
/* lower-section scrims — all full-bleed + equal opacity so the dimmed
   backdrop spans the viewport (no width-constrained rectangles) */
body.bg-on .skills,
body.bg-on .otc,
body.bg-on .dstats-band {background:rgba(16,5,11,0.56);}
body.bg-on .contact{background:radial-gradient(120% 90% at 50% 120%,rgba(58,24,40,0.42) 0%,rgba(16,5,11,0.56) 62%);}
body.bg-on .site-footer{background:radial-gradient(150% 130% at 50% 0%,rgba(46,18,31,0.45) 0%,rgba(16,5,11,0.56) 38%,rgba(13,3,8,0.88) 100%);border-top:0;}

/* about & exp are width-limited by .wrap, so their scrim is painted by a
   100vw ::before (else it only covers the centred column → side rectangles) */
body.bg-on .about,
body.bg-on .exp{position:relative;overflow:visible;background:transparent;}
body.bg-on .about::before,
body.bg-on .exp::before{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;transform:translateX(-50%);
  background:rgba(16,5,11,0.56);z-index:0;pointer-events:none;
}
body.bg-on .about > *,
body.bg-on .exp > *{position:relative;z-index:1;}

/* ---------- 5. EDITORIAL HEADING INK-FILL ---------- */
/* the italic accent words "fill" with the sacred gradient as they reveal */
.sec-h em,.contact-h em{
  background-size:100% 220%;
  background-position:50% 100%;
  transition:background-position 1.15s var(--ease-out-expo) 0.12s;
}
[data-reveal].in .sec-h em,
[data-reveal].in .contact-h em{background-position:50% 0%;}
@media(prefers-reduced-motion:reduce){
  .sec-h em,.contact-h em{transition:none;background-position:50% 0%;}
}

/* ---------- 5b. HEADING GLIMMER — a shiny sweep over the accent words ---------- */
.sec-h em,.contact-h em{position:relative;}
.sec-h em::after,.contact-h em::after{
  content:attr(data-text);
  position:absolute;left:0;top:0;
  background:linear-gradient(105deg,transparent 38%,rgba(255,250,246,0.92) 50%,transparent 62%);
  background-size:260% 100%;background-repeat:no-repeat;
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;
  pointer-events:none;
  animation:em-glimmer 4.6s ease-in-out infinite;
}
@keyframes em-glimmer{0%{background-position:230% 0;}55%,100%{background-position:-70% 0;}}
@media(prefers-reduced-motion:reduce){.sec-h em::after,.contact-h em::after{animation:none;content:none;}}

/* ---------- 6. MAGNETIC CTA ---------- */
/* JS sets --mxx/--myy; the existing .btn transform transition eases the pull */
.btn.is-magnetic{will-change:transform;}

/* ---------- 7. LIQUID-GLASS SURFACES ---------- */
/* refraction is applied by liquid-glass.js (backdrop feDisplacementMap);
   these rules add the specular rim + tint that make it read as glass.
   Spent deliberately on the player + the 4 About id-cards only. */
.player.lq{background:rgba(26,7,16,0.32);border-color:rgba(240,192,204,0.45);}
.player.lq::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 1px 1px rgba(255,245,240,0.62),
             inset 0 -10px 18px rgba(42,15,28,0.40),
             inset 0 0 0 1px rgba(255,255,255,0.07);
}
.id-card.lq{background:rgba(255,255,255,0.035);}
.id-card.lq::before{
  background:linear-gradient(160deg,
    rgba(255,245,240,0.78) 0%,
    rgba(240,192,204,0.22) 20%,
    rgba(255,255,255,0) 46%,
    rgba(255,255,255,0) 60%,
    rgba(196,116,139,0.30) 82%,
    rgba(255,245,240,0.62) 100%);
}
