/* Diamonds of Doom — per-screen layout. */

/* ══ TITLE ════════════════════════════════════════════ */
.title-screen{text-align:center;padding-bottom:var(--sp-7)}

/* The cover carries its own title lettering, so the screen shows the art and
   gets out of its way — no duplicate wordmark competing with the painting. */
.cover{
  position:relative;margin:0 0 calc(var(--sp-7) * -1);
  border-radius:var(--r-md);overflow:hidden;
  box-shadow:0 12px 48px rgba(0,0,0,.75);
  border:1px solid var(--night-400);
}
.cover img{display:block;width:100%;height:auto}
/* Fade the bottom of the art into the page so the controls sit on darkness
   rather than on a hard edge. */
.cover::after{
  content:"";position:absolute;inset:auto 0 0 0;height:45%;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(5,8,15,.55) 55%,var(--night-900));
}
.title-inner{max-width:560px;margin:0 auto;position:relative;z-index:2}
.title-tag{
  font-style:italic;color:var(--frost-200);font-size:18px;
  margin-bottom:var(--sp-6);text-shadow:0 2px 12px #000;
}
.name-field{
  width:100%;background:var(--night-800);border:1px solid var(--night-400);border-radius:var(--r-sm);
  color:var(--frost-100);font-family:var(--font-display);font-size:18px;letter-spacing:.05em;
  padding:13px var(--sp-4);text-align:center;margin-bottom:var(--sp-4);
}
.name-field:focus{outline:none;border-color:var(--ice-500);box-shadow:var(--glow-ice)}
.name-field::placeholder{color:var(--frost-300);opacity:.55;font-style:italic}
.title-actions{display:flex;gap:var(--sp-3);justify-content:center;flex-wrap:wrap}
.title-foot{margin-top:var(--sp-7);font-size:14px;color:var(--frost-300);font-style:italic}

/* ══ MAP ══════════════════════════════════════════════ */
.map-wrap{display:grid;grid-template-columns:1fr 320px;gap:var(--sp-4)}

/* — The frame —
   One window; two maps behind it at different distances. Everything inside is
   positioned in percentages of this box, which is why it keeps the painted
   maps' own 8:5 rather than a screen aspect: a node at 24%,21% has to land on
   the walled town, and a crop would quietly move every marker on the map. */
.map-frame{
  position:relative;aspect-ratio:8/5;max-height:calc(100vh - 220px);
  border:1px solid var(--night-400);border-radius:var(--r-md);overflow:hidden;
  background:linear-gradient(165deg,#16233c,#080d18 72%);
}
.map-frame::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:5;
  box-shadow:inset 0 0 90px 10px rgba(5,8,15,.6);
}
.map-layer{
  position:absolute;inset:0;transform-origin:0 0;
  opacity:0;pointer-events:none;
  transition:opacity .55s ease,transform .95s cubic-bezier(.33,.9,.3,1);
}
.map-layer.on{opacity:1;pointer-events:auto}
.map-layer .map-art{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;user-select:none;
}
/* The region map carries the interface on top of it, so it takes the same
   pushed-back treatment the old backdrop had. The world map does not — when
   you pull back to look at the whole campaign, looking at it *is* the point. */
.map-layer.region .map-art{filter:saturate(.96) brightness(1.02) contrast(1.03)}
.map-layer.region svg{position:absolute;inset:0;width:100%;height:100%;z-index:1}
/* Mid-flight nothing should be clickable — a click that lands on the region you
   are leaving would queue a second journey behind the one already playing. */
.map-frame.is-flying .map-layer{pointer-events:none}

/* — Regions on the world map — */
.region-plate{
  position:absolute;z-index:2;padding:0;border:0;background:none;cursor:pointer;
  font:inherit;color:inherit;display:grid;place-items:center;
  transition:filter var(--t-fast) ease-out;
}
.region-plate .region-veil{
  position:absolute;inset:0;border-radius:14px;
  transition:background var(--t-med) ease,box-shadow var(--t-med) ease;
}
.region-plate .region-tag{
  position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:2px;
  padding:7px 13px;border-radius:99px;
  background:rgba(5,8,15,.74);border:1px solid rgba(51,69,106,.55);
  text-shadow:0 1px 2px #000;transition:opacity var(--t-med) ease;
}
.region-plate .region-tag b{
  font-family:var(--font-display);font-size:14px;font-weight:600;color:var(--frost-100);
}
.region-plate .region-tag i{
  font-family:var(--font-ui);font-style:normal;font-size:9.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--steel-400);
}
.region-plate .region-gem{font-style:normal;font-size:12px;color:var(--ice-400);margin-top:1px}

.region-plate.open .region-veil{box-shadow:inset 0 0 0 1px rgba(111,182,232,.35)}
.region-plate.open:hover .region-veil,.region-plate.sel .region-veil{
  background:rgba(111,182,232,.10);box-shadow:inset 0 0 0 2px rgba(111,182,232,.7)
}
.region-plate.cleared .region-veil{background:rgba(5,8,15,.22);box-shadow:inset 0 0 0 1px rgba(122,196,160,.4)}
.region-plate.cleared .region-tag b{color:var(--vital-500)}
.region-plate.next .region-veil{box-shadow:inset 0 0 0 1px rgba(125,147,173,.4)}
.region-plate.next .region-tag i{color:var(--steel-500)}

/* — The shadow —
   Not a lock icon and not a grey box: the country is *there*, painted, and you
   simply cannot see it yet.

   It is its own tiling layer rather than a veil on each region plate, because
   the plates are sized for the *camera* — they frame what the zoom flies to,
   and they do not touch edge to edge. Anything a plate did not cover stayed lit,
   so the unreached half of the map had bright seams running through it. These
   shades tile the full picture between them and are blurred so the joins
   disappear into the dark. */
.world-shade{
  position:absolute;z-index:1;pointer-events:none;
  background:rgb(2,4,9);
  filter:blur(26px);
  opacity:0;
  transition:opacity 1.1s ease;
}
.world-shade.on{opacity:.96}
.region-plate.shadow{cursor:default}
/* In admin the dark still draws — you have to be able to see what a player
   sees — but the plate stays live, marked amber like every other admin
   affordance so it never reads as something a player could click. */
.region-plate.shadow.admin-see{cursor:pointer;z-index:3}
.region-plate.shadow.admin-see .region-tag{
  opacity:1;background:rgba(5,8,15,.8);border:1px dashed var(--coin-500)
}
.region-plate.shadow.admin-see .region-tag b{color:var(--coin-500);font-size:13px;letter-spacing:.06em}
.region-plate.shadow.admin-see .region-tag i{color:var(--coin-500);opacity:.7}
.region-plate.shadow .region-tag{opacity:.3;background:none;border-color:transparent}
.region-plate.shadow .region-tag b{color:var(--steel-600);font-size:12px;letter-spacing:.3em}

.region-plate.just-opened .region-veil{animation:regionWake 2.6s ease-out 1}
@keyframes regionWake{
  0%{background:rgba(111,182,232,0);box-shadow:inset 0 0 0 0 rgba(111,182,232,0)}
  35%{background:rgba(111,182,232,.16);box-shadow:inset 0 0 0 3px rgba(111,182,232,.95)}
  100%{background:transparent;box-shadow:inset 0 0 0 1px rgba(125,147,173,.4)}
}
@media (prefers-reduced-motion:reduce){
  .map-layer{transition:opacity .2s linear}
  .region-plate.just-opened .region-veil{animation:none}
  .world-shade{transition:none}
}

/* — The bar across the map — */
.map-hud{
  position:absolute;left:0;right:0;top:0;z-index:6;
  display:flex;align-items:center;gap:var(--sp-3);
  padding:10px 12px;pointer-events:none;
  background:linear-gradient(180deg,rgba(5,8,15,.82),transparent);
}
.map-hud > *{pointer-events:auto}
.map-zoom{
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.06em;
  color:var(--frost-200);background:rgba(5,8,15,.72);border:1px solid rgba(51,69,106,.6);
  border-radius:99px;padding:6px 12px;cursor:pointer;
  transition:border-color var(--t-fast) ease,color var(--t-fast) ease;
}
.map-zoom:hover{border-color:var(--ice-500);color:var(--ice-400)}
.map-where{display:flex;flex-direction:column;line-height:1.2}
.map-where b{font-family:var(--font-display);font-size:14px;color:var(--frost-100)}
.map-where i{font-family:var(--font-ui);font-style:normal;font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--steel-400)}
.map-diamonds{margin-left:auto}
.gem-row{display:flex;align-items:center;gap:3px;
  background:rgba(5,8,15,.72);border:1px solid rgba(51,69,106,.6);border-radius:99px;padding:5px 11px}
.gem-row b{font-size:12px;color:rgba(125,147,173,.45)}
.gem-row b.has{color:var(--ice-400);text-shadow:0 0 8px rgba(111,182,232,.85)}
.gem-row i{font-family:var(--font-ui);font-style:normal;font-size:10px;font-weight:600;
  color:var(--steel-400);margin-left:5px}

.map-toast{
  position:absolute;left:50%;bottom:22px;transform:translate(-50%,10px);z-index:6;
  font-family:var(--font-display);font-size:16px;color:var(--frost-100);
  background:rgba(5,8,15,.86);border:1px solid rgba(51,69,106,.6);border-radius:99px;
  padding:9px 20px;opacity:0;pointer-events:none;
  transition:opacity .5s ease,transform .5s ease;
}
.map-toast.on{opacity:1;transform:translate(-50%,0)}

.node{position:absolute;transform:translate(-50%,-50%);text-align:center;z-index:2;background:none;border:0;cursor:pointer;font:inherit;color:inherit}
.node .dot{position:relative}
.node .dot{
  width:40px;height:40px;border-radius:50%;display:grid;place-items:center;font-size:18px;
  background:var(--night-600);border:2px solid var(--night-400);margin:0 auto;
  transition:transform var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.node .cap{
  font-family:var(--font-ui);font-size:9.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--frost-200);margin-top:7px;white-space:nowrap;
  /* The art behind is busy, so captions get their own dark plate rather than
     relying on a text-shadow that vanishes over the bright crystals. */
  display:inline-block;padding:2px 7px;border-radius:99px;
  background:rgba(5,8,15,.72);border:1px solid rgba(51,69,106,.5);
  text-shadow:0 1px 2px #000;
}
/* — Painted map markers —
   The circular chrome comes off entirely when there's a picture. These icons
   already carry their own forged-metal frame, and a plate behind one reads as
   a sticker on a sticker. Everything the ring used to say — locked, cleared,
   the next main quest — is said with light instead. */
.node.has-icon .dot{
  width:52px;height:52px;background:none;border:none;border-radius:0;
  filter:drop-shadow(0 4px 10px rgba(5,8,15,.95));
}
.node.has-icon .dot img{width:100%;height:100%;object-fit:contain;display:block}
/* Cleared: keep the picture, add a badge. You should still recognise Blackfen
   on the map after you've beaten it. */
.node.has-icon.done .dot{filter:drop-shadow(0 4px 10px rgba(5,8,15,.95)) saturate(.6) brightness(.78)}
.node.has-icon .tick{
  position:absolute;right:-4px;bottom:-2px;
  width:19px;height:19px;border-radius:50%;
  display:grid;place-items:center;font-size:11px;font-weight:700;
  background:var(--vital-500);color:var(--night-900);
  box-shadow:0 2px 6px rgba(5,8,15,.9);
}
.node.has-icon.locked .dot{filter:grayscale(1) brightness(.4) drop-shadow(0 3px 7px rgba(5,8,15,.9));opacity:1}
/* The next main quest pulses. A box-shadow can't glow around a transparent
   PNG, so the breathing is a drop-shadow instead of a ring. */
.node.has-icon.main .dot{animation:iconBreathe 2.4s ease-in-out infinite}
@keyframes iconBreathe{
  0%,100%{filter:drop-shadow(0 4px 10px rgba(5,8,15,.95))}
  50%{filter:drop-shadow(0 4px 10px rgba(5,8,15,.95)) drop-shadow(0 0 12px rgba(111,182,232,.95))}
}
.node.has-icon.main.done .dot{animation:none}
.node.has-icon:not(.locked):hover .dot,.node.has-icon:focus-visible .dot{
  transform:scale(1.16);
  filter:drop-shadow(0 4px 10px rgba(5,8,15,.95)) drop-shadow(0 0 14px rgba(168,220,255,.95));
}
.node.has-icon.sel .dot{filter:drop-shadow(0 4px 10px rgba(5,8,15,.95)) drop-shadow(0 0 14px rgba(168,220,255,.8))}
@media (prefers-reduced-motion:reduce){.node.has-icon.main .dot{animation:none}}

.node.hub:not(.has-icon) .dot{border-color:var(--ice-500);background:#1c2b45}
.node.main:not(.has-icon) .dot{border-color:var(--ice-500);animation:breathe 2s ease-in-out infinite}
.node.main .cap{color:var(--ice-500)}
.node.side:not(.has-icon) .dot{border-color:var(--steel-500)}
.node.done:not(.has-icon) .dot{border-color:var(--vital-500);opacity:.75}
.node.locked{cursor:not-allowed}
.node.locked:not(.has-icon) .dot{opacity:.3}
.node.locked .cap{opacity:.4}
.node:not(.locked):hover .dot,.node:focus-visible .dot{transform:scale(1.14);box-shadow:var(--glow-ice)}
.node:focus-visible{outline:none}
/* The Vale is a crowded map — whichever marker you're pointing at wins. */
.node:hover,.node:focus-visible,.node.sel{z-index:6}
@keyframes breathe{0%,100%{box-shadow:0 0 0 rgba(111,182,232,0)}50%{box-shadow:0 0 20px rgba(111,182,232,.75)}}

.map-side{display:flex;flex-direction:column;gap:var(--sp-3)}
.q-card{padding:var(--sp-4)}
.q-title{font-family:var(--font-display);font-size:17px;font-weight:600;margin:6px 0}
.q-desc{font-size:15px;color:var(--frost-200);font-style:italic;line-height:1.55}
.q-meta{display:flex;justify-content:space-between;align-items:center;margin-top:var(--sp-4)}
.skulls{color:var(--blood-500);font-size:11px;letter-spacing:1px}
.reward{font-family:var(--font-ui);font-size:11px;color:var(--ice-500);font-weight:600}
.roster{list-style:none;padding:var(--sp-2) var(--sp-4) var(--sp-4)}
.roster li{display:flex;justify-content:space-between;gap:var(--sp-3);font-size:15px;color:var(--frost-200);padding:6px 0;border-bottom:1px dashed var(--night-500)}
.roster li:last-child{border:none}

/* ══ INTRO ════════════════════════════════════════════
   The opening runs full-bleed, outside the usual page column — it is the one
   screen that isn't an interface, so it doesn't wear one.                    */
.intro{
  position:fixed;inset:0;z-index:600;overflow:hidden;cursor:pointer;
  background:var(--night-900);
  display:flex;flex-direction:column;justify-content:flex-end;
}
/* Two stacked layers so frames cross-fade instead of cutting through black. */
.intro-art{
  position:absolute;inset:0;background-position:center center;background-size:cover;
  background-repeat:no-repeat;opacity:1;
  /* A very slow drift. Enough to stop a still image reading as a frozen page,
     not enough to notice as motion. */
  animation:introDrift 22s ease-out both;
}
.intro-art.next{opacity:0;transition:opacity 900ms ease-out}
.intro-art.next.on{opacity:1}

/* The moving version, sitting on top of the paintings. Starts invisible and is
   only faded up once the browser reports it is actually playing — so a clip
   that is still arriving, or one autoplay refuses, is simply never seen and the
   painting underneath carries the frame. */
.intro-clip{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity 700ms ease-out;pointer-events:none;
  background:transparent;
}
.intro-clip.on{opacity:1}
/* The slow scale drift exists to stop a still image reading as a frozen page.
   A clip is already moving, so once one is up the drift is just wobble. */
.intro-art:has(~ .intro-clip.on){animation:none}
@keyframes introDrift{from{transform:scale(1.06)}to{transform:scale(1.13)}}
@media (prefers-reduced-motion:reduce){.intro-art{animation:none}.intro-clip{display:none}}

/* The text always lands on darkness, whatever the painting is doing there. */
.intro-veil{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(5,8,15,.5) 0%,rgba(5,8,15,.04) 20%,
                    rgba(5,8,15,.5) 52%,rgba(5,8,15,.97) 100%);
}

.intro-body{
  position:relative;z-index:2;
  padding:0 clamp(var(--sp-5),7vw,110px) clamp(70px,9vh,110px);
  max-width:1180px;margin:0 auto;width:100%;
}
.intro-title{
  font-family:var(--font-display);font-weight:700;
  font-size:clamp(30px,6vw,68px);letter-spacing:.1em;text-transform:uppercase;
  color:var(--frost-100);text-shadow:0 0 40px rgba(111,182,232,.55),0 4px 22px rgba(5,8,15,.95);
  margin-bottom:var(--sp-5);opacity:0;transform:translateY(10px);
  transition:opacity 1.2s ease-out,transform 1.2s ease-out;
}
.intro-title.on{opacity:1;transform:none}
.intro-wordmark{display:none}

.intro-line{
  font-family:var(--font-display);font-size:clamp(17px,2.3vw,26px);line-height:1.55;
  color:var(--frost-100);text-shadow:0 2px 16px rgba(5,8,15,.98);
  max-width:46ch;margin-bottom:.45em;min-height:1.55em;
}
.intro-line:last-child{margin-bottom:0}

.intro-bar{
  position:relative;z-index:3;display:flex;align-items:center;gap:var(--sp-4);
  padding:0 clamp(var(--sp-5),7vw,110px) clamp(var(--sp-5),4vh,40px);
  max-width:1180px;margin:0 auto;width:100%;
}
.intro-dots{display:flex;gap:7px;flex:1}
.intro-dots .dot{
  width:26px;height:3px;border-radius:2px;background:rgba(230,241,251,.2);
  transition:background var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.intro-dots .dot.on{background:rgba(230,241,251,.6)}
.intro-dots .dot.now{background:var(--ice-400);box-shadow:0 0 12px rgba(168,220,255,.8)}
/* The skip button must not disappear into the painting behind it. */
.intro-bar .btn{background:rgba(5,8,15,.55);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
#introMute{padding:11px 14px;font-size:15px;line-height:1;filter:grayscale(1)}

/* ══ ARM WRESTLING ════════════════════════════════════
   The tug bar reuses the two colours the game has already taught you: forge
   orange is you pressing (same as the strike meter — heat marks the places the
   game is asking you for something), violet is the other side of a contest.
   Nothing new to learn mid-mash.                                             */
.arm-panel{margin-top:var(--sp-4)}
.arm-meta{
  font-family:var(--font-ui);font-size:9px;letter-spacing:.14em;text-transform:none;
  color:var(--frost-300);margin-inline-start:var(--sp-3);text-transform:uppercase;
}
.arm-body{padding:var(--sp-5);display:flex;flex-direction:column;gap:var(--sp-5);align-items:center}
.arm-note{font-size:15.5px;color:var(--frost-200);text-align:center;max-width:56ch;line-height:1.6}
.arm-sub{font-size:13.5px;color:var(--frost-300);text-align:center}
.arm-sub b{color:var(--coin-500)}
.btn-big{font-size:16px;padding:15px 34px}

/* — Choosing a stake — */
.arm-stake{width:min(460px,100%);display:flex;flex-direction:column;gap:var(--sp-3)}
.arm-stake-row{display:flex;justify-content:space-between;align-items:baseline}
.arm-amount{font-family:var(--font-display);font-size:30px;font-weight:700;color:var(--coin-500)}
.arm-slider{width:100%;accent-color:var(--coin-500);cursor:pointer}
.arm-quick{display:flex;gap:6px;justify-content:center;flex-wrap:wrap}

/* — The bout — */
.arm-bout{width:min(620px,100%);display:flex;flex-direction:column;gap:var(--sp-4);align-items:center}
.arm-track{
  position:relative;width:100%;height:46px;overflow:hidden;
  /* Your side is the left, hers the right, and the knob is the joined hands.
     Driving it right means driving her arm down onto her half of the table.
     It was the other way round for one build and read as pushing toward your
     own name, which is exactly backwards from what your hands are doing. */
  background:linear-gradient(90deg,rgba(247,168,60,.16),rgba(13,19,33,.85) 45%,rgba(13,19,33,.85) 55%,rgba(139,95,196,.3));
  border:1px solid var(--night-400);border-radius:var(--r-sm);
  transition:box-shadow var(--t-fast) ease-out;
}
.arm-track.live{border-color:var(--forge-500)}
.arm-track.winning{box-shadow:0 0 24px rgba(247,168,60,.5)}
.arm-track.losing{box-shadow:0 0 24px rgba(139,95,196,.55)}
.arm-fill{
  position:absolute;inset:0 auto 0 0;width:50%;
  background:linear-gradient(90deg,rgba(232,152,52,.25),rgba(247,168,60,.6));
}
/* No CSS transition on the knob — it is driven by requestAnimationFrame, and a
   transition on top of that lags a frantic bar behind the actual state. */
.arm-knob{
  position:absolute;top:-6px;bottom:-6px;left:50%;width:8px;margin-left:-4px;border-radius:4px;
  background:var(--frost-100);box-shadow:0 0 16px rgba(255,214,120,1),0 0 4px #fff;
}
.arm-end{
  position:absolute;top:50%;transform:translateY(-50%);
  font-family:var(--font-ui);font-size:9.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  text-shadow:0 1px 4px rgba(5,8,15,.95);pointer-events:none;
}
.arm-end.you{left:12px;color:var(--forge-300)}
.arm-end.them{right:12px;color:var(--shadow-400,#b18ce0)}

.arm-clock{width:100%;height:4px;background:var(--night-900);border-radius:2px;overflow:hidden}
.arm-clock-fill{height:100%;width:100%;background:var(--steel-500)}

.arm-mash{min-width:260px;letter-spacing:.2em}
.arm-mash:active{transform:none}

/* — The reckoning — */
.arm-result{text-align:center}
.arm-verdict{
  font-family:var(--font-display);font-size:15px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--frost-300);
}
.arm-gold{font-family:var(--font-display);font-size:46px;font-weight:700;margin:6px 0}
.arm-result.won .arm-gold{color:var(--forge-300);text-shadow:0 0 26px rgba(247,168,60,.6)}
.arm-result.lost .arm-gold{color:var(--blood-400)}

/* ══ THE AXE BOARD ════════════════════════════════════
   Same palette rule as everywhere else: forge orange is you doing something,
   violet is the other side. The board itself is wood and iron and stays out of
   both.                                                                      */
.axe-round{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--sp-6);align-items:center;width:100%;
}
.axe-board{
  position:relative;aspect-ratio:1;width:min(320px,100%);margin:0 auto;border-radius:50%;
  background:radial-gradient(circle at 50% 42%,#3b3024,#241c14 70%,#14100b);
  border:6px solid #1b1610;
  box-shadow:0 0 0 2px rgba(90,115,145,.25),inset 0 0 40px rgba(0,0,0,.8),0 14px 34px rgba(0,0,0,.6);
}
.axe-ring{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);border-radius:50%;
  width:var(--r);height:var(--r);border:1px solid rgba(230,241,251,.14);
}
.axe-ring.r1{border-color:rgba(230,241,251,.2)}
/* The outermost ring is the edge of the board itself — everything past it is
   wall, and scores nothing. Drawn solid so that reads without a legend. */
.axe-ring.r4{
  border:2px solid rgba(230,241,251,.4);
  box-shadow:0 0 0 1px rgba(5,8,15,.6),0 0 22px rgba(0,0,0,.7) inset;
}
.axe-ring.r0{border-color:rgba(247,168,60,.75);box-shadow:0 0 14px rgba(247,168,60,.35)}
.axe-pip{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:5px;height:5px;border-radius:50%;background:var(--forge-400);
}
/* Bottom-anchored so `bottom` reads as "up the board", matching the rise meter. */
.axe-hit{
  position:absolute;transform:translate(-50%,50%);
  min-width:24px;height:24px;padding:0 5px;border-radius:12px;
  display:grid;place-items:center;
  font-family:var(--font-display);font-size:12px;font-weight:700;
  background:rgba(5,8,15,.86);color:var(--frost-100);
  border:1px solid rgba(230,241,251,.35);box-shadow:0 2px 8px rgba(0,0,0,.8);
  animation:axeLand 260ms cubic-bezier(.2,1.4,.4,1);
}
.axe-hit.bull{border-color:var(--forge-400);color:var(--forge-300);box-shadow:0 0 16px rgba(247,168,60,.7)}
.axe-hit.miss{border-color:var(--blood-500);color:var(--blood-400)}
@keyframes axeLand{from{transform:translate(-50%,50%) scale(2.2);opacity:0}to{transform:translate(-50%,50%) scale(1);opacity:1}}

.axe-controls{display:flex;flex-direction:column;gap:var(--sp-4);min-width:0}
.axe-prompt{
  font-family:var(--font-ui);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--frost-300);text-align:center;min-height:16px;
}
.axe-prompt b{color:var(--forge-400)}

/* The two meters. The lit band is the slice that is actually over the board —
   the rest of the bar is the wall, which is why a slow meter is still hard. */
.axe-meter{
  position:relative;background:var(--night-900);
  border:1px solid var(--night-400);border-radius:var(--r-sm);overflow:hidden;
  opacity:.42;transition:opacity var(--t-fast) ease-out,border-color var(--t-fast) ease-out;
}
.axe-meter.active{opacity:1;border-color:var(--forge-500)}
.axe-meter.line{height:30px}
.axe-meter.rise{height:96px}
.axe-band{position:absolute;background:linear-gradient(180deg,rgba(247,168,60,.42),rgba(232,152,52,.2))}
.axe-meter.line .axe-band{top:0;bottom:0}
.axe-meter.rise .axe-band{left:0;right:0}
.axe-marker{position:absolute;background:var(--frost-100);box-shadow:0 0 12px rgba(255,214,120,.95)}
.axe-meter.line .axe-marker{top:-2px;bottom:-2px;width:4px;margin-left:-2px;left:50%}
.axe-meter.rise .axe-marker{left:-2px;right:-2px;height:4px;margin-bottom:-2px;bottom:50%}
.axe-meter.locked{opacity:.62;border-color:var(--vital-500)}
.axe-meter.locked .axe-marker{background:var(--vital-400);box-shadow:0 0 10px rgba(95,194,168,.9)}

.axe-tally{list-style:none;display:flex;flex-direction:column;gap:2px}
.axe-tally li{
  display:grid;grid-template-columns:auto 1fr auto;gap:var(--sp-3);align-items:baseline;
  font-size:14px;color:var(--frost-200);padding:5px 0;
  border-bottom:1px dashed rgba(51,69,106,.5);
}
.axe-tally li.miss{color:var(--frost-300)}
.axe-tally li.miss b{color:var(--blood-400)}
.axe-tally .axe-where{font-style:italic;color:var(--frost-300);font-size:12.5px;text-align:end}
.axe-tally b{font-family:var(--font-display);color:var(--forge-300);min-width:1.4em;text-align:end}
.axe-tally .axe-total{border-bottom:none;border-top:1px solid var(--night-400);margin-top:4px;padding-top:8px}
.axe-tally .axe-total b{font-size:19px}

@media (max-width:900px){
  .axe-round{grid-template-columns:1fr}
}

/* ══ ADMIN ════════════════════════════════════════════
   Deliberately unlike the rest of the interface. Everything else in this game
   is cold blue; the admin panel is amber and dashed, because the one failure
   mode that matters here is forgetting you're in it and drawing conclusions
   from a run where you gave yourself gold.                                   */
.admin-panel{border-color:var(--coin-500);border-style:dashed}

/* The admin escape hatch. Amber and dashed like every other admin control, so
   it never reads as part of the game — you should not be able to mistake it for
   something a player has. Absolute rather than fixed: it belongs to the screen
   it can leave, not to the window. */
.admin-bail{
  position:absolute;left:10px;top:10px;z-index:40;
  display:inline-flex;align-items:center;gap:7px;
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.06em;
  color:var(--coin-500);background:rgba(5,8,15,.8);
  border:1px dashed var(--coin-500);border-radius:99px;padding:6px 12px;cursor:pointer;
  transition:background var(--t-fast) ease,color var(--t-fast) ease;
}
.admin-bail:hover{background:rgba(216,166,74,.14)}
.admin-bail .key{opacity:.75}
.game-exit-row{display:flex;justify-content:flex-end;min-height:32px;margin-bottom:var(--sp-2)}
.game-exit-row .admin-bail{position:static}
.game-exit-button{white-space:nowrap}
.game-forfeit{
  display:inline-flex;align-items:center;
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.06em;
  color:var(--blood-400);background:rgba(5,8,15,.78);
  border:1px solid rgba(202,75,64,.58);border-radius:99px;padding:6px 12px;cursor:pointer;
  transition:background var(--t-fast) ease,color var(--t-fast) ease,border-color var(--t-fast) ease;
}
.game-forfeit:hover{background:rgba(202,75,64,.12);border-color:var(--blood-400)}
.game-forfeit.armed{color:var(--frost-100);background:rgba(134,31,31,.76);border-color:#e06054}
.combat,.riddle-bg{position:relative}
.admin-panel .panel-h{color:var(--coin-500);letter-spacing:.2em}
.admin-body{display:flex;flex-direction:column;gap:var(--sp-3);padding:var(--sp-4)}
.admin-note{font-size:12.5px;color:var(--frost-300);font-style:italic;line-height:1.5}
.admin-select{
  width:100%;background:var(--night-800);border:1px solid var(--night-400);border-radius:var(--r-sm);
  color:var(--frost-100);font-family:var(--font-display);font-size:14px;padding:9px var(--sp-3);
}
.admin-select:focus{outline:none;border-color:var(--coin-500)}
.admin-tools{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.admin-panel .toggle{border-color:rgba(216,180,95,.5);color:var(--coin-500)}
.admin-panel .toggle.on{background:rgba(216,180,95,.16);border-color:var(--coin-500)}
.admin-off{width:100%;margin-top:var(--sp-2)}
.admin-hint{opacity:.45;font-size:12px}
.admin-hint code{
  font-family:var(--font-ui);font-size:11px;letter-spacing:.08em;
  background:rgba(216,180,95,.12);border:1px solid rgba(216,180,95,.35);
  border-radius:3px;padding:1px 6px;color:var(--coin-500);
}
/* The badge in the topbar. It is not subtle on purpose. */
.tb-admin{
  font-family:var(--font-ui);font-size:9.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:#0d1220;background:var(--coin-500);border-radius:3px;padding:3px 8px;margin-inline-start:var(--sp-3);
}

/* ══ COMBAT ═══════════════════════════════════════════
   Enemies across the top, dice in the middle, you and the log along the bottom.

   The portraits are square frames because the art is square busts. Frames also
   keep the row legible while half the bestiary is still on emoji — the box is
   the same size either way, so a finished wolf and an unfinished cyclops don't
   look like different games.                                                  */
.combat{position:relative}
.combat-scene{
  position:relative;overflow:hidden;
  border:1px solid var(--night-400);border-top-left-radius:var(--r-md);border-top-right-radius:var(--r-md);
  background:
    radial-gradient(ellipse at 50% 12%,rgba(139,95,196,.22),transparent 58%),
    radial-gradient(ellipse at 50% 96%,rgba(111,182,232,.16),transparent 55%),
    linear-gradient(180deg,#101a2e,#070b14);
  padding:var(--sp-5) var(--sp-4) var(--sp-4);
}
/* The stage's own background, set per node as --scene.
   Dimmed and softened rather than shown at full strength: everything that
   matters in a fight — health, dice, trait chips — is small text sitting on top
   of it, and a painting at full contrast underneath makes all of that unreadable.
   The blur is light, enough to push it back without turning it to soup. */
.combat-scene.has-art::before{
  content:"";position:absolute;inset:-14px;z-index:0;pointer-events:none;
  background:var(--scene) center 42%/cover no-repeat;
  opacity:.62;filter:blur(1.5px) saturate(.94) brightness(.82);
}
/* And a vignette over the top of it, so the corners stay dark where the
   nameplates live. */
.combat-scene.has-art::after{
  content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  box-shadow:inset 0 0 120px 24px rgba(5,8,15,.92);
}
.combat-scene > *{position:relative;z-index:1}
/* With the stage's painting behind the whole page, the scene panel stops being
   a picture frame and becomes a window: no background of its own, just the
   border that keeps the fight, the log and the buttons reading as one object. */
body.art-mode .combat-scene{background:rgba(5,8,15,.18);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
body.art-mode .combat-bottom{background:rgba(13,19,33,.62);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
body.art-mode .actions{background:linear-gradient(180deg,rgba(13,19,33,.66),rgba(5,8,15,.82));backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}

.enemy-row{display:flex;gap:var(--sp-6);justify-content:center;flex-wrap:wrap;align-items:flex-start}
.enemy{width:210px;text-align:center;background:none;border:0;padding:0;font:inherit;color:inherit}
.enemy.selectable{cursor:pointer}
.enemy.selectable .portrait{border-color:var(--ice-700)}
.enemy.selectable:hover .portrait,.enemy.selectable:focus-visible .portrait{
  border-color:var(--ice-400);box-shadow:0 0 20px rgba(111,182,232,.55);transform:translateY(-3px);
}
.enemy.active .portrait{border-color:var(--blood-500);box-shadow:0 0 18px rgba(184,55,47,.45)}
.enemy.dead{opacity:.28;filter:grayscale(1)}
.enemy.dead .hb-name{text-decoration:line-through}
.enemy:focus-visible{outline:none}
.trait.key-hint{border-color:var(--ice-700);color:var(--ice-500)}
/* Names sit under a painting now rather than under an emoji, so they need a
   plate of their own to stay readable. */
.enemy .hb-row{text-shadow:0 1px 3px rgba(5,8,15,.95)}

.targeting-hint{
  text-align:center;font-family:var(--font-ui);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ice-500);margin-top:var(--sp-4);min-height:16px;
  text-shadow:0 1px 4px rgba(5,8,15,.9);
}

/* — the centre stage: dice, meter, math — */
.stage-centre{min-height:210px;display:grid;place-items:center;padding:var(--sp-4) 0 var(--sp-2)}
.centre-quiet{
  font-family:var(--font-display);font-style:italic;font-size:15px;
  color:var(--frost-300);text-align:center;max-width:52ch;
  text-shadow:0 1px 4px rgba(5,8,15,.9);
}
.die-label{font-family:var(--font-ui);font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--frost-300);margin-bottom:8px;text-align:center}
/* — Whose roll is this? —
   Three agreeing signals: a face, a colour, and a direction of travel. The
   block rises from below when it is yours and drops from above when it is
   theirs, matching where those combatants stand on the screen. */
.roll-block.mine{animation:rollFromBelow 320ms cubic-bezier(.2,.9,.3,1)}
.roll-block.theirs{animation:rollFromAbove 320ms cubic-bezier(.2,.9,.3,1)}
@keyframes rollFromBelow{from{transform:translateY(26px);opacity:0}to{transform:none;opacity:1}}
@keyframes rollFromAbove{from{transform:translateY(-26px);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){
  .roll-block.mine,.roll-block.theirs{animation:none}
}
.roll-who{
  display:flex;align-items:center;justify-content:center;gap:var(--sp-3);
  margin-bottom:var(--sp-3);
}
.roll-who .die-label{margin-bottom:0}
.portrait.xs{width:42px;height:42px;font-size:20px;margin:0;border-width:1px;flex:none}
.roll-block.mine .portrait.xs{border-color:var(--ice-500);box-shadow:0 0 12px rgba(111,182,232,.5)}
.roll-block.theirs .portrait.xs{border-color:var(--shadow-500,#8b5fc4);box-shadow:0 0 12px rgba(139,95,196,.55)}
.roll-block.mine .die-label{color:var(--ice-500)}
.roll-block.theirs .die-label{color:var(--shadow-400,#b18ce0)}

.die{
  width:78px;height:78px;margin:0 auto;display:grid;place-items:center;
  font-family:var(--font-display);font-size:30px;font-weight:700;color:var(--ice-500);
  background:linear-gradient(160deg,#1d2c46,#0b1120);border:2px solid var(--ice-700);
  clip-path:polygon(50% 0,93% 25%,93% 75%,50% 100%,7% 75%,7% 25%);box-shadow:var(--glow-ice);
}
/* Violet is already the language for the other side of a fight — enemy health
   bars, the Shadow, his magic. A die that arrives in it needs no legend. */
.roll-block.theirs .die{
  color:var(--shadow-400,#b18ce0);border-color:var(--shadow-500,#8b5fc4);
  background:linear-gradient(160deg,#2a1f42,#120b1e);
  box-shadow:0 0 22px rgba(139,95,196,.55);
}
.die.rolling{animation:tumble 600ms cubic-bezier(.3,.9,.4,1)}
.die.crit,.roll-block.theirs .die.crit{color:var(--ice-400);border-color:var(--ice-400);box-shadow:0 0 30px rgba(168,220,255,.85)}
.die.fumble,.roll-block.theirs .die.fumble{color:var(--blood-500);border-color:var(--blood-500);box-shadow:0 0 20px rgba(184,55,47,.55)}
@keyframes tumble{
  0%{transform:rotate(0) scale(.5);opacity:.4}
  40%{transform:rotate(320deg) scale(1.18)}
  70%{transform:rotate(560deg) scale(.94)}
  100%{transform:rotate(720deg) scale(1)}
}
.roll-math{font-family:var(--font-display);font-size:16px;letter-spacing:.03em;margin-top:var(--sp-3);color:var(--frost-200);text-align:center;min-height:24px;text-shadow:0 1px 4px rgba(5,8,15,.9)}
.roll-math .hit{color:var(--vital-400)}
.roll-math .miss{color:var(--frost-300)}
.roll-math .crit{color:var(--ice-400)}
.roll-math .fumble{color:var(--blood-400)}
.roll-dmg{font-family:var(--font-display);font-size:14px;color:var(--frost-300);margin-top:5px;text-align:center;min-height:20px;text-shadow:0 1px 4px rgba(5,8,15,.9)}
.roll-dmg b{color:var(--frost-100)}

/* — Strike meter (attack skill) —
   The one warm thing in a cold game, and the exception is the point.

   Everything else on this screen is blue-black: the backdrop, the panels, the
   dice, the health bars, the enemy's own portrait lighting. A blue sweet spot
   sat inside all of that and had to be hunted for. Warm forge-orange has
   nothing to compete with, so the eye finds it before it has finished looking —
   which is exactly what a mechanic measured in tenths of a second needs.

   It also says something true: the meter is the one place the game is asking
   *you* for something rather than showing you a number. Heat marks agency.
   (`03_VISUAL_STYLE.md §2.2` — the second and last warm exception, after the
   coin count.) */
.meter-wrap{width:min(560px,90%);text-align:center}
.meter-prompt{
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--forge-400);margin-bottom:var(--sp-3);
}
.meter-prompt .kbd{
  display:inline-block;border:1px solid var(--forge-500);border-radius:3px;padding:1px 8px;margin:0 4px;
  font-size:10px;letter-spacing:.1em;
}
.meter{
  position:relative;height:38px;background:var(--night-900);
  border:1px solid var(--night-400);border-radius:var(--r-sm);overflow:hidden;
}
.meter .zone{position:absolute;top:0;bottom:0}
/* Cool at the edges, hot in the middle — the gradient itself tells you which
   way is better, before you have read a single label. */
.meter .zone.fair{background:rgba(216,140,60,.14)}
.meter .zone.good{background:rgba(232,152,52,.36)}
.meter .zone.perfect{
  background:linear-gradient(180deg,rgba(255,214,120,.95),rgba(240,150,44,.75));
  box-shadow:0 0 22px rgba(247,168,60,.75);
}
.meter .marker{
  position:absolute;top:-3px;bottom:-3px;width:4px;margin-left:-2px;
  background:var(--frost-100);box-shadow:0 0 10px rgba(230,241,251,.95);border-radius:2px;
}
/* Locked on the sweet spot: the marker goes white-hot rather than ice. */
.meter.locked .marker{background:#fff3d0;box-shadow:0 0 18px rgba(255,214,120,1),0 0 6px #fff}
.meter-scale{
  display:flex;justify-content:space-between;margin-top:6px;
  font-family:var(--font-ui);font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--frost-300);
}
.meter-result{
  font-family:var(--font-display);font-size:22px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  margin-top:var(--sp-3);min-height:28px;
}
.meter-result.perfect{color:var(--forge-300);text-shadow:0 0 20px rgba(247,168,60,.7)}
.meter-result.good{color:var(--forge-400)}
.meter-result.fair{color:var(--frost-200)}
.meter-result.weak{color:var(--blood-400)}

/* — Parry ring (defense skill) — */
.parry-wrap{text-align:center}
.parry-ring{position:relative;width:150px;height:150px;margin:0 auto}
.parry-ring .target{
  position:absolute;inset:50px;border:2px dashed var(--vital-400);border-radius:50%;opacity:.85;
}
.parry-ring .band{
  position:absolute;inset:38px;border:1px solid rgba(95,194,168,.35);border-radius:50%;
}
.parry-ring .incoming{
  position:absolute;left:50%;top:50%;border:3px solid var(--blood-400);border-radius:50%;
  transform:translate(-50%,-50%);box-shadow:0 0 20px rgba(224,90,74,.55);
}
.parry-ring .glyph{
  position:absolute;inset:0;display:grid;place-items:center;font-size:34px;opacity:.85;
}
.parry-wrap.perfect .target{border-color:var(--ice-400);box-shadow:0 0 26px rgba(168,220,255,.75)}

/* — The pack (consumables in combat) — */
.pack{text-align:center}
.pack-row{display:flex;gap:var(--sp-3);justify-content:center;flex-wrap:wrap;margin-top:var(--sp-2)}
.pack-item{
  position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;
  width:150px;padding:var(--sp-3);background:var(--night-600);
  border:1px solid var(--night-400);border-radius:var(--r-sm);cursor:pointer;font:inherit;color:inherit;
  transition:transform var(--t-fast) ease-out,border-color var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.pack-item:hover:not(:disabled){border-color:var(--ice-500);transform:translateY(-2px);box-shadow:var(--glow-ice)}
.pack-item:disabled{opacity:.4;cursor:not-allowed}
.pack-item:focus-visible{outline:2px solid var(--ice-400);outline-offset:2px}
.pack-item .ico{font-size:24px}
.pack-item .nm{font-family:var(--font-display);font-size:12.5px;font-weight:600}
.pack-item .st{font-family:var(--font-ui);font-size:10px;color:var(--frost-300)}
.pack-item .qty{
  position:absolute;top:5px;inset-inline-end:8px;
  font-family:var(--font-ui);font-size:10px;font-weight:600;color:var(--frost-300);
}

/* — Bottom: your side on the left, the log on the right — */
.combat-bottom{
  display:grid;grid-template-columns:1fr 1.15fr;gap:var(--sp-4);
  border:1px solid var(--night-400);border-top:none;background:var(--night-800);padding:var(--sp-4);
}
.party{display:flex;flex-direction:column;gap:var(--sp-3);padding:var(--sp-4)}
.party-row{display:flex;align-items:center;gap:var(--sp-3)}
.party-row .bars{flex:1;min-width:0}
.party-row .portrait{flex:none}
.party-row.dead{opacity:.4}
.party-row.dead .hb-name{text-decoration:line-through}
.party-row.turn .portrait{border-color:var(--ice-500);box-shadow:var(--glow-ice)}
.party-row.warded .portrait{border-color:var(--steel-500);box-shadow:0 0 14px rgba(125,147,173,.6)}
.party-tags{display:flex;gap:5px;margin-top:5px;flex-wrap:wrap}
.party-tags .trait{font-size:8.5px;padding:2px 6px}
.party-tags .trait.cover{border-color:var(--steel-500);color:var(--steel-500)}
.tag-fallen{font-family:var(--font-ui);font-size:9px;letter-spacing:.14em;color:var(--blood-500);font-weight:600}
.log{padding:var(--sp-3) var(--sp-4);font-size:14.5px;color:var(--frost-200);height:196px;overflow-y:auto;scroll-behavior:smooth}
.log .round{font-family:var(--font-ui);font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--ice-500);margin:var(--sp-3) 0 5px;font-weight:600}
.log p{padding:3px 0;border-bottom:1px dashed rgba(51,69,106,.5)}
.log p:last-child{border:none}
.log .out{color:var(--frost-100)}
.log .in{color:var(--blood-400)}
.log .good{color:var(--vital-400)}
.log .gold{color:var(--ice-400)}

/* The action bar sticks to the bottom of the window.

   `position: sticky` rather than `fixed`: it only pins while the fight is on
   screen, and settles back into the panel stack at the end of it — so it never
   floats over the results screen or leaves a gap under the last panel. On a
   window tall enough to show the whole fight it behaves exactly as before.

   The buttons are the only thing here with a keyboard shortcut *and* a time
   limit, so having to scroll to find out what your options were was the worst
   possible thing to hide. */
.actions{
  position:sticky;bottom:0;z-index:20;
  display:flex;gap:var(--sp-3);justify-content:center;padding:var(--sp-4);
  border:1px solid var(--night-400);border-top:none;
  border-bottom-left-radius:var(--r-md);border-bottom-right-radius:var(--r-md);
  background:linear-gradient(180deg,var(--night-800),#070b14);flex-wrap:wrap;
  box-shadow:0 -14px 28px rgba(5,8,15,.6);
}
/* The page ends flush with the bar, so nothing hides behind it at full scroll. */
.combat{padding-bottom:0}

/* — Floating damage numbers — */
.float-dmg{
  position:absolute;font-family:var(--font-display);font-weight:700;font-size:30px;
  pointer-events:none;z-index:500;animation:floatUp 900ms ease-out forwards;text-shadow:0 2px 8px #000;
}
.float-dmg.taken{color:var(--blood-400)}
.float-dmg.dealt{color:var(--frost-100)}
.float-dmg.critical{color:var(--ice-400);font-size:42px}
/* Same size, opposite meaning: a critical against you is not a celebration. */
.float-dmg.critical-taken{color:var(--blood-400);font-size:42px}
.float-dmg.blocked{color:var(--steel-500);font-size:22px}
@keyframes floatUp{from{opacity:1;transform:translate(-50%,0)}to{opacity:0;transform:translate(-50%,-46px)}}

.screen-flash{
  position:fixed;inset:0;pointer-events:none;z-index:700;opacity:0;
  box-shadow:inset 0 0 140px rgba(168,220,255,.75);animation:flash 380ms ease-out;
}
.screen-flash.blood{box-shadow:inset 0 0 140px rgba(184,55,47,.6)}
@keyframes flash{0%{opacity:.9}100%{opacity:0}}

/* ══ PLACES ═══════════════════════════════════════════
   A painted room gets its own band at full brightness, with the name burned
   into the bottom of it. Using one of these as wallpaper behind a whole screen
   was tempting and wrong — they are busy in the middle, which is exactly where
   prices and health numbers go.                                              */
.place-hero{
  position:relative;overflow:hidden;
  height:clamp(150px,22vh,230px);margin-bottom:var(--sp-4);
  border-radius:var(--r-md);border:1px solid var(--night-400);
  background:radial-gradient(ellipse at 50% 120%,rgba(111,182,232,.28),rgba(40,52,80,.2) 55%,transparent 70%),
             linear-gradient(180deg,#141d33,#080d18);
  display:flex;align-items:flex-end;
  box-shadow:0 10px 34px rgba(0,0,0,.55);
}
.place-hero.has-art::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:var(--scene) center 46%/cover no-repeat;
}
/* Fade the bottom into the page so the title sits on darkness, not on a
   lantern. */
.place-hero::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(5,8,15,.15) 0%,rgba(5,8,15,0) 34%,rgba(5,8,15,.9) 100%);
  box-shadow:inset 0 0 90px 12px rgba(5,8,15,.7);
}
.place-hero-text{position:relative;z-index:2;padding:var(--sp-4) var(--sp-5)}
.place-hero-text h1{
  font-family:var(--font-display);font-size:clamp(22px,3.4vw,34px);font-weight:700;
  letter-spacing:.06em;color:var(--frost-100);margin:2px 0 0;
  text-shadow:0 2px 14px rgba(5,8,15,.95);
}
.place-hero-text .kicker{text-shadow:0 2px 10px rgba(5,8,15,.95)}
/* The no-box variant, for when the room is already behind the whole page. */
.place-title{padding:var(--sp-3) var(--sp-2) var(--sp-5)}
.place-title h1{
  font-family:var(--font-display);font-size:clamp(24px,3.6vw,36px);font-weight:700;
  letter-spacing:.06em;color:var(--frost-100);margin:4px 0 0;text-transform:none;
  text-shadow:0 2px 16px rgba(5,8,15,.95);
}

/* ══ TAVERN ═══════════════════════════════════════════ */
.tav-grid{display:grid;grid-template-columns:1fr 1.15fr 1.25fr;gap:var(--sp-4);align-items:start}
.tav-grid > .panel{display:flex;flex-direction:column;min-height:300px}
.svc{padding:var(--sp-4);flex:1}
.svc-item{
  display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);
  padding:10px 0;border-bottom:1px dashed var(--night-500);
}
.svc-item:last-child{border:none}
.svc-item .nm{font-size:15.5px}
.eff{display:block;font-family:var(--font-ui);font-size:10.5px;color:var(--frost-300);letter-spacing:.04em;margin-top:2px}
.eff-inline{font-family:var(--font-ui);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--frost-300)}
.blurb{font-size:13.5px;font-style:italic;color:var(--frost-300);margin-top:4px;line-height:1.45}
.hire{
  display:flex;gap:var(--sp-3);align-items:center;
  padding:11px 0;border-bottom:1px dashed var(--night-500);
}
.hire:last-child{border:none}
.hire .btn{flex:none}
.hire.is-downed{opacity:.6}
.hire-card{align-items:flex-start}
.hire-card .btn{margin-top:4px}

/* ══ WAREHOUSE ════════════════════════════════════════ */
.wh-head{
  display:flex;align-items:center;gap:var(--sp-5);padding:var(--sp-4) var(--sp-5);margin-bottom:var(--sp-4);
}
.wh-head-art{
  width:74px;height:74px;flex:none;border-radius:var(--r-md);border:2px solid var(--night-400);
  display:grid;place-items:center;font-size:36px;
  background:radial-gradient(circle at 50% 35%,#24344f,#0c1220);
}
.wh-head h2{margin:4px 0}
.wh-head .q-desc{max-width:64ch;min-height:1.5em}
.wh-head .btn{margin-inline-start:auto;flex:none}

.wh-grid{display:grid;grid-template-columns:1fr 290px 1fr;gap:var(--sp-4);align-items:stretch}
.wh-grid > .panel{display:flex;flex-direction:column;min-height:480px}

.items{
  display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-3);
  padding:var(--sp-4);align-content:start;flex:1;
}
.item{
  position:relative;display:flex;flex-direction:column;gap:2px;text-align:start;
  background:var(--night-600);border:1px solid var(--night-400);border-radius:var(--r-sm);
  padding:var(--sp-3);cursor:pointer;font:inherit;color:inherit;
  transition:transform var(--t-fast) ease-out,border-color var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.item:hover{border-color:var(--ice-500);transform:translateY(-2px);box-shadow:var(--shadow-card)}
.item:focus-visible{outline:2px solid var(--ice-400);outline-offset:2px}
.item.sel{border-color:var(--ice-400);box-shadow:var(--glow-ice)}
.item.equipped{border-color:var(--ice-700)}
.item.poor{opacity:.55}
.item.poor .pr{color:var(--blood-400)}
.item .ico{font-size:26px;text-align:center;margin-bottom:4px}
.item .nm{font-family:var(--font-display);font-size:12.5px;font-weight:600;line-height:1.25}
.item .st{font-family:var(--font-ui);font-size:10px;color:var(--frost-300)}
.item .mods{display:flex;flex-direction:column;gap:1px;margin-top:3px}
.item .mod{font-family:var(--font-ui);font-size:10px;font-weight:600}
.mod.atk{color:var(--stat-atk)}
.mod.def{color:var(--stat-def)}
.mod.hp{color:var(--vital-400)}
.item .pr{font-family:var(--font-display);font-size:12.5px;font-weight:700;color:var(--ice-500);margin-top:6px}
.item .ribbon{
  position:absolute;top:-1px;inset-inline-end:-1px;background:var(--ice-500);color:var(--night-900);
  font-family:var(--font-ui);font-size:8px;font-weight:600;letter-spacing:.1em;
  padding:2px 6px;border-radius:0 var(--r-sm) 0 var(--r-sm);
}
.item .qty{
  position:absolute;top:6px;inset-inline-start:8px;font-family:var(--font-ui);
  font-size:10px;font-weight:600;color:var(--frost-300);
}
.empty-note{padding:var(--sp-5) var(--sp-3);grid-column:1/-1;text-align:center;font-style:italic;font-size:15px}
/* Buy and Sell stick to the bottom of the window while their column is on
   screen. The stock lists are long and the button that acts on your selection
   was falling below the fold — you could pick a sword and then have to go
   looking for the way to pay for it. */
.wh-foot{
  position:sticky;bottom:0;z-index:5;
  padding:var(--sp-3) var(--sp-4) var(--sp-4);min-height:62px;
  background:linear-gradient(180deg,rgba(13,19,33,0),var(--night-700) 38%);
  border-bottom-left-radius:var(--r-md);border-bottom-right-radius:var(--r-md);
}
body.art-mode .wh-foot{background:linear-gradient(180deg,rgba(13,19,33,0),rgba(13,19,33,.92) 38%)}
.hint-line{font-size:13.5px;font-style:italic;text-align:center;padding-top:var(--sp-2)}

.equip-col{display:flex;flex-direction:column;padding:0}
.equip-h{border-bottom:1px solid var(--night-500)}
.slots{display:flex;flex-direction:column;gap:var(--sp-2);padding:var(--sp-4)}
.slot{
  display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3);
  background:var(--night-600);border:1px solid var(--night-400);border-radius:var(--r-sm);
  transition:border-color var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.slot.empty{opacity:.55}
.slot.target{border-color:var(--ice-500);box-shadow:var(--glow-ice);opacity:1}
.slot .s-ico{font-size:20px;width:26px;text-align:center;flex:none}
.slot .s-body{display:flex;flex-direction:column;flex:1;min-width:0}
.slot .s-lbl{font-family:var(--font-ui);font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--frost-300)}
.slot .s-val{font-family:var(--font-display);font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.slot .s-off{
  flex:none;background:transparent;border:1px solid var(--night-400);border-radius:3px;
  color:var(--frost-300);cursor:pointer;font-size:11px;line-height:1;padding:4px 6px;
  transition:all var(--t-fast) ease-out;
}
.slot .s-off:hover{border-color:var(--blood-500);color:var(--blood-400)}

.totals{border-top:1px solid var(--night-500);padding:var(--sp-3) var(--sp-4);margin-top:auto}
.tot-row{display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);padding:6px 0}
.tot-row .k{font-family:var(--font-ui);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--frost-300)}
.tot-row .v{font-family:var(--font-display);font-size:15px;font-weight:600;text-align:end}
.tot-row .preview{color:var(--ice-400)}
.tot-row .delta{font-family:var(--font-ui);font-size:10px;font-weight:600;margin-inline-start:5px}
.tot-row .delta.up{color:var(--vital-400)}
.tot-row .delta.down{color:var(--blood-400)}

/* ══ VELLUM SURFACES (riddle · story · choice) ════════ */

/* The one place in the game that goes light. Long text is easier dark-on-light,
   and the contrast makes these screens feel like a different kind of moment. */
.riddle-bg{
  border-radius:var(--r-md);border:1px solid var(--night-400);
  padding:var(--sp-7) var(--sp-5);
  background:
    radial-gradient(ellipse at 50% 35%,rgba(139,95,196,.20),transparent 62%),
    linear-gradient(180deg,#141026,#080b14);
  box-shadow:inset 0 0 90px rgba(0,0,0,.85);
}
.riddle-sheet{
  max-width:680px;margin:0 auto;padding:var(--sp-6) var(--sp-7);
  background:linear-gradient(160deg,var(--vellum),var(--vellum-sh));
  color:var(--vellum-ink);border-radius:2px;
  box-shadow:var(--shadow-panel);transform:rotate(-.35deg);
  position:relative;
}
.riddle-sheet::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:2px;
  box-shadow:inset 0 0 46px rgba(60,80,110,.35);
}
.riddle-kicker{
  font-family:var(--font-ui);font-size:9.5px;font-weight:600;letter-spacing:.18em;
  text-transform:uppercase;color:#5a7391;
}
.riddle-title{
  font-family:var(--font-display);font-size:22px;font-weight:600;letter-spacing:.06em;
  color:#24354d;margin:6px 0 var(--sp-4);
}
.riddle-scene{font-style:italic;color:#3c5573;font-size:16px;line-height:1.6;margin-bottom:var(--sp-4)}
.riddle-prompt{font-size:18px;line-height:1.75;margin-bottom:var(--sp-5)}
.riddle-prompt .para,.riddle-scene .para{display:block}
.riddle-prompt .para + .para,.riddle-scene .para + .para{margin-top:.85em}
.riddle-prompt strong{font-weight:600;color:#12253d}

.choices{display:flex;flex-direction:column;gap:var(--sp-2)}
.choice{
  display:flex;align-items:center;gap:var(--sp-3);width:100%;text-align:start;
  padding:11px var(--sp-3);border:1px solid rgba(90,115,145,.4);border-radius:var(--r-sm);
  background:transparent;cursor:pointer;font:inherit;font-size:16.5px;color:inherit;
  transition:background var(--t-fast) ease-out,border-color var(--t-fast) ease-out;
}
.choice:hover:not(.spent){background:rgba(90,115,145,.12);border-color:rgba(90,115,145,.8)}
.choice:focus-visible{outline:2px solid var(--shadow-500);outline-offset:2px}
.choice .mark{
  width:14px;height:14px;border-radius:50%;border:1.5px solid #5a7391;flex:none;
  transition:background var(--t-fast) ease-out;
}
.choice.sel{background:rgba(139,95,196,.16);border-color:var(--shadow-500)}
.choice.sel .mark{background:var(--shadow-500);border-color:var(--shadow-500)}
.choice.spent{opacity:.42;text-decoration:line-through;cursor:not-allowed}

.riddle-hint{
  margin-top:var(--sp-4);padding:var(--sp-3);border-inline-start:3px solid var(--shadow-500);
  background:rgba(139,95,196,.10);font-style:italic;font-size:15.5px;color:#33475f;
}
.riddle-foot{
  display:flex;justify-content:space-between;align-items:center;gap:var(--sp-3);flex-wrap:wrap;
  margin-top:var(--sp-5);padding-top:var(--sp-4);border-top:1px dashed rgba(90,115,145,.45);
}
.attempts{font-family:var(--font-ui);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#5a7391;font-weight:600}
.pip{display:inline-block;width:9px;height:9px;border-radius:50%;border:1.5px solid #5a7391;margin-inline-start:5px;vertical-align:middle}
.pip.used{background:var(--blood-500);border-color:var(--blood-500)}
.riddle-actions{display:flex;gap:10px}
.btn-ink{
  background:transparent;border:1px solid #5a7391;color:#33475f;
  font-family:var(--font-display);font-size:11px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;padding:8px 15px;border-radius:var(--r-sm);cursor:pointer;
  transition:background var(--t-fast) ease-out,opacity var(--t-fast) ease-out;
}
.btn-ink:hover:not(:disabled){background:rgba(90,115,145,.16)}
.btn-ink:disabled{opacity:.4;cursor:not-allowed}
.btn-ink.solid{background:#33475f;color:var(--vellum);border-color:#33475f}
.btn-ink.solid:hover:not(:disabled){background:#24354d}
.note{font-size:14.5px;color:var(--frost-300);font-style:italic;text-align:center;margin-top:var(--sp-5)}
.note .wrong{color:var(--blood-400);font-style:normal;font-weight:600}

/* ══ STORY ════════════════════════════════════════════ */
.story-bg{
  border-radius:var(--r-md);border:1px solid var(--night-400);padding:var(--sp-7) var(--sp-5);
  background:
    radial-gradient(ellipse at 50% 20%,rgba(111,182,232,.16),transparent 60%),
    linear-gradient(180deg,#0e1728,#070b14);
  box-shadow:inset 0 0 90px rgba(0,0,0,.8);
}
.story-sheet{max-width:660px;margin:0 auto;text-align:center}
.story-art{font-size:56px;line-height:1;margin-bottom:var(--sp-4);filter:drop-shadow(0 0 22px rgba(111,182,232,.35))}
.story-art.story-portrait{
  width:104px;height:104px;margin:0 auto var(--sp-4);overflow:hidden;
  border:2px solid var(--night-400);border-radius:var(--r-md);
  background:var(--night-800);box-shadow:var(--shadow-card),0 0 24px rgba(111,182,232,.18);
  filter:none;
}
.story-art.story-portrait img{width:100%;height:100%;display:block;object-fit:cover}
.story-sheet h2{font-family:var(--font-display);font-size:26px;margin-bottom:var(--sp-5);color:var(--frost-100)}
.story-lines{text-align:start;max-width:62ch;margin:0 auto var(--sp-6)}
.story-lines p{margin-bottom:1.1em;font-size:17.5px;line-height:1.75;color:var(--frost-200)}
.story-lines p.speech{color:var(--frost-100);font-style:italic}
.story-lines p:last-child{margin-bottom:0}

/* ══ CHOICE ═══════════════════════════════════════════ */
.choice-cards{display:grid;gap:var(--sp-3);margin-top:var(--sp-5)}
.choice-card{
  display:block;width:100%;text-align:start;padding:var(--sp-4);
  background:var(--night-700);border:1px solid var(--night-400);border-radius:var(--r-md);
  cursor:pointer;font:inherit;color:inherit;
  transition:transform var(--t-fast) ease-out,border-color var(--t-fast) ease-out,box-shadow var(--t-fast) ease-out;
}
.choice-card:hover:not(:disabled){border-color:var(--ice-500);transform:translateY(-2px);box-shadow:var(--glow-ice)}
.choice-card:disabled{opacity:.4;cursor:not-allowed}
.choice-card .cc-title{font-family:var(--font-display);font-size:17px;font-weight:600;color:var(--frost-100)}
.choice-card .cc-detail{font-size:15.5px;color:var(--frost-200);margin-top:5px;line-height:1.55}
.choice-card .cc-cost{
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;margin-top:var(--sp-3);display:flex;gap:var(--sp-4);flex-wrap:wrap;
}
.cc-cost .gold{color:var(--coin-500)}
.cc-cost .hp{color:var(--blood-400)}
.cc-cost .risk{color:var(--shadow-400)}
.cc-cost .none{color:var(--frost-300)}
.saved-count{
  font-family:var(--font-display);font-size:44px;font-weight:700;color:var(--vital-400);
  text-align:center;margin:var(--sp-4) 0;
}

/* ══ RESULTS ══════════════════════════════════════════ */
.results{min-height:60vh;display:grid;place-items:center;text-align:center;padding:var(--sp-8) var(--sp-5)}
.results-inner{max-width:560px;width:100%}
.results h1{font-size:40px;margin-bottom:var(--sp-3)}
.results.defeat h1{color:var(--blood-500)}
.results.defeat{filter:saturate(.35)}
.results .flavour{font-style:italic;color:var(--frost-200);margin-bottom:var(--sp-6);font-size:18px}
.rewards{display:flex;flex-direction:column;gap:var(--sp-2);margin-bottom:var(--sp-6)}
.reward-row{
  display:flex;justify-content:space-between;align-items:center;padding:11px var(--sp-4);
  background:var(--night-700);border:1px solid var(--night-400);border-radius:var(--r-sm);
  opacity:0;transform:translateY(6px);animation:rewardIn 280ms var(--ease) forwards;
}
@keyframes rewardIn{to{opacity:1;transform:none}}
.reward-row .k{font-family:var(--font-ui);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--frost-300)}
.reward-row .v{font-family:var(--font-display);font-size:18px;font-weight:700;color:var(--ice-500)}
.rule{height:1px;background:linear-gradient(90deg,transparent,var(--ice-700),transparent);margin:var(--sp-5) 0}
.results .solved{
  max-width:60ch;margin:0 auto;padding:var(--sp-4);
  background:var(--night-700);border:1px solid var(--night-400);border-inline-start:3px solid var(--ice-500);
  border-radius:var(--r-sm);font-size:16px;line-height:1.65;color:var(--frost-200);text-align:start;
}

/* ══ CREDITS ══════════════════════════════════════════ */
.credits{text-align:center;padding-bottom:var(--sp-8)}
.cover-sm{max-width:760px;margin:0 auto calc(var(--sp-7) * -1)}
.credits-inner{max-width:600px;margin:0 auto;position:relative;z-index:2}
.credits-inner h1{font-size:34px}
.credits-line{font-size:18px;color:var(--frost-200);line-height:1.7;margin-bottom:var(--sp-5)}
.credits-note{
  font-size:15.5px;font-style:italic;color:var(--frost-300);line-height:1.9;margin-bottom:var(--sp-6);
}
.reward-row .v.good{color:var(--vital-400)}
.reward-row .v.grim{color:var(--blood-400)}

/* ══ SETTINGS / misc ══════════════════════════════════ */
.settings-bar{display:flex;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-4);flex-wrap:wrap}

/* Difficulty. Three buttons, one row, on the title screen and on the map rail.
   Deliberately the same `.toggle` chrome as the other settings: this is a
   preference, not a class of run, and dressing it up as a bigger decision than
   that would make people afraid to change it when they are stuck. */
.diff-pick{display:flex;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-4)}
.diff-pick .toggle{min-width:6.5rem}
.diff-row{gap:var(--sp-2)}
.diff-row .toggle{padding-inline:0}

/* The save code. Shown in full and in the coin amber the game uses for money
   and admin — it is a ticket, not a password, and the player has to be able to
   read it off the screen and type it into a phone. */
.save-code{font-family:ui-monospace, "SF Mono", Menlo, monospace;font-size:1.05rem;letter-spacing:.14em;
  text-align:center;padding:var(--sp-3);border:1px dashed var(--coin-500);border-radius:var(--r-md);
  color:var(--coin-400);cursor:pointer;user-select:all}
.save-code:hover{background:rgba(216,169,74,.08)}
.code-row{display:flex;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-3);max-width:26rem;margin-inline:auto}
.code-row .name-field{margin:0;text-align:center;letter-spacing:.12em;text-transform:uppercase}
.code-row .btn{white-space:nowrap}
#codeNote{max-width:34rem;margin-inline:auto}

/* The three runs. A list rather than three cards side by side, because the
   metadata (name, level, region, when) is the whole point of the thing and a
   card wide enough to hold it is wider than a third of the panel. */
.slots{display:flex;flex-direction:column;gap:var(--sp-2);max-width:30rem;margin:var(--sp-4) auto 0}
.slot{display:flex;align-items:center;gap:var(--sp-3);
  border:1px solid var(--night-400);border-radius:var(--r-md);
  padding:var(--sp-2) var(--sp-3);background:rgba(10,18,30,.5)}
.slot-n{font-family:ui-monospace,Menlo,monospace;font-size:.8rem;color:var(--frost-300);
  min-width:1.1rem;text-align:center}
.slot-body{flex:1;display:flex;flex-direction:column;align-items:flex-start;gap:2px;
  background:none;border:0;padding:var(--sp-2) 0;text-align:left;color:inherit;font:inherit}
button.slot-body{cursor:pointer}
button.slot-body:hover .slot-name{color:var(--ice-400)}
.slot-name{font-family:var(--font-display);font-size:1rem;color:var(--frost-100)}
.slot-meta{font-size:.8rem;color:var(--frost-300)}
.slot-empty{font-size:.85rem;color:var(--frost-300);font-style:italic}
.slot.empty{opacity:.72}
.slot.broken .slot-empty{color:var(--blood-400)}

/* Choosing which run to write over. The list is the dialog. */
.slots.choosing .slot.pick{border-color:var(--coin-500);cursor:pointer}
.slots.choosing .slot.pick:hover{background:rgba(216,169,74,.1)}

/* The rerolled die, in the roll readout. Ice cyan, because it is your agency
   the same as a parry is — you chose the setting. */
.reroll{color:var(--ice-400);font-variant-numeric:tabular-nums;opacity:.9}
.toggle{
  font-family:var(--font-ui);font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--frost-300);background:transparent;border:1px solid var(--night-400);
  border-radius:99px;padding:6px 13px;cursor:pointer;transition:all var(--t-fast) ease-out;
}
.toggle:hover{border-color:var(--ice-700);color:var(--frost-200)}
.toggle.on{border-color:var(--ice-500);color:var(--ice-500)}

/* ══ Responsive ═══════════════════════════════════════ */
@media (max-width:1100px){
  .map-wrap{grid-template-columns:1fr}
  .map-frame{max-height:none}
  .map-hud{flex-wrap:wrap}
  /* Narrower screen, shorter figures — the ground line and the plates stay put,
     so a four-strong warband still fits on one row instead of wrapping. */
  .combat-bottom{grid-template-columns:1fr}
  .enemy{width:170px}
  .portrait.lg{width:140px;height:140px;font-size:56px}
  .wh-grid{grid-template-columns:1fr}
  .equip-col{order:-1}
  .tav-grid{grid-template-columns:1fr}
}


/* ══ CUTSCENE ═════════════════════════════════════════
   One clip, full bleed, with a skip. The still underneath is always drawn and
   the video fades in over it once it is genuinely playing — same contract as
   the opening, for the same reason: a refused autoplay or a slow start should
   leave a picture on screen, never a black rectangle. */
.cutscene{
  position:fixed;inset:0;z-index:60;background:#03050a;
  display:grid;place-items:center;overflow:hidden;
}
.cut-still,.cut-clip{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
}
.cut-clip{opacity:0;transition:opacity .7s ease}
.cut-clip.on{opacity:1}
/* A vignette, so a caption over a bright frame is still readable and so the
   edges of a 16:9 clip on a wider window do not read as a hard cut. */
.cut-veil{
  position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 200px 60px rgba(3,5,10,.9);
  background:linear-gradient(180deg,rgba(3,5,10,.35),transparent 22%,transparent 62%,rgba(3,5,10,.85));
}
.cut-caption{
  position:absolute;left:50%;bottom:11%;transform:translateX(-50%);
  max-width:min(46ch,86vw);margin:0;text-align:center;
  font-family:var(--font-display);font-size:clamp(17px,2.4vw,26px);line-height:1.4;
  color:var(--frost-100);text-shadow:0 2px 14px rgba(3,5,10,.95),0 1px 3px #000;
  animation:cutCaption 1.1s ease-out both .5s;
}
@keyframes cutCaption{from{opacity:0;transform:translate(-50%,12px)}to{opacity:1;transform:translate(-50%,0)}}
.cut-skip{
  position:absolute;right:18px;top:16px;
  font-family:var(--font-ui);font-size:11px;font-weight:600;letter-spacing:.08em;
  color:var(--frost-200);background:rgba(3,5,10,.6);border:1px solid rgba(51,69,106,.6);
  border-radius:99px;padding:7px 14px;cursor:pointer;
  transition:border-color var(--t-fast) ease,color var(--t-fast) ease;
}
.cut-skip:hover{border-color:var(--ice-500);color:var(--ice-400)}
.cut-skip .key{opacity:.7}
@media (prefers-reduced-motion:reduce){
  .cut-clip{transition:none}
  .cut-caption{animation:none}
}

/* ══ The Long Table ═══════════════════════════════════════
   A real board: two rows of twelve points, the bar down the middle, the tray
   on the right, home at the bottom right the way it is on a physical set.
   Column 7 is the bar and column 14 the tray, which is why the point columns
   skip a number halfway along. */
.bg-screen{max-width:64rem;margin:0 auto;padding:var(--sp-4)}
.bg-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);margin-bottom:var(--sp-3)}
.bg-who{display:flex;flex-direction:column;gap:2px}
.bg-who.mine{text-align:right}
.bg-name{font-family:var(--font-display);font-size:1.05rem;color:var(--frost-100)}
.bg-pip{font-size:.78rem;color:var(--frost-300);font-variant-numeric:tabular-nums}
.bg-dice{display:flex;gap:var(--sp-2)}
.bg-die{display:grid;place-items:center;width:2rem;height:2rem;border-radius:var(--r-sm);
  background:linear-gradient(145deg,#263951,#0b111c 68%);border:1px solid #7599b8;color:var(--frost-100);
  box-shadow:inset 0 0 0 2px rgba(5,8,15,.75),inset 0 1px 5px rgba(168,220,255,.22),0 3px 8px rgba(0,0,0,.65);
  text-shadow:0 0 7px rgba(168,220,255,.55);
  font-family:ui-monospace,Menlo,monospace;font-size:1.1rem}
.bg-die.spent{opacity:.28;border-color:var(--night-400)}

.bg-board{position:relative;display:grid;
  /* The painted board includes its own outer rails, centre bar and bear-off
     tray. These measurements follow the pixel geometry of the 1599×984
     painting: outer rail, six points, small hinge gap, bar, second hinge gap,
     six points, right rail, tray. The middle row is intentionally empty. */
  grid-template-columns:8.43% repeat(6,5.46%) 1.5% 4.9% .81% repeat(6,5.53%) 5.62% 12.8%;
  grid-template-rows:7% 33.5% 18.3% 37.2% 4%;gap:0;aspect-ratio:13/8;
  background:#070c13 url('../../assets/art/boards/backgammon-board-rimefells.png') center/100% 100% no-repeat;
  border:1px solid var(--night-400);border-radius:var(--r-md);padding:0;overflow:hidden;
  box-shadow:0 12px 34px rgba(0,0,0,.68)}

/* The route, across the dead middle of the board. Left along the top, right
   along the bottom, off at the bottom right — obvious to anyone who plays and
   invisible to everyone else, because the points are symmetrical and the
   numbers are tiny. */
.bg-flow{position:absolute;left:8.43%;right:18.42%;display:flex;align-items:center;justify-content:center;
  gap:.55rem;pointer-events:none;font-size:.7rem;color:var(--frost-300);opacity:.42;z-index:2}
.bg-flow.top{top:44.5%}
.bg-flow.bottom{bottom:43.5%}
.bg-chev{font-size:.62rem;line-height:1}
.bg-flow-label{letter-spacing:.09em;text-transform:uppercase;font-size:.6rem;white-space:nowrap}

/* The triangles are part of the painting. Earlier versions drew another set
   with pseudo-elements for legal-move highlighting; even a one-pixel scaling
   difference made the two boards visibly double. Interaction now lights the
   checker or the circular landing ghost, never redraws the board art. */
.bg-pt{position:relative;display:flex;flex-direction:column;align-items:center;padding:3px 0}
.bg-pt.bottom{flex-direction:column-reverse}
.bg-num{position:absolute;top:1px;right:3px;z-index:2;font-size:.62rem;color:var(--frost-300);opacity:.7}
.bg-pt.bottom .bg-num{top:auto;bottom:1px}
.bg-stack{position:relative;z-index:1;display:flex;flex-direction:inherit;align-items:center;gap:1px;width:100%}
/* The painted lower rail covers the final part of each triangle. The logical
   point continues underneath it, but a physical checker must stop at the
   rail's inner lip rather than sitting on the metalwork. */
.bg-pt.bottom .bg-stack{transform:translateY(-15px)}

.bg-chk{width:min(1.9rem,84%);aspect-ratio:1;border-radius:50%;flex:none}
.bg-chk.mine{background:radial-gradient(circle at 38% 30%,#e1f3ff 0 9%,#8fc6e7 32%,#416f92 68%,#172d42 100%);
  border:2px solid #93b9d4;box-shadow:inset 0 0 0 2px rgba(7,18,29,.35),0 2px 5px rgba(0,0,0,.72)}
.bg-chk.theirs{background:radial-gradient(circle at 38% 30%,#836aa0 0 8%,#4b3c5d 34%,#241c2e 69%,#0c0910 100%);
  border:2px solid #665078;box-shadow:inset 0 0 0 2px rgba(5,3,8,.46),0 2px 5px rgba(0,0,0,.75)}
.bg-more{position:relative;z-index:1;font-size:.6rem;color:var(--frost-300)}

/* Where the man you are holding would land, and the die that takes it there.
   The number is the whole point: it turns "this square is legal" into "this
   square is five away, in that direction". */
.bg-ghost{width:min(1.9rem,84%);aspect-ratio:1;border-radius:50%;flex:none;
  display:grid;place-items:center;
  border:2px dashed var(--ice-400);background:rgba(111,182,232,.14);
  animation:bgGhost 1.4s ease-in-out infinite}
.bg-ghost.tray{width:82%;aspect-ratio:auto;height:1.3rem;border-radius:3px}
.bg-ghost-die{font-family:ui-monospace,Menlo,monospace;font-size:.82rem;color:var(--frost-100)}
@keyframes bgGhost{0%,100%{opacity:.65}50%{opacity:1}}

/* Ice cyan is your agency everywhere else in the game. Keep it on the live
   pieces and ghosts so the painted silver/gold points remain undisturbed. */
.bg-pt.liftable{cursor:pointer}
.bg-pt.liftable .bg-chk.mine{filter:drop-shadow(0 0 5px rgba(111,182,232,.82))}
.bg-pt.liftable:hover .bg-chk.mine{filter:drop-shadow(0 0 8px rgba(168,220,255,1))}
.bg-pt.held .bg-chk.mine{outline:2px solid var(--ice-400);outline-offset:1px}
.bg-pt.landable{cursor:pointer}
.bg-pt.landable .bg-ghost{filter:drop-shadow(0 0 7px rgba(111,182,232,.82))}

.bg-bar{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;
  gap:2px;background:transparent;border-radius:2px;padding:4px 0}
.bg-bar.liftable{cursor:pointer;box-shadow:inset 0 0 0 1px var(--ice-400)}
.bg-bar.held{box-shadow:inset 0 0 0 2px var(--ice-400)}
.bg-bar.bottom{justify-content:flex-end}
.bg-bar .bg-chk{width:74%}

.bg-tray{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:2px;
  background:transparent;border:0;border-radius:3px;padding:4px 7px}
.bg-tray.bottom{justify-content:flex-end}
.bg-off{width:80%;height:7px;border-radius:2px}
.bg-off.mine{background:var(--ice-500)}
.bg-off.theirs{background:#4a3d5c}
.bg-tray-hint{font-size:.6rem;color:var(--frost-300);opacity:.6}

.bg-msg{text-align:center;margin-top:var(--sp-3);color:var(--frost-200);min-height:1.4em}
.bg-turn-controls{display:flex;align-items:center;justify-content:center;gap:var(--sp-3);min-height:36px;margin-top:var(--sp-2)}
.bg-turn-controls span{font-family:var(--font-ui);font-size:.68rem;color:var(--frost-300)}
.bg-turn-controls .btn{padding:6px 12px;font-size:.72rem}
.bg-turn-controls .btn.ready{border-color:var(--ice-500);box-shadow:0 0 10px rgba(111,182,232,.18)}

@media (max-width:720px){
  /* Never stretch the painted board: the interaction grid is registered to
     its native 13:8 geometry. It scales down as one piece. */
  .bg-board{aspect-ratio:13/8}
  .bg-num{display:none}
  .bg-turn-controls span{display:none}
}

/* ══ The Tide — liar's dice ═══════════════════════════════ */
.ld-screen{max-width:46rem;margin:0 auto;padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-3)}
.ld-side{display:flex;flex-direction:column;gap:var(--sp-2)}
.ld-side.mine{order:3}
.ld-who{display:flex;align-items:baseline;gap:var(--sp-3);
  font-family:var(--font-display);font-size:1rem;color:var(--frost-100)}
.ld-count{font-family:ui-monospace,Menlo,monospace;font-size:.74rem;color:var(--frost-300)}
.ld-cup{display:flex;gap:var(--sp-2);flex-wrap:wrap}
.ld-die{display:grid;place-items:center;width:2.6rem;height:2.6rem;border-radius:var(--r-md);
  background:var(--night-800);border:1px solid var(--ice-700);color:var(--frost-100);
  font-family:ui-monospace,Menlo,monospace;font-size:1.4rem;line-height:1}
/* His cup, before it comes up. Dashed and dimmer than yours, but it has to be
   plainly *there* — a die you cannot see is the whole game, a die you cannot
   find on the screen is a bug. */
.ld-die.facedown{border-style:dashed;border-color:var(--shadow-500);
  background:rgba(139,95,196,.10);color:var(--frost-300);font-size:1.15rem}

.ld-middle{order:2;text-align:center;padding:var(--sp-3) 0;
  border-top:1px solid var(--night-400);border-bottom:1px solid var(--night-400)}
.ld-bid{display:flex;flex-direction:column;gap:2px;align-items:center}
.ld-bid b{font-family:var(--font-display);font-size:1.5rem;color:var(--coin-400)}
.ld-standing,.ld-by{font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;color:var(--frost-300)}
.ld-msg{margin-top:var(--sp-2);color:var(--frost-200);min-height:1.4em}

.ld-controls{order:4}
.ld-build{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:var(--sp-3)}
.ld-stepper{display:flex;align-items:center;gap:var(--sp-2);
  border:1px solid var(--night-400);border-radius:var(--r-md);padding:var(--sp-2) var(--sp-3)}
.ld-stepper .toggle{min-width:2rem}
.ld-stepper .toggle[disabled]{opacity:.25;cursor:not-allowed}
.ld-val{min-width:2rem;text-align:center;font-size:1.35rem;color:var(--frost-100);font-family:ui-monospace,Menlo,monospace}
.ld-lab{font-size:.7rem;color:var(--frost-300);letter-spacing:.06em}
.ld-rule{text-align:center;margin-top:var(--sp-3);font-size:.78rem;color:var(--frost-300)}
.ld-waiting{text-align:center;color:var(--frost-300);min-height:2.4rem;display:grid;place-items:center}

/* ══ The Ring — nine men's morris ═════════════════════════ */
.mo-screen{max-width:40rem;margin:0 auto;padding:var(--sp-4)}
.mo-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);margin-bottom:var(--sp-3)}
.mo-who{display:flex;flex-direction:column;gap:2px}
.mo-who.mine{text-align:right}
.mo-name{font-family:var(--font-display);font-size:1.02rem;color:var(--frost-100)}
.mo-men{font-size:.74rem;color:var(--frost-300);font-variant-numeric:tabular-nums}
.mo-clock{display:flex;flex-direction:column;align-items:center;gap:2px}
.mo-phase{font-size:.66rem;letter-spacing:.11em;text-transform:uppercase;color:var(--coin-400)}
.mo-plies{font-size:.68rem;color:var(--frost-300);font-variant-numeric:tabular-nums}

.mo-board{background:var(--night-900);border:1px solid var(--night-400);
  border-radius:var(--r-md);padding:var(--sp-4)}
.mo-svg{width:100%;height:auto;display:block}
.mo-line{fill:none;stroke:var(--night-400);stroke-width:.7;stroke-linejoin:round}

.mo-hit{fill:transparent;cursor:default}
.mo-man{fill:var(--night-400);transition:fill .12s}
.mo-pt.mine .mo-man{fill:url(#none);fill:#8fd0ff;stroke:#2c6a99;stroke-width:.8}
.mo-pt.theirs .mo-man{fill:#4a3d5c;stroke:#7a6494;stroke-width:.8}

/* Ice cyan for anything you may do, the same as everywhere else in the game. */
.mo-pt.liftable .mo-hit,.mo-pt.landable .mo-hit,.mo-pt.takeable .mo-hit{cursor:pointer}
.mo-pt.liftable .mo-man{stroke:var(--ice-400);stroke-width:1.4}
.mo-pt.held .mo-man{stroke:var(--ice-400);stroke-width:2.2}
.mo-ghost{fill:rgba(111,182,232,.2);stroke:var(--ice-400);stroke-width:.9;stroke-dasharray:1.6 1.4;
  animation:moGhost 1.4s ease-in-out infinite}
@keyframes moGhost{0%,100%{opacity:.6}50%{opacity:1}}
.mo-take{fill:none;stroke:var(--blood-400);stroke-width:1.2;stroke-dasharray:2 1.6;
  animation:moGhost 1s ease-in-out infinite}
.mo-msg{text-align:center;margin-top:var(--sp-3);color:var(--frost-200);min-height:1.4em}

/* ══ The Wall — the crossbow ══════════════════════════════
   The canvas is the whole stage; everything else is a thin band under it. */
.cb-screen{max-width:64rem;margin:0 auto;padding:var(--sp-4);position:relative}
.cb-canvas{display:block;width:100%;aspect-ratio:16/9;border-radius:var(--r-md);
  border:1px solid var(--night-400);background:var(--night-900);cursor:crosshair;touch-action:none}
.cb-hud{display:flex;align-items:center;gap:var(--sp-4);margin-top:var(--sp-3);flex-wrap:wrap}
.cb-stat{display:flex;align-items:center;gap:var(--sp-2)}
.cb-stat.wide{flex:1;min-width:9rem}
.cb-k{font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--frost-300)}
.cb-stat b{font-family:ui-monospace,Menlo,monospace;font-size:1.05rem;color:var(--frost-100)}
.cb-bar{flex:1;height:7px;border-radius:4px;background:rgba(0,0,0,.5);
  border:1px solid var(--night-400);overflow:hidden}
.cb-bar i{display:block;height:100%;background:var(--ice-500);transition:width .08s linear}
.cb-bar.amber i{background:var(--coin-500)}
.cb-bar i.winded{background:var(--blood-400)}
.cb-msg{text-align:center;margin-top:var(--sp-3);color:var(--frost-200);min-height:1.4em}
.cb-touch{display:flex;gap:var(--sp-3);justify-content:center;margin-top:var(--sp-3)}
.cb-touch .btn{min-width:8rem;touch-action:manipulation}
@media (hover:hover) and (pointer:fine){
  /* On a mouse the keyboard and the click are the controls; the buttons stay
     for anyone who prefers them but stop shouting. */
  .cb-touch .btn{opacity:.6;font-size:.8rem;min-width:6rem}
  .cb-touch .btn:hover{opacity:1}
}
