/* Spell effects (spells.js): one look per keyword, layered over the board. Pieces are placed in screen pixels. */
#spells, #spellcv { position: fixed; inset: 0; pointer-events: none; z-index: 59; }
#spellcv { width: 100%; height: 100%; }
.sp { position: fixed; box-sizing: border-box; pointer-events: none; }
.sp-ghost > .mc, .sp-copy > .mc { width: 100%; height: 100%; }

/* Verify: a scanning beam and lock-on brackets */
.sp-scan { border: 1px solid rgba(114,220,255,.55); border-radius: 6px; overflow: hidden;
  background: repeating-linear-gradient(0deg, rgba(114,220,255,.08) 0 1px, transparent 1px 6px);
  box-shadow: inset 0 0 26px rgba(24,191,255,.28), 0 0 20px rgba(24,191,255,.35); }
.sp-scan i { position: absolute; left: 0; right: 0; top: 0; mix-blend-mode: screen;
  background: linear-gradient(180deg, transparent, rgba(95,228,255,.22) 30%, rgba(95,228,255,.6) 47%, #fff 50%, rgba(95,228,255,.6) 53%, rgba(95,228,255,.22) 70%, transparent),
    repeating-linear-gradient(90deg, rgba(255,255,255,.18) 0 1px, transparent 1px 12px); }
.sp-scan i::after { content: ""; position: absolute; left: -4%; right: -4%; top: 50%; height: 3px; transform: translateY(-50%); background: #fff; box-shadow: 0 0 18px 6px rgba(95,228,255,.9), 0 0 70px 18px rgba(24,191,255,.45); }
/* the lock-on reticle on the target */
.sp-reticle { border-radius: 50%; border: 2px solid rgba(95,228,255,.9); box-shadow: 0 0 24px rgba(95,228,255,.6), inset 0 0 24px rgba(95,228,255,.35); }
.sp-reticle i, .sp-reticle b { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
.sp-reticle i { width: 112%; height: 2px; background: linear-gradient(90deg, #5FE4FF 0 16%, transparent 16% 84%, #5FE4FF 84%); }
.sp-reticle b { width: 2px; height: 112%; background: linear-gradient(180deg, #5FE4FF 0 16%, transparent 16% 84%, #5FE4FF 84%); }
.sp-lock i { position: absolute; width: 24%; height: 18%; border: 0 solid #9FF0FF; filter: drop-shadow(0 0 5px #18BFFF); }
.sp-lock i:nth-child(1) { left: -4%; top: -4%; border-width: 3px 0 0 3px; }
.sp-lock i:nth-child(2) { right: -4%; top: -4%; border-width: 3px 3px 0 0; }
.sp-lock i:nth-child(3) { left: -4%; bottom: -4%; border-width: 0 0 3px 3px; }
.sp-lock i:nth-child(4) { right: -4%; bottom: -4%; border-width: 0 3px 3px 0; }

/* Leak: a crack with red light seeping out */
.sp-crack svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sp-crack path { fill: none; stroke: #FF4A3A; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; filter: drop-shadow(0 0 5px #FF2A1A) drop-shadow(0 0 14px #FF4A3A); }
.sp-crack path.core { stroke: #FFE6D8; stroke-width: 1.4; filter: none; }
.sp-crack .glow { position: absolute; inset: -12%; background: radial-gradient(50% 40% at 50% 50%, rgba(255,60,40,.45), rgba(255,40,20,.12) 60%, transparent 75%); mix-blend-mode: screen; }

/* Mail: an envelope of light */
.sp-env { perspective: 420px; }
.sp-env .body { position: absolute; inset: 0; z-index: 2; border-radius: 4px;
  background: linear-gradient(to top right, transparent 49%, rgba(20,110,150,.55) 50%, transparent 52%) left bottom / 50% 70% no-repeat,
    linear-gradient(to top left, transparent 49%, rgba(20,110,150,.55) 50%, transparent 52%) right bottom / 50% 70% no-repeat,
    linear-gradient(160deg, rgba(225,250,255,.97), rgba(114,220,255,.85));
  box-shadow: 0 0 18px 4px rgba(114,220,255,.75), 0 0 50px 8px rgba(24,191,255,.35); }
.sp-env .flap { position: absolute; left: 0; right: 0; top: 0; height: 58%; z-index: 3; transform-origin: 50% 0; clip-path: polygon(0 0, 100% 0, 50% 100%);
  background: linear-gradient(180deg, #F2FDFF, #9FE6FF); }
.sp-env .ltr { position: absolute; left: 13%; right: 13%; top: 8%; height: 76%; z-index: 1; border-radius: 2px;
  background: repeating-linear-gradient(180deg, transparent 0 18%, rgba(24,140,190,.35) 18% 22%) 20% 30% / 60% 60% no-repeat, #fff; box-shadow: 0 0 22px 6px rgba(255,255,255,.75); }

/* Sealed: a wax seal of light that cracks in two */
.sp-seal .h { position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle at 50% 46%, #E2FCFF 0 7%, #72DCFF 8% 16%, #18BFFF 17% 34%, #0B5F88 35% 55%, #18BFFF 56% 60%, #0A4A6C 61% 70%, rgba(24,191,255,.0) 72%);
  filter: drop-shadow(0 0 14px rgba(24,191,255,.9)) drop-shadow(0 0 4px #fff); }
.sp-seal .l { clip-path: inset(-10% 50% -10% -10%); }
.sp-seal .r { clip-path: inset(-10% -10% -10% 50%); }
.sp-seal svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.sp-seal path { fill: none; stroke: #fff; stroke-width: 3; stroke-dasharray: 1; stroke-linejoin: round; filter: drop-shadow(0 0 4px #72DCFF) drop-shadow(0 0 10px #18BFFF); }

/* Attested: a gold halo and a stamp */
.sp-halo { border-radius: 50%; background: repeating-conic-gradient(rgba(246,227,174,.95) 0 1.5deg, transparent 1.5deg 12deg);
  -webkit-mask: radial-gradient(closest-side, transparent 80%, #000 82% 90%, transparent 92%); mask: radial-gradient(closest-side, transparent 80%, #000 82% 90%, transparent 92%); }
.sp-halo::after { content: ""; position: absolute; inset: 6%; border-radius: 50%; border: 2px solid rgba(246,227,174,.9); }
.sp-stamp { display: grid; place-items: center; font: 700 16px/1 var(--hud, sans-serif); letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
  border: 3px solid currentColor; border-radius: 6px; background: rgba(3,7,11,.78); }
.sp-stamp.gold { color: #F6E3AE; border-color: #E0BE72; text-shadow: 0 0 12px #E0BE72; box-shadow: 0 0 26px -4px #E0BE72, inset 0 0 12px -4px #E0BE72; }
.sp-stamp.red { color: #FF6B5A; text-shadow: 0 0 12px #FF4A3A; box-shadow: 0 0 26px -4px #FF4A3A, inset 0 0 12px -4px #FF4A3A; }

/* Refund and Tax: the Budget row lights up where the pips land or leave */
.sp-gain, .sp-pull { border-radius: 8px; }
.sp-gain { background: rgba(114,220,255,.12); box-shadow: 0 0 0 2px rgba(114,220,255,.75), 0 0 26px 4px rgba(24,191,255,.5); }
.sp-pull { background: rgba(255,122,89,.12); box-shadow: 0 0 0 2px rgba(255,122,89,.75), 0 0 26px 4px rgba(255,90,60,.45); }

/* Cap: a shield ring locks around the Zone */
.sp-cap .ring { position: absolute; inset: 0; border-radius: 22px; border: 6px double rgba(160,235,205,.95);
  box-shadow: 0 0 0 6px rgba(143,208,184,.14), 0 0 32px 4px rgba(95,211,168,.5), inset 0 0 34px rgba(95,211,168,.3);
  background: linear-gradient(90deg, rgba(143,208,184,.9) 0 0) top left / 22% 4px no-repeat, linear-gradient(90deg, rgba(143,208,184,.9) 0 0) bottom right / 22% 4px no-repeat; }
.sp-cap .lock { position: absolute; left: 50%; top: 50%; width: 48px; height: 40px; border-radius: 8px; background: linear-gradient(180deg, #E4FFF4, #5FD3A8 60%, #2E8F6E);
  box-shadow: 0 0 22px 6px rgba(95,211,168,.85), inset 0 -3px 0 rgba(0,0,0,.25); }
.sp-cap .lock::after { content: ""; position: absolute; left: 50%; top: 42%; width: 16%; height: 30%; transform: translateX(-50%); border-radius: 40% 40% 20% 20%; background: #12382b; }
.sp-cap .lock i { position: absolute; left: 20%; top: -52%; width: 60%; height: 62%; box-sizing: border-box; border: 5px solid #C8F7E4; border-bottom: 0; border-radius: 99px 99px 0 0; }
.sp-ripple { border-radius: 50%; border: 3px solid rgba(143,208,184,.8); box-shadow: 0 0 20px rgba(95,211,168,.6), inset 0 0 20px rgba(95,211,168,.4); }

/* Loop: copies spiral in */
.sp-copy { mix-blend-mode: screen; filter: drop-shadow(0 0 10px #FF7AD9) saturate(1.3); }

/* Fake: a glitch, then the real Power */
.mc.sp-glitch { animation: spGlitch .8s steps(1) both !important; }
@keyframes spGlitch {
  0% { clip-path: inset(0); filter: none; transform: none; }
  10% { clip-path: inset(10% 0 55% 0); transform: translateX(-6px); filter: hue-rotate(90deg) saturate(3); }
  20% { clip-path: inset(60% 0 8% 0); transform: translateX(5px); filter: hue-rotate(-60deg) brightness(1.6); }
  30% { clip-path: inset(0); transform: translateX(-2px); filter: drop-shadow(-3px 0 #18BFFF) drop-shadow(3px 0 #FF2A6A); }
  45% { clip-path: inset(30% 0 35% 0); transform: translateX(7px) skewX(-8deg); filter: invert(.8); }
  55% { clip-path: inset(0); transform: none; filter: drop-shadow(-4px 0 #18BFFF) drop-shadow(4px 0 #FF2A6A); }
  70% { clip-path: inset(5% 0 70% 0); transform: translateX(-4px); filter: brightness(2); }
  80%, 100% { clip-path: inset(0); transform: none; filter: none; } }
.sp-slices i { position: absolute; left: -5%; right: -5%; height: 6%; mix-blend-mode: screen; animation: spSlice .16s steps(2) infinite; }
.sp-slices i:nth-child(1) { top: 18%; background: linear-gradient(90deg, transparent, rgba(24,191,255,.9), transparent); }
.sp-slices i:nth-child(2) { top: 47%; height: 4%; background: linear-gradient(90deg, transparent, rgba(255,42,106,.9), transparent); animation-delay: -.05s; }
.sp-slices i:nth-child(3) { top: 72%; background: linear-gradient(90deg, transparent, rgba(255,255,255,.7), transparent); animation-delay: -.1s; }
@keyframes spSlice { 50% { transform: translateX(8%); } }
.sp-real { display: flex; justify-content: center; align-items: center; overflow: visible; font: 700 16px/1 var(--mono, monospace); text-transform: uppercase; letter-spacing: .08em; }
.sp-real span { padding: .35em .6em; border-radius: 4px; background: rgba(3,7,11,.88); border: 1px solid #FF7A59; color: #FFB7A3; white-space: nowrap;
  text-shadow: -2px 0 rgba(24,191,255,.8), 2px 0 rgba(255,42,106,.8); box-shadow: 0 0 18px -2px #FF7A59; }
.sp-real b { font-size: 1.5em; color: #fff; }

/* Receipts: slips of light */
.sp-slip { border-radius: 3px; border: 1px solid rgba(200,245,255,.95);
  background: linear-gradient(90deg, rgba(40,110,140,.55) 0 0) 16% 22% / 60% 5% no-repeat, linear-gradient(90deg, rgba(40,110,140,.45) 0 0) 16% 36% / 44% 5% no-repeat,
    linear-gradient(90deg, rgba(40,110,140,.45) 0 0) 16% 50% / 52% 5% no-repeat, linear-gradient(90deg, rgba(40,110,140,.35) 0 0) 16% 64% / 36% 5% no-repeat,
    linear-gradient(180deg, #FFFFFF, #E2F8FF 70%, #BFEFFF);
  box-shadow: 0 0 14px 3px rgba(159,230,255,.75), 0 0 36px 6px rgba(24,191,255,.3); }
/* the tick printed on each slip */
.sp-slip::after { content: ""; position: absolute; right: 14%; bottom: 12%; width: 22%; height: 12%; border: solid #18BFFF; border-width: 0 0 3px 3px; transform: rotate(-45deg); }

/* Ward: a shield bubble that pops */
.sp-ward { border-radius: 50% 50% 46% 46% / 62% 62% 38% 38%; border: 2px solid rgba(214,190,255,.95); transform-origin: 50% 100%;
  background: radial-gradient(60% 40% at 36% 24%, rgba(255,255,255,.45), transparent 60%),
    radial-gradient(closest-side, rgba(180,140,255,.08) 55%, rgba(180,140,255,.32) 85%, rgba(200,170,255,.55) 100%),
    repeating-conic-gradient(from 0deg at 50% 100%, rgba(214,190,255,.10) 0 4deg, transparent 4deg 14deg);
  box-shadow: 0 0 34px 6px rgba(180,140,255,.55), inset 0 0 36px rgba(180,140,255,.45); }
.sp-ward svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sp-ward path { fill: none; stroke: #fff; stroke-width: 1.6; stroke-dasharray: 1; vector-effect: non-scaling-stroke; filter: drop-shadow(0 0 4px #B48CFF); }

/* reduced motion or a skipped sequence: one soft flash */
.sp-flash { border-radius: 8px; background: color-mix(in srgb, var(--sc) 30%, transparent); box-shadow: 0 0 24px 6px color-mix(in srgb, var(--sc) 60%, transparent); }

/* Wipe: the art dissolves from the top down (a registered property so the mask edge can animate) */
@property --cut { syntax: "<percentage>"; inherits: false; initial-value: 0%; }
.sp-dissolve { -webkit-mask-image: linear-gradient(180deg, transparent calc(var(--cut) - 8%), #000 calc(var(--cut) + 8%)); mask-image: linear-gradient(180deg, transparent calc(var(--cut) - 8%), #000 calc(var(--cut) + 8%)); }
/* Refund: a burst of light where the pips leave the card */
.sp-pipsrc { border-radius: 50%; background: radial-gradient(closest-side, rgba(255,255,255,.7), rgba(114,220,255,.45) 40%, transparent 72%); mix-blend-mode: screen; }
/* Tax: the enemy's Budget pips, and the tether that drags them over */
.sp-ebudget { display: flex; align-items: center; justify-content: center; gap: 10px; border-radius: 10px; background: rgba(20,8,6,.8); border: 1px solid rgba(255,122,89,.6); box-shadow: 0 0 22px -4px #FF7A59; }
.sp-ebudget i { width: 24px; height: 24px; clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); background: linear-gradient(180deg, #FFD2C4, #FF7A59); }
.sp-tether { transform-origin: 0 50%; border-radius: 3px; background: repeating-linear-gradient(90deg, #FFB39F 0 10px, #FF5A3C 10px 20px); box-shadow: 0 0 16px 5px rgba(255,90,60,.8), 0 0 44px 10px rgba(255,90,60,.35); animation: spTeth .3s linear infinite; }
@keyframes spTeth { to { background-position: 20px 0; } }

/* Siege: a Shield breaking (a flaring hexagon with cracks) and a Base hit (a red shockwave) */
.sp-shield { clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
  background: radial-gradient(circle at 50% 45%, #fff 0 18%, color-mix(in srgb, var(--sc) 85%, #fff) 40%, color-mix(in srgb, var(--sc) 40%, transparent) 75%); }
.sp-shield svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sp-shield path { fill: none; stroke: #05070A; stroke-width: 3; stroke-dasharray: 1; vector-effect: non-scaling-stroke; }
.sp-base { border-radius: 50%; background: radial-gradient(circle, rgba(255,240,230,.95) 0 8%, rgba(255,90,60,.75) 22%, rgba(255,90,60,.25) 45%, transparent 68%); mix-blend-mode: screen; }
