/* Card geometry and foil recipes adapted from Simon Goellner (2022).
 * GPL-3.0; see ../LICENSE.txt. Only Etched and Hyper Holo are included.
 */
:root {
  color-scheme: dark;
  --card-aspect: 5 / 7;
  --pointer-x: 50%;
  --pointer-y: 50%;
  --pointer-from-center: 0;
  --pointer-from-top: .5;
  --pointer-from-left: .5;
  --background-x: 50%;
  --background-y: 50%;
  --card-opacity: 0;
  --rotate-x: 0deg;
  --rotate-y: 0deg;
}

* { box-sizing: border-box; }
body { margin: 0; background: #000; isolation: isolate; }
body::before {
  content: "";
  position: fixed;
  inset: -24px;
  z-index: -1;
  background: url("img/bg.webp") center / cover no-repeat;
  opacity: .2;
  pointer-events: none;
}
main {
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
}
.card-slot {
  container-type: inline-size;
  width: min(528px, 80vw, calc(80vh * 5 / 7));
  width: min(528px, 80vw, calc(80svh * 5 / 7));
  aspect-ratio: var(--card-aspect);
}
.card {
  --card-radius: 4.545455cqw;
  --glare-strength: .1;
  --px: 0cqw;
  --py: 0cqw;
  width: 100%;
  transform: translate3d(0cqw, 0cqw, 0.003788cqw);
  pointer-events: none;
  transform-style: preserve-3d;
}
.card,
.card__rotator {
  aspect-ratio: var(--card-aspect);
  border-radius: var(--card-radius);
}
.card__translater,
.card__rotator {
  display: grid;
  perspective: 227.272727cqw;
  will-change: transform, box-shadow;
  transform-origin: center;
  transform-style: preserve-3d;
}
.card__translater {
  position: relative;
  transform: translate3d(0, 0, calc(56.818182cqw + 0.003788cqw));
}
.card__rotator {
  width: 100%;
  transform: rotateY(var(--rotate-x)) rotateX(var(--rotate-y));
  pointer-events: auto;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  box-shadow:
    0cqw 3.7cqw 7.5cqw -1.8cqw rgba(0,0,0,0.25),
    0 0.7cqw 5.5cqw -1.8cqw rgba(0,0,0,0.25);
}
.card__front {
  position: relative;
  width: 100%;
  aspect-ratio: var(--card-aspect);
  isolation: isolate;
  transform-style: flat;
  transform: translate3d(0cqw, 0cqw, 0.003788cqw);
  overflow: hidden;
  border-radius: var(--card-radius);
  clip-path: inset(0.189394cqw round var(--card-radius));
  background: #121212;
}
.card__front,
.card__front * {
  backface-visibility: hidden;
  pointer-events: none;
}
.card-scene,
.frame-plane {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  isolation: isolate;
}
.card-scene { overflow: hidden; }
.character-plane {
  position: absolute;
  inset: -6.439394cqw;
  width: calc(100% + 12.878788cqw);
  height: calc(100% + 12.878788cqw);
  z-index: 2;
  isolation: isolate;
  transform: translate(calc(var(--px) * .35), calc(var(--py) * .35)) scale(1.03);
  will-change: transform;
}
.art-character {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  object-position: center;
  z-index: 1;
}
.foil-surface { display: contents; }
.card__shine {
  position: absolute;
  inset: 0;
  display: grid;
  width: 100%;
  height: 100%;
  transform: translateZ(0.378788cqw);
  overflow: hidden;
  z-index: 2;
  background: transparent;
  background-size: cover;
  background-position: center;
  filter: brightness(.85) contrast(2.75) saturate(.65);
  mix-blend-mode: color-dodge;
  opacity: var(--card-opacity);
  will-change: transform, opacity, background-position, filter;
}
.card__shine::before,
.card__shine::after {
  grid-area: 1 / 1;
  transform: translateZ(0.378788cqw);
}
.card__shine::after { transform: translateZ(0.454545cqw); }

/* Etched: the gallery's gradients, blend modes, light response and alpha
 * coverage. The supplied character replaces the tiled material pattern.
 */
.effect-layer[data-effect="etched"] {
  --foil-brightness: .6;
  --etch-grain-size: 50cqw;
  --etch-grain-strength: .55;
}
.effect-layer[data-effect="etched"] .card__shine {
  --foil: url("img/etch.webp");
  background-blend-mode: soft-light, difference;
  background-image:
    radial-gradient(circle at var(--pointer-x) var(--pointer-y), #fff 5%, #000 50%, #fff 80%),
    linear-gradient(-45deg, #000 15%, #fff, #000 85%),
    var(--foil);
  background-position:
    center center,
    calc(100% * var(--pointer-from-left)) calc(100% * var(--pointer-from-top)),
    center center;
  background-size: 120% 120%, 200% 200%, cover;
  background-repeat: no-repeat;
  -webkit-mask-image: var(--foil);
  mask-image: var(--foil);
  -webkit-mask-size: cover;
  mask-size: cover;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  mask-mode: alpha;
  filter: brightness(var(--foil-brightness)) contrast(1.5) saturate(1);
  mix-blend-mode: color-dodge;
  opacity: calc((1.5 * var(--card-opacity)) - var(--pointer-from-center));
}
/* The grain follows each coating's artwork/border mask and light response.
 * Only this fine texture repeats; the artwork remains a single image.
 */
.effect-layer[data-effect="etched"] .card__shine::before {
  content: "";
  background: url("img/grain.webp") center / var(--etch-grain-size) var(--etch-grain-size) repeat;
  mix-blend-mode: screen;
  opacity: var(--etch-grain-strength);
}

/* The frame plane stays fixed, as in the gallery. Each full-canvas image
 * masks its own material, keeping their original registration intact.
 */
.frame-plane {
  --holo-strength: 1;
  --holo-transition: .6%;
  --holo-contrast: 2;
  z-index: 3;
}
.frame-shadow {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}
.foil-mark {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  isolation: isolate;
  background: var(--mark) center / 100% 100% no-repeat;
}
/* Mask and tint only the foil coating, leaving the supplied image neutral. */
.foil-mark .card__shine {
  -webkit-mask-image: var(--mark);
  mask-image: var(--mark);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  mask-mode: alpha;
}
.foil-mark--silver {
  --mark: url("img/text.webp");
  --holo-tint: grayscale(1);
  --text-emboss-depth: .2cqw;
  --text-emboss-strength: .48;
}
/* Subtract a shifted copy of the text alpha to shade only its inner edges. */
.foil-mark--silver::before,
.foil-mark--silver::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  opacity: var(--text-emboss-strength);
  -webkit-mask-image: var(--mark), var(--mark);
  mask-image: var(--mark), var(--mark);
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: 0 0, var(--emboss-offset) var(--emboss-offset);
  mask-position: 0 0, var(--emboss-offset) var(--emboss-offset);
  -webkit-mask-composite: source-out;
  mask-composite: subtract;
}
.foil-mark--silver::before {
  --emboss-offset: var(--text-emboss-depth);
  background: #000;
  mix-blend-mode: multiply;
}
.foil-mark--silver::after {
  --emboss-offset: calc(var(--text-emboss-depth) * -1);
  background: #fff;
  mix-blend-mode: screen;
}
.foil-mark--gold {
  --mark: url("img/diamond.webp");
  --holo-tint: grayscale(1) sepia(1) saturate(2.2);
}
.foil-mark--pink {
  --mark: url("img/heart.webp");
  --holo-tint: grayscale(1) sepia(1) saturate(3) hue-rotate(285deg);
}

/* Hyper Holo, with tighter color transitions and stronger band contrast.
 * Preserve the gallery's band spacing, motion and blend modes; tint the shine.
 */
.effect-layer[data-effect="silver-texture"] {
  --sunpillar-1: hsl(2, 100%, 73%);
  --sunpillar-2: hsl(53, 100%, 69%);
  --sunpillar-3: hsl(93, 100%, 69%);
  --sunpillar-4: hsl(176, 100%, 76%);
  --sunpillar-5: hsl(228, 100%, 74%);
  --sunpillar-6: hsl(283, 100%, 73%);
  --angle: 133deg;
  --space: 5%;
}
.effect-layer[data-effect="silver-texture"] .card__shine {
  filter: brightness(.85) contrast(2.75) saturate(.65) var(--holo-tint);
  opacity: calc(var(--card-opacity) * var(--holo-strength));
}
.effect-layer[data-effect="silver-texture"] .card__shine::after {
  --sunpillar-clr-1: var(--sunpillar-6);
  --sunpillar-clr-2: var(--sunpillar-1);
  --sunpillar-clr-3: var(--sunpillar-2);
  --sunpillar-clr-4: var(--sunpillar-3);
  --sunpillar-clr-5: var(--sunpillar-4);
  --sunpillar-clr-6: var(--sunpillar-5);
  background-image: repeating-linear-gradient(calc(var(--angle)),
    var(--sunpillar-clr-1) calc(var(--space) * 1) calc(var(--space) * 2 - var(--holo-transition)),
    var(--sunpillar-clr-2) calc(var(--space) * 2) calc(var(--space) * 3 - var(--holo-transition)),
    var(--sunpillar-clr-3) calc(var(--space) * 3) calc(var(--space) * 4 - var(--holo-transition)),
    var(--sunpillar-clr-4) calc(var(--space) * 4) calc(var(--space) * 5 - var(--holo-transition)),
    var(--sunpillar-clr-5) calc(var(--space) * 5) calc(var(--space) * 6 - var(--holo-transition)),
    var(--sunpillar-clr-6) calc(var(--space) * 6) calc(var(--space) * 7 - var(--holo-transition)),
    var(--sunpillar-clr-1) calc(var(--space) * 7)
  );
  background-position:
    calc(50% + (50% - var(--background-x)) * 3)
    calc(50% + (50% - var(--background-y)) * 3);
  background-size: 400% 800%;
  content: "";
  filter: brightness(calc((var(--pointer-from-center) * .4) + .6)) contrast(var(--holo-contrast)) saturate(1.2);
  mix-blend-mode: difference;
}

/* Retain only the base frame's black outer border (8px at 264px wide). */
.frame-geometry {
  position: absolute;
  inset: 0;
  border: 3.030303cqw solid #111;
  border-radius: 4.545455cqw;
  box-shadow: inset 0 0 0 .378788cqw #0000001f;
  z-index: 4;
}
.surface-glare {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  z-index: 6;
  background: radial-gradient(
    farthest-corner circle at var(--pointer-x) var(--pointer-y),
    hsla(0, 0%, 100%, .8) 10%,
    hsla(0, 0%, 100%, .65) 20%,
    hsla(0, 0%, 0%, .5) 90%
  );
  opacity: calc(var(--card-opacity) * var(--glare-strength));
  mix-blend-mode: overlay;
}
/* Reuse the Etched recipe on the rim, with its own border-only coverage.
 * Blend the masked coating into the border beneath it.
 */
.border-etch {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  z-index: 5;
  padding: 3.030303cqw;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  mix-blend-mode: color-dodge;
}
.border-etch[data-effect="etched"] .card__shine {
  --foil: none;
  -webkit-mask-image: none;
  mask-image: none;
}
