/* ==========================================================================
   DELIGHT — styles for the micro-interaction layer (public/js/delight.js).
   docs/micro-interactions.md is the spec.

   Rules of this file:
   - One vocabulary: parchment, ink, quill, wax, ember, candlelight.
   - transform/opacity first; the few paint-only exceptions (a colour fade,
     an SVG ring draw) are brief and bounded.
   - Every overlay is pointer-events:none. Nothing here may steal a tap.
   - All colours come from tokens.css. Spacing from the scale where it IS
     spacing; decorative geometry (line weights, glow radii) may be raw px,
     like every other ornament in this codebase.
   - prefers-reduced-motion: base.css already kills every animation and
     transition globally; nothing more is needed here.
   ========================================================================== */

/* ---------- the effect layer's shared bones ---------- */
.dl-fx{
  position:absolute;
  inset:0;
  pointer-events:none !important;
  z-index:5;
}
.dl-ghost{
  position:fixed;
  left:var(--dl-x);
  top:var(--dl-y);
  width:var(--dl-w);
  height:var(--dl-h);
  margin:0;
  z-index:96;
  pointer-events:none !important;
}
.dl-ghost *{pointer-events:none !important}

/* parents that host overlays gain a positioning context (layout-neutral) */
.hp-figure,
.vrow--alarm,
.vrow--rest,
.orb--mod,
.row-lead{position:relative}

/* ==========================================================================
   VITALS DOCK
   ========================================================================== */

/* liquid HP bar — the render sets the final width; delight rewinds and lets
   this transition pour it (300ms, combat-speed budget) */
.hp-bar.dl-liquid .bar-fill,
.hp-bar.dl-liquid .bar-ward{transition:width .3s cubic-bezier(.3,.7,.3,1)}

/* damage: the numeral takes the hit */
@keyframes dl-hurt{
  0%{transform:translateX(0);color:var(--rubric)}
  25%{transform:translateX(-3px)}
  50%{transform:translateX(2px)}
  75%{transform:translateX(-1px)}
  100%{transform:translateX(0);color:var(--rubric)}
}
#hp-cur.dl-hurt{animation:dl-hurt .28s ease-out}

/* a red ink bloom that soaks into the parchment and dries */
@keyframes dl-bloom{
  0%{transform:scale(.35);opacity:0}
  30%{opacity:.4}
  100%{transform:scale(1.15);opacity:0}
}
.dl-bloom{
  background:radial-gradient(closest-side at 50% 55%, var(--rubric) 0%, color-mix(in srgb, var(--rubric-deep) 65%, transparent) 45%, transparent 78%);
  mix-blend-mode:multiply;
  animation:dl-bloom .45s ease-out forwards;
}
:root[data-theme="dark"] .dl-bloom{mix-blend-mode:screen;opacity:.5}

/* heal: a warm gold glow sweep */
@keyframes dl-glow{
  0%{transform:scale(.5);opacity:0}
  35%{opacity:.42}
  100%{transform:scale(1.12);opacity:0}
}
.dl-glow{
  background:radial-gradient(closest-side at 50% 55%, var(--gold-hi) 0%, color-mix(in srgb, var(--gold) 55%, transparent) 50%, transparent 80%);
  animation:dl-glow .45s ease-out forwards;
}
#hp-cur.dl-mend{animation:dl-mendtint .3s ease-out}
@keyframes dl-mendtint{0%,100%{color:var(--mend)}}

/* Temporary Hit Points shimmer when they absorb damage */
@keyframes dl-shimmer-sweep{
  from{transform:translateX(-130%) rotate(18deg);opacity:0}
  30%{opacity:.85}
  to{transform:translateX(130%) rotate(18deg);opacity:0}
}
.dl-shimmer{overflow:hidden;border-radius:var(--r-md)}
.dl-shimmer::before{
  content:"";
  position:absolute;inset:-20% -30%;
  background:linear-gradient(100deg, transparent 38%, color-mix(in srgb, var(--ward-hi) 85%, #fff 15%) 50%, transparent 62%);
  animation:dl-shimmer-sweep .38s ease-out forwards;
}

/* when Temp HP breaks: a hairline crack flashes across the capsule */
@keyframes dl-crack-draw{
  0%{transform:rotate(64deg) scaleY(0);opacity:0}
  25%{transform:rotate(64deg) scaleY(1);opacity:1}
  70%{opacity:.7}
  100%{transform:rotate(64deg) scaleY(1);opacity:0}
}
.dl-crack::before{
  content:"";
  position:absolute;
  left:50%;top:8%;
  width:1.5px;height:74%;
  background:linear-gradient(180deg, transparent 0%, var(--ward-hi) 12%, var(--ward-hi) 42%, transparent 46%, var(--ward-hi) 52%, var(--ward-hi) 88%, transparent 100%);
  transform-origin:top center;
  animation:dl-crack-draw .4s ease-out forwards;
}

/* death saves: each diamond fills with a quill-stroke */
@keyframes dl-quill-dia{
  from{transform:rotate(45deg) scale(0)}
  70%{transform:rotate(45deg) scale(1.12)}
  to{transform:rotate(45deg) scale(1)}
}
.pip--dia.dl-quill::before{animation:dl-quill-dia .24s cubic-bezier(.3,.7,.3,1.2)}

/* third success: one soft golden pulse — stabilized */
@keyframes dl-stable{
  0%{opacity:0}
  35%{opacity:.4}
  100%{opacity:0}
}
.dl-stable{
  background:radial-gradient(closest-side at 40% 50%, var(--gold-hi) 0%, transparent 85%);
  animation:dl-stable .6s ease-in-out forwards;
}

/* third failure: a slow, somber ink wash — dignified, not gamified */
@keyframes dl-inkwash{
  0%{opacity:0;transform:translateY(-8%)}
  40%{opacity:.5}
  100%{opacity:0;transform:translateY(0)}
}
.dl-inkwash{
  background:linear-gradient(180deg, color-mix(in srgb, var(--ink) 85%, var(--rubric-deep) 15%) 0%, color-mix(in srgb, var(--ink) 55%, transparent) 70%, transparent 100%);
  mix-blend-mode:multiply;
  animation:dl-inkwash .62s ease-in-out forwards;
}
:root[data-theme="dark"] .dl-inkwash{mix-blend-mode:normal;opacity:.65}

/* heroic inspiration: one twinkle when granted, an ember fade when spent */
@keyframes dl-twinkle{
  0%{transform:scale(1) rotate(0deg)}
  40%{transform:scale(1.28) rotate(-12deg);filter:brightness(1.5)}
  70%{transform:scale(.94) rotate(4deg)}
  100%{transform:scale(1) rotate(0deg);filter:none}
}
.insp.dl-twinkle{animation:dl-twinkle .35s cubic-bezier(.3,.7,.3,1.2)}
@keyframes dl-emberfade{
  0%{filter:brightness(1.3) sepia(.4)}
  100%{filter:none;transform:none}
}
.insp.dl-emberfade{animation:dl-emberfade .35s ease-out}

/* ==========================================================================
   RESTS
   ========================================================================== */

/* short rest: the dock warms by the fire while the hit dice are out */
.dock{position:relative}
.dock::after{
  content:"";
  position:absolute;inset:0;
  pointer-events:none;
  border-radius:inherit;
  background:radial-gradient(120% 90% at 12% 100%, color-mix(in srgb, var(--ember) 26%, transparent) 0%, transparent 55%);
  opacity:0;
  transition:opacity .3s ease;
}
.dock.dl-campfire::after{opacity:.5}

/* a small ember beside the fresh hit-dice row */
@keyframes dl-ember{
  0%{opacity:0;transform:scale(.4)}
  35%{opacity:.9;transform:scale(1.1)}
  100%{opacity:0;transform:scale(.9)}
}
.dl-ember{
  inset:auto auto 50% 2px;
  width:7px;height:7px;
  border-radius:50%;
  background:radial-gradient(circle at 40% 35%, var(--gold-hi), var(--ember) 70%);
  box-shadow:0 0 10px color-mix(in srgb, var(--ember) 80%, transparent);
  animation:dl-ember .6s ease-out forwards;
}

/* long rest: night passes over the sheet, then dawn */
@keyframes dl-night{
  0%{opacity:0}
  40%{opacity:.5}
  100%{opacity:0}
}
.dl-night{
  position:fixed;
  z-index:95;
  background:linear-gradient(180deg, #0a0e1c 0%, #141326 55%, #241a10 100%);
  animation:dl-night .6s ease-in-out forwards;
}

/* refill, staggered: slots → sorcery → AP → HP. "Poured light." */
@keyframes dl-pour-glow{
  0%{opacity:0;transform:scale(.4)}
  45%{opacity:.9;transform:scale(1)}
  100%{opacity:0;transform:scale(1.25)}
}
.pip.dl-pour::after,
.dl-pour.pip::after{
  content:"";
  position:absolute;inset:7px;
  border-radius:50%;
  pointer-events:none;
  background:radial-gradient(circle, color-mix(in srgb, var(--gold-hi) 90%, #fff 10%) 0%, color-mix(in srgb, var(--gold) 55%, transparent) 55%, transparent 75%);
  animation:dl-pour-glow .32s ease-out forwards;
}

/* a slot spent burns: brief ember flicker, then the empty ring it left */
@keyframes dl-burn-flicker{
  0%{opacity:0;transform:scale(.5)}
  20%{opacity:1;transform:scale(1.05)}
  40%{opacity:.35}
  60%{opacity:.85;transform:scale(.95)}
  100%{opacity:0;transform:scale(1.2)}
}
.pip.dl-burn::after{
  content:"";
  position:absolute;inset:7px;
  border-radius:50%;
  pointer-events:none;
  background:radial-gradient(circle, var(--gold-hi) 0%, var(--ember) 40%, color-mix(in srgb, var(--rubric) 60%, transparent) 62%, transparent 78%);
  animation:dl-burn-flicker .32s ease-out forwards;
}

/* the Empower mote — a bead of light on its way to the AP pip */
.dl-arcdot{
  z-index:97;
  background:radial-gradient(circle at 50% 50%, #fff 0%, var(--gold-hi) 30%, color-mix(in srgb, var(--gold) 60%, transparent) 55%, transparent 70%);
  border-radius:50%;
  opacity:0;
}

/* ==========================================================================
   DICE TRAY
   ========================================================================== */

/* nat 20: a single gold sheen sweep + faint sparkle. The die speaks. */
@keyframes dl-glint-sweep{
  from{transform:translateX(-140%) rotate(22deg);opacity:0}
  30%{opacity:.9}
  to{transform:translateX(140%) rotate(22deg);opacity:0}
}
.dl-glint{overflow:hidden;border-radius:var(--r-lg);z-index:6}
.dl-glint::before{
  content:"";
  position:absolute;inset:-25% -35%;
  background:linear-gradient(100deg, transparent 40%, color-mix(in srgb, var(--gold-hi) 80%, #fff 20%) 50%, transparent 60%);
  animation:dl-glint-sweep .6s ease-in-out forwards;
}
@keyframes dl-sparkle{
  0%{opacity:0;transform:scale(.3) rotate(0deg)}
  40%{opacity:1;transform:scale(1) rotate(18deg)}
  100%{opacity:0;transform:scale(.6) rotate(30deg)}
}
.dl-sparkle::after{
  content:"✦";
  position:absolute;
  top:-4px;right:-2px;
  font-size:var(--fs-small);
  color:var(--gold-hi);
  text-shadow:0 0 8px color-mix(in srgb, var(--gold-hi) 80%, transparent);
  animation:dl-sparkle .7s ease-out forwards;
}

/* nat 1: the die dulls; a tiny ink smudge beneath it */
@keyframes dl-dull{
  0%{filter:none}
  30%,80%{filter:brightness(.78) saturate(.72)}
  100%{filter:none}
}
.die.dl-dull{animation:dl-dull .9s ease-in-out}
@keyframes dl-smudge{
  0%{opacity:0;transform:scaleX(.5)}
  35%{opacity:.5}
  100%{opacity:0;transform:scaleX(1.1)}
}
.dl-smudge{
  inset:auto 12% -6% 12%;
  height:10px;
  border-radius:50%;
  background:radial-gradient(ellipse at center, rgba(10,8,4,.85) 0%, transparent 70%);
  animation:dl-smudge .9s ease-out forwards;
}

/* the roll log: wet ink, drying to matte over ~1s */
@keyframes dl-wetink{
  0%{opacity:.55;filter:brightness(1.7) saturate(1.25)}
  100%{opacity:1;filter:none}
}
.log-line.dl-wetink{animation:dl-wetink 1s ease-out}

/* ==========================================================================
   SPELLCRAFT
   ========================================================================== */

/* a spell or feature row unrolls like a scroll edge */
@keyframes dl-unroll{
  from{opacity:0;transform:translateY(-4px) scaleY(.985)}
  to{opacity:1;transform:none}
}
.dl-unroll{
  transform-origin:top center;
  animation:dl-unroll .24s ease-out;
}
/* the open row's shadow curl — 2–3px, as if the vellum lifts */
.spell-desc:not([hidden]),
.feat-desc:not([hidden]){box-shadow:inset 0 3px 3px -2px color-mix(in srgb, var(--ink) 22%, transparent)}

/* school-tinted hairline on the open spell (decorative, AA-exempt) */
.spell-desc:not([hidden]){border-left:2px solid transparent}
.spell-desc[data-school="Abjuration"]{border-left-color:color-mix(in srgb, var(--ward) 65%, transparent)}
.spell-desc[data-school="Conjuration"]{border-left-color:color-mix(in srgb, var(--gold) 65%, transparent)}
.spell-desc[data-school="Divination"]{border-left-color:color-mix(in srgb, var(--gold-hi) 75%, transparent)}
.spell-desc[data-school="Enchantment"]{border-left-color:color-mix(in srgb, var(--seal-wax-hi) 65%, transparent)}
.spell-desc[data-school="Evocation"]{border-left-color:color-mix(in srgb, var(--rubric) 65%, transparent)}
.spell-desc[data-school="Illusion"]{border-left-color:color-mix(in srgb, var(--ward-hi) 65%, transparent)}
.spell-desc[data-school="Necromancy"]{border-left-color:color-mix(in srgb, var(--rubric-deep) 70%, transparent)}
.spell-desc[data-school="Transmutation"]{border-left-color:color-mix(in srgb, var(--verdigris) 65%, transparent)}

/* ==========================================================================
   ABILITIES & SKILLS
   ========================================================================== */

/* proficient: a wax-stamp press — tiny scale-down and settle */
@keyframes dl-stamp{
  0%{transform:scale(1.3)}
  55%{transform:scale(.85)}
  100%{transform:scale(1)}
}
.ppip.dl-stamp{animation:dl-stamp .26s cubic-bezier(.3,.7,.3,1.2)}

/* expertise: the second ring draws itself around the first */
@keyframes dl-ring-draw{
  from{stroke-dashoffset:100}
  to{stroke-dashoffset:0}
}
@keyframes dl-ring-fade{
  0%,70%{opacity:1}
  100%{opacity:0}
}
.dl-ring{
  inset:auto;
  left:50%;top:50%;
  width:24px;height:24px;
  margin:-12px 0 0 -12px;
  animation:dl-ring-fade .42s ease-out forwards;
}
.dl-ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.dl-ring circle{
  fill:none;
  stroke:var(--gold-deep);
  stroke-width:1.6;
  stroke-dasharray:100;
  stroke-dashoffset:100;
  animation:dl-ring-draw .3s ease-out forwards;
}

/* an enchantment inks itself in with a small flourish */
@keyframes dl-inkin{
  0%{transform:scale(0) rotate(-45deg);opacity:0}
  70%{transform:scale(1) rotate(6deg);opacity:1}
  100%{transform:scale(1) rotate(0deg);opacity:1}
}
.ench-mark.dl-inkin{animation:dl-inkin .3s cubic-bezier(.3,.7,.3,1)}

/* …and the number it binds glows verdigris once */
@keyframes dl-verdigris{
  0%,60%{color:var(--verdigris)}
  100%{color:inherit}
}
.statval.dl-verdigris{animation:dl-verdigris .45s ease-out}

/* the last enchantment removed: the ✱ fades like erased pencil */
@keyframes dl-erase{
  0%{opacity:.8;filter:none;transform:scale(1)}
  100%{opacity:0;filter:blur(1.5px);transform:scale(.75)}
}
.dl-erase{
  color:var(--verdigris);
  font-size:var(--fs-body);
  line-height:1;
  animation:dl-erase .32s ease-out forwards;
}

/* the modifier orb's one sheen sweep, first time its card is seen */
@keyframes dl-sheen-sweep{
  from{transform:translateX(-130%) rotate(20deg);opacity:0}
  35%{opacity:.55}
  to{transform:translateX(130%) rotate(20deg);opacity:0}
}
.dl-sheen{overflow:hidden;border-radius:50%}
.dl-sheen::before{
  content:"";
  position:absolute;inset:-20% -30%;
  background:linear-gradient(105deg, transparent 40%, color-mix(in srgb, var(--gold-hi) 65%, #fff 12%) 50%, transparent 60%);
  animation:dl-sheen-sweep .65s ease-in-out forwards;
}

/* ==========================================================================
   EDITING
   ========================================================================== */

/* field commit: a quill underline draws across, and the ink dries */
@keyframes dl-inkdry{
  0%{color:color-mix(in srgb, var(--ink) 70%, var(--gold-deep) 30%)}
  100%{color:inherit}
}
.dl-commit{animation:dl-inkdry .45s ease-out}
@keyframes dl-underline{
  from{transform:scaleX(0)}
  to{transform:scaleX(1)}
}
@keyframes dl-underline-fade{
  0%,75%{opacity:1}
  100%{opacity:0}
}
.ink-field.dl-commit{position:relative}
.ink-field.dl-commit::after{
  content:"";
  position:absolute;
  left:0;right:0;bottom:-1px;
  height:1.5px;
  background:var(--gold-deep);
  transform-origin:left center;
  animation:dl-underline .28s ease-out, dl-underline-fade .46s ease-out forwards;
}

/* a new row arrives as a freshly penned line */
@keyframes dl-penned{
  from{opacity:0;transform:translateY(-3px)}
  to{opacity:1;transform:none}
}
.dl-penned{animation:dl-penned .3s ease-out}

/* a deleted row: ink strike-through on a ghost while the list closes */
@keyframes dl-strike-fade{
  0%,45%{opacity:.85}
  100%{opacity:0;transform:translateY(2px)}
}
.dl-strike{
  background:var(--panel);
  animation:dl-strike-fade .4s ease-in forwards;
  overflow:hidden;
}
.dl-strike::after{
  content:"";
  position:absolute;
  left:2%;right:2%;top:50%;
  height:1.5px;
  background:var(--ink);
  transform-origin:left center;
  animation:dl-underline .16s ease-out;
}

/* coin steppers: a micro coin-flip on the numeral */
@keyframes dl-coinflip{
  from{transform:rotateX(0)}
  to{transform:rotateX(360deg)}
}
output.dl-coinflip{display:inline-block;animation:dl-coinflip .24s ease-out}

/* a condition chip is wax-stamped on… */
@keyframes dl-stampon{
  0%{transform:scale(1.18);opacity:.5}
  60%{transform:scale(.95);opacity:1}
  100%{transform:scale(1);opacity:1}
}
.chip.dl-stampon{animation:dl-stampon .26s cubic-bezier(.3,.7,.3,1.2)}

/* …and its seal cracks off when lifted */
@keyframes dl-sealcrack{
  0%{opacity:.9;transform:rotate(0) translateY(0)}
  30%{transform:rotate(-2deg) translateY(1px)}
  100%{opacity:0;transform:rotate(5deg) translateY(10px)}
}
.dl-sealcrack{
  animation:dl-sealcrack .36s ease-in forwards;
}
.dl-sealcrack::after{
  content:"";
  position:absolute;
  left:46%;top:-10%;
  width:1.5px;height:120%;
  background:linear-gradient(180deg, transparent 0%, var(--rubric) 15%, var(--rubric) 45%, transparent 50%, var(--rubric) 58%, var(--rubric) 90%, transparent 100%);
  transform:rotate(14deg);
}

/* ==========================================================================
   NAVIGATION & CHROME
   ========================================================================== */

/* the ribbon's fleuron slides between sections instead of teleporting */
.ribbon ul{position:relative}
#ribbon.dl-has-fleuron a::before{opacity:0 !important}
.dl-fleuron{
  position:absolute;
  left:0;bottom:1px;
  font-family:var(--font-scribal);
  font-size:var(--fs-micro);
  line-height:1;
  color:var(--gold);
  pointer-events:none;
  transform:translateX(calc(var(--dl-fx-x, -100px) - 50%));
  transition:transform .25s cubic-bezier(.3,.7,.3,1);
}

/* section flourishes draw in on first scroll-into-view (once per visit) */
@keyframes dl-flourish{
  from{opacity:0;transform:scale(.4) rotate(-18deg)}
  to{opacity:1;transform:none}
}
.chapter .fleuron.dl-flourish{display:inline-block;animation:dl-flourish .3s ease-out}

/* theme toggle: one candle-flicker luminance wobble, not a hard swap */
@keyframes dl-candle{
  0%{opacity:0}
  25%{opacity:.16}
  45%{opacity:.05}
  65%{opacity:.12}
  100%{opacity:0}
}
.dl-candle{
  position:fixed;
  z-index:98;
  background:radial-gradient(80% 60% at 50% 30%, color-mix(in srgb, var(--gold-hi) 70%, #fff 10%) 0%, transparent 70%);
  animation:dl-candle .4s ease-in-out forwards;
}

/* login: the wax seal presses onto the page before the sheet loads —
   the one sanctioned ~500ms moment */
@keyframes dl-sealpress{
  0%{opacity:0;transform:translate(-50%,-50%) scale(1.7)}
  30%{opacity:1;transform:translate(-50%,-50%) scale(.96)}
  42%{transform:translate(-50%,-50%) scale(1.04)}
  52%,78%{opacity:1;transform:translate(-50%,-50%) scale(1)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1)}
}
.dl-sealpress{
  position:fixed;
  inset:auto; /* the shorthand resets all four — it must come FIRST */
  left:50%;top:44%;
  width:104px;height:104px;
  z-index:99;
  filter:drop-shadow(0 6px 14px rgba(30,10,2,.45));
  animation:dl-sealpress .55s ease-out forwards;
}
.dl-sealpress svg{width:100%;height:100%}
.dl-sealpress path{fill:var(--seal-wax)}
.dl-sealpress text{
  fill:var(--rubric-ink);
  font-family:var(--font-scribal);
  font-size:var(--fs-2xl);
}

/* ==========================================================================
   THE BELL — opt-in table sounds, seated in House Rules
   ========================================================================== */
.chime-row{
  display:grid;
  grid-template-columns:1fr auto;
  gap:var(--s1) var(--s4);
  align-items:center;
  padding:var(--s3) 0;
  margin-top:var(--s2);
  border-top:1px solid var(--rule-soft);
}
.chime-bell{
  grid-row:span 2;
  width:var(--field);height:var(--field);
  border:1px solid var(--rule);
  border-radius:50%;
  color:var(--ink-faint);
  display:grid;place-items:center;
  transition:color .18s ease, background-color .18s ease, border-color .18s ease;
}
.chime-bell svg{width:20px;height:20px}
.chime-bell:hover{border-color:var(--gold-deep);color:var(--gold-deep)}
.chime-bell[aria-pressed="true"]{
  background:linear-gradient(180deg,var(--gold-btn-a),var(--gold-btn-b));
  border-color:var(--gold-deep);
  color:var(--on-gold);
}
.chime-row .rule-desc em{font-style:italic;color:var(--gold-deep)}
