/*
 * Scarlet & Violet finishes that many sets share, so every set's cards draw
 * them the same way: Tera ex and ACE SPEC. Both need the card's TCG Live foil
 * map (js/foil-maps.js), so foilPattern() in js/app.js only adds their class
 * when a map ships, and a set without maps keeps the older recipes.
 *
 * - Tera ex (Double Rare and Ultra Rare cards with the Tera subtype). TCG Live
 *   prints them SV_ULTRA / ETCHED, the same foil as a Special Illustration
 *   Rare (its print ids end DoubleRareC / UltraRareC): the whole card is foil,
 *   the Pokémon at part strength, with a fine etched grating cut with
 *   four-point sparkles. The crystal facets are ink over that foil; the map's
 *   grey steps keep them faceted under the shine.
 * - ACE SPEC Rare: ACE_FOIL / ETCHED. A crosshatch holo that collectors
 *   likened to the Sword & Shield Radiant pattern when it was revealed
 *   (PokeBeach, January 2024): hot pink stock that stays pink, cyan metal
 *   banners, a rainbow art window, and fine horizontal ridges everywhere.
 *
 * Layer ideas follow pokemon-cards-151's special illustration rare and
 * pokemon-cards-css's radiant holo by Simon Goellner (@simeydotme), GPL-3.0;
 * see NOTICE.md. The research is in the card-textures skill,
 * .claude/skills/card-textures/reference/sv-tera-acespec.md.
 *
 * Each finish rides on a second class next to the older pattern class
 * (`foil-ex foil-tera`, `foil-ultra foil-tera`, `foil-holo foil-acespec`), so
 * the Classic engine is untouched. The doubled class outranks the
 * three-class map rules other sheets add for `.foil-ultra` and friends,
 * whichever order the sheets load in. Loaded after celebration.css.
 *
 * Rest state (PR 5): a resting card paints `.foil` alone; the pseudo layers
 * and `.glare` only exist while a card is held or settling.
 */

body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map,
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map {
  --sv-spectrum: hsl(2, 100%, 73%), hsl(53, 100%, 69%), hsl(93, 100%, 69%),
    hsl(176, 100%, 76%), hsl(228, 100%, 74%), hsl(283, 100%, 73%), hsl(2, 100%, 73%);
}

/* Shared shape: the map is the mask (maps.css), the shine rises with the
   light, and the older recipes' pseudo layers are cleared first. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil,
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .foil {
  background-repeat: repeat;
  border-radius: 0;
  opacity: calc((0.18 + var(--card-opacity) * 0.82) * var(--foil-strength, 1));
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map:not(.lit):not(.settling) .foil,
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map:not(.lit):not(.settling) .foil {
  opacity: calc(0.18 * var(--foil-strength, 1));
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil::before,
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil::after,
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .foil::before,
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .foil::after {
  background-image: none;
  background-size: auto;
  background-position: center;
  background-repeat: repeat;
  background-blend-mode: normal;
  mix-blend-mode: normal;
  filter: none;
  -webkit-mask-image: none;
  mask-image: none;
  clip-path: none;
  opacity: 1;
}

/* ---- Tera ex: SV_ULTRA / ETCHED ---------------------------------------------
   The Special Illustration Rare's foil on a regular or full-art frame: a soft
   15deg rainbow that shows inside two light bars crossing with the tilt, fine
   glitter, a multiply glare that dims the card away from the light, and the
   etch glare (below) lighting the grating and its sparkles. Resting, the
   silver stays silver. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil {
  background-image: repeating-linear-gradient(15deg, var(--sv-spectrum), var(--sv-spectrum), var(--sv-spectrum));
  background-size: 240% 240%;
  background-position: var(--background-x) var(--background-y);
  background-blend-mode: normal;
  filter: brightness(0.6) contrast(1.5) saturate(1.1);
  mix-blend-mode: color-dodge;
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map:not(.lit):not(.settling) .foil {
  filter: brightness(0.6) contrast(1.5) saturate(0.4);
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil::before {
  background-image:
    linear-gradient(calc(var(--rotate-x) * -0.25), #000 24%, #797979 30%, #000 36%),
    linear-gradient(calc(var(--rotate-x) * 0.25), #000 24%, #797979 30%, #000 36%);
  background-size: 300% 300%;
  background-position: 50% min(100%, calc(var(--background-y) * 1.7)), 50% calc(100% - (var(--background-y) * 1.3));
  background-blend-mode: exclusion;
  filter: contrast(0.75);
  mix-blend-mode: hard-light;
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .foil::after {
  --shift: 3px;
  background-image: var(--holo-glitter);
  background-size: 25% auto;
  background-position: calc(50% + var(--pointer-from-left) * var(--shift))
    calc(50% + var(--pointer-from-top) * var(--shift));
  filter: brightness(1.4) contrast(2) saturate(1.2);
  mix-blend-mode: plus-lighter;
  opacity: calc(0.25 + var(--pointer-from-center) * 0.5);
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-foil-map .glare {
  background-image: radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
    hsl(0, 0%, 90%) 10%, hsl(0, 0%, 62%) 70%);
  background-size: cover;
  background-position: center;
  mix-blend-mode: multiply;
  filter: contrast(1.4);
  opacity: calc(var(--card-opacity) * 0.75);
}

/* ---- ACE SPEC Rare: ACE_FOIL / ETCHED ---------------------------------------
   Retuned against Surging Sparks photos (2026-09-27): the magenta body stays
   saturated hot pink at every angle and never goes silver; the ACE SPEC
   banners are a separate cyan metal; the art window runs the full rainbow
   with X and diamond facets (Deluxe Bomb); and fine horizontal ridges cross
   the whole card, visible even unlit.

   Everything that shines is a colour-dodge on `.foil`, masked by the map:
   a dodge lifts the channels the print already has, so the magenta stock
   (empty green channel) only gets hotter pink, the cyan banners (the map's
   full-strength zone) turn bright cyan metal, and the art window takes the
   whole spectrum. `.foil` stacks the ridges over a rainbow cut into a
   crosshatch lattice (pokemon-cards-css's radiant holo bars, crossed with
   `lighten` so the lattice lines are the bright ones); `::after` runs the
   rainbow through the etch map's line fields; `::before` is the sparkle
   grain. The glare darkens away from the light, and its `::after` only
   brightens the ridges near the light, never a white wash. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map {
  --ace-bar: 1.2%;
  --ace-bars: hsl(0, 0%, 10%) 0%, hsl(0, 0%, 10%) var(--ace-bar),
    hsl(0, 0%, 20%) calc(var(--ace-bar) + 0.01%), hsl(0, 0%, 20%) calc(var(--ace-bar) * 2),
    hsl(0, 0%, 35%) calc(var(--ace-bar) * 2 + 0.01%), hsl(0, 0%, 35%) calc(var(--ace-bar) * 3),
    hsl(0, 0%, 42.5%) calc(var(--ace-bar) * 3 + 0.01%), hsl(0, 0%, 42.5%) calc(var(--ace-bar) * 4),
    hsl(0, 0%, 50%) calc(var(--ace-bar) * 4 + 0.01%), hsl(0, 0%, 50%) calc(var(--ace-bar) * 5),
    hsl(0, 0%, 42.5%) calc(var(--ace-bar) * 5 + 0.01%), hsl(0, 0%, 42.5%) calc(var(--ace-bar) * 6),
    hsl(0, 0%, 35%) calc(var(--ace-bar) * 6 + 0.01%), hsl(0, 0%, 35%) calc(var(--ace-bar) * 7),
    hsl(0, 0%, 20%) calc(var(--ace-bar) * 7 + 0.01%), hsl(0, 0%, 20%) calc(var(--ace-bar) * 8),
    hsl(0, 0%, 10%) calc(var(--ace-bar) * 8 + 0.01%), hsl(0, 0%, 10%) calc(var(--ace-bar) * 9),
    hsl(0, 0%, 0%) calc(var(--ace-bar) * 9 + 0.01%), hsl(0, 0%, 0%) calc(var(--ace-bar) * 10);
  /* The ridges: one bright line every 3px, in device-independent CSS px so
     they stay fine on any card size. */
  --ace-ridges: repeating-linear-gradient(180deg,
    hsl(0, 0%, 100%) 0, hsl(0, 0%, 100%) 1px, hsl(0, 0%, 55%) 1px, hsl(0, 0%, 55%) 3px);
  --ace-ridge-mask: repeating-linear-gradient(180deg,
    #000 0, #000 1px, transparent 1px, transparent 3px);
  --ace-bars-at: calc((var(--background-x) - 50%) * 1.5 + 50%) calc((var(--background-y) - 50%) * 1.5 + 50%);
}
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .foil {
  background-image:
    var(--ace-ridges),
    linear-gradient(115deg, var(--sv-spectrum)),
    repeating-linear-gradient(45deg, var(--ace-bars)),
    repeating-linear-gradient(-45deg, var(--ace-bars));
  background-size: 100% 3px, 300% 300%, 210% 210%, 210% 210%;
  background-repeat: repeat;
  background-position: 0 0, var(--background-x) var(--background-y), var(--ace-bars-at), var(--ace-bars-at);
  background-blend-mode: multiply, multiply, lighten, normal;
  filter: brightness(1.05) contrast(1.6) saturate(1.3);
  mix-blend-mode: color-dodge;
  opacity: calc((0.3 + var(--card-opacity) * 0.7) * var(--foil-strength, 1));
}
/* Resting: the ridges and a faint lattice show, with no colour wash, as on
   an unlit card. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map:not(.lit):not(.settling) .foil {
  filter: brightness(1.1) contrast(1.1) saturate(0.35);
  opacity: calc(0.3 * var(--foil-strength, 1));
}
/* The etched line fields (art background, banners) catch the rainbow as it
   sweeps against the tilt. Without an etch map the card keeps the lattice
   alone. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map.has-etch-map .foil::after {
  background-image: linear-gradient(55deg, var(--sv-spectrum));
  background-size: 400% 400%;
  background-position: calc((var(--background-x) - 50%) * -2.5 + 50%) calc((var(--background-y) - 50%) * -2.5 + 50%);
  -webkit-mask-image: var(--etch-map);
  mask-image: var(--etch-map);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  filter: brightness(0.55) saturate(1.3);
  mix-blend-mode: screen;
  opacity: 0.55;
}
/* Sparkle grain: glitter lit around the pointer. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .foil::before {
  background-image:
    var(--holo-glitter),
    radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
      hsl(0, 0%, 70%) 0%, hsl(0, 0%, 30%) 45%, hsl(0, 0%, 12%) 100%);
  background-size: 18% 18%, 100% 100%;
  background-position: center;
  background-repeat: repeat, no-repeat;
  background-blend-mode: multiply;
  filter: contrast(1.6);
  mix-blend-mode: screen;
  opacity: 0.6;
}
/* Away from the light the pink deepens toward red-magenta; near it the
   glare lifts only a little, so the stock never bleaches. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .glare {
  background-image: radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
    hsl(0, 0%, 60%) 0%, hsl(0, 0%, 50%) 30%, hsl(0, 0%, 32%) 110%);
  background-size: cover;
  background-position: center;
  filter: none;
  mix-blend-mode: hard-light;
  opacity: calc(var(--card-opacity) * 0.7);
}
/* The ridges catching the light: thin bright lines near the pointer, the
   stock showing between them. Replaces the white hot spot other etched
   finishes use, which bleached the magenta and the art window. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-acespec.foil-acespec.has-foil-map .glare::after {
  background-image: radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
    hsla(330, 100%, 94%, 0.75) 0%, hsla(330, 100%, 94%, 0.3) 25%, hsla(330, 100%, 94%, 0) 50%);
  background-size: 100% 100%;
  background-position: center;
  -webkit-mask-image: var(--ace-ridge-mask);
  mask-image: var(--ace-ridge-mask);
  -webkit-mask-size: 100% 3px;
  mask-size: 100% 3px;
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
  mix-blend-mode: normal;
  filter: none;
  opacity: calc(var(--card-opacity) * 0.8);
}

/* ---- The etch catching the light -------------------------------------------
   A white hot spot masked by the etch map, as in celebration.css, restated
   at this sheet's specificity so the older glare::after resets for these
   classes cannot clear it. */
body.fx-holo.fx-holo.fx-holo .tcg.foil-tera.foil-tera.has-etch-map .glare::after {
  background-image: radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
    hsla(0, 0%, 100%, 0.95) 0%, hsla(0, 0%, 100%, 0.45) 25%, hsla(0, 0%, 100%, 0) 60%);
  background-size: 100% 100%;
  -webkit-mask-image: var(--etch-map);
  mask-image: var(--etch-map);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  mix-blend-mode: normal;
  filter: none;
  opacity: calc(0.5 + var(--pointer-from-center) * 0.45);
}
