/* =========================================================
   XXII: Ex Tenebris — dark elegant, black + thin gold
   ========================================================= */

:root {
  --black:        #050506;
  --ink:          #0a0a0d;
  --panel:        #101014;
  --panel-2:      #16161c;
  --line:         #26262e;
  --line-gold:    rgba(197, 164, 96, 0.28);
  --gold:         #c5a460;
  --gold-bright:  #e6c884;
  --gold-dim:     #8a7442;
  --text:         #e8e6df;
  --muted:        #9a978d;
  --faint:        #6a6862;

  --fire:  #d9663f;
  --water: #4a86c9;
  --air:   #c8b25e;
  --earth: #6fa06a;

  /* Secondary accent — dramatic moments only (Legendary, key hover states). Not a primary color. */
  --oxblood:        #6b1f2a;
  --oxblood-bright: #8f3040;
  --ink-violet:     #1a1420;
  --card-black:     #121016;

  /* Cinzel is cut from Roman inscriptional capitals — it is the reason "XXII"
     reads as carved rather than typed, and it carries the brand far better than
     a general-purpose serif. Kept for MARKS and headings only; at body size its
     tight caps become hard work.
     Spectral replaces Inter. Inter is the default of every dashboard on the
     internet — technically fine, and completely without character, which is
     exactly the complaint. Spectral is a screen-first serif: it has a voice and
     still holds up at 15px. */
  --display: "Cinzel", "Cormorant Garamond", Georgia, serif;
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans:  "Spectral", Georgia, "Times New Roman", serif;
  --mono:  "Space Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --maxw: 1180px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

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

html { scroll-behavior: smooth; }

body {
  background: var(--black);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

::selection { background: var(--gold); color: #000; }

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }

/* ---------- Layout helpers ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
section { position: relative; padding: 120px 0; }

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 22px;
  display: inline-block;
}
.eyebrow::before { content: "— "; color: var(--gold-dim); }

.section-head { max-width: 720px; margin-bottom: 56px; }
h2.headline {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(2rem, 4.4vw, 3.3rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: #fff;
}
.section-head .body { color: var(--muted); font-size: 1.06rem; margin-top: 20px; max-width: 620px; }

.divider-glyph {
  text-align: center;
  color: var(--gold-dim);
  font-size: 20px;
  letter-spacing: 1.2em;
  padding: 8px 0 0;
  opacity: 0.6;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--mono);
  font-size: 12.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 15px 28px;
  border: 1px solid var(--line-gold);
  color: var(--text);
  background: transparent;
  cursor: pointer;
  transition: all 0.4s var(--ease);
  position: relative;
}
.btn:hover { border-color: var(--gold); color: var(--gold-bright); background: rgba(197,164,96,0.06); }
.btn-primary {
  background: linear-gradient(180deg, var(--gold-bright), var(--gold));
  color: #14100a;
  border-color: var(--gold);
  font-weight: 700;
  overflow: hidden;
}
.btn-primary:hover {
  color: #14100a; box-shadow: 0 0 32px rgba(197,164,96,0.28); filter: brightness(1.05);
  background: linear-gradient(180deg, var(--gold-bright), var(--gold)); /* re-assert — .btn:hover's faint tint would otherwise win */
}
.btn-primary::after {
  content: ""; position: absolute; top: 0; left: -100%; width: 60%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255,255,255,0.35), transparent);
  transition: left 0.6s ease; pointer-events: none;
}
.btn-primary:hover::after { left: 120%; }
.btn-ghost { border-color: var(--line); }

/* =========================================================
   NAV
   ========================================================= */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 28px;
  transition: background 0.4s, border-color 0.4s, padding 0.4s;
  border-bottom: 1px solid transparent;
}
.nav.scrolled {
  background: rgba(5,5,6,0.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  padding: 12px 28px;
}
.nav .brand {
  font-family: var(--serif);
  font-size: 22px;
  letter-spacing: 0.28em;
  color: #fff;
  font-weight: 600;
}
.nav .brand span { color: var(--gold); }
.nav-links { display: flex; gap: 30px; align-items: center; }
.nav-links a {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted); transition: color 0.3s;
}
.nav-links a:hover { color: var(--gold); }
.nav-links .btn { padding: 10px 20px; }
.nav-toggle { display: none; background: none; border: none; color: var(--text); font-size: 22px; cursor: pointer; }
@media (max-width: 820px) {
  .nav-links { display: none; }
  .nav-toggle { display: block; }
  .nav-links.open {
    display: flex; flex-direction: column; position: absolute; top: 100%; right: 0; left: 0;
    background: var(--ink); border-bottom: 1px solid var(--line); padding: 24px; gap: 20px;
  }
}

/* =========================================================
   HERO
   ========================================================= */
.hero {
  min-height: 100vh;
  display: flex; align-items: center;
  padding: 120px 0 80px;
  position: relative; overflow: hidden;
}
.hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(ellipse 60% 50% at 50% 40%, rgba(197,164,96,0.10), transparent 70%),
    radial-gradient(ellipse 80% 60% at 50% 120%, rgba(197,164,96,0.06), transparent 60%),
    var(--black);
  /* Living background: the two glows drift very slowly — barely perceptible
     unless watched. background-size:200% gives them room to travel. */
  background-size: 200% 200%, 200% 200%, auto;
  animation: bgDrift 25s ease-in-out infinite alternate;
}
@keyframes bgDrift {
  0%   { background-position: 0% 0%, 0% 0%, 0 0; }
  100% { background-position: 100% 100%, 100% 100%, 0 0; }
}
/* A separate, undrifting layer for the cursor-glow — kept independent of
   bgDrift above so the mousemove transition never fights the drift animation. */
.hero-cursor-glow {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(600px circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(197,164,96,0.07), transparent 70%);
  transition: background 0.3s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .hero-cursor-glow { transition: none; }
}
.hero-bg::after {
  content: ""; position: absolute; inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  opacity: 0.04; mix-blend-mode: overlay;
}
.hero-fog { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero-fog span {
  position: absolute; border-radius: 50%;
  background: radial-gradient(circle, rgba(197,164,96,0.12), transparent 70%);
  filter: blur(30px); animation: drift 26s var(--ease) infinite;
}
.hero-fog span:nth-child(1){ width: 380px; height: 380px; top: 8%; left: -6%; animation-duration: 30s; }
.hero-fog span:nth-child(2){ width: 300px; height: 300px; bottom: 6%; right: -4%; animation-duration: 38s; animation-delay: -8s; }
.hero-fog span:nth-child(3){ width: 220px; height: 220px; top: 40%; left: 60%; animation-duration: 34s; animation-delay: -14s; }
@keyframes drift {
  0%,100% { transform: translate(0,0) scale(1); opacity: 0.6; }
  50% { transform: translate(40px,-30px) scale(1.15); opacity: 1; }
}

.hero .wrap { position: relative; z-index: 2; }
.hero-eyebrow {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.4em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 30px;
}
.hero-mark {
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(6rem, 22vw, 17rem);
  line-height: 0.82; letter-spacing: 0.04em; color: #fff;
  text-shadow: 0 0 60px rgba(197,164,96,0.2);
  position: relative;
}
.hero-sub {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(1.6rem, 4vw, 2.6rem); color: var(--gold-bright);
  margin-top: 6px; letter-spacing: 0.04em;
}
.hero-tag { color: var(--muted); font-size: 1.15rem; margin-top: 26px; max-width: 460px; }
.hero-body { color: var(--faint); font-size: 1rem; margin-top: 12px; max-width: 480px; }
.hero-cta { display: flex; gap: 16px; margin-top: 40px; flex-wrap: wrap; }
.hero-rule { width: 60px; height: 1px; background: var(--gold); margin: 30px 0 0; }
.scroll-hint {
  position: absolute; bottom: 34px; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.3em; color: var(--faint);
  text-transform: uppercase; z-index: 2; animation: pulse 3s infinite;
}
@keyframes pulse { 0%,100%{opacity:0.4;} 50%{opacity:1;} }

/* =========================================================
   THE DRAW
   ========================================================= */
.draw { background: var(--ink); border-top: 1px solid var(--line); }
.draw-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
@media (max-width: 900px) { .draw-grid { grid-template-columns: 1fr; gap: 48px; } }

/* ---------- Reading preview: small face-down grid inside the landing panel ---------- */
.reading-preview-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; max-width: 320px; }
.reading-preview-card {
  aspect-ratio: 3 / 5; border-radius: 6px; border: 1px solid var(--line-gold);
  background: #0a0a0e url('../assets/cards/card-back.webp') center / cover no-repeat;
  transition: transform 0.4s var(--ease);
}
.reading-preview-card.lifted { transform: translateY(-8px); border-color: var(--gold-bright); box-shadow: 0 8px 18px -8px rgba(197,164,96,0.5); }

.flip-stage { display: flex; justify-content: center; perspective: 1100px; }
/* Two composed layers so tilt and flip never fight each other:
   .flip-card  = mouse-follow tilt (rotateX + rotateY, any direction)
   .flip-inner = the front/back flip (rotateY 0 -> 180)
   Because .flip-card keeps preserve-3d, the child flip rotates inside the
   parent's tilted space — it reads as one solid card turning in 3D. */
.flip-card {
  width: 280px; aspect-ratio: 3 / 5; position: relative;
  transform-style: preserve-3d;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.5s var(--ease);
  cursor: pointer;
}
.flip-card.tilting { transition: none; } /* follow the pointer 1:1 while it moves */
.flip-inner {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transform: rotateY(0deg);
  transition: transform 0.7s var(--ease), box-shadow 0.7s var(--ease);
  border-radius: 14px;
  /* Shadow sits to one side while the back faces us, then slides across during
     the flip so it reads like light raking the card from the side. */
  box-shadow: -14px 20px 46px -20px rgba(0,0,0,0.9);
}
.flip-card.flipped .flip-inner { transform: rotateY(180deg); box-shadow: 14px 20px 46px -20px rgba(0,0,0,0.9); }
.flip-face {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: 14px; border: 1px solid var(--line-gold);
  display: flex; flex-direction: column; overflow: hidden;
}
/* card-back.webp is the real illustrated back now — static CSS url() so it
   resolves against this stylesheet (css/ -> ../assets/...), sidestepping the
   custom-property url() resolution gotcha. The gradient stays as a fallback
   colour under the image. */
.flip-back {
  background:
    #0a0a0e url('../assets/cards/card-back.webp') center / cover no-repeat;
  align-items: center; justify-content: center; text-align: center;
}
/* Legacy glyph placeholders — the illustrated back supersedes them. Hidden
   rather than deleted everywhere so any stray markup degrades cleanly. */
.flip-back .ornament,
.flip-back .ornament-sub,
.flip-back .corner { display: none; }

.flip-front { transform: rotateY(180deg); padding: 22px; justify-content: flex-end; }
/* The front face is a .tcard; its hover rule (translateY) would otherwise
   cancel the rotateY that keeps this face turned toward us. Pin it. */
.flip-front.tcard:hover { transform: rotateY(180deg); box-shadow: none; }
.flip-hint { text-align: center; font-family: var(--mono); font-size: 10px; letter-spacing: 0.25em; color: var(--faint); text-transform: uppercase; margin-top: 22px; }

.draw-steps { list-style: none; margin-top: 30px; }
.draw-steps li { display: flex; gap: 18px; padding: 16px 0; border-top: 1px solid var(--line); }
.draw-steps li .idx { font-family: var(--serif); font-size: 1.4rem; color: var(--gold); min-width: 30px; }
.draw-steps li strong { color: #fff; font-weight: 600; display: block; margin-bottom: 2px; }
.draw-steps li span { color: var(--muted); font-size: 0.94rem; }
.micro { font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.05em; color: var(--gold-dim); margin-top: 26px; font-style: italic; }

/* =========================================================
   CARD (shared component — grimoire + preview)
   ========================================================= */
.tcard {
  position: relative; border-radius: 12px; overflow: hidden;
  border: 1px solid var(--line);
  background-image:
    linear-gradient(to top, rgba(5,5,6,0.92) 0%, rgba(5,5,6,0.22) 52%, rgba(5,5,6,0.4) 100%),
    var(--art-url, none),
    linear-gradient(170deg, var(--panel-2), var(--panel));
  background-size: cover, cover, cover;
  background-position: center, center, center;
  aspect-ratio: 3 / 5; /* matches the source art (800x1334) + card-back, so every card reads at one scale */
  display: flex; flex-direction: column;
  padding: 16px 15px; cursor: pointer;
  transition: transform 0.5s var(--ease), border-color 0.5s, box-shadow 0.5s;
}
.tcard:hover { transform: translateY(-8px); border-color: var(--line-gold); box-shadow: 0 20px 50px -20px rgba(0,0,0,0.9), 0 0 30px -12px var(--el-color, var(--gold)); }
.tcard.locked { filter: grayscale(1) brightness(0.5); opacity: 0.72; }
.tcard.locked:hover { transform: translateY(-4px); filter: grayscale(0.6) brightness(0.7); }

.tcard-top { display: flex; justify-content: space-between; align-items: flex-start; }
.tcard-roman { font-family: var(--serif); font-size: 1.5rem; color: #fff; line-height: 1; }
.tcard-el {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  font-size: 15px; border: 1px solid var(--el-color); color: var(--el-color);
  background: color-mix(in srgb, var(--el-color) 12%, transparent);
}
.tcard-art {
  flex: 1; display: grid; place-items: center; margin: 8px 0;
  font-family: var(--serif); font-size: 2.6rem; color: var(--el-color);
  opacity: 0.9; position: relative;
}
.tcard-art::before {
  content: ""; position: absolute; inset: 12% 18%;
  border: 1px solid var(--el-color); opacity: 0.22; border-radius: 50%;
}
.tcard-name { font-family: var(--serif); font-size: 1.02rem; color: var(--text); line-height: 1.15; }
.tcard-meta { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; }
.tcard-rarity { font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.18em; text-transform: uppercase; padding: 3px 7px; border-radius: 3px; }
.r-common   { color: var(--muted); border: 1px solid var(--line); }
.r-rare     { color: #8fb8e0; border: 1px solid rgba(143,184,224,0.4); background: rgba(74,134,201,0.08); }
.r-legendary{ color: var(--gold-bright); border: 1px solid var(--line-gold); background: rgba(197,164,96,0.1); }

/* ---------- Rarity frame (Common thin / Rare gold+glow / Legendary thick+ornament+strong glow) ----------
   Shared across every card-shaped element: landing .tcard, game .pick-card/.bf-card/.result-card. */
.tcard.rar-rare, .pick-card.rar-rare, .bf-card.rar-rare, .result-card.rar-rare {
  border-color: rgba(197,164,96,0.6) !important;
  box-shadow: 0 0 16px -6px var(--gold);
}
.tcard.rar-legendary, .pick-card.rar-legendary, .bf-card.rar-legendary, .result-card.rar-legendary {
  border-width: 2px !important; border-color: var(--gold-bright) !important;
  box-shadow: 0 0 28px -4px var(--gold-bright), inset 0 0 16px -6px rgba(230,200,132,0.35);
}
.tcard.rar-legendary::before, .pick-card.rar-legendary::before, .bf-card.rar-legendary::before {
  content: ""; position: absolute; inset: 3px; border: 1px solid rgba(230,200,132,0.4); border-radius: 8px; pointer-events: none; z-index: 1;
}
.tcard-el-label { font-family: var(--mono); font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--el-color); }

/* Level badge — shared by the grimoire grid, deck picker, and draw modal */
.card-lv-badge {
  position: absolute; top: 8px; right: 8px; z-index: 2;
  font-family: var(--mono); font-size: 9px; letter-spacing: 0.06em;
  padding: 2px 7px; border-radius: 20px;
  border: 1px solid var(--gold); color: var(--gold-bright);
  background: rgba(5,5,6,0.78);
}

/* Grimoire */
.grimoire { background: var(--black); border-top: 1px solid var(--line); }
.grim-controls { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 34px; align-items: center; }
.filter {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 8px 16px; border: 1px solid var(--line); color: var(--muted); background: transparent;
  cursor: pointer; transition: all 0.3s; border-radius: 2px;
}
.filter:hover { color: var(--text); border-color: var(--line-gold); }
.filter.active { color: var(--gold-bright); border-color: var(--gold); background: rgba(197,164,96,0.08); }
.grim-count { margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--faint); letter-spacing: 0.1em; }

.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 18px; }

.legend { display: flex; gap: 28px; flex-wrap: wrap; margin-top: 40px; padding-top: 30px; border-top: 1px solid var(--line); }
.legend div { font-size: 0.9rem; color: var(--muted); }
.legend strong { color: var(--text); font-weight: 600; }
.elem-legend { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 20px; }
.elem-legend span { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; display: inline-flex; align-items: center; gap: 7px; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }

/* =========================================================
   DUEL
   ========================================================= */
.duel { background: var(--ink); border-top: 1px solid var(--line); }
.duel-grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 60px; align-items: center; }
@media (max-width: 940px) { .duel-grid { grid-template-columns: 1fr; gap: 48px; } }
.duel-points { list-style: none; margin: 30px 0; }
.duel-points li { padding: 14px 0 14px 26px; position: relative; color: var(--muted); border-top: 1px solid var(--line); }
.duel-points li::before { content: "◆"; position: absolute; left: 0; color: var(--gold); font-size: 10px; top: 17px; }

/* Battle mockup */
.battle {
  border: 1px solid var(--line-gold); border-radius: 14px; overflow: hidden;
  background: linear-gradient(180deg, #0c0c11, #08080b);
  box-shadow: 0 30px 70px -30px #000;
}
.battle-head { display: flex; justify-content: space-between; align-items: center; padding: 12px 18px; border-bottom: 1px solid var(--line); font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; color: var(--faint); text-transform: uppercase; }
.battle-turn { color: var(--gold); }
.combatants { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; padding: 24px 18px; }
.vs { font-family: var(--serif); font-style: italic; color: var(--gold-dim); font-size: 1.3rem; }
.fighter { text-align: center; }
.fighter.enemy { opacity: 0.92; }
.fighter-orb {
  width: 74px; height: 74px; margin: 0 auto 12px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--serif); font-size: 1.8rem;
  border: 1px solid var(--f-color); color: var(--f-color);
  background: radial-gradient(circle, color-mix(in srgb, var(--f-color) 22%, transparent), transparent 70%);
}
.fighter-name { font-family: var(--serif); font-size: 1rem; color: #fff; }
.fighter-el { font-family: var(--mono); font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--f-color); margin-top: 3px; }
.hpbar { height: 6px; background: #1a1a20; border-radius: 3px; margin-top: 10px; overflow: hidden; }
.hpbar i { display: block; height: 100%; background: linear-gradient(90deg, var(--earth), var(--air)); border-radius: 3px; transition: width 1.2s var(--ease); }
.hpbar.low i { background: linear-gradient(90deg, #b04a3a, var(--fire)); }
.hp-num { font-family: var(--mono); font-size: 9px; color: var(--faint); margin-top: 5px; letter-spacing: 0.1em; }
.matchup-tag {
  text-align: center; font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold-bright); padding: 8px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  background: rgba(197,164,96,0.05);
}
.skill-list { padding: 14px 18px 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.skill {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 6px;
  font-size: 0.82rem; color: var(--muted); transition: all 0.3s; cursor: default;
}
.skill:hover { border-color: var(--line-gold); color: var(--text); background: rgba(197,164,96,0.04); }
.skill b { color: var(--text); font-weight: 600; }
.skill .pw { font-family: var(--mono); font-size: 10px; color: var(--gold); }
.skill.heavy { grid-column: span 2; border-color: var(--line-gold); }

/* =========================================================
   TOKENOMICS
   ========================================================= */
.token { background: var(--black); border-top: 1px solid var(--line); }
.token-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 64px; align-items: center; }
@media (max-width: 900px) { .token-grid { grid-template-columns: 1fr; gap: 48px; } }
.donut-wrap { display: flex; flex-direction: column; align-items: center; }
.donut { position: relative; width: 300px; max-width: 100%; }
.donut svg { transform: rotate(-90deg); }
.donut-center {
  position: absolute; inset: 0; display: grid; place-items: center; text-align: center;
}
.donut-center .tick { font-family: var(--serif); font-size: 2.4rem; color: #fff; }
.donut-center .lbl { font-family: var(--mono); font-size: 10px; letter-spacing: 0.25em; color: var(--gold); text-transform: uppercase; }
.alloc { list-style: none; }
.alloc li { display: flex; align-items: center; gap: 14px; padding: 15px 0; border-top: 1px solid var(--line); }
.alloc .sw { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; }
.alloc .nm { color: var(--text); font-weight: 500; flex: 1; }
.alloc .pct { font-family: var(--mono); color: var(--gold-bright); font-size: 0.95rem; }
.alloc .desc { color: var(--faint); font-size: 0.8rem; width: 100%; padding-left: 26px; margin-top: -8px; }
.token-utils { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; margin-top: 40px; }
@media (max-width: 620px){ .token-utils { grid-template-columns: 1fr; } }
.util { border: 1px solid var(--line); border-radius: 10px; padding: 22px 20px; background: var(--panel); }
.util .ic { font-size: 1.4rem; color: var(--gold); margin-bottom: 12px; }
.util h4 { font-family: var(--serif); font-size: 1.15rem; color: #fff; font-weight: 500; margin-bottom: 6px; }
.util p { color: var(--muted); font-size: 0.88rem; }
.contract-note {
  margin-top: 30px; padding: 16px 20px; border: 1px dashed var(--line-gold); border-radius: 8px;
  font-family: var(--mono); font-size: 11.5px; color: var(--gold-dim); letter-spacing: 0.05em;
  display: flex; align-items: center; gap: 12px;
}
.ca-mark { color: var(--gold); }

/* The live contract address. Replaces the note above once XT_SITE.contract is
   filled in. The address itself is allowed to wrap and to be selected — people
   verify it character by character against the one posted on X. */
.ca-live {
  margin-top: 30px; padding: 14px 16px;
  border: 1px solid var(--line-gold); border-radius: 8px;
  background: rgba(198, 160, 74, 0.05);
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.ca-label {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--faint); flex: none;
}
.ca-addr {
  font-family: var(--mono); font-size: 13px; color: var(--gold-bright);
  letter-spacing: 0.02em; word-break: break-all; user-select: all;
  flex: 1 1 220px; min-width: 0;
}
.ca-copy {
  flex: none; cursor: pointer; padding: 8px 16px; border-radius: 20px;
  border: 1px solid var(--line-gold); background: transparent;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--gold);
  transition: border-color 0.25s, color 0.25s, background 0.25s;
}
.ca-copy:hover { border-color: var(--gold-bright); color: var(--gold-bright); background: rgba(198,160,74,0.1); }
.ca-copy.done { color: #7ee0a8; border-color: rgba(126,224,168,0.5); }
@media (max-width: 560px) {
  .ca-live { gap: 10px; }
  .ca-addr { font-size: 11.5px; flex-basis: 100%; }
}

/* =========================================================
   ROADMAP
   ========================================================= */
.roadmap { background: var(--ink); border-top: 1px solid var(--line); }
.phases { position: relative; margin-top: 20px; }
.phases::before { content: ""; position: absolute; left: 15px; top: 10px; bottom: 10px; width: 1px; background: var(--line); }
.phase { position: relative; padding: 0 0 44px 56px; }
.phase:last-child { padding-bottom: 0; }
.phase .node {
  position: absolute; left: 6px; top: 4px; width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--gold); background: var(--black); display: grid; place-items: center;
}
.phase .node::after { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--line); }
.phase.done .node { border-color: var(--gold-bright); }
.phase.done .node::after { background: var(--gold-bright); box-shadow: 0 0 12px var(--gold); }
.phase.active .node::after { background: var(--gold); animation: pulse 2.4s infinite; }
.phase.active .node { animation: nodePulse 2s ease-in-out infinite; }
@keyframes nodePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(197,164,96,0.4); }
  50%      { box-shadow: 0 0 0 8px rgba(197,164,96,0); }
}
.phase .ph-tag { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
.phase h3 { font-family: var(--serif); font-weight: 500; font-size: 1.6rem; color: #fff; margin: 6px 0 8px; }
.phase p { color: var(--muted); max-width: 520px; }
.phase .state { display: inline-block; margin-top: 10px; font-family: var(--mono); font-size: 10px; letter-spacing: 0.15em; text-transform: uppercase; padding: 4px 10px; border-radius: 3px; }
.phase.done .state { color: var(--earth); border: 1px solid rgba(111,160,106,0.4); }
.phase.active .state { color: var(--gold-bright); border: 1px solid var(--line-gold); background: rgba(197,164,96,0.08); }
.phase.soon .state { color: var(--faint); border: 1px solid var(--line); }

/* =========================================================
   FAQ
   ========================================================= */
.faq { background: var(--black); border-top: 1px solid var(--line); }
.faq-list { max-width: 780px; }
.faq-item { border-top: 1px solid var(--line); }
.faq-item:last-child { border-bottom: 1px solid var(--line); }
.faq-q {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: 26px 40px 26px 0; position: relative;
  font-family: var(--serif); font-size: 1.35rem; color: var(--text); transition: color 0.3s;
}
.faq-q:hover { color: var(--gold-bright); }
.faq-q::after { content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%); font-family: var(--sans); font-size: 1.5rem; color: var(--gold); transition: transform 0.4s; }
.faq-item.open .faq-q::after { transform: translateY(-50%) rotate(45deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height 0.5s var(--ease); }
.faq-a p { color: var(--muted); padding: 0 40px 26px 0; }

/* =========================================================
   FOOTER
   ========================================================= */
.footer { background: var(--ink); border-top: 1px solid var(--line-gold); padding: 70px 0 34px; }
.footer-top { display: flex; justify-content: space-between; gap: 40px; flex-wrap: wrap; padding-bottom: 40px; border-bottom: 1px solid var(--line); }
.footer-brand .mark { font-family: var(--serif); font-size: 2rem; letter-spacing: 0.2em; color: #fff; }
.footer-brand .mark span { color: var(--gold); }
.footer-brand .tag { font-family: var(--serif); font-style: italic; color: var(--gold-dim); margin-top: 8px; }
.footer-cols { display: flex; gap: 60px; flex-wrap: wrap; }
.footer-col h5 { font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint); margin-bottom: 16px; }
.footer-col a { display: block; color: var(--muted); font-size: 0.9rem; padding: 5px 0; transition: color 0.3s; }
.footer-col a:hover { color: var(--gold); }
.socials { display: flex; gap: 12px; }
.socials a {
  width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 50%;
  display: grid; place-items: center; color: var(--muted); font-family: var(--mono); font-size: 13px;
  transition: all 0.3s;
}
.socials a:hover { border-color: var(--gold); color: var(--gold); }
.footer-bottom { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; padding-top: 28px; }
.copyright { font-family: var(--mono); font-size: 11px; color: var(--faint); letter-spacing: 0.08em; white-space: nowrap; }

/* =========================================================
   MODAL (card detail)
   ========================================================= */
.modal {
  position: fixed; inset: 0; z-index: 200; display: none;
  align-items: center; justify-content: center; padding: 24px;
  background: rgba(3,3,4,0.86); backdrop-filter: blur(6px);
}
.modal.open { display: flex; animation: fade 0.3s; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.modal-card {
  width: 100%; max-width: 720px; max-height: 88vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--panel), var(--ink));
  border: 1px solid var(--line-gold); border-radius: 16px;
  display: grid; grid-template-columns: 240px 1fr;
  animation: rise 0.4s var(--ease);
}
@keyframes rise { from { transform: translateY(20px) scale(0.98); opacity: 0; } to { transform: none; opacity: 1; } }
@media (max-width: 640px){ .modal-card { grid-template-columns: 1fr; max-height: 92vh; } }
.modal-visual {
  position: relative; overflow: hidden;
  padding: 28px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  border-right: 1px solid var(--line); text-align: center; min-height: 320px;
  background-image:
    linear-gradient(to top, rgba(5,5,6,0.94) 0%, rgba(5,5,6,0.15) 55%, rgba(5,5,6,0.35) 100%),
    var(--art-url, none),
    radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--el-color) 14%, transparent), transparent 65%);
  background-size: cover, cover, cover;
  background-position: center, center, center;
}
@media (max-width: 640px){ .modal-visual { border-right: none; border-bottom: 1px solid var(--line); } }
.modal-visual .roman {
  font-family: var(--serif); font-size: 2.2rem; color: #fff; line-height: 1;
  position: absolute; top: 20px; left: 24px;
}
.modal-visual .art { display: none; } /* replaced by the illustration background */
.modal-visual .nm { font-family: var(--serif); font-size: 1.5rem; color: #fff; }
.modal-visual .el { font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--el-color); margin-top: 8px; }
.modal-visual.rar-rare { box-shadow: inset 0 0 0 2px rgba(197,164,96,0.5); }
.modal-visual.rar-legendary { box-shadow: inset 0 0 0 2px var(--gold-bright), inset 0 0 30px -8px rgba(230,200,132,0.5); }
.modal-body { padding: 28px; position: relative; }
.modal-close { position: absolute; top: 16px; right: 18px; background: none; border: none; color: var(--muted); font-size: 24px; cursor: pointer; transition: color 0.3s; }
.modal-close:hover { color: var(--gold); }
.modal-body .blurb { font-family: var(--serif); font-style: italic; font-size: 1.15rem; color: var(--gold-bright); margin: 6px 0 22px; line-height: 1.4; }

/* =========================================================
   Reveal animation
   ========================================================= */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition-duration: 0.01ms !important; }
  .reveal { opacity: 1; transform: none; }
  html { scroll-behavior: auto; }
}

@media (max-width: 560px) {
  section { padding: 84px 0; }
  .wrap { padding: 0 18px; }
  .card-grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 12px; }
}

/* =========================================================
   SINGLE-SCREEN SPLASH (index.html) — no scroll, game-site style
   Reuses .hero-bg / .hero-fog / .btn from above.
   ========================================================= */
.splash-body { height: 100vh; height: 100dvh; overflow: hidden; }
.splash {
  position: relative; height: 100vh; height: 100dvh;
  display: flex; flex-direction: column; overflow: hidden;
}
.splash > .hero-bg, .splash > .hero-fog { position: absolute; inset: 0; }

/* Top bar */
.splash-nav {
  position: relative; z-index: 3;
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px clamp(20px, 4vw, 44px);
}
.splash-nav .brand { font-family: var(--serif); font-size: 22px; letter-spacing: 0.26em; color: #fff; }
.splash-nav .brand span { color: var(--gold); }

/* Brand wordmark logo (shared by splash-nav + game-nav) — sized by height so
   the full circular medallion stays proportional. */
.brand { display: inline-flex; align-items: center; line-height: 0; }
.brand-logo { height: 46px; width: auto; display: block; transition: filter 0.3s var(--ease); }
.brand:hover .brand-logo { filter: drop-shadow(0 0 10px rgba(197,164,96,0.45)); }
@media (max-width: 600px) { .brand-logo { height: 38px; } }
.splash-nav-right { display: flex; align-items: center; gap: 14px; }
.splash-nav .social {
  width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 50%;
  display: grid; place-items: center; color: var(--muted); font-size: 13px; transition: all 0.3s;
}
.splash-nav .social:hover { border-color: var(--gold); color: var(--gold); }
.btn-sm { padding: 10px 18px; font-size: 11px; }

/* Center */
.splash-main {
  position: relative; z-index: 3; flex: 1;
  display: flex; flex-direction: column; align-items: center;
  /* `safe center` centres while the content fits and falls back to flex-start
     the moment it does not. Plain `center` overflows in BOTH directions, which
     pushed the eyebrow up under the nav on short screens. */
  justify-content: center;
  justify-content: safe center;
  text-align: center; padding: 12px 20px; min-height: 0;
  /* Safety net, not the primary fit strategy. flex:1 + min-height:0 lets this
     box shrink below its content's natural height, but shrinking the BOX does
     not shrink its CHILDREN — without a clip/scroll boundary of its own, the
     eyebrow-to-CTA stack simply overflowed the box and painted on top of
     .splash-foot on any real phone (nav+footer pinned, this the only part
     that may ever move). The design target stays a single screen with no
     scrollbar in view — see the max-width/max-height rules throughout this
     file that trim spacing so typical phones never reach it — but a device
     shorter than tuned-for, or a future line of copy, now scrolls a few
     pixels instead of stacking icons on top of button text. */
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
/* Two columns from 900px, with the DECK taking the larger share.
   22 cards on a ring need radius > 3.5x the card width or they overlap, so the
   card size is derived FROM the radius (see .ring-stage) rather than set
   independently — that keeps the gap constant at every width instead of
   letting the cards crowd as the column narrows. An even 50/50 split could only
   ever hold small cards; the copy needs less room than the deck does. */
@media (min-width: 900px) {
  .splash-main {
    display: grid;
    grid-template-columns: minmax(0, 1.22fr) minmax(0, 1fr);
    align-items: center; gap: clamp(18px, 2.4vw, 44px);
    padding-inline: clamp(20px, 3vw, 56px);
  }
  .splash-deck { grid-column: 1; width: 100%; }
  .splash-copy { grid-column: 2; }
}
.splash-deck { display: flex; flex-direction: column; align-items: center; width: 100%; }

/* NO panel around the copy — only the buttons are boxed. Legibility over the
   plate comes from text shadows instead.

   Four stacked definitions of this rule had accumulated here from successive
   passes; each edit added a new block without removing the old one, so the
   LAST one silently won and the panel kept coming back however many times it
   was "removed". One definition only. */
.splash-copy {
  display: flex; flex-direction: column; align-items: center; min-width: 0;
}
.splash-copy .splash-tag,
.splash-copy .splash-lead,
.splash-copy .splash-eyebrow,
.splash-copy .cd-n,
.splash-copy .cd-when,
.splash-copy .cd-label { text-shadow: 0 2px 16px rgba(5,5,6,0.95), 0 1px 4px rgba(5,5,6,0.9); }
.mark-num, .mark-sub { filter: drop-shadow(0 2px 18px rgba(5,5,6,0.9)); }

/* Page-load choreography — each element gets its own delay/duration rather than
   a generic stagger, matching the exact hero sequence. No static opacity:0 is
   ever set outside the animation itself, so `animation:none` under
   prefers-reduced-motion (see global rule below) naturally reveals everything
   immediately instead of leaving it stuck invisible. */
@keyframes heroFadeRise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

.splash-eyebrow {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.36em; text-transform: uppercase;
  color: var(--gold); margin-bottom: clamp(9px, 1.4vh, 16px);
  animation: heroFadeRise 0.6s var(--ease) 0s both;
}
/* The hero mark is TYPE, not the emblem.

   The emblem's interior is purple nebula — the same texture as the plate
   behind it — so it never read as an object sitting on the scene, and at hero
   size it covered the hooded figure's face no matter where it was moved. It is
   a seal: it still serves as the favicon, the nav mark, the loading mark and
   the card backs, which is what a seal is for.

   Set in Cormorant Garamond, which the page already loads — no new font, no
   image, zero extra bytes, and razor sharp at every size and pixel ratio. */
.splash-mark {
  display: flex; flex-direction: column; align-items: center;
  margin-top: clamp(6px, 1.5vh, 20px);
  animation: heroFadeRise 0.8s var(--ease) 0.15s both;
}
.mark-num {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(3rem, 7.4vw, 5.6rem); line-height: 1;
  /* Optical, not metric: at this size the default tracking looks cramped, and
     the trailing space keeps the last I from sitting off-centre. */
  letter-spacing: 0.06em; padding-left: 0.06em;
  background: linear-gradient(174deg, #f4e3b6 0%, var(--gold-bright) 38%, var(--gold) 66%, #8a6f37 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 18px rgba(197,164,96,0.30));
}
.mark-rule {
  width: min(220px, 58%); height: 1px; margin: clamp(7px, 1.1vh, 13px) 0 clamp(6px, 0.9vh, 10px);
  background: linear-gradient(90deg, transparent, var(--gold-dim) 22%, var(--gold) 50%, var(--gold-dim) 78%, transparent);
}
.mark-sub {
  font-family: var(--serif); font-style: italic; font-weight: 400;
  font-size: clamp(1.05rem, 2.2vw, 1.5rem); line-height: 1;
  letter-spacing: 0.14em; color: var(--gold-bright);
  text-shadow: 0 1px 14px rgba(5,5,6,0.9);
}
.splash-rule { margin: clamp(16px, 3vh, 28px) auto 0; }
/* The hero already has .mark-rule inside the lockup — a second divider a few
   pixels below repeats the same gesture and costs ~35px of a hero that has
   none to spare. */
.splash-main .ornament-divider { display: none; }
.splash-tag {
  font-family: var(--serif);
  color: var(--text); font-size: clamp(1.02rem, 2.2vw, 1.24rem); margin-top: clamp(8px, 1.2vh, 14px);
  animation: heroFadeRise 0.6s var(--ease) 0.6s both;
}
.splash-lead {
  color: var(--muted); font-size: 1.02rem; margin-top: 6px; max-width: 560px;
  animation: heroFadeRise 0.6s var(--ease) 0.6s both;
}

.splash-cta {
  display: flex; gap: 11px; margin-top: clamp(15px, 2.5vh, 26px); flex-wrap: wrap; justify-content: center;
  animation: heroFadeRise 0.6s var(--ease) 0.75s both;
}

.splash-features {
  list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
  gap: 8px 0; margin-top: clamp(22px, 4vh, 44px);
}
.splash-features li {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); padding: 0 clamp(12px, 2vw, 20px); position: relative;
}
.splash-features li:not(:last-child)::after {
  content: "◆"; position: absolute; right: -4px; top: 50%; transform: translateY(-50%);
  color: var(--gold-dim); font-size: 6px;
}

/* Bottom bar */
.splash-foot {
  position: relative; z-index: 3;
  display: flex; align-items: center; justify-content: flex-end; gap: 16px;
  padding: 16px clamp(20px, 4vw, 44px); border-top: 1px solid var(--line);
}
.splash-foot .copyright { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; color: var(--faint); white-space: nowrap; }
/* ---------- Social sigils ----------
   The landing's only outbound links, so they get the brand's own object rather
   than a grey pill: a ringed gold disc, the same anatomy as the logo mark —
   hairline outer ring, a second ring inset just inside it, dark centre. Lit
   from within on hover, the way every other gold element on this page is. */
.splash-foot .socials { gap: 10px; margin-right: auto; align-items: center; }
.splash-foot .socials a {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line-gold);
  background: radial-gradient(circle at 50% 38%, rgba(198,160,74,0.13), rgba(8,8,11,0.72) 72%);
  box-shadow: inset 0 0 0 3px rgba(5,5,6,0.9), inset 0 0 0 4px rgba(198,160,74,0.22);
  color: var(--gold-dim);
  transition: color 0.28s var(--ease), border-color 0.28s var(--ease),
              box-shadow 0.28s var(--ease), transform 0.28s var(--ease);
}
.splash-foot .socials a:hover,
.splash-foot .socials a:focus-visible {
  color: var(--gold-bright);
  border-color: var(--gold-bright);
  transform: translateY(-2px);
  box-shadow: inset 0 0 0 3px rgba(5,5,6,0.9), inset 0 0 0 4px rgba(230,200,132,0.5),
              0 0 18px -4px rgba(197,164,96,0.6);
}
.socials a svg { width: 14px; height: 14px; fill: currentColor; display: block; }
@media (prefers-reduced-motion: reduce) {
  .splash-foot .socials a, .splash-foot .socials a:hover { transform: none; }
}

@media (max-width: 620px) {
  .splash-nav .social { display: none; }
  .splash-features li { font-size: 10px; padding: 0 10px; }
  .splash-foot { flex-direction: column; gap: 6px; text-align: center; padding: 10px 20px; }
  /* The bar stacks and centres here; margin-right:auto would still shove the
     sigils to the left edge while the copyright sat centred under them. */
  .splash-foot .socials { margin-right: 0; justify-content: center; }
}
@media (max-height: 700px) {
  /* The footer is fixed height at the bottom of the flex column — every pixel
     it gives up is a pixel .splash-main doesn't need to scroll for. */
  .splash-foot { padding-top: 8px; padding-bottom: 8px; }
  .splash-foot .socials a { width: 28px; height: 28px; }
}
@media (max-height: 560px) {
  .splash-lead { display: none; }
  .splash-features { margin-top: 16px; }
}

/* =========================================================
   SPLASH MENU + CLICK-TO-OPEN PANELS (index.html)
   ========================================================= */
.splash-nav { position: relative; z-index: 20; }
.menu-toggle { display: none; background: none; border: none; color: var(--text); font-size: 22px; cursor: pointer; z-index: 5; }
.splash-menu { display: flex; align-items: center; gap: clamp(12px, 1.7vw, 22px); }
/* Was 11px in --muted. Small AND low-contrast is two problems stacking, and it
   sits over a moving plate where a flat contrast ratio does not tell the whole
   story. Bigger, brighter, and with real vertical padding so each item is a
   proper target rather than a 14px-tall sliver of text. */
.splash-menu a[data-panel] {
  font-family: var(--mono); font-size: 13.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: #d3cfc6; transition: color 0.28s var(--ease); cursor: pointer;
  padding: 10px 4px;
}
.splash-menu a[data-panel]:hover { color: var(--gold-bright); }

.splash-features li[data-panel] { cursor: pointer; transition: color 0.3s; }
.splash-features li[data-panel]:hover { color: var(--gold-bright); }

/* Overlay + panel card */
.panel-overlay {
  position: fixed; inset: 0; z-index: 150; display: none;
  align-items: center; justify-content: center; padding: 24px;
  background: rgba(3,3,4,0.82); backdrop-filter: blur(8px);
}
.panel-overlay.open { display: flex; animation: fade 0.3s; }
.panel {
  position: relative; width: 100%; max-width: 940px; max-height: 88vh; overflow-y: auto;
  background: linear-gradient(180deg, var(--panel), var(--ink));
  border: 1px solid var(--line-gold); border-radius: 16px;
  padding: 20px clamp(20px, 4vw, 48px) 44px;
  animation: rise 0.4s var(--ease);
}
.panel-close {
  position: sticky; top: 0; margin: 0 -8px 4px auto; display: block;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--muted); font-size: 22px; line-height: 1; cursor: pointer; z-index: 4; transition: all 0.3s;
}
.panel-close:hover { color: var(--gold); border-color: var(--line-gold); }

.panel-section { display: none; }
.panel-section.active { display: block; animation: fade 0.35s; }
.panel-head { margin-bottom: 26px; }
.panel-head .headline { margin-top: 6px; }
.panel-lead { color: var(--muted); margin-top: 14px; max-width: 620px; font-size: 1.02rem; }

/* panels reuse component classes; tame a few section-scale margins inside them */
.panel-section .draw-grid { align-items: center; }
.panel-section .grim-controls { margin-top: 8px; }
.panel-section .card-grid { margin-top: 20px; }
.panel-section .legend { margin-top: 26px; }
.panel-section .token-grid,
.panel-section .token-utils { margin-top: 8px; }
.panel-section .phases { margin-top: 8px; }

@media (max-width: 820px) {
  .menu-toggle { display: block; }
  .splash-menu {
    display: none; position: absolute; top: calc(100% + 6px); right: 16px; left: 16px;
    flex-direction: column; align-items: stretch; gap: 2px;
    background: var(--ink); border: 1px solid var(--line); border-radius: 12px; padding: 12px; z-index: 20;
  }
  .splash-menu.open { display: flex; animation: fade 0.25s; }
  /* 46px tall — above the 44px minimum a thumb needs. */
  .splash-menu a[data-panel] { padding: 15px 12px; font-size: 14px; border-bottom: 1px solid var(--line); }
  .splash-menu a[data-panel]:last-of-type { border-bottom: none; }
  .splash-menu .btn-sm { margin-top: 8px; justify-content: center; }
  .panel { padding: 16px 18px 32px; max-height: 90vh; }
}

/* ---------- Reincarnation variant subtitles (shared) ---------- */
.tcard-variant { font-family: var(--serif); font-style: italic; font-size: 0.78rem; color: var(--gold-bright); line-height: 1.1; margin-top: 1px; }
.modal-visual .nm-variant { font-family: var(--serif); font-style: italic; font-size: 1rem; color: var(--gold-bright); margin-top: 3px; }

/* ---------- Passive row (card detail modal) ---------- */
.passive-row { padding: 12px 0; border-top: 1px dashed var(--line-gold); margin-top: 4px; }
.passive-row .k { font-family: var(--mono); font-size: 9px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--gold); min-width: 52px; display: inline-block; }
.passive-row .v b { color: var(--gold-bright); font-weight: 600; }
.passive-row .v span { color: var(--muted); font-size: 0.85rem; }

/* ---------- Lineage filter (view all reincarnations of one Arcanum) ---------- */
.lineage-select {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  padding: 8px 14px; border: 1px solid var(--line); border-radius: 2px;
  background: var(--panel); color: var(--muted); cursor: pointer; transition: all 0.3s;
}
.lineage-select:hover { border-color: var(--line-gold); color: var(--text); }
.lineage-select:focus { outline: none; border-color: var(--gold); }

/* =========================================================
   HERO REDESIGN — signature card, ember particles, ornamental
   divider, card strip, nav underline (index.html splash)
   ========================================================= */

/* ---------- Signature tarot card (Death · Cinderfall) ---------- */
.hero-signature-card {
  position: absolute; z-index: 2; pointer-events: none;
  top: 10%; right: 7%;
  width: clamp(150px, 19vw, 300px); aspect-ratio: 3 / 5;
  border-radius: 16px; overflow: hidden;
  background-image:
    linear-gradient(to top, rgba(5,5,6,0.97) 0%, rgba(5,5,6,0.1) 48%, rgba(5,5,6,0.3) 100%),
    url('../assets/cards/art-32-death-cinderfall.webp');
  background-size: cover; background-position: center;
  box-shadow: 0 0 70px -8px rgba(217,102,63,0.45), 0 40px 80px -30px rgba(0,0,0,0.9);
  border: 1px solid rgba(217,102,63,0.3);
  opacity: 0.92; /* reduced-motion fallback resting state */
  transform: rotate(10deg);
  animation: sigCardIn 0.7s var(--ease) 0.3s both, sigCardFloat 8s ease-in-out 0.3s infinite;
}
@keyframes sigCardIn { from { opacity: 0; } to { opacity: 0.92; } }
@keyframes sigCardFloat {
  0%, 100% { transform: rotate(10deg) translateY(0); }
  50%      { transform: rotate(8.5deg) translateY(-12px); }
}
@media (max-width: 900px) {
  .hero-signature-card { width: clamp(110px, 30vw, 170px); top: 8%; right: 4%; opacity: 0.6; }
}
@media (max-width: 600px) {
  .hero-signature-card { top: 6%; right: 2%; width: clamp(90px, 26vw, 130px); opacity: 0.45; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-signature-card { animation: none; }
}

/* ---------- Ambient ember particles ---------- */
.ember-field { position: absolute; inset: 0; z-index: 1; pointer-events: none; overflow: hidden; }
.ember-particle {
  position: absolute; bottom: -10px; border-radius: 50%;
  background: var(--gold-dim);
  animation: emberFloat linear infinite;
}
@keyframes emberFloat {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  10%  { opacity: var(--ember-op, 0.4); }
  90%  { opacity: var(--ember-op, 0.4); }
  100% { transform: translateY(-115vh) translateX(var(--ember-drift, 20px)); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ember-particle { display: none; }
}

/* ---------- Ornamental divider (hero + panel heads) ---------- */
.ornament-divider {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: clamp(16px, 3vh, 28px) auto 0; width: 100%;
}
.panel-head .ornament-divider { justify-content: flex-start; margin: 14px 0 0; }
.odiv-line {
  width: 34px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold)); 
}
.panel-head .odiv-line:first-child,
.ornament-divider .odiv-line:first-child { background: linear-gradient(90deg, transparent, var(--gold)); }
.ornament-divider .odiv-line:last-child { background: linear-gradient(90deg, var(--gold), transparent); }
.odiv-sigil { color: var(--gold); font-size: 11px; opacity: 0.85; line-height: 1; }

/* Hero instance only: lines grow outward from the center sigil on page load.
   Panel-head instances stay static (they open on click, not on page load). */
@keyframes odivLineExpand { from { width: 0; } to { width: 34px; } }
.splash-main .ornament-divider .odiv-line { animation: odivLineExpand 0.7s var(--ease) 0.5s both; }
.splash-main .ornament-divider .odiv-sigil { animation: heroFadeRise 0.4s var(--ease) 0.75s both; }

/* ---------- Card strip (real illustrations under the CTA) ---------- */
.card-strip {
  display: flex; justify-content: center; margin-top: clamp(24px, 4vh, 44px);
  animation: heroFadeRise 0.5s var(--ease) 0.85s both; /* container fades in; cards below stagger their own opacity */
}
.strip-card {
  position: relative; width: clamp(64px, 8vw, 96px); aspect-ratio: 3 / 5; border-radius: 8px;
  background-size: cover; background-position: center;
  border: 1px solid var(--line); overflow: hidden; cursor: pointer;
  margin-left: -22px;
  transition: box-shadow 0.35s var(--ease), border-color 0.35s var(--ease), z-index 0s;
  box-shadow: 0 10px 24px -10px rgba(0,0,0,0.7);
  /* Idle float is the resting state (0%/100% = the card's own --card-tilt), so
     it composes cleanly with the entrance fade without fighting over transform. */
  animation:
    stripCardIn 0.5s var(--ease) calc(0.9s + var(--strip-i, 0) * 0.05s) both,
    idleFloat var(--idle-dur, 4.5s) ease-in-out var(--idle-delay, 0s) infinite;
}
@keyframes stripCardIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes idleFloat {
  0%, 100% { transform: translateY(0) rotate(var(--card-tilt, 0deg)); }
  50%      { transform: translateY(-6px) rotate(var(--card-tilt, 0deg)); }
}
.strip-card:first-child { margin-left: 0; }
.strip-card::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(5,5,6,0.75), transparent 55%);
}
.strip-card:hover {
  animation-play-state: paused;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease), border-color 0.35s var(--ease), z-index 0s;
  transform: translateY(-10px) rotate(0deg) scale(1.08) perspective(400px) rotateY(6deg);
  z-index: 5; border-color: var(--el-color, var(--gold));
  box-shadow: 0 20px 40px -14px rgba(0,0,0,0.85), 0 0 22px -4px var(--el-color, var(--gold));
}
.strip-card.rar-rare { border-color: rgba(197,164,96,0.45); }
.strip-card.rar-legendary { border-color: var(--gold-bright); box-shadow: 0 0 18px -6px var(--gold-bright), 0 10px 24px -10px rgba(0,0,0,0.7); }
.strip-card.rar-legendary:hover { box-shadow: 0 20px 40px -14px rgba(0,0,0,0.85), 0 0 26px -2px var(--oxblood-bright), 0 0 14px -2px var(--gold-bright); border-color: var(--oxblood-bright); }
@media (max-width: 560px) {
  .strip-card { width: clamp(50px, 15vw, 70px); margin-left: -16px; }
}

/* ---------- Nav link underline hover ---------- */
.splash-menu a[data-panel] { display: inline-block; }
.splash-menu a[data-panel]::after {
  content: ""; position: absolute; bottom: 4px; left: 50%; width: 0; height: 1px;
  background: var(--gold); transition: all 0.3s var(--ease); transform: translateX(-50%);
}
.splash-menu a[data-panel] { position: relative; }
.splash-menu a[data-panel]:hover::after { width: 100%; }

/* =========================================================
   HERO CINEMATIC PLATE
   The source footage is 752x416, so it is never shown sharp: blurred, dimmed
   and vignetted it reads as depth behind the mark, which is what the hero was
   missing. Shown sharp it would just look like a low-resolution video.
   ========================================================= */
.hero-video {
  /* z-index 1, not 0: .hero-bg is a LATER sibling at z0, so at z0 the footage
     painted underneath the old gradient backdrop and the hero read as flat
     black with the video "playing" invisibly. At z1 it sits above hero-bg and
     the cursor glow, below the fog (later sibling at z1) and the scrim. */
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity 1.6s var(--ease);
  filter: saturate(0.95) contrast(1.08) brightness(0.85) blur(0.5px);
  transform: scale(1.08);           /* hides the blur's soft edge */
}
.hero-video.ready { opacity: 0.8; }
/* NO blanket rule on .splash children here. An earlier version set
   `position: relative` on all of them to force them above the plate — which
   dropped .hero-signature-card, .hero-fog, .ember-field and
   .hero-cursor-glow out of absolute positioning and into the flex column.
   The floating card jumped to the left edge and the nav was shoved into the
   middle of the logo. The splash already has a working stack: hero-bg 0,
   hero-fog 1, nav/main 3 — the plate only has to sit at the bottom of it.
   Keeps the mark and the copy legible over moving footage. */
.splash::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(ellipse 58% 50% at 50% 46%, rgba(5,5,6,0.5) 0%, rgba(5,5,6,0.88) 58%, rgba(5,5,6,0.97) 100%),
    linear-gradient(180deg, rgba(5,5,6,0.92) 0%, transparent 24%, transparent 70%, rgba(5,5,6,0.97) 100%);
}
@media (prefers-reduced-motion: reduce) { .hero-video { display: none; } }

/* ---------- Hero: fit the viewport HEIGHT, not just its width ----------
   The splash never scrolls, so on a short viewport the stack (eyebrow → mark →
   divider → tagline → lead → CTA → card strip) simply grew past the top and
   ran into the nav — at 1440x900 the eyebrow was sitting on the menu. Every
   size below is already width-clamped; these clamp them against height too. */
@media (max-height: 940px) {
  .splash-eyebrow { margin-bottom: 10px; font-size: 11px; }
  .splash-tag { margin-top: 12px; }
  .splash-lead { margin-top: 8px; font-size: 0.92rem; }
  .splash-cta { margin-top: 20px; }
  .splash-main { padding-top: 4px; }
}
@media (max-height: 820px) {
  .splash-lead { display: none; }        /* the tagline already carries it */
  .splash-cta { margin-top: 16px; }
}

/* The plate needs to survive the scrim. Darkening is concentrated where the
   copy actually sits (centre and lower third) instead of flat across the frame,
   so the footage still reads at the top and sides. */
/* The footage is the point now — darkening concentrates in a tight core
   behind the wordmark/CTA column and the extreme edges, and nowhere else. */
.hero-video.ready { opacity: 0.8; }
.splash::after {
  background:
    radial-gradient(ellipse 34% 34% at 50% 46%, rgba(5,5,6,0.55) 0%, rgba(5,5,6,0.22) 60%, transparent 80%),
    linear-gradient(180deg, rgba(5,5,6,0.6) 0%, transparent 18%, transparent 74%, rgba(5,5,6,0.72) 100%);
}

/* ---------- Token: hard facts before the poetry ----------
   A game token page is judged on whether the boring numbers are stated plainly
   and early. Chain, supply, mint authority and tax belong above the utility
   copy, not buried in it. */
.token-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px; margin: 22px 0 6px;
}
.token-facts .fact {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px;
  background: rgba(255,255,255,0.015);
}
.token-facts .k {
  display: block; font-family: var(--mono); font-size: 9px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--faint); margin-bottom: 5px;
}
.token-facts .v { font-family: var(--serif); font-size: 1.02rem; color: var(--gold-bright); }

.util-head {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--gold-dim); margin: 26px 0 12px; text-align: center;
}
.util-note {
  font-size: 0.88rem; color: var(--muted); line-height: 1.6; margin-top: 16px;
  padding: 13px 16px; border-left: 2px solid var(--line-gold); background: rgba(197,164,96,0.04);
}
.util-note b { color: var(--gold-bright); }

/* ---------- Roadmap ---------- */
.phase.done .node { background: var(--gold-dim); box-shadow: 0 0 0 3px rgba(138,116,66,0.18); }
.phase.done .state { color: var(--earth); border-color: color-mix(in srgb, var(--earth) 45%, transparent); }
.roadmap-note {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em; color: var(--faint);
  text-align: center; margin-top: 22px; font-style: italic;
}

/* ---------- Panel banner ----------
   A cinematic band at the head of each panel. Masked to nothing at the bottom
   so the artwork dissolves into the panel instead of ending on a hard edge. */
.panel-banner {
  position: relative; height: clamp(120px, 17vh, 190px); margin: -28px -28px 4px;
  background-size: cover; background-position: center 42%;
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0%, #000 42%, transparent 100%);
  opacity: 0.85;
}
.panel-banner::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5,5,6,0.5) 0%, rgba(5,5,6,0.1) 45%, rgba(5,5,6,0.85) 100%);
}
@media (max-width: 700px) { .panel-banner { margin: -20px -20px 2px; height: clamp(96px, 14vh, 140px); } }

/* Per-panel banner art. Two tiers, picked by the same .assets-sm switch the
   game uses, so a phone never pulls the 1400px plates. */
.pb-reading  { background-image: url('../assets/panels/reading.webp'); }
.pb-draw     { background-image: url('../assets/panels/draw.webp'); }
.pb-grimoire { background-image: url('../assets/panels/grimoire.webp'); }
.pb-duel     { background-image: url('../assets/panels/duel.webp'); }
.pb-token    { background-image: url('../assets/panels/token.webp'); }
.pb-roadmap  { background-image: url('../assets/panels/roadmap.webp'); }
.pb-faq      { background-image: url('../assets/panels/faq.webp'); }
.assets-sm .pb-reading  { background-image: url('../assets/panels/reading-sm.webp'); }
.assets-sm .pb-draw     { background-image: url('../assets/panels/draw-sm.webp'); }
.assets-sm .pb-grimoire { background-image: url('../assets/panels/grimoire-sm.webp'); }
.assets-sm .pb-duel     { background-image: url('../assets/panels/duel-sm.webp'); }
.assets-sm .pb-token    { background-image: url('../assets/panels/token-sm.webp'); }
.assets-sm .pb-roadmap  { background-image: url('../assets/panels/roadmap-sm.webp'); }
.assets-sm .pb-faq      { background-image: url('../assets/panels/faq-sm.webp'); }

/* Duel panel: a real capture of the board, not a hand-built mockup. The old
   one had drifted badly — it showed 3v3 when the Master trial is five a side,
   listed skills with pow/acc that combat never uses, and quoted HP values no
   card has any more. A screenshot cannot drift. */
.duel-shot { margin: 0; }
.duel-shot img {
  width: 100%; height: auto; display: block; border-radius: 12px;
  border: 1px solid var(--line); box-shadow: 0 24px 60px -24px rgba(0,0,0,0.95);
}
.duel-shot figcaption {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--faint); margin-top: 9px; text-align: center;
}
.duel-soon { font-family: var(--mono); font-size: 10px; letter-spacing: 0.06em; color: var(--faint); margin-top: 10px; }

/* =========================================================
   STORY PLAYER
   Four separate clips played back to back on one <video>. There is no encoder
   in this project to concatenate them, so the playlist advances in JS on
   `ended` — which also means each clip can carry its own caption.
   ========================================================= */
.btn-story { letter-spacing: 0.18em; }
.story-overlay {
  position: fixed; inset: 0; z-index: 900; display: none;
  align-items: center; justify-content: center; background: #000;
}
.story-overlay.open { display: flex; animation: storyIn 0.4s var(--ease); }
@keyframes storyIn { from { opacity: 0; } to { opacity: 1; } }
.story-video { width: 100%; height: 100%; object-fit: cover; }
.story-overlay::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(5,5,6,0.55) 0%, transparent 22%, transparent 62%, rgba(5,5,6,0.9) 100%);
}
/* Subtitles. Sat over the overlay's own bottom gradient so they stay legible
   on a bright frame without a plate behind the type. */
.story-caption {
  position: absolute; left: 50%; bottom: clamp(78px, 13vh, 132px);
  transform: translateX(-50%) translateY(10px);
  width: min(880px, 86vw); text-align: center; z-index: 2;
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1.15rem, 2.3vw, 1.85rem); line-height: 1.45;
  letter-spacing: 0.012em; color: #f6ecd8;
  text-shadow: 0 2px 4px rgba(0,0,0,0.95), 0 6px 26px rgba(0,0,0,0.9);
  opacity: 0; transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
}
.story-caption.show { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .story-caption { transition: opacity 0.3s linear; transform: translateX(-50%); }
  .story-caption.show { transform: translateX(-50%); }
}

/* One continuous film, so one continuous bar — driven from currentTime in JS. */
.story-progress {
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: rgba(255,255,255,0.14); z-index: 2; overflow: hidden;
}
.story-progress i {
  display: block; width: 100%; height: 100%; background: var(--gold-bright);
  transform: scaleX(0); transform-origin: left;
}
.story-close, .story-skip {
  position: absolute; z-index: 3; background: rgba(5,5,6,0.6);
  border: 1px solid rgba(255,255,255,0.2); color: #fff; cursor: pointer;
  font-family: var(--mono); transition: border-color 0.25s, color 0.25s;
}
.story-close { top: 18px; right: 20px; width: 38px; height: 38px; border-radius: 50%; font-size: 20px; line-height: 1; }
.story-skip { bottom: 24px; right: 24px; padding: 9px 18px; border-radius: 24px; font-size: 10px; letter-spacing: 0.2em; text-transform: uppercase; }
.story-close:hover, .story-skip:hover { border-color: var(--gold-bright); color: var(--gold-bright); }


/* =========================================================
   THE RING — 22 commons on a draggable 3D carousel
   Radius formula: (cardW/2) / tan(180°/22). At 116px cards that is ~404px,
   which with perspective fits a 1440px hero; the phone size drops both.
   Only .ring-track transforms per frame — the cards never change style, so a
   spin is pure re-composition of 22 cached layers.
   ========================================================= */
/* ---------- The deck ----------
   A horizontal 3D carousel. Perspective SCALES the front card: at z=+R with
   1200px perspective the nearest face renders ~1.5x its layout size, so the
   stage height budgets for the PROJECTED card (w * 5/3 * 1.55), not the layout
   one — the first cut clipped every front card at the fold. */
.ring-stage {
  /* Radius drives the card size, not the other way round. With 11 cards the
     step is 32.7deg and the chord between neighbours is 2R*sin(16.36deg) =
     0.563R; dividing by 1.95 leaves that chord ~10% wider than a card, so the
     gap holds at every viewport automatically. (At 22 cards the same rule
     demanded R > 3.86w — which is why one ring could never hold big cards in a
     column this narrow, and why the deck is split in two.) */
  --ring-r: clamp(120px, 14vw, 268px);
  --ring-w: calc(var(--ring-r) / 1.95);
  position: relative; width: 100%; height: calc(var(--ring-w) * 2.62);
  margin-top: clamp(6px, 1.2vh, 14px); margin-bottom: 0;
  perspective: 1250px;
  /* `none`, not `pan-y`: the splash never scrolls, so reserving vertical pan
     bought nothing and cost everything — Chrome claimed each touch for a
     possible scroll and fired pointercancel instead of pointerup, so tapping a
     card on a phone did nothing at all. */
  touch-action: none; cursor: grab; user-select: none;
}
.ring-stage:active { cursor: grabbing; }
.ring-track {
  position: absolute; left: 50%; top: 50%; width: 0; height: 0;
  transform-style: preserve-3d; will-change: transform;
}
.ring-card {
  position: absolute; left: calc(var(--ring-w) / -2); top: calc(var(--ring-w) * -0.93);
  width: var(--ring-w); aspect-ratio: 3 / 5;
  transform: rotateY(calc(var(--i) * var(--step, 32.7273deg))) translateZ(var(--ring-r));
  transform-style: preserve-3d; cursor: pointer;
}
.ring-face {
  position: absolute; inset: 0; border-radius: 9px; overflow: hidden;
  border: 1px solid var(--line-gold);
  background-size: cover; background-position: center;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: 0 12px 30px -10px rgba(0,0,0,0.85);
}
.ring-front::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5,5,6,0.25) 0%, transparent 30%, transparent 62%, rgba(5,5,6,0.85) 100%);
}
.ring-roman {
  position: absolute; left: 0; right: 0; bottom: 7px; z-index: 2; text-align: center;
  font-family: var(--serif); font-size: 1.25rem; color: var(--gold-bright);
  text-shadow: 0 1px 6px rgba(0,0,0,0.9);
}
/* The reverse of every card is the shared back, so the far side of the ring
   reads as a face-down deck rather than as the backs of pictures. */
.ring-back {
  transform: rotateY(180deg);
  background-image: url('../assets/cards/card-back.webp');
  filter: brightness(0.8);
}
@media (max-width: 900px) {
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
}
@media (max-width: 520px) {
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
  .ring-roman { font-size: 0.78rem; }
}
/* Height-constrained heroes: the ring replaces the old lead copy entirely. */
@media (max-height: 940px) {
  .ring-stage { margin-top: 8px; }
}
/* ---------- Countdown ----------
   Set as an inscription, not a dashboard widget: no cards, no boxes, no
   gradients. Serif numerals in gold, hairline rules between units, mono labels
   underneath. Tabular figures so the seconds column does not jitter the whole
   row as digits change width. */
.countdown {
  position: relative; isolation: isolate;
  margin-top: clamp(10px, 1.6vh, 18px);
  animation: heroFadeRise 0.6s var(--ease) 0.68s both;
}
/* The ellipse of shade that used to sit behind this is gone — .splash-copy is a
   panel now and does the job for every line at once. */
.countdown[hidden] { display: none; }
.cd-label {
  font-family: var(--mono); font-size: 13px; letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--gold); margin-bottom: 10px;
}
.cd-tick {
  font-weight: 700; letter-spacing: 0.1em;
  padding: 2px 7px; border-radius: 4px; margin-right: 2px;
  background: rgba(197,164,96,0.20); color: var(--gold-bright);
}
.cd-clock { display: flex; align-items: flex-start; justify-content: center; gap: 0; }
.cd-unit {
  display: flex; flex-direction: column; align-items: center;
  padding: 0 clamp(14px, 2.6vw, 26px);
}
.cd-unit + .cd-unit { border-left: 1px solid var(--line-gold); }
.cd-n {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(1.7rem, 4vw, 2.5rem); line-height: 1;
  color: var(--gold-bright); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px rgba(197,164,96,0.28);
}
.cd-when {
  font-family: var(--mono); font-size: 15px; letter-spacing: 0.06em;
  color: #cfcac1; margin-top: 12px;
}
@media (max-width: 420px) {
  .cd-unit { padding: 0 clamp(9px, 3.4vw, 16px); }
}

/* The landing reading shows no battle numbers at all — passive, HP and ATK
   belong to the lobby. This used to be done by hiding .passive-row inside the
   old two-column modal; openModal simply never renders one now. */

/* Short viewports. The splash never scrolls, so anything that does not fit is
   clipped at BOTH ends — the eyebrow slides under the nav and the wheel runs
   past the footer. Order of sacrifice: wheel arc first, then the lead line,
   never the countdown or the CTA. */
@media (max-height: 820px) {
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
  .splash-mark { margin-top: clamp(8px, 2vh, 26px); }
}
@media (max-height: 700px) {
  .splash-lead { display: none; }
  .ornament-divider { display: none; }
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
  .cd-n { font-size: clamp(1.5rem, 4vw, 2.1rem); }
}


/* ---------- Phone: the wheel stacks above the copy ----------
   Both have to fit in one no-scroll screen, so the wheel is sized from what is
   left after the copy, not the other way round — the deck is the decoration,
   the countdown and the button are the reason anyone is here. */
@media (max-width: 899px) {
  .splash-main { gap: clamp(6px, 1.4vh, 14px); }
  .splash-deck { order: 1; }
  .splash-copy { order: 2; }
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
  .splash-lead { display: none; }          /* the tagline above already says it */
  .mark-num { font-size: clamp(2.5rem, 13vw, 3.4rem); }
  .mark-sub { font-size: clamp(0.95rem, 4.4vw, 1.2rem); }
  .mark-rule { margin: 8px 0 6px; }
}
@media (max-width: 899px) and (max-height: 720px) {
  .ring-stage { --ring-r: clamp(104px, 26vw, 190px); }
  .ornament-divider { display: none; }
}

/* ---------- The reading card (landing) ----------
   One portrait card, full-bleed art, everything set over the foot of the
   image. Replaces the old two-column art+stats modal — see openModal(). */
.modal-card.reading-card {
  position: relative;
  width: auto; max-width: none;
  height: min(78vh, 620px);
  aspect-ratio: 3 / 5;
  max-height: none; overflow: hidden;
  display: block; padding: 0;
  border: 1px solid var(--line-gold); border-radius: 14px;
  background-color: var(--card-black);
  background-image:
    linear-gradient(to top, rgba(4,4,5,0.97) 0%, rgba(4,4,5,0.86) 26%,
                            rgba(4,4,5,0.10) 58%, rgba(4,4,5,0.30) 100%),
    var(--art-url, none);
  background-size: cover, cover;
  background-position: center, center;
  box-shadow: 0 34px 90px -30px #000, 0 0 40px -14px rgba(197,164,96,0.28);
}
@media (max-width: 640px) {
  .modal-card.reading-card { height: auto; width: min(86vw, 380px); }
}
/* Rarity reads as the strength of the rim light, not as a coloured chrome. */
.reading-card.rar-rare   { box-shadow: 0 34px 90px -30px #000, inset 0 0 0 1px rgba(197,164,96,0.45); }
.reading-card.rar-legendary {
  border-color: var(--gold-bright);
  box-shadow: 0 34px 90px -30px #000, inset 0 0 0 1px rgba(230,200,132,0.75),
              inset 0 0 46px -12px rgba(230,200,132,0.45), 0 0 60px -18px rgba(230,200,132,0.4);
}
.reading-card .modal-close {
  position: absolute; top: 12px; right: 14px; z-index: 4;
  width: 32px; height: 32px; border-radius: 50%;
  background: rgba(5,5,6,0.55); border: 1px solid var(--line);
  color: var(--muted); font-size: 19px; line-height: 1; cursor: pointer;
  transition: color 0.3s, border-color 0.3s;
}
.reading-card .modal-close:hover { color: var(--gold-bright); border-color: var(--line-gold); }
.rd-roman {
  position: absolute; top: 16px; left: 22px; z-index: 3;
  font-family: var(--serif); font-size: 2.4rem; line-height: 1; color: #fff;
  text-shadow: 0 2px 16px rgba(0,0,0,0.95);
}
.rd-foot {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 0 clamp(20px, 5%, 30px) clamp(20px, 5%, 28px);
  text-align: left;
}
.rd-name {
  font-family: var(--serif); font-size: clamp(1.5rem, 4.4vw, 2rem);
  line-height: 1.1; color: #fff;
}
.rd-variant {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(0.95rem, 2.6vw, 1.1rem); color: var(--gold-bright); margin-top: 2px;
}
.rd-el {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--el-color); margin-top: 9px;
}
.rd-blurb {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(1rem, 2.7vw, 1.16rem); line-height: 1.5;
  color: var(--gold-bright); margin: 12px 0 0;
  /* A hairline above the reading separates it from the card's own name block
     without adding a panel. */
  padding-top: 12px; border-top: 1px solid rgba(197,164,96,0.22);
}

/* The reading card tilts to the pointer, exactly as the in-game draw card does
   — the perspective lives on the backdrop so the card rotates in the scene
   rather than inside its own flat box. */
.modal { perspective: 1400px; }
.modal-card.reading-card {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform 0.5s var(--ease);
  will-change: transform;
}
.modal-card.reading-card.tilting { transition: none; }   /* 1:1 with the pointer */
/* Element mark, matching the badge on the in-game card. */
.rd-glyph {
  position: absolute; right: 18px; bottom: 132px; z-index: 3;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 18px; color: var(--el-color);
  border: 1px solid color-mix(in srgb, var(--el-color) 55%, transparent);
  background: rgba(5,5,6,0.45);
  text-shadow: 0 0 14px color-mix(in srgb, var(--el-color) 60%, transparent);
}
@media (max-width: 640px) { .rd-glyph { width: 34px; height: 34px; font-size: 15px; bottom: 118px; } }
@media (prefers-reduced-motion: reduce) {
  .modal-card.reading-card { transform: none !important; }
}

/* ---------- Buy ----------
   Reads as a coin, not a third ghost button: gold rule, the ticker set in mono
   ahead of the word. Muted while there is no contract to point at. */
.btn-buy {
  display: inline-flex; align-items: center; gap: 9px;
  border: 1px solid var(--gold-dim); background: rgba(197,164,96,0.07);
  color: var(--gold-bright);
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease);
}
.btn-buy:hover:not(.pending) {
  border-color: var(--gold-bright); background: rgba(197,164,96,0.16); color: #fff;
}
.buy-tick {
  font-family: var(--mono); font-size: 0.72em; letter-spacing: 0.08em;
  padding: 2px 6px; border-radius: 4px;
  background: rgba(197,164,96,0.18); color: var(--gold-bright);
}
.btn-buy.pending {
  border-color: var(--line); background: none; color: var(--muted); cursor: default;
}
.btn-buy.pending .buy-tick { background: rgba(255,255,255,0.05); color: var(--faint); }

/* The two rings sit as one stacked object in the deck column. */
.splash-deck .ring-stage + .ring-stage { margin-top: clamp(4px, 0.8vh, 12px); }

/* ---------- Phone: two rings have to earn their height ----------
   Stacked, the deck is the tallest thing on the page. Four actions in a 2x2
   grid (Enter the Dark + Buy on top, The Fate + The Story below) instead of
   flex-wrapping, so the row count is decided here rather than by whatever
   happens to fit — this is the ONE definition of the mobile CTA layout; two
   earlier ones from before "The Story" existed are gone, they only ever
   fought this rule for a browser's attention and .splash-main's own overflow
   scroll (above) is what actually keeps a loss from becoming visible overlap. */
@media (max-width: 899px) {
  .splash-cta {
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 8px; width: 100%; max-width: 360px;
  }
  .splash-cta .btn { flex: none; justify-content: center; padding: 11px 10px; font-size: 0.76rem; }
  .cd-n { font-size: clamp(1.5rem, 8vw, 2rem); }
  .cd-unit { padding: 0 clamp(8px, 3vw, 14px); }
  .countdown { margin-top: clamp(6px, 1vh, 12px); }
  .cd-when { font-size: 10.5px; margin-top: 6px; }
  .ring-stage { --ring-r: clamp(72px, 17vw, 136px); }
  .splash-deck .ring-stage + .ring-stage { margin-top: clamp(2px, 0.5vh, 8px); }
  .splash-eyebrow { margin-bottom: 6px; }
  .splash-mark { margin-top: clamp(4px, 1vh, 14px); }
  .splash-tag { margin-top: 6px; }
}

/* The copy panel has to earn its padding on a phone — the splash never scrolls,
   so every pixel of frame comes straight out of the deck below it. */


/* ---------- Hero buttons ----------
   The boxes live here and nowhere else. Same treatment as the lobby's utility
   chips so the two screens read as one product: warm dark gradient, gold border,
   an inset top highlight for a lit edge. */
.splash-cta .btn-ghost,
.splash-cta .btn-buy {
  background: linear-gradient(180deg, rgba(38,30,16,0.94) 0%, rgba(14,11,8,0.96) 100%);
  border: 1px solid rgba(197,164,96,0.42);
  box-shadow: inset 0 1px 0 rgba(230,200,132,0.14), 0 6px 20px rgba(0,0,0,0.5);
  backdrop-filter: blur(6px);
  transition: border-color 0.28s var(--ease), background 0.28s var(--ease), box-shadow 0.28s var(--ease);
}
.splash-cta .btn-ghost:hover,
.splash-cta .btn-buy:hover:not(.pending) {
  border-color: rgba(230,200,132,0.72);
  background: linear-gradient(180deg, rgba(52,41,20,0.95) 0%, rgba(20,16,10,0.96) 100%);
  box-shadow: inset 0 1px 0 rgba(230,200,132,0.22), 0 10px 26px rgba(0,0,0,0.6);
}
.splash-cta .btn-buy.pending {
  background: linear-gradient(180deg, rgba(26,24,20,0.92) 0%, rgba(12,11,9,0.95) 100%);
  border-color: rgba(197,164,96,0.22);
}
