Engine parity check

Kyogre, reproduced exactly

The same MIT foil engine, unmodified, driving a real Amazing Rare card and our Godlike Harrowfield card side by side. Every difference between them is a configuration variable, not a code change — which is the whole point of the exercise.

Every element of the Kyogre card

What the engine is actually composing, in paint order. The stack is ordered by translateZ, not z-index.

LayerWhat it isSource
card__backCard back, shown while unflippedtcg.pokemon.com
card__front › imgThe printed card face at 734×1024images.pokemontcg.io/swsh45/21_hires.png
--foilBespoke, registered to this artwork. A contrast-crushed greyscale luminance map over black — it decides where the shine fires021_foil_etched_swsecret_2x.webp
--maskBespoke. Alpha × 8, crushing partial alpha — it decides what is foil at all021_foil_etched_swsecret_2x.webp
card__shineTwo glitter tiles + a pointer-tracked radial, soft-light then color-burnshared glitter.png
card__shine::beforeThe foil map itself, color-burn against a pointer radial, mix-blend-mode: lighten, opacity 0.5--foil
card__shine::afterSix sunpillar stops, repeating, mix-blend-mode: saturation, brightness falling with --pointer-from-centergradient only
card__glareThe clearcoat — a single specular tracking the pointergradient only
This is the finding that matters. 84 of the reference's 91 cards carry a foil and a mask authored for that one card. That registration is why the shine hugs Kyogre's water and crest and stops at the frame. Our card has no equivalent layer — one shared texture, applied flat. That gap, not typography, is the reason ours reads as cheaper.

The variable contract

Thirteen values, recomputed every frame from one pointer position. Both cards below are driven by the identical loop; I reimplemented the spring rather than importing Svelte, matching the reference's constants (interact k .066 / d .25).

VariableDerivation
--pointer-x / yclamped % of the card box
--pointer-from-centerclamp(hypot(x−50, y−50) / 50, 0, 1)
--pointer-from-top / lefty / 100  ·  x / 100
--rotate-x / y−(x−50) / 3.5  ·  (y−50) / 3.5
--background-x / yremap 0..100 → 37..63  ·  33..67
--card-opacity1 while interacting, springs to 0 on leave
--seedx / seedy / --cosmosbgstatic per card, so no two cards glitter alike