:root {
  /* wine-dark sea → a deep-blue voyage; cream + gold stay as the brand ink */
  --bg: #0a1f34;
  --bg-mid: #123f60;
  --bg-high: #1c5e82;
  --cream: #f4e9d4;
  --cream-dim: #d8c6a8;
  --gold: #d9b36a;
  --coral: #f4907e;
  --wine: rgba(8, 24, 40, 0.7);
  --wine-deep: rgba(4, 16, 28, 0.6);
  --ink: #2b3a67;
  --red: #e05656;
  /* Latin uses Georgia; Thai glyphs fall through to Noto Serif Thai */
  --serif: Georgia, "Noto Serif Thai", "Times New Roman", serif;
  --spring: cubic-bezier(0.22, 1.4, 0.36, 1);
  --spring-hard: cubic-bezier(0.22, 1.75, 0.4, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* visually hidden, still read by assistive tech */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

html, body { height: 100%; }

body {
  font-family: var(--serif);
  overflow: hidden;
  background: var(--bg);
  color: var(--cream);
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  padding: clamp(14px, 2.6vh, 30px) clamp(18px, 3.5vw, 52px) 46px;
}

/* ---- preloader: a ship rocking out to sea while assets load ---- */
#preloader {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 90% at 50% 30%, #123f60, transparent 70%),
    #0a1f34;
  transition: opacity 0.6s ease, visibility 0.6s ease;
}
#preloader.done { opacity: 0; visibility: hidden; }
.pl-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  animation: pl-rise 0.6s var(--spring);
}
@keyframes pl-rise { from { opacity: 0; transform: translateY(10px); } }
.pl-lockup b {
  display: block;
  font-size: clamp(16px, 3vw, 20px);
  letter-spacing: 3px;
  color: var(--cream);
  text-align: center;
}
.pl-lockup i {
  display: block;
  font-size: 10px;
  letter-spacing: 4px;
  color: var(--cream-dim);
  text-align: center;
  margin-top: 2px;
}
.pl-title {
  font-family: "Arial Rounded MT Bold", "Avenir Next", "Helvetica Neue", sans-serif;
  font-weight: bold;
  font-size: clamp(44px, 11vw, 60px);
  color: var(--coral);
  line-height: 1;
  margin: 4px 0 6px;
}
.pl-sea {
  position: relative;
  width: 180px;
  height: 100px;
  overflow: hidden;
}
.pl-ship {
  position: absolute;
  left: 50%;
  bottom: 26px;
  width: 84px;
  height: auto;
  transform: translateX(-50%);
  transform-origin: 50% 90%;
  animation: pl-bob 2.4s ease-in-out infinite;
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.4));
}
@keyframes pl-bob {
  0%, 100% { transform: translateX(-50%) translateY(0) rotate(-5deg); }
  50%      { transform: translateX(-50%) translateY(-6px) rotate(5deg); }
}
.pl-waves {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 40px;
}
.pl-waves svg {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 200%;
  height: 40px;
  display: block;
}
.pl-waves .w1 { animation: pl-drift 3s linear infinite; }
.pl-waves .w2 { animation: pl-drift 4.4s linear infinite reverse; }
.pl-waves svg:first-child { opacity: 0.7; }
@keyframes pl-drift { to { transform: translateX(-25%); } }
.pl-load {
  font-family: var(--serif);
  font-size: 14px;
  letter-spacing: 0.5px;
  color: var(--gold);
}
.pl-load i { font-style: normal; animation: pl-dot 1.4s infinite; }
.pl-load i:nth-child(2) { animation-delay: 0.2s; }
.pl-load i:nth-child(3) { animation-delay: 0.4s; }
@keyframes pl-dot { 0%, 100% { opacity: 0.2; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .pl-ship, .pl-waves .w1, .pl-waves .w2, .pl-load i, .pl-inner { animation: none; }
}

/* ---- painterly wine-dark sea, like the Beat promo ----
   The swirl texture is baked ONCE into a background image by fx.bakeBackground()
   (live SVG filters re-rasterize every frame and scale with pixel area).
   The layers below only animate cheap composited transforms. */
.felt {
  position: fixed;
  inset: -20%;
  z-index: 0;
  background: #0b2438 center / cover no-repeat;
}
.felt::before {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.45; /* the bake already carries these swells; this layer adds drift */
  background:
    radial-gradient(60% 50% at 22% 28%, var(--bg-high) 0%, transparent 60%),
    radial-gradient(50% 60% at 76% 18%, #1c6187 0%, transparent 55%),
    radial-gradient(55% 45% at 62% 74%, var(--bg-mid) 0%, transparent 60%),
    radial-gradient(45% 55% at 8% 86%, var(--bg-high) 0%, transparent 55%),
    radial-gradient(70% 40% at 50% 100%, #04121e 0%, transparent 70%);
  animation: drift 30s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(3%, -2%) scale(1.08); }
}
/* scattered stars */
.felt::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle 1.6px at 12% 18%, rgba(255,250,240,0.8), transparent 60%),
    radial-gradient(circle 1.1px at 28% 64%, rgba(255,250,240,0.55), transparent 60%),
    radial-gradient(circle 1.9px at 41% 32%, rgba(255,250,240,0.7), transparent 60%),
    radial-gradient(circle 1.2px at 55% 79%, rgba(255,250,240,0.5), transparent 60%),
    radial-gradient(circle 1.5px at 63% 12%, rgba(255,250,240,0.75), transparent 60%),
    radial-gradient(circle 1.1px at 72% 48%, rgba(255,250,240,0.5), transparent 60%),
    radial-gradient(circle 1.8px at 84% 26%, rgba(255,250,240,0.7), transparent 60%),
    radial-gradient(circle 1.2px at 91% 68%, rgba(255,250,240,0.55), transparent 60%),
    radial-gradient(circle 1.4px at 18% 88%, rgba(255,250,240,0.6), transparent 60%),
    radial-gradient(circle 1.3px at 47% 55%, rgba(255,250,240,0.45), transparent 60%);
  animation: drift 44s ease-in-out infinite alternate-reverse;
}

/* ---- masthead, like the promo poster ---- */
.masthead {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.lockup b {
  display: block;
  font-size: clamp(22px, 2.6vw, 34px);
  font-weight: normal;
  letter-spacing: 3px;
  color: var(--cream);
}
.lockup i {
  display: block;
  font-size: clamp(11px, 1.2vw, 15px);
  letter-spacing: 4px;
  color: var(--cream-dim);
  margin: 2px 0 0 3px;
}
/* player badge (top-right, was the "Beat" wordmark) */
.brand {
  text-align: right;
  line-height: 1.2;
  max-width: 45vw;
}
.brand span {
  display: block;
  font-size: clamp(10px, 1vw, 11px);
  color: var(--gold);
}
.brand b {
  display: block;
  font-weight: normal;
  font-size: clamp(19px, 2.2vw, 28px);
  color: var(--coral);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- centered board ---- */
.stage {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 8px 0;
  transition: filter 0.6s ease;
}
/* Athena's god-mode: a divine owl-blue aura over the board */
.stage.athena { filter: drop-shadow(0 0 26px rgba(150, 185, 230, 0.55)); }
/* the Sirens' superboss: a violet lure aura over the board */
.stage.siren { filter: drop-shadow(0 0 24px rgba(201, 139, 192, 0.5)); }
.caption.athena h2 {
  color: #d7e6f7;
  text-shadow: 0 0 16px rgba(150, 185, 230, 0.8);
}

/* ---- caption band with inline HUD ---- */
.caption {
  position: relative;
  z-index: 2;
  text-align: center;
  padding-top: 10px;
}
.caption h2 {
  font-size: clamp(18px, 2vw, 25px);
  font-weight: normal;
  letter-spacing: 0.5px;
  color: var(--cream);
  text-wrap: balance;
}
.caption-thai {
  font-size: clamp(12px, 1.3vw, 15px);
  line-height: 1.4;
  color: var(--cream-dim);
  margin-top: 3px;
}

/* ---- HUD rail: labels on one line, values on a shared baseline ----
   Every stat shares the same two-row footprint (10px label + 30px value box)
   so labels align across the row and every value sits on one baseline — the
   ×Favor pills included. Numbers are tabular so they never jitter as they tick. */
.hudbar {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(13px, 2.1vw, 28px);
  margin-top: 18px;
}
.hud-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}
.hud-item span {
  font-size: 11px;
  line-height: 1.25;
  color: var(--gold);
}
.hud-item b {
  font-size: 22px;
  font-weight: normal;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
/* shared value box → one baseline for plain numbers and the pill cluster alike */
.hud-item b,
.hud-mult .mult {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 34px; /* matches the tallest value (the pills) so labels align too */
  line-height: 1;
}
.hud-mult .mult { gap: 7px; }
.mult-chips, .mult-mult {
  min-width: 42px;
  border-radius: 8px;
  padding: 5px 9px;
  font-size: 17px;
  font-weight: normal;
  line-height: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: transform 0.18s var(--spring-hard);
}
.hudbar .mult-chips {
  background: var(--cream);
  color: #123f60;
}
.hudbar .mult-mult {
  background: #a12437;
  color: var(--cream);
  border: 1px solid rgba(217, 179, 106, 0.4);
}
.mult-x { font-style: normal; color: var(--gold); font-size: 15px; }
.mult-chips.bump, .mult-mult.bump { transform: scale(1.18); }

/* divider between the stat rail and the action controls */
.hud-sep {
  align-self: center;
  width: 1px;
  height: 40px;
  background: linear-gradient(transparent, rgba(217, 179, 106, 0.55), transparent);
}
.hudbar .btn-new, .hudbar .btn-icon { align-self: center; }

/* ---- page footer + frieze ---- */
.pagefoot {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding-top: 14px;
}
.thai-title { font-size: clamp(14px, 1.6vw, 19px); color: var(--cream); }
.credit {
  font-size: 11px;
  color: var(--cream-dim);
  margin-right: 110px; /* clear the draw pile */
}

.meander {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 38px;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  border-top: 1px solid rgba(217, 179, 106, 0.5);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 36 36'%3E%3Cpath d='M2 32 V8 H30 V24 H14 V16 H22' fill='none' stroke='%23d9b36a' stroke-width='3'/%3E%3C/svg%3E");
  background-repeat: repeat-x;
  background-position: left center;
  background-color: rgba(4, 16, 28, 0.35);
}

/* icon buttons in the HUD (home, mute) */
.btn-icon {
  appearance: none;
  flex: 0 0 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid rgba(217, 179, 106, 0.5);
  color: var(--cream);
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.15s var(--spring-hard), background 0.2s, border-color 0.2s;
}
.btn-icon:hover { transform: translateY(-2px); background: rgba(217, 179, 106, 0.12); border-color: var(--gold); }
.btn-icon svg { width: 22px; height: 22px; display: block; }
/* mute-specific: the slash + wave crossfade */
#muteBtn .slash {
  stroke-dasharray: 26;
  stroke-dashoffset: 26; /* hidden until muted */
  transition: stroke-dashoffset 0.2s ease;
}
#muteBtn.muted { opacity: 0.6; color: var(--cream-dim); }
#muteBtn.muted .wave { opacity: 0; }
#muteBtn.muted .slash { stroke-dashoffset: 0; }
#muteBtn .wave { transition: opacity 0.2s ease; }

.btn-new {
  appearance: none;
  border: 0;
  background: var(--gold);
  color: #0a1f34;
  font-family: var(--serif);
  font-size: 17px;
  letter-spacing: 0.5px;
  padding: 12px;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s var(--spring-hard), background 0.2s;
}
.btn-new:hover { transform: translateY(-2px) scale(1.03); background: #e8c684; }
.btn-new:active { transform: translateY(1px); }

/* ---- board ---- */
.grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(10px, 1.6vw, 20px);
  /* width bounded by viewport height (dvh: excludes the mobile toolbar) so
     3 rows always fit above the caption */
  width: min(600px, 92vw, calc((100dvh - 320px) / 1.12));
}
/* the Trials: 6 sets dealt as triples → 18 cards in a 6×3 grid.
   still 3 rows, so height is bounded like the voyage but wider (×1.5 for 6 cols);
   the larger reservation leaves room for the caption + Blessings band below */
.grid.trials {
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(8px, 1.2vw, 16px);
  width: min(840px, 96vw, calc((100dvh - 430px) / 1.12 * 1.5));
}

.cell {
  perspective: 900px;
  aspect-ratio: 2 / 3; /* matches the Beat card proportions */
  contain: layout style;
}
.cell:hover { z-index: 5; } /* lifted card rides above its neighbors */

.card {
  position: relative;
  width: 100%;
  height: 100%;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transform: translateY(var(--lift, 0px)) scale(var(--zoom, 1))
             rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.45s var(--spring);
  transform-style: preserve-3d;
  animation: wobble 3.4s ease-in-out infinite;
  animation-delay: var(--wobble-delay, 0s);
}
/* promote to its own layer only while it actually moves — idle cards stay
   un-promoted so the board doesn't hold ~2 GPU layers per card at rest */
.card:hover, .card:focus-visible, .card.up, .card.peek, .card.matched {
  will-change: transform;
}
@keyframes wobble {
  0%   { rotate: -0.8deg; translate: 0 0; }
  50%  { rotate:  0.8deg; translate: 0 -2px; }
  100% { rotate: -0.8deg; translate: 0 0; }
}
/* Balatro hand-feel: grow + lift instantly, spring back on leave */
.card:hover,
.card:focus-visible {
  animation-play-state: paused;
  --lift: -5px;
  --zoom: 1.06;
  transition-duration: 0.07s;
  transition-timing-function: ease-out;
}
.card { outline: none; }
/* keyboard focus ring — sits on the visible face, follows the flip */
.card:focus-visible .face {
  box-shadow: -5px 10px 16px rgba(0,0,0,0.38),
              0 0 0 3px var(--gold), 0 0 14px rgba(217,179,106,0.6);
}

.flip {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transition: transform 0.55s var(--spring);
}
.card.up .flip, .card.peek .flip, .card.matched .flip { will-change: transform; }
.card.up .flip {
  transform: rotateY(180deg);
  animation: flip-stretch 0.55s var(--spring);
}
/* squash & stretch layered over the rotate (scale composites with transform) */
@keyframes flip-stretch {
  0%   { scale: 1 1; }
  40%  { scale: 1.09 0.91; }
  70%  { scale: 0.96 1.04; }
  100% { scale: 1 1; }
}

.face {
  position: absolute;
  inset: 0;
  border-radius: 10px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  box-shadow: -3px 4px 0 rgba(0,0,0,0.28);
  transition: box-shadow 0.2s ease;
}
.card:hover .face { box-shadow: -5px 10px 16px rgba(0,0,0,0.38); }

/* foil sheen that tracks the cursor, Balatro holo-card style */
.face::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    circle at var(--mx, 50%) var(--my, 50%),
    rgba(255, 250, 235, 0.2) 0%,
    rgba(255, 250, 235, 0) 45%
  );
  opacity: 0;
  transition: opacity 0.25s ease;
}
.card:hover .face::before { opacity: 1; }

/* card back — real Beat edition artwork (the ship on stormy seas).
   WebP with a JPEG fallback; the crimson underneath shows if both fail. */
.face.back {
  background: url("assets/back.jpg") center / cover no-repeat, #0b2438;
  background: image-set(
      url("assets/back.webp") type("image/webp"),
      url("assets/back.jpg") type("image/jpeg")
    ) center / cover no-repeat, #0b2438;
  background-size: cover;
}
/* the printed back carries its own title/frame, so drop the CSS chrome */
.face.back::after { display: none; }
.back-title { display: none; }
.back-title {
  text-align: center;
  color: #f2d9a0;
  font-family: var(--serif);
  font-size: clamp(11px, 1.5vw, 16px);
  letter-spacing: 1px;
  line-height: 1.15;
  text-shadow: 0 2px 3px rgba(0,0,0,0.5);
  padding: 4px;
}
.back-title small {
  display: block;
  font-style: italic;
  font-size: 0.7em;
  letter-spacing: 2px;
}
.back-title span {
  display: block;
  margin-top: 6px;
  font-size: 0.72em;
  font-family: inherit;
  opacity: 0.9;
}

/* card front — per-character themed frame
   --c1: banner/plaque  --c2: frame  --c3/--c4: art background */
.face.front {
  background: linear-gradient(165deg, var(--c3), var(--c4));
  border: 4px solid var(--c2);
  transform: rotateY(180deg);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 7px;
}
.face.front::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid color-mix(in srgb, var(--c1) 45%, transparent);
  border-radius: 5px;
  pointer-events: none;
}

.banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  background: var(--c1);
  color: #fff;
  border-radius: 6px;
  padding: 3px 5px 3px 8px;
  font-family: var(--serif);
  font-size: clamp(11px, 1.4vw, 16px);
  letter-spacing: 0.5px;
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.25);
}
.numeral {
  flex: 0 0 auto;
  width: 1.6em;
  height: 1.6em;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.6);
  background: rgba(255,255,255,0.16);
  font-size: 0.78em;
}

.art {
  flex: 1;
  display: grid;
  place-items: center;
  font-size: clamp(30px, 5.5vw, 56px);
  filter: drop-shadow(0 4px 4px rgba(0,0,0,0.3));
}
.art-img {
  flex: 1;
  min-height: 0;
  width: 100%;
  object-fit: cover;
  border-radius: 5px;
}

.plaque {
  background: var(--c1);
  color: #fff;
  border-radius: 6px;
  text-align: center;
  padding: 4px 2px;
  font-family: var(--serif);
  font-size: clamp(8px, 1vw, 12px);
  letter-spacing: 0.5px;
  line-height: 1.15;
  box-shadow: inset 0 -2px 0 rgba(0,0,0,0.25);
}
.plaque small {
  display: block;
  font-style: italic;
  font-size: 0.8em;
}
.plaque span {
  display: block;
  font-size: 0.85em;
  opacity: 0.9;
}
.plaque i {
  display: block;
  font-size: 0.7em;
  font-style: normal;
  opacity: 0.75;
  margin-top: 1px;
}

/* full-card artwork mode — the image IS the card face */
.face.front.photo {
  padding: 0;
  border: 0;
  background: none;
}
.face.front.photo::after { display: none; }
.face.front.photo .banner,
.face.front.photo .plaque { display: none; }
.face.front.photo .art-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 10px;
  object-fit: cover;
}

/* character palettes, sampled from the Beat cards */
.card.t-odysseus { --c1: #b8452f; --c2: #a8cfe0; --c3: #f6fbfd; --c4: #cfe6f0; }
.card.t-odysseus .banner { background: #f6fbfd; color: #b8452f; box-shadow: inset 0 0 0 1px #a8cfe0; }
.card.t-odysseus .numeral { border-color: #b8452f66; background: #b8452f14; }
.card.t-athene   { --c1: #8e1f2a; --c2: #d98a3d; --c3: #f7dfb8; --c4: #e8a86a; }
.card.t-poseidon { --c1: #1c2b57; --c2: #3f7fae; --c3: #bfe2ea; --c4: #2e6b9e; }
.card.t-circe    { --c1: #6a3f8c; --c2: #c98bc0; --c3: #f4e3f2; --c4: #d8a8d4; }
.card.t-cyclopes { --c1: #7a1030; --c2: #d94f3d; --c3: #f4b98a; --c4: #c9503a; }
.card.t-skylla   { --c1: #1d5c34; --c2: #6fae63; --c3: #dcedc8; --c4: #8cbf72; }

/* matched */
.card.matched { cursor: default; }
.card.matched .flip { animation: match-pop 0.5s var(--spring-hard); }
.card.matched .face.front {
  box-shadow:
    -3px 4px 0 rgba(0,0,0,0.28),
    0 0 0 3px var(--gold),
    0 0 24px rgba(255, 182, 74, 0.55);
}
@keyframes match-pop {
  0%   { scale: 1; }
  45%  { scale: 1.16; }
  100% { scale: 1; }
}

/* ---- divine foil: a matched god's cards shimmer rainbow holo,
   "ready to grant a blessing", until the blessing is spent ---- */
.card.blessed .face.front::after {
  content: "";
  display: block;
  position: absolute;
  inset: 0;
  z-index: 3;
  border-radius: inherit;
  pointer-events: none;
  border: 0;
  background:
    linear-gradient(115deg,
      transparent 12%,
      rgba(255, 60, 170, 0.55) 28%,
      rgba(255, 216, 77, 0.55) 40%,
      rgba(85, 255, 190, 0.55) 52%,
      rgba(80, 170, 255, 0.55) 64%,
      rgba(190, 90, 255, 0.55) 76%,
      transparent 92%);
  background-size: 260% 260%;
  mix-blend-mode: screen;
  opacity: 0.75;
  /* vivid rainbow foil, but per-card duration + phase (set in JS) so the
     cards don't all shimmer in lockstep */
  animation: holo-shift var(--holo-dur, 3.4s) linear infinite;
  animation-delay: var(--holo-delay, 0s);
  transition: opacity 0.5s ease;
}
/* a second sweeping specular streak for the "วิ๊ง" sparkle */
.card.blessed .face.front::before {
  background:
    radial-gradient(circle at var(--mx, 50%) var(--my, 50%),
      rgba(255, 250, 235, 0.25) 0%, rgba(255, 250, 235, 0) 45%),
    linear-gradient(60deg, transparent 40%, rgba(255,255,255,0.5) 50%, transparent 60%);
  background-size: auto, 250% 250%;
  opacity: 1;
  animation: holo-sweep var(--holo-dur, 3.4s) linear infinite;
  animation-delay: var(--holo-delay, 0s);
}
.card.blessed .face.front { box-shadow: -3px 4px 0 rgba(0,0,0,0.28), 0 0 0 2px var(--gold), 0 0 22px rgba(150, 220, 255, 0.6); }
@keyframes holo-shift {
  0%   { background-position: 0% 50%; }
  100% { background-position: 260% 50%; }
}
@keyframes holo-sweep {
  0%   { background-position: 50% 50%, 200% 0%; }
  100% { background-position: 50% 50%, -60% 0%; }
}
/* fading out when the blessing is spent */
.card.unblessing .face.front::after { opacity: 0; }
.card.unblessing .face.front::before { animation: none; opacity: 0; }

/* Odysseus the hero — a warm gold-bronze glint on match (distinct from the gods' rainbow foil) */
.card.hero .face.front {
  box-shadow:
    -3px 4px 0 rgba(0,0,0,0.28),
    0 0 0 2px var(--gold),
    0 0 22px rgba(217, 179, 106, 0.7),
    inset 0 0 22px rgba(214, 160, 74, 0.32);
}
.card.hero .face.front::after {
  content: "";
  display: block;
  position: absolute;
  inset: 0;
  z-index: 3;
  border: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(60deg,
    transparent 42%,
    rgba(255, 240, 200, 0.85) 49%,
    rgba(255, 216, 130, 0.95) 50%,
    rgba(255, 240, 200, 0.85) 51%,
    transparent 58%);
  background-size: 250% 250%;
  mix-blend-mode: screen;
  opacity: 0; /* invisible at rest — only the box-shadow glow stays after the sweep */
  animation: hero-gleam 1s ease-out 0.15s 2 forwards; /* sweep twice, then fade out */
}
@keyframes hero-gleam {
  0%   { background-position: 200% 0%; opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { background-position: -60% 0%; opacity: 0; }
}

/* mismatch shake */
.card.shake { animation: shake 0.4s ease-in-out; }
@keyframes shake {
  0%, 100% { translate: 0 0; }
  20% { translate: -7px 0; rotate: -2deg; }
  40% { translate: 7px 0; rotate: 2deg; }
  60% { translate: -5px 0; }
  80% { translate: 5px 0; }
}

/* ---- draw pile ---- */
.deck {
  position: fixed;
  right: 34px;
  bottom: 58px;
  z-index: 3;
  width: 76px;
  height: 114px;
}
.deck-card {
  position: absolute;
  inset: 0;
  border-radius: 8px;
  border: 3px solid #d9b36a;
  background: url("assets/back.jpg") center / cover no-repeat, #0b2438;
  background: image-set(
      url("assets/back.webp") type("image/webp"),
      url("assets/back.jpg") type("image/jpeg")
    ) center / cover no-repeat, #0b2438;
  background-size: cover;
  box-shadow: -2px 3px 0 rgba(0,0,0,0.3);
  transition: opacity 0.3s ease;
}
.deck-card:nth-child(1) { transform: translate(6px, 6px) rotate(2deg); }
.deck-card:nth-child(2) { transform: translate(3px, 3px) rotate(-1.5deg); }
.deck-count {
  position: absolute;
  right: -8px;
  bottom: -10px;
  background: #0a1f34;
  color: var(--cream);
  border: 1px solid var(--gold);
  border-radius: 999px;
  padding: 4px 9px;
  font-size: 13px;
  box-shadow: 0 6px 14px rgba(0,0,0,0.4);
}
.deck.empty .deck-card { opacity: 0.15; }

.deck.shuffling .deck-card:nth-child(1) { animation: shuf-a 0.15s ease-in-out 4 alternate; }
.deck.shuffling .deck-card:nth-child(2) { animation: shuf-b 0.13s ease-in-out 4 alternate; }
.deck.shuffling .deck-card:nth-child(3) { animation: shuf-c 0.16s ease-in-out 4 alternate; }
@keyframes shuf-a { to { transform: translate(18px, -5px) rotate(10deg); } }
@keyframes shuf-b { to { transform: translate(-15px, 3px) rotate(-9deg); } }
@keyframes shuf-c { to { transform: translate(9px, -9px) rotate(6deg); } }

/* ---- screen shake (on the board only, HUD stays still) ---- */
.stage.shake-sm { animation: st-sm 0.12s ease-out; }
.stage.shake-md { animation: st-md 0.22s ease-out; }
.stage.shake-lg { animation: st-lg 0.32s ease-out; }
@keyframes st-sm {
  30% { translate: 2px 1px; }
  60% { translate: -2px -1px; }
}
@keyframes st-md {
  20% { translate: -5px 2px; rotate: -0.3deg; }
  45% { translate: 5px -2px; rotate: 0.3deg; }
  70% { translate: -3px 1px; }
}
@keyframes st-lg {
  15% { translate: -8px 3px; rotate: -0.5deg; }
  35% { translate: 8px -3px; rotate: 0.5deg; }
  55% { translate: -6px 2px; }
  75% { translate: 4px -1px; }
}

/* ---- gold chips flying to the score ---- */
.chip-fly {
  position: fixed;
  z-index: 45;
  width: 13px;
  height: 13px;
  margin: -7px 0 0 -7px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #f4e9d4, #d9b36a 55%, #a17a35);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ---- particle canvas ---- */
.fx-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 48;
  pointer-events: none;
}

/* ---- streak heat: the room warms as the mult climbs ---- */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(120% 80% at 50% 105%, rgba(244, 110, 60, 0.3), transparent 60%);
  opacity: var(--heat, 0);
  transition: opacity 0.7s ease;
}
.hudbar .mult-mult {
  transition: transform 0.18s var(--spring-hard), box-shadow 0.4s ease;
  box-shadow: 0 0 calc(var(--heat, 0) * 18px) rgba(244, 144, 126, calc(var(--heat, 0) * 0.9));
}

/* HUD numbers punch when they change */
.hud-item b { transition: transform 0.18s var(--spring-hard); }
.hud-item b.bump { transform: scale(1.22); }

/* ---- altar of blessings — a prominent band under the caption ---- */
.altar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 2vw, 20px);
  margin: 0;
  padding: 6px 18px;
  border: 1px solid rgba(217, 179, 106, 0.4);
  border-radius: 999px;
  background:
    radial-gradient(140% 180% at 50% 0%, rgba(217, 179, 106, 0.16), transparent 70%),
    rgba(9, 26, 44, 0.55);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35), inset 0 0 16px rgba(217, 179, 106, 0.12);
  animation: altar-in 0.5s var(--spring-hard);
}
.altar[hidden] { display: none; }
@keyframes altar-in { from { opacity: 0; transform: translateY(8px) scale(0.96); } }
.altar-label {
  font-size: 13px;
  color: var(--gold);
}
.altar-slots { display: flex; gap: clamp(10px, 1.6vw, 16px); }
.bless {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 60px;
  padding: 2px;
  border: 0;
  background: none;
  color: var(--gold);
  cursor: pointer;
  transition: transform 0.15s var(--spring-hard);
}
.bless svg {
  width: 44px;
  height: 44px;
  padding: 9px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: rgba(217, 179, 106, 0.14);
  box-shadow: 0 0 12px rgba(217, 179, 106, 0.4);
  transition: box-shadow 0.3s ease, background 0.2s;
}
.bless-name { font-size: 11px; color: var(--cream-dim); }
.bless[hidden] { display: none; }
.bless:hover:not(.spent) { transform: translateY(-3px); }
.bless:hover:not(.spent) svg {
  background: rgba(217, 179, 106, 0.24);
  box-shadow: 0 0 20px rgba(217, 179, 106, 0.7);
}
.bless.arrive { animation: bless-in 0.5s var(--spring-hard); }
@keyframes bless-in { from { scale: 0; rotate: -40deg; } }
.bless.spent { cursor: default; opacity: 0.5; }
.bless.spent svg {
  color: #8a7c6b;
  border-color: rgba(138, 124, 107, 0.35);
  background: rgba(0, 0, 0, 0.2);
  box-shadow: none;
}
.bless.spent .bless-name { color: #8a7c6b; }

/* Athene's reveal */
.card.peek .flip { transform: rotateY(180deg); }

/* Circe's charm wraps the Favor pill */
.hudbar .mult-mult.charmed {
  box-shadow: 0 0 14px rgba(201, 139, 192, 0.9);
  border-color: #c98bc0;
}

/* trials (boss) overlay accent */
.overlay-card.trials .overlay-title { color: var(--coral); }

/* score popup */
.pop {
  position: fixed;
  z-index: 40;
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: pop-float 0.9s var(--spring) forwards;
  white-space: nowrap;
}
.pop-inner {
  background: rgba(8, 24, 40, 0.92);
  border: 1px solid var(--gold);
  color: var(--cream);
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 18px;
  font-family: var(--serif);
  box-shadow: 0 10px 24px rgba(0,0,0,0.4);
}
.pop-inner b { color: var(--gold); font-weight: normal; }
.pop-inner em { color: var(--coral); font-style: normal; }
@keyframes pop-float {
  0%   { opacity: 0; scale: 0.5; translate: 0 10px; }
  20%  { opacity: 1; scale: 1; translate: 0 0; }
  75%  { opacity: 1; }
  100% { opacity: 0; translate: 0 -42px; }
}

/* ---- win overlay ---- */
.overlay[hidden] { display: none; }
.overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(5, 16, 28, 0.68);
  display: grid;
  place-items: center;
}
.overlay-card {
  background: linear-gradient(165deg, rgba(14, 38, 58, 0.96), rgba(5, 18, 30, 0.97));
  border: 1px solid rgba(217, 179, 106, 0.55);
  color: var(--cream);
  border-radius: 12px;
  padding: 34px 50px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0,0,0,0.55);
  animation: overlay-in 0.45s var(--spring-hard);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
@keyframes overlay-in {
  from { scale: 0.5; opacity: 0; }
  to   { scale: 1; opacity: 1; }
}
.overlay-title {
  font-size: 38px;
  font-weight: 600;
  color: var(--gold);
}
.overlay-score { font-size: 20px; }
.overlay-score b { color: var(--gold); }
.overlay-sub { font-size: 13px; color: var(--cream-dim); }
.overlay-rank { font-size: 15px; color: var(--cream); }
.overlay-rank b { color: var(--gold); }
.overlay-rank[hidden] { display: none; }
.overlay-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 4px;
}

/* ---- ghost (secondary) button ---- */
.btn-ghost {
  appearance: none;
  background: transparent;
  border: 1px solid rgba(217, 179, 106, 0.55);
  color: var(--cream);
  font-family: var(--serif);
  font-size: 15px;
  letter-spacing: 0.3px;
  padding: 11px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: transform 0.15s var(--spring-hard), background 0.2s, border-color 0.2s;
}
.btn-ghost:hover { transform: translateY(-2px); background: rgba(217, 179, 106, 0.14); border-color: var(--gold); }
.btn-ghost:active { transform: translateY(1px); }

/* ---- game-flow screens (start / how-to / leaderboard) ---- */
.screen {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(5, 15, 26, 0.8);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  overflow: auto;
}
.screen[hidden] { display: none; }

/* start screen wears the Beat garden spread; a crimson scrim keeps the
   menu card and text legible and ties it to the game's palette */
#startScreen {
  /* ?v bumped whenever the image bytes change, so the Cloudflare edge cache
     (keyed on URL) serves the new file instead of a stale same-name copy */
  background:
    radial-gradient(130% 105% at 50% 38%, rgba(20, 5, 9, 0.28), rgba(10, 3, 6, 0.9)) center / cover no-repeat,
    url("assets/menu-bg.jpg?v=35") center / cover no-repeat;
  background:
    radial-gradient(130% 105% at 50% 38%, rgba(20, 5, 9, 0.28), rgba(10, 3, 6, 0.9)),
    image-set(
      url("assets/menu-bg.webp?v=35") type("image/webp"),
      url("assets/menu-bg.jpg?v=35") type("image/jpeg")
    ) center / cover no-repeat;
  background-size: cover;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* let the artwork breathe through the menu card a touch */
#startScreen .screen-card {
  background: linear-gradient(165deg, rgba(14, 38, 58, 0.9), rgba(5, 18, 30, 0.94));
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.screen-card {
  width: min(460px, 100%);
  max-height: calc(100dvh - 32px);
  overflow: auto;
  background: linear-gradient(165deg, rgba(14, 38, 58, 0.97), rgba(5, 18, 30, 0.97));
  border: 1px solid rgba(217, 179, 106, 0.55);
  border-radius: 14px;
  padding: 30px clamp(22px, 5vw, 40px) 28px;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  animation: overlay-in 0.4s var(--spring-hard);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* menu — book cover plate beside the controls */
.screen-card.menu {
  width: min(720px, 100%);
  flex-direction: row;
  align-items: center;
  gap: clamp(20px, 3vw, 34px);
  text-align: left;
  padding: clamp(24px, 4vw, 36px);
}
.menu-cover {
  flex: 0 0 auto;
  width: clamp(160px, 34%, 240px);
  align-self: center;
}
.menu-cover img {
  display: block;
  width: 100%;
  border-radius: 10px;
  border: 1px solid rgba(217, 179, 106, 0.35);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.55);
}
.menu-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: center;
}
/* stack cover on top on narrow screens, and tighten every step so the whole
   menu fits without a scroll (or with a very short one) on small phones */
@media (max-width: 640px) {
  .screen { padding: 14px; }
  .screen-card.menu {
    flex-direction: column;
    gap: 10px;
    padding: 16px clamp(18px, 5vw, 28px);
  }
  .menu-cover { width: clamp(88px, 25vw, 112px); }
  .menu-body { gap: 8px; }
  .menu-lockup i { font-size: 10px; }
  .menu-title { font-size: clamp(34px, 9.5vw, 46px); margin: 0; }
  .menu-tag { font-size: 12px; margin-top: -2px; }
  .name-field { gap: 4px; margin-top: 0; }
  .name-field input { font-size: 16px; padding: 9px 12px; }
  .menu-actions { gap: 7px; margin-top: 0; }
  .menu-actions .btn-new { font-size: 17px; padding: 10px; }
  .menu-body .menu-actions button.btn-ghost { padding: 9px; }
}

/* very short phones (landscape, small devices): drop the cover so the
   controls always fit */
@media (max-width: 640px) and (max-height: 620px) {
  .menu-cover { display: none; }
}

.menu-lockup b {
  display: block;
  font-size: clamp(18px, 4vw, 24px);
  letter-spacing: 3px;
  color: var(--cream);
}
.menu-lockup i {
  display: block;
  font-size: 11px;
  letter-spacing: 4px;
  color: var(--cream-dim);
}
.menu-title {
  font-family: "Arial Rounded MT Bold", "Avenir Next", "Helvetica Neue", sans-serif;
  font-size: clamp(46px, 12vw, 64px);
  font-weight: bold;
  color: var(--coral);
  line-height: 0.9;
  margin: 2px 0;
}
.menu-tag { font-size: 13px; color: var(--cream-dim); margin-top: -6px; }

.name-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  margin-top: 4px;
}
.name-field span {
  font-size: 12px;
  color: var(--gold);
  text-align: center;
}
.name-field input {
  font-family: var(--serif);
  font-size: 18px;
  text-align: center;
  color: var(--cream);
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(217, 179, 106, 0.4);
  border-radius: 8px;
  padding: 11px 12px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.name-field input::placeholder { color: rgba(216, 198, 168, 0.55); }
.name-field input:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(217, 179, 106, 0.22);
}

.menu-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 4px;
}
.menu-actions .btn-new { font-size: 18px; padding: 13px; }
/* menu buttons carry a leading SVG icon */
.menu-body .menu-actions button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.menu-body .menu-actions button svg {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

/* how-to */
.screen-title {
  font-size: clamp(24px, 6vw, 32px);
  font-weight: 600;
  color: var(--gold);
}
.rules { text-align: left; display: flex; flex-direction: column; gap: 14px; }
.rule-lead { font-size: 14px; line-height: 1.5; color: var(--cream); }
.rule-lead b { color: var(--gold); font-weight: normal; }
.rule { display: flex; gap: 12px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: var(--cream-dim); }
.rule b { color: var(--cream); font-weight: normal; }
.rule em { color: var(--coral); font-style: normal; }
.rule ul { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.rule ul li { font-size: 12.5px; }
.rule ul b { color: var(--gold); }
/* gold diamond marker, drawn — no emoji */
.rule-mark {
  flex: 0 0 auto;
  width: 10px; height: 10px;
  margin-top: 4px;
  background: var(--gold);
  transform: rotate(45deg);
  box-shadow: 0 0 8px rgba(217, 179, 106, 0.5);
}

/* leaderboard */
.board-list {
  list-style: none;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0; padding: 0;
  /* the full list can run long — keep it scrollable inside the card so the
     controls below stay reachable */
  max-height: min(56vh, 520px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.board-list li {
  display: grid;
  grid-template-columns: 2.5ch 1fr auto;
  align-items: baseline;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.22);
  font-size: 15px;
}
.board-list li .rank-n { color: var(--gold); font-size: 13px; text-align: right; font-variant-numeric: tabular-nums; }
.board-list li .who { color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board-list li .glory { color: var(--gold); font-variant-numeric: tabular-nums; }
.board-list li.top { background: rgba(217, 179, 106, 0.14); border: 1px solid rgba(217, 179, 106, 0.4); }
.board-list li.you { box-shadow: inset 0 0 0 1px var(--coral); }
.board-list li.you .who::after { content: " ← เจ้า"; color: var(--coral); font-size: 12px; }
/* the "…" divider before the player's own standing when it's below the Top Ten */
.board-list li.board-gap {
  background: none;
  padding: 2px 0;
  justify-items: center;
  grid-template-columns: 1fr;
  color: var(--cream-dim);
  pointer-events: none;
}
.board-list li.board-gap::after { content: "···"; letter-spacing: 3px; }
.board-empty { font-size: 13px; color: var(--cream-dim); padding: 10px 0; }
.board-empty[hidden] { display: none; }

/* "ดูทั้งหมด" — a quiet text button that expands the list to every run */
.board-more {
  align-self: center;
  margin-top: 4px;
  padding: 6px 14px;
  border: 1px solid rgba(217, 179, 106, 0.35);
  border-radius: 999px;
  background: rgba(217, 179, 106, 0.08);
  color: var(--gold);
  font-family: var(--serif);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s, transform 0.15s var(--spring-hard);
}
.board-more:hover { background: rgba(217, 179, 106, 0.18); border-color: rgba(217, 179, 106, 0.6); }
.board-more:active { transform: scale(0.97); }
.board-more[hidden] { display: none; }
.board-list li.athena { background: rgba(146, 178, 224, 0.16); border: 1px solid rgba(168, 196, 232, 0.5); }
.board-list li.athena .who { color: #cfe0f2; }

/* ---- "Show me Athena!" call-to-action on How to Play ---- */
.athena-cta {
  margin-top: 4px;
  padding: 16px;
  border-radius: 10px;
  border: 1px solid rgba(168, 196, 232, 0.35);
  background:
    radial-gradient(120% 120% at 50% 0%, rgba(120, 160, 210, 0.18), transparent 70%),
    rgba(10, 26, 44, 0.5);
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.athena-cta p { font-size: 13px; line-height: 1.55; color: var(--cream-dim); }
.btn-athena {
  appearance: none;
  align-self: center;
  border: 1px solid rgba(168, 196, 232, 0.6);
  background: linear-gradient(165deg, #2c4a74, #17314f);
  color: #eaf1fa;
  font-family: var(--serif);
  font-size: 16px;
  letter-spacing: 0.3px;
  padding: 11px 22px;
  border-radius: 8px;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4), inset 0 0 12px rgba(168, 196, 232, 0.25);
  transition: transform 0.15s var(--spring-hard), box-shadow 0.25s ease, background 0.2s;
}
.btn-athena:hover {
  transform: translateY(-2px) scale(1.03);
  background: linear-gradient(165deg, #35578a, #1d3c60);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45), 0 0 20px rgba(168, 196, 232, 0.5);
}
.btn-athena:active { transform: translateY(1px); }

/* ---- responsive ---- */
/* short windows: stop shrinking the board, scroll instead */
@media (max-height: 700px) {
  body { overflow: auto; }
  .grid { width: min(440px, 92vw); }
  .stage { padding: 14px 0; }
}

@media (max-width: 720px) {
  body { overflow: auto; padding-bottom: 54px; }

  /* masthead: keep the wordmark and the player badge together on the top row,
     and drop the Blessings band onto its own compact row below — otherwise the
     wide altar pill wraps between them and balloons the header, shoving the
     board down into the HUD */
  .masthead { row-gap: 8px; }
  .lockup { order: 1; }
  .brand { order: 2; max-width: 42vw; }
  .altar { order: 3; flex-basis: 100%; padding: 5px 12px; gap: 12px; }
  .altar-label { font-size: 12px; }
  .altar-slots { gap: 12px; }
  .bless { width: 52px; }
  .bless svg { width: 30px; height: 30px; }
  .bless-name { font-size: 10px; }

  /* board height budget: reserve the header + caption + HUD. When a god has
     been matched the Blessings row adds ~64px, so reserve more then. */
  .grid { width: min(92vw, calc((100dvh - 320px) / 1.12)); min-width: 220px; }
  body:has(#altar:not([hidden])) .grid:not(.trials) {
    width: min(92vw, calc((100dvh - 400px) / 1.12));
  }
  .grid.trials { width: min(96vw, calc((100dvh - 400px) / 1.12 * 1.5)); }

  .deck { width: 50px; height: 75px; right: 10px; bottom: 46px; }
  .deck-count { font-size: 11px; padding: 3px 7px; }
  .hudbar { gap: 12px; }
  .hud-item b { font-size: 17px; }
  .btn-new { font-size: 14px; padding: 9px 14px; }
}

@media (prefers-reduced-motion: reduce) {
  .card { animation: none; transition: none; }
  .flip { transition-duration: 0.01s; animation: none !important; }
  .felt::before, .felt::after { animation: none; }
  .stage { animation: none !important; }
  body::after { transition: none; }
  /* keep the rainbow foil, just hold it still */
  .card.blessed .face.front::after,
  .card.blessed .face.front::before { animation: none !important; }
  .card.hero .face.front::after { animation: none !important; }
}
