/* CaptureDex — holographic card engine (theme-agnostic, drop-in)
   Markup contract:
     <div class="holo-card">          <- the card; give it size + your frame/art inside
        ...your card content...
     </div>
   holo.js injects two overlay layers (.holo-card__glare, .holo-card__foil)
   and drives these custom properties on the element:
     --px,--py  pointer position inside the card, 0..100 (%)
     --rx,--ry  tilt rotation in deg
     --act      activity 0..1 (0 at rest, 1 while interacting)
   Style the card's own look in your variant; this file only handles the shine. */

.holo-card {
  position: relative;
  aspect-ratio: 63 / 88;            /* trading-card ratio */
  border-radius: clamp(12px, 4.5cqw, 22px);
  overflow: hidden;                 /* clip inner layers (e.g. cf-bottom) to the rounded corners */
  /* NB: NO transform-style:preserve-3d here. The overlays (foil/glare/frame) are
     flat, and on iOS preserve-3d breaks overflow+border-radius clipping, leaving
     square corners poking past the rounded card ("quininha"). Flat keeps the tilt
     and restores corner clipping. */
  transform:
    perspective(900px)
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg));
  transition: transform .4s cubic-bezier(.23,1,.32,1);
  will-change: transform;
  isolation: isolate;
  container-type: inline-size;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: pan-y;
}
.holo-card.is-active { transition: transform .08s ease-out; }

/* ---------------------------------------------------------------------------
   Per-style knobs. A style = one class on .holo-card (e.g. holo-cosmos) that
   overrides these vars. Defaults below = "Rainbow Foil", a clean premium sheen.
   Texture is SOFT + wide (no hard 1px lines) so it never aliases into a moiré
   crawl when the card is scaled/tilted — the artifact we are killing here.
   --------------------------------------------------------------------------- */
.holo-card{
  /* DISCREET pastel rainbow — low-chroma (S≈45%, l≈86%) so the foil reads as a
     soft metallic sheen, not a colourful wash. The poke-holo trick is pastel;
     we push it further toward near-neutral for a subtle, premium finish. */
  --foil-rainbow: linear-gradient(110deg,
    hsl(3,45%,86%), hsl(29,48%,86%), hsl(53,45%,85%), hsl(160,42%,86%),
    hsl(188,46%,86%), hsl(228,44%,87%), hsl(283,40%,87%), hsl(309,44%,87%),
    hsl(3,45%,86%), hsl(160,42%,86%));
  /* soft diagonal sheen comb — wide & feathered, scales cleanly at any size */
  --foil-texture: repeating-linear-gradient(102deg,
    rgba(0,0,0,0) 0px, rgba(0,0,0,.28) 4px,
    rgba(255,255,255,.45) 8px, rgba(0,0,0,0) 12px);
  --foil-tex-size: 220% 220%;
  --foil-mix: color-dodge;          /* how the foil blends over the photo */
  --foil-filter: brightness(.95) contrast(1.35) saturate(0.7);
  --foil-op: .5;                    /* per-style peak; scaled by --holo-master */
  --holo-master: .5;                /* GLOBAL intensity dial — lower = subtler */
}

/* glare: a moving specular highlight — opacity driven ENTIRELY by interaction
   (--act 0..1), so a card at rest shows just its photo. (poke-holo technique) */
.holo-card__glare {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 4;
  mix-blend-mode: overlay;
  opacity: calc(var(--act, 0) * .5);
  background: radial-gradient(
    farthest-corner circle at var(--px, 50%) var(--py, 50%),
    rgba(255,255,255,.7) 8%,
    rgba(255,255,255,.4) 18%,
    rgba(0,0,0,.5) 80%
  );
  transition: opacity .3s ease;
}

/* foil: soft holographic texture + a broad moving rainbow + a radial DARK
   localizer at the pointer (color-dodge) that confines the shine near the
   light instead of washing the whole card. All look knobs are per-style vars
   (above) so each style is a genuinely different recipe, not just a recolor.
   Opacity is interaction-driven: near-invisible at rest, blooms as you move. */
.holo-card__foil {
  position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 3;
  mix-blend-mode: var(--foil-mix, color-dodge);
  opacity: calc(.02 + var(--act, 0) * var(--foil-op, .5) * var(--holo-master, .5));
  /* ONLY the rainbow + localizer here — both NO-REPEAT, so the big 300% gradient
     never tiles (tiling was what produced the hard quadrant seams / edges). The
     pointer parallax is kept inside a safe 20–80% range so the gradient always
     fully covers the card (no transparent gap, no seam). */
  background-image:
    var(--foil-rainbow),
    radial-gradient(farthest-corner circle at var(--px, 50%) var(--py, 50%),
      rgba(0,0,0,.05) 10%, rgba(0,0,0,.28) 34%, rgba(0,0,0,.45) 90%);
  background-repeat: no-repeat;
  background-blend-mode: color-dodge;
  background-size: 300% 300%, 200% 200%;
  background-position:
    calc(var(--px, 50%) * 0.6 + 20%) calc(var(--py, 50%) * 0.6 + 20%),
    var(--px, 50%) var(--py, 50%);
  filter: var(--foil-filter, brightness(.92) contrast(1.55) saturate(0.85));
  transition: opacity .3s ease;
}
/* texture (scanlines / comb / sparkle dust) on its OWN layer. A texture is a
   periodic pattern that tiles seamlessly, so it can repeat freely here without
   ever creating the rainbow's tile seam. Inherits the foil's gated opacity. */
.holo-card__foil::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background-image: var(--foil-texture, none);
  background-size: var(--foil-tex-size, 220% 220%);
  background-position: calc(var(--px, 50%) * -0.6) calc(var(--py, 50%) * -0.6);
  mix-blend-mode: overlay;
  opacity: .55;
}

/* a subtle inner light edge so the card reads as glossy stock */
.holo-card::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none; z-index: 5;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14),
              inset 0 1px 1px rgba(255,255,255,.22);
}

@media (prefers-reduced-motion: reduce) {
  .holo-card { transition: none; transform: none !important; }
  .holo-card__glare { opacity: .25; }
  .holo-card__foil { opacity: .2; }
}

/* Real-photo support: photo as <img class="cap-photo"> inside .card-art.
   The base foil is already tuned to sit over a photo, so no extra weakening. */
.cap-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block}

/* =====================================================================
   10 holographic styles — add ONE class to .holo-card (e.g. holo-cosmos).
   Each only overrides the foil's image/size/blend/filter; the pointer-
   driven position + 3D tilt keep working. No class = the default rainbow.
   ===================================================================== */
.holo-card.holo-rainbow{}              /* = default (clean soft sheen + full rainbow) */

/* Scan — the classic lined foil, but at a moiré-safe ~5px period (not 1px) */
.holo-card.holo-scan {
  --foil-texture: repeating-linear-gradient(96deg,
    rgba(0,0,0,.55) 0px, rgba(0,0,0,.55) 2px,
    rgba(255,255,255,.7) 2px, rgba(255,255,255,.7) 5px);
  --foil-tex-size: cover;
  --foil-filter: brightness(.88) contrast(1.9) saturate(0.85);
  --foil-op: .6;
}

/* Radiant — poke-holo "radiant rare": crosshatched diamond bars + pastel
   rainbow stripes. The signature realistic foil. (adapted from radiant-holo.css) */
.holo-card.holo-radiant {
  --foil-rainbow: repeating-linear-gradient(55deg,
    hsl(3,95%,85%) 0px, hsl(207,100%,84%) 70px, hsl(29,100%,85%) 140px,
    hsl(160,100%,86%) 210px, hsl(309,94%,87%) 280px, hsl(188,95%,85%) 350px,
    hsl(3,95%,85%) 420px);
  --foil-texture:
    repeating-linear-gradient(45deg,
      rgba(0,0,0,.55) 0 1.1%, rgba(255,255,255,.55) 1.1% 2.2%),
    repeating-linear-gradient(-45deg,
      rgba(0,0,0,.55) 0 1.1%, rgba(255,255,255,.55) 1.1% 2.2%);
  --foil-tex-size: 200% 200%;
  --foil-filter: brightness(.78) contrast(2.1) saturate(0.85);
  --foil-op: .62;
}

/* Cosmos — deep space; fine sparkle dust over a jewel-tone sweep */
.holo-card.holo-cosmos {
  --foil-rainbow: linear-gradient(125deg,#6b4ba8,#3b7fc4,#46c0b0,#9a5bc0,#6b4ba8,#3b7fc4);
  --foil-texture:
    radial-gradient(circle at 20% 30%, rgba(255,255,255,.9) 0 1px, transparent 1.8px),
    radial-gradient(circle at 70% 60%, rgba(255,255,255,.8) 0 1.3px, transparent 2px),
    radial-gradient(circle at 45% 85%, rgba(255,255,255,.7) 0 1px, transparent 1.8px),
    radial-gradient(circle at 88% 22%, rgba(255,255,255,.6) 0 .9px, transparent 1.6px);
  --foil-tex-size: 80px 80px;
  --foil-filter: brightness(.95) contrast(1.45) saturate(0.85);
  --foil-op: .58;
}

/* Aurora — wide soft ribbons of teal/violet */
.holo-card.holo-aurora {
  --foil-rainbow: linear-gradient(115deg,#9af0d2,#a7e0ff,#cdb6ff,#a7ffe6,#9af0d2,#a7e0ff);
  --foil-texture: repeating-linear-gradient(80deg,
    rgba(0,0,0,0) 0px, rgba(255,255,255,.32) 16px, rgba(0,0,0,0) 34px);
  --foil-tex-size: 260% 260%;
  --foil-filter: brightness(.96) contrast(1.35) saturate(0.85);
  --foil-op: .5;
}

/* Gold Secret — warm metallic, low saturation, soft sheen */
.holo-card.holo-gold {
  --foil-rainbow: linear-gradient(110deg,#8a6420,#ffeec0,#d9b568,#a5781f,#ffeec0,#8a6420);
  --foil-filter: brightness(.96) contrast(1.55) saturate(0.85);
  --foil-op: .55;
}

/* Prism — angular spectrum, pastel so it reads premium not neon */
.holo-card.holo-prism {
  --foil-rainbow: conic-gradient(from 210deg at 50% 50%,
    hsl(3,95%,85%),hsl(45,100%,85%),hsl(140,90%,85%),hsl(195,95%,85%),
    hsl(270,85%,87%),hsl(320,90%,87%),hsl(3,95%,85%));
  --foil-texture: repeating-linear-gradient(115deg,
    rgba(0,0,0,0) 0px, rgba(0,0,0,.28) 6px, rgba(255,255,255,.5) 12px, rgba(0,0,0,0) 18px);
  --foil-tex-size: 180% 180%;
  --foil-filter: brightness(.9) contrast(1.6) saturate(0.85);
  --foil-op: .56;
}

/* Wave — flowing pastel rainbow, gentle */
.holo-card.holo-wave {
  --foil-rainbow: linear-gradient(100deg,
    hsl(3,95%,86%),hsl(53,90%,85%),hsl(140,90%,86%),hsl(190,95%,86%),
    hsl(235,90%,87%),hsl(320,90%,87%),hsl(3,95%,86%),hsl(140,90%,86%));
  --foil-tex-size: 300% 300%;
  --foil-op: .5;
}

/* Glitter — dense fine sparkle dust, like a glittered foil */
.holo-card.holo-glitter {
  --foil-rainbow: linear-gradient(110deg,
    hsl(3,95%,86%),hsl(190,95%,86%),hsl(53,90%,85%),hsl(140,90%,86%),
    hsl(283,85%,87%),hsl(3,95%,86%));
  --foil-texture:
    radial-gradient(circle at 12% 18%, rgba(255,255,255,.95) 0 1px, transparent 1.6px),
    radial-gradient(circle at 42% 36%, rgba(255,255,255,.85) 0 .9px, transparent 1.4px),
    radial-gradient(circle at 68% 22%, rgba(255,255,255,.9) 0 1px, transparent 1.6px),
    radial-gradient(circle at 28% 64%, rgba(255,255,255,.8) 0 .9px, transparent 1.4px),
    radial-gradient(circle at 82% 72%, rgba(255,255,255,.9) 0 1px, transparent 1.6px),
    radial-gradient(circle at 56% 88%, rgba(255,255,255,.85) 0 .9px, transparent 1.4px);
  --foil-tex-size: 46px 46px;
  --foil-filter: brightness(1) contrast(1.5) saturate(0.85);
  --foil-op: .6;
}

/* Confetti — speckled multicolour flecks */
.holo-card.holo-confetti {
  --foil-rainbow: linear-gradient(110deg,
    hsl(3,95%,86%),hsl(195,95%,86%),hsl(45,100%,86%),hsl(140,90%,86%),
    hsl(283,85%,87%),hsl(3,95%,86%),hsl(195,95%,86%));
  --foil-texture:
    radial-gradient(circle at 15% 25%, rgba(255,150,180,.85) 0 1.3px, transparent 2.2px),
    radial-gradient(circle at 60% 40%, rgba(150,210,255,.85) 0 1.3px, transparent 2.2px),
    radial-gradient(circle at 80% 75%, rgba(255,230,150,.85) 0 1.3px, transparent 2.2px),
    radial-gradient(circle at 35% 80%, rgba(170,255,200,.85) 0 1.3px, transparent 2.2px);
  --foil-tex-size: 64px 64px;
  --foil-filter: brightness(.98) contrast(1.45) saturate(0.85);
  --foil-op: .56;
}

/* Crystal — faceted cool shimmer (toned down so it doesn't blow out white) */
.holo-card.holo-crystal {
  --foil-rainbow: linear-gradient(120deg,
    hsl(190,90%,87%),hsl(53,85%,86%),hsl(150,85%,87%),hsl(200,95%,87%),
    hsl(250,80%,88%),hsl(310,85%,88%),hsl(190,90%,87%));
  --foil-texture: repeating-linear-gradient(60deg,
      rgba(0,0,0,.15) 0px, rgba(255,255,255,.32) 7px, rgba(0,0,0,.15) 16px),
    repeating-linear-gradient(-60deg,
      rgba(0,0,0,.15) 0px, rgba(255,255,255,.25) 7px, rgba(0,0,0,.15) 16px);
  --foil-tex-size: 170% 170%;
  --foil-filter: brightness(.88) contrast(1.5) saturate(0.85);
  --foil-op: .52;
}

/* Silver Sheen — subtle metallic, no rainbow, for understated cards */
.holo-card.holo-sheen {
  --foil-rainbow: linear-gradient(110deg,rgba(255,255,255,.95),rgba(150,160,180,.3),rgba(255,255,255,.95),rgba(150,160,180,.3));
  --foil-mix: soft-light;
  --foil-filter: brightness(1.05) contrast(1.2) saturate(0.6);
  --foil-op: .7;
}

/* Neon — punchy magenta/cyan (kept saturated on purpose, for bold cards) */
.holo-card.holo-neon {
  --foil-rainbow: linear-gradient(110deg,#ff4dd8,#37f0ff,#ff4dd8,#37f0ff,#ff4dd8);
  --foil-texture: repeating-linear-gradient(96deg,
    rgba(0,0,0,.4) 0px, rgba(0,0,0,.4) 3px, rgba(255,255,255,.55) 3px, rgba(255,255,255,.55) 7px);
  --foil-tex-size: cover;
  --foil-filter: brightness(.9) contrast(1.7) saturate(0.85);
  --foil-op: .58;
}
