:root{
  --flame-core:#FFFFFF; --flame-hot:#E8D5FF; --flame-mid:#A855F7; --flame-deep:#6D5AE6;
  --flame-fade:#3B1E6E; --flame-smoke:#1A1030; --flame-ember:#C77DFF;
  --flame-scorch:#2A1240; --flame-spill:#FFD9F5;
}

/* ================= hero button effects =================
   Every layer is absolutely positioned — no button changes size. */

/* ---------- 1. Résumé: card fan pops on hover ---------- */
.fx-resume{position:relative;overflow:visible}
.rz-fan{position:absolute;left:50%;bottom:calc(100% + 12px);width:86px;height:108px;
  transform:translateX(-50%);pointer-events:none;opacity:0;z-index:6;transition:opacity .22s ease}
.rz-fan > span{position:absolute;inset:0;border-radius:9px;transform-origin:50% 100%;
  transform:translateY(16px) scale(.86) rotate(0deg);
  transition:transform .4s cubic-bezier(.22,1.4,.4,1)}
.rz-l{background:linear-gradient(155deg,#a855f7,#6366f1)}
.rz-r{background:linear-gradient(155deg,#22d3ee,#6366f1)}
.rz-doc{background:#f6f7fb;box-shadow:0 16px 34px rgba(0,0,0,.6);display:flex;flex-direction:column;gap:4px;padding:11px 10px}
.rz-doc b{display:block;height:7px;width:56%;border-radius:2px;background:#2b3049}
.rz-doc i{display:block;height:3px;border-radius:2px;background:#c7ccdb}
.rz-doc s{display:block;height:4px}
.fx-resume:hover .rz-fan,.fx-resume:focus-visible .rz-fan{opacity:1}
.fx-resume:hover .rz-l,.fx-resume:focus-visible .rz-l{transform:translate(-17px,-2px) scale(1) rotate(-13deg)}
.fx-resume:hover .rz-r,.fx-resume:focus-visible .rz-r{transform:translate(17px,-2px) scale(1) rotate(13deg)}
.fx-resume:hover .rz-doc,.fx-resume:focus-visible .rz-doc{transform:translateY(-6px) scale(1) rotate(-3deg)}

/* ---------- 2. GitHub: metaball symbiote ----------
   The transformed state is NOT the button's own box. The <a> paints nothing;
   every black pixel comes from .venom-goo, an inset:-40px layer of blobs fused
   by an SVG metaball threshold, so the silhouette bleeds outside the rect. */
.fx-defs{position:absolute;width:0;height:0;overflow:hidden}

.venom-host{position:relative;overflow:visible;display:inline-flex;isolation:isolate}
.fx-venom{position:relative;overflow:visible;
  transition:background .5s ease,border-color .5s ease,color .5s ease}

/* the only filtered layer — text must never live in here */
.venom-goo{position:absolute;inset:-26px;pointer-events:none;z-index:0;opacity:0;
  filter:url(#venom-goo);will-change:filter;transition:opacity .25s ease}
.vb{position:absolute;border-radius:50%;scale:0;
  transition:scale .55s cubic-bezier(.34,1.5,.5,1);
  /* opaque base, so the feColorMatrix alpha threshold preserves the RGB above it */
  background:
    radial-gradient(38% 20% at 31% 11%,rgba(255,255,255,.13),transparent 58%),
    radial-gradient(110% 80% at 50% 108%,rgba(139,92,246,.07),transparent 50%),
    radial-gradient(circle at 40% 32%,#08080d,#000 58%)}
/* the mass: sits exactly over the button rect inside the -40px layer */
.vb-core{inset:26px;width:auto;height:auto;margin:0;border-radius:16px;transition-delay:0ms;
  animation:f-core 6.7s ease-in-out infinite alternate}
@keyframes f-core{from{transform:scale(1) translate(0,0)}to{transform:scale(1.035) translate(2px,-1px)}}

.vb1{width:24px;height:24px;left:16%;top:44%;margin:-12.0px 0 0 -12.0px;animation:f-vb1 4.7s 0.0s ease-in-out infinite alternate;transition-delay:245ms}
@keyframes f-vb1{from{transform:translate(0,0) scale(.72)}to{transform:translate(14px,-9px) scale(1.22)}}
.vb2{width:18px;height:18px;left:32%;top:24%;margin:-9.0px 0 0 -9.0px;animation:f-vb2 3.1s 0.4s ease-in-out infinite alternate;transition-delay:105ms}
@keyframes f-vb2{from{transform:translate(0,0) scale(.72)}to{transform:translate(-8px,-12px) scale(1.18)}}
.vb3{width:14px;height:14px;left:52%;top:19%;margin:-7.0px 0 0 -7.0px;animation:f-vb3 2.3s 0.9s ease-in-out infinite alternate;transition-delay:35ms}
@keyframes f-vb3{from{transform:translate(0,0) scale(.72)}to{transform:translate(10px,7px) scale(1.25)}}
.vb4{width:21px;height:21px;left:70%;top:26%;margin:-10.5px 0 0 -10.5px;animation:f-vb4 6.1s 1.3s ease-in-out infinite alternate;transition-delay:140ms}
@keyframes f-vb4{from{transform:translate(0,0) scale(.72)}to{transform:translate(-11px,-8px) scale(1.15)}}
.vb5{width:25px;height:25px;left:84%;top:52%;margin:-12.5px 0 0 -12.5px;animation:f-vb5 5.3s 0.2s ease-in-out infinite alternate;transition-delay:280ms}
@keyframes f-vb5{from{transform:translate(0,0) scale(.72)}to{transform:translate(16px,6px) scale(1.2)}}
.vb6{width:20px;height:20px;left:74%;top:76%;margin:-10.0px 0 0 -10.0px;animation:f-vb6 7.3s 1.7s ease-in-out infinite alternate;transition-delay:210ms}
@keyframes f-vb6{from{transform:translate(0,0) scale(.72)}to{transform:translate(-9px,12px) scale(1.17)}}
.vb7{width:17px;height:17px;left:48%;top:81%;margin:-8.5px 0 0 -8.5px;animation:f-vb7 8.9s 0.6s ease-in-out infinite alternate;transition-delay:70ms}
@keyframes f-vb7{from{transform:translate(0,0) scale(.72)}to{transform:translate(7px,14px) scale(1.24)}}
.vb8{width:22px;height:22px;left:28%;top:74%;margin:-11.0px 0 0 -11.0px;animation:f-vb8 10.1s 2.1s ease-in-out infinite alternate;transition-delay:175ms}
@keyframes f-vb8{from{transform:translate(0,0) scale(.72)}to{transform:translate(-13px,10px) scale(1.13)}}
.vb9{width:15px;height:15px;left:13%;top:62%;margin:-7.5px 0 0 -7.5px;animation:f-vb9 11.3s 1.1s ease-in-out infinite alternate;transition-delay:315ms}
@keyframes f-vb9{from{transform:translate(0,0) scale(.72)}to{transform:translate(12px,-7px) scale(1.21)}}

/* drips: crawl below the bottom edge and thin out, so the threshold reads them
   as a tendril stretching and snapping back */
.vd1{width:15px;height:15px;left:38%;top:72%;margin:-7.5px 0 0 -7.5px;transition-delay:350ms;
  animation:f-vd1 9.7s .5s ease-in-out infinite}
.vd2{width:14px;height:14px;left:63%;top:74%;margin:-7.0px 0 0 -7.0px;transition-delay:385ms;
  animation:f-vd2 13.1s 2.3s ease-in-out infinite}
@keyframes f-vd1{0%,100%{transform:translateY(0) scale(1)}
  38%{transform:translateY(18px) scale(.62)}58%{transform:translateY(29px) scale(.34)}
  74%{transform:translateY(15px) scale(.7)}}
@keyframes f-vd2{0%,100%{transform:translateY(0) scale(1)}
  42%{transform:translateY(15px) scale(.6)}62%{transform:translateY(24px) scale(.3)}
  80%{transform:translateY(11px) scale(.75)}}

/* label rides above the filter, untouched by it */
.venom-label{position:relative;z-index:2;color:inherit}

/* transformed: the button itself stops painting. border-color, not border, so
   the 1px box is preserved and the row does not reflow. */
.fx-venom.vn-done{background:transparent;border-color:transparent;box-shadow:none;
  border-radius:0;color:#fff}
.fx-venom.vn-done .venom-label{text-shadow:0 1px 3px rgba(0,0,0,.9),0 0 14px rgba(168,85,247,.35)}
.fx-venom.vn-done .venom-goo{opacity:1}
.fx-venom.vn-done .vb{scale:1}
.venom-host:hover .fx-venom.vn-done .venom-goo{filter:url(#venom-goo) brightness(1.12)}

@media(prefers-reduced-motion:reduce){
  /* keep the irregular silhouette, stop it moving */
  .venom-goo{filter:url(#venom-goo-still)}
  .vb,.vb-core,.vd1,.vd2{animation:none}
  .vb{transition:none}
}

/* ---------- 3. View My Work: dragon + canvas fire ----------
   The dragon stays SVG. Fire is a canvas overlay (assets/dragon-fire.js) that
   aims at the button's top edge, so it is no longer welded to the dragon. */
.dragon-host{position:relative;display:inline-flex;overflow:visible}
.dfire{position:absolute;left:-26px;top:-86px;
  /* definite CSS size: a replaced element with width:auto would track its own
     bitmap width, so measure() would grow the canvas every frame */
  width:calc(100% + 52px);height:calc(100% + 92px);pointer-events:none;z-index:5}
.fx-dragon{position:relative;overflow:visible}

.dg-lane{position:absolute;left:0;right:0;bottom:calc(100% - 10px);height:46px;
  pointer-events:none;z-index:6;overflow:hidden}
/* fly + bob both on .dg so the mouth anchor tracks the body exactly */
.dg{position:absolute;left:0;top:0;width:104px;height:40px;
  animation:dgFly 7.2s linear infinite,dgBob 1.5s ease-in-out infinite alternate}
.dg-svg{width:104px;height:40px;overflow:visible}
/* emitter origin — invisible, read every frame */
.dragon-mouth{position:absolute;left:44px;top:9px;width:1px;height:1px}
/* the head turns toward whatever it is burning; JS writes --head-rot */
.dg-head{transform-box:fill-box;transform-origin:4% 88%;transform:rotate(var(--head-rot,0deg));
  transition:transform .28s ease-out}

.dg-wn{transform-box:fill-box;transform-origin:88% 96%;animation:dgFlapN .62s cubic-bezier(.7,0,.3,1) infinite alternate}
.dg-wf{transform-box:fill-box;transform-origin:88% 96%;animation:dgFlapF .62s cubic-bezier(.7,0,.3,1) infinite alternate;animation-delay:.07s}
@keyframes dgFlapN{from{transform:rotate(-34deg) scaleY(.62) skewX(6deg)}to{transform:rotate(16deg) scaleY(1.08) skewX(-4deg)}}
@keyframes dgFlapF{from{transform:rotate(-26deg) scaleY(.7)}to{transform:rotate(12deg) scaleY(1)}}
@keyframes dgFly{0%{left:-112px}100%{left:100%}}
@keyframes dgBob{from{transform:translateY(-2.5px) rotate(-3.5deg)}to{transform:translateY(2.5px) rotate(3.5deg)}}

@media(prefers-reduced-motion:reduce){
  /* dragon parks; the canvas paints a static violet edge glow instead */
  .dg{animation:none;left:38%}
  .dg-wn,.dg-wf{animation:none}
}
