/* ══ THE OPEN CARD'S BORDER GLOW (192 §3) ═════════════════════════════════
   Xinlu asked for a glow on the open card's four edges, from a component whose
   own behaviour 192 §2.1 measured: a near-white hotspot with a blue-violet TAIL
   trailing off it, fading to an unlit border further round. ⚠️ His three
   colours appear only in the FALLOFF, not in the bright part — the hotspot's
   brightest pixels mean #FAF9FA.

   ⚠️ TWO NESTED ELEMENTS, AND BOTH LEVELS ARE FORCED.
     - It is a SIBLING of the cards, not a child and not a wrapper: the halo
       reaches 40px outside and .card has overflow: hidden, while 173 §1.4
       forbids ANY element between .intro__deck and .card. 192 §3.3 states the
       constraint; index.html states it at the markup.
     - It is TWO elements because a mask clips to the BORDER BOX, so a mask on
       the element carrying the shadow erases the shadow entirely. Measured
       both ways: masked directly, a 40px halo read (0,0,0) on BOTH sides of
       the box; with the mask on a wrapper and the shadow on an inner ring, the
       lit side read (72,72,72) and the cut side (0,0,0) — an arc.

   ⚠️ box-sizing: content-box IS LOAD-BEARING. The shared width/height rule
   above gives this element the CARD's box; the padding then expands its border
   box by the glow radius on every side, which is the area the arc mask has to
   cover and the room the halo needs. Written as padding rather than as a second
   width calculation so the card's box is expressed once. */
.deck-glow {
  position: absolute;
  top: 0;
  left: 0;
  box-sizing: content-box;
  padding: var(--card-edge-r, 40px);
  z-index: 899;               /* under .card.is-open's 900, over everything else */
  pointer-events: none;
  opacity: 0;
  transition: opacity 160ms linear;
}

/* ⚠️ NOTHING OPEN, NOTHING PAINTED — and C32's control is exactly this. Without
   it the halo would sit at the front card's slot lighting a card nobody chose. */
.deck-glow.is-lit { opacity: 1; }

/* ?cardedgedrive=off removes it outright rather than leaving it at zero, so
   C33's OFF arm is measuring an absent element and not a transparent one. */
.cards-eglow-off .deck-glow,
.eglow-off .deck-glow { display: none; }

/* The halo itself. inset: the glow radius puts this back at the CARD's exact
   box inside the padded wrapper, so the card's geometry is written once and
   read here rather than recomputed.

   ⚠️ THE RADIUS IS DERIVED FROM --card-radius, NOT TYPED (192 §3.2). Xinlu's
   "Border Radius 11" was chosen against the example's card; ours is 12, and two
   radii typed separately drift — 000 §5 entry 48.

   Four shadows: a near-white core at the edge, then his three colours spreading
   outward, which is 192 §2.1's measured white-hotspot-with-a-coloured-tail
   rather than the three swatches painting the bright part. ?cardedgeint=
   multiplies every alpha. */
.deck-glow__ring {
  position: absolute;
  inset: var(--card-edge-r, 40px);
  border-radius: var(--card-radius, 12px);
  box-shadow:
    0 0 calc(var(--card-edge-r, 40px) * 0.35)
      color-mix(in srgb, #fff calc(55% * var(--card-edge-int, 1.1)), transparent),
    0 0 calc(var(--card-edge-r, 40px) * 0.80)
      color-mix(in srgb, var(--card-edge-c1, #c095ea) calc(38% * var(--card-edge-int, 1.1)), transparent),
    0 0 calc(var(--card-edge-r, 40px) * 1.40)
      color-mix(in srgb, var(--card-edge-c2, #f472b6) calc(26% * var(--card-edge-int, 1.1)), transparent),
    0 0 calc(var(--card-edge-r, 40px) * 2.00)
      color-mix(in srgb, var(--card-edge-c3, #38bdf8) calc(16% * var(--card-edge-int, 1.1)), transparent);
}

/* ⚠️ REGISTERED SO IT CAN ANIMATE. An unregistered custom property is an
   untyped token stream and interpolates as a discrete step, so the sweep would
   jump rather than travel. This is the only @property on the site; it is here
   rather than in base.css because nothing else needs it. */
@property --card-edge-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 110deg;
}

/* The arc, for `sweep` and `pointer`. A conic gradient centred on
   --card-edge-angle with ?cardedgecone= as its half-width, so the lit arc is
   twice the cone and its edges ramp rather than cut. */
.deck-glow.is-sweep,
.deck-glow.is-pointer {
  -webkit-mask: conic-gradient(from calc(var(--card-edge-angle) - var(--card-edge-cone, 25) * 2deg),
    transparent 0deg,
    #000 calc(var(--card-edge-cone, 25) * 1deg),
    #000 calc(var(--card-edge-cone, 25) * 3deg),
    transparent calc(var(--card-edge-cone, 25) * 4deg),
    transparent 360deg);
          mask: conic-gradient(from calc(var(--card-edge-angle) - var(--card-edge-cone, 25) * 2deg),
    transparent 0deg,
    #000 calc(var(--card-edge-cone, 25) * 1deg),
    #000 calc(var(--card-edge-cone, 25) * 3deg),
    transparent calc(var(--card-edge-cone, 25) * 4deg),
    transparent 360deg);
}

/* ⚠️ THE SWEEP SETTLES, IT DOES NOT VANISH (192 §3.1). The reference removes
   its active class and the glow disappears entirely; on our open card that
   would leave no glow at all, which is the opposite of what was asked for. So
   cards.js drops `is-sweep` on animationend and what remains is `all` — an even
   halo on all four edges. C34 asserts the settled state and its control is the
   reference's own behaviour, which must fail it. */
.deck-glow.is-sweep {
  animation: deck-glow-sweep 3.75s cubic-bezier(0.33, 0, 0.2, 1) forwards;
}

@keyframes deck-glow-sweep {
  from { --card-edge-angle: 110deg; }
  to   { --card-edge-angle: 465deg; }
}

/* ⚠️ NO SWEEP UNDER reduce — a 3.75s one-shot is motion, and 171 §11's rule is
   to zero the animated dials and leave the resting frame alone. cards.js also
   skips adding the class, so this is the second of the two places. What a
   reduced-motion visitor gets is the settled `all` halo, which is the resting
   frame. */
@media (prefers-reduced-motion: reduce) {
  .deck-glow.is-sweep { animation: none; }
  .deck-glow.is-sweep,
  .deck-glow.is-pointer { -webkit-mask: none; mask: none; }
}

