/* STARFALL — cozy sky duel */
* { box-sizing: border-box; margin: 0; padding: 0; user-select: none; }

:root {
  --gold: #ffd66b;
  --gold-deep: #f0a830;
  --indigo: #2a2a5e;
  --indigo-deep: #1a1a3e;
  --lavender: #b8a9e8;
  --cream: #fff6e0;
  /* Swift is first light: a white core burning out into an ember rim. Amber is
     the one hue the board has not spent — green says can-attack, red says enemy
     target, blue friendly target, gold selected, mint settling. */
  --swift-core: #fffaf0;
  --swift-light: #ffe6a0;
  --swift-edge: #ffb42e;
  --swift-deep: #e07a10;
  --swift-ink: #6b3f06;
  --card-w: 150px;
  /* 204 left no room for a unit's attack/health badges, which are laid across
     the card's foot: seventeen units had rules text running underneath their
     own numbers and three cards lost a line off the bottom entirely. The extra
     height is what those badges occupy; js/cardfit.js takes up the rest. */
  --card-h: 218px;
  --unit-w: 128px;
  --unit-h: 160px;
  /* the phone's notch, home bar and rounded corners (zero on a desktop).
     The page is allowed to paint under them (viewport-fit=cover, so the sky
     reaches the edges) and anything you read or tap keeps clear instead. */
  --sat: env(safe-area-inset-top, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  --sal: env(safe-area-inset-left, 0px);
}

html, body { height: 100%; overflow: hidden; }
body {
  font-family: 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
  color: var(--cream);
  background: linear-gradient(180deg, #2b3a67 0%, #4a5a8a 50%, #7a6a9a 100%);
  transition: background 2.5s ease;
}
body.phase-morning {
  background: linear-gradient(180deg, #ff9a76 0%, #ffc38a 40%, #ffe0b3 100%);
}
body.phase-afternoon {
  background: linear-gradient(180deg, #4a90d9 0%, #7ab8e8 50%, #b8ddf0 100%);
}
body.phase-night {
  background: linear-gradient(180deg, #12123a 0%, #232360 55%, #43427e 100%);
}
body.phase-morning, body.phase-afternoon { color: #3a2a1a; }

#app {
  height: 100%; display: flex; flex-direction: column; position: relative;
  padding: var(--sat) var(--sar) var(--sab) var(--sal);
}

/* ------- ambient sky ------- */
#sky {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden; z-index: 0;
}
.bglayer {
  position: absolute; inset: 0;
  background-size: cover; background-position: center bottom;
  opacity: 0; transition: opacity 2.8s ease;
}

/* traced constellations painted into the owner's sky */
.skyconst {
  position: absolute; width: 160px; height: 160px; pointer-events: none;
  mix-blend-mode: screen; opacity: 0; transition: opacity 2.5s ease;
  -webkit-mask-image: radial-gradient(circle, #000 30%, transparent 66%);
  mask-image: radial-gradient(circle, #000 30%, transparent 66%);
}
.skyconst.shown { opacity: 0.95; }

/* celestial clock: soft painted sun/moon disc arcing with the round */
#celestial {
  position: absolute; width: 90px; height: 90px; pointer-events: none;
  transition: left 3s ease, top 3s ease, opacity 2s ease; opacity: 0;
}
#celestial.sun {
  opacity: 0.95;
  background: radial-gradient(circle, #fff4c8 0%, #ffd66b 28%, rgba(255, 190, 80, 0.55) 46%, transparent 70%);
}
#celestial.moon {
  opacity: 0.95;
  background: radial-gradient(circle, #fdfbf2 0%, #e8e4d0 22%, rgba(220, 215, 235, 0.45) 42%, transparent 68%);
}

/* soft painterly cloud wisps (parallax drift) */
.cloudwisp {
  position: absolute; pointer-events: none; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255,255,255,0.85) 0%, rgba(255,255,255,0.35) 55%, transparent 75%);
  filter: blur(6px);
  animation: wispdrift linear infinite;
}
@keyframes wispdrift {
  from { transform: translateX(-260px); }
  to   { transform: translateX(115vw); }
}

/* weather overlays */
.weather-rain {
  position: fixed; inset: 0; z-index: 55; pointer-events: none;
  background: repeating-linear-gradient(78deg,
    transparent 0 13px, rgba(160, 208, 255, 0.5) 13px 15px, transparent 15px 30px);
  animation: rainfall 0.5s linear infinite, weatherfade 3s ease forwards;
}
@keyframes rainfall { from { background-position: 0 0; } to { background-position: -34px 120px; } }
.weather-fog {
  position: fixed; left: -30%; top: 25%; width: 160%; height: 45%; z-index: 55;
  pointer-events: none; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255,255,255,0.75), rgba(255,255,255,0.3) 60%, transparent 78%);
  filter: blur(16px);
  animation: fogroll 4s ease forwards;
}
@keyframes fogroll {
  0% { transform: translateX(-14%); opacity: 0; }
  25% { opacity: 1; } 75% { opacity: 1; }
  100% { transform: translateX(14%); opacity: 0; }
}
.weather-flash {
  position: fixed; inset: 0; z-index: 55; pointer-events: none;
  background: rgba(255, 250, 220, 0.85);
  animation: flashpop 0.65s ease forwards;
}
@keyframes flashpop {
  0% { opacity: 0; } 12% { opacity: 1; } 24% { opacity: 0.15; }
  36% { opacity: 0.7; } 100% { opacity: 0; }
}
@keyframes weatherfade {
  0% { opacity: 0; } 15% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; }
}
.shooting-star {
  position: fixed; z-index: 55; pointer-events: none; font-size: 30px;
  filter: drop-shadow(0 0 10px rgba(255, 230, 140, 0.95));
  animation: shoot 1.6s ease-in forwards;
}
.shooting-star::after {
  content: ''; position: absolute; right: 55%; top: 42%; width: 190px; height: 4px;
  background: linear-gradient(90deg, transparent, rgba(255, 235, 160, 0.9));
  border-radius: 2px; transform: rotate(9deg);
}
@keyframes shoot {
  from { transform: translate(0, 0) rotate(-8deg); opacity: 1; }
  70% { opacity: 1; }
  to { transform: translate(-52vw, 26vh) rotate(-8deg); opacity: 0; }
}
.skystar {
  position: absolute; font-size: 14px; opacity: 0.9;
  animation: twinkle 2.4s ease-in-out infinite;
  transition: top 1s ease, left 1s ease;
}
@keyframes twinkle {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.25); }
}
.skystar.newborn { animation: rise 1.2s ease-out, twinkle 2.4s 1.2s ease-in-out infinite; }
@keyframes rise {
  from { transform: translateY(190px) scale(0.4); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}

/* ------- layout rows ------- */
.row { position: relative; z-index: 1; }
#ai-strip {
  display: flex; align-items: center; gap: 16px; padding: 8px 16px; min-height: 76px;
  flex-shrink: 0;
}
#ai-hand { display: flex; gap: 5px; }
.cardback {
  width: 42px; height: 58px; border-radius: 6px;
  background: linear-gradient(135deg, #2a2a5e, #4a4a8e);
  border: 2px solid #6a6ab0;
  box-shadow: 0 2px 4px rgba(0,0,0,0.35);
  position: relative;
}
.cardback::after {
  content: '✦'; position: absolute; inset: 0; display: grid; place-items: center;
  color: #ffd66b; font-size: 17px;
}

#boards {
  flex: 1; display: flex; flex-direction: column; min-height: 0;
}
.board {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 4px 12px; min-height: var(--unit-h);
  position: relative;
}
.board::before {
  content: ''; position: absolute; left: 50%; transform: translateX(-50%);
  bottom: -4px; width: min(880px, 94%); height: 68%;
  background: radial-gradient(ellipse at 50% 100%,
    rgba(255,255,255,0.55) 0%, rgba(255,255,255,0.22) 55%, transparent 76%);
  border-radius: 50%; filter: blur(3px); z-index: 0;
}
body.phase-night .board::before {
  background: radial-gradient(ellipse at 50% 100%,
    rgba(200, 200, 240, 0.4) 0%, rgba(190, 190, 235, 0.16) 55%, transparent 76%);
}
.board > * { position: relative; z-index: 1; }
.board:empty::after {
  content: attr(data-hint); position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%); font-size: 15.5px; font-style: italic;
  opacity: 0.55; font-weight: 700; white-space: nowrap; z-index: 1;
}

/* sized by its content (the constellation cards) — a fixed height here
   lets the cards spill over the board rows above and below */
#midbar {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  padding: 8px 12px; flex-shrink: 0;
}

#player-strip {
  display: flex; align-items: flex-end; gap: 14px; padding: 4px 16px 12px; height: 280px;
  flex-shrink: 0;
}
#hand {
  flex: 1; display: flex; gap: 0; align-items: flex-end; justify-content: center;
  perspective: 700px; min-width: 0;
}
#hand .card { margin-right: 10px; }
#player-strip > div:first-child { flex-shrink: 0; }
#end-turn { flex-shrink: 0; }

/* ------- panels & chips ------- */
.panel {
  background: rgba(20, 20, 50, 0.5); backdrop-filter: blur(6px);
  border: 1px solid rgba(255, 214, 107, 0.25); border-radius: 14px;
  padding: 8px 12px;
}
body.phase-morning .panel, body.phase-afternoon .panel {
  background: rgba(255, 250, 235, 0.55); border-color: rgba(160, 110, 40, 0.3);
}
.chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 15px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  background: rgba(0,0,0,0.25);
}
body.phase-morning .chip, body.phase-afternoon .chip { background: rgba(255,255,255,0.5); }
.playerinfo { display: flex; flex-direction: column; gap: 5px; min-width: 170px; }
.playerinfo .pname { font-size: 14.5px; font-weight: 800; opacity: 0.9; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }

/* ------- cards in hand ------- */
.card {
  width: var(--card-w); height: var(--card-h);
  border-radius: 10px; position: relative; flex-shrink: 0;
  background: linear-gradient(180deg, #fffdf5, #f5ecd8);
  border: 2.5px solid #c9b891; color: #3a2e1a;
  box-shadow: 0 3px 8px rgba(0,0,0,0.3);
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
  cursor: pointer; overflow: hidden;
}
.card.court-day { border-color: var(--gold-deep); }
.card.court-night { border-color: #5a4a9e; background: linear-gradient(180deg, #f2eefc, #ddd3f2); }
.card.court-neutral { border-color: #7a9ab0; background: linear-gradient(180deg, #f0f6fa, #dce8f0); }
.card:hover { transform: translateY(-20px) scale(1.18); z-index: 30; box-shadow: 0 10px 24px rgba(0,0,0,0.45); }
.card.unplayable { filter: grayscale(0.55) brightness(0.82); cursor: default; }
/* Entrust: a small balloon in the card's top-right that hands it to the sky
   unplayed. Deliberately a separate target from the card body — letting go of
   something must be a thing you meant to do. */
.card .entrustbtn {
  position: absolute; top: 4px; right: 4px; z-index: 3;
  width: 26px; height: 26px; padding: 0; line-height: 24px; font-size: 11px;
  border-radius: 50%; cursor: pointer;
  border: 1.5px solid #b9932f;
  /* gold, like every other affordance in the game — a dark disc read as a
     smudge on the card art rather than as something you could press */
  background: radial-gradient(circle at 34% 28%, #ffe9a8, var(--gold, #ffd66b) 60%, #e0ac33);
  box-shadow: 0 1px 3px rgba(0,0,0,.4), inset 0 0 0 1.5px rgba(255,255,255,.55);
  transition: transform .12s ease, box-shadow .12s ease;
}
.card .entrustbtn:hover, .card .entrustbtn:focus-visible {
  transform: translateY(-2px) scale(1.12); outline: none;
  box-shadow: 0 3px 8px rgba(255,214,107,.4);
}
.card.givable { box-shadow: 0 0 0 1px rgba(255,214,107,.35), 0 6px 14px rgba(0,0,0,.35); }
.card.unplayable .entrustbtn { filter: none; }
.card .cost {
  position: absolute; top: 4px; left: 4px; z-index: 2;
  width: 32px; height: 32px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe9a8, var(--gold-deep));
  border: 1.5px solid #b07818; color: #4a3000;
  display: grid; place-items: center; font-weight: 900; font-size: 17px;
}
.card .art {
  height: 98px; display: grid; place-items: center; font-size: 58px;
  background: linear-gradient(180deg, rgba(130,180,255,0.25), rgba(255,255,255,0));
}
.card .art svg { width: 100%; height: 98px; display: block; }
.artimg { width: 100%; height: 100%; object-fit: cover; display: block; }
.card .art, .unit .art, .constellation .cart, .cardpv .part { overflow: hidden; }
.unit .art { border-radius: 9px 9px 0 0; }
.card .cname {
  font-size: 14px; font-weight: 800; text-align: center; padding: 2px 4px 0;
  line-height: 1.15;
}
.card .ctext {
  font-size: 11.5px; text-align: center; padding: 2px 6px; line-height: 1.3; opacity: 0.9;
}
.card .stats {
  position: absolute; bottom: 4px; left: 0; right: 0;
  display: flex; justify-content: space-between; padding: 0 5px;
  font-weight: 900; font-size: 14px;
}
.statb {
  display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  min-width: 42px; height: 28px; border-radius: 999px; padding: 0 8px;
  color: #fff; font-size: 15.5px; font-weight: 900;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
  border: 1.5px solid rgba(255,255,255,0.55);
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
/* the emoji swords are wide: without the gap and the extra width they sat on the digit */
.statb.atk::before { content: "⚔\FE0F"; font-size: 11px; line-height: 1; }
.statb.atk { padding: 0 9px 0 7px; }
.statb.hp::before { content: "♥\FE0E"; font-size: 12px; opacity: 0.95; }
.statb.atk { background: radial-gradient(circle at 35% 30%, #ffb060, #d86a10); }
.statb.hp { background: radial-gradient(circle at 35% 30%, #7ae87a, #1f8a2f); }
.statb.hp.hurt { background: radial-gradient(circle at 35% 30%, #ff9a9a, #c02020); }
.card .typetag {
  position: absolute; top: 4px; right: 4px; font-size: 9.5px; font-weight: 800;
  background: rgba(0,0,0,0.14); border-radius: 6px; padding: 1px 6px;
}

/* Swift wears its name in hand. A fanned hand overlaps cards by up to 110px of
   150px and later cards paint on top, so the left sliver under the cost disc is
   the only strip guaranteed to be visible — the name and rules text are not.
   left:0 exactly, because .card is overflow:hidden and clips anything negative. */
.card.kw-swift .swiftmark {
  position: absolute; left: 0; top: 38px; z-index: 3;
  height: 21px; display: flex; align-items: center; gap: 3px;
  padding: 0 7px 0 16px;
  font-size: 10px; font-weight: 900; line-height: 1;
  color: var(--swift-ink);
  background: linear-gradient(90deg,
    rgba(255,250,240,0) 0%, var(--swift-light) 40%, var(--swift-core) 100%);
  clip-path: polygon(0 44%, 24% 0, 100% 0, 100% 100%, 24% 100%, 0 56%);
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.4));
  pointer-events: none;
}
.card.kw-swift .swiftmark b { font-size: 11px; filter: drop-shadow(0 0 2px rgba(255,255,255,.9)); }

/* ------- units on board ------- */
.unit {
  width: var(--unit-w); height: var(--unit-h);
  border-radius: 12px; position: relative;
  background: linear-gradient(180deg, #fffdf5, #efe4c8);
  border: 2.5px solid #c9b891; color: #3a2e1a;
  box-shadow: 0 3px 8px rgba(0,0,0,0.3);
  display: flex; flex-direction: column; align-items: center;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
  cursor: default;
}
.unit .art { flex: 1; display: grid; place-items: center; font-size: 54px; width: 100%; }
.unit .art svg { width: 100%; height: 100%; max-height: 96px; }
.unit .uname { font-size: 12.5px; font-weight: 800; text-align: center; line-height: 1.12; padding: 0 3px; }
.unit .stats {
  width: 100%; display: flex; justify-content: space-between; padding: 2px 7px 6px;
  font-weight: 900; font-size: 15px;
}
.unit.can-attack { box-shadow: 0 0 0 3px #7ae87a, 0 3px 10px rgba(0,0,0,0.3); cursor: pointer; }
.unit.selected { transform: translateY(-8px) scale(1.06); box-shadow: 0 0 0 3px #ffd66b, 0 8px 18px rgba(0,0,0,0.4); }
.unit.targetable { box-shadow: 0 0 0 3px #ff7a7a, 0 3px 10px rgba(0,0,0,0.3); cursor: crosshair; animation: pulse 0.9s ease-in-out infinite; }
.unit.friendly-targetable { box-shadow: 0 0 0 3px #7ab8ff; cursor: crosshair; animation: pulse 0.9s ease-in-out infinite; }
@keyframes pulse { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.18); } }
.unit .badge {
  position: absolute; top: -8px; font-size: 15px;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4));
}
.unit .badge.guardian { left: -5px; }
.unit .badge.sleeping { right: -5px; animation: bob 1.6s ease-in-out infinite; }
.unit .badge.soaring { left: -5px; }
.unit .badge.awake { left: -5px; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.unit .badge.settling {
  right: -6px; font-size: 15px; transform-origin: 50% 100%;
  animation: sway 2.4s ease-in-out infinite;
  background: radial-gradient(circle at 50% 60%, #eaf7dc, #cdeab2);
  border: 1.5px solid #9ccc7a; border-radius: 50%;
  width: 24px; height: 24px; line-height: 21px; text-align: center;
}
@keyframes sway { 0%,100% { transform: rotate(-9deg); } 50% { transform: rotate(9deg); } }
.unit.settling { filter: saturate(0.8); }

/* The top-right corner of a unit is the readiness dial — 🌱 wait · ⚡ go · 💤 out
   cold — and it shows exactly one face. Swift took the sprout's exact slot so the
   two read as one dial rather than as a badge and an absence: an absence is what
   nobody noticed. The top-left corner keeps "how it fights" (🛡️ 🪁 ☕). */
.unit .badge.swift {
  right: -7px; top: -10px;
  width: 27px; height: 27px; line-height: 23px; text-align: center;
  font-size: 14px; border-radius: 50%;
  background: radial-gradient(circle at 58% 32%, #fff6d8, var(--swift-edge) 58%, var(--swift-deep));
  border: 2px solid #8a4e08;
  box-shadow: 0 0 0 2px rgba(255,246,224,.85), 0 2px 6px rgba(0,0,0,.45);
  text-shadow: 0 1px 1px rgba(90,52,6,.55);
  filter: none;                    /* it carries its own shadow */
}
/* live: this one can attack right now *because* it is Swift.
   box-shadow only, never transform — the phone scales every badge by .85. */
.unit .badge.swift.ready { animation: swift-thrum 1.5s ease-in-out infinite; }
@keyframes swift-thrum {
  0%, 100% { box-shadow: 0 0 0 2px rgba(255,246,224,.85), 0 2px 6px rgba(0,0,0,.45); }
  50%      { box-shadow: 0 0 0 3px #fff6e0, 0 0 12px 3px rgba(255,190,70,.75), 0 2px 6px rgba(0,0,0,.45); }
}
/* once its first turn is spent, Swift is a reminder rather than an alarm —
   smaller and quieter, but still full colour, because desaturating it read as
   a disabled button */
.unit .badge.swift.resting {
  width: 23px; height: 23px; line-height: 20px; font-size: 12.5px;
  right: -6px; top: -8px;
  box-shadow: 0 0 0 1.5px rgba(255,246,224,.6), 0 1px 4px rgba(0,0,0,.4);
}
/* the mirror of .unit.settling's saturate(0.8) */
.unit.swift-ready { filter: saturate(1.08) brightness(1.04); }
/* a flare at the badge when a spell hands Swift out mid-game */
.unit .badge.swift.land::after {
  content: ""; position: absolute; inset: -8px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,246,224,.95), rgba(255,190,70,0) 70%);
  animation: swift-flare .62s ease-out forwards; pointer-events: none;
}
@keyframes swift-flare {
  0% { transform: scale(.4); opacity: 0; } 30% { opacity: 1; }
  100% { transform: scale(1.5); opacity: 0; }
}
.unit.asleep { filter: saturate(0.5) brightness(0.86); }
.unit.attacking { animation: lunge-down 0.7s cubic-bezier(0.3, 0, 0.4, 1); z-index: 20; }
.unit.attacking-up { animation: lunge-up 0.7s cubic-bezier(0.3, 0, 0.4, 1); z-index: 20; }
@keyframes lunge-down {
  18% { transform: translateY(-12px) scale(1.06); }
  45% { transform: translateY(48px) scale(1.12); }
}
@keyframes lunge-up {
  18% { transform: translateY(12px) scale(1.06); }
  45% { transform: translateY(-48px) scale(1.12); }
}
.unit.entering { animation: pop-in 0.35s ease; }
@keyframes pop-in { from { transform: scale(0.3); opacity: 0; } 60% { transform: scale(1.12); } }

/* Swift arrives sideways. Everything else in Starfall pops, sways, bobs, rises
   or lunges vertically; the horizontal axis is unclaimed, so a run in from the
   left can only mean one rule. It enters from the left on purpose: leftward
   overflow is not scrollable, so a crowded phone board cannot be widened by it. */
.unit.entering-swift { animation: swift-arrive 0.42s cubic-bezier(.18,.85,.28,1); }
@keyframes swift-arrive {
  0%   { transform: translateX(-64px) skewX(-10deg) scale(.94); opacity: 0; }
  55%  { transform: translateX(6px) skewX(4deg) scale(1.03); opacity: 1; }
  100% { transform: none; }
}

/* the wake and the caption mount on the body, like popOn and spawnAscension,
   because the phone board scrolls on x and would clip anything inside it */
.swift-wake { position: fixed; z-index: 55; pointer-events: none; }
.swift-wake i {
  position: absolute; left: -46px; height: 4px; border-radius: 3px;
  background: linear-gradient(90deg, rgba(255,250,240,0), var(--swift-core) 55%, rgba(255,214,107,0));
  filter: drop-shadow(0 0 6px rgba(255,190,70,.8));
  animation: swift-streak .52s cubic-bezier(.22,.9,.3,1) forwards;
}
.swift-wake i:nth-child(1) { top: 20%; width: 64px; }
.swift-wake i:nth-child(2) { top: 48%; width: 92px; height: 5px; animation-delay: .06s; }
.swift-wake i:nth-child(3) { top: 74%; width: 52px; opacity: .75; animation-delay: .12s; }
@keyframes swift-streak {
  0%   { transform: translateX(0) scaleX(.4); opacity: 0; }
  18%  { opacity: 1; }
  100% { transform: translateX(var(--run)); opacity: 0; }
}

/* the caption says the rule at the instant the rule applies */
.swift-say {
  position: fixed; z-index: 56; pointer-events: none;
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
  font-size: 11.5px; font-weight: 700; color: #5a3400;
  background: linear-gradient(100deg, var(--swift-core), var(--gold));
  border: 1.5px solid #c98a12; border-radius: 999px;
  padding: 3px 10px 3px 8px; box-shadow: 0 2px 7px rgba(0,0,0,.45);
  animation: swift-say 1.5s ease forwards;
}
.swift-say b { font-weight: 900; }
@keyframes swift-say {
  0%   { opacity: 0; transform: translateX(-50%) translateX(-14px) scale(.9); }
  14%  { opacity: 1; transform: translateX(-50%) translateX(0) scale(1); }
  78%  { opacity: 1; transform: translateX(-50%) translateX(6px); }
  100% { opacity: 0; transform: translateX(-50%) translateX(18px) scale(.98); }
}

/* one bloom off the green ring the player already knows, so the arrival ends by
   pointing at "you can attack with this, now" */
.unit.can-attack.ring-wake { animation: ring-wake .62s ease-out; }
@keyframes ring-wake {
  0%   { box-shadow: 0 0 0 3px #7ae87a, 0 0 0 0 rgba(122,232,122,.55), 0 3px 10px rgba(0,0,0,0.3); }
  100% { box-shadow: 0 0 0 3px #7ae87a, 0 0 0 14px rgba(122,232,122,0), 0 3px 10px rgba(0,0,0,0.3); }
}

/* ascension: a fallen unit floats up into the sky */
.ascend-ghost {
  position: fixed; z-index: 60; pointer-events: none;
  animation: ascendrise 1.8s ease-out forwards;
}
.ascend-ghost .ghostart { width: 100%; height: 78%; overflow: hidden; border-radius: 12px; }
.ascend-ghost .ghostart svg, .ascend-ghost .ghostart img {
  width: 100%; height: 100%; object-fit: cover;
}
.ascend-ghost .ghosttrail {
  text-align: center; font-size: 20px; animation: twinkle 0.7s ease-in-out infinite;
}
@keyframes ascendrise {
  0% { transform: translateY(0) scale(1); opacity: 0.95; filter: brightness(1); }
  25% { opacity: 0.9; filter: brightness(1.5) saturate(0.8); }
  100% { transform: translateY(-190px) scale(0.45); opacity: 0; filter: brightness(2.4) saturate(0.4); }
}

/* enemy spell reveal */
#ai-reveal {
  position: fixed; left: 50%; top: 24%; transform: translateX(-50%);
  z-index: 70; pointer-events: none; text-align: center;
  animation: revealpop 2.1s ease forwards;
}
#ai-reveal .reveal-label {
  font-size: 13px; font-weight: 800; margin-bottom: 6px; color: #fff6e0;
  text-shadow: 0 1px 6px rgba(0,0,0,0.6);
}
#ai-reveal .card { transform: scale(1.35); transform-origin: top center; box-shadow: 0 14px 40px rgba(0,0,0,0.5); }
@keyframes revealpop {
  0% { opacity: 0; transform: translateX(-50%) translateY(-16px) scale(0.8); }
  12% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
  82% { opacity: 1; }
  100% { opacity: 0; transform: translateX(-50%) translateY(-8px) scale(0.96); }
}

/* damage / heal pops */
.pop {
  position: absolute; z-index: 50; font-size: 22px; font-weight: 900;
  pointer-events: none; animation: popfly 1s ease forwards;
  text-shadow: 0 2px 4px rgba(0,0,0,0.5);
}
.pop.dmg { color: #ff5a5a; }
.pop.big { font-size: 34px; animation-duration: 1.5s; }
.pop.heal { color: #6ae86a; }
.pop.star { color: var(--gold); }
@keyframes popfly {
  from { transform: translateY(0) scale(0.6); opacity: 0; }
  25% { transform: translateY(-14px) scale(1.2); opacity: 1; }
  to   { transform: translateY(-44px) scale(1); opacity: 0; }
}

/* ------- lanterns / face ------- */
.face {
  display: flex; align-items: center; gap: 6px; border-radius: 12px; padding: 4px 10px;
  transition: box-shadow 0.2s ease;
  white-space: nowrap;
}
.face.targetable { box-shadow: 0 0 0 3px #ff7a7a; cursor: crosshair; animation: pulse 0.9s ease-in-out infinite; }
.lanterns { font-size: 19px; letter-spacing: -3px; }
.lantern-dim { opacity: 0.22; filter: grayscale(1); }

/* ------- middle bar ------- */
#round-banner { text-align: center; min-width: 150px; }
#round-banner .rname { font-size: 22px; font-weight: 900; }
#round-banner .rsub { font-size: 12.5px; opacity: 0.85; }
#round-banner .rwins { font-size: 15px; margin-top: 3px; letter-spacing: 2px; }

.constellation {
  width: 148px; border-radius: 12px; padding: 6px 8px 8px; text-align: center;
  background: linear-gradient(180deg, #1a1a44, #26265c);
  border: 2px solid #4a4a9e; color: var(--cream); cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  position: relative;
}
.constellation .cemoji { font-size: 34px; }
.constellation .cname { font-size: 13px; font-weight: 800; margin-top: 2px; }
.constellation .ccost { font-size: 15px; font-weight: 900; color: var(--gold); }
.constellation .ctext2 { font-size: 11px; opacity: 0.9; line-height: 1.3; }
/* the art box needs an explicit height: raster art (.artimg) fills 100% of it,
   so an auto-height box would grow to the image's natural size and overflow */
.constellation .cart {
  height: 76px; display: grid; place-items: center; border-radius: 8px;
}
.constellation .cart svg { width: 100%; height: 76px; }
.constellation.affordable { border-color: var(--gold); box-shadow: 0 0 12px rgba(255, 214, 107, 0.5); }
.constellation.affordable:hover { transform: translateY(-4px) scale(1.05); }
.constellation.spent { opacity: 0.42; filter: grayscale(0.7); cursor: default; }
.constellation .minestar { position: absolute; top: -8px; right: -6px; font-size: 16px; }

/* The falling star holds its slot even when the sky is empty, so players learn
   it exists before one arrives, and it is deliberately styled AWAY from the
   Constellations next to it — no card frame, no star cost, a standing label. */
#falling-star {
  text-align: center; width: 168px; font-size: 11.5px; line-height: 1.35;
  display: flex; flex-direction: column; gap: 3px;
}
#falling-star .fslabel {
  font-size: 9px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase;
  opacity: .62;
}
#falling-star .fsname { font-weight: 900; font-size: 14px; color: var(--gold); }
#falling-star .fscond { opacity: .9; }
#falling-star .fsstate { font-size: 10px; font-weight: 800; opacity: .8; }
#falling-star .fsfade { font-size: 9px; opacity: .5; letter-spacing: .04em; }

#falling-star.fs-live { animation: shimmer 2s ease-in-out infinite; }
/* you already qualify: the prize lands at your next turn start */
#falling-star.fs-ready {
  border-color: rgba(255, 214, 107, .75);
  box-shadow: 0 0 0 1px rgba(255, 214, 107, .35), 0 6px 18px -10px rgba(255, 214, 107, .5);
}
#falling-star.fs-ready .fsstate { color: #9ff2a8; opacity: 1; }
/* empty sky: present but quiet, teaching the rhythm rather than shouting */
#falling-star.fs-empty { opacity: .42; }
#falling-star.fs-empty .fsname, #falling-star.fs-empty .fscond { display: none; }
#falling-star .fsnone { font-size: 10.5px; font-style: italic; opacity: .85; }
@keyframes shimmer { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.35); } }

/* a Wish that springs turns over like a trap card (ui.js showWishFlip) */
#wish-reveal {
  position: fixed; left: 50%; top: 24%; transform: translateX(-50%);
  z-index: 71; pointer-events: none; text-align: center;
}
#wish-reveal .reveal-label {
  font-size: 13px; font-weight: 800; margin-bottom: 6px; color: #f3e6ff;
  text-shadow: 0 0 10px rgba(176,106,232,0.9), 0 1px 6px rgba(0,0,0,0.6);
  animation: wishlabel 0.5s ease 0.3s both;
}
#wish-reveal .wr-zoom { transform: scale(1.35); transform-origin: top center; perspective: 900px; }
#wish-reveal .wr-flipper {
  position: relative; width: var(--card-w); height: var(--card-h); margin: 0 auto;
  transform-style: preserve-3d;
}
#wish-reveal .wr-back, #wish-reveal .wr-front {
  position: absolute; inset: 0; margin: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: 0 14px 40px rgba(0,0,0,0.5);
}
#wish-reveal .wr-front { transform: rotateY(180deg); }
/* the back is the ❔ slot the player has been staring at, grown to card size */
#wish-reveal .wr-back {
  border-radius: 10px; border: 2.5px solid #b06ae8;
  background:
    radial-gradient(circle at 50% 45%, rgba(255,214,107,0.28), transparent 55%),
    repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 0 6px, transparent 6px 12px),
    linear-gradient(135deg, #3a2a5e, #5a3a8e);
  display: grid; place-items: center; font-size: 46px;
  box-shadow: 0 0 22px rgba(176,106,232,0.75), 0 14px 40px rgba(0,0,0,0.5);
}
/* the flash as the face comes round */
#wish-reveal .wr-flipper::after {
  content: ''; position: absolute; inset: -18px; border-radius: 22px; opacity: 0;
  background: radial-gradient(closest-side, rgba(255,236,170,0.95), rgba(176,106,232,0.55) 60%, transparent);
  transform: translateZ(1px) rotateY(180deg);
}
#wish-reveal.sprung .wr-flipper::after { animation: wishburst 0.6s ease-out forwards; }
@keyframes wishburst {
  0% { opacity: 0; transform: translateZ(1px) rotateY(180deg) scale(0.7); }
  25% { opacity: 0.9; }
  100% { opacity: 0; transform: translateZ(1px) rotateY(180deg) scale(1.35); }
}
@keyframes wishlabel {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
/* answering a spell whose reveal is still up: stand beside it, not on it */
#ai-reveal.answered { left: 27%; transition: left 0.3s ease; }
#wish-reveal.beside { left: 73%; }
/* reduced motion: no flight, no flip — the face simply fades in and out */
#wish-reveal.still .wr-back { display: none; }
#wish-reveal.still .wr-front { transform: none; }

/* ------- wish slots ------- */
.wishslot {
  width: 42px; height: 58px; border-radius: 6px; border: 2px dashed rgba(255,255,255,0.3);
  display: grid; place-items: center; font-size: 18px;
}
.wishslot.set {
  border-style: solid; border-color: #b06ae8;
  background: linear-gradient(135deg, #3a2a5e, #5a3a8e);
  animation: shimmer 2.2s ease-in-out infinite;
}
body.phase-morning .wishslot, body.phase-afternoon .wishslot { border-color: rgba(90,60,20,0.4); }
/* lit while the rule card about it is up, so "where did it go?" answers itself */
.wishslot.spotlight {
  position: relative; z-index: 86; border-color: var(--gold);
  animation: shimmer 2.2s ease-in-out infinite, wish-spotlight 1.1s ease-in-out infinite;
}
.wishslot.spotlight::after {
  content: 'Wish'; position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%);
  padding: 1px 7px; border-radius: 999px; white-space: nowrap;
  font-size: 11px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase;
  background: var(--gold); color: #4a3000; pointer-events: none;
}
@keyframes wish-spotlight {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 214, 107, 0.85); }
  50% { box-shadow: 0 0 0 7px rgba(255, 214, 107, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .wishslot.spotlight { animation: none; box-shadow: 0 0 0 3px var(--gold); }
}

/* ------- buttons ------- */
button {
  font-family: inherit; font-weight: 800; border: none; border-radius: 12px;
  cursor: pointer; transition: transform 0.12s ease, filter 0.12s ease;
}
button:hover:not(:disabled) { transform: translateY(-2px); filter: brightness(1.1); }
button:disabled { opacity: 0.45; cursor: default; }
#end-turn {
  padding: 14px 22px; font-size: 17px;
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  color: #4a3000; box-shadow: 0 4px 10px rgba(0,0,0,0.3);
}
#end-turn.ai-turn { background: linear-gradient(180deg, #8a8ab8, #5a5a92); color: #ddd; }
#redraw-btn {
  padding: 9px 14px; font-size: 13.5px;
  background: linear-gradient(180deg, #b8a9e8, #8a72c8); color: #fff;
}
.smallbtn { padding: 8px 14px; font-size: 13.5px; background: #4a4a8e; color: #fff; }

/* ------- overlays ------- */
.overlay {
  position: fixed; inset: 0; z-index: 100; display: grid; place-items: center;
  background: rgba(10, 10, 30, 0.75); backdrop-filter: blur(4px);
  animation: fadein 0.4s ease;
}
@keyframes fadein { from { opacity: 0; } }
.overlay .obox {
  text-align: center; padding: 34px 48px; border-radius: 22px;
  background: linear-gradient(180deg, #23234e, #16163a);
  border: 2px solid var(--gold); color: var(--cream);
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
  box-sizing: border-box; max-width: min(90vw, 700px);
  max-height: calc(100dvh - 24px); overflow-y: auto; overscroll-behavior: contain;
}
.overlay h1 { font-size: 34px; margin-bottom: 10px; }
.overlay h2 { font-size: 25px; margin-bottom: 9px; }
.overlay p { font-size: 16px; opacity: 0.9; margin-bottom: 18px; line-height: 1.55; }
.overlay .obtn {
  padding: 13px 26px; font-size: 16px;
  background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: #4a3000;
}

/* ------- title screen ------- */
.homebox {
  max-width: min(92vw, 720px); max-height: 92vh; overflow-y: auto;
  padding: 30px 40px 26px;
}
/* Account control. Signing in is identity, not a game mode, so it sits in the
   corner people actually look for it rather than in the "other ways to play"
   grid, where anyone hunting for a login scrolls straight past it. */
.acctbtn {
  /* in the flow rather than pinned over the corner: the title is centred and
     grows with the panel, so an absolute pill collides with it on mid-width
     screens once an account name is long */
  display: flex; align-items: center; gap: 7px;
  margin: 0 0 10px auto; max-width: 100%;
  padding: 7px 13px; border-radius: 999px;
  font-size: 12.5px; font-weight: 800; letter-spacing: 0.3px;
  color: var(--cream); background: rgba(255,255,255,0.07);
  border: 1.5px solid rgba(255,255,255,0.14);
}
.acctbtn .ai { font-size: 14px; line-height: 1; flex: 0 0 auto; }
.acctbtn .al { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acctbtn:hover:not(:disabled) {
  background: rgba(255,255,255,0.13); border-color: rgba(255,214,107,0.55); transform: none;
}
.acctbtn.in { border-color: rgba(255,214,107,0.42); color: var(--gold); }
.homebox::-webkit-scrollbar { width: 8px; }
.homebox::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 8px; }
.home-title {
  font-size: 42px; letter-spacing: 5px; margin-bottom: 8px; line-height: 1;
  color: var(--gold); text-shadow: 0 0 26px rgba(255,214,107,0.35);
}
.home-title .tstar {
  display: inline-block; font-size: 30px; margin-right: 10px;
  vertical-align: 5px; letter-spacing: 0; text-shadow: none;
}
.home-tag {
  font-size: 14.5px; line-height: 1.6; opacity: 0.72; margin: 0 auto 22px;
  max-width: 470px; font-weight: 600;
}
.obtn.resume { margin-bottom: 22px; }

.home-sec { margin-bottom: 22px; }
.seclabel {
  font-size: 11px; font-weight: 800; letter-spacing: 1.8px; text-transform: uppercase;
  opacity: 0.5; margin-bottom: 11px;
  display: flex; align-items: center; gap: 12px; justify-content: center;
}
.seclabel::before, .seclabel::after {
  content: ''; height: 1px; flex: 1; max-width: 120px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.22), transparent);
}

.courtpick { display: flex; gap: 16px; justify-content: center; }
.courtbtn {
  flex: 1 1 0; max-width: 260px; padding: 0; overflow: hidden;
  border-radius: 16px; color: var(--cream); text-align: center;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, #2c2c5c, #1e1e46);
  border: 2px solid rgba(255,255,255,0.12);
  box-shadow: 0 6px 18px rgba(0,0,0,0.32);
  transition: transform 0.14s ease, box-shadow 0.14s ease, border-color 0.14s ease;
}
.courtbtn .skywin {
  display: grid; place-items: center; height: 100px; position: relative;
  border-bottom: 1px solid rgba(0,0,0,0.2);
}
.courtbtn.slim .skywin { height: 78px; }
.courtbtn .emblem { width: 74px; height: 74px; display: block; }
.courtbtn.slim .emblem { width: 56px; height: 56px; }
.courtbtn .cbody { padding: 12px 15px 16px; display: block; }
.courtbtn.slim { max-width: 190px; }
.courtbtn.slim .cbody { padding: 11px 12px 13px; }
.courtbtn.slim .cname { font-size: 15px; margin-bottom: 0; white-space: nowrap; }
.courtbtn .cname { display: block; font-size: 17px; font-weight: 900; margin-bottom: 5px; }
.courtbtn small {
  display: block; font-size: 12.5px; font-weight: 600; line-height: 1.45; opacity: 0.7;
}
/* A deck you named yourself sits where a court name usually does, and unlike
   "Day Court" it can run to 24 characters — let it wrap rather than spill. */
.courtbtn.slim .cname.owndeck {
  white-space: normal; overflow-wrap: anywhere; line-height: 1.25; margin-bottom: 3px;
}
/* the only <select> in the game: match the overlay's inputs rather than
   inheriting the platform's grey box */
.netdeck {
  font-family: inherit; font-size: 15px; padding: 9px 14px; border-radius: 10px;
  border: 2px solid var(--gold); background: rgba(255,255,255,0.1);
  color: var(--cream); text-align: center; outline: none; cursor: pointer;
  max-width: 100%;
}
.netdeck option { background: #1e1e46; color: var(--cream); }
.courtbtn.day .skywin {
  background:
    radial-gradient(circle at 50% 44%, rgba(255,244,205,0.55), transparent 58%),
    linear-gradient(180deg, #6fb6e0 0%, #f3b263 62%, #ef9440 100%);
}
/* a few soft clouds drifting along the day court's horizon */
.courtbtn.day .skywin::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 40px;
  pointer-events: none;
  background:
    radial-gradient(20px 10px at 14% 62%, rgba(255,253,246,0.6), transparent 70%),
    radial-gradient(13px 8px at 24% 52%, rgba(255,253,246,0.5), transparent 70%),
    radial-gradient(17px 9px at 84% 78%, rgba(255,253,246,0.45), transparent 70%);
}
.courtbtn.day .cname { color: #ffd08a; }
.courtbtn.night .skywin {
  background:
    radial-gradient(circle at 54% 46%, rgba(150,160,255,0.32), transparent 60%),
    linear-gradient(180deg, #3a3a84, #1c1c48);
}
.courtbtn.night .cname { color: var(--lavender); }
.courtbtn:hover:not(:disabled) {
  transform: translateY(-4px); filter: none;
  box-shadow: 0 12px 26px rgba(0,0,0,0.4);
}
.courtbtn.day:hover { border-color: var(--gold-deep); }
.courtbtn.night:hover { border-color: #8b93f0; }

.modegrid { display: grid; gap: 10px; }
.modetile.hero { grid-column: span var(--span, 1); }
.modetile {
  display: flex; align-items: center; gap: 11px; text-align: left;
  padding: 11px 13px; border-radius: 13px; color: var(--cream);
  background: rgba(255,255,255,0.07); border: 1.5px solid rgba(255,255,255,0.1);
}
.modetile .ti { font-size: 21px; line-height: 1; flex: 0 0 auto; }
.modetile .tt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.modetile .tl { font-size: 14px; font-weight: 800; }
.modetile .ts { font-size: 11px; font-weight: 600; opacity: 0.6; line-height: 1.3; }
.modetile:hover:not(:disabled) {
  background: rgba(255,255,255,0.13); border-color: rgba(255,214,107,0.5); transform: none;
}

.optbar {
  display: flex; flex-wrap: wrap; gap: 12px 26px; justify-content: center; align-items: center;
  padding: 13px 16px; border-radius: 14px;
  background: rgba(0,0,0,0.22); border: 1px solid rgba(255,255,255,0.07);
}
.optgroup { display: flex; align-items: center; gap: 9px; }
.optcheck { cursor: pointer; gap: 8px; }
.optcheck input { position: absolute; opacity: 0; pointer-events: none; }
.optcheck .box {
  width: 17px; height: 17px; border-radius: 5px; flex: 0 0 auto;
  border: 1.5px solid rgba(255,255,255,0.32); background: rgba(0,0,0,0.28);
  display: grid; place-items: center; font-size: 11px; color: #4a3000;
  transition: background 0.14s ease, border-color 0.14s ease;
}
.optcheck .box::after { content: '✓'; opacity: 0; font-weight: 900; }
.optcheck input:checked + .box { background: var(--gold); border-color: var(--gold-deep); }
.optcheck input:checked + .box::after { opacity: 1; }
.optcheck:hover .box { border-color: var(--gold); }
.optcheck input:focus-visible + .box { outline: 2px solid var(--gold); outline-offset: 2px; }
.optlabel { font-size: 12.5px; font-weight: 800; opacity: 0.8; }
.opthint { font-size: 11px; font-weight: 600; opacity: 0.5; }
.segmented {
  display: inline-flex; padding: 3px; gap: 3px; border-radius: 11px;
  background: rgba(0,0,0,0.3);
}
.diffbtn {
  padding: 6px 13px; font-size: 12.5px; border-radius: 9px;
  background: transparent; color: var(--cream); opacity: 0.7;
}
.diffbtn:hover:not(:disabled) { transform: none; opacity: 1; }
.diffbtn.on { background: var(--gold); color: #4a3000; opacity: 1; }

.homefoot {
  margin-top: 18px; display: flex; flex-wrap: wrap; gap: 8px 18px;
  align-items: center; justify-content: center;
}
.linkbtn {
  background: none; color: var(--cream); opacity: 0.68;
  font-size: 13px; font-weight: 700; padding: 4px 2px;
  border-bottom: 1.5px solid rgba(255,255,255,0.25); border-radius: 0;
}
.linkbtn:hover:not(:disabled) { opacity: 1; transform: none; border-bottom-color: var(--gold); }
.recline { font-size: 11.5px; font-weight: 600; opacity: 0.5; }

@media (max-width: 620px) {
  .homebox { padding: 22px 18px 18px; }
  .home-title { font-size: 32px; letter-spacing: 3px; }
  .home-tag { font-size: 13px; margin-bottom: 16px; }
  .home-sec { margin-bottom: 16px; }
  .courtpick { gap: 12px; }
  .courtbtn .cbody { padding: 10px 12px 13px; }
  .courtpick { flex-direction: column; align-items: stretch; }
  /* flex-basis 0 would collapse the cards' height once the axis turns vertical */
  .courtbtn { flex: 0 0 auto; max-width: 100%; width: 100%; }
  .courtbtn .skywin { height: 76px; }
  .courtbtn .emblem { width: 56px; height: 56px; }
  .modegrid { grid-template-columns: 1fr 1fr !important; }
}

/* constellation celebration */
#celebrate {
  position: fixed; inset: 0; z-index: 110; pointer-events: none;
  display: grid; place-items: center;
  background: radial-gradient(circle at 50% 45%, rgba(20,20,60,0.85) 0%, rgba(10,10,30,0.55) 55%, transparent 100%);
  animation: celebfade 2.2s ease forwards;
}
@keyframes celebfade {
  0% { opacity: 0; } 12% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; }
}
#celebrate .cbox { text-align: center; animation: celebzoom 2.2s ease; }
@keyframes celebzoom {
  0% { transform: scale(0.35) rotate(-5deg); opacity: 0; }
  22% { transform: scale(1.12) rotate(1deg); opacity: 1; }
  32% { transform: scale(1); }
  100% { transform: scale(1.04); }
}
#celebrate .cart svg { width: 220px; height: 220px; filter: drop-shadow(0 0 26px rgba(255,214,107,0.9)); }
#celebrate .cart img {
  width: 240px; height: 240px; object-fit: cover; border-radius: 20px;
  border: 3px solid var(--gold);
  filter: drop-shadow(0 0 26px rgba(255,214,107,0.9));
}
#celebrate .ctitle {
  font-size: 26px; font-weight: 900; color: var(--gold);
  text-shadow: 0 0 18px rgba(255,214,107,0.8); margin-top: 6px;
}
#celebrate .cwho { font-size: 13px; color: var(--cream); opacity: 0.9; }
.celebstar {
  position: absolute; font-size: 18px; pointer-events: none;
  animation: celebstarfly 1.8s ease-out forwards;
}
@keyframes celebstarfly {
  0% { transform: translate(0, 0) scale(0.4); opacity: 0; }
  20% { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(1.2) rotate(180deg); opacity: 0; }
}

.unit.hit, .face.hit { animation: hitflash 0.5s ease; }
@keyframes hitflash {
  0% { filter: brightness(1); }
  30% { filter: brightness(1.6) saturate(1.6) hue-rotate(-18deg); transform: translateX(-3px); }
  55% { transform: translateX(3px); }
  100% { filter: brightness(1); }
}

/* scry choices */
.scryrow { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin: 10px 0 4px; }
/* Keep action spacing separate from the button's own padding and colour. */
.overlay-actions { display: flex; justify-content: center; gap: 10px; margin-top: 20px; }
@media (min-width: 561px) {
  #mull-overlay .obox, #piles-overlay .obox, #log-overlay .obox { padding-bottom: 18px; }
  #mull-row { margin-bottom: 0; }
}

/* Court Trials list */
.triallist { display: flex; flex-direction: column; gap: 8px; max-height: 52vh; overflow-y: auto; padding: 2px; }
.trialrow {
  display: flex; align-items: center; gap: 14px; text-align: left;
  background: rgba(255,255,255,0.07); border: 1.5px solid rgba(255,214,107,0.25);
  border-radius: 14px; padding: 8px 14px;
}
.trialrow.unlocked { cursor: pointer; transition: transform 0.12s ease, background 0.12s ease; }
.trialrow.unlocked:hover { transform: translateX(4px); background: rgba(255,214,107,0.14); }
.trialrow.locked { opacity: 0.5; }
.trialart { width: 58px; height: 58px; border-radius: 10px; overflow: hidden; flex-shrink: 0;
  display: grid; place-items: center; background: rgba(0,0,0,0.25); }
.trialart img, .trialart svg { width: 100%; height: 100%; object-fit: cover; }
.trialinfo { flex: 1; font-size: 14px; }
.trialblurb { font-size: 12px; opacity: 0.85; line-height: 1.4; margin-top: 2px; }
.trialstate { font-size: 22px; width: 32px; text-align: center; }
.scryrow .card:hover { transform: translateY(-8px) scale(1.1); }

/* ------- top-right chrome -------
   One corner slot per z-level, sized by flexbox — never by hand-tuned pixel
   offsets, which collide as soon as a label changes width. Layout:
     row 1:  [ turn pill ] [ music ]     (music is the fixed-width anchor)
     row 2:  [ piles ] [ help ] [ log ] [ speed ] [ zoom ]
     below:  [ battle log panel ]                                          */
#log-wrap { position: fixed; right: calc(14px + var(--sar)); top: calc(104px + var(--sat)); width: 280px; z-index: 40; }
#log {
  max-height: 44vh; overflow-y: auto; font-size: 12px; line-height: 1.45;
  display: flex; flex-direction: column-reverse;
}
#log div { padding: 2px 0; border-bottom: 1px dotted rgba(255,255,255,0.08); }
#chrome-btns {
  position: fixed; right: calc(14px + var(--sar)); top: calc(58px + var(--sat)); z-index: 41;
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px;
  max-width: 60vw;
}
/* audio controls sit above overlays (z 100) so sound is adjustable on the title screen */
#audio-ctrl {
  position: fixed; right: calc(14px + var(--sar)); top: calc(14px + var(--sat)); z-index: 120;
  display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
}
#music-toggle { width: 108px; }
#volume-slider {
  display: none; width: 120px; accent-color: var(--gold); cursor: pointer;
  background: rgba(20, 20, 50, 0.85); border-radius: 999px; padding: 8px 10px;
}
#audio-ctrl:hover #volume-slider, #audio-ctrl:focus-within #volume-slider,
#audio-ctrl.open #volume-slider { display: block; }

/* turn indicator: to the left of the music button (14 + 108 + 8 gap) */
#turn-pill {
  position: fixed; right: calc(130px + var(--sar)); top: calc(14px + var(--sat)); z-index: 41;
  font-size: 14px; font-weight: 800; padding: 8px 18px; border-radius: 999px;
}
#turn-pill.mine { background: rgba(122, 232, 122, 0.25); border: 1px solid #7ae87a; }
#turn-pill.theirs { background: rgba(255, 122, 122, 0.2); border: 1px solid #ff7a7a; }

.hint { font-size: 12.5px; opacity: 0.8; text-align: center; }

/* accessibility: respect reduced-motion preferences */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Swift without motion. The blanket rule above snaps every animation to its end
   frame, which for the caption is opacity 0 — so it has to opt out by name and
   hold its lit state. The information is the point; only the motion is optional. */
@media (prefers-reduced-motion: reduce) {
  .unit.entering-swift { animation: none; }
  .unit .badge.swift.ready {
    animation: none;
    box-shadow: 0 0 0 3px #fff6e0, 0 0 0 5px rgba(224,122,16,.6), 0 2px 6px rgba(0,0,0,.45);
  }
  .unit .badge.swift.land::after { animation: none; display: none; }
  .swift-say { animation: none; opacity: 1; transform: translateX(-50%); }
}

/* narrow windows: the auto-zoom in ui.js scales the whole layout down
   uniformly, so cards keep their proportions; just drop the log panel */
@media (max-width: 900px) {
  #log-wrap { display: none !important; }
}

/* the readable card face — shared by the in-game hover preview (#preview,
   which only adds placement) and the deckbuilder's tap-to-read modal */
.cardpv {
  width: 290px; border-radius: 16px; overflow: hidden;
  background: linear-gradient(180deg, #fffdf5, #f5ecd8);
  border: 3px solid #c9b891; color: #3a2e1a;
  box-shadow: 0 14px 40px rgba(0,0,0,0.55);
  position: relative;
}
#preview {
  position: fixed; left: 18px; bottom: 296px; z-index: 80; pointer-events: none;
  animation: previewpop 0.12s ease;
}
@keyframes previewpop { from { opacity: 0; transform: scale(0.92); } }
.cardpv.court-day { border-color: var(--gold-deep); }
.cardpv.court-night { border-color: #5a4a9e; background: linear-gradient(180deg, #f2eefc, #ddd3f2); }
.cardpv.court-neutral { border-color: #7a9ab0; background: linear-gradient(180deg, #f0f6fa, #dce8f0); }
.cardpv.court-const { border-color: #4a4a9e; background: linear-gradient(180deg, #1a1a44, #26265c); color: var(--cream); }
.cardpv .pcost {
  position: absolute; top: 8px; left: 8px; width: 44px; height: 44px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffe9a8, var(--gold-deep));
  border: 2px solid #b07818; color: #4a3000;
  display: grid; place-items: center; font-weight: 900; font-size: 23px;
}
.cardpv .part { height: 186px; display: grid; place-items: center; font-size: 100px;
  background: linear-gradient(180deg, rgba(130,180,255,0.25), rgba(255,255,255,0)); }
.cardpv .part svg { width: 100%; height: 186px; }
.cardpv .pname { font-size: 20px; font-weight: 900; text-align: center; padding: 5px 8px 0; }
.cardpv .ptext { font-size: 15.5px; text-align: center; padding: 5px 14px 12px; line-height: 1.4; }
/* keywords as chips, so the preview's Swift is the same object as the board's */
.cardpv .pkw { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; padding: 0 10px 2px; }
.cardpv .kwchip {
  font-size: 11.5px; font-weight: 900; padding: 2px 8px; border-radius: 999px;
  background: rgba(0,0,0,.09);
}
.cardpv .kwchip.kw-swift {
  background: linear-gradient(100deg, var(--swift-core), var(--gold));
  border: 1.5px solid #c98a12; color: #5a3400;
}
.cardpv .pkwnote { font-size: 11px; text-align: center; opacity: .8; padding: 2px 12px 0; font-weight: 700; }
.cardpv .pstats { display: flex; justify-content: space-between; padding: 0 12px 12px; }
.cardpv .pstats .statb { min-width: 40px; height: 38px; font-size: 20px; }
.cardpv .ptag { position: absolute; top: 10px; right: 10px; font-size: 12px; font-weight: 800;
  background: rgba(0,0,0,0.15); border-radius: 8px; padding: 2px 8px; }

.card.mullsel {
  transform: translateY(-14px);
  box-shadow: 0 0 0 3px #ff9a5a, 0 8px 18px rgba(0,0,0,0.4);
}
.scryrow .card.mullsel:hover { transform: translateY(-14px) scale(1.1); }

/* ------- overworld: The Sky-Meadow (Opus design spec) ------- */
:root {
  --ow-font-story: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, 'Times New Roman', serif;
  --ow-font-ui: 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
  --ow-gold: #ffd66b; --ow-gold-deep: #f0a830;
  --ow-brass: #c9903f; --ow-brass-hi: #f0c477;
  --ow-rim: #fff8ea;
  --ow-paper: #fdf3de; --ow-paper-edge: #d9c49a;
  --ow-ink: #3b2f24; --ow-ink-soft: #6b4a2a; --ow-ink-name: #8a5a1f;
  --ow-lantern: #ffc46b; --ow-starlight: #fff8e0;
  --ow-void-day: radial-gradient(120% 100% at 50% 0%, #bfe3f2, #7fb6d8 58%, #5b86a8);
  --ow-void-night: radial-gradient(120% 100% at 50% 0%, #2a2c58, #14142f 58%, #0b0b1e);
  --ow-flash-dusk: linear-gradient(180deg, rgba(255,176,120,0), rgba(255,152,104,.55) 55%, rgba(255,120,150,.30));
  --ow-flash-dawn: linear-gradient(180deg, rgba(255,238,190,.55), rgba(255,214,140,.35) 60%, rgba(190,220,255,.18));
  --ow-skymask: linear-gradient(180deg, #000 0 22%, rgba(0,0,0,.85) 26%, transparent 31%);
  --ow-fgmask: linear-gradient(180deg, transparent 0 10%, rgba(0,0,0,.6) 44%, #000 74%);
  --ow-ease-soft: cubic-bezier(.2,.8,.3,1);
  --ow-ease-lift: cubic-bezier(.34,1.4,.64,1);
  --ow-ease-sink: cubic-bezier(.45,.05,.55,.95);
  --ow-ease-dial: cubic-bezier(.7,0,.3,1);
  --ow-t-fade: 1200ms;
}

#overworld {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  background: var(--ow-void-day); transition: background 1400ms ease;
}
#overworld.night { background: var(--ow-void-night); }
.ow-scene {
  position: relative; width: 1280px; height: 720px; flex: 0 0 auto;
  transform-origin: center center; border-radius: 22px; overflow: hidden;
  box-shadow: 0 30px 90px -20px rgba(10,8,30,.7), 0 0 0 1px rgba(255,243,220,.10);
  touch-action: none; user-select: none; cursor: pointer;
  background: #1c2038;
}
.ow-scene.notrans * { transition: none !important; }

/* --- painted layers --- */
.ow-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.ow-bg[data-k="day"] { z-index: 1; opacity: 1; }
.ow-bg[data-k="night"] { z-index: 2; opacity: 0; }
.ow-bg[data-k="dusk"] { z-index: 3; opacity: 0; }
.ow-scene[data-time="night"] .ow-bg[data-k="day"] { opacity: 0; }
.ow-scene[data-time="night"] .ow-bg[data-k="night"] { opacity: 1; }
.ow-changing.to-night .ow-bg[data-k="day"] { transition: opacity 1200ms ease-in-out 200ms; }
.ow-changing.to-night .ow-bg[data-k="night"] { transition: opacity 1200ms ease-in-out; }
.ow-changing.to-day .ow-bg[data-k="night"] { transition: opacity 1200ms ease-in-out; }
.ow-changing.to-day .ow-bg[data-k="day"] { transition: opacity 1200ms ease-in-out 200ms; }

/* day-only / night-only layer sets with choreographed fades */
.ow-daily, .ow-nightly { position: absolute; pointer-events: none; }
.ow-scene[data-time="day"] .ow-nightly { opacity: 0; }
.ow-scene[data-time="night"] .ow-daily { opacity: 0; }
.ow-daily, .ow-nightly { transition: opacity var(--ow-t-fade) ease; }
.ow-changing.to-night .ow-nightly { transition: opacity 1200ms ease-out 600ms; }
.ow-changing.to-night .ow-daily { transition: opacity 900ms ease-in; }
.ow-changing.to-day .ow-daily { transition: opacity 1200ms ease-out 600ms; }
.ow-changing.to-day .ow-nightly { transition: opacity 1200ms ease-in; }

#ow-stars { inset: 0; z-index: 4; mix-blend-mode: screen;
  -webkit-mask-image: var(--ow-skymask); mask-image: var(--ow-skymask); }
#ow-stars img { width: 100%; height: 46%; object-fit: cover;
  animation: ow-breathe 9s ease-in-out infinite alternate; }
@keyframes ow-breathe { from { opacity: .78; } to { opacity: .95; } }

#ow-twinkles { inset: 0; z-index: 5;
  -webkit-mask-image: var(--ow-skymask); mask-image: var(--ow-skymask); }
#ow-twinkles span {
  position: absolute; border-radius: 50%; background: var(--ow-starlight);
  box-shadow: 0 0 6px 1px rgba(255,248,224,.7);
  animation: ow-twinkle 3s ease-in-out infinite;
}
@keyframes ow-twinkle { 0%,100% { opacity: .15; } 50% { opacity: 1; } }

#ow-weavergap {
  left: 560px; top: 16px; width: 170px; height: 92px; z-index: 6;
  border-radius: 50%;
  background: radial-gradient(50% 50%, rgba(9,7,24,.88), rgba(9,7,24,.5) 55%, transparent 72%);
  filter: blur(3px);
  animation: ow-gap 6.5s ease-in-out infinite alternate;
}
@keyframes ow-gap { from { opacity: .55; } to { opacity: .85; } }
.ow-scene[data-time="day"] #ow-weavergap { animation: none; }

#ow-shooting { inset: 0; z-index: 7;
  -webkit-mask-image: var(--ow-skymask); mask-image: var(--ow-skymask); }
#ow-shooting div {
  position: absolute; width: 90px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--ow-starlight));
  opacity: 0;
}
#ow-shooting div:nth-child(1) { left: 140px; top: 52px; animation: ow-shoot 26s linear 4s infinite; }
#ow-shooting div:nth-child(2) { left: 420px; top: 96px; animation: ow-shoot 37s linear 17s infinite; }
#ow-shooting div:nth-child(3) { left: 1000px; top: 64px; animation: ow-shoot 49s linear 31s infinite; }
@keyframes ow-shoot {
  0%, 88% { opacity: 0; transform: rotate(26deg) translate(0, 0); }
  89% { opacity: 1; }
  96.5% { opacity: 1; transform: rotate(26deg) translate(300px, 0); }
  100% { opacity: 0; transform: rotate(26deg) translate(340px, 0); }
}

#ow-moonwash { inset: 0; z-index: 8;
  background: radial-gradient(90% 70% at 78% 8%, rgba(196,214,255,.16), transparent 66%); }

#ow-celestial { position: absolute; inset: 0; z-index: 8; pointer-events: none; }
#ow-sun, #ow-moon {
  position: absolute; border-radius: 50%; overflow: visible;
  transition: transform 900ms var(--ow-ease-sink), opacity 900ms var(--ow-ease-sink);
}
#ow-sun { left: 52px; top: 20px; width: 72px; height: 72px; }
#ow-moon { left: 1104px; top: 14px; width: 70px; height: 70px; }
#ow-sun img, #ow-moon img {
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;
  mix-blend-mode: screen;
}
#ow-sun::after, #ow-moon::after {
  content: ''; position: absolute; inset: -46%; border-radius: 50%; z-index: -1;
}
#ow-sun::after { background: radial-gradient(circle, rgba(255,244,206,.55), transparent 70%); }
#ow-moon::after { background: radial-gradient(circle, rgba(230,236,255,.4), transparent 70%); }
.ow-scene[data-time="night"] #ow-sun { transform: translateY(230px) scale(1.22); opacity: 0;
  filter: saturate(1.45) hue-rotate(-10deg); }
.ow-scene[data-time="day"] #ow-moon { transform: translateY(96px); opacity: 0; }
.ow-changing.to-night #ow-moon { transition: transform 1400ms cubic-bezier(.22,.9,.3,1) 400ms, opacity 1400ms ease 400ms; }
.ow-changing.to-day #ow-sun { transition: transform 1400ms cubic-bezier(.22,.9,.3,1) 400ms, opacity 1400ms ease 400ms; }

#ow-clouds { inset: 0; z-index: 9; opacity: .5;
  -webkit-mask-image: var(--ow-skymask); mask-image: var(--ow-skymask); overflow: hidden; }
#ow-clouds img { width: 200%; height: 42%; object-fit: cover;
  animation: ow-drift 200s linear infinite; }
@keyframes ow-drift { from { transform: translateX(0); } to { transform: translateX(-50%); } }

.ow-shafts { inset: 0; z-index: 10; }
.ow-shafts div {
  position: absolute; top: -70px; height: 420px; transform: skewX(-16deg);
  background: linear-gradient(180deg, rgba(255,244,206,.55), transparent 78%);
  mix-blend-mode: soft-light; filter: blur(10px);
}
.ow-shafts div:nth-child(1) { left: 18%; width: 150px; animation: ow-sway 17s ease-in-out infinite alternate; }
.ow-shafts div:nth-child(2) { left: 64%; width: 210px; animation: ow-sway 22s ease-in-out infinite alternate; }
@keyframes ow-sway {
  from { opacity: .16; transform: skewX(-16deg); }
  to { opacity: .30; transform: skewX(-13deg); }
}

.ow-cloudshadows { inset: 0; z-index: 11; }
.ow-cloudshadows div {
  position: absolute; border-radius: 50%; opacity: .085; filter: blur(26px);
  background: radial-gradient(50% 50%, rgba(30,50,30,.30), transparent 70%);
}
.ow-cloudshadows div:nth-child(1) { width: 460px; height: 150px; top: 330px;
  animation: ow-shadowdrift 118s linear infinite; }
.ow-cloudshadows div:nth-child(2) { width: 560px; height: 175px; top: 480px;
  animation: ow-shadowdrift 152s linear infinite; animation-delay: -60s; }
@keyframes ow-shadowdrift {
  from { transform: translateX(-30%) translateY(0); }
  to { transform: translateX(130vw) translateY(-14px); }
}

#ow-pond-day, #ow-pond-night {
  left: 170px; top: 490px; width: 380px; height: 115px; z-index: 12;
  border-radius: 50%; overflow: hidden;
}
#ow-pond-day {
  background: repeating-linear-gradient(96deg, rgba(255,255,255,.5) 0 3px, transparent 3px 13px);
  opacity: .28; animation: ow-glint 7.5s ease-in-out infinite alternate;
}
@keyframes ow-glint {
  from { opacity: .18; transform: translateX(0); }
  to { opacity: .42; transform: translateX(9px); }
}
#ow-pond-night {
  background: linear-gradient(180deg, rgba(255,250,230,.45), transparent);
  opacity: .35; animation: ow-pondmoon 6.5s ease-in-out infinite alternate;
}
@keyframes ow-pondmoon {
  from { opacity: .22; transform: translateY(0); }
  to { opacity: .42; transform: translateY(2px); }
}

#ow-glows { inset: 0; z-index: 13; mix-blend-mode: screen; }
#ow-glows .lamp {
  position: absolute; left: 922px; top: 240px; width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,196,107,.85), rgba(255,180,90,.28) 42%, transparent 70%);
  animation: ow-flicker 4.2s ease-in-out infinite alternate;
}
#ow-glows .window {
  position: absolute; left: 751px; top: 123px; width: 210px; height: 210px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,214,120,.7), transparent 70%);
  animation: ow-flicker 7.5s ease-in-out infinite alternate;
}
@keyframes ow-flicker {
  from { opacity: .48; transform: scale(1); }
  to { opacity: .64; transform: scale(1.045); }
}

.ow-motes { position: absolute; inset: 0; z-index: 14; pointer-events: none; }
.ow-mote { position: absolute; animation: ow-rise linear infinite; }
.ow-mote i {
  display: block; border-radius: 50%;
  animation: ow-motesway ease-in-out infinite alternate;
}
.ow-motes[data-kind="day"] .ow-mote i {
  background: radial-gradient(circle, #fffbe6, rgba(255,251,230,0) 70%);
}
.ow-motes[data-kind="night"] .ow-mote i {
  background: radial-gradient(circle, #ffe0a0, rgba(255,224,160,0) 70%);
  box-shadow: 0 0 8px rgba(255,196,107,.6);
}
@keyframes ow-rise {
  0% { transform: translateY(60px); opacity: 0; }
  12% { opacity: .8; }
  88% { opacity: .5; }
  100% { transform: translateY(-520px); opacity: 0; }
}
@keyframes ow-motesway { from { transform: translateX(-22px); } to { transform: translateX(22px); } }

#ow-fg {
  position: absolute; left: 0; right: 0; bottom: -18px; height: 260px; z-index: 300;
  pointer-events: none; transform-origin: 50% 100%;
  -webkit-mask-image: var(--ow-fgmask); mask-image: var(--ow-fgmask);
  animation: ow-fgsway 9s ease-in-out infinite alternate;
}
#ow-fg img { width: 100%; height: 100%; object-fit: cover; object-position: center bottom; }
@keyframes ow-fgsway { from { transform: skewX(0); } to { transform: skewX(.35deg); } }
#ow-fg.exhale { animation: ow-exhale 800ms cubic-bezier(.34,1.3,.64,1) 1; }
@keyframes ow-exhale { 0% { transform: skewX(0); } 50% { transform: skewX(1.3deg); } 100% { transform: skewX(0); } }

#ow-vig { position: absolute; inset: 0; z-index: 340; pointer-events: none;
  background: radial-gradient(122% 94% at 50% 46%, transparent 52%, rgba(24,16,44,.30) 100%); }
.ow-scene[data-time="night"] #ow-vig {
  background: radial-gradient(122% 94% at 50% 46%, transparent 52%, rgba(24,16,44,.32) 100%); }

#ow-wash { position: absolute; inset: 0; z-index: 360; pointer-events: none; opacity: 0;
  mix-blend-mode: soft-light; }
#ow-wash.dusk { background: radial-gradient(126% 84% at 42% 80%, rgba(255,148,88,.55), rgba(255,112,150,.22) 44%, transparent 72%); }
#ow-wash.dawn { background: radial-gradient(126% 84% at 58% 80%, rgba(255,206,140,.55), rgba(180,170,255,.20) 46%, transparent 74%); }
#ow-wash.firing { animation: ow-washfire 1800ms ease-in-out 1; }
@keyframes ow-washfire { 0% { opacity: 0; } 45% { opacity: .85; } 100% { opacity: 0; } }

#ow-fall { position: absolute; inset: 0; z-index: 380; pointer-events: none; }
#ow-fall div {
  position: absolute; top: -60px; width: 2px; height: 26px; border-radius: 2px;
  background: linear-gradient(180deg, transparent, var(--ow-starlight));
  transform: rotate(12deg); opacity: 0;
  animation: ow-starfall cubic-bezier(.4,0,.9,.5) 1 both;
}
@keyframes ow-starfall {
  0% { transform: rotate(12deg) translateY(0); opacity: 0; }
  15% { opacity: 1; }
  85% { opacity: 0; }
  100% { transform: rotate(12deg) translateY(790px); opacity: 0; }
}
#ow-fall .ow-sunburst {
  left: 150px; top: 160px; width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, #fffbe8, rgba(255,214,107,.6) 40%, transparent 70%);
  transform: none; animation: ow-burst 900ms cubic-bezier(.16,.8,.3,1) 1 both;
}
@keyframes ow-burst {
  0% { transform: scale(.35); opacity: 0; }
  30% { opacity: .9; }
  100% { transform: scale(2.6); opacity: 0; }
}

#ow-flash { position: fixed; inset: 0; z-index: 90; pointer-events: none; opacity: 0; }
#ow-flash.dusk { background: var(--ow-flash-dusk); }
#ow-flash.dawn { background: var(--ow-flash-dawn); }
#ow-flash.firing { animation: ow-flashfire 750ms ease-out 1; }
@keyframes ow-flashfire { 0% { opacity: 0; } 40% { opacity: .5; } 100% { opacity: 0; } }

/* --- charted tokens --- */
.ow-tok {
  position: absolute; transform: translate(-50%, -100%);
  width: 84px; pointer-events: auto; cursor: pointer;
}
.ow-tok-me { width: 78px; cursor: default; }
.ow-tok::after {
  content: ''; position: absolute; left: 50%; bottom: -7px;
  width: 60px; height: 15px; transform: translateX(-50%);
  background: radial-gradient(50% 50%, rgba(24,16,44,.42), rgba(24,16,44,0) 72%);
  filter: blur(1.5px); pointer-events: none;
}
.ow-tok-disc {
  position: relative; width: 100%; aspect-ratio: 1; border-radius: 50%; overflow: visible;
  background: var(--ow-paper);
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-brass), 0 8px 16px -5px rgba(18,12,40,.55);
  animation: ow-idle 3.6s ease-in-out infinite;
  transition: box-shadow 200ms var(--ow-ease-soft), transform 200ms var(--ow-ease-lift);
}
.ow-tok-disc > img {
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;
}
@keyframes ow-idle { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2.5px); } }
@keyframes ow-walkbob {
  0%,100% { transform: translateY(0) rotate(-1.1deg); }
  50% { transform: translateY(-4px) rotate(1.1deg); }
}
/* the walk bob belongs to anyone walking, not only to you */
.ow-tok.walking .ow-tok-disc { animation: ow-walkbob .42s ease-in-out infinite; }
/* a token that strolls should slide between frames rather than teleport */
.ow-tok:not(.ow-tok-me) { transition: left 90ms linear, top 90ms linear; }
.ow-tok-me .ow-tok-disc > img { transition: transform 160ms var(--ow-ease-soft); }
.ow-tok-me.facing-left .ow-tok-disc > img { transform: scaleX(-1); }

.ow-tok-plate {
  margin-top: 7px; text-align: center; white-space: nowrap;
  font: 700 11px/1 var(--ow-font-ui); letter-spacing: .04em;
  color: var(--ow-rim);
  background: rgba(34,26,62,.72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,243,220,.20);
  border-radius: 999px; padding: 4px 10px;
  display: inline-block; position: relative; left: 50%; transform: translateX(-50%);
  transition: color 180ms, background 180ms, border-color 180ms;
}
.ow-tok-me .ow-tok-plate {
  font-size: 10px; opacity: .9; letter-spacing: .1em; text-transform: lowercase;
  color: rgba(255,243,220,.82); background: rgba(34,26,62,.6);
}

.ow-tok.near .ow-tok-disc, .ow-tok:not(.ow-tok-me):hover .ow-tok-disc {
  transform: scale(1.06);
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-gold),
    0 0 22px rgba(255,214,107,.55), 0 10px 20px -5px rgba(18,12,40,.6);
}
.ow-tok.near .ow-tok-plate {
  color: #2c1f06; background: var(--ow-gold); border-color: var(--ow-gold-deep);
}
.ow-tok.near::before {
  content: ''; position: absolute; left: 50%; bottom: -9px;
  width: 64px; height: 19px; transform: translateX(-50%);
  border: 2px solid rgba(255,214,107,.85); border-radius: 50%;
  animation: ow-ripple 1.9s ease-out infinite; pointer-events: none;
}
@keyframes ow-ripple {
  0% { transform: translateX(-50%) scale(.62); opacity: 0; }
  22% { opacity: .85; }
  100% { transform: translateX(-50%) scale(1.5); opacity: 0; }
}

.ow-tok-badge {
  position: absolute; right: -2px; top: -2px; width: 20px; height: 20px;
  border-radius: 50%; box-shadow: 0 0 0 2px var(--ow-rim), 0 2px 6px rgba(18,12,40,.5);
  background: radial-gradient(circle at 35% 30%, #fff2c4, var(--ow-gold-deep));
  display: grid; place-items: center; z-index: 2;
}
.ow-tok-badge::after {
  content: ''; width: 11px; height: 11px; background: #fffaf0;
  clip-path: polygon(50% 0%,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0% 50%,39% 39%);
}
.ow-tok-badge.duel { animation: ow-badgepulse 2.1s ease-in-out infinite; }
.ow-tok-badge.beaten { background: radial-gradient(circle at 35% 30%, #ffffff, #c9c2d8); opacity: .85; }
@keyframes ow-badgepulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.14); } }

.ow-tok.leaving { opacity: 0; transform: translate(-50%, -100%) scale(.86) translateY(6px);
  transition: opacity 420ms ease-in, transform 420ms ease-in; }
.ow-tok.arriving { animation: ow-arrive 520ms var(--ow-ease-lift) both; }
@keyframes ow-arrive {
  from { opacity: 0; transform: translate(-50%, -100%) scale(.9) translateY(10px); }
  to { opacity: 1; transform: translate(-50%, -100%) scale(1) translateY(0); }
}

/* --- HUD rail --- */
.ow-hud {
  position: fixed; top: 0; left: 0; right: 0; min-height: calc(62px + var(--sat)); z-index: 65;
  padding: var(--sat) var(--sar) 12px var(--sal);
  background: linear-gradient(180deg, rgba(26,20,48,.88) 0%, rgba(26,20,48,.60) 62%, rgba(26,20,48,0) 100%);
  -webkit-backdrop-filter: blur(10px) saturate(1.08); backdrop-filter: blur(10px) saturate(1.08);
  pointer-events: none;
}
.ow-hud::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 12px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,243,220,.22) 18%, rgba(255,243,220,.22) 82%, transparent);
}
.ow-hud-in {
  position: relative; max-width: 1280px; margin: 0 auto; min-height: 44px;
  padding: 8px 148px 8px 22px;
  display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: center;
  justify-content: space-between; pointer-events: auto;
}
.ow-place-name {
  font: 400 18px/1 var(--ow-font-story); font-variant: small-caps;
  letter-spacing: .09em; color: #fff3dc;
}
.ow-place-sub {
  margin-top: 3px; font: 700 9.5px/1 var(--ow-font-ui);
  text-transform: uppercase; letter-spacing: .18em; color: rgba(255,243,220,.52);
}
.ow-hud-right { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.ow-hud-right > * { flex-shrink: 0; }
.ow-dust { display: flex; align-items: baseline; gap: 6px; color: #fff3dc; }
.ow-star {
  width: 11px; height: 11px; background: var(--ow-gold); align-self: center;
  clip-path: polygon(50% 0%,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0% 50%,39% 39%);
}
.ow-dust b { font: 800 15px/1 var(--ow-font-ui); font-variant-numeric: tabular-nums; color: var(--ow-gold); }
.ow-dust span { font: 700 9.5px/1 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .14em; opacity: .58; }

/* Keep the objective below the entire rail, including wrapped controls. */
.ow-place { min-width: 180px; flex: 1 1 180px; }
.ow-goal {
  position: absolute; top: calc(100% + 9px); left: 22px;
  display: flex; align-items: center; gap: 7px; pointer-events: none;
  width: max-content;
  max-width: min(46ch, calc(100vw - 44px)); padding: 7px 13px 7px 11px;
  color: #fff3dc; background: rgba(26,20,48,.72);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid rgba(255,214,107,.32); border-left: 2px solid var(--ow-gold);
  border-radius: 4px 13px 13px 4px;
  font: 600 12px/1.35 var(--ow-font-ui);
  box-shadow: 0 8px 20px -12px rgba(10,8,28,.9);
  animation: ow-goal-in 420ms var(--ow-ease-soft) both;
}
.ow-goal::before {                        /* the same star as .ow-star */
  content: ''; flex: 0 0 auto; width: 10px; height: 10px; background: var(--ow-gold);
  clip-path: polygon(50% 0%,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0% 50%,39% 39%);
}
.ow-goal.done { border-left-color: var(--ow-brass); color: rgba(255,243,220,.72); }
.ow-goal.done::before { background: var(--ow-brass); }
@keyframes ow-goal-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

/* --- chapter title card, shown once --- */
.ow-card {
  position: fixed; inset: 0; z-index: 72; display: grid; place-items: center;
  pointer-events: none; text-align: center;
  background: radial-gradient(58% 46% at 50% 48%, rgba(14,10,32,.62), rgba(14,10,32,0) 78%);
  animation: ow-card-life 3500ms ease-in-out both;
}
.ow-card small {
  display: block; margin-bottom: 12px; color: var(--ow-gold);
  font: 800 10px/1 var(--ow-font-ui); text-transform: uppercase;
  letter-spacing: .42em; text-indent: .42em;
}
.ow-card b {
  display: block; color: #fff6e4;
  font: 400 clamp(30px,6vw,52px)/1.1 var(--ow-font-story);
  font-variant: small-caps; letter-spacing: .07em;
  text-shadow: 0 3px 26px rgba(8,6,24,.8);
}
.ow-card i {
  display: block; width: 128px; height: 1px; margin: 16px auto;
  background: linear-gradient(90deg, transparent, var(--ow-brass), transparent);
}
.ow-card span {
  display: block; max-width: 30ch; margin: 0 auto; color: rgba(255,243,220,.82);
  font: italic 400 clamp(13px,1.6vw,16px)/1.5 var(--ow-font-story);
}
@keyframes ow-card-life {
  0% { opacity: 0; transform: translateY(10px); }
  16%, 74% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(-8px); }
}
/* the global reduced-motion rule collapses every animation to an instant;
   the card is dismissed by its timer instead, so it must render whole */
@media (prefers-reduced-motion: reduce) {
  .ow-goal { animation: none; }
  .ow-card { animation: none !important; opacity: 1; }
}
/* chapter one had no phone layout at all; two and three scope down at 760/880 */
@media (max-width: 760px) {
  #overworld .ow-hud-in { padding: 0 108px 0 12px; }
  #overworld .ow-hud-right { gap: 6px; }
  #overworld .ow-place-sub, #overworld .ow-dust span { display: none; }
  #overworld .ow-place-name { font-size: 15px; }
  #overworld .ow-gbtn { padding: 8px 9px; font-size: 10px; }
  #overworld .ow-dial { margin-left: 40px; }
  .ow-goal { top: calc(100% + 7px); padding: 6px 11px 6px 9px;
    font-size: 11px; max-width: calc(100vw - 24px); }
}

.ow-dial {
  position: relative; width: 78px; height: 32px; border-radius: 999px; padding: 0;
  margin-left: 64px;   /* room for the time label that hangs off its left edge */
  border: 1px solid rgba(255,243,220,.28); cursor: pointer;
  background: linear-gradient(90deg, #6ba8d0, #29406e);
  transition: background 900ms ease;
}
.ow-dial[data-time="night"] { background: linear-gradient(90deg, #2b3f6b, #14142f); }
.ow-dial-label {
  /* hangs off the dial's left edge, so "10:45 am" never runs under the knob */
  position: absolute; right: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  white-space: nowrap;
  font: 700 9.5px/1 var(--ow-font-ui); letter-spacing: .16em; color: rgba(255,243,220,.6);
}
.ow-dial-knob {
  position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%;
  overflow: hidden; box-shadow: 0 0 0 1.5px var(--ow-rim), 0 2px 6px rgba(10,8,26,.6);
  transition: transform 600ms var(--ow-ease-dial);
}
.ow-dial[data-time="night"] .ow-dial-knob { transform: translateX(46px); }
.ow-dial-knob img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: opacity 400ms ease; }
.ow-dial-knob img:nth-child(2) { opacity: 0; }
.ow-dial[data-time="night"] .ow-dial-knob img:nth-child(1) { opacity: 0; }
.ow-dial[data-time="night"] .ow-dial-knob img:nth-child(2) { opacity: 1; }
.ow-dial:disabled { cursor: default; }

.ow-gbtn {
  font: 700 12px/1 var(--ow-font-ui); letter-spacing: .03em; color: #f4e6c8;
  background: rgba(255,243,220,.07); border: 1px solid rgba(255,243,220,.18);
  border-radius: 10px; padding: 8px 15px; cursor: pointer;
  transition: background 140ms, border-color 140ms, color 140ms;
}
.ow-gbtn:hover { background: rgba(255,214,107,.16); border-color: rgba(255,214,107,.5); color: #fff6e0; }
.ow-dial:focus-visible, .ow-gbtn:focus-visible { outline: 2px solid var(--ow-gold); outline-offset: 3px; }

/* --- hint bar --- */
.ow-hint {
  position: fixed; bottom: calc(14px + var(--sab)); left: 50%; transform: translateX(-50%); z-index: 64;
  font: 700 11.5px/1.5 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .16em;
  color: rgba(255,243,220,.62); text-shadow: 0 1px 7px rgba(10,8,28,.85);
  max-width: 92vw; text-align: center; transition: opacity 260ms ease;
}
.ow-hint .ow-key {
  display: inline-block; min-width: 18px; padding: 3px 6px; margin: 0 2px;
  border-radius: 5px; background: rgba(255,243,220,.14);
  border: 1px solid rgba(255,243,220,.30); border-bottom-width: 2px;
  font: 700 10.5px/1 var(--ow-font-ui); letter-spacing: 0; color: #fff3dc;
}
.ow-hint.toast {
  font: italic 400 14px/1.5 var(--ow-font-story);
  text-transform: none; letter-spacing: .01em; color: #fff3dc;
}

/* --- storybook dialogue --- */
#ow-dim {
  position: fixed; inset: 0; z-index: 62; background: rgba(20,16,44,.34);
  opacity: 0; transition: opacity 260ms ease; pointer-events: none;
}
#ow-dim.on { opacity: 1; }
.ow-dialogue {
  position: fixed; left: 50%; bottom: calc(40px + var(--sab)); z-index: 70;
  width: min(680px, 92vw); padding: 26px 26px 16px;
  background-image:
    linear-gradient(180deg, rgba(255,248,232,.93), rgba(252,240,218,.97)),
    url('../art/img/ow_paper.webp');
  background-size: cover; background-position: center;
  color: var(--ow-ink);
  border: 1px solid var(--ow-paper-edge);
  border-radius: 20px;
  box-shadow: 0 20px 54px -14px rgba(14,10,34,.66), inset 0 2px 0 rgba(255,255,255,.72);
  transform: translateX(-50%);
  animation: ow-dlg-in 420ms var(--ow-ease-soft) both;
}
@keyframes ow-dlg-in {
  from { opacity: 0; transform: translateX(-50%) translateY(22px) scale(.985); }
  to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
.ow-dlg-face {
  position: absolute; left: 24px; top: -30px; width: 64px; height: 64px;
  border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-brass), 0 6px 14px -4px rgba(18,12,40,.5);
}
.ow-dlg-name {
  margin-left: 76px; font: 400 17px/1.1 var(--ow-font-story);
  font-variant: small-caps; letter-spacing: .06em; color: var(--ow-ink-name);
}
.ow-dlg-name::after {
  content: ''; display: block; margin-top: 10px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--ow-brass), rgba(201,144,63,.15));
}
.ow-dlg-text {
  margin: 14px 0 16px; max-width: 60ch;
  font: 400 16.5px/1.62 var(--ow-font-story); color: var(--ow-ink);
  animation: ow-line-in 380ms cubic-bezier(.2,.7,.3,1) both;
}
@keyframes ow-line-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.ow-dlg-text em { font-style: italic; color: var(--ow-ink-soft); }
.ow-dlg-foot { display: flex; align-items: center; justify-content: space-between; }
.ow-dlg-dots { display: flex; gap: 6px; }
.ow-dlg-dots i { width: 6px; height: 6px; border-radius: 50%; background: #e0d2b4; transition: background 200ms; }
.ow-dlg-dots i.on { background: var(--ow-brass); }
.ow-dlg-acts { display: flex; gap: 10px; }
.ow-dlg-next {
  font: 700 13px/1 var(--ow-font-ui); color: var(--ow-ink-soft);
  background: transparent; border: 1px solid #cbb083; border-radius: 11px;
  padding: 9px 18px; cursor: pointer; transition: background 140ms, color 140ms;
}
.ow-dlg-next:hover { background: rgba(201,144,63,.14); color: var(--ow-ink); }
.ow-dlg-duel {
  font: 800 13px/1 var(--ow-font-ui); letter-spacing: .02em; color: #4a3200;
  background: linear-gradient(180deg, #ffd66b, #f0a830);
  border: none; border-radius: 11px; padding: 10px 20px; cursor: pointer;
  box-shadow: 0 4px 0 #cf8b1f, 0 8px 18px -6px rgba(120,70,10,.5);
  transition: transform 100ms, box-shadow 100ms;
}
.ow-dlg-duel:active { transform: translateY(3px); box-shadow: 0 1px 0 #cf8b1f; }
.ow-dlg-next:focus-visible, .ow-dlg-duel:focus-visible { outline: 2px solid var(--ow-brass); outline-offset: 3px; }
/* the button E will press, when it is not the plain Next/Goodbye */
.ow-dlg-default::after {
  content: 'E'; display: inline-block; margin-left: 8px; padding: 1px 5px 0;
  border: 1px solid currentColor; border-radius: 4px; font-size: 10px; line-height: 1.35;
  opacity: .62; vertical-align: 1px;
}
@media (hover: none) { .ow-dlg-default::after { display: none; } }

/* Chapter One road marker */
.ow-road {
  position: absolute; z-index: 56; transform: translate(-50%, -50%);
  width: 138px; padding: 10px 13px; cursor: pointer; text-align: left;
  color: #fff3dc; background: rgba(36,29,57,.86); border: 1px solid rgba(255,214,107,.55);
  border-radius: 12px; box-shadow: 0 8px 20px -8px rgba(15,10,30,.8);
  font-family: var(--ow-font-ui); transition: transform 160ms, background 160ms;
}
.ow-road:hover:not(:disabled) { transform: translate(-50%, -50%) scale(1.04); background: rgba(62,45,73,.94); }
.ow-road b { display: block; font: 700 13px/1.2 var(--ow-font-story); }
.ow-road span { display: block; margin-top: 3px; font-size: 9px; text-transform: uppercase; letter-spacing: .12em; opacity: .68; }

/* ------- Lantern Hollow: chapter two ------- */
#cloudbreak,
#road-east,
#lantern-hollow {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  overflow: hidden;
  background: radial-gradient(120% 100% at 50% 0%, #c8e3e8, #789eb1 60%, #466275);
  transition: background 1100ms ease;
}
#cloudbreak.night,
#road-east.night,
#lantern-hollow.night { background: radial-gradient(120% 100% at 50% 0%, #30345f, #17172f 60%, #0a0a1b); }
.lh-scene {
  position: relative; width: 1280px; height: 720px; flex: 0 0 auto; transform-origin: center;
  overflow: hidden; border-radius: 22px; cursor: pointer; touch-action: none; user-select: none;
  background: #19213a; box-shadow: 0 30px 90px -20px rgba(10,8,30,.74), 0 0 0 1px rgba(255,243,220,.13);
}
.lh-bg { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover;
  transition: filter 1500ms ease, transform 10s ease; pointer-events: none; }
#cloudbreak.night .lh-bg,
#lantern-hollow.night .lh-bg { filter: brightness(.43) saturate(.72) hue-rotate(18deg) contrast(1.08); }
.lh-nightwash { position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, rgba(26,30,78,.40), rgba(27,18,58,.22) 52%, rgba(8,9,28,.48));
  mix-blend-mode: multiply; transition: opacity 1300ms ease; }
#cloudbreak.night .lh-nightwash,
#lantern-hollow.night .lh-nightwash { opacity: 1; }
.lh-vig { position: absolute; inset: 0; z-index: 45; pointer-events: none;
  box-shadow: inset 0 0 80px rgba(25,16,43,.18); }
.lh-lights { position: absolute; inset: 0; z-index: 7; pointer-events: none; }
.lh-lights i { position: absolute; width: 12px; height: 12px; border-radius: 50%; opacity: 0; transform: scale(.3);
  background: #fff0af; box-shadow: 0 0 9px 3px rgba(255,190,83,.9), 0 0 28px 10px rgba(255,153,59,.38);
  transition: opacity 440ms ease, transform 550ms var(--ow-ease-lift); }
#cloudbreak.night .lh-lights i,
#lantern-hollow.night .lh-lights i { opacity: .95; transform: scale(1); transition-delay: inherit; animation: lh-lampbreath 4.5s ease-in-out infinite alternate; }
@keyframes lh-lampbreath { from { filter: brightness(.88); } to { filter: brightness(1.2); } }
#lh-player { left: 180px; top: 610px; z-index: 250; }
#lh-dim { position: fixed; inset: 0; z-index: 62; pointer-events: none; opacity: 0;
  background: rgba(14,12,38,.42); transition: opacity 260ms ease; }
#lh-dim.on { opacity: 1; }
.lh-exit {
  position: absolute; z-index: 52; transform: translate(-50%, -50%); cursor: pointer;
  font: 800 10px/1 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .1em;
  color: #fff1d0; background: rgba(31,26,55,.80); border: 1px solid rgba(255,214,107,.5);
  border-radius: 999px; padding: 9px 14px; box-shadow: 0 6px 18px -8px #0c081d;
}
.lh-exit:hover, .lh-exit:focus-visible { background: #5e4769; border-color: var(--ow-gold); outline: none; }
.lh-exit.near:not(.lh-shut) {
  background: #5e4769; border-color: var(--ow-gold);
  box-shadow: 0 0 0 2px rgba(255,214,107,.16), 0 0 18px rgba(255,214,107,.28);
}
/* same specificity trap as .ow-road above — keep the centring on hover */
.lh-exit:hover:not(:disabled) { transform: translate(-50%, -50%); }
.lh-choice-prompt { margin: -5px 0 10px; color: #704b25; font: italic 600 14px/1.45 var(--ow-font-story); }
.lh-choices { display: grid; gap: 7px; margin: 0 0 14px; }
.lh-choices button {
  padding: 9px 13px; text-align: left; cursor: pointer; border-radius: 10px;
  font: 700 13px/1.25 var(--ow-font-ui); color: #4c3626; background: rgba(201,144,63,.08);
  border: 1px solid rgba(138,90,31,.3); transition: background 140ms, transform 140ms;
}
.lh-choices button:hover { background: rgba(201,144,63,.18); transform: translateX(3px); }
.lh-choices button:focus-visible { outline: 2px solid var(--ow-brass); outline-offset: 2px; }

.lh-journal { width: min(620px, 94vw); text-align: left; }
.lh-objective { padding: 15px 17px; border-radius: 14px; background: rgba(255,214,107,.11);
  border: 1px solid rgba(255,214,107,.3); }
.lh-objective small { display: block; margin-bottom: 5px; color: var(--gold); font: 800 9px/1 var(--ow-font-ui);
  text-transform: uppercase; letter-spacing: .16em; }
.lh-objective b { display: block; line-height: 1.45; }
.lh-seals { display: grid; grid-template-columns: repeat(3,1fr); gap: 9px; margin: 14px 0; }
.lh-seals > div { padding: 12px; text-align: center; opacity: .4; border: 1px dashed rgba(255,255,255,.25); border-radius: 12px; }
.lh-seals > div.won { opacity: 1; border-style: solid; border-color: rgba(255,214,107,.6); background: rgba(255,214,107,.08); }
.lh-seals i { display: block; margin-bottom: 5px; color: var(--gold); font-size: 22px; font-style: normal; }
.lh-seals span { font-size: 12px; font-weight: 800; }
.lh-notes { font-size: 13px; line-height: 1.65; opacity: .88; }
.lh-duel-result { margin: 8px 0 14px; }
.lh-result-speaker { display: flex; align-items: center; justify-content: center; gap: 11px; }
.lh-result-speaker img { width: 46px; height: 46px; border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 0 2px #fff8ea,0 0 0 4px #c9903f; }
.lh-result-speaker p { max-width: 390px; text-align: left; font: italic 14px/1.45 var(--ow-font-story); }
.lh-rewards { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; margin: 12px 0; }
.lh-reward { width: 132px; min-height: 88px; display: grid; grid-template-columns: 32px 1fr;
  grid-template-rows: auto auto; gap: 2px 6px; align-items: center; padding: 10px;
  color: #433322; background: linear-gradient(160deg,#fff4d8,#ead7ad); border: 1px solid #bd9557;
  border-radius: 12px; box-shadow: 0 7px 18px -10px #000; }
.lh-reward > span { grid-row: 1/3; font-size: 26px;
  display: grid; place-items: center; width: 32px; height: 44px; }
.lh-reward > span .artimg { width: 32px; height: 44px; border-radius: 5px; }.lh-reward b { font-size: 11px; line-height: 1.15; }
.lh-reward small { font-size: 8.5px; line-height: 1.2; opacity: .7; }.lh-reward.dust { filter: saturate(.55); }
.lh-seal-earned, .lh-loss-light { margin: 9px auto; color: var(--gold); font-weight: 900; font-size: 13px; }
.lh-seal-earned.finale { font-size: 15px; }.lh-loss-light { color: #c8c2ef; }

@media (max-width: 760px) {
  #lantern-hollow .ow-hud-in, #cloudbreak .ow-hud-in { padding: 0 10px; }
  #lantern-hollow .ow-hud-right, #cloudbreak .ow-hud-right { gap: 5px; }
  #lantern-hollow .ow-dust span, #lantern-hollow .ow-place-sub,
  #cloudbreak .ow-dust span, #cloudbreak .ow-place-sub { display: none; }
  #lantern-hollow .ow-dial, #cloudbreak .ow-dial { margin-left: 38px; }
  #lantern-hollow .ow-gbtn, #cloudbreak .ow-gbtn { padding: 8px 9px; font-size: 10px; }
  #lantern-hollow .ow-place-name, #cloudbreak .ow-place-name { font-size: 14px; }
  .lh-choices { max-height: 25vh; overflow-y: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .ow-motes, .ow-shafts, .ow-cloudshadows, #ow-shooting, #ow-fall { display: none; }
  .ow-tok-disc, #ow-fg, #ow-clouds img, #ow-twinkles > span, #ow-stars img,
  #ow-pond-day, #ow-pond-night, #ow-glows > div, #ow-weavergap
    { animation: none !important; }
  .ow-tok.near::before { animation: none; opacity: .8; transform: translateX(-50%) scale(1.1); }
  .lh-lights i { animation: none !important; transition: none; }
}

/* ------- The Falling Roads: chapter three ------- */
#wild-route {
  --wr-moss:#182c2a; --wr-glass:#6d91a3; --wr-hearth:#e39a62; --wr-comet:#9de0c0; --wr-salt:#f2e7c9; --wr-bruise:#37314d;
  position:fixed; inset:0; z-index:60; display:flex; align-items:center; justify-content:center;
  overflow:hidden;
  background:radial-gradient(120% 95% at 50% 0%,#a9c5bf,#587778 58%,#253f42); transition:background 1.2s ease;
}
#wild-route.night { background:radial-gradient(120% 95% at 50% 0%,#404864,#222b42 58%,#111725); }
.wr-scene { position:relative; width:1280px; height:720px; flex:0 0 auto; overflow:hidden; border-radius:20px;
  transform-origin:center; cursor:pointer; touch-action:none; user-select:none; background:var(--wr-moss);
  box-shadow:0 30px 95px -18px rgba(7,18,20,.8),0 0 0 1px rgba(242,231,201,.17); }

/* Campaign scenes are camera canvases, not centered cards. The JS camera
   translates and scales them to cover every viewport while preserving art. */
#overworld .ow-scene,
#lantern-hollow .lh-scene,
#cloudbreak .lh-scene,
#road-east .lh-scene,
#wild-route .wr-scene {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  border-radius: 0;
  box-shadow: none;
  will-change: transform;
}
.wr-bg { position:absolute; inset:0; z-index:1; width:100%; height:100%; object-fit:cover; pointer-events:none;
  transition:filter 1.5s ease,transform 12s ease; }
#wild-route.night .wr-bg { filter:brightness(.48) saturate(.74) hue-rotate(8deg) contrast(1.08); }
.wr-weather { position:absolute; inset:0; z-index:3; pointer-events:none; opacity:.35;
  background:linear-gradient(112deg,transparent 18%,rgba(210,241,232,.28) 18.5%,transparent 19.2%,transparent 66%,rgba(210,241,232,.18) 66.4%,transparent 67%); }
#wild-route.night .wr-weather { opacity:.7; mix-blend-mode:screen; }
.wr-starroads { position:absolute; inset:0; z-index:6; pointer-events:none; overflow:hidden; }
.wr-starroads i { position:absolute; width:170px; height:3px; border-radius:99px; opacity:.18; transform:rotate(24deg);
  background:linear-gradient(90deg,transparent,var(--wr-comet),#fff,transparent); box-shadow:0 0 13px rgba(157,224,192,.8);
  animation:wr-roadfall 5.8s ease-in-out infinite; }
#wild-route.night .wr-starroads i { opacity:.64; }
@keyframes wr-roadfall { 0%,100%{transform:translate(-35px,-50px) rotate(24deg);opacity:.08} 45%,70%{transform:translate(35px,55px) rotate(24deg);opacity:.72} }
#wr-player { left:170px; top:610px; z-index:250; }
#wr-dim { position:fixed; inset:0; z-index:62; pointer-events:none; opacity:0; background:rgba(11,19,29,.48); transition:opacity .25s; }
#wr-dim.on { opacity:1; }
.wr-exit { border-color:rgba(157,224,192,.62); color:#f4ffef; background:rgba(24,44,42,.86); }
.wr-exit:hover,.wr-exit:focus-visible { background:#385e59; border-color:var(--wr-comet); }
.wr-hud .ow-hud-in { gap:12px; }
/* the place name is the thing you read; the breadcrumb gives way to it rather
   than squeezing "Kettlebridge Verge" onto two lines and under the bar */
.wr-hud .ow-place { flex: 1 1 180px; }
.wr-hud .ow-place-name, .wr-hud .ow-place-sub { white-space: normal; }
.wr-ribbon { display:flex; align-items:center; gap:4px; min-width:0; flex:0 1 auto; overflow:hidden; padding:8px 13px; color:#b9c8c2;
  border:1px dashed rgba(242,231,201,.3); border-radius:4px 13px 4px 13px; background:rgba(24,44,42,.72);
  font:800 8px/1 var(--ow-font-ui); text-transform:uppercase; letter-spacing:.08em; transform:rotate(-.5deg); }
.wr-ribbon i { font-style:normal; opacity:.46; white-space:nowrap; }.wr-ribbon i.done { color:var(--wr-comet); opacity:1; }.wr-ribbon b{opacity:.35;}
.wr-camp,.wr-route { width:min(660px,94vw); text-align:left; }
.wr-camp>p,.wr-route>p { line-height:1.55; }
.wr-camp-choices { display:grid; grid-template-columns:repeat(3,1fr); gap:9px; margin:15px 0; }
.wr-camp-choices button { min-height:126px; padding:16px 13px; text-align:left; cursor:pointer; color:var(--wr-salt);
  background:linear-gradient(155deg,rgba(109,145,163,.16),rgba(24,44,42,.62)); border:1px solid rgba(157,224,192,.3);
  border-radius:5px 18px 5px 18px; transition:transform .16s,background .16s; }
.wr-camp-choices button:hover { transform:translateY(-3px); background:linear-gradient(155deg,rgba(227,154,98,.22),rgba(24,44,42,.7)); }
.wr-camp-choices b,.wr-camp-choices span { display:block; }.wr-camp-choices b { color:var(--wr-comet); margin-bottom:9px; font:700 16px/1.1 var(--ow-font-story); }
.wr-camp-choices span { font-size:11px; line-height:1.45; opacity:.78; }
.wr-route-line { display:flex; align-items:center; justify-content:center; gap:8px; padding:18px; margin:12px 0;
  color:#aebbb7; background:rgba(24,44,42,.42); border-radius:5px 17px; font:800 10px/1 var(--ow-font-ui); text-transform:uppercase; }
.wr-route-line i{font-style:normal;opacity:.4}.wr-route-line i.done{color:var(--wr-comet);opacity:1}.wr-route-line b{opacity:.4}
.wr-objective { padding:14px 16px; border-left:3px solid var(--wr-hearth); background:rgba(227,154,98,.08); }
.wr-objective small,.wr-objective b { display:block; }.wr-objective small{margin-bottom:5px;color:var(--wr-hearth);font:800 9px/1 var(--ow-font-ui);text-transform:uppercase;letter-spacing:.15em}
.wr-bearing-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:9px; margin:14px 0; }
.wr-bearing-grid>div { padding:13px;text-align:center;opacity:.38;border:1px dashed rgba(255,255,255,.25);border-radius:5px 15px; }
.wr-bearing-grid>div.won { opacity:1;border-style:solid;border-color:rgba(157,224,192,.55);background:rgba(157,224,192,.07); }
.wr-bearing-grid i,.wr-bearing-grid b,.wr-bearing-grid span{display:block}.wr-bearing-grid i{color:var(--wr-comet);font-size:20px;font-style:normal}.wr-bearing-grid b{font-size:12px}.wr-bearing-grid span{font-size:9px;opacity:.65;margin-top:3px;text-transform:uppercase}
.wr-bearing-earned { margin:9px auto;color:var(--wr-comet);font-weight:900;font-size:13px; }.wr-bearing-earned.finale{font-size:15px;color:var(--gold)}

@media(max-width:880px){.wr-ribbon{display:none}#wild-route .ow-hud-in{padding:0 9px}#wild-route .ow-hud-right{gap:4px}#wild-route .ow-place-sub,#wild-route .ow-dust span{display:none}#wild-route .ow-gbtn{padding:8px 7px;font-size:9px}.wr-camp-choices{grid-template-columns:1fr}.wr-camp-choices button{min-height:80px}}
@media(prefers-reduced-motion:reduce){.wr-starroads i{animation:none!important}}

/* ------- deckbuilder ------- */
.dbcols { display: flex; gap: 16px; text-align: left; align-items: flex-start; }
.dbcols > div { flex: 1; min-width: 0; }
.dbcols h3 { font-size: 13px; margin-bottom: 6px; color: var(--gold); }
.dblist { max-height: 46vh; overflow-y: auto; padding-right: 4px; }
.dbrow {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px; margin-bottom: 3px;
  background: rgba(255,255,255,0.06); border-radius: 8px; font-size: 12.5px;
  cursor: pointer; user-select: none; transition: background 0.1s ease;
}
.dbrow:hover { background: rgba(255,214,107,0.16); }
.dbrow:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
/* at the copy limit the row still READS — only its + is spent */
.dbrow.maxed { opacity: 0.6; }
.dbcols h3 .dbhint {
  font-size: 10.5px; font-weight: 700; color: var(--cream);
  opacity: 0.45; margin-left: 6px; letter-spacing: 0.02em;
}
.dbrow .dbcost {
  flex: 0 0 20px; height: 20px; border-radius: 50%; background: var(--gold);
  color: #4a3200; font-weight: 900; font-size: 12px; display: flex;
  align-items: center; justify-content: center;
}
.dbrow .dbname { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dbrow .dbstats { opacity: 0.85; font-size: 11.5px; flex: 0 0 auto; }
.dbrow .dbcount { flex: 0 0 auto; font-weight: 900; color: var(--gold); }
.dbrow .set2badge {
  flex: 0 0 auto; font-size: 9.5px; font-weight: 800; padding: 1px 5px; border-radius: 6px;
  background: rgba(140,200,255,0.25); color: #bfe3ff;
}
.dbrow .dbcount.zero { color: rgba(255,246,224,0.35); }
.dbstep { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.dbstep .dbcount { min-width: 30px; text-align: center; font-size: 12px; }
.dbstepbtn {
  width: 22px; height: 22px; border-radius: 7px; padding: 0; flex: 0 0 auto;
  font-size: 15px; line-height: 1; font-weight: 900;
  background: rgba(255,255,255,0.14); color: var(--cream);
  display: grid; place-items: center;
}
.dbstepbtn:hover:not(:disabled) { background: var(--gold); color: #4a3200; transform: none; }
.dbstepbtn:disabled { opacity: 0.25; }
.dbstepbtn.big { width: 44px; height: 44px; border-radius: 12px; font-size: 26px; }

/* tap-to-read: the card, full size, over the builder */
.dbmodal {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  background: rgba(8, 8, 24, 0.72); backdrop-filter: blur(3px);
  animation: fadein 0.15s ease;
}
.dbmodal-inner {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  animation: previewpop 0.14s ease;
}
.dbmodal .cardpv { width: 300px; }
.dbmodal-bar {
  display: flex; align-items: center; gap: 16px;
  padding: 8px 14px; border-radius: 16px;
  background: rgba(20, 20, 48, 0.92); border: 1px solid rgba(255,255,255,0.12);
}
.dbmodal-count {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-width: 128px; font-size: 14px; font-weight: 900; color: var(--gold);
}
.dbmodal-count small { font-size: 10.5px; font-weight: 700; color: var(--cream); opacity: 0.55; }
.dbrow .set2badge.set3 { background: rgba(255,190,96,.24); color: #ffe1a8; }
.dbrow .set2badge.set4 { background: rgba(157,224,192,.20); color: #c9f5e0; }
.dbrow .set2badge.set5 { background: rgba(169,212,255,.20); color: #d8ecff; }
.badge.keepsake { background: #6d4c73; color: #ffe9a8; }
.badge.trailblaze { background:#285b55;color:#c9f5e0; }
/* these two say what happens *later*, so they hang along the foot and leave the
   top-right dial (🌱 / ⚡ / 💤) to say whether the unit can act now */
.unit .badge.keepsake, .unit .badge.trailblaze {
  top: auto; bottom: -8px; font-size: 13px;
  border-radius: 999px; padding: 1px 5px; line-height: 17px;
}
.unit .badge.keepsake { left: -5px; }
.unit .badge.trailblaze { right: -5px; }
/* satchel (campaign collection) */
.satgrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px; max-height: 48vh; overflow-y: auto; padding: 2px;
}
.sattile {
  background: rgba(255,255,255,.06); border-radius: 10px;
  padding: 8px 6px 6px; font-size: 11px; text-align: center;
}
.sattile .satart {
  width: 64px; height: 64px; margin: 0 auto 5px; border-radius: 8px;
  overflow: hidden; font-size: 34px; line-height: 64px;
}
.sattile .satart img, .sattile .satart svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.sattile b { display: block; line-height: 1.2; margin-bottom: 2px; }
.sattile .satcount { color: var(--gold); font-weight: 800; }
.sattile.court-day { box-shadow: inset 0 0 0 1px rgba(255,214,107,.3); }
.sattile.court-night { box-shadow: inset 0 0 0 1px rgba(150,150,230,.4); }
.sattile.court-neutral { box-shadow: inset 0 0 0 1px rgba(200,220,230,.25); }

.deckrow {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; margin-bottom: 8px;
  background: rgba(255,255,255,0.07); border-radius: 12px;
}
.deckrow b { flex: 1; text-align: left; }
#db-name {
  font-family: inherit; font-size: 15px; font-weight: 800; padding: 6px 12px;
  border-radius: 10px; border: 2px solid var(--gold); background: rgba(255,255,255,0.1);
  color: var(--cream); text-align: center; outline: none; max-width: 240px;
}
.dbsearch {
  font-family: inherit; font-size: 13px; padding: 6px 10px; border-radius: 10px;
  border: 2px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.08);
  color: var(--cream); outline: none; width: 160px;
}
.dbsearch:focus { border-color: var(--gold); }

.pilecols { display: flex; gap: 18px; justify-content: center; text-align: left; }
.pilecols h3 { font-size: 13px; margin-bottom: 6px; color: var(--gold); }
.pilecols ul { list-style: none; font-size: 12px; line-height: 1.6; min-width: 150px; }
.pilecols .count { opacity: 0.75; }

#target-banner {
  position: fixed; bottom: 292px; left: 50%; transform: translateX(-50%); z-index: 60;
  display: flex; align-items: center; gap: 10px;
  background: rgba(20, 20, 50, 0.92); color: #fff6e0;
  padding: 10px 20px; border-radius: 999px; font-weight: 800; font-size: 14.5px;
  border: 1.5px solid #ffd66b; box-shadow: 0 6px 20px rgba(0,0,0,0.4);
}

#end-turn.all-done {
  animation: readyglow 1.4s ease-in-out infinite;
}
@keyframes readyglow {
  0%, 100% { box-shadow: 0 4px 10px rgba(0,0,0,0.3); }
  50% { box-shadow: 0 0 18px 4px rgba(255, 214, 107, 0.75); }
}

.helplist { text-align: left; font-size: 15px; line-height: 1.65; }

/* tutorial */
.tut-body { min-height: 300px; display: flex; flex-direction: column; justify-content: center; }
.tut-row { display: flex; gap: 26px; align-items: center; justify-content: center; text-align: left; }
.tut-legend { list-style: none; font-size: 15px; line-height: 1.5; max-width: 330px; }
.tut-legend li { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.tut-legend .bullet {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%; margin-top: 2px;
  display: grid; place-items: center; font-weight: 900; font-size: 13px; color: #fff;
  border: 2px solid rgba(255,255,255,0.6);
}
.tut-legend .bullet.cost { background: radial-gradient(circle at 35% 30%, #ffe9a8, var(--gold-deep)); color: #4a3000; border-color: #b07818; }
.tut-legend .bullet.atk { background: radial-gradient(circle at 35% 30%, #ffb060, #d86a10); }
.tut-legend .bullet.hp { background: radial-gradient(circle at 35% 30%, #7ae87a, #1f8a2f); }
.tut-legend .bullet.star { background: #26265c; }
.tut-legend b { color: var(--gold); }
.tut-dots { margin: 18px 0 4px; }
.tut-dots span { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin: 0 4px; background: rgba(255,255,255,0.25); }
.tut-dots span.on { background: var(--gold); }
.tut-nav { display: flex; gap: 12px; justify-content: center; }
.tut-nav .obtn.ghost { background: rgba(255,255,255,0.12); color: var(--cream); }
.tut-bignum { font-size: 40px; }
.tut-card-demo { flex-shrink: 0; transform: scale(1.35); transform-origin: center; margin: 24px 30px; }
.helplist b { color: var(--gold); }
.overlay .obox.wide { max-width: min(94vw, 980px); }

/* ================= PACK RITUAL (Opus spec: "a gift, a seal, three stars") ================= */
:root {
  --pk-scrim: rgba(12, 10, 32, .88);
  --pk-mouth: #241c3e;
  --pk-dust: #ffe9a8;
  --pk-ease-out: cubic-bezier(.2, .8, .3, 1);
  --pk-ease-pop: cubic-bezier(.34, 1.4, .64, 1);
  --pk-ease-snap: cubic-bezier(.5, 0, .9, .4);
  --pk-ease-flip: cubic-bezier(.5, 0, .2, 1);
  --pk-ease-fly: cubic-bezier(.25, .7, .25, 1);
  --ps: 1; /* speed multiplier; JS sets .72 from pack #4 */
}

/* ---------- the packet (shared by offer + layer) ---------- */
.pk-packet {
  position: relative; display: block;
  width: var(--pw); height: calc(var(--pw) * .75);
  border-radius: calc(var(--pw) * .035);
  perspective: 700px;
  filter: drop-shadow(0 10px 22px rgba(10, 8, 28, .55));
}
.pk-body, .pk-mouth, .pk-flap, .pk-shaft { position: absolute; left: 0; width: 100%; }
.pk-body {
  top: 0; height: 100%; border-radius: inherit;
  background: url('../art/img/ow_pack.webp') center/100% 100% no-repeat, var(--ow-paper);
  box-shadow: inset 0 0 0 1px rgba(120, 88, 40, .22);
}
.pk-mouth {
  top: 0; height: 46%; opacity: 0; border-radius: inherit;
  clip-path: polygon(0 0, 100% 0, 100% 74%, 50% 100%, 0 74%);
  background:
    radial-gradient(120% 90% at 50% 108%, rgba(255, 248, 224, .55), rgba(255, 214, 107, .18) 42%, transparent 70%),
    linear-gradient(180deg, var(--pk-mouth), #120e26);
}
.pk-flap {
  top: 0; height: 46%; transform-origin: top center; backface-visibility: hidden;
  clip-path: polygon(0 0, 100% 0, 100% 74%, 50% 100%, 0 74%);
  border-radius: inherit;
  background: url('../art/img/ow_pack.webp') top center/100% 217.4% no-repeat, var(--ow-paper);
  box-shadow: 0 3px 6px -3px rgba(60, 40, 12, .45);
}
.pk-shaft {
  top: 4%; height: 46%; opacity: 0; transform-origin: bottom center; transform: scaleY(.18);
  background: radial-gradient(60% 100% at 50% 100%,
              rgba(255, 248, 224, .92), rgba(255, 214, 107, .34) 45%, transparent 72%);
  filter: blur(1px); pointer-events: none;
}
/* each set prints its own design on the pack's paper. It sits above the paper
   and below the flap, cord and medal, so opening the pack still reads right. */
.pk-print {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden;
  pointer-events: none; opacity: .92;
}
.pk-print svg { display: block; width: 100%; height: 100%; }
.pk-setline {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  margin: 6px 0 2px; font-size: 11px; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--pk-set, #ffd66b);
}
.pk-setline i { font-style: normal; font-size: 14px; }
.pk-setline span {
  font-size: 9.5px; letter-spacing: .12em; padding: 2px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--pk-set, #ffd66b) 20%, transparent);
}
.pk-cord { position: absolute; top: 46%; left: 0; width: 100%; height: 0; }
.pk-cord i {
  position: absolute; top: calc(var(--pw) * -.011); width: 50%;
  height: calc(var(--pw) * .019); border-radius: 2px;
}
.pk-cord-l { left: 0; transform-origin: left center;
             background: linear-gradient(90deg, #7d5518, var(--ow-brass) 55%, var(--ow-brass-hi)); }
.pk-cord-r { right: 0; transform-origin: right center;
             background: linear-gradient(270deg, #7d5518, var(--ow-brass) 55%, var(--ow-brass-hi)); }
.pk-knot {
  position: absolute; left: 34%; top: calc(var(--pw) * -.024);
  width: calc(var(--pw) * .05); height: calc(var(--pw) * .045); border-radius: 50% 50% 45% 45%;
  background: radial-gradient(circle at 34% 30%, var(--ow-brass-hi), #8a5f22);
}
.pk-medal {
  position: absolute; top: 46%; left: 50%; transform: translate(-50%, -50%);
  width: calc(var(--pw) * .25); aspect-ratio: 1; border-radius: 50%;
  background: var(--ow-paper);
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-brass),
              0 6px 14px -4px rgba(18, 12, 40, .55);
}
.pk-medal img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block; }
.pk-flare {
  position: absolute; top: 46%; left: 50%; width: calc(var(--pw) * .25); aspect-ratio: 1;
  transform: translate(-50%, -50%) scale(.3); opacity: 0; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, var(--ow-starlight) 0%, rgba(255, 214, 107, .62) 38%, transparent 70%);
}
.pk-crumbs { position: absolute; top: 46%; left: 50%; width: 0; height: 0; }
.pk-crumbs i {
  position: absolute; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px; border-radius: 50%;
  background: var(--pk-dust); box-shadow: 0 0 8px rgba(255, 233, 168, .9); opacity: 0;
}

/* ---------- the offer, inside the win overlay ---------- */
.pk-offer { margin: 4px 0 16px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.overlay .pk-line {
  margin: 0; opacity: 1;
  font: 400 16px/1.5 var(--ow-font-story); font-variant: small-caps; letter-spacing: .05em;
  color: var(--ow-starlight);
}
.pk-trigger {
  background: none; padding: 0; display: flex; flex-direction: column; align-items: center; gap: 11px;
  border: none; cursor: pointer;
}
.pk-trigger:hover:not(:disabled) { transform: none; filter: none; }
.pk-trigger .pk-packet { animation: pk-breathe 3.6s ease-in-out infinite; transition: transform 220ms var(--pk-ease-out); }
.pk-trigger:hover .pk-packet,
.pk-trigger:focus-visible .pk-packet { animation-play-state: paused; transform: translateY(-4px) scale(1.025); }
.pk-trigger:hover .pk-medal,
.pk-trigger:focus-visible .pk-medal {
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-gold),
              0 0 24px rgba(255, 214, 107, .6), 0 8px 18px -5px rgba(18, 12, 40, .6);
}
.pk-trigger:focus-visible { outline: 2px solid var(--ow-gold); outline-offset: 8px; border-radius: 14px; }
.pk-cta {
  font: 800 12.5px/1 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .16em;
  color: var(--ow-gold); border: 1px solid rgba(255, 214, 107, .5);
  border-radius: 999px; padding: 9px 20px; transition: background 150ms, color 150ms;
}
.pk-trigger:hover .pk-cta { background: var(--ow-gold); color: #4a3200; border-color: var(--ow-gold); }
.pk-offer.leaving { animation: pk-offer-out calc(180ms * var(--ps)) var(--pk-ease-out) forwards; }
.pk-nudge .pk-knot { animation: pk-tug 420ms ease-in-out; }

@keyframes pk-breathe { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2.5px); } }
@keyframes pk-tug {
  0%, 100% { transform: translateX(0) rotate(0); }
  35% { transform: translateX(3px) rotate(7deg); }
  70% { transform: translateX(-1px) rotate(-3deg); }
}
@keyframes pk-offer-out { to { opacity: 0; transform: scale(.94); } }

/* ---------- the opening layer ---------- */
.pk-layer {
  position: fixed; inset: 0; z-index: 130; display: grid; place-items: center;
  background: radial-gradient(120% 100% at 50% 34%, rgba(38, 28, 74, .82), var(--pk-scrim) 62%);
  -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px);
  animation: fadein calc(180ms * var(--ps)) ease;
  cursor: pointer;
}
.pk-stage {
  position: relative; width: 520px;
  display: flex; flex-direction: column; align-items: center;
  transform-origin: center center;
}
.pk-stage .pk-packet { margin-bottom: 34px; opacity: 0; }
/* the bottom padding is the ribbon's lane — see .pk-tag */
.pk-row { display: flex; gap: 22px; padding-bottom: 30px; }
/* the set name sat against the revealed cards, which overhang their slots
   by 9px; hug the packet instead and leave the cards some air */
.pk-stage .pk-setline { margin: -14px 0 22px; }
.pk-slot { position: relative; width: 148px; height: 200px; flex: none; }
.pk-mote {
  position: absolute; left: 50%; top: 50%; width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px;
  border-radius: 50%; background: var(--ow-starlight); opacity: 0;
  box-shadow: 0 0 14px 5px rgba(255, 233, 168, .85), 0 0 34px 12px rgba(255, 214, 107, .35);
  transform: translate(var(--fx), var(--fy));
}
.pk-card {
  position: absolute; left: 50%; top: 50%; width: var(--card-w); height: var(--card-h);
  margin: calc(var(--card-h) / -2) 0 0 calc(var(--card-w) / -2);
  transform-style: preserve-3d; transform: rotateY(180deg) scale(.12);
  visibility: hidden;
}
.pk-face { position: absolute; inset: 0; backface-visibility: hidden; border-radius: 10px; }
.pk-front { transform: rotateY(0deg); }
.pk-back { transform: rotateY(180deg);
  background: linear-gradient(160deg, #fdf3de, #e6d3ab);
  box-shadow: inset 0 0 0 2.5px var(--ow-brass), inset 0 0 0 4px var(--ow-rim),
              0 3px 8px rgba(0, 0, 0, .3);
  display: grid; place-items: center;
}
.pk-back::after {
  content: ''; position: absolute; width: 74px; height: 74px; border-radius: 50%;
  border: 1.5px solid rgba(201, 144, 63, .42);
}
.pk-mark {
  width: 40px; height: 40px; background: linear-gradient(180deg, var(--ow-gold), var(--ow-gold-deep));
  clip-path: polygon(50% 0%, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0% 50%, 39% 39%);
}
.pk-card .card { cursor: default; transition: none; }
.pk-card .card:hover { transform: rotateY(0deg); box-shadow: 0 3px 8px rgba(0, 0, 0, .3); z-index: auto; }

/* the ribbon hangs BELOW the card — across its foot it buried the atk/hp badges */
.pk-tag {
  position: absolute; left: 50%; top: calc(50% + var(--card-h) / 2 + 6px);
  transform: translateX(-50%) translateY(7px);
  white-space: nowrap; opacity: 0;
  font: 400 10px/1 var(--ow-font-story); font-variant: small-caps; letter-spacing: .06em;
  color: #4a3200; background: linear-gradient(180deg, var(--ow-brass-hi), var(--ow-brass));
  border: 1px solid var(--ow-rim); border-radius: 999px; padding: 4px 10px;
  box-shadow: 0 3px 10px -3px rgba(18, 12, 40, .6);
}
.pk-sparks { position: absolute; left: 50%; top: 50%; width: 0; height: 0; }
.pk-sparks i {
  position: absolute; width: 6px; height: 6px; margin: -3px 0 0 -3px; opacity: 0;
  background: var(--ow-starlight);
  clip-path: polygon(50% 0%, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0% 50%, 39% 39%);
}
.pk-flecks { position: absolute; left: 50%; top: 58%; width: 0; height: 0; }
.pk-flecks i {
  position: absolute; width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%;
  background: var(--pk-dust); box-shadow: 0 0 7px rgba(255, 233, 168, .85); opacity: 0;
}
.pk-flyer {
  position: absolute; left: 50%; top: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px;
  border-radius: 50%; background: var(--ow-starlight); opacity: 0;
  box-shadow: 0 0 12px 4px rgba(255, 233, 168, .9);
}
.pk-dustcard {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(.5);
  width: 122px; opacity: 0; text-align: center;
}
.pk-dustcard .ow-star { width: 15px; height: 15px; display: inline-block; vertical-align: -2px; }
.pk-dustcard b {
  font: 800 25px/1 var(--ow-font-ui); color: var(--ow-gold); margin-left: 5px;
  text-shadow: 0 0 16px rgba(255, 214, 107, .55);
}
.pk-dustcard em {
  display: block; margin-top: 7px; font-style: normal;
  font: 400 13px/1.25 var(--ow-font-story); font-variant: small-caps; letter-spacing: .05em;
  color: var(--ow-starlight);
}
.pk-dustcard small {
  display: block; margin-top: 3px;
  font: 700 9px/1 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .14em;
  color: rgba(255, 248, 224, .48);
}
.pk-dustcard::before {
  content: ''; position: absolute; left: 50%; top: 22px; transform: translate(-50%, -50%);
  width: 88px; height: 88px; border-radius: 50%; z-index: -1;
  background: radial-gradient(circle, rgba(255, 214, 107, .16), transparent 68%);
  box-shadow: 0 0 0 1px rgba(201, 144, 63, .34);
}
.pk-tally {
  margin-top: 18px; display: flex; align-items: center; gap: 7px;
  color: rgba(255, 243, 220, .8);
}
.pk-tally b {
  font: 800 17px/1 var(--ow-font-ui); font-variant-numeric: tabular-nums; color: var(--ow-gold);
  display: inline-block; transition: color 180ms;
}
.pk-tally span {
  font: 700 9.5px/1 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .14em; opacity: .55;
}
.pk-tally.bump b { animation: pk-tally-bump calc(260ms * var(--ps)) var(--pk-ease-pop); }
.pk-foot {
  margin: 20px 0 0; min-height: 24px; opacity: 0;
  font: 400 17px/1.4 var(--ow-font-story); font-variant: small-caps; letter-spacing: .05em;
  color: var(--ow-starlight);
}
.pk-done {
  margin-top: 14px; opacity: 0; pointer-events: none;
  padding: 13px 26px; font-size: 16px; border-radius: 12px; border: none; cursor: pointer;
  font-family: inherit; font-weight: 800;
  background: linear-gradient(180deg, var(--ow-gold), var(--ow-gold-deep)); color: #4a3000;
  box-shadow: 0 4px 0 #cf8b1f, 0 10px 22px -8px rgba(120, 70, 10, .6);
}
.pk-skip {
  position: absolute; right: 0; bottom: -34px; background: none; padding: 6px 4px; border: none; cursor: pointer;
  font: 700 11px/1 var(--ow-font-ui); text-transform: lowercase; letter-spacing: .12em;
  color: rgba(255, 243, 220, .5); transition: color 150ms;
}
.pk-skip:hover:not(:disabled) { color: var(--ow-gold); transform: none; filter: none; }
.pk-stage[data-state="done"] .pk-skip { opacity: 0; pointer-events: none; }
.pk-stage[data-state="done"] .pk-foot { opacity: 1; animation: pk-foot-in calc(260ms * var(--ps)) var(--pk-ease-out); }
.pk-stage[data-state="done"] .pk-done { opacity: 1; pointer-events: auto;
  animation: pk-foot-in calc(260ms * var(--ps)) var(--pk-ease-out) 70ms both; }
.pk-done:focus-visible, .pk-skip:focus-visible { outline: 2px solid var(--ow-gold); outline-offset: 4px; }

/* ---------- the animation classes (JS toggles these) ---------- */
.pk-go-arrive .pk-packet { opacity: 1; transform: rotate(-2deg);
  animation: pk-arrive calc(380ms * var(--ps)) var(--pk-ease-out) calc(60ms * var(--ps)) backwards; }
.pk-go-snap .pk-cord-l { animation: pk-cord-l calc(120ms * var(--ps)) var(--pk-ease-snap) forwards; }
.pk-go-snap .pk-cord-r { animation: pk-cord-r calc(120ms * var(--ps)) var(--pk-ease-snap) forwards; }
.pk-go-snap .pk-knot { animation: pk-cord-l calc(120ms * var(--ps)) var(--pk-ease-snap) forwards; }
.pk-go-snap .pk-packet { animation: pk-recoil calc(180ms * var(--ps)) var(--pk-ease-pop); }
.pk-go-burst .pk-medal { animation: pk-seal-burst calc(240ms * var(--ps)) cubic-bezier(.3,0,.2,1) forwards; }
.pk-go-burst .pk-flare { animation: pk-flare calc(420ms * var(--ps)) cubic-bezier(.15,.7,.3,1) forwards; }
.pk-go-burst .pk-crumbs i { animation: pk-crumb calc(520ms * var(--ps)) cubic-bezier(.15,.75,.3,1) forwards; }
.pk-go-open .pk-flap { animation: pk-flap-open calc(240ms * var(--ps)) var(--pk-ease-pop) forwards; }
.pk-go-open .pk-mouth { animation: pk-mouth-in calc(240ms * var(--ps)) ease-out forwards; }
.pk-go-open .pk-shaft { animation: pk-shaft calc(300ms * var(--ps)) var(--pk-ease-out) calc(40ms * var(--ps)) forwards; }
.pk-slot.fly .pk-mote { animation: pk-mote-fly calc(340ms * var(--ps)) var(--pk-ease-fly) forwards; }
.pk-slot.grow .pk-card { visibility: visible; animation: pk-card-grow calc(200ms * var(--ps)) var(--pk-ease-pop) forwards; }
.pk-slot.flip .pk-card { animation: pk-card-flip calc(280ms * var(--ps)) var(--pk-ease-flip) forwards; }
.pk-slot.crown .pk-front { animation: pk-rim-new calc(400ms * var(--ps)) var(--pk-ease-out) forwards; }
.pk-slot.crown .pk-tag { animation: pk-tag-in calc(220ms * var(--ps)) var(--pk-ease-pop) calc(90ms * var(--ps)) forwards; }
.pk-slot.crown .pk-sparks i { animation: pk-spark calc(480ms * var(--ps)) var(--pk-ease-out) var(--d) forwards; }
.pk-slot.melt .pk-card { animation: pk-dust-out calc(560ms * var(--ps)) cubic-bezier(.4,0,.6,1) forwards; }
.pk-slot.melt .pk-flecks i { animation: pk-dust-rise calc(640ms * var(--ps)) var(--pk-ease-out) var(--d) forwards; }
.pk-slot.send .pk-flyer { animation: pk-fly-tally calc(420ms * var(--ps)) cubic-bezier(.4,0,.2,1) forwards; }
.pk-slot.land .pk-dustcard { animation: pk-dustcard-in calc(300ms * var(--ps)) var(--pk-ease-pop) forwards; }

/* rushed (skip) overrides */
.pk-stage.rush { --ps: .5; }
.pk-stage.rush .pk-packet { animation: none; opacity: 1; transform: none; }
.pk-stage.rush .pk-flap { animation: none; transform: rotateX(-154deg); filter: brightness(.72); }
.pk-stage.rush .pk-mouth { animation: none; opacity: 1; }
.pk-stage.rush .pk-medal, .pk-stage.rush .pk-cord,
.pk-stage.rush .pk-flare, .pk-stage.rush .pk-crumbs, .pk-stage.rush .pk-mote { display: none; }

/* ---------- keyframes ---------- */
@keyframes pk-arrive {
  from { opacity: 0; transform: translateY(30px) scale(.84) rotate(-5deg); }
  to { opacity: 1; transform: translateY(0) scale(1) rotate(-2deg); }
}
@keyframes pk-recoil {
  0% { transform: scale(1) rotate(-2deg); }
  38% { transform: scale(1.045, .955) rotate(-2.6deg); }
  100% { transform: scale(1) rotate(-2deg); }
}
@keyframes pk-cord-l { to { transform: scaleX(0) rotate(6deg) translateY(5px); opacity: 0; } }
@keyframes pk-cord-r { to { transform: scaleX(0) rotate(-6deg) translateY(5px); opacity: 0; } }
@keyframes pk-seal-burst {
  from { transform: translate(-50%, -50%) scale(1); opacity: 1; filter: blur(0); }
  to { transform: translate(-50%, -50%) scale(1.4); opacity: 0; filter: blur(4px); }
}
@keyframes pk-flare {
  0% { transform: translate(-50%, -50%) scale(.3); opacity: 0; }
  30% { transform: translate(-50%, -50%) scale(1.5); opacity: .85; }
  100% { transform: translate(-50%, -50%) scale(2.7); opacity: 0; }
}
@keyframes pk-crumb {
  0% { transform: rotate(var(--a)) translateX(6px) scale(1); opacity: 1; }
  100% { transform: rotate(var(--a)) translateX(92px) scale(.15); opacity: 0; }
}
@keyframes pk-flap-open {
  from { transform: rotateX(0deg); filter: brightness(1); }
  to { transform: rotateX(-154deg); filter: brightness(.72); }
}
@keyframes pk-mouth-in { to { opacity: 1; } }
@keyframes pk-shaft { to { opacity: .7; transform: scaleY(1); } }
@keyframes pk-mote-fly {
  0% { transform: translate(var(--fx), var(--fy)) scale(1); opacity: 1; }
  55% { opacity: 1; }
  70% { transform: translate(calc(var(--fx) * .3), calc(var(--fy) * .3)) scale(1.6); opacity: 1; }
  92% { transform: translate(0, 0) scale(1.05); opacity: 1; }
  100% { transform: translate(0, 0) scale(.9); opacity: 0; }
}
@keyframes pk-card-grow {
  from { transform: rotateY(180deg) scale(.12); }
  to { transform: rotateY(180deg) scale(1); }
}
@keyframes pk-card-flip {
  0% { transform: rotateY(180deg) scale(1); }
  79% { transform: rotateY(0deg) scale(1.07); }
  100% { transform: rotateY(0deg) scale(1); }
}
@keyframes pk-rim-new {
  0% { box-shadow: 0 3px 8px rgba(0, 0, 0, .3); }
  45% { box-shadow: 0 0 0 3px var(--ow-gold), 0 0 26px rgba(255, 214, 107, .62), 0 3px 8px rgba(0, 0, 0, .3); }
  100% { box-shadow: 0 0 0 2px var(--ow-gold), 0 0 12px rgba(255, 214, 107, .4), 0 3px 8px rgba(0, 0, 0, .3); }
}
@keyframes pk-tag-in { to { opacity: 1; transform: translateX(-50%) translateY(0); } }
@keyframes pk-spark {
  0% { transform: translate(0, 0) scale(.2); opacity: 0; }
  25% { transform: translate(calc(var(--sx) * .4), calc(var(--sy) * .4)) scale(1.15); opacity: 1; }
  100% { transform: translate(var(--sx), var(--sy)) scale(.3); opacity: 0; }
}
@keyframes pk-dust-out {
  0% { transform: rotateY(0deg) scale(1); opacity: 1; filter: brightness(1) saturate(1); }
  55% { opacity: .7; filter: brightness(1.55) saturate(.6); }
  100% { transform: rotateY(0deg) scale(.88); opacity: 0; filter: brightness(1.9) saturate(.35); }
}
@keyframes pk-dust-rise {
  0% { transform: translate(var(--jx), 14px) scale(1); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: translate(calc(var(--jx) * 1.5), -48px) scale(.25); opacity: 0; }
}
@keyframes pk-fly-tally {
  0% { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(var(--tx), var(--ty)) scale(.4); opacity: 0; }
}
@keyframes pk-tally-bump {
  0% { transform: scale(1); color: var(--ow-gold); }
  40% { transform: scale(1.28); color: var(--ow-starlight); }
  100% { transform: scale(1); color: var(--ow-gold); }
}
@keyframes pk-dustcard-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.5); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes pk-foot-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---------- responsive ---------- */
@media (max-width: 559px) { .pk-stage { transform: scale(.82); } }
@media (max-width: 459px) { .pk-stage { transform: scale(.64); } }
@media (max-height: 660px) { .pk-stage { transform: scale(.76); } }
@media (max-width: 459px) and (max-height: 660px) { .pk-stage { transform: scale(.58); } }

/* ---------- reduced motion: no layer, static result inline ---------- */
@media (prefers-reduced-motion: reduce) {
  .pk-static { animation: fadein 200ms ease; }
  .pk-static .pk-slot { display: inline-block; }
  .pk-static .pk-card { visibility: visible; transform: rotateY(0deg) scale(1); }
  .pk-static .pk-back, .pk-static .pk-mote, .pk-static .pk-flecks,
  .pk-static .pk-flyer, .pk-static .pk-sparks { display: none; }
  .pk-static .is-dust { display: none; }
  .pk-static .pk-tag { opacity: 1; transform: translateX(-50%); }
  .pk-static .pk-dustcard { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  .pk-static .is-new .pk-front {
    box-shadow: 0 0 0 2px var(--ow-gold), 0 0 12px rgba(255, 214, 107, .4), 0 3px 8px rgba(0, 0, 0, .3);
  }
  .pk-static .pk-foot { opacity: 1; }
}

/* ------- account panel ------- */
.acct-form { display: flex; flex-direction: column; gap: 10px; max-width: 300px; margin: 0 auto 4px; }
.acct-field { display: flex; flex-direction: column; gap: 4px; text-align: left; }
.acct-field span {
  font: 700 10px/1 var(--ow-font-ui, inherit); text-transform: uppercase;
  letter-spacing: .14em; opacity: .7;
}
.acct-field input, #chart-code-in {
  font-family: inherit; font-size: 15px; padding: 9px 12px; border-radius: 10px;
  border: 2px solid var(--gold); background: rgba(255, 255, 255, 0.1);
  color: var(--cream); outline: none;
}
.acct-field input:focus, #chart-code-in:focus { border-color: #fff3dc; }
.acct-note { min-height: 20px; font-size: 13px; margin: 8px 0 2px; opacity: .9; }
.acct-note.good { color: var(--gold); }
.acct-note.bad { color: #ffb0b0; }
.linkbtn {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  font-size: 13px; color: var(--gold); text-decoration: underline;
}
.linkbtn:hover { color: #fff3dc; }
.obtn.danger { background: linear-gradient(180deg, #e88a8a, #c95a5a); color: #fff; box-shadow: 0 4px 0 #a34444; }
.linkbtn.danger { color: #ffb0b0; }
.linkbtn.danger:hover { color: #ff8f8f; }

/* a doorway reads as somewhere to step into, not a signpost to somewhere else */
.lh-exit.lh-door {
  border-radius: 14px 14px 4px 4px;
  background: linear-gradient(180deg, rgba(38,28,64,.92), rgba(24,18,44,.94));
  border-color: rgba(255,214,107,.55);
  padding-top: 10px;
}
.lh-exit.lh-door::before {
  content: ''; display: block; width: 18px; height: 3px; margin: 0 auto 5px;
  border-radius: 2px; background: var(--ow-gold, #ffd66b); opacity: .85;
}
.dbearn {
  margin: 0 0 10px; padding: 7px 10px; border-radius: 8px; font-size: 11.5px; line-height: 1.5;
  background: rgba(255,214,107,.09); border: 1px solid rgba(255,214,107,.24); color: #e9dcc4;
}
.dbearn b { color: var(--gold, #ffd66b); }

/* a card you have not earned is still worth looking at: dimmed, not hidden */
.dbrow.locked { opacity: .48; }
.dbrow.locked .dbname { color: #cfc6dd; }
.dbrow.locked .dbcount { letter-spacing: 0; }
.dbrow.locked:hover, .dbrow.locked:focus-visible { opacity: .72; }

/* a gate that is shut is still a gate: you can walk up to it and be told no */
.lh-exit.lh-shut {
  border-radius: 14px 14px 4px 4px;
  background: linear-gradient(180deg, rgba(30,26,38,.9), rgba(18,16,26,.92));
  border-color: rgba(198,186,206,.38);
  color: #cfc3d6; padding-top: 10px;
}
.lh-exit.lh-shut::before {
  content: ''; display: block; width: 18px; height: 7px; margin: 0 auto 5px;
  border-radius: 2px; opacity: .7;
  background: repeating-linear-gradient(90deg, #b9adc4 0 2px, transparent 2px 4px),
              linear-gradient(#b9adc4, #b9adc4) center/100% 2px no-repeat;
}
.lh-exit.lh-shut:hover, .lh-exit.lh-shut:focus-visible {
  background: #3a3346; border-color: rgba(216,206,224,.6);
}

/* indoors, the street furniture has no business glowing */
#lantern-hollow.interior .lh-lights, #lantern-hollow.interior .lh-nightwash,
#cloudbreak.interior .lh-lights, #cloudbreak.interior .lh-nightwash { display: none; }

/* chapter-one area exits, matching the town's doors */
.ow-exit {
  position: absolute; transform: translate(-50%, -50%); z-index: 320;
  font: 700 11.5px/1 var(--ow-font-ui, inherit); letter-spacing: .04em;
  color: #f4e6c8; background: rgba(26,20,48,.86);
  border: 1px solid rgba(255,243,220,.28); border-radius: 12px;
  padding: 8px 14px; cursor: pointer; white-space: nowrap;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background 140ms, border-color 140ms, transform 140ms;
}
.ow-exit:hover { background: rgba(255,214,107,.2); border-color: var(--ow-gold, #ffd66b); transform: translate(-50%,-50%) scale(1.04); }
.ow-exit.near {
  background: rgba(255,214,107,.2); border-color: var(--ow-gold, #ffd66b);
  box-shadow: 0 0 0 2px rgba(255,214,107,.14), 0 0 18px rgba(255,214,107,.26);
}
.ow-exit.ow-door { border-radius: 14px 14px 4px 4px; padding-top: 10px; border-color: rgba(255,214,107,.55); }
.ow-exit.ow-door::before {
  content: ''; display: block; width: 18px; height: 3px; margin: 0 auto 5px;
  border-radius: 2px; background: var(--ow-gold, #ffd66b); opacity: .85;
}

/* Star Echoes: details hidden in the painting, not map pins laid over it.
   The 72px button is generous for touch; only its small hand-drawn orbit is
   visible. A found echo settles into a tiny constellation instead of vanishing,
   so the landscape keeps the mark of having been listened to. */
.ow-echo {
  --echo-mint: #9de0c0; --echo-violet: #a793ff; --echo-light: #fff8e0;
  position: absolute; z-index: 86; width: 72px; height: 72px;
  margin: -36px 0 0 -36px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--echo-light); cursor: pointer;
  opacity: .22; transform: scale(.78); filter: saturate(.7);
  transition: opacity .45s ease, transform .55s var(--ow-ease-lift), filter .45s ease;
}
.ow-echo::before {
  content: ''; position: absolute; left: 25px; top: 25px; width: 22px; height: 22px;
  border: 1px solid rgba(255,248,224,.5); border-left-color: transparent;
  border-radius: 48% 52% 46% 54%; transform: rotate(-22deg);
  box-shadow: 0 0 13px rgba(167,147,255,.26);
  animation: ow-echo-orbit 7s ease-in-out infinite;
}
.ow-echo::after {
  content: ''; position: absolute; left: 34px; top: 34px; width: 4px; height: 4px;
  border-radius: 50%; background: var(--echo-light);
  box-shadow: 0 0 8px 2px rgba(255,248,224,.72), -12px 7px 0 -1px rgba(157,224,192,.9),
    11px -9px 0 -1px rgba(167,147,255,.9);
}
.ow-echo i { position: absolute; display: block; pointer-events: none; }
.ow-echo i:nth-child(1) {
  left: 20px; top: 36px; width: 32px; height: 1px; transform: rotate(-31deg);
  background: linear-gradient(90deg, transparent, rgba(255,248,224,.58), transparent);
}
.ow-echo i:nth-child(2) {
  left: 31px; top: 20px; width: 1px; height: 31px; transform: rotate(27deg);
  background: linear-gradient(180deg, transparent, rgba(157,224,192,.55), transparent);
}
.ow-echo i:nth-child(3) { inset: 12px; border-radius: 50%; border-top: 1px dashed rgba(167,147,255,.38); }
.ow-echo span {
  position: absolute; left: 50%; top: 61px; transform: translate(-50%, 7px);
  width: max-content; max-width: 190px; padding: 6px 10px; border-radius: 10px;
  color: #fff8e8; background: rgba(23,25,54,.86); border: 1px solid rgba(255,248,224,.22);
  box-shadow: 0 7px 22px rgba(11,10,30,.28);
  font: 700 10px/1.15 var(--ow-font-ui); letter-spacing: .055em;
  opacity: 0; pointer-events: none; transition: opacity .22s ease, transform .28s ease;
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
}
.ow-echo:hover, .ow-echo:focus-visible, .ow-echo.near {
  opacity: 1; transform: scale(1); filter: saturate(1.15);
}
.ow-echo:hover span, .ow-echo:focus-visible span, .ow-echo.near span {
  opacity: 1; transform: translate(-50%, 0);
}
.ow-echo:focus-visible { outline: 2px solid var(--echo-mint); outline-offset: 3px; }
.ow-echo.found { opacity: .58; transform: scale(.88); filter: saturate(1.1); }
.ow-echo.found::before { border-style: dotted; border-color: rgba(157,224,192,.7); }
.ow-echo.found:hover, .ow-echo.found:focus-visible, .ow-echo.found.near { opacity: 1; transform: scale(1); }
.ow-echo.found-now { animation: ow-echo-found 1.35s var(--ow-ease-lift) both; }
@keyframes ow-echo-orbit {
  0%,100% { transform: rotate(-22deg) scale(.94); }
  50% { transform: rotate(158deg) scale(1.08); }
}
@keyframes ow-echo-found {
  0% { filter: brightness(1); }
  28% { filter: brightness(2.3) drop-shadow(0 0 18px rgba(157,224,192,.9)); }
  100% { filter: brightness(1); }
}
.night .ow-echo, .ow-scene[data-time="night"] .ow-echo {
  --echo-mint: #b9f1d8; opacity: .38; mix-blend-mode: screen;
}
.night .ow-echo.near, .ow-scene[data-time="night"] .ow-echo.near { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .ow-echo, .ow-echo::before, .ow-echo.found-now { animation: none !important; transition: none; }
}

/* The journal remembers discovered echoes without revealing their names first.
   It borrows the route-map language—ink, dashes, tiny plotted stars—rather
   than looking like an achievement grid. */
.ow-echo-ledger {
  margin: 16px 0 18px; padding: 14px;
  color: #e9dcc4; background: rgba(23,25,54,.28);
  border: 1px solid rgba(167,147,255,.2); border-radius: 5px 16px 5px 16px;
}
.ow-echo-ledger > header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 11px; }
.ow-echo-ledger > header small, .ow-echo-ledger > header b { display: block; }
.ow-echo-ledger > header small {
  color: #a793ff; font: 800 8px/1 var(--ow-font-ui); letter-spacing: .18em; text-transform: uppercase;
}
.ow-echo-ledger > header b { margin-top: 4px; color: #fff3dc; font: 700 13px/1.1 var(--ow-font-story); }
.ow-echo-ledger > header > i { color: #9de0c0; font: 400 22px/1 var(--ow-font-story); font-style: normal; }
.ow-echo-ledger-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 8px; }
.ow-echo-ledger-grid > div {
  display: flex; align-items: center; gap: 9px; min-width: 0; padding: 10px;
  color: rgba(233,220,196,.48); border: 1px dashed rgba(233,220,196,.18); border-radius: 4px 12px;
}
.ow-echo-ledger-grid > div > i {
  flex: 0 0 auto; width: 18px; height: 18px; border-radius: 50%;
  border: 1px dotted currentColor; transform: rotate(-16deg);
}
.ow-echo-ledger-grid > div span, .ow-echo-ledger-grid > div b, .ow-echo-ledger-grid > div small { display: block; min-width: 0; }
.ow-echo-ledger-grid > div b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 700 11px/1.2 var(--ow-font-story); }
.ow-echo-ledger-grid > div small { margin-top: 3px; font: 700 8px/1.2 var(--ow-font-ui); text-transform: uppercase; letter-spacing: .08em; }
.ow-echo-ledger-grid > div.found { color: #fff3dc; border-style: solid; border-color: rgba(157,224,192,.28); background: rgba(157,224,192,.05); }
.ow-echo-ledger-grid > div.found > i {
  border-color: #9de0c0; box-shadow: inset 0 0 0 5px rgba(23,25,54,.8), 0 0 9px rgba(157,224,192,.35);
  background: #fff8e0;
}
@media (max-width: 560px) { .ow-echo-ledger-grid { grid-template-columns: 1fr; } }
@media (max-width: 560px) {
  .overlay .lh-journal, .overlay .wr-route { padding: 22px 20px; }
}
/* the view through the telescope */
.ow-skybox .ow-skyplate {
  position: relative; width: 100%; max-width: 620px; margin: 0 auto 14px;
  aspect-ratio: 16/9; border-radius: 999px / 60%; overflow: hidden;
  box-shadow: 0 0 0 6px rgba(201,144,63,.55), 0 0 0 10px rgba(255,248,234,.18),
              inset 0 0 70px 30px rgba(4,4,16,.85);
}
.ow-skybox .ow-skyplate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ow-skybox .ow-skyplate.daylight { background: radial-gradient(circle at 50% 45%, #bfe3f2, #6ea8d4 70%); }
.ow-skybox .ow-skygap {
  position: absolute; left: 44%; top: 34%; width: 22%; height: 26%;
  border-radius: 50%; transform: translate(-50%,-50%);
  background: radial-gradient(50% 50%, rgba(6,5,20,.96), rgba(6,5,20,.55) 55%, transparent 74%);
  filter: blur(2px);
}

/* ---- phones: the overworld HUD wraps into two rows, in every chapter ----
   One 44px rail cannot hold a place name, a purse, a clock, a dial and four
   buttons at 390px, and the fixed music button sits on whatever lands under
   it. Row one is the place (with room kept clear for the music button) and
   the course ribbon beneath it; row two is purse, dial and buttons. This
   block sits last so it wins over each chapter's own narrow-screen rules. */
@media (max-width: 760px) {
  #overworld .ow-hud, #lantern-hollow .ow-hud, #cloudbreak .ow-hud, #wild-route .ow-hud { height: auto; padding-bottom: 8px; }
  #overworld .ow-hud::after, #lantern-hollow .ow-hud::after, #cloudbreak .ow-hud::after, #wild-route .ow-hud::after { display: none; }
  #overworld .ow-hud-in, #lantern-hollow .ow-hud-in, #cloudbreak .ow-hud-in, #wild-route .ow-hud-in {
    height: auto; flex-wrap: wrap; row-gap: 8px; padding: 8px 12px 0; align-items: flex-start;
  }
  #overworld .ow-place, #lantern-hollow .ow-place, #cloudbreak .ow-place, #wild-route .ow-place {
    flex: 1 1 100%; min-width: 0; padding-right: 124px;   /* the music button lives here */
  }
  #overworld .ow-place-name, #lantern-hollow .ow-place-name, #cloudbreak .ow-place-name, #wild-route .ow-place-name {
    font-size: 16px; white-space: normal; overflow-wrap: anywhere;
  }
  .ow-goal { position: static; margin-top: 6px; width: auto; max-width: 100%; animation: none; }
  #overworld .ow-hud-right, #lantern-hollow .ow-hud-right, #cloudbreak .ow-hud-right, #wild-route .ow-hud-right {
    flex: 1 1 100%; justify-content: space-between; gap: 6px; flex-wrap: wrap;
  }
  #overworld .ow-dial, #lantern-hollow .ow-dial, #cloudbreak .ow-dial, #wild-route .ow-dial { margin-left: 56px; }
  .wr-ribbon { display: none; }
}

/* Where you pushed against the edge of the walkable ground. A painting cannot
   show you its own collision, so the world answers with a small scuff of light
   instead of letting you bump an invisible wall in silence. */
.ow-edge {
  position: absolute; width: 58px; height: 34px; margin: -17px 0 0 -29px;
  border-radius: 50%; pointer-events: none; z-index: 90;
  background: radial-gradient(closest-side, rgba(255,246,214,.58), rgba(255,246,214,0));
  animation: ow-edge-fade .6s ease-out forwards;
}
@keyframes ow-edge-fade {
  from { opacity: .95; transform: scale(.55); }
  to   { opacity: 0;   transform: scale(1.35); }
}
@media (prefers-reduced-motion: reduce) {
  .ow-edge { animation: ow-edge-fade .6s linear forwards; }
}

/* Charted footsteps. The alternating brush ovals are joined by a dotted
   surveyor's thread, so walking briefly draws a constellation over the road.
   It stays under every token and disappears before becoming a UI layer. */
.ow-trail-mark {
  position: absolute; z-index: 88; pointer-events: none;
  width: 18px; height: 8px; margin: -4px 0 0 -9px;
  border-radius: 70% 35% 65% 40%;
  transform: rotate(var(--trail-angle)) translateY(var(--trail-side));
  color: rgba(255,248,224,.78);
  background: radial-gradient(ellipse at 68% 50%, currentColor 0 18%, rgba(157,224,192,.55) 24%, transparent 68%);
  box-shadow: 0 0 9px rgba(157,224,192,.22);
  mix-blend-mode: screen;
  animation: ow-trail-fade 1.45s ease-out forwards;
}
.ow-trail-mark::before {
  content: ''; position: absolute; left: 12px; top: 2px; width: 5px; height: 5px;
  background: #fff8e0;
  clip-path: polygon(50% 0,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0 50%,39% 39%);
  filter: drop-shadow(0 0 3px rgba(157,224,192,.75));
}
.ow-trail-mark::after {
  content: ''; position: absolute; right: 13px; top: 50%; width: 29px; height: 1px;
  background: repeating-linear-gradient(90deg, rgba(167,147,255,.5) 0 2px, transparent 2px 6px);
}
.ow-trail-mark.night, .night .ow-trail-mark {
  color: rgba(255,248,224,.92); box-shadow: 0 0 12px rgba(157,224,192,.38);
}
@keyframes ow-trail-fade {
  0% { opacity: 0; filter: blur(1px); }
  15% { opacity: .9; filter: none; }
  62% { opacity: .5; }
  100% { opacity: 0; filter: blur(1.5px); }
}
@media (prefers-reduced-motion: reduce) { .ow-trail-mark { display: none; } }

/* A landmark whisper is ambient copy, not a prompt: it never takes input and
   stays clear of both the top HUD and the persistent control hint below. */
.ow-landmark-whisper {
  position: absolute; z-index: 340; left: 50%; bottom: 74px;
  width: min(540px, 78vw); padding: 9px 18px; transform: translateX(-50%);
  pointer-events: none; text-align: center;
  color: rgba(255,248,224,.94); background: rgba(20,18,43,.58);
  border: 1px solid rgba(255,232,168,.24); border-radius: 999px;
  box-shadow: 0 8px 24px -15px rgba(8,7,24,.92);
  text-shadow: 0 1px 8px rgba(8,7,24,.95);
  font: italic 600 15px/1.35 var(--ow-font-story);
  animation: ow-landmark-whisper 3.55s ease both;
}
.ow-landmark-whisper.night, .night .ow-landmark-whisper {
  background: rgba(14,16,41,.66); border-color: rgba(157,224,192,.28);
}
@keyframes ow-landmark-whisper {
  0% { opacity: 0; transform: translate(-50%,8px); filter: blur(2px); }
  14%,76% { opacity: 1; transform: translate(-50%,0); filter: none; }
  100% { opacity: 0; transform: translate(-50%,-4px); filter: blur(1px); }
}
@media (max-width: 760px) {
  .ow-landmark-whisper { bottom: 88px; width: min(430px,78vw); font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .ow-landmark-whisper {
    transform: none; left: 50%; margin-left: max(-270px,-39vw);
    animation: none !important; opacity: 1;
  }
}

/* The place you tapped is stamped like a point on a brass star chart. It
   breathes while the route is active, then folds into its centre on arrival. */
.ow-waypoint {
  position: absolute; z-index: 89; width: 34px; height: 34px;
  margin: -17px 0 0 -17px; border-radius: 50%; pointer-events: none;
  border: 1px dashed rgba(157,224,192,.8);
  box-shadow: 0 0 0 4px rgba(23,25,54,.18), inset 0 0 12px rgba(157,224,192,.2),
    0 0 13px rgba(157,224,192,.18);
  animation: ow-waypoint-breathe 1.1s ease-in-out infinite alternate;
}
.ow-waypoint::before {
  content: ''; position: absolute; left: 10px; top: 10px; width: 12px; height: 12px;
  background: #fff8e0; transform: rotate(13deg);
  clip-path: polygon(50% 0,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0 50%,39% 39%);
  filter: drop-shadow(0 0 4px rgba(157,224,192,.9));
}
.ow-waypoint::after {
  content: ''; position: absolute; inset: 5px; border: 1px solid rgba(167,147,255,.5);
  border-radius: 48% 52% 46% 54%; transform: rotate(-18deg);
}
.ow-waypoint.arrived { animation: ow-waypoint-close .34s ease-in forwards; }
@keyframes ow-waypoint-breathe {
  from { opacity: .56; transform: scale(.82) rotate(-5deg); }
  to { opacity: .94; transform: scale(1.05) rotate(5deg); }
}
@keyframes ow-waypoint-close {
  to { opacity: 0; transform: scale(.3) rotate(35deg); filter: blur(2px); }
}
@media (prefers-reduced-motion: reduce) {
  .ow-waypoint { animation: none; opacity: .8; }
  .ow-waypoint.arrived { opacity: 0; }
}

/* The charter thread redraws the remaining walk route as quiet surveyor's ink:
   brass for the paper chart, mint for its living destination. */
.ow-route-thread {
  position: absolute; inset: 0; z-index: 87; width: 1280px; height: 720px;
  overflow: visible; pointer-events: none;
}
.ow-route-thread-line {
  fill: none; stroke: rgba(201,144,63,.68); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 3 8;
  filter: drop-shadow(0 0 2px rgba(157,224,192,.5));
  animation: ow-route-thread-dash 1.8s linear infinite;
}
.ow-route-turn-star {
  fill: rgba(157,224,192,.9); stroke: rgba(255,232,168,.92); stroke-width: 1;
  filter: drop-shadow(0 0 3px rgba(157,224,192,.72));
}
@keyframes ow-route-thread-dash { to { stroke-dashoffset: -22; } }
@media (prefers-reduced-motion: reduce) {
  .ow-route-thread-line { animation: none; }
}

/* Area changes arrive like ink settling on a field chart. The place stamp is
   a duplicate visual flourish (aria-hidden), while the permanent HUD remains
   the readable source of truth. */
.ow-entering .ow-bg { animation: ow-paint-settle .85s cubic-bezier(.2,.78,.3,1) both; }
.ow-entering .lh-bg, .ow-entering .wr-bg {
  animation: ow-paint-settle-shared .85s cubic-bezier(.2,.78,.3,1) both;
}
.ow-arrival-stamp {
  position: fixed; z-index: 59; left: 50%; top: 23%; width: min(430px, 82vw);
  transform: translateX(-50%); text-align: center; pointer-events: none;
  color: #fff8e0; text-shadow: 0 2px 10px rgba(10,10,28,.92), 0 0 24px rgba(10,10,28,.72);
  animation: ow-arrival-stamp 2.2s ease both;
}
.ow-arrival-stamp > i {
  display: block; position: relative; width: 112px; height: 1px; margin: 0 auto 11px;
  background: linear-gradient(90deg, transparent, #9de0c0 22%, #fff8e0 50%, #9de0c0 78%, transparent);
  box-shadow: 0 0 8px rgba(157,224,192,.45);
}
.ow-arrival-stamp > i::after {
  content: ''; position: absolute; left: 52px; top: -4px; width: 9px; height: 9px;
  background: #fff8e0; transform: rotate(18deg);
  clip-path: polygon(50% 0,61% 39%,100% 50%,61% 61%,50% 100%,39% 61%,0 50%,39% 39%);
}
.ow-arrival-stamp small, .ow-arrival-stamp b, .ow-arrival-stamp span { display: block; }
.ow-arrival-stamp small {
  color: #9de0c0; font: 800 9px/1 var(--ow-font-ui); letter-spacing: .24em; text-transform: uppercase;
}
.ow-arrival-stamp b {
  margin-top: 7px; font: 700 clamp(24px,3vw,38px)/1.05 var(--ow-font-story);
  font-variant: small-caps; letter-spacing: .09em;
}
.ow-arrival-stamp span {
  margin-top: 7px; color: rgba(255,248,224,.72);
  font: italic 600 12px/1 var(--ow-font-story); letter-spacing: .04em;
}
@keyframes ow-paint-settle {
  from { transform: scale(1.024); filter: blur(4px) brightness(.72) saturate(.7); }
  to { transform: none; filter: none; }
}
/* Shared chapter paintings carry their own night filters. Settling only their
   scale and opacity lets those filters remain continuously authoritative. */
@keyframes ow-paint-settle-shared {
  from { transform: scale(1.024); opacity: .52; }
  to { transform: none; opacity: 1; }
}
@keyframes ow-arrival-stamp {
  0% { opacity: 0; transform: translate(-50%,10px); filter: blur(3px); }
  17%,68% { opacity: 1; transform: translate(-50%,0); filter: none; }
  100% { opacity: 0; transform: translate(-50%,-7px); filter: blur(1px); }
}
@media (max-width: 760px) { .ow-arrival-stamp { top: 31%; } }
@media (prefers-reduced-motion: reduce) {
  .ow-entering .ow-bg, .ow-entering .lh-bg, .ow-entering .wr-bg { animation: none; }
  .ow-arrival-stamp {
    animation: none !important; opacity: 1; transform: translateX(-50%); filter: none;
  }
}

/* ------- ambient, shared by every chapter -------
   Chapter one gates its daytime layers on .ow-scene[data-time], which the later
   chapters do not have: they carry .night on the wrapper instead. One extra
   rule and the same markup works in all four. */
.night .ow-daily { opacity: 0; }

/* Birds. Two wings on a body, crossing the sky band and gone. Day only, and
   outdoors only — nothing flies through the Hall of Names. */
.ow-birds { position: absolute; inset: 0; z-index: 9; pointer-events: none; }
.ow-bird { position: absolute; animation: ow-birdfly linear infinite; }
.ow-bird svg {
  display: block; width: 22px; height: 9px; overflow: visible;
  transform: scale(var(--bird-scale, .8));
  animation: ow-birdflap ease-in-out infinite alternate;
  transform-origin: 50% 60%;
}
.ow-bird svg path {
  fill: none; stroke: rgba(58,52,74,.30); stroke-width: 1.15;
  stroke-linecap: round; stroke-linejoin: round;
}
.night .ow-bird svg path, .ow-scene[data-time="night"] .ow-bird svg path {
  stroke: rgba(28,26,44,.34);
}
/* wings that rise and fall together, by flattening the curve — not two bars
   scissoring about a hinge */
@keyframes ow-birdflap {
  from { transform: scale(var(--bird-scale, .8)) scaleY(1); }
  to   { transform: scale(var(--bird-scale, .8)) scaleY(.42); }
}
@media (prefers-reduced-motion: reduce) { .ow-birds { display: none; } }

/* =====================================================================
   PHONES (Opus spec, mobile-spec.md). Everything below is gated on a
   media query or a body.phone* class that only a narrow window sets, so a
   desktop renders pixel-identical. The duel is re-stacked for a portrait
   phone at zoom 1 rather than shrunk: its natural width is ~790px and no
   zoom renders that legibly at 390px.
   ===================================================================== */

/* the toast used to be inline styles; identical values, now a class */
.gtoast {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: 90;
  background: rgba(20,20,50,0.9); color: #fff6e0; padding: 8px 18px; border-radius: 999px;
  font-weight: 800; font-size: 14px; border: 1px solid rgba(255,214,107,0.5); pointer-events: none;
  max-width: 60vw; text-align: center;
}
/* a rule card: the first time you meet a rule, it stays until you have read it */
.rulecard {
  position: fixed; top: calc(112px + var(--sat)); left: 50%; transform: translateX(-50%);
  z-index: 85; width: min(440px, calc(100vw - 24px)); cursor: pointer;
  display: grid; grid-template-columns: 38px 1fr auto; gap: 0 12px; align-items: center;
  padding: 11px 12px 11px 14px; border-radius: 16px;
  background: rgba(22, 22, 58, 0.95); color: var(--cream);
  border: 1.5px solid rgba(255, 214, 107, 0.7);
  box-shadow: 0 14px 40px rgba(0,0,0,0.45), 0 0 0 1px rgba(255,255,255,0.05) inset;
  animation: rulecard-in 320ms cubic-bezier(.2,.8,.3,1) both;
}
.rulecard.leaving { animation: rulecard-out 260ms ease both; }
@keyframes rulecard-in { from { opacity: 0; transform: translate(-50%, -14px); } }
@keyframes rulecard-out { to { opacity: 0; transform: translate(-50%, -10px); } }
.rulecard .rc-icon { font-size: 26px; line-height: 1; text-align: center; }
.rulecard .rc-title {
  font-size: 11px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 2px;
}
.rulecard .rc-text { font-size: 13.5px; line-height: 1.45; }
.rulecard .rc-ok {
  padding: 9px 14px; font-size: 13px; border-radius: 10px; align-self: center;
  background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: #4a3000;
}
/* A tip pinned to the top of a phone covers the enemy's board, which is the
   one thing a lesson about the board wants you to look at. The middle of a
   portrait screen is empty until units are in play, so tips sit there
   instead: clear of both courts and clear of the hand. */
body.phone-portrait .rulecard { top: auto; bottom: calc(266px + var(--sab)); }
body.phone .rulecard .rc-ok { min-height: 40px; }
@media (prefers-reduced-motion: reduce) { .rulecard, .rulecard.leaving { animation: none; } }
#chrome-more, #ow-more { display: none; }
#ow-sheet[hidden] { display: none; }
#ow-vp { position: fixed; inset: 0; pointer-events: none; visibility: hidden; }

/* hover states stick after a tap on a touch screen */
@media (hover: none) {
  .card:hover, .scryrow .card:hover, .unit:hover, .constellation.affordable:hover { transform: none; }
  button:hover:not(:disabled) { transform: none; filter: none; }
  /* a tapped card keeps its grey: the hover reset must not un-grey it, or a
     tap reads as a highlight */
  .card.unplayable:hover { filter: grayscale(0.55) brightness(0.82); }
  .card.mullsel, .scryrow .card.mullsel:hover { transform: translateY(-8px); }
}

/* ---- the chrome cluster folds into one ⋯ (both orientations) ---- */
body.phone #chrome-more { display: grid; place-items: center; }
body.phone #chrome-btns {
  top: calc(8px + var(--sat)); right: calc(10px + var(--sar));
  max-width: none; flex-direction: column; align-items: flex-end; gap: 8px;
}
body.phone #chrome-btns > button {
  width: 44px; height: 44px; padding: 0; border-radius: 50%;
  font-size: 17px; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
}
body.phone:not(.chrome-open) #chrome-btns > button:not(#chrome-more) { display: none; }
body.phone:not(.chrome-open) #chrome-btns .lbl { display: none; }
body.phone.chrome-open #chrome-btns > button:not(#chrome-more) {
  width: auto; min-width: 176px; height: 44px; border-radius: 12px;
  padding: 0 16px; font-size: 14px; justify-content: flex-start; gap: 8px;
}
body.phone #zoom-toggle { display: none !important; }
/* music is a row of the sheet (ui.js moves #audio-ctrl into the column on a phone) */
body.phone #audio-ctrl { position: static; display: none; align-items: flex-end; gap: 6px; }
body.phone.chrome-open #audio-ctrl { display: flex; }
body.phone #music-toggle { width: 176px; height: 44px; padding: 0 16px; border-radius: 12px; font-size: 14px; text-align: left; }
body.phone #volume-slider { width: 176px; }
body.phone.campaign #chrome-btns { display: none; }
body.phone #ow-sheet #audio-ctrl { display: flex; }
body.phone-portrait #turn-pill { display: none !important; }
body.phone-landscape #turn-pill { right: calc(116px + var(--sar)); font-size: 12.5px; padding: 6px 14px; }
body.phone-portrait #end-turn.ai-turn { animation: phone-wait 1.6s ease-in-out infinite; }
@keyframes phone-wait { 50% { opacity: .55; } }
body.phone .smallbtn { min-height: 44px; }

/* ---- overlays become sheets ---- */
#net-code {
  width: 100%; box-sizing: border-box; max-width: 320px;
  font: inherit; font-size: 16px; padding: 10px 12px;
  border: 2px solid var(--gold); border-radius: 10px;
  background: rgba(255,255,255,.1); color: var(--cream); text-align: center;
}
#net-overlay {
  inset: 0 0 auto; height: 100dvh; box-sizing: border-box;
  padding: calc(8px + var(--sat)) 8px calc(8px + var(--sab));
}
#net-overlay .obox {
  width: 100%; max-height: calc(100dvh - 16px - var(--sat) - var(--sab)); min-height: 0;
  overflow-y: auto; overflow-wrap: anywhere;
}
#net-back { min-height: 44px; }
#net-overlay input { font-size: 16px !important; max-width: 100%; box-sizing: border-box; }
@media (max-width: 560px) {
  .overlay { place-items: end center; }
  .overlay .obox, .overlay .obox.wide, .overlay .homebox {
    max-width: none; width: calc(100vw - 16px);
    padding: 20px 16px calc(14px + var(--sab));
    margin-bottom: 0;
    max-height: calc(100dvh - 16px - var(--sat));
    border-radius: 20px 20px 14px 14px;
    -webkit-overflow-scrolling: touch;
  }
  .overlay .homebox { padding-top: 58px; }   /* clear of the two round buttons */
  .overlay h1 { font-size: 26px; }
  .overlay h2 { font-size: 21px; margin-bottom: 8px; }
  .overlay p { font-size: 15px; line-height: 1.5; margin-bottom: 14px; }
  .overlay .obtn { min-height: 46px; padding: 12px 22px; font-size: 15.5px; }
  /* the action row stays in reach while the body scrolls */
  .overlay .obox > .tut-nav,
  .overlay .obox > .overlay-actions {
    position: sticky; bottom: calc(-14px - var(--sab)); z-index: 2;
    margin: 10px -16px calc(-14px - var(--sab)); padding: 10px 16px calc(14px + var(--sab));
    width: calc(100% + 32px); box-sizing: border-box;
    background: linear-gradient(180deg, rgba(22,22,58,0), #16163a 32%);
    display: flex; gap: 10px; justify-content: center;
  }
  .overlay .obox > .obtn, .overlay-actions > .obtn { border-radius: 14px; }
  .smallbtn { min-height: 44px; padding: 10px 14px; }
  #redraw-btn { min-height: 40px; }
  .card .entrustbtn { width: 32px; height: 32px; line-height: 30px; font-size: 13px; }
  .card .entrustbtn::before { content: ''; position: absolute; inset: -6px; border-radius: 50%; }
  #log-sheet { max-height: 56dvh; overflow-y: auto; text-align: left; font-size: 13px; line-height: 1.5; }
  #log-sheet div { padding: 3px 0; border-bottom: 1px dotted rgba(255,255,255,0.1); }
  .gtoast { max-width: calc(100vw - 28px) !important; font-size: 13.5px; padding: 8px 14px; }

  /* tutorial: the card sits above its legend */
  .tut-body { min-height: 0; }
  .tut-row { flex-direction: column; gap: 14px; align-items: center; }
  .tut-card-demo { transform: none; margin: 4px auto 6px; }
  .tut-legend, .tut-legend[style] { max-width: none !important; width: 100%; font-size: 14.5px; line-height: 1.5; }
  .tut-legend li { margin-bottom: 12px; gap: 9px; }
  .tut-legend .bullet { width: 26px; height: 26px; font-size: 12px; }
  .tut-dots { margin: 12px 0 2px; }
  .tut-dots span { width: 10px; height: 10px; margin: 0 5px; }
  .tut-nav .obtn { flex: 1 1 0; max-width: 190px; }
  .tut-bignum { font-size: 34px; }

  /* piles: three stacked lists, each scrolling on its own */
  .pilecols { flex-direction: column; gap: 14px; }
  .pilecols ul { min-width: 0; font-size: 13px; }
  .pilecols > div { max-height: 34dvh; overflow-y: auto; }
  /* mulligan: swipe the five, same idiom as the hand */
  .scryrow {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x mandatory;
    margin: 10px -16px; padding: 6px 16px; justify-content: flex-start; scrollbar-width: none;
  }
  .scryrow::-webkit-scrollbar { display: none; }
  .scryrow .card { scroll-snap-align: center; flex-shrink: 0; }
  .scryrow .card.mullsel { transform: translateY(-8px); box-shadow: 0 0 0 3px var(--gold); }

  /* deckbuilder: the two lists stack, and a row shows the name, not the set code */
  .dbcols { flex-direction: column; gap: 12px; }
  .dblist { max-height: 30dvh; }
  .dbrow .set2badge { display: none; }
}

/* ---- the readable card on any touch screen (class-gated, so a desktop is untouched) ---- */
/* the readable card becomes a centred sheet over its own scrim */
#preview.pvsheet {
  left: 50%; top: 50%; right: auto; bottom: auto;
  transform: translate(-50%, -50%);
  pointer-events: auto; z-index: 95; animation: none;
}
/* the scrim is its own element: a pseudo-element inside the card painted over
   the card's own face, and a tap on it must dismiss without touching the board */
#pv-scrim {
  position: fixed; inset: 0; z-index: 94;
  background: rgba(10,10,30,.62); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
#preview.pvsheet.cardpv { width: min(300px, calc(100vw - 56px)); }
.pvfoot { display: flex; justify-content: center; padding: 2px 14px 14px; }
.pvfoot .obtn {
  width: 100%; min-height: 48px; padding: 12px 26px; font-size: 16px; border-radius: 14px;
  background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: #4a3000;
  box-shadow: 0 4px 10px rgba(0,0,0,0.25);
}
.fspv-body { padding: 18px 18px 6px; text-align: center; color: var(--cream); }
.fspv-body .fslabel { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; opacity: .8; }
.fspv-body .fsname { font-size: 20px; font-weight: 900; color: var(--gold); margin: 6px 0; }
.fspv-body .fscond, .fspv-body .fsnone { font-size: 15px; line-height: 1.5; }
.fspv-body .fsstate { margin-top: 8px; font-weight: 800; font-size: 13px; }
.fspv-body .fsfade { opacity: .6; font-size: 12px; margin-top: 4px; }
#preview.pvsheet.fspv { background: linear-gradient(180deg, #23234e, #16163a); border-color: var(--gold); }

/* ---- the portrait duel board ---- */
@media (max-width: 560px) and (orientation: portrait) {
  /* the budget on an iPhone 14 is 763px once the notch and home bar are
     taken: strip 64 · board 124 · rail 84 · board 124 · your bar 40 ·
     hand 198 · End Turn 48 · gaps ~25 = 707, and the rest is painted sky */
  body { --unit-w: 104px; --unit-h: 140px; --card-w: 132px; --card-h: 168px; }
  .card .art, .card .art svg, .card .art img { height: 68px; }
  .card .ctext { font-size: 10.5px; line-height: 1.25; }
  /* the units are what a duel is about: the badges and name go compact so
     the painting gets the tile — about 80px of it instead of a sliver */
  .unit .uname { font-size: 10.5px; line-height: 1.1; padding: 1px 3px 0; max-height: 24px; overflow: hidden; }
  .unit .stats { padding: 2px 5px 4px; }
  .unit .statb { min-width: 30px; height: 22px; padding: 0 6px; font-size: 12.5px; gap: 2px; }
  .unit .statb.atk { padding: 0 7px 0 5px; }
  .unit .statb.atk::before { font-size: 9px; }
  .unit .statb.hp::before { font-size: 10px; }
  .unit .art svg { max-height: none; }
  .unit .badge { transform: scale(.85); }
  #ai-strip {
    display: grid; grid-template-columns: auto auto 1fr;
    align-items: center; gap: 2px 6px;
    min-height: 0; padding: 3px 58px 3px calc(10px + var(--sal));  /* 58 = the ⋯ button */
  }
  #ai-info { grid-column: 1 / -1; }
  .playerinfo { flex-direction: row; align-items: center; gap: 6px; min-width: 0; }
  .playerinfo .pname { font-size: 12px; max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .chips { flex-wrap: nowrap; gap: 4px; }
  .chip { font-size: 11.5px; padding: 2px 7px; gap: 3px; white-space: nowrap; }
  .panel { padding: 4px 7px; border-radius: 10px; }
  .lanterns { font-size: 11px; letter-spacing: -2px; white-space: nowrap; }
  .wishslot { width: 24px; height: 32px; font-size: 12px; }
  #ai-hand { gap: 0; justify-self: end; }
  .cardback { width: 20px; height: 28px; border-width: 1.5px; border-radius: 4px; }
  .cardback + .cardback { margin-left: -11px; }
  .cardback::after { font-size: 10px; }

  #boards { justify-content: space-evenly; min-height: 0; }
  .board {
    flex: 0 0 auto; min-height: calc(var(--unit-h) + 12px);
    gap: 6px; padding: 9px 8px 3px; justify-content: safe center;
    overflow-x: auto; overflow-y: visible; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; scrollbar-width: none; touch-action: pan-x;
  }
  .board::-webkit-scrollbar { display: none; }
  .unit { scroll-snap-align: center; }
  .unit .uname { font-size: 11.5px; }
  .board:empty::after { font-size: 13px; white-space: normal; width: 80%; }
  .board:has(> .unit:nth-child(4)) { --unit-w: 88px; }
  .board:has(> .unit:nth-child(6)) { --unit-w: 74px; }
  .unit .badge.keepsake, .unit .badge.trailblaze { bottom: -4px; }

  #midbar { --rail-h: 46px; position: relative; flex-direction: column; gap: 3px; padding: 2px 8px; flex-shrink: 0; }
  #round-banner {
    order: 1; width: 100%; min-width: 0; display: flex; align-items: center;
    justify-content: center; gap: 8px; padding: 3px 10px; border-radius: 999px;
  }
  #round-banner .rname { font-size: 13px; }
  #round-banner .rsub { font-size: 10.5px; }
  #round-banner .rwins { font-size: 12px; margin-top: 0; }
  #midbar > #constellations { order: 2; gap: 6px !important; padding-right: 40px; }
  #falling-star {
    order: 3; position: absolute; right: 8px; bottom: 2px;
    width: 34px; height: var(--rail-h); font-size: 9px; gap: 1px; padding: 4px 2px; min-width: 0;
    overflow: hidden;
  }
  /* the falling star is a glyph on the rail; its story opens on tap */
  #falling-star .fslabel, #falling-star .fsname, #falling-star .fscond, #falling-star .fsstate,
  #falling-star .fsfade, #falling-star .fsnone { display: none; }
  #falling-star::before { content: '🌠'; font-size: 20px; line-height: 1; display: block; margin-top: 12px; }
  #falling-star.fs-ready::after { content: '✓'; font-size: 11px; font-weight: 900; color: #9ff2a8; display: block; }
  .constellation {
    width: 104px; height: var(--rail-h);
    display: grid; grid-template-columns: 36px 1fr; grid-template-rows: auto auto;
    align-items: center; gap: 0 6px; padding: 5px 6px; text-align: left;
  }
  .constellation .cart { grid-row: 1 / 3; width: 32px; height: 32px; border-radius: 50%; }
  .constellation .cart svg, .constellation .cart img { width: 32px; height: 32px; }
  .constellation .cname { font-size: 10.5px; line-height: 1.1; margin: 0; align-self: end; }
  .constellation .ccost { font-size: 12px; align-self: start; }
  .constellation .ctext2 { display: none; }
  .constellation .cemoji { font-size: 22px; }

  #player-strip {
    display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto auto;
    height: auto; gap: 4px; padding: 0 8px calc(6px + var(--sab));
  }
  /* your bar: chips · lanterns · wish · redraw on one line; the name is yours, it goes */
  #player-strip > div:first-child { flex-direction: row !important; align-items: center; gap: 6px; flex-wrap: nowrap; min-width: 0; }
  #player-strip > div:first-child > div:last-child { gap: 5px; flex-shrink: 0; }
  #player-info { min-width: 0; flex-shrink: 1; }
  #player-info .pname { display: none; }
  #player-face { flex-shrink: 0; }
  #hand {
    order: 2; display: flex; gap: 8px; align-items: flex-end; justify-content: flex-start;
    height: calc(var(--card-h) + 8px);
    overflow-x: auto; overflow-y: visible; perspective: none;
    scroll-snap-type: x mandatory; scroll-padding: 0 12px;
    padding: 4px 12px 2px; margin: 0 -8px; touch-action: pan-x;
    overscroll-behavior-x: contain; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
  }
  #hand::-webkit-scrollbar { display: none; }
  #hand .card { margin-right: 0; scroll-snap-align: center; flex-shrink: 0; }
  #hand .card:hover { transform: none; }
  #end-turn { order: 3; width: 100%; min-height: 46px; padding: 9px 22px; font-size: 16px; border-radius: 16px; }
  #redraw-btn { width: 40px; height: 36px; padding: 0; font-size: 0; }
  #redraw-btn::after { content: '🌟'; font-size: 18px; }

  #target-banner {
    bottom: calc(300px + var(--sab)); flex-wrap: wrap; row-gap: 6px;
    max-width: calc(100vw - 20px); font-size: 13.5px; padding: 9px 14px;
  }
  #target-banner .smallbtn { min-height: 40px; }
}
/* the narrowest phones: your bar must still fit chips, lanterns, wish and redraw */
@media (max-width: 380px) and (orientation: portrait) {
  .chip { font-size: 11px; padding: 2px 5px; }
  .lanterns { font-size: 10px; letter-spacing: -2.5px; }
  #player-strip > div:first-child { gap: 4px; }
}
/* a tall phone can afford the cards at their designed size */
@media (max-width: 560px) and (orientation: portrait) and (min-height: 900px) {
  body { --unit-w: 112px; --unit-h: 150px; --card-w: 150px; --card-h: 200px; }
  .card .art, .card .art svg, .card .art img { height: 90px; }
}
/* a short one gives up a little of everything */
@media (max-width: 560px) and (orientation: portrait) and (max-height: 700px) {
  body { --unit-w: 88px; --unit-h: 104px; --card-w: 120px; --card-h: 150px; }
  .card .art, .card .art svg, .card .art img { height: 58px; }
  .card .ctext { font-size: 10px; }
  #midbar { --rail-h: 42px; }
  #hand { height: calc(var(--card-h) + 6px); }
}

/* ---- phone landscape: only lower the natural height so the zoom can rise ---- */
@media (orientation: landscape) and (max-height: 500px) {
  body { --card-h: 196px; --unit-h: 132px; --unit-w: 116px; }
  .card .art, .card .art svg { height: 88px; }
  #ai-strip { min-height: 60px; padding: 4px 12px; }
  #player-strip { height: 208px; padding: 2px 12px 6px; }
  #midbar { padding: 4px 10px; gap: 12px; }
  .constellation { width: 132px; }
  .constellation .cart, .constellation .cart svg { height: 62px; }
  .constellation .ctext2 { font-size: 10px; }
  #falling-star { width: 132px; }
  .board { min-height: var(--unit-h); padding: 2px 10px; }
}

/* ---- the campaign on a portrait phone ---- */
@media (max-width: 560px) and (orientation: portrait) {
  /* the camera paints between the HUD and the hint bar */
  #ow-vp { top: calc(88px + var(--sat)); bottom: calc(96px + var(--sab)); }
  /* the void above and below the band, painted in the root's own colour;
     a clip on the root would take the HUD and hint bar with it */
  #overworld::before, #overworld::after, #lantern-hollow::before, #lantern-hollow::after,
  #wild-route::before, #wild-route::after, #cloudbreak::before, #cloudbreak::after {
    content: ''; position: absolute; left: 0; right: 0; z-index: 61; pointer-events: none;
    background: inherit;
  }
  #overworld::before, #lantern-hollow::before, #wild-route::before, #cloudbreak::before {
    top: 0; height: calc(88px + var(--sat));
  }
  #overworld::after, #lantern-hollow::after, #wild-route::after, #cloudbreak::after {
    bottom: 0; height: calc(96px + var(--sab));
  }
  .ow-hud { height: calc(88px + var(--sat)); }
  .ow-hud::after { top: 84px; }
  .ow-hud-in {
    display: grid; grid-template-columns: 1fr auto; grid-template-rows: minmax(40px, auto) 40px;
    min-height: 80px; height: auto; padding: 0 60px 0 calc(14px + var(--sal)) !important;  /* 60 = the ⋯ button */
    align-items: center; column-gap: 8px;
  }
  #overworld .ow-hud-in, #lantern-hollow .ow-hud-in, #cloudbreak .ow-hud-in, #wild-route .ow-hud-in { align-items: center; }
  .ow-place { grid-area: 1 / 1 / 2 / 3; min-width: 0; }
  #overworld .ow-place, #lantern-hollow .ow-place, #cloudbreak .ow-place, #wild-route .ow-place { padding-right: 0; }
  .ow-place-name { font-size: 16px; white-space: normal; overflow-wrap: anywhere; display: block; }
  .ow-hud-right { grid-area: 2 / 1 / 3 / 3; gap: 10px !important; justify-content: flex-start; }
  .ow-place-sub, .ow-dust span { display: none; }
  .ow-hud .ow-gbtn { display: none; }
  .ow-goal {
    position: fixed; top: calc(92px + var(--sat)); left: calc(12px + var(--sal));
    max-width: calc(100vw - 28px); font-size: 11.5px; padding: 6px 11px 6px 9px;
  }
  .wr-ribbon { display: none; }
  body.campaign #ow-more {
    display: grid; place-items: center; position: fixed;
    top: calc(8px + var(--sat)); right: calc(10px + var(--sar));
    width: 44px; height: 44px; padding: 0; border-radius: 50%; font-size: 18px; z-index: 66;
  }
  #ow-sheet {
    position: fixed; top: calc(58px + var(--sat)); right: calc(10px + var(--sar));
    z-index: 66; display: flex; flex-direction: column; gap: 6px;
    padding: 8px; min-width: 176px;
    background: rgba(26,20,48,.94); border: 1px solid rgba(255,214,107,.32);
    border-radius: 14px; box-shadow: 0 18px 40px -14px rgba(10,8,28,.9);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  }
  #ow-sheet .ow-gbtn { display: block; width: 100%; min-height: 44px; text-align: left; font-size: 13.5px; }
  .ow-hint {
    bottom: calc(24px + var(--sab)); font-size: 12.5px; letter-spacing: .04em;
    text-transform: none; max-width: calc(100vw - 40px); line-height: 1.45;
    color: rgba(255,243,220,.95); background: rgba(26,20,48,.6); padding: 9px 16px;
    border-radius: 14px; border: 1px solid rgba(255,214,107,.22); text-shadow: none;
  }
}

/* ---------------------------------------------------------------- the 3D world
   The painted scene stays in the DOM (the walk loop, the tokens and every
   overlay still hang off it) but is not shown; the canvas takes its place
   under the HUD, and the name plates are DOM so they stay crisp. */
#overworld.ow-3d { background: #0f1430; }
/* Portrait painting fillers must not cover the full-screen 3D scene. */
:is(#overworld, #lantern-hollow, #wild-route, #cloudbreak).ow-3d::before,
:is(#overworld, #lantern-hollow, #wild-route, #cloudbreak).ow-3d::after { display: none; }
/* opacity rather than visibility: the browser tests wait for tokens in this
   scene to be "visible", and a transparent scene still counts */
#overworld.ow-3d .ow-scene { opacity: 0; pointer-events: none; }
#ow-3d {
  position: absolute; inset: 0; z-index: 1; overflow: hidden;
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: pointer;
}
#ow-3d canvas { display: block; width: 100%; height: 100%; }
/* through a door: the screen dips to a warm dark while the next world builds (World3D.dip) */
.w3-dip {
  position: fixed; inset: 0; z-index: 9000; pointer-events: none; opacity: 0;
  background: radial-gradient(ellipse at center, #2a1d14 0%, #120c09 75%);
  transition: opacity .34s ease-out;
}
.w3-dip.on { opacity: 1; pointer-events: auto; transition: opacity .16s ease-in; }
@media (prefers-reduced-motion: reduce) { .w3-dip, .w3-dip.on { transition: none; } }
.w3-dip p {
  position: absolute; left: 0; right: 0; top: 50%; margin: 0; text-align: center;
  color: #ead9b6; opacity: .72; font: italic 19px/1.3 Georgia, 'Times New Roman', serif; letter-spacing: .04em;
}
#ow-3d .w3-grade {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0) 52%, rgba(24,16,44,.46) 100%);
  mix-blend-mode: multiply;
}
#ow-3d .w3-warm {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,214,150,.12), rgba(255,240,220,0) 42%, rgba(110,80,170,.12));
  mix-blend-mode: soft-light;
}
#ow-3d .w3-plates { position: absolute; inset: 0; pointer-events: none; }
/* a word as you pass (js/townlife.js greeting), floated over the name plate */
.w3-bubble {
  position: absolute; left: 50%; bottom: calc(100% + 7px); transform: translate(-50%, 5px);
  padding: 5px 11px; border-radius: 12px; white-space: nowrap; pointer-events: none;
  font: italic 500 13px/1.2 Georgia, 'Times New Roman', serif; color: #3b2d1f;
  background: rgba(255, 246, 226, .94); box-shadow: 0 3px 10px rgba(20, 12, 30, .28);
  opacity: 0; transition: opacity 260ms ease, transform 260ms ease;
}
.w3-bubble::after {
  content: ''; position: absolute; left: 50%; top: 100%; margin-left: -6px;
  border: 6px solid transparent; border-top-color: rgba(255, 246, 226, .94);
}
.w3-bubble.on { opacity: 1; transform: translate(-50%, 0); }
/* the door, or the person, the objective sends you to (js/world3d/world.js) */
.w3-plate.goal { box-shadow: 0 0 0 1.5px rgba(255, 214, 130, .85), 0 0 14px rgba(255, 200, 110, .45); }
.w3-plate.goal > span:not(.w3-bubble)::before { content: '\2726\00a0'; color: #ffd98a; }
.w3-plate.goal.edge > span:not(.w3-bubble)::after { color: #ffd98a; margin-left: 6px; }
.w3-plate.goal.edge[data-edge=behind] > span:not(.w3-bubble)::after { content: '\2193'; }
.w3-plate.goal.edge[data-edge=left] > span:not(.w3-bubble)::after { content: '\2190'; }
.w3-plate.goal.edge[data-edge=right] > span:not(.w3-bubble)::after { content: '\2192'; }
@media (prefers-reduced-motion: reduce) { .w3-bubble { transition: none; } }
.w3-plate {
  position: absolute; transform: translate(-50%, -100%); pointer-events: none;
  display: flex; align-items: center; gap: 6px; padding: 3px 10px 3px 4px;
  border-radius: 999px; white-space: nowrap;
  font: 700 12px/1.2 var(--ow-font-ui); letter-spacing: .02em; color: var(--ow-rim);
  background: rgba(34,26,62,.72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,243,220,.20);
  opacity: 0; transition: opacity 240ms ease, box-shadow 160ms ease;
}
.w3-plate img { width: 22px; height: 22px; border-radius: 50%; box-shadow: 0 0 0 1.5px #c9903f; }
.w3-plate.on { opacity: 1; }
.w3-plate.near { box-shadow: 0 0 0 2px #fff3dc, 0 0 14px rgba(255,214,107,.55); }
.w3-plate-me { opacity: 0 !important; }
.w3-badge { display: none; width: 10px; height: 10px; border-radius: 50%; margin-left: 2px; }
.w3-badge.duel { display: block; background: radial-gradient(circle at 35% 30%, #fff6c8, #e0a030); box-shadow: 0 0 7px #ffd66b; animation: ow-badgepulse 2.1s ease-in-out infinite; }
.w3-badge.beaten { display: block; background: radial-gradient(circle at 35% 30%, #ffffff, #c9c2d8); opacity: .85; }
/* any chapter's painted scene, while its 3D view is mounted */
.w3-hidden { opacity: 0 !important; pointer-events: none !important; }
/* plates you can tap: people, fixtures, and every doorway */
.w3-plate-npc, .w3-plate-fixture, .w3-plate-exit, .w3-plate-act { pointer-events: auto; cursor: pointer; }
/* something small to do here: stroke the cat, feed the ducks (js/world3d/world.js offerAct) */
.w3-plate-act { background: rgba(58, 42, 24, .82); border: 1px solid rgba(255, 214, 130, .55); color: #fff3d6; padding: 4px 12px 4px 8px; }
.w3-plate-act span::before { content: '\270B\00a0'; }
@media (hover: hover) and (pointer: fine) { .w3-plate-act:not(.nokey) span::before { content: 'E\00a0\00b7\00a0'; color: #ffd98a; } }
.w3-plate-exit {
  background: rgba(62,45,73,.92); border-color: rgba(201,144,63,.7); color: #fff3dc;
  padding: 4px 11px 4px 8px; letter-spacing: .06em; text-transform: uppercase; font-size: 10px;
}
.w3-plate-exit .w3-door {
  width: 10px; height: 12px; border-radius: 5px 5px 1px 1px; background: #c9903f;
  box-shadow: inset 0 0 0 1.5px rgba(62,45,73,.9), 0 0 6px rgba(255,214,107,.35);
}
.w3-plate-exit.near { box-shadow: 0 0 0 2px #fff3dc, 0 0 16px rgba(255,214,107,.6); background: rgba(90,62,100,.96); }
.w3-plate-exit.shut { opacity: .72; }
.w3-plate-exit.shut .w3-door { background: #8a8090; box-shadow: none; }
/* seen! the plate of whoever has spotted you carries the exclamation */
.w3-plate.spot { opacity: 1; box-shadow: 0 0 0 2px #fff3dc, 0 0 18px rgba(255,214,107,.7); }
.w3-plate.spot::before {
  content: '!'; position: absolute; left: 50%; top: -34px; transform: translateX(-50%);
  width: 26px; height: 26px; border-radius: 50%; background: #ffd66b; color: #3a2f27;
  font: 900 20px/26px var(--ow-font-ui); text-align: center;
  box-shadow: 0 2px 8px rgba(20,14,40,.35); animation: w3-spot 480ms cubic-bezier(.2,1.6,.4,1) both;
}
@keyframes w3-spot { from { transform: translateX(-50%) translateY(10px) scale(.4); opacity: 0; } to { transform: translateX(-50%) scale(1); opacity: 1; } }
/* the painted tokens get the same mark */
.ow-tok.spot .ow-tok-disc::after {
  content: '!'; position: absolute; left: 50%; top: -30px; transform: translateX(-50%);
  width: 24px; height: 24px; border-radius: 50%; background: #ffd66b; color: #3a2f27;
  font: 900 18px/24px var(--ow-font-ui); text-align: center;
}

/* ---- the first campaign duel's primer: the overworld's parchment dialogue,
   spoken by the opponent, over a lighter scrim so the board shows through */
.overlay.duel-primer-ov { background: rgba(20,16,44,.46); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  overflow-y: auto; padding: 44px 16px 16px; box-sizing: border-box; }
.duel-primer {
  position: relative; box-sizing: border-box; width: min(560px, 100%); padding: 26px 26px 16px;
  background-image: linear-gradient(180deg, rgba(255,248,232,.93), rgba(252,240,218,.97)), url('../art/img/ow_paper.webp');
  background-size: cover; background-position: center; color: var(--ow-ink); text-align: left;
  border: 1px solid var(--ow-paper-edge); border-radius: 20px;
  box-shadow: 0 20px 54px -14px rgba(14,10,34,.66), inset 0 2px 0 rgba(255,255,255,.72);
  animation: duel-primer-in 420ms var(--ow-ease-soft) both;
}
@keyframes duel-primer-in { from { opacity: 0; transform: translateY(18px) scale(.985); } to { opacity: 1; transform: none; } }
.duel-primer-face { position: absolute; left: 24px; top: -30px; width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 0 3px var(--ow-rim), 0 0 0 5px var(--ow-brass), 0 6px 14px -4px rgba(18,12,40,.5); }
.duel-primer-name { margin-left: 76px; font: 400 17px/1.1 var(--ow-font-story); font-variant: small-caps;
  letter-spacing: .06em; color: var(--ow-ink-name); }
.duel-primer-name::after { content: ''; display: block; margin-top: 10px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--ow-brass), rgba(201,144,63,.15)); }
.duel-primer.no-face .duel-primer-name { margin-left: 0; }
.duel-primer-text { margin: 14px 0 16px; }
.overlay .duel-primer-text p { margin: 0 0 10px; opacity: 1; font: 400 16.5px/1.62 var(--ow-font-story); color: var(--ow-ink); }
.overlay .duel-primer-text p:last-child { margin-bottom: 0; }
.duel-primer-text b { font-weight: 700; color: var(--ow-ink-name); }
.duel-primer-text em { font-style: italic; color: var(--ow-ink-soft); }
.duel-primer-lanterns { display: grid; gap: 4px; justify-content: start; margin: 4px 0 12px; padding: 8px 12px;
  background: rgba(201,144,63,.08); border: 1px solid rgba(201,144,63,.28); border-radius: 12px; }
.duel-primer-lanterns div { display: flex; align-items: center; gap: 10px; }
.duel-primer-lanterns span { width: 44px; font: 700 9.5px/1 var(--ow-font-ui); text-transform: uppercase;
  letter-spacing: .14em; color: var(--ow-ink-soft); }
.duel-primer-lanterns i { font-style: normal; font-size: 14px; letter-spacing: 2px; line-height: 1.2; white-space: nowrap; }
.duel-primer-foot { display: flex; justify-content: flex-end; align-items: center; gap: 10px; }
.duel-primer-more { font: 700 13px/1 var(--ow-font-ui); color: var(--ow-ink-soft); background: transparent;
  border: 1px solid #cbb083; border-radius: 11px; padding: 9px 18px; cursor: pointer; transition: background 140ms, color 140ms; }
.duel-primer-more:hover { background: rgba(201,144,63,.14); color: var(--ow-ink); }
.duel-primer-go { font: 800 13px/1 var(--ow-font-ui); letter-spacing: .02em; color: #4a3200;
  background: linear-gradient(180deg, #ffd66b, #f0a830); border: none; border-radius: 11px; padding: 10px 20px; cursor: pointer;
  box-shadow: 0 4px 0 #cf8b1f, 0 8px 18px -6px rgba(120,70,10,.5); transition: transform 100ms, box-shadow 100ms; }
.duel-primer-go:active { transform: translateY(3px); box-shadow: 0 1px 0 #cf8b1f; }
.duel-primer-more:focus-visible, .duel-primer-go:focus-visible { outline: 2px solid var(--ow-brass); outline-offset: 3px; }
@media (max-width: 480px) {
  .duel-primer { padding: 22px 18px 14px; }
  .duel-primer-face { left: 18px; top: -26px; width: 56px; height: 56px; }
  .duel-primer-name { margin-left: 66px; font-size: 16px; }
  .overlay .duel-primer-text p { font-size: 15.5px; line-height: 1.55; }
  .duel-primer-lanterns i { font-size: 13px; letter-spacing: 1px; }
}
@media (prefers-reduced-motion: reduce) { .duel-primer { animation: none; } }
/* between-rounds card in a campaign duel: the primer's parchment, plus the
   score line and the "what just happened" recap re-inked for paper */
.overlay .duel-round .duel-round-score { font: 600 13px/1.4 var(--ow-font-ui); letter-spacing: .02em; color: var(--ow-ink-soft); margin-top: 6px; }
.duel-round details { margin: 0 0 14px !important; }
.duel-round details summary { color: var(--ow-ink-soft) !important; font: 700 12px/1.3 var(--ow-font-ui) !important; }
.duel-round details > div { background: rgba(201,144,63,.08) !important; border: 1px solid rgba(201,144,63,.28); color: var(--ow-ink); }

/* ---- campaign match end: the primer's parchment for the biggest beat */
.overlay.duel-match-ov { background: rgba(20,16,44,.6); place-items: start center; }
.duel-match { margin-block: auto; }
.duel-match .duel-result, .duel-match .lh-duel-result { margin: 14px 0 0 !important; text-align: left; }
.duel-match .duel-result-speaker, .duel-match .lh-result-speaker { display: block !important; }
.duel-match .duel-result-speaker img, .duel-match .lh-result-speaker img { display: none; }
.overlay .duel-match .duel-result-speaker p, .overlay .duel-match .lh-result-speaker p {
  margin: 0; max-width: none !important; opacity: 1; text-align: left !important;
  font: 400 17.5px/1.6 var(--ow-font-story) !important; font-style: normal !important; color: var(--ow-ink); }
.overlay .duel-match .duel-match-score { margin: 12px 0 0; opacity: 1; text-align: left;
  font: 600 13.5px/1.4 var(--ow-font-ui); color: var(--ow-ink-soft); }
.duel-match-score b { font: 400 17px/1.2 var(--ow-font-story); font-variant: small-caps;
  letter-spacing: .05em; color: var(--ow-ink-name); }
.duel-match .duel-result-bonus, .duel-match .lh-seal-earned,
.duel-match .lh-loss-light, .duel-match .wr-bearing-earned {
  display: inline-block; margin: 10px 6px 0 0 !important; padding: 4px 11px; border-radius: 999px;
  background: rgba(201,144,63,.12); border: 1px solid rgba(201,144,63,.34);
  font: 700 12.5px/1.3 var(--ow-font-ui) !important; color: #7a4d12 !important; }
.duel-match .pk-offer { margin: 16px 0 4px; padding: 14px 12px 16px; border-radius: 14px;
  background: rgba(201,144,63,.08); border: 1px solid rgba(201,144,63,.28); }
.overlay .duel-match .pk-line { color: var(--ow-ink-name); font-size: 15.5px; text-align: center; }
.duel-match .pk-setline { margin: 0; color: color-mix(in srgb, var(--pk-set, #c9903f) 40%, #3b2f24); }
.duel-match .pk-packet { filter: drop-shadow(0 8px 14px rgba(90,60,20,.3)); }
.duel-match .pk-cta { color: #7a4d12; border-color: rgba(201,144,63,.6); background: rgba(255,248,234,.7); }
.duel-match .pk-trigger:hover .pk-cta, .duel-match .pk-trigger:focus-visible .pk-cta {
  background: linear-gradient(180deg, #ffd66b, #f0a830); color: #4a3200; border-color: #cf8b1f; }
.duel-match .pk-trigger:focus-visible { outline-color: var(--ow-brass); }
.duel-match .pk-static .pk-row { flex-wrap: wrap; justify-content: center; gap: 12px 10px; }
.duel-match .pk-foot { color: var(--ow-ink-name); }
/* the one exit; no !important on display, so the inline display:none still
   hides it until the pack is opened */
.duel-match #camp-return { display: block; margin: 16px 0 0 auto; min-height: 0; padding: 12px 22px;
  font: 800 14px/1 var(--ow-font-ui); letter-spacing: .02em; color: #4a3200; border: none; border-radius: 11px;
  background: linear-gradient(180deg, #ffd66b, #f0a830);
  box-shadow: 0 4px 0 #cf8b1f, 0 8px 18px -6px rgba(120,70,10,.5); }
.duel-match #camp-return:active { transform: translateY(3px); box-shadow: 0 1px 0 #cf8b1f; }
.duel-match #camp-return:focus-visible { outline: 2px solid var(--ow-brass); outline-offset: 3px; }
.duel-match-stats { margin: 16px 0 0; padding-top: 10px; border-top: 1px solid rgba(201,144,63,.3); }
.duel-match-stats summary { cursor: pointer; font: 700 12px/1.3 var(--ow-font-ui); color: var(--ow-ink-soft); }
.duel-match-stats > div { margin-top: 8px; padding: 8px 12px; max-height: 220px; overflow-y: auto;
  background: rgba(201,144,63,.08); border: 1px solid rgba(201,144,63,.28); border-radius: 10px;
  font: 400 12.5px/1.55 var(--ow-font-ui); color: var(--ow-ink); }
.duel-match-stats table { margin: 0 0 10px !important; }
@media (max-width: 480px) {
  .overlay .duel-match .duel-result-speaker p, .overlay .duel-match .lh-result-speaker p { font-size: 16px !important; }
  .duel-match #camp-return { width: 100%; margin-left: 0; padding: 14px 22px; }
}
/* The music toggle is the app's own control, but while a painted or 3D world
   is on screen it stands beside Journal/Deck/Satchel/Leave — so it wears the
   HUD's cream outline there instead of the menu's purple pill. */
body:has(#overworld) #music-toggle,
body:has(#lantern-hollow) #music-toggle,
body:has(#wild-route) #music-toggle,
body:has(#cloudbreak) #music-toggle {
  font: 700 12px/1 var(--ow-font-ui); letter-spacing: .03em; color: #f4e6c8;
  background: rgba(34,26,62,.55); border: 1px solid rgba(255,243,220,.18);
  border-radius: 10px; padding: 9px 15px; width: auto;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background 140ms, border-color 140ms, color 140ms;
}
body:has(#overworld) #music-toggle:hover,
body:has(#lantern-hollow) #music-toggle:hover,
body:has(#wild-route) #music-toggle:hover,
body:has(#cloudbreak) #music-toggle:hover {
  background: rgba(255,214,107,.16); border-color: rgba(255,214,107,.5); color: #fff6e0;
}

/* ======================================================================
   Duel & deck clarity (2026-09-28): what a duel starts with, why a click
   did nothing, which deck each way of playing deals you, and a deck
   editor that works on a 320px phone.
   ====================================================================== */

/* ---- deck editor: the name, whether it can duel, and its exits ---- */
.dbhead { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 10px; }
.dbstate {
  font-size: 11.5px; font-weight: 800; letter-spacing: .02em; white-space: nowrap;
  padding: 4px 11px; border-radius: 999px;
}
.dbstate.ok { color: #c4f5bb; background: rgba(122,232,122,.13); border: 1px solid rgba(122,232,122,.45); }
.dbstate.draft { color: #ffd3bf; background: rgba(255,150,110,.11); border: 1px dashed rgba(255,170,130,.6); }
.dbactions { align-items: center; flex-wrap: wrap; }
.dbtally {
  font-weight: 900; font-size: 14px; padding: 6px 12px; border-radius: 10px;
  background: rgba(0,0,0,.28); color: var(--gold); letter-spacing: .02em;
}
.dbtally.short { color: #ffb8a8; }
/* a draft is a real save, just not the gold one */
.smallbtn.dbdraft {
  background: rgba(255,246,224,.06); color: var(--cream);
  border: 1.5px dashed rgba(255,214,107,.55);
}
.smallbtn.dbdraft:hover:not(:disabled) { background: rgba(255,214,107,.14); }

/* ---- deck list: incomplete decks say so ---- */
.deckrow-name { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 3px 8px; text-align: left; }
.deckrow .deckrow-name b { flex: 0 1 auto; overflow-wrap: anywhere; }
.deckbadge {
  font-size: 10px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.deckbadge.draft { color: #ffd3bf; background: rgba(255,150,110,.13); border: 1px dashed rgba(255,170,130,.65); }
.deckbadge.ready { color: #c4f5bb; background: rgba(122,232,122,.1); border: 1px solid rgba(122,232,122,.4); }
.deckwhy { flex-basis: 100%; font-size: 11.5px; color: #ffbfae; opacity: .9; }
.overlay .deck-where {
  font-size: 12.5px; line-height: 1.5; margin: -4px auto 14px; max-width: 520px;
  padding: 8px 12px; border-radius: 10px; background: rgba(255,214,107,.07);
  border: 1px solid rgba(255,214,107,.2); color: #f3e6c4;
}
.overlay .deck-held { font-size: 12px; line-height: 1.45; color: #ffcdb9; margin: 8px 0 0; }

/* ---- the title screen: which deck each way of playing deals you ---- */
.modetile .td { font-size: 10.5px; font-weight: 700; line-height: 1.3; color: #d6b56c; margin-top: 1px; }
.journey-lobby .modetile .td { color: #8c6a2c; }
.journey-location.journey-deck { margin-top: 4px; font-style: italic; opacity: .85; }
.journey-legacy .deckline { font-style: italic; color: #8c6a2c; font-size: 12px; }
.overlay .journey-lobby .deck-held { color: #8a4b2a; font: 12.5px/1.45 system-ui, sans-serif; margin-top: 10px; }

/* ---- Court Trials: the deck you are dealt and the rule each one bends ---- */
.trialfacts { display: flex; flex-wrap: wrap; gap: 4px 6px; margin-top: 6px; }
.tf {
  display: inline-block; font-size: 11px; font-weight: 600; line-height: 1.3;
  padding: 2px 9px; border-radius: 999px; background: rgba(0,0,0,.24);
  border: 1px solid rgba(255,214,107,.22); color: var(--cream);
}
.tf b { font-weight: 800; }
.tf.deck { color: var(--gold); font-weight: 800; }
.tf.fair { opacity: .75; }
.tf.onboard { background: rgba(255,122,122,.12); border-color: rgba(255,140,140,.5); }
.tf .bb-art { width: 18px; height: 18px; margin: -2px 2px 0 -3px; }
.bb-art { display: inline-block; flex: 0 0 auto; border-radius: 6px; overflow: hidden; vertical-align: middle; background: rgba(0,0,0,.25); }
.bb-art img, .bb-art svg { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---- the opening hand: "Before you begin" ---- */
.setup-strip {
  margin: 0 auto 12px; max-width: 660px; text-align: left;
  padding: 9px 14px 11px; border-radius: 14px;
  background: linear-gradient(180deg, rgba(255,246,224,.1), rgba(255,246,224,.04));
  border: 1px solid rgba(255,214,107,.38);
}
.setup-title {
  font-size: 10.5px; font-weight: 900; letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold); text-align: center; margin-bottom: 6px;
}
.setup-strip ul { list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 5px 16px; }
.setup-strip li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; line-height: 1.35; color: var(--cream); }
.setup-strip li b { color: #fff; }
.setup-strip .si { flex: 0 0 20px; text-align: center; font-size: 14px; }
.setup-strip li.onboard {
  grid-column: 1 / -1; padding: 5px 9px; border-radius: 10px;
  background: rgba(255,122,122,.13); border: 1px solid rgba(255,140,140,.5);
}
.setup-strip li.onboard .si { flex-basis: 38px; }
.setup-strip li.onboard .bb-art { width: 38px; height: 38px; border-radius: 8px; }

/* ---- a unit that can't attack says why, in a word ---- */
.unit .ustate {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%); z-index: 3;
  font-size: 9.5px; font-weight: 900; letter-spacing: .07em; text-transform: uppercase; line-height: 1.5;
  padding: 0 7px; border-radius: 999px; white-space: nowrap; pointer-events: none;
  border: 1.5px solid #fff6e0; box-shadow: 0 1px 3px rgba(0,0,0,.35);
}
.unit .ustate.spent { background: #7a6a4c; color: #fff3d6; }
.unit .ustate.fog { background: #74808c; color: #f3f7fb; }
.unit .ustate.settling { background: #56813f; color: #f0fbe5; }
.unit .ustate.asleep { background: #55519a; color: #ecebff; }
.unit.spent { filter: saturate(.72) brightness(.95); }

/* ---- constellation tiles: traced, or how far off ---- */
.constellation .cneed { font-size: 10.5px; font-weight: 800; color: #ffcfb8; margin-left: 3px; white-space: nowrap; }
.constellation .cdone { font-size: 12.5px; font-weight: 900; color: #c4f5bb; }
.constellation.spent { opacity: .62; }
.pvfoot { flex-wrap: wrap; }
.pvfoot .pvnote {
  flex-basis: 100%; margin: 0 0 10px; padding: 9px 12px; border-radius: 12px; text-align: center;
  font-size: 14px; line-height: 1.45; color: var(--cream);
  background: rgba(255,214,107,.1); border: 1px solid rgba(255,214,107,.35);
}

/* ---- aiming: what is legal, and how far along ---- */
#target-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; line-height: 1.3; }
#target-text .tb-step { font-size: 9.5px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase; color: var(--gold); }
#target-text .tb-main { font-weight: 700; }
#target-text .tb-main b { font-weight: 900; }
/* width: max-content, or the banner (left: 50%) shrink-wraps to half the
   screen and the sentence stacks a word to a line */
#target-banner { border-radius: 18px; width: max-content; max-width: min(820px, calc(100vw - 20px)); }
/* a wide screen reads it as one line: the step, then the sentence */
@media (min-width: 561px) {
  #target-text { flex-direction: row; align-items: baseline; gap: 10px; }
}
#target-banner .smallbtn { flex: 0 0 auto; }

/* ---- between rounds: the ledger, and why the round went as it did ---- */
.round-ledger {
  list-style: none; text-align: left; margin: 2px auto 14px; max-width: 470px;
  display: grid; gap: 6px; padding: 10px 14px; border-radius: 12px;
  background: rgba(0,0,0,.22); border: 1px solid rgba(255,214,107,.22);
  font-size: 13px; line-height: 1.4;
}
.round-ledger li { display: flex; gap: 10px; align-items: flex-start; }
.round-ledger .li { flex: 0 0 20px; text-align: center; }
.cause-line {
  max-width: 470px; margin: 0 auto 12px; padding: 8px 12px; text-align: left;
  font-size: 13.5px; line-height: 1.45; border-radius: 0 10px 10px 0;
  border-left: 3px solid #ff9f8f; background: rgba(255,122,122,.09);
}
.cause-line.won { border-left-color: var(--gold); background: rgba(255,214,107,.09); }
.overlay .obox .cause-line { margin-bottom: 12px; }
/* on the campaign's parchment the same two things in ink */
.duel-primer .round-ledger {
  margin: 0 0 14px; max-width: none; background: rgba(201,144,63,.08);
  border-color: rgba(201,144,63,.3); color: var(--ow-ink); font: 400 13px/1.45 var(--ow-font-ui);
}
.duel-primer .round-ledger b { color: var(--ow-ink-name); }
.overlay .duel-primer .cause-line {
  max-width: none; margin: 0 0 12px; color: var(--ow-ink); font: 400 14px/1.5 var(--ow-font-story);
  background: rgba(201,144,63,.1); border-left-color: #c9903f; opacity: 1;
}

/* ---- the lanterns as a number, where ten of them will not fit ---- */
.lantern-count { display: none; }
@media (max-width: 340px) {
  .lanterns .lantern-row { display: none; }
  .lanterns .lantern-count {
    display: inline-flex; align-items: baseline; gap: 2px; letter-spacing: 0;
    font-size: 12px; font-weight: 900; color: #5a3a12;
  }
  .lanterns .lantern-count b { font-size: 14px; }
  .lanterns .lantern-count small { font-size: 10px; opacity: .7; }
}

/* ---- phones ---- */
@media (max-width: 560px) {
  /* stacked, the two lists take the sheet's width: flex-start left them as
     wide as their longest row, which ran off a 320px screen */
  .dbcols { align-items: stretch; }
  .dbcols > div { width: 100%; }
  .dbrow { gap: 6px; padding: 4px 6px; }
  .dbrow .dbname {
    min-width: 0; white-space: normal; line-height: 1.15; overflow-wrap: anywhere;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  #db-name { max-width: 100%; min-width: 0; flex: 1 1 160px; }
  /* one row in reach: ← · Save · Save & play. The count is in the chip by
     the name and in a draft's own label, and a Save & play that cannot play
     is only in the way here */
  .overlay .obox > .dbactions {
    display: grid; grid-template-columns: 46px minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: stretch;
  }
  .dbactions .dbtally, .dbactions #db-play:disabled { display: none; }
  .overlay .obox > .dbactions:has(#db-play:disabled), .overlay .obox > .dbactions:not(:has(#db-play)) { grid-template-columns: 46px minmax(0, 1fr); }
  .dbactions #db-back { order: -1; padding: 0; font-size: 18px; }
  .dbactions #db-back .bk { display: none; }
  .dbactions .obtn, .dbactions .smallbtn {
    min-height: 46px; padding: 8px 10px; font-size: 14px; line-height: 1.2; white-space: normal; margin: 0;
  }
  .smallbtn.dbdraft { background: #2a2958; font-size: 13px; }
  /* a deck row: the name and its state on one line, its buttons on the next */
  .deckrow { flex-wrap: wrap; gap: 8px 10px; }
  .deckrow-name { flex: 1 1 calc(100% - 44px); }
  .deckrow .smallbtn { flex: 1 1 0; }
  .deckrow [data-del] { flex: 0 0 52px; }
  .overlay .deck-where { font-size: 13px; margin: -6px 0 14px; }
  .overlay .deck-held { font-size: 12.5px; margin: 8px 0 0; }
  .setup-strip { padding: 8px 10px 9px; margin-bottom: 8px; }
  .setup-strip ul { grid-template-columns: 1fr; gap: 4px; }
  .setup-strip li { font-size: 12.5px; }
  .trialfacts .tf { font-size: 10.5px; }
  .round-ledger { font-size: 12.5px; padding: 9px 11px; }
  .pvfoot .pvnote { font-size: 13.5px; }
}
@media (max-width: 560px) and (orientation: portrait) {
  /* three tiles share the rail rather than each claiming 104px of it */
  #midbar > #constellations { min-width: 0; width: 100%; }
  .constellation {
    flex: 1 1 0; min-width: 0; width: auto;
    padding: 4px 5px; gap: 0 4px; grid-template-columns: 26px minmax(0, 1fr);
  }
  .constellation .cart, .constellation .cart svg, .constellation .cart img { width: 26px; height: 26px; }
  .constellation .cname { font-size: 10px; line-height: 1.05; min-width: 0; overflow-wrap: anywhere; }
  .constellation .ccost { white-space: nowrap; min-width: 0; font-size: 11px; line-height: 1.2; }
  .constellation .cneed { font-size: 9.5px; margin-left: 1px; }
  .constellation .cneed .more { display: none; }
  .constellation .cdone { font-size: 10.5px; }
  .unit .ustate { font-size: 8.5px; padding: 0 5px; top: -8px; }
  #target-banner { border-radius: 16px; gap: 8px; padding: 8px 10px 8px 14px; flex-wrap: nowrap; }
  #target-text { font-size: 12.5px; }
}

/* ---- reduced motion: the celebrations keep their news, lose their flight ---- */
@keyframes revealfade { 0% { opacity: 0; } 10% { opacity: 1; } 85% { opacity: 1; } 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  #celebrate .cbox { animation: none; }
  #ai-reveal { animation-name: revealfade; transform: translateX(-50%); }
  .unit .badge.sleeping, .unit .badge.settling { animation: none; }
}
/* the narrowest phones: the constellation rail gives its art to the words */
@media (max-width: 340px) and (orientation: portrait) {
  .constellation { grid-template-columns: minmax(0, 1fr); text-align: center; padding: 4px; }
  .constellation .cart { display: none; }
}

/* =====================================================================
   Collection goals, the Daily's score breakdown, and Save & backup
   ===================================================================== */

/* ---- the Daily: every factor, its value, its points ---- */
.dsb {
  margin: 12px auto 14px; max-width: 440px; text-align: left;
  padding: 10px 14px 8px; border-radius: 14px;
  background: rgba(0,0,0,0.22); border: 1px solid rgba(255,214,107,0.28);
}
.dsb-title { font-size: 11.5px; font-weight: 900; letter-spacing: .09em; text-transform: uppercase; color: var(--gold); margin-bottom: 4px; }
details.dsb > summary.dsb-title { cursor: pointer; list-style: none; }
details.dsb > summary.dsb-title::before { content: '▸ '; }
details.dsb[open] > summary.dsb-title::before { content: '▾ '; }
details.dsb > summary::-webkit-details-marker { display: none; }
.dsb-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 6px 0; border-bottom: 1px dotted rgba(255,255,255,0.14);
}
.dsb-label { font-size: 14px; font-weight: 700; display: flex; flex-direction: column; gap: 1px; }
.dsb-label small { font-size: 11.5px; font-weight: 600; opacity: .58; }
.dsb-pts { font-size: 15px; font-weight: 900; color: var(--gold); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dsb-row.nil .dsb-pts { color: rgba(255,246,224,.4); }
.dsb-total { border-bottom: 0; border-top: 1.5px solid rgba(255,214,107,.5); margin-top: 2px; }
.dsb-total .dsb-label { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; color: var(--gold); }
.dsb-total .dsb-pts { font-size: 18px; }
.overlay p.dsb-tip, .dsb-tip { font-size: 13px; line-height: 1.45; margin: 6px 0 2px; opacity: .88; font-style: italic; }

/* ---- the deckbuilder's wishlist ---- */
.dbwish, .dbwish-gap { flex: 0 0 26px; width: 26px; height: 26px; }
.dbwish {
  padding: 0; border-radius: 8px; font-size: 16px; line-height: 1; display: grid; place-items: center;
  background: transparent; color: rgba(255,246,224,.55); border: 1px dashed rgba(255,246,224,.28);
}
.dbwish:hover:not(:disabled) { transform: none; color: var(--gold); border-color: var(--gold); }
.dbwish.on { color: #4a3200; background: var(--gold); border: 1px solid var(--gold-deep); }
.dbrow.locked:has(.dbwish.on) { opacity: .85; }
.dbwanted { margin-top: 10px; padding: 8px 10px; border-radius: 10px; border: 1px dashed rgba(255,214,107,.5); background: rgba(255,214,107,.06); }
.dbwanted h3 { font-size: 12.5px; margin: 0 0 4px; color: var(--gold); }
.dbwanted h3 small { font-size: 11px; opacity: .7; margin-left: 4px; }
.dbwanted-row { display: flex; flex-direction: column; gap: 1px; padding: 5px 6px; border-radius: 7px; cursor: pointer; font-size: 12.5px; }
.dbwanted-row:hover, .dbwanted-row:focus-visible { background: rgba(255,214,107,.14); outline: none; }
.dbwanted-name { font-weight: 800; color: #ffe7a8; }
.dbwanted-name i { font-weight: 600; opacity: .7; }
.dbwanted-row small { font-size: 11px; opacity: .7; }
.overlay p.dbwanted-empty { font-size: 11.5px; opacity: .55; margin: 8px 2px 0; }
.dbearn .linkbtn { font-size: 12.5px; color: var(--gold); opacity: .9; border-bottom-color: rgba(255,214,107,.5); padding: 0 1px; }
.dbm-where {
  width: min(360px, 88vw); display: flex; flex-direction: column; gap: 8px; align-items: stretch;
  padding: 10px 12px; border-radius: 14px; background: rgba(20,20,48,.95); border: 1px solid rgba(255,214,107,.3); color: var(--cream);
}
.dbm-wish.on, .cm-star.on { background: var(--gold); color: #4a3200; }
.dbmodal-inner { max-height: calc(100dvh - 20px); overflow-y: auto; padding: 4px; }
.srclist { text-align: left; font-size: 12.5px; }
.srclist b { display: block; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--gold); margin-bottom: 3px; }
.srclist ul { margin: 0; padding: 0; list-style: none; }
.srclist li { position: relative; padding: 3px 0 3px 18px; line-height: 1.4; border-bottom: 1px dotted rgba(255,255,255,.1); }
.srclist li::before { position: absolute; left: 0; top: 3px; content: '·'; opacity: .6; }
.srclist li.src-reward::before { content: '⚔'; color: var(--gold); opacity: 1; }
.srclist li.src-reward { font-weight: 800; color: #ffe7a8; }
.srclist li.src-shop::before { content: '✦'; }
.srclist li.src-duels::before { content: '⚑'; }
.srclist li.src-wish::before { content: '✨'; opacity: 1; }
.srclist li.src-gift::before { content: '❀'; }
.srclist li.src-base::before { content: '✓'; color: #c4f5bb; opacity: 1; }
.deckbadge.wish { color: #ffe7a8; background: rgba(255,214,107,.12); border: 1px solid rgba(255,214,107,.5); margin-left: 6px; }
.collstrip {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin: 0 0 12px; padding: 9px 12px; border-radius: 12px; font-size: 13.5px;
  background: rgba(255,214,107,.08); border: 1px solid rgba(255,214,107,.3);
}
.collstrip b { color: var(--gold); }

/* ---- the collection ---- */
.overlay .obox.coll { text-align: left; max-width: min(94vw, 1000px); padding: 26px 32px 18px; }
.coll h2 { text-align: center; }
.overlay .coll-lede { text-align: center; font-size: 14.5px; margin: 0 auto 14px; max-width: 640px; }
.coll-lede b { color: var(--gold); }
.coll-top { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 14px; align-items: stretch; margin-bottom: 12px; }
.colltable { border-radius: 14px; overflow: hidden; background: rgba(0,0,0,.2); border: 1px solid rgba(255,255,255,.1); }
.ct-row {
  display: grid; grid-template-columns: minmax(0, 1.5fr) repeat(4, minmax(0, 1fr)); gap: 8px; align-items: center;
  width: 100%; padding: 6px 12px; background: transparent; color: var(--cream); text-align: left;
  border-radius: 0; font-size: 12.5px; font-weight: 700; border-top: 1px solid rgba(255,255,255,.07);
}
button.ct-row:hover:not(:disabled) { transform: none; background: rgba(255,214,107,.1); }
.ct-row.on { background: rgba(255,214,107,.18); box-shadow: inset 3px 0 0 var(--gold); }
.ct-head { border-top: 0; font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; opacity: .65; padding-top: 8px; }
.ct-foot { background: rgba(255,214,107,.07); font-weight: 900; }
.ct-set { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf { display: flex; flex-direction: column; gap: 3px; font-variant-numeric: tabular-nums; font-size: 12px; opacity: .85; }
.cf-n { white-space: nowrap; }
.cf b { font-size: 13.5px; }
.cf i { display: block; height: 3px; border-radius: 3px; background: linear-gradient(90deg, var(--gold) var(--p), rgba(255,255,255,.14) var(--p)); }
.cf.full { color: var(--gold); opacity: 1; }
.cf.none { opacity: .3; }
.collpurse { padding: 12px 14px; border-radius: 14px; background: linear-gradient(160deg, rgba(255,214,107,.14), rgba(255,214,107,.04)); border: 1px solid rgba(255,214,107,.35); }
.cp-dust { font-size: 20px; font-weight: 900; color: var(--gold); margin-bottom: 4px; }
.overlay .collpurse p { font-size: 12.5px; line-height: 1.5; margin: 0; }
.collpurse p b { color: #ffe7a8; }
.collwish { margin: 0 0 12px; padding: 10px 12px; border-radius: 14px; border: 1px dashed rgba(255,214,107,.55); background: rgba(255,214,107,.05); }
.collwish h3 { font-size: 13px; color: var(--gold); margin: 0 0 6px; }
.collwish h3 small { opacity: .7; margin-left: 4px; }
.cw-row { display: flex; align-items: center; gap: 10px; padding: 6px 6px; border-radius: 9px; cursor: pointer; }
.cw-row + .cw-row { border-top: 1px dotted rgba(255,255,255,.12); }
.cw-row:hover, .cw-row:focus-visible { background: rgba(255,214,107,.1); outline: none; }
.cw-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: 13.5px; }
.cw-main i { font-size: 12px; opacity: .7; }
.cw-for { font-size: 11.5px; color: #ffe7a8; font-weight: 700; }
.cw-src { font-size: 11.5px; opacity: .7; }
.cw-grant { flex: 0 0 auto; background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: #4a3000; }
.cw-grant[aria-disabled="true"] { background: rgba(255,255,255,.1); color: rgba(255,246,224,.6); }
.cw-x { flex: 0 0 auto; width: 30px; height: 30px; padding: 0; border-radius: 50%; background: rgba(255,255,255,.08); color: var(--cream); font-size: 12px; }
.overlay .collwish-empty { font-size: 12.5px; opacity: .65; margin: 0 0 12px; text-align: center; }
.collfilters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 8px; }
.collfilters .segmented { background: rgba(0,0,0,.3); flex-wrap: wrap; }
.segbtn { padding: 6px 11px; font-size: 12px; border-radius: 9px; background: transparent; color: var(--cream); opacity: .72; }
.segbtn:hover:not(:disabled) { transform: none; opacity: 1; }
.segbtn.on { background: var(--gold); color: #4a3000; opacity: 1; }
.collset-clear { padding: 6px 10px; font-size: 12px; }
.coll-list { max-height: 42vh; overflow-y: auto; padding-right: 4px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px 10px; align-content: start; }
.coll-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 8px; font-size: 12.5px;
  background: rgba(255,255,255,.06); cursor: pointer; min-height: 30px;
}
.coll-row:hover, .coll-row:focus-visible { background: rgba(255,214,107,.16); outline: none; }
.coll-row .dbcost { flex: 0 0 20px; height: 20px; border-radius: 50%; background: var(--gold); color: #4a3200; font-weight: 900; font-size: 12px; display: grid; place-items: center; }
.coll-row.missing .dbcost { background: rgba(255,255,255,.18); color: var(--cream); }
.cr-emoji { flex: 0 0 auto; }
.cr-name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.cr-name b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cr-name small { font-size: 10.5px; opacity: .62; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.coll-row.missing .cr-name b { color: #cfc6dd; }
.coll-row .set2badge { flex: 0 0 auto; font-size: 9.5px; font-weight: 800; padding: 1px 5px; border-radius: 6px; background: rgba(140,200,255,.25); color: #bfe3ff; }
.coll-row .set2badge.set1 { background: rgba(255,214,107,.18); color: #ffe7a8; }
.coll-row .set2badge.set3 { background: rgba(255,190,96,.24); color: #ffe1a8; }
.coll-row .set2badge.set4 { background: rgba(157,224,192,.20); color: #c9f5e0; }
.coll-row .set2badge.set5 { background: rgba(169,212,255,.20); color: #d8ecff; }
.cr-have { flex: 0 0 52px; text-align: right; font-weight: 900; color: var(--cream); font-variant-numeric: tabular-nums; }
.cr-have.full { color: var(--gold); }
.cr-have.zero { color: rgba(255,246,224,.4); font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; }
.overlay .coll-none { grid-column: 1 / -1; text-align: center; font-size: 13.5px; opacity: .7; margin: 14px 0; }
.coll .overlay-actions { display: flex; justify-content: center; margin-top: 12px; }
.collmodal-inner { flex-direction: row; align-items: center; gap: 18px; }
.collmodal-side {
  width: 320px; display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: 16px;
  background: rgba(20,20,48,.95); border: 1px solid rgba(255,214,107,.3); color: var(--cream);
}
.cm-have { font-size: 17px; font-weight: 900; color: var(--gold); display: flex; flex-direction: column; }
.cm-have small { font-size: 11.5px; color: var(--cream); opacity: .6; font-weight: 700; }
.cm-grant { padding: 11px 16px; font-size: 14.5px; background: linear-gradient(180deg, var(--gold), var(--gold-deep)); color: #4a3000; }
.cm-why { font-size: 12px; opacity: .75; margin: -4px 0 0; line-height: 1.4; }

/* the home screen: five tiles fit one row, the backup link sits in the foot */
.journey-lobby .modegrid:has(> .modetile:nth-child(5)) { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.journey-lobby .backup-link { color: #58635b; opacity: .9; }

@media (max-width: 760px) {
  .coll-top { grid-template-columns: minmax(0, 1fr); }
  .coll-list { grid-template-columns: minmax(0, 1fr); max-height: none; overflow: visible; }
  .collmodal-inner { flex-direction: column; }
  .collmodal-side { width: min(340px, 90vw); }
  .journey-lobby .modegrid:has(> .modetile:nth-child(5)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .journey-lobby .modegrid > .modetile:nth-child(5):last-child { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
  .overlay .obox.coll { padding: 18px 12px calc(14px + var(--sab)); }
  .ct-row { padding: 6px 8px; gap: 5px; font-size: 11.5px; grid-template-columns: minmax(0, 1.25fr) repeat(4, minmax(0, 1fr)); }
  .ct-head span { font-size: 9.5px; }
  .cf b { font-size: 12.5px; }
  .cf { font-size: 11px; }
  .ct-set { white-space: normal; line-height: 1.2; }
  .coll-row { align-items: flex-start; padding: 7px 8px; }
  .coll-row .dbcost, .coll-row .cr-emoji { margin-top: 1px; }
  .cr-name b { white-space: normal; }
  .cr-name small { white-space: normal; line-height: 1.3; margin-top: 1px; }
  .cr-have { flex-basis: 34px; }
  .cr-have.zero { font-size: 0; }
  .cr-have.zero::after { content: '🔒'; font-size: 12px; opacity: .6; }
  .cw-row { flex-wrap: wrap; }
  .cw-main { flex-basis: calc(100% - 44px); }
  .dbwish { flex-basis: 32px; width: 32px; height: 32px; }
  .dbwish-gap { flex-basis: 32px; width: 32px; }
  .dsb { padding: 8px 12px 6px; }
  .dbmodal .collmodal-inner .cardpv { width: 240px; }
}

/* ---- Save & backup ---- */
.sfb-backdrop {
  position: fixed; inset: 0; z-index: 20000; display: grid; place-items: center; padding: 16px;
  background: rgba(8, 10, 26, 0.78); backdrop-filter: blur(5px); animation: fadein .25s ease;
  overflow-y: auto; box-sizing: border-box;
}
.sfb-panel {
  position: relative; box-sizing: border-box; width: min(620px, 100%);
  max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain;
  padding: 28px 32px 24px; border-radius: 18px; color: #f6efdc; text-align: left;
  font-family: 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
  background: radial-gradient(120% 70% at 50% 0%, #2a2c5c 0%, #1a1b3c 55%, #141530 100%);
  border: 1px solid rgba(255,214,107,.4); border-top: 3px solid #ffd66b;
  box-shadow: 0 28px 90px rgba(0,0,0,.6);
}
.sfb-x {
  position: absolute; top: 10px; right: 10px; width: 40px; height: 40px; padding: 0; border-radius: 50%;
  background: rgba(255,255,255,.08); color: #f6efdc; font-size: 22px; line-height: 1;
}
.sfb-panel .sfb-eyebrow { margin: 0 0 2px; font-size: 11px; font-weight: 900; letter-spacing: .16em; text-transform: uppercase; color: #ffd66b; }
.sfb-panel h2 { margin: 0 0 8px; font: 400 29px/1.15 Georgia, 'Iowan Old Style', serif; color: #fff6e0; }
.sfb-panel h3 { margin: 0 0 6px; font-size: 11px; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; color: #ffd66b; opacity: .85; }
.sfb-panel p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.5; }
.sfb-panel .sfb-lede { opacity: .85; }
.sfb-card { margin: 14px 0; padding: 12px 14px 6px; border-radius: 12px; background: rgba(0,0,0,.24); border: 1px solid rgba(255,255,255,.09); }
.sfb-list { margin: 0; }
.sfb-list > div { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 10px; padding: 6px 0; border-top: 1px dotted rgba(255,255,255,.12); }
.sfb-list > div:first-child { border-top: 0; }
.sfb-list dt { font-size: 12.5px; font-weight: 800; opacity: .65; }
.sfb-list dd { margin: 0; font-size: 13.5px; font-weight: 700; }
.sfb-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 8px; }
.sfb-primary, .sfb-secondary { min-height: 46px; padding: 11px 20px; border-radius: 12px; font-size: 15px; font-weight: 800; }
.sfb-primary { background: linear-gradient(180deg, #ffd66b, #f0a830); color: #4a3000; box-shadow: 0 6px 18px rgba(240,168,48,.25); }
.sfb-secondary { background: transparent; color: #fff6e0; border: 1.5px solid rgba(255,246,224,.45); }
.sfb-secondary:hover:not(:disabled) { border-color: #ffd66b; color: #ffd66b; }
/* the story page resets every button's font; the panel looks the same on both */
#backup-overlay .sfb-primary, #backup-overlay .sfb-secondary { font: 800 15px/1.2 'Avenir Next', 'Segoe UI', system-ui, sans-serif; }
#backup-overlay .sfb-x { font: 400 22px/1 'Avenir Next', 'Segoe UI', system-ui, sans-serif; }
.sfb-panel .sfb-status { min-height: 1em; font-size: 13.5px; color: #c4f5bb; margin: 4px 0 10px; }
.sfb-status b { color: #fff6e0; }
.sfb-panel .sfb-note { font-size: 13px; opacity: .78; padding-left: 12px; border-left: 2px solid rgba(255,214,107,.45); }
.sfb-panel .sfb-sync { opacity: .95; background: rgba(140,200,255,.08); border-left-color: #8cc8ff; padding: 10px 12px; border-radius: 0 10px 10px 0; }
.sfb-undo { margin-top: 14px; padding: 12px 14px; border-radius: 12px; border: 1px dashed rgba(255,214,107,.5); background: rgba(255,214,107,.06); }
.sfb-panel .sfb-undo p { font-size: 13px; margin-bottom: 10px; }
.sfb-panel .sfb-file { font-size: 12.5px; opacity: .75; margin-bottom: 12px; overflow-wrap: anywhere; }
.sfb-panel .sfb-error { color: #ffc2b0; font-weight: 700; padding: 10px 12px; border-radius: 10px; background: rgba(255,120,100,.12); border: 1px solid rgba(255,140,120,.45); }
.sfb-panel .sfb-warn { font-size: 13.5px; padding: 10px 12px; border-radius: 10px; background: rgba(255,214,107,.1); border: 1px solid rgba(255,214,107,.4); }
.sfb-compare { margin: 0 0 14px; border-radius: 12px; overflow: hidden; border: 1px solid rgba(255,255,255,.1); }
.sfb-crow { display: grid; grid-template-columns: 124px minmax(0, 1fr) minmax(0, 1fr); gap: 10px; padding: 7px 12px; font-size: 13px; border-top: 1px solid rgba(255,255,255,.07); }
.sfb-crow > span:first-child { font-weight: 800; opacity: .65; font-size: 12px; }
.sfb-chead { border-top: 0; background: rgba(0,0,0,.25); font-size: 10.5px; font-weight: 900; letter-spacing: .08em; text-transform: uppercase; color: #ffd66b; }
.sfb-chead > span:first-child { opacity: 1; }
.sfb-in { font-weight: 800; color: #fff6e0; }
.sfb-now { opacity: .7; }
.sfb-crow.same .sfb-in, .sfb-crow.same .sfb-now { opacity: .5; font-weight: 600; }
@media (max-width: 560px) {
  .sfb-backdrop { place-items: end center; padding: 8px 8px 0; }
  .sfb-panel { padding: 22px 18px calc(18px + var(--sab)); border-radius: 18px 18px 12px 12px; max-height: calc(100dvh - 8px - var(--sat)); }
  .sfb-panel h2 { font-size: 24px; padding-right: 36px; }
  .sfb-list > div { grid-template-columns: 112px minmax(0, 1fr); }
  .sfb-actions > button { flex: 1 1 100%; }
  .sfb-crow { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 2px 10px; }
  .sfb-crow > span:first-child { grid-column: 1 / -1; }
  .sfb-chead > span:first-child { display: none; }
}
