/* Image-first card: geometry, finish and self-hosted faces for card-el.js. */

@font-face {
  font-family: "Alegreya";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/alegreya-400-italic-cyrillic-ext.woff2") format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Alegreya";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/alegreya-400-italic-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Alegreya";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/alegreya-400-italic-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Alegreya";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/alegreya-cyrillic-ext.woff2") format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Alegreya";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/alegreya-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Alegreya";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/alegreya-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/philosopher-400-cyrillic-ext.woff2") format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/philosopher-400-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/philosopher-400-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/philosopher-700-cyrillic-ext.woff2") format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/philosopher-700-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Philosopher";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/philosopher-700-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

.game-card {
  --dc: var(--border);
  --gem-str: var(--stat-strength);
  --card-display: "Philosopher", Georgia, serif;
  --card-body: "Alegreya", Georgia, serif;
  position: relative;
  box-sizing: border-box;
  flex: none;
  cursor: pointer;
  /* Holding a card reads it: no text selection, no iOS callout, no 300ms wait. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  touch-action: manipulation;
  /* Transparent so game.css's border-color state rules have something to paint. */
  border: 1px solid transparent;
  transition:
    transform var(--transition),
    box-shadow var(--transition),
    opacity var(--transition),
    filter var(--transition);
}

/* ---- Ring colour per domain ---- */
.domain-forest {
  --dc: var(--forest);
}
.domain-sparks {
  --dc: var(--sparks);
}
.domain-glacier {
  --dc: var(--glacier);
}
.domain-volcano {
  --dc: var(--volcano);
}
.domain-ocean {
  --dc: var(--ocean);
}
.domain-wind {
  --dc: var(--wind);
}
.domain-wasteland {
  --dc: var(--wasteland);
}
.domain-stars {
  --dc: var(--stars);
}

/* ---- Shared parts ---- */
.gc-bg {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  overflow: hidden;
}
.gc-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.gc-ring {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  transition: box-shadow var(--transition);
}
.gc-type {
  font-family: var(--card-display);
}
.gc-glyph {
  position: absolute;
  display: block;
  color: color-mix(in srgb, var(--dc) 75%, white 15%);
  opacity: 0.7;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.8));
}
.gc-glyph svg {
  width: 100%;
  height: 100%;
}
.gc-overlay {
  position: absolute;
  background: rgba(0, 0, 0, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 5px;
  color: #fff;
  font-family: var(--card-display);
  font-weight: 700;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.game-card.copy-card .gc-overlay {
  color: var(--glacier);
  border-color: color-mix(in srgb, var(--glacier) 45%, transparent);
}
/* A face-down created creature has no domain and no art of its own. A copy
   token wears the copied card's face, so neither mark belongs on it. */
.game-card.token-card:not(.copy-card) {
  --dc: var(--text-dim);
}
.game-card.token-card:not(.copy-card) .gc-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 8px,
    rgba(255, 255, 255, 0.05) 8px,
    rgba(255, 255, 255, 0.05) 16px
  );
}

/* ---- Grain over the painted-in-CSS surfaces ---- */
.card-unit:not(.has-art) .gc-bg::before,
.card-full:not(.has-art) .gc-bg::before,
.card-full.art-only .gc-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.14;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* ---- Gems: a cut stone in a metal bezel, the number on top ---- */
.gc-gem {
  --bezel-hi: #f5e2a4;
  --bezel-mid: #b9893b;
  --bezel-lo: #3a260c;
  position: absolute;
  display: grid;
  place-items: center;
  /* The bezel and the stone are the pseudo-elements, stacked under the number. */
  isolation: isolate;
  font-family: var(--card-display);
  font-weight: 700;
  line-height: 1;
  color: #fff;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.9),
    0 0 6px rgba(0, 0, 0, 0.6);
}
.gc-gem::before,
.gc-gem::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
}
/* Spun metal, lit from the top-left. */
.gc-gem::before {
  inset: 0;
  background: conic-gradient(
    from 220deg,
    var(--bezel-lo),
    var(--bezel-mid) 14%,
    var(--bezel-hi) 25%,
    var(--bezel-mid) 38%,
    var(--bezel-lo) 55%,
    var(--bezel-mid) 68%,
    var(--bezel-hi) 78%,
    var(--bezel-mid) 88%,
    var(--bezel-lo)
  );
  box-shadow:
    0 0.1em 0.18em rgba(0, 0, 0, 0.7),
    inset 0 0 0 1px rgba(0, 0, 0, 0.35);
}
/* The stone: crown facets around a table that catches the light. */
.gc-gem::after {
  --stone-mid: 40%;
  --stone-edge: 100%;
  inset: 13%;
  background:
    radial-gradient(
      55% 40% at 36% 28%,
      rgba(255, 255, 255, 0.72),
      rgba(255, 255, 255, 0) 70%
    ),
    radial-gradient(
      circle at 50% 50%,
      color-mix(in srgb, var(--g) 78%, white) 0 30%,
      transparent 31%
    ),
    conic-gradient(
      from 0deg,
      rgba(255, 255, 255, 0.16) 0 60deg,
      rgba(0, 0, 0, 0.1) 60deg 120deg,
      rgba(0, 0, 0, 0.28) 120deg 180deg,
      rgba(0, 0, 0, 0.18) 180deg 240deg,
      rgba(255, 255, 255, 0.05) 240deg 300deg,
      rgba(255, 255, 255, 0.24) 300deg 360deg
    ),
    radial-gradient(
      circle at 50% 45%,
      color-mix(in srgb, var(--g) 70%, white) 0%,
      var(--g) var(--stone-mid),
      color-mix(in srgb, var(--g) 50%, black) var(--stone-edge)
    );
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.5),
    inset 0 -0.15em 0.25em rgba(0, 0, 0, 0.45),
    inset 0 0.08em 0.12em rgba(255, 255, 255, 0.35);
}
.gc-gem.gc-str {
  --g: var(--gem-str);
}
/* Energy is a crystal: the cost gem is cut as a hexagon. A clipped shape
   keeps no box-shadow, so this one wears a filter for its drop shadow. */
.gc-gem.gc-cost {
  --g: var(--gem-cost);
  filter: drop-shadow(0 0.1em 0.18em rgba(0, 0, 0, 0.7));
}
.gc-gem.gc-cost::before,
.gc-gem.gc-cost::after {
  border-radius: 0;
  clip-path: polygon(50% 0%, 94% 25%, 94% 75%, 50% 100%, 6% 75%, 6% 25%);
  box-shadow: none;
}
/* The clip takes the rim with it: the stone darkens to its edge instead. */
.gc-gem.gc-cost::after {
  --stone-mid: 32%;
  --stone-edge: 78%;
}
.gc-gem.gc-cost.cost-increased {
  --g: #ff5a5a;
}
.gc-gem.gc-cost.cost-decreased {
  --g: #7ee08a;
}

/* ---- Board unit ---- */
.game-card.card-unit {
  --w: 96px;
  width: var(--w);
  aspect-ratio: 3 / 4;
  border-radius: calc(var(--w) * 0.1);
}
/* The resting shadow lives on the ring so game.css's state glows still land. */
.card-unit .gc-ring {
  box-shadow:
    inset 0 0 0 2px color-mix(in srgb, var(--dc) 80%, white 10%),
    inset 0 0 0 3px rgba(0, 0, 0, 0.55),
    inset 0 -22px 26px -12px rgba(0, 0, 0, 0.75),
    0 6px 16px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.6);
}
.game-card.card-unit:hover {
  transform: translateY(-4px) scale(1.03);
}
.game-card.card-unit:hover .gc-ring {
  box-shadow:
    inset 0 0 0 2px color-mix(in srgb, var(--dc) 80%, white 10%),
    inset 0 0 0 3px rgba(0, 0, 0, 0.55),
    inset 0 -22px 26px -12px rgba(0, 0, 0, 0.75),
    0 12px 26px rgba(0, 0, 0, 0.6),
    0 0 18px color-mix(in srgb, var(--dc) 45%, transparent);
}
/* On every unit, art or not: a lazy image decodes over the domain colour
   instead of over a black hole. */
.card-unit .gc-bg {
  background:
    radial-gradient(
      120% 80% at 50% 110%,
      color-mix(in srgb, var(--dc) 55%, black) 0%,
      transparent 60%
    ),
    radial-gradient(
      90% 60% at 20% 0%,
      color-mix(in srgb, var(--dc) 35%, black) 0%,
      transparent 60%
    ),
    linear-gradient(160deg, #1d1d2a, #0b0b12);
}
.card-unit .gc-glyph {
  inset: 18% 20% 26%;
  color: color-mix(in srgb, var(--dc) 70%, white 15%);
  opacity: 0.75;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.7));
}
.card-unit .gc-type {
  position: absolute;
  bottom: 4%;
  left: 5%;
  width: 19%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  display: grid;
  place-items: center;
  color: var(--dc);
}
.card-unit .gc-type svg {
  width: 62%;
  height: 62%;
}
.card-unit .gc-type-label {
  display: none;
}
.card-unit .gc-gem.gc-str {
  width: 36%;
  aspect-ratio: 1;
  right: -8%;
  bottom: -8%;
  font-size: calc(var(--w) * 0.2);
}
.card-unit .gc-overlay {
  left: 5%;
  top: 5%;
  right: 30%;
  padding: 3px 4px;
  font-size: calc(var(--w) * 0.1);
}

/* ---- Tapped posture: a tilt, not a fade ---- */
.game-card.tapped {
  transform: rotate(9deg);
}
/* Only .gc-bg dims, so the gems, the type chip and the overlay — the parts
   that sit outside it — stay legible. The glyph is inside, and dims with it. */
.game-card.tapped .gc-bg {
  filter: saturate(0.35) brightness(0.7);
}
/* card.css loads last, so a tapped casualty needs the collapse restated here,
   as do the raised attacker and the card untapped ahead of its render. */
.game-card.tapped.beat-dead {
  transform: scale(0.8) rotate(8deg);
}
.game-card.tapped.beat-attack {
  transform: rotate(9deg) translateY(-8px);
}
.game-card.tapped.beat-untap {
  transform: rotate(0deg);
}
.game-card.tapped.beat-untap .gc-bg {
  filter: none;
}
.game-card.card-unit.tapped:hover {
  transform: rotate(9deg) translateY(-2px);
}

/* ---- Full card ---- */
.game-card.card-full {
  --w: 150px;
  width: var(--w);
  aspect-ratio: 815 / 1110;
  border-radius: calc(var(--w) * 0.045);
  font-size: calc(var(--w) * 0.06);
}
.card-full .gc-ring {
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.7),
    inset 0 0 0 2px rgba(255, 255, 255, 0.08),
    0 8px 22px rgba(0, 0, 0, 0.6);
}
.game-card.card-full:hover {
  transform: translateY(-10px);
  z-index: 5;
}
/* The lift replaces the whole transform, so the tilt has to ride along. */
.game-card.card-full.tapped:hover {
  transform: rotate(9deg) translateY(-10px);
}
.game-card.card-full:hover .gc-ring {
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.7),
    inset 0 0 0 2px rgba(255, 255, 255, 0.08),
    0 18px 40px rgba(0, 0, 0, 0.65),
    0 0 20px color-mix(in srgb, var(--dc) 40%, transparent);
}
.gc-name {
  position: absolute;
  left: 8%;
  top: 5%;
  /* A composited full.jpg paints its plate and pips: the name stops with it. */
  width: 70%;
  height: 10.5%;
  display: flex;
  align-items: center;
  overflow: hidden;
  font-family: var(--card-display);
  font-weight: 700;
  font-size: 1.05em;
  line-height: 1;
  letter-spacing: 0.01em;
  color: #f3efe4;
  text-shadow:
    0 1px 0 #000,
    0 0 8px rgba(0, 0, 0, 0.9);
}
.gc-text {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 54%;
  bottom: 9%;
  overflow: hidden;
  /* Centred in the plate; a text that fills the box starts at its top. */
  display: flex;
  flex-direction: column;
  justify-content: safe center;
  font-family: var(--card-body);
  font-size: 0.78em;
  line-height: 1.28;
  color: #e6e1d3;
  text-shadow: 0 1px 1px #000;
}
/* A framed card at thumbnail size is a silhouette: fade the overflow instead
   of cutting a line. */
.card-full:not(.card-zoom) .gc-text {
  mask-image: linear-gradient(to bottom, #000 70%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent);
}
.gc-text .card-para {
  align-items: flex-start;
  gap: 0.35em;
}
.gc-text .card-para + .card-para {
  margin-top: 0.45em;
}
/* The mock draws no bracket, only the paragraph's icon. */
.gc-text .card-para-bracket {
  width: 0.9em;
  padding: 0;
  opacity: 0.55;
}
.gc-text .card-para-bracket::before {
  display: none;
}
.gc-text .ability-icon {
  width: 0.9em;
  height: 0.9em;
}
.gc-text .stat-icon {
  width: 0.85em;
  height: 0.85em;
}
/* The mock sets the adapt and alt-cost lines apart under a hairline. */
.gc-text .card-para[data-kind="adaptation"],
.gc-text .card-para[data-kind="alt_cost"] {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: 0.35em;
  color: #cbd8cf;
  font-style: italic;
}
.card-full .gc-gem.gc-cost {
  width: 15%;
  aspect-ratio: 1;
  left: -3%;
  top: -3%;
  font-size: 1.25em;
}
.card-full .gc-gem.gc-str {
  width: 17%;
  aspect-ratio: 1;
  right: -3%;
  bottom: -3%;
  font-size: 1.35em;
}
.card-full .gc-type {
  position: absolute;
  left: 4%;
  bottom: 2.5%;
  max-width: 64%;
  display: flex;
  align-items: center;
  gap: 0.3em;
  overflow: hidden;
  white-space: nowrap;
  background: rgba(0, 0, 0, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 1em;
  padding: 0.15em 0.5em 0.15em 0.3em;
  color: var(--text-dim);
  font-family: var(--card-display);
  font-size: 0.7em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.card-full .gc-type svg {
  flex: none;
  width: 1.2em;
  height: 1.2em;
  color: var(--dc);
}
.card-full .gc-overlay {
  left: 6%;
  right: 6%;
  top: 15.5%;
  padding: 0.15em 0.4em;
  font-size: 0.72em;
}

/* ---- CSS frame: no full illustration to sit behind the text ---- */
.card-full .gc-bg {
  background:
    radial-gradient(
      80% 45% at 50% 32%,
      color-mix(in srgb, var(--dc) 40%, black) 0%,
      transparent 70%
    ),
    linear-gradient(
      170deg,
      color-mix(in srgb, var(--dc) 28%, #0e0e16) 0%,
      #0a0a12 55%,
      color-mix(in srgb, var(--dc) 18%, #0a0a12) 100%
    );
}
.gc-plate {
  position: absolute;
  pointer-events: none;
  background: rgba(8, 8, 12, 0.78);
  border-radius: 12% / 30%;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.07),
    0 0 0 3px color-mix(in srgb, var(--dc) 40%, transparent),
    0 0 14px rgba(0, 0, 0, 0.6);
}
/* Tall enough to hold .gc-name, which starts 1% lower than the plate does. */
.gc-plate-top {
  left: 6%;
  top: 4%;
  width: 88%;
  height: 11.5%;
}
.card-full:not(.has-art) .gc-name,
.card-full.art-only .gc-name {
  width: 84%;
}
.gc-plate-bottom {
  left: 7%;
  right: 7%;
  top: 51%;
  bottom: 5%;
  border-radius: 6% / 5%;
}
.card-full .gc-glyph {
  left: 22%;
  top: 17%;
  width: 56%;
  height: 32%;
}
.card-full.art-only .gc-window {
  position: absolute;
  left: 6%;
  right: 6%;
  top: 17%;
  height: 31%;
  overflow: hidden;
  border-radius: 4% / 6%;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.1),
    0 0 0 2px color-mix(in srgb, var(--dc) 40%, transparent);
}

/* ---- Hand card: the board portrait under a name bar, with the cost ----
   Built to match the approved mock (games.marqueewinq.xyz/conflux-hand-mock);
   the numbers below are the mock's. */
.game-card.card-hand {
  --w: 120px;
  --bar: linear-gradient(
    180deg,
    color-mix(in srgb, var(--dc) 72%, #141420),
    color-mix(in srgb, var(--dc) 44%, #0b0b14)
  );
  --bar-edge:
    inset 0 -1px 0 color-mix(in srgb, var(--dc) 85%, white 15%),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
  aspect-ratio: 3 / 4.6;
}
/* The portrait keeps the board's 3:4 under a bar that takes the top 13%. */
.card-hand .gc-bg {
  top: 13%;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
.card-hand .gc-name {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  left: 0;
  right: 0;
  top: 0;
  width: auto;
  height: 13%;
  padding: 0 5% 0 27%;
  box-sizing: border-box;
  border-radius: inherit;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  background: var(--bar);
  box-shadow: var(--bar-edge);
  font-family: var(--card-display);
  font-weight: 700;
  font-size: calc(var(--w) * 0.082);
  line-height: 1.05;
  letter-spacing: 0.01em;
  text-align: center;
  color: #fbf8f0;
  text-shadow:
    0 1px 0 rgba(0, 0, 0, 0.9),
    0 0 6px rgba(0, 0, 0, 0.7);
  overflow: hidden;
}
/* The cost gem mirrors the strength gem: same size, same overhang. */
.card-hand .gc-gem.gc-cost {
  width: 36%;
  aspect-ratio: 1;
  left: -8%;
  top: -7%;
  font-size: calc(var(--w) * 0.19);
  z-index: 1;
}
/* The type tab hangs off the gem, the icon a little below the gem's point. */
.card-hand .gc-type {
  left: 1%;
  top: 12.5%;
  bottom: auto;
  width: 18%;
  height: 16.2%;
  aspect-ratio: auto;
  place-items: start center;
  padding-top: calc(var(--w) * 0.103);
  box-sizing: border-box;
  overflow: hidden;
  border-radius: 0 0 30% 30% / 0 0 22% 22%;
  background: var(--bar);
  box-shadow:
    var(--bar-edge),
    0 2px 6px rgba(0, 0, 0, 0.5);
  color: #fbf8f0;
}
.card-hand .gc-type svg {
  width: 58%;
  height: auto;
  aspect-ratio: 1;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.8));
}
/* The text's paragraph kinds in one strip off the bottom-left corner. */
.card-hand .gc-kinds {
  position: absolute;
  left: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--w) * 0.03);
  width: calc(var(--w) * 0.18 - 1px);
  padding: calc(var(--w) * 0.045) 0 calc(var(--w) * 0.055);
  box-sizing: border-box;
  overflow: hidden;
  border-radius: 0 calc(var(--w) * 0.06) 0 calc(var(--w) * 0.1);
  background: var(--bar);
  box-shadow:
    var(--bar-edge),
    0 2px 6px rgba(0, 0, 0, 0.5);
  color: #fbf8f0;
}
.card-hand .gc-kinds:empty {
  display: none;
}
.card-hand .gc-kind {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
}
.card-hand .gc-kind svg {
  width: 58%;
  height: 58%;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.8));
}
/* Texture: grain and a faint brushed weave over the bar, the tab and the strip. */
.card-hand .gc-name::after,
.card-hand .gc-type::after,
.card-hand .gc-kinds::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    repeating-linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.07) 0 1px,
      transparent 1px 4px
    );
  opacity: 0.45;
  mix-blend-mode: overlay;
}
.card-hand .gc-overlay {
  left: 30%;
  right: 5%;
  top: 16%;
}
.card-hand .gc-glyph {
  inset: 30% 20% 26%;
}
/* The labels an inlined zone card carries: clear of the bar, the tab and the gem. */
.card-hand .zone-origin-label {
  left: auto;
  right: 4%;
  top: 16%;
  bottom: auto;
}
.card-hand .playable-cost-label {
  right: 4%;
  bottom: 30%;
}

/* ---- Size tokens the callers ask for by name ---- */
.game-card.card-size-grid {
  --w: 170px;
}
.game-card.card-size-row {
  --w: 120px;
}
.game-card.card-size-trigger {
  --w: 120px;
}

/* ---- Zoom: the reading surface, so nothing here may clip ---- */
.game-card.card-zoom {
  --w: min(360px, 92vw);
}
.game-card.card-zoom:hover {
  transform: none;
}
/* Sizes measured against the longest text in the library: nothing may clip. */
.card-zoom .gc-text {
  top: 44%;
  bottom: 7%;
  left: 9%;
  right: 9%;
  font-size: 0.66em;
  line-height: 1.28;
}
/* A composited full.jpg paints its plate from 50% to 93%: the box sits
   symmetrically inside it, so a centred text lands on the plate's middle. */
.card-zoom.has-art:not(.art-only) .gc-text {
  top: 52%;
  bottom: 8%;
  font-size: 0.7em;
}
.card-zoom .gc-plate-bottom {
  top: 41%;
}
.card-zoom.art-only .gc-window {
  height: 21%;
}
.card-zoom:not(.has-art) .gc-glyph {
  height: 22%;
}
/* The board tilts and dims a tapped card; the zoom of it is read, not fought. */
.game-card.card-zoom.tapped {
  transform: none;
}
.game-card.card-zoom.tapped .gc-bg {
  filter: none;
}
/* The layer the hover zoom is drawn into: over everything, under no pointer. */
.card-zoom-layer {
  position: fixed;
  z-index: 120;
  pointer-events: none;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.65));
}
.card-zoom-layer.hidden {
  display: none;
}

/* ---- Board furniture that predates the card and has to sit on it ---- */
/* Outlines, not box-shadows: game.css paints `blocking`, `target-selected`
   and `beat-hit` with a shadow at one class, and card.css loads after it. */
.game-card.being-played-card {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.game-card.selected {
  outline: 2px solid var(--gold);
  outline-offset: -1px;
  filter: drop-shadow(0 0 10px rgba(233, 196, 106, 0.55));
}
.game-card.card-unit .btn-ability,
.game-card.card-unit .blocker-badge {
  left: 5%;
  right: 5%;
  top: auto;
  bottom: 24%;
  border-radius: 4px;
  padding: 2px 0;
  font-size: calc(var(--w) * 0.12);
}
.card-full .playable-cost-label {
  right: 4%;
  bottom: 16%;
}
.card-full .zone-origin-label {
  left: 6%;
  right: auto;
  top: auto;
  bottom: 16%;
}
/* The zoom is the reading surface; nothing else may sit on its text. */
.card-zoom .playable-cost-label,
.card-zoom .zone-origin-label {
  display: none;
}

/* ---- Mobile ---- */
@media (max-width: 768px) {
  /* Four of these fit a 390px phone; both sides the same size, so the board
     is read by comparing them. */
  .game-card.card-unit {
    --w: 78px;
  }
  /* Hand, mulligan grid and the opponent's open hand alike. */
  .game-card.card-hand {
    --w: 96px;
  }
  .game-card.card-size-grid {
    --w: 120px;
  }
  .game-card.card-size-row {
    --w: 92px;
  }
  .game-card.card-size-trigger {
    --w: 100px;
  }
  /* Last: a zoom is parented to no zone, so it may not inherit a zone width. */
  .game-card.card-zoom {
    --w: min(360px, 92vw);
  }
}
