/* Grimhold — ash, ember and old iron.
 *
 * Layout sizes live in custom properties so the phone breakpoints only
 * restate numbers: --sk skill slot, --pot potion slot, --globe life/resource
 * globe. Rarity colours are --r-* and are also handed to ui.js via `static`.
 */

:root {
  --bg: #07060a;
  --ink: #e8dcc4;              /* parchment */
  --ink-dim: #a8977c;
  --ink-mute: #6f6455;
  --ember: #e0642a;
  --ember-hi: #ff9a4a;
  --gold: #c9a24a;
  --gold-hi: #f2d27a;
  --blood: #b8202a;
  --panel: rgba(14, 11, 12, .94);
  --panel-line: rgba(201, 162, 74, .35);
  --hud-bg: rgba(10, 8, 10, .72);
  --hud-line: rgba(201, 162, 74, .28);
  --r-common: #d8d8d8;
  --r-magic: #6f8dff;
  --r-rare: #ffd83a;
  --r-legendary: #ff8a2a;
  --r-set: #5fe07a;            /* a set piece and an ancient are tiers the */
  --r-ancient: #ffd06a;        /* rarity does not carry — see itemColor()  */
  --serif: "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;
  --sans: "Segoe UI", system-ui, sans-serif;
  --sk: 64px;
  --pot: 52px;
  --globe: 96px;
  --gap: 6px;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%; overflow: hidden;
  background: var(--bg); color: var(--ink);
  font-family: var(--sans);
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}
button { font-family: inherit; }
.muted { color: var(--ink-mute); }
.small { font-size: 12px; }

#gameCanvas {
  position: fixed; inset: 0; width: 100%; height: 100%;
  display: block; touch-action: none;
}

/* ── HUD root ─────────────────────────────────────────────────────── */
#hud { position: fixed; inset: 0; pointer-events: none; z-index: 5; font-variant-numeric: tabular-nums; }

/* ── hurt flash + low life ─────────────────────────────────────────
   Two layers on one element: the element itself is the LOW-LIFE state (a
   slow red heartbeat that stays until you heal), ::after is the one-shot
   flash for a hit. They have to be separate or a hit at 20% life would
   restart, and so cancel, the pulse. --hx/--hy move the flash toward the
   thing that hit you when the client passes a direction. */
.hurt-vignette { position: absolute; inset: 0; pointer-events: none; z-index: 1; opacity: 0;
  background: radial-gradient(ellipse at 50% 50%, rgba(120,0,10,0) 42%, rgba(150,10,20,.55) 78%, rgba(90,0,8,.85) 100%); }
.hurt-vignette.low { animation: lowlife 1.5s ease-in-out infinite; }
.hurt-vignette::after { content: ""; position: absolute; inset: 0; opacity: 0;
  background: radial-gradient(ellipse at var(--hx, 50%) var(--hy, 50%), rgba(255,40,40,0) 20%, rgba(200,20,25,.5) 62%, rgba(120,0,6,.92) 100%); }
.hurt-vignette.hit::after { animation: hurt-flash .42s ease-out; }
@keyframes lowlife { 0%, 100% { opacity: .22; } 50% { opacity: .58; } }
@keyframes hurt-flash { 0% { opacity: 0; } 12% { opacity: 1; } 100% { opacity: 0; } }
/* the life globe answers too: D3 pulses it, and the number is what you read */
#hud.lowlife .globe-life { border-color: #8a2020; animation: globe-alarm 1.5s ease-in-out infinite; }
#hud.lowlife .globe-life .globe-num { color: #ffdcdc; }
@keyframes globe-alarm { 0%, 100% { box-shadow: 0 0 0 2px #1a120c, 0 0 20px rgba(0,0,0,.8), inset 0 0 18px rgba(0,0,0,.9); }
  50% { box-shadow: 0 0 0 2px #3a0c0c, 0 0 26px rgba(200,20,30,.75), inset 0 0 18px rgba(0,0,0,.9); } }

/* ── party frames (top-left) ──────────────────────────────────────── */
.party {
  position: absolute; top: calc(10px + env(safe-area-inset-top)); left: calc(10px + env(safe-area-inset-left));
  display: flex; flex-direction: column; gap: 6px; width: 190px;
}
.pf { display: grid; grid-template-columns: 34px 1fr; gap: 8px; align-items: center;
  background: var(--hud-bg); border: 1px solid var(--hud-line); border-radius: 10px; padding: 4px 8px 4px 4px;
  backdrop-filter: blur(6px); }
.pf-portrait { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-weight: 700; font-size: 16px; color: #1a0e08;
  background: var(--c, #888); box-shadow: 0 0 10px color-mix(in srgb, var(--c, #888) 60%, transparent), inset 0 -4px 8px rgba(0,0,0,.35); }
.pf-name { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-name small { color: var(--ink-dim); margin-left: 4px; }
.pf-bar { height: 6px; background: #2a1414; border-radius: 3px; overflow: hidden; margin-top: 3px; border: 1px solid rgba(0,0,0,.6); }
.pf-bar > i { display: block; height: 100%; background: linear-gradient(180deg, #ff5a4a, #b8202a); }
.pf.dead { opacity: .55; filter: grayscale(1); }
.pf.dead .pf-name::after { content: " ☠"; color: #ff8a8a; }

/* ── area banner + boss bar (top-centre) ──────────────────────────── */
.area-banner {
  position: absolute; left: 50%; top: 22%; transform: translate(-50%, -50%);
  text-align: center; opacity: 0; transition: opacity .6s; width: min(90vw, 700px);
}
.area-banner.show { opacity: 1; transition: opacity .3s; }
.ab-title { font-family: var(--serif); font-size: clamp(28px, 6vw, 54px); letter-spacing: .12em; color: #f6e7c8;
  text-shadow: 0 0 30px rgba(224, 100, 42, .7), 0 3px 0 #000, 0 0 2px #000; }
.ab-sub { font-family: var(--serif); font-size: clamp(12px, 2.2vw, 18px); letter-spacing: .3em; text-transform: uppercase; color: var(--gold-hi);
  text-shadow: 0 2px 6px #000; margin-top: 4px; }

.boss-bar { position: absolute; left: 50%; transform: translateX(-50%); top: calc(12px + env(safe-area-inset-top)); width: min(560px, 70vw); pointer-events: none; }
.boss-name { text-align: center; font-family: var(--serif); font-size: 15px; letter-spacing: .18em; color: #ffd9c4; text-shadow: 0 2px 6px #000; margin-bottom: 4px; }
.boss-name small { display: block; font-size: 10px; letter-spacing: .3em; color: var(--ink-dim); text-transform: uppercase; }
.boss-track { height: 12px; background: #1a0808; border: 1px solid #7a2a2a; border-radius: 3px; overflow: hidden; box-shadow: 0 0 14px rgba(184, 32, 42, .4); }
#bossFill { height: 100%; width: 100%; background: linear-gradient(180deg, #ff4a4a, #8a1018); transition: width .15s linear; }

/* ── target frame (top-centre) ─────────────────────────────────────
   What you are hitting or hovering: name, rank, life and — the reason it
   exists — the elite affixes IN THEIR OWN COLOURS, so "Frozen, Molten"
   is readable before the ice orbs land. It takes the boss bar's slot and
   steps down when a boss owns it (#hud.bossing, set by setBoss). */
.target-frame { position: absolute; left: 50%; transform: translateX(-50%); top: calc(10px + env(safe-area-inset-top));
  width: min(340px, calc(100vw - 360px)); min-width: 210px; padding: 5px 10px 6px; z-index: 6;
  background: var(--hud-bg); border: 1px solid var(--tc, var(--hud-line)); border-radius: 10px; backdrop-filter: blur(6px);
  box-shadow: 0 0 16px color-mix(in srgb, var(--tc, #000) 30%, transparent), 0 6px 18px rgba(0,0,0,.5); }
#hud.bossing .target-frame { top: calc(62px + env(safe-area-inset-top)); }
.target-frame.elite { --tc: #ff9a2a; }
.target-frame.boss { --tc: #ff3a3a; }
.tf-top { display: flex; align-items: baseline; gap: 8px; }
.tf-name { font-family: var(--serif); font-size: 13.5px; letter-spacing: .06em; color: var(--tc, var(--ink)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tf-rank { margin-left: auto; font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-mute); white-space: nowrap; }
.tf-track { position: relative; height: 9px; margin-top: 3px; background: #1a0808; border: 1px solid rgba(0,0,0,.6); border-radius: 3px; overflow: hidden; }
.tf-fill { height: 100%; width: 100%; background: linear-gradient(180deg, #ff5a4a, #a01820); transition: width .12s linear; }
.tf-hp { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 8.5px; font-weight: 700; color: #fff; text-shadow: 0 1px 2px #000; }
.tf-affixes { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.tf-affixes:empty { display: none; }
.tf-aff { font-size: 10px; letter-spacing: .04em; padding: 1px 6px; border-radius: 999px; white-space: nowrap;
  color: var(--ac, #fff); border: 1px solid color-mix(in srgb, var(--ac, #fff) 55%, transparent); background: color-mix(in srgb, var(--ac, #fff) 14%, rgba(0,0,0,.5)); }

/* ── top-right column: gear / minimap / quests ────────────────────── */
.hud-tr { position: absolute; top: calc(10px + env(safe-area-inset-top)); right: calc(10px + env(safe-area-inset-right));
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px; }
#minimap { display: block; width: 160px; height: 160px; border-radius: 8px; border: 1px solid var(--hud-line);
  background: rgba(6, 5, 7, .8); image-rendering: pixelated; pointer-events: auto; }
#minimap.hidden { display: none; }
/* big map (M cycles normal → big → hidden): the same canvas, lifted to the
   centre of the screen; ui.js sets the inline size to min(70vw, 70vh) */
#minimap.big { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 7; border-radius: 12px; border-color: var(--gold);
  box-shadow: 0 0 0 1px #000, 0 20px 60px rgba(0,0,0,.8); image-rendering: auto; }
.quests { width: 220px; background: var(--hud-bg); border: 1px solid var(--hud-line); border-radius: 10px; pointer-events: auto;
  backdrop-filter: blur(6px); font-size: 12px; }
.q-head { display: flex; justify-content: space-between; align-items: center; padding: 5px 10px; cursor: pointer;
  font-family: var(--serif); letter-spacing: .14em; font-size: 11px; color: var(--gold-hi); text-transform: uppercase; }
.q-caret { transition: transform .2s; color: var(--ink-dim); }
.q-hprog { margin-left: auto; margin-right: 8px; color: var(--ink); font-family: var(--sans); letter-spacing: 0; text-transform: none; font-size: 11px; display: none; }
.quests.collapsed .q-hprog { display: inline; }
.quests.collapsed .q-caret { transform: rotate(-90deg); }
.quests.collapsed .q-body { display: none; }
.q-body { padding: 0 10px 8px; }
.q-main { border-top: 1px solid rgba(201,162,74,.18); padding-top: 6px; }
.q-name { color: var(--ink); font-weight: 600; }
.q-prog { color: var(--gold-hi); font-size: 11.5px; margin-top: 1px; }
/* compass: ▲ rotated toward the nearest quest marker, distance beside it */
.q-compass { display: flex; align-items: center; gap: 6px; margin-top: 4px; color: var(--gold-hi); font-size: 11.5px; min-width: 0; }
.qc-arrow { display: inline-block; width: 14px; text-align: center; font-size: 12px; line-height: 1; transition: transform .15s linear; transform-origin: 50% 55%; flex: none; }
.qc-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.q-bounties { margin-top: 6px; display: grid; gap: 3px; }
.q-b { display: flex; justify-content: space-between; gap: 8px; color: var(--ink-dim); }
.q-b.done { color: #8ee86f; text-decoration: line-through; opacity: .8; }
.q-b span:last-child { color: var(--gold-hi); white-space: nowrap; }
.q-b.done span:last-child { color: #8ee86f; }
.q-b .q-map { font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-mute); }

/* gear disclosure with the audio strip. Desktop: bottom-right corner, out of the
   flow of the column. Phones: it stays at the top of the column so it never
   lands on the touch cluster. */
.hud-gear { pointer-events: auto; z-index: 7; position: fixed; right: calc(10px + env(safe-area-inset-right));
  bottom: calc(10px + env(safe-area-inset-bottom)); display: flex; flex-direction: column-reverse; align-items: flex-end; }
.hud-gear summary { list-style: none; cursor: pointer; width: 34px; height: 34px; border-radius: 50%;
  background: var(--hud-bg); border: 1px solid var(--hud-line); color: var(--ink);
  display: flex; align-items: center; justify-content: center; font-size: 16px; }
.hud-gear summary::-webkit-details-marker { display: none; }
.hud-gear[open] summary { background: rgba(224, 100, 42, .35); border-color: var(--ember); }
/* The popover itself: options rows then the audio strip, one panel so the two
   cannot land on top of each other. site_audio.css pins #hudAudio fixed
   bottom-centre — that is where the action bar lives — so it is restated as a
   plain flow child in here (this sheet loads later and wins at equal
   specificity). */
.gear-body { position: absolute; right: 0; left: auto; bottom: calc(var(--globe) + 16px); width: min(346px, calc(100vw - 20px));
  background: var(--panel); border: 1px solid var(--panel-line); border-radius: 12px; padding: 10px 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,.7); display: grid; gap: 10px; max-height: 72vh; overflow-y: auto; overflow-x: hidden; }
/* a grid item's min-width is auto: without this the key list and the audio
   strip size to their MIN-CONTENT and hang off the right of the screen */
.gear-body > * { min-width: 0; }
#hudAudio { position: static; left: auto; right: auto; bottom: auto; transform: none; z-index: auto; pointer-events: auto;
  margin: 0; max-width: 100%; }
#hudAudio .mps-audio { background: rgba(0,0,0,.25); border-color: var(--hud-line); }
/* options rows: a label on the left, the control on the right */
.hud-options { display: grid; gap: 7px; font-size: 12.5px; min-width: 0; }
.opt-h { font-family: var(--serif); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); }
.opt-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.opt-row > span { color: var(--ink-dim); }
.opt-seg { display: flex; gap: 3px; }
.opt-seg button { background: #1a1412; color: var(--ink-dim); border: 1px solid #4a3a24; border-radius: 6px; padding: 3px 9px; font-size: 11.5px; cursor: pointer; }
.opt-seg button.on { background: rgba(224,100,42,.35); border-color: var(--ember); color: #fff; }
.opt-check { position: relative; width: 40px; height: 21px; border-radius: 999px; border: 1px solid #4a3a24; background: #1a1412; cursor: pointer; flex: none; padding: 0; }
.opt-check::after { content: ""; position: absolute; left: 2px; top: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--ink-mute); transition: transform .15s, background .15s; }
.opt-check.on { border-color: var(--ember); background: rgba(224,100,42,.3); }
.opt-check.on::after { transform: translateX(19px); background: var(--ember-hi); }
.opt-keys { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; font-size: 11.5px; color: var(--ink-mute); }
.opt-keys span { overflow-wrap: anywhere; }
html.touch .opt-keys, html.touch .opt-h.keys-h { display: none; }   /* a touch player has no keys to press */
.opt-keys b { color: var(--gold-hi); font-family: var(--serif); font-weight: 700; white-space: nowrap; }
/* web/style.css pins .volume-slider position:fixed top:12px — undo it (CLAUDE.md item 5). */
.volume-slider { position: static !important; top: auto !important; }
.audio-controls { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; justify-content: center; padding: 4px 0; }
.audio-controls button { background: #241a14; color: var(--ink); border: 1px solid #4a3424; border-radius: 8px; padding: 5px 10px; font-size: 12px; cursor: pointer; }
.audio-controls input[type="range"] { width: 86px; accent-color: var(--ember); }
.mps-audio-slider { accent-color: var(--ember); }

/* ── buff bar (above the action bar) ───────────────────────────────
   Own buffs only. The ring is the REMAINING fraction, the same reading as
   a skill cooldown sweep, so one glance covers both rows. */
/* The BAR is 520 px wide and mostly empty, and it sits over the ground right
   above the action bar — so it must never take a pointer event, or a click to
   move lands on nothing whenever a buff is up. Only the icons opt in (they
   own the hover tooltip). */
.buff-bar { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(var(--globe) + 14px + env(safe-area-inset-bottom));
  display: flex; flex-wrap: wrap-reverse; justify-content: center; align-items: flex-end; gap: 5px; z-index: 6; pointer-events: none;
  width: min(520px, calc(100vw - 24px)); }
.buff-bar:empty { display: none; }
#hud.bossing .buff-bar { bottom: calc(var(--globe) + 14px + env(safe-area-inset-bottom)); }
.buff { position: relative; width: 32px; height: 32px; border-radius: 7px; overflow: hidden; cursor: help; pointer-events: auto;
  background: linear-gradient(180deg, #1c1614, #0d0a0a); border: 1px solid color-mix(in srgb, var(--bc, var(--gold)) 70%, #000);
  box-shadow: 0 0 8px color-mix(in srgb, var(--bc, var(--gold)) 35%, transparent), inset 0 1px 0 rgba(255,255,255,.06); }
.buff .bf-icon { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--bc, var(--gold-hi)); }
.buff .bf-icon svg { width: 60%; height: 60%; filter: drop-shadow(0 0 5px currentColor); }
/* --p is the remaining fraction: the dark wedge eats the icon as it runs out */
.buff .bf-ring { position: absolute; inset: 0; pointer-events: none;
  background: conic-gradient(transparent calc(var(--p, 1) * 360deg), rgba(0,0,0,.72) 0); }
.buff .bf-num { position: absolute; left: 0; right: 0; bottom: 0; text-align: center; font-size: 9px; font-weight: 700;
  color: #fff; text-shadow: 0 1px 2px #000, 0 0 4px #000; background: linear-gradient(180deg, transparent, rgba(0,0,0,.6)); }
.buff.ending { animation: buff-ending .6s ease-in-out infinite; }
@keyframes buff-ending { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ── prompt ───────────────────────────────────────────────────────── */
.prompt { position: absolute; left: 50%; bottom: calc(var(--globe) + 56px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  padding: 6px 16px; border-radius: 999px; background: var(--hud-bg); border: 1px solid var(--gold);
  color: var(--ink); font-size: 14px; white-space: nowrap; box-shadow: 0 0 18px rgba(201,162,74,.25); }
.prompt b { color: var(--gold-hi); font-family: var(--serif); margin-right: 6px; }
.player-menu { position: absolute; left: 50%; bottom: calc(var(--globe) + 100px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 8; pointer-events: auto;
  background: rgba(14, 11, 10, .94); border: 1px solid var(--gold-hi); border-radius: 10px; padding: 10px 12px; min-width: 240px; box-shadow: 0 0 18px rgba(255, 190, 90, .25); }
.player-menu .pm-head { display: flex; gap: 8px; align-items: baseline; margin-bottom: 8px; }
.player-menu .pm-head b { font-family: var(--serif); color: var(--gold-hi); }
.player-menu .pm-row { display: flex; gap: 8px; align-items: center; }
.player-menu .pm-btn { padding: 6px 12px; }
.player-menu .pm-close { margin-left: auto; padding: 2px 8px; }

/* ── action bar ───────────────────────────────────────────────────── */
.action-bar {
  position: absolute; left: 50%; bottom: calc(8px + env(safe-area-inset-bottom)); transform: translateX(-50%);
  display: grid; grid-template-columns: auto auto auto; grid-template-areas: "life skills res" "life xp res";
  align-items: end; gap: 5px 10px; pointer-events: auto; z-index: 6;
}
.skills { grid-area: skills; justify-self: center; }
#xpBar { grid-area: xp; }
.globe { position: relative; width: var(--globe); height: var(--globe); border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 50% 40%, #1c1416, #0a0708 70%);
  border: 3px solid #4a3a24; box-shadow: 0 0 0 2px #1a120c, 0 0 20px rgba(0,0,0,.8), inset 0 0 18px rgba(0,0,0,.9);
  align-self: end; }
.globe-life { grid-area: life; }
.globe-res { grid-area: res; }
.globe-fill { position: absolute; left: 0; right: 0; bottom: 0; height: var(--p, 100%); transition: height .18s ease-out;
  background: linear-gradient(180deg, #ff6a5a 0%, #c0202a 45%, #6a0a10 100%); box-shadow: inset 0 6px 10px rgba(255,255,255,.18); }
.globe-life .globe-fill::before { content: ""; position: absolute; inset: -6px 0 auto; height: 12px; border-radius: 50%; background: rgba(255,150,130,.35); }
.globe-res .globe-fill { background: linear-gradient(180deg, var(--rc-hi, #ffb04a) 0%, var(--rc, #e0642a) 45%, var(--rc-lo, #6a2a08) 100%); }
.globe-gloss { position: absolute; left: 18%; top: 8%; width: 40%; height: 26%; border-radius: 50%; background: linear-gradient(180deg, rgba(255,255,255,.28), rgba(255,255,255,0)); pointer-events: none; }
.globe-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: calc(var(--globe) * .2); font-weight: 700; color: #fff; text-shadow: 0 1px 2px #000, 0 0 8px #000; }

.skills { display: flex; gap: var(--gap); align-items: end; }
.skill { position: relative; width: var(--sk); height: var(--sk); border-radius: 8px; cursor: pointer;
  background: linear-gradient(180deg, #1c1614, #0d0a0a); border: 2px solid #4a3a24;
  box-shadow: 0 0 0 1px #1a120c, 0 4px 12px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.06);
  touch-action: manipulation; overflow: hidden; }
.skill:hover { border-color: var(--gold); }
.skill.active { border-color: var(--ember-hi); box-shadow: 0 0 0 1px #1a120c, 0 0 16px rgba(255,154,74,.6); }
.skill.nores .sk-icon { filter: saturate(.3) brightness(.7); }
.skill.nores { border-color: #6a1a1a; }
.skill.nores::after { content: ""; position: absolute; inset: 0; background: rgba(160, 20, 30, .28); pointer-events: none; }
.skill.locked .sk-icon { filter: grayscale(1) brightness(.4); }
.skill.locked { cursor: default; }
.sk-icon { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--ember-hi); }
.glyph { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; }
.sk-icon svg { width: 62%; height: 62%; filter: drop-shadow(0 0 6px currentColor); }
.sk-key { position: absolute; left: 4px; top: 2px; font-size: 9.5px; font-weight: 700; color: var(--ink-dim); letter-spacing: .04em; text-shadow: 0 1px 2px #000; }
.sk-cost { position: absolute; right: 4px; bottom: 2px; font-size: 10px; font-weight: 700; color: var(--gold-hi); text-shadow: 0 1px 2px #000; }
.skill.nores .sk-cost { color: #ff7a7a; }
/* cooldown sweep: --cd is the REMAINING fraction (1 = just used, 0 = ready) */
.sk-cd { position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: conic-gradient(rgba(0,0,0,.78) calc(var(--cd, 0) * 360deg), transparent 0); }
.skill.cooling .sk-cd { opacity: 1; }
.sk-cdnum { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; font-family: var(--serif); font-weight: 700;
  font-size: calc(var(--sk) * .32); color: #fff; text-shadow: 0 1px 2px #000, 0 0 8px #000; pointer-events: none; }
.skill.cooling .sk-cdnum { display: flex; }
.sk-lock { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  color: var(--ink-dim); background: rgba(0,0,0,.45); letter-spacing: .06em; font-family: var(--serif); }
.skill.locked .sk-lock { display: flex; }
.skill.potion { width: var(--pot); height: var(--pot); border-radius: 50%; border-color: #5a2a2a; }
.skill.potion .sk-icon { color: #ff6a6a; }
.skill.potion .sk-cdnum { font-size: calc(var(--pot) * .32); }

.xp-bar { position: relative; width: 100%; height: 10px; background: #120e0c; border: 1px solid #4a3a24; border-radius: 5px; overflow: visible; }
.xp-fill { height: 100%; width: 0; background: linear-gradient(90deg, #7a5a1a, var(--gold-hi)); border-radius: 4px; transition: width .3s; }
.xp-lv { position: absolute; right: 0; top: -15px; font-size: 10.5px; color: var(--gold-hi); font-family: var(--serif); letter-spacing: .08em; }

/* ── bottom-left panel buttons ────────────────────────────────────── */
/* The action bar is CENTRED, so the room to its left shrinks with the window.
   Six buttons no longer fit beside the life globe at 1280 (the sixth landed on
   the orb), so the row is capped at the space that is actually free and wraps
   UPWARD into it. */
.hud-bl { position: absolute; left: calc(10px + env(safe-area-inset-left)); bottom: calc(10px + env(safe-area-inset-bottom));
  display: flex; flex-wrap: wrap-reverse; gap: 6px; pointer-events: auto; z-index: 6;
  max-width: max(140px, calc(50vw - 330px)); }
.hbtn { background: var(--hud-bg); color: var(--ink); border: 1px solid var(--hud-line); border-radius: 8px; padding: 6px 10px; font-size: 12px; cursor: pointer;
  touch-action: manipulation; }
.hbtn b { color: var(--gold-hi); font-family: var(--serif); }
.hbtn span { margin-left: 5px; }
.hbtn:hover, .hbtn.on { border-color: var(--gold); background: rgba(201,162,74,.18); }

/* ── dialogue card (bottom-left, above buttons) ───────────────────── */
.dialogue { position: absolute; left: calc(10px + env(safe-area-inset-left)); bottom: calc(var(--globe) + 28px + env(safe-area-inset-bottom));
  width: min(360px, 40vw); background: var(--panel); border: 1px solid var(--panel-line); border-radius: 10px; padding: 8px 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,.6); animation: fade-in .25s; }
.dl-name { font-family: var(--serif); color: var(--gold-hi); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 3px; }
.dl-text { font-size: 13.5px; line-height: 1.4; font-style: italic; }
@keyframes fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── in-world chat (bottom-left, above the dialogue card) ───────────
   The log is never clickable — it sits over the ground the player clicks
   on — so only the entry opts in to pointer events, and only while open. */
.chat-wrap { position: absolute; left: calc(10px + env(safe-area-inset-left)); bottom: calc(var(--globe) + 100px + env(safe-area-inset-bottom));
  width: min(420px, 42vw); display: flex; flex-direction: column; gap: 5px; z-index: 6; pointer-events: none; }
.chat-log { display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }
.chat-log:empty { display: none; }
.chat-line { max-width: 100%; padding: 2px 8px; border-radius: 6px; font-size: 12.5px; line-height: 1.35; color: var(--ink);
  background: rgba(8, 6, 8, .62); border: 1px solid rgba(201,162,74,.18); text-shadow: 0 1px 2px #000;
  overflow-wrap: anywhere; animation: fade-in .2s; transition: opacity .8s; }
.chat-line b { color: var(--gold-hi); margin-right: 5px; }
.chat-line.system { font-style: italic; color: var(--ink-dim); }
.chat-line.fading { opacity: 0; }
.chat-entry { display: flex; align-items: center; gap: 6px; pointer-events: auto;
  background: var(--panel); border: 1px solid var(--gold); border-radius: 10px; padding: 5px 8px; box-shadow: 0 0 18px rgba(201,162,74,.25); }
.ce-label { font-family: var(--serif); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--gold-hi); }
#chatText { flex: 1 1 auto; min-width: 0; background: #120e0c; border: 1px solid #4a3a24; border-radius: 6px; color: var(--ink);
  font-family: var(--sans); font-size: 13px; padding: 5px 8px; }
#chatText:focus { outline: none; border-color: var(--gold); }
#chatSend { padding: 5px 10px; font-size: 12px; }

/* ── toasts ───────────────────────────────────────────────────────── */
.toasts { position: absolute; left: 50%; top: 36%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 4px; width: min(90vw, 520px); }
.toast { padding: 5px 14px; border-radius: 999px; background: var(--hud-bg); border: 1px solid var(--hud-line); font-size: 13px; color: var(--ink);
  animation: toast-in .25s ease-out, toast-out .4s ease-in 2.6s forwards; text-shadow: 0 1px 2px #000; text-align: center; }
.toast.quest { border-color: var(--gold); color: var(--gold-hi); font-family: var(--serif); letter-spacing: .06em; }
.toast.loot { color: var(--ink); }
.toast.gold { color: var(--gold-hi); }
.toast.warn, .toast.error { border-color: #7a2a2a; color: #ff9a8a; }
.toast.levelup { border-color: var(--gold-hi); color: #fff3d0; font-family: var(--serif); font-size: 15px; box-shadow: 0 0 20px rgba(242,210,122,.4); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-8px); } }

/* ── floating damage numbers ───────────────────────────────────────
   Four cases have to be told apart at a glance while a pack is dying on
   top of you (Diablo III's rule): YOUR crit is the loudest thing on the
   screen, your normal hit is bright but plain, anybody else's hit is
   deliberately muted so it never competes, and damage TAKEN is blood red
   and falls DOWN — the only numbers that move down are the ones costing
   you life. `other` is a modifier the client adds for an ally's number. */
.float-layer, .loot-layer { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.float { position: absolute; left: 0; top: 0; transform: translate(-50%, -100%); font-weight: 800; font-size: 16px; color: #fff;
  text-shadow: 0 1px 0 #000, 0 0 4px #000; white-space: nowrap; will-change: transform, opacity; display: none; letter-spacing: .01em; }
.float.on { display: block; animation: float-up .9s ease-out forwards; }
/* somebody else's damage: small, dim, no glow */
.float.dmg { color: #cfc6b4; font-size: 15px; opacity: .8; font-weight: 700; }
/* my normal hit */
.float.mine-hit { color: #fff3d8; font-size: 21px; text-shadow: 0 1px 0 #000, 0 0 6px rgba(255,170,90,.8), 0 0 2px #000; }
/* my crit: serif, twice the size, a punch and an ember glow */
.float.crit { color: #ffd06a; font-size: 34px; font-family: var(--serif); font-weight: 700; animation-name: float-crit;
  text-shadow: 0 2px 0 #4a1a00, 0 0 14px rgba(255,140,40,.9), 0 0 30px rgba(255,90,20,.6); }
.float.crit::after { content: "!"; font-size: .7em; color: #ff9a4a; margin-left: 2px; vertical-align: super; }
/* an ally's crit still reads as a crit, at the muted volume */
.float.crit.other { font-size: 20px; color: #d8b978; opacity: .8; text-shadow: 0 1px 0 #000, 0 0 6px rgba(0,0,0,.9); animation-name: float-up; }
.float.crit.other::after { display: none; }
/* damage taken: red, anchored on the hero, falls */
.float.hurt { color: #ff4a4a; font-size: 24px; font-family: var(--serif); animation-name: float-hurt;
  text-shadow: 0 2px 0 #2a0000, 0 0 12px rgba(220,20,30,.9); }
.float.hurt.other { color: #c07070; font-size: 16px; opacity: .75; text-shadow: 0 1px 0 #000; }
.float.heal { color: #7cf58a; text-shadow: 0 1px 0 #000, 0 0 8px rgba(80,240,120,.6); }
.float.xp { color: #b9a5ff; font-size: 13px; }
.float.gold { color: var(--gold-hi); font-size: 14px; }
.float.miss, .float.block, .float.good { color: #9aa; font-size: 13px; font-style: italic; }
@keyframes float-up { 0% { opacity: 1; translate: 0 0; } 70% { opacity: 1; } 100% { opacity: 0; translate: 0 -46px; } }
@keyframes float-crit { 0% { opacity: 1; scale: 1.9; translate: 0 0; } 14% { scale: .92; } 24% { scale: 1.05; } 34% { scale: 1; } 75% { opacity: 1; } 100% { opacity: 0; translate: 0 -62px; } }
@keyframes float-hurt { 0% { opacity: 1; scale: 1.45; translate: 0 0; } 18% { scale: 1; } 65% { opacity: 1; } 100% { opacity: 0; translate: 0 26px; } }

/* ── loot pills ───────────────────────────────────────────────────── */
.loot-pill { position: absolute; left: 0; top: 0; transform: translate(-50%, -100%); pointer-events: auto; cursor: pointer;
  padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; white-space: nowrap; max-width: 42vw; overflow: hidden; text-overflow: ellipsis;
  background: rgba(8, 6, 8, .85); border: 1px solid var(--rc, var(--r-common)); color: var(--rc, var(--r-common));
  text-shadow: 0 1px 2px #000; box-shadow: 0 0 8px color-mix(in srgb, var(--rc, #d8d8d8) 45%, transparent); }
/* --lift is how far ui.js pushed this label up to clear the one under it;
   the beam grows by the same amount so it still points at its own pile. */
.loot-pill::after { content: ""; position: absolute; left: 50%; top: 100%; width: 2px; height: calc(14px + var(--lift, 0px)); transform: translateX(-50%);
  background: linear-gradient(180deg, var(--rc, #d8d8d8), transparent); opacity: .8; }
.loot-pill:hover { background: rgba(30, 22, 16, .95); }
.loot-pill.common { --rc: var(--r-common); }
.loot-pill.magic { --rc: var(--r-magic); }
.loot-pill.rare { --rc: var(--r-rare); }
.loot-pill.legendary { --rc: var(--r-legendary); box-shadow: 0 0 16px rgba(255,138,42,.7); }
.loot-pill.legendary::after { height: calc(60px + var(--lift, 0px)); width: 3px; }
.loot-pill.gold { --rc: var(--gold-hi); }
.loot-pill.globe { --rc: #ff5a5a; }
.loot-pill.relic { --rc: #d9c7ff; }

/* ── overlays inside the HUD ──────────────────────────────────────── */
.travel-overlay { position: absolute; left: 50%; top: 30%; transform: translateX(-50%); padding: 12px 26px; text-align: center;
  background: var(--panel); border: 1px solid var(--panel-line); border-radius: 12px; font-family: var(--serif); font-size: 18px; letter-spacing: .08em;
  box-shadow: 0 0 30px rgba(0,0,0,.7); }
.travel-overlay b { color: var(--gold-hi); }
.dead-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, rgba(90, 0, 10, .35), rgba(0, 0, 0, .75) 70%); pointer-events: auto; z-index: 7; }
.dead-box { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 26px 48px 30px; border-radius: 18px;
  background: rgba(6, 3, 4, .78); border: 1px solid rgba(184, 32, 42, .35); box-shadow: 0 0 60px rgba(0,0,0,.8); }
.dead-title { font-family: var(--serif); font-size: clamp(34px, 8vw, 64px); letter-spacing: .16em; color: #c8202a; text-shadow: 0 0 40px rgba(184,32,42,.8), 0 3px 0 #000; }
.dead-sub { color: var(--ink-dim); font-size: 14px; margin-bottom: 6px; }
.dead-overlay .primary { width: auto; min-width: 220px; }

/* ── touch layer ──────────────────────────────────────────────────── */
#touchLayer { position: absolute; inset: 0; pointer-events: none; z-index: 4; }
#stickZone { position: absolute; left: 0; top: 25%; bottom: 0; width: 50%; pointer-events: auto; touch-action: none; }
.stick { position: absolute; width: 112px; height: 112px; margin: -56px 0 0 -56px; display: none; pointer-events: none; }
.stick-base { position: absolute; inset: 0; border-radius: 50%; border: 2px solid rgba(232, 220, 196, .35); background: rgba(20, 14, 12, .35); }
.stick-knob { position: absolute; width: 52px; height: 52px; left: 30px; top: 30px; border-radius: 50%;
  background: rgba(232, 200, 150, .6); box-shadow: 0 0 14px rgba(224, 100, 42, .5); }
.touch-cluster { position: absolute; right: calc(12px + env(safe-area-inset-right)); bottom: calc(var(--globe) + 44px + env(safe-area-inset-bottom));
  display: grid; grid-template-columns: 56px 56px 56px; grid-auto-rows: 56px; gap: 10px; pointer-events: auto; justify-items: end; align-items: end;
  grid-template-areas: "inv pot use" "s4 s3 s2" "tree party s1"; }
.tbtn { width: 56px; height: 56px; border-radius: 50%; border: 1px solid rgba(201,162,74,.5); position: relative;
  background: rgba(20, 14, 12, .6); color: var(--ink); font-weight: 800; font-size: 11px; letter-spacing: .06em;
  touch-action: manipulation; backdrop-filter: blur(3px); padding: 0; display: flex; align-items: center; justify-content: center; }
.tbtn:active, .tbtn.active { background: rgba(224, 100, 42, .55); border-color: var(--ember-hi); }
.tbtn .tb-icon { display: flex; align-items: center; justify-content: center; width: 60%; height: 60%; color: var(--ember-hi); }
.tbtn .tb-icon svg { width: 100%; height: 100%; }
.tbtn .tb-key { position: absolute; left: 6px; top: 4px; font-size: 8.5px; color: var(--ink-dim); }
.tbtn.tbtn-big { width: 72px; height: 72px; }
.tbtn.locked { opacity: .35; }
.tbtn.cooling { opacity: .55; }
.tbtn[data-slot="1"] { grid-area: s1; }
.tbtn[data-slot="2"] { grid-area: s2; }
.tbtn[data-slot="3"] { grid-area: s3; }
.tbtn[data-slot="4"] { grid-area: s4; }
.tbtn-potion { grid-area: pot; border-color: #7a3a3a; }
.tbtn-potion .tb-icon { color: #ff6a6a; }
.tbtn-interact { grid-area: use; border-color: #7dff7a; color: #d6ffd4; }
.tbtn-inv { grid-area: inv; }
.tbtn-tree { grid-area: tree; font-size: 10px; }
.tbtn-party { grid-area: party; font-size: 10px; }

/* ── the invitation (top-centre, under the boss bar's slot) ───────────
   Gold border and glow like medieval's. Desktop: below the boss bar; the
   width keeps clear of the party frames (left) and the tracker column
   (right) down to 641 px. Phones restate it below the top row. */
.invite-box { position: absolute; left: 50%; top: calc(64px + env(safe-area-inset-top)); transform: translateX(-50%); z-index: 7; pointer-events: auto;
  width: min(340px, calc(100vw - 380px)); padding: 10px 14px; background: var(--panel); border: 1px solid var(--gold); border-radius: 12px;
  box-shadow: 0 0 22px rgba(201,162,74,.3), 0 8px 24px rgba(0,0,0,.6); animation: fade-in .25s; }
.ib-text { font-size: 13.5px; line-height: 1.35; margin-bottom: 8px; text-align: center; }
.ib-btns { display: flex; gap: 8px; }
.ib-btns button { flex: 1 1 0; padding: 8px 10px; }
.ib-yes { background: linear-gradient(180deg, #ff9a4a 0%, #e0642a 55%, #9a3a12 100%); color: #1c0a04; border: 1px solid #6a3a14; border-radius: 8px;
  font-family: var(--serif); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; font-size: 13px; cursor: pointer; touch-action: manipulation;
  box-shadow: 0 4px 14px rgba(224,100,42,.3), inset 0 1px 0 rgba(255,255,255,.35); }
.ib-yes:hover { filter: brightness(1.08); }

/* ── spectator flag ───────────────────────────────────────────────── */
.spectator-flag { position: fixed; top: calc(14px + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); z-index: 9;
  padding: 4px 12px; background: var(--hud-bg); border: 1px solid var(--hud-line); border-radius: 999px; font-size: 12px; letter-spacing: .1em; color: var(--ink-dim); }

/* ── panels ───────────────────────────────────────────────────────── */
.panel { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 8; width: min(680px, 96vw); max-height: min(92vh, 760px);
  display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--panel-line); border-radius: 14px;
  box-shadow: 0 0 0 1px #000, 0 24px 60px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.05); pointer-events: auto; }
.panel::before { content: ""; position: absolute; inset: 6px; border: 1px solid rgba(201,162,74,.14); border-radius: 10px; pointer-events: none; }
.panel-sm { width: min(440px, 96vw); }
.panel-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px 10px; border-bottom: 1px solid rgba(201,162,74,.22); }
.panel-head h2 { margin: 0; font-family: var(--serif); font-size: 18px; letter-spacing: .14em; color: var(--gold-hi); text-transform: uppercase; flex: 1; }
.panel-close { margin-left: auto; background: transparent; color: var(--ink-dim); border: 1px solid var(--hud-line); border-radius: 50%; width: 30px; height: 30px; cursor: pointer; font-size: 13px; touch-action: manipulation; }
.panel-close:hover { color: var(--ink); border-color: var(--gold); }
.panel-body { overflow-y: auto; padding: 14px 16px 16px; scrollbar-width: thin; scrollbar-color: var(--gold) rgba(255,255,255,.08); }
.gold-readout { font-family: var(--serif); color: var(--gold-hi); font-size: 15px; letter-spacing: .04em; }
.ch-sub { color: var(--ink-dim); font-size: 12.5px; }
button.ghost { background: transparent; color: var(--ink); border: 1px solid var(--hud-line); border-radius: 8px; padding: 6px 12px; font-size: 12.5px; cursor: pointer; touch-action: manipulation; }
button.ghost:hover { border-color: var(--gold); background: rgba(201,162,74,.12); }
button.ghost:disabled { opacity: .45; cursor: default; }

/* inventory */
.inv-layout { display: grid; grid-template-columns: 210px 1fr; gap: 18px; align-items: start; }
.paperdoll { display: grid; grid-template-columns: repeat(3, 62px); grid-auto-rows: 62px; gap: 6px; justify-content: center; padding: 8px 0;
  grid-template-areas: ". helm amulet" "gloves chest ring1" ". belt ring2" "mainhand boots offhand";
  background: radial-gradient(ellipse 60px 120px at 50% 52%, rgba(201,162,74,.10), transparent 70%); }
.eq-slot[data-eslot="helm"] { grid-area: helm; } .eq-slot[data-eslot="amulet"] { grid-area: amulet; }
.eq-slot[data-eslot="gloves"] { grid-area: gloves; } .eq-slot[data-eslot="chest"] { grid-area: chest; }
.eq-slot[data-eslot="ring1"] { grid-area: ring1; } .eq-slot[data-eslot="belt"] { grid-area: belt; }
.eq-slot[data-eslot="ring2"] { grid-area: ring2; } .eq-slot[data-eslot="mainhand"] { grid-area: mainhand; }
.eq-slot[data-eslot="boots"] { grid-area: boots; } .eq-slot[data-eslot="offhand"] { grid-area: offhand; }
.eq-slot, .inv-cell { position: relative; border-radius: 6px; background: linear-gradient(180deg, #16110f, #0c0908); border: 1px solid #3a2c1c;
  display: flex; align-items: center; justify-content: center; cursor: pointer; touch-action: manipulation; }
.eq-slot:hover, .inv-cell:hover { border-color: var(--gold); }
.eq-label { position: absolute; bottom: 3px; left: 0; right: 0; text-align: center; font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-mute); pointer-events: none; }
.eq-slot.has .eq-label { display: none; }
.item-icon { width: 78%; height: 78%; display: flex; align-items: center; justify-content: center; color: var(--rc, var(--r-common)); }
.item-icon svg { width: 100%; height: 100%; filter: drop-shadow(0 0 3px color-mix(in srgb, currentColor 60%, transparent)); }
.eq-slot.has, .inv-cell.has { border-color: color-mix(in srgb, var(--rc, #d8d8d8) 70%, #000); box-shadow: inset 0 0 10px color-mix(in srgb, var(--rc, #d8d8d8) 18%, transparent); }
.inv-cell.has.legendary { box-shadow: inset 0 0 12px rgba(255,138,42,.35), 0 0 6px rgba(255,138,42,.35); }
.inv-cell.pinned, .eq-slot.pinned { outline: 2px solid var(--gold-hi); }
.inv-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; }
.inv-cell { aspect-ratio: 1; min-width: 0; }
.inv-cell .ilvl { position: absolute; right: 3px; bottom: 1px; font-size: 9px; color: var(--ink-mute); }
.inv-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.inv-hint { font-size: 11px; color: var(--ink-mute); }

/* tooltip */
.tooltip { position: fixed; z-index: 9; width: 290px; max-width: calc(100vw - 16px); background: rgba(8, 6, 7, .97); border: 1px solid var(--tc, var(--panel-line));
  border-radius: 8px; padding: 10px 12px; font-size: 12.5px; line-height: 1.4; box-shadow: 0 12px 40px rgba(0,0,0,.8), 0 0 0 1px #000; pointer-events: none; }
.tooltip.pinned { pointer-events: auto; }
@media (max-width: 640px) {
  .tooltip.pinned { left: 8px !important; right: 8px; top: auto !important; bottom: calc(8px + env(safe-area-inset-bottom)); width: auto; max-height: 72vh; overflow-y: auto; }
}
.tt-name { font-family: var(--serif); font-size: 15px; letter-spacing: .04em; color: var(--tc, var(--ink)); margin-bottom: 2px; }
.tt-base { color: var(--ink-dim); font-size: 11.5px; }
.tt-big { font-size: 20px; font-family: var(--serif); color: #fff; margin: 4px 0 0; line-height: 1.1; }
.tt-big small { font-size: 11px; color: var(--ink-dim); font-family: var(--sans); margin-left: 6px; }
.tt-sub { color: var(--ink-dim); font-size: 11.5px; margin-bottom: 4px; }
.tt-aff { color: var(--r-magic); }
.tt-aff.leg { color: var(--r-legendary); }
.tt-power { color: var(--r-legendary); margin-top: 4px; }
.tt-flavor { color: #a89a86; font-style: italic; margin-top: 4px; font-size: 11.5px; }
.tt-req { color: #ff8a7a; margin-top: 4px; font-size: 11.5px; }
.tt-cmp { margin-top: 6px; padding-top: 6px; border-top: 1px dashed rgba(201,162,74,.25); font-size: 11.5px; }
.tt-cmp .tt-cmp-h { color: var(--ink-mute); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 2px; }
.tt-cmp .up { color: #7cf58a; } .tt-cmp .down { color: #ff7a6a; } .tt-cmp .same { color: var(--ink-mute); }
.tt-value { color: var(--gold-hi); margin-top: 4px; font-size: 11.5px; }
.tt-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.tt-actions button { flex: 1 1 auto; }
.tt-actions .danger { border-color: #7a2a2a; color: #ff9a8a; }
.tt-actions .primary-sm { border-color: var(--gold); color: var(--gold-hi); }
.tt-line { color: var(--ink); }
.tt-desc { color: var(--ink-dim); margin-top: 3px; }

/* character */
.ch-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.ch-stats { display: grid; grid-template-columns: 1fr auto; column-gap: 12px; row-gap: 3px; font-size: 12.5px; align-content: start; }
.ch-stats .st-h { grid-column: 1 / -1; font-family: var(--serif); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); margin: 8px 0 2px; border-bottom: 1px solid rgba(201,162,74,.2); }
.ch-stats .st-h:first-child { margin-top: 0; }
.ch-stats .st-l { color: var(--ink-dim); }
.ch-stats .st-v { color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.ch-stats .st-v.main { color: var(--gold-hi); font-weight: 700; }
.ch-skills { display: grid; gap: 8px; align-content: start; }
.ch-skill { display: grid; grid-template-columns: 40px 1fr; gap: 10px; align-items: start; padding: 6px 8px; border: 1px solid rgba(201,162,74,.16); border-radius: 8px; background: rgba(255,255,255,.02); }
.ch-skill .sk-ico { width: 40px; height: 40px; border-radius: 6px; background: #100c0b; border: 1px solid #3a2c1c; display: flex; align-items: center; justify-content: center; color: var(--ember-hi); }
.ch-skill .sk-ico svg { width: 70%; height: 70%; }
.ch-skill.locked .sk-ico { color: #555; }
.ch-skill b { font-family: var(--serif); font-size: 13px; letter-spacing: .04em; color: var(--ink); }
.ch-skill b small { color: var(--ink-mute); font-family: var(--sans); letter-spacing: 0; margin-left: 6px; font-weight: 400; }
.ch-skill p { margin: 2px 0 0; font-size: 11.5px; color: var(--ink-dim); line-height: 1.35; }
.ch-skill .sk-meta { font-size: 10.5px; color: var(--gold-hi); margin-top: 2px; }
.ch-skill .sk-tree { font-size: 10.5px; color: var(--r-magic); margin-top: 2px; }
.ch-toolbar { display: flex; justify-content: flex-end; margin-bottom: 10px; }

/* skill tree */
.tree-panel { width: min(760px, 96vw); }
.tree-sub { color: var(--ink-dim); font-size: 12.5px; }
.tree-sub.has { color: var(--gold-hi); }
#respecBtn { white-space: nowrap; }
.tree-note { margin: 0 0 8px; font-size: 12.5px; }
.tree-hint { margin-top: 12px; text-align: center; }
.tree-cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; align-items: start; }
.tree-col { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 6px 10px; min-width: 0;
  border: 1px solid rgba(201,162,74,.16); border-radius: 10px; background: rgba(255,255,255,.02); }
.tree-col.locked { opacity: .7; }
.tc-head { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; width: 100%; min-width: 0; min-height: 88px; }   /* a two-line name must not push the pips down */
.tc-head .sk-ico { width: 40px; height: 40px; border-radius: 6px; background: #100c0b; border: 1px solid #3a2c1c; display: flex; align-items: center; justify-content: center; color: var(--ember-hi); }
.tc-head .sk-ico svg { width: 70%; height: 70%; }
.tree-col.locked .sk-ico { color: #555; }
.tc-head b { display: block; font-family: var(--serif); font-size: 12px; letter-spacing: .04em; color: var(--ink); line-height: 1.2; max-width: 100%; }
.tc-head b small { display: block; color: var(--ink-mute); font-family: var(--sans); letter-spacing: 0; font-weight: 400; font-size: 10px; }
.tc-pips { display: flex; gap: 3px; margin-top: 4px; }
.tc-pips i { width: 9px; height: 9px; border-radius: 50%; border: 1px solid #5a4424; background: #120e0c; }
.tc-pips i.on { background: var(--gold-hi); border-color: var(--gold-hi); box-shadow: 0 0 6px rgba(242,210,122,.6); }
.tnode { position: relative; font-family: inherit; cursor: pointer; touch-action: manipulation; color: var(--ink); padding: 0;
  background: linear-gradient(180deg, #1c1614, #0d0a0a); border: 1px solid #4a3a24; border-radius: 8px; }
.tnode.rank { width: 34px; height: 34px; border-radius: 50%; margin-top: 4px; display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 18px; font-weight: 700; color: var(--gold-hi); }
.tnode.rank.maxed { font-size: 14px; border-color: var(--gold); }
.tnode.rank.lv { font-size: 9.5px; letter-spacing: .04em; font-family: var(--sans); color: var(--ink-dim); }
.tnode.rune, .tnode.passive { width: 100%; min-height: 40px; padding: 6px; font-size: 11.5px; line-height: 1.25; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; }
.tnode.passive small { color: var(--ink-mute); font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; }
.tnode:hover { border-color: var(--gold); }
.tnode.on { border-color: var(--gold-hi); color: var(--gold-hi); background: linear-gradient(180deg, #2a2012, #16100a);
  box-shadow: 0 0 12px rgba(242,210,122,.35), inset 0 0 0 1px rgba(242,210,122,.35); }
.tnode.on::after { content: "✓"; position: absolute; right: 4px; top: 1px; font-size: 10px; color: var(--gold-hi); }
.tnode.off { opacity: .5; cursor: default; }
.tnode.off:hover { border-color: #4a3a24; }
.tnode.on.off { opacity: 1; cursor: default; }
.tnode.dim { opacity: .28; }
.tnode.pinned { outline: 2px solid var(--gold-hi); }
.tree-link { width: 2px; height: 12px; background: linear-gradient(180deg, var(--gold), rgba(201,162,74,.2)); }
.tree-passives-h { margin: 14px 0 6px; font-family: var(--serif); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi);
  border-bottom: 1px solid rgba(201,162,74,.2); padding-bottom: 3px; }
.tree-passives { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 8px; }

/* quests panel */
.qp-section { margin-bottom: 14px; }
.qp-section h3 { margin: 0 0 6px; font-family: var(--serif); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); border-bottom: 1px solid rgba(201,162,74,.2); padding-bottom: 3px; }
.qp-q { padding: 8px 10px; border: 1px solid rgba(201,162,74,.16); border-radius: 8px; margin-bottom: 6px; background: rgba(255,255,255,.02); }
.qp-q b { font-family: var(--serif); letter-spacing: .04em; }
.qp-q .qp-map { font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-mute); margin-left: 8px; }
.qp-q p { margin: 3px 0 0; font-size: 12.5px; color: var(--ink-dim); line-height: 1.4; }
.qp-q .qp-prog { font-size: 12px; color: var(--gold-hi); margin-top: 3px; }
.qp-q.done { opacity: .6; } .qp-q.done b::after { content: " ✓"; color: #8ee86f; }
.qp-done { font-size: 12.5px; line-height: 1.6; }

/* shop / stash / waypoint */
.shop-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.shop-h { margin: 0 0 6px; font-family: var(--serif); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); border-bottom: 1px solid rgba(201,162,74,.2); padding-bottom: 3px; }
.shop-h small { font-family: var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink-mute); margin-left: 6px; font-size: 11px; }
.shop-grid { grid-template-columns: repeat(3, 1fr); }
.shop-grid .inv-cell .ilvl { color: var(--gold-hi); font-size: 10px; }
.stash-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.stash-grid { grid-template-columns: repeat(5, 1fr); }
.tt-price { color: var(--gold-hi); font-weight: 700; }
.wp-list { display: grid; gap: 8px; }
.wp-row { text-align: left; background: linear-gradient(180deg, #17110f, #0d0a09); border: 1px solid #3a2c1c; border-radius: 10px; padding: 10px 12px; color: var(--ink); cursor: pointer; touch-action: manipulation; display: grid; gap: 4px; }
.wp-row:hover { border-color: var(--gold); }
.wp-row.locked { opacity: .55; cursor: default; }
.wp-row .wp-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.wp-row b { font-family: var(--serif); letter-spacing: .06em; font-size: 14px; color: var(--gold-hi); }
.wp-row .wp-lv { font-size: 11px; color: var(--ink-mute); white-space: nowrap; }
.wp-row p { margin: 0; font-size: 12.5px; color: var(--ink-dim); line-height: 1.4; }
.wp-row small { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ember-hi); }
.wp-row.locked small { color: var(--ink-mute); }
.q-b.posted .q-map { color: var(--ink-mute); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; }
.xp-lv.paragon { color: var(--gold-hi); }
#rerollBtn { margin-top: 6px; }
/* waypoint: my difficulty, the group's road, the leader's right to choose it */
.wp-diff { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid rgba(201,162,74,.18); }
.wp-note { margin: 8px 0 0; font-size: 12.5px; color: var(--gold-hi); line-height: 1.4; }
.wp-note.hold { color: #ff9a8a; }
.wp-row:disabled { cursor: default; }
.wp-row.held { opacity: .5; }
.wp-row.held:hover { border-color: #3a2c1c; }
.wp-row.held small { color: var(--ink-mute); }
button.ghost.danger { border-color: #7a2a2a; color: #ff9a8a; }
button.ghost.danger:hover { background: rgba(184,32,42,.15); border-color: #b8202a; }

/* party panel (P): your group, then everybody in town */
.pty-rows { display: grid; gap: 5px; }
.pty-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 6px 10px; border-radius: 8px; background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.05); font-size: 13.5px; }
.pty-row.me { border-color: rgba(201,162,74,.35); }
.pty-row.away { opacity: .55; }
.pty-name { flex: 1 1 110px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pty-name.lead { color: var(--gold-hi); }
.pty-diff { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; border: 1px solid #3a2c1c; color: var(--ink-dim); background: #17110f; white-space: nowrap; }
.pty-diff.hard { color: var(--ember-hi); border-color: rgba(224,100,42,.5); }
.pty-diff.torment { color: #ff6a6a; border-color: rgba(184,32,42,.6); }
.pty-kick { background: none; border: 1px solid transparent; color: var(--ink-mute); font: inherit; font-size: 13px; line-height: 1; cursor: pointer; padding: 4px 7px; border-radius: 6px; touch-action: manipulation; }
.pty-kick:hover { color: #ff9a8a; border-color: #7a2a2a; }
.pty-invite { white-space: nowrap; padding: 4px 12px; }
.pty-road { margin: 8px 0 0; font-size: 12.5px; color: var(--gold-hi); line-height: 1.4; }
#ptyLeave { margin-top: 8px; }
.pty-town-h { margin-top: 16px; }
.pty-empty { margin: 0; font-size: 12.5px; line-height: 1.4; }
.pty-hint { margin-top: 12px; }
/* roster chips, shared by the character screen and the party panel */
.pr-where { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; white-space: nowrap; color: var(--ink-mute); border: 1px solid rgba(255,255,255,.08); }
.pr-where.town { color: #8ee86f; border-color: rgba(142,232,111,.3); }
.pr-where.away { color: var(--gold-hi); border-color: rgba(201,162,74,.3); }
.pr-grp { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-dim); white-space: nowrap; }
.pr-grp.lead { color: var(--gold-hi); }

/* gamble */
.gamble-line { margin: 0 0 12px; font-style: italic; color: var(--ink-dim); font-size: 13px; text-align: center; }
.gamble-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.gamble-btn { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 10px 6px 8px; background: linear-gradient(180deg, #16110f, #0c0908);
  border: 1px solid #3a2c1c; border-radius: 8px; color: var(--ink); cursor: pointer; touch-action: manipulation; }
.gamble-btn:hover { border-color: var(--gold); }
.gamble-btn:disabled { opacity: .45; cursor: default; }
.gamble-btn .gb-ico { width: 34px; height: 34px; color: var(--ink-dim); }
.gamble-btn .gb-ico svg { width: 100%; height: 100%; }
.gamble-btn b { font-size: 12px; font-family: var(--serif); letter-spacing: .04em; }
.gamble-btn small { color: var(--gold-hi); font-size: 11px; }

/* ── lobby overlay ────────────────────────────────────────────────── */
#lobbyOverlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 10; overflow-y: auto;
  padding: 12px 0;
  background: radial-gradient(1000px 600px at 50% 110%, rgba(224, 100, 42, .22), transparent 60%),
              radial-gradient(800px 500px at 50% -10%, rgba(120, 30, 20, .25), transparent 60%),
              linear-gradient(180deg, rgba(4, 3, 6, .9), rgba(8, 5, 8, .94)); }
.card { width: min(520px, 94vw); padding: 22px 22px 14px; margin: auto; background: var(--panel); border: 1px solid var(--panel-line); border-radius: 16px;
  box-shadow: 0 0 0 1px #000, 0 24px 80px rgba(0,0,0,.8), inset 0 1px 0 rgba(255,255,255,.05); text-align: center; position: relative; }
.card::before { content: ""; position: absolute; inset: 6px; border: 1px solid rgba(201,162,74,.14); border-radius: 12px; pointer-events: none; }
/* background-clip:text paints nothing outside the h1 box, so the trailing
   letter-spacing must stay inside it: symmetric padding, size capped at 52px. */
.grim-title { margin: 4px 0 2px; font-family: var(--serif); font-weight: 700; font-size: clamp(32px, 7vw, 52px); letter-spacing: .22em; line-height: 1.1; padding: 0 0 0 .22em;
  background: linear-gradient(180deg, #fff3d8 0%, #f2d27a 40%, #c9762a 75%, #7a3a12 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 0 22px rgba(224, 100, 42, .5)) drop-shadow(0 2px 0 rgba(0,0,0,.7)); }
.grim-title.small { font-size: clamp(26px, 6vw, 36px); margin-bottom: 8px; }
.grim-h2 { font-family: var(--serif); letter-spacing: .14em; color: var(--gold-hi); font-size: 20px; margin: 6px 0 10px; }
.tagline { margin: 0 0 10px; font-family: var(--serif); letter-spacing: .3em; text-transform: uppercase; font-size: 12px; color: var(--ember-hi); }
.blurb { margin: 0 0 16px; color: var(--ink-dim); font-size: 13.5px; line-height: 1.45; }
.instructions { margin: 14px 0 4px; font-size: 12px; color: var(--ink-mute); display: grid; gap: 4px; }
.instructions b { color: var(--ink-dim); }
input#nameInput { width: 100%; padding: 11px 14px; border-radius: 10px; font-size: 15px; border: 1px solid #4a3424; background: #110d0c; color: var(--ink); outline: none; margin-bottom: 10px; }
input#nameInput:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(201,162,74,.18); }
button.primary { width: 100%; padding: 12px; border: 1px solid #6a3a14; border-radius: 10px; font-family: var(--serif); font-size: 16px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  background: linear-gradient(180deg, #ff9a4a 0%, #e0642a 55%, #9a3a12 100%); color: #1c0a04; cursor: pointer; box-shadow: 0 6px 22px rgba(224, 100, 42, .35), inset 0 1px 0 rgba(255,255,255,.35);
  touch-action: manipulation; }
button.primary:hover { filter: brightness(1.08); }
button.primary:active { filter: brightness(.9); transform: translateY(1px); }
button.primary:disabled { filter: grayscale(.6) brightness(.6); cursor: default; box-shadow: none; }
.lobby-audio-wrap { display: flex; justify-content: center; margin-bottom: 8px; }
.lobby-section { text-align: left; margin: 10px 0; }
.ls-label { font-family: var(--serif); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); margin-bottom: 6px; }
/* five classes: three across, the odd row centred (flex wraps, grid would not centre it) */
.class-picker { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.class-card { position: relative; flex: 0 1 calc((100% - 16px) / 3); min-width: 0; background: linear-gradient(180deg, #17110f, #0d0a09); border: 1px solid #3a2c1c; border-radius: 10px; padding: 10px 8px 8px; color: var(--ink);
  cursor: pointer; text-align: left; display: flex; flex-direction: column; gap: 4px; min-height: 120px; touch-action: manipulation; }
.class-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; border-radius: 10px 0 0 10px; background: var(--c); }
.class-card b { font-family: var(--serif); font-size: 14px; letter-spacing: .06em; color: var(--c); }
.class-card small { font-size: 11px; color: var(--ink-dim); line-height: 1.35; flex: 1; }
.class-card .cc-lv { font-size: 11px; color: var(--gold-hi); }
.class-card .cc-lv.new { color: var(--ink-mute); }
.class-card.on { border-color: var(--c); box-shadow: 0 0 16px color-mix(in srgb, var(--c) 40%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--c) 40%, transparent); background: linear-gradient(180deg, #221712, #120d0b); }
.class-card:hover { border-color: color-mix(in srgb, var(--c) 60%, #3a2c1c); }
.diff-pills { display: flex; gap: 6px; flex-wrap: wrap; }
.diff-pills button { background: #17110f; color: var(--ink-dim); border: 1px solid #3a2c1c; border-radius: 999px; padding: 6px 14px; font-size: 12.5px; cursor: pointer; touch-action: manipulation; }
.diff-pills button.on { background: rgba(224,100,42,.25); color: var(--ember-hi); border-color: var(--ember); font-weight: 700; }
.diff-pills button:disabled { cursor: default; opacity: .6; } .diff-pills button.on:disabled { opacity: 1; }
.diff-desc { margin: 6px 0 0; font-size: 12px; min-height: 16px; }
.diff-bonus { margin: 4px 0 0; font-size: 12px; color: var(--gold-hi); min-height: 16px; line-height: 1.4; }
.ls-note { font-family: var(--sans); letter-spacing: 0; text-transform: none; font-size: 11px; }
#startNote { margin: 8px 0 0; line-height: 1.4; }
#startNote b { color: var(--gold-hi); font-family: var(--serif); }
.player-list { max-height: 200px; overflow-y: auto; }
.player-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 5px 10px; border-radius: 8px; background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.05); margin-bottom: 4px; font-size: 13.5px; }
.player-row .pr-name { flex: 1 1 110px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.player-row .pr-host { font-size: 10.5px; color: var(--gold-hi); letter-spacing: .1em; text-transform: uppercase; }
.player-row .pr-cls { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--c, var(--ink-mute)); white-space: nowrap; }
.player-row .pr-spec { font-size: 10.5px; color: var(--ink-mute); }
.player-row.me { border-color: rgba(201,162,74,.35); }
.leaderboard { text-align: left; margin-top: 12px; padding: 10px 12px; background: rgba(255,255,255,.03); border-radius: 10px; border: 1px solid rgba(201,162,74,.16); }
.leaderboard h3 { margin: 0 0 6px; font-family: var(--serif); font-size: 12px; letter-spacing: .14em; color: var(--gold-hi); text-transform: uppercase; }
.lb-row { display: grid; grid-template-columns: 22px 1fr auto; gap: 8px; font-size: 12.5px; padding: 3px 0; color: var(--ink); align-items: baseline; border-bottom: 1px solid rgba(255,255,255,.04); }
.lb-row .lb-rank { color: var(--ink-mute); }
.lb-row .lb-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-row .lb-name small { color: var(--ink-mute); margin-left: 4px; }
.lb-row .lb-right { color: var(--gold-hi); white-space: nowrap; font-variant-numeric: tabular-nums; }
.lb-row .lb-right small { color: var(--ink-mute); margin-left: 6px; font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; }
.lb-row.victory .lb-right::before { content: "⚔ "; color: #8ee86f; }
.lb-row.me { color: var(--gold-hi); }
.load-list { display: grid; gap: 8px; margin: 10px 0; text-align: left; }
.load-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; font-size: 13px; align-items: center; }
.load-row .lr-bar { grid-column: 1 / -1; height: 8px; background: #120e0c; border: 1px solid #3a2c1c; border-radius: 4px; overflow: hidden; }
.load-row .lr-bar > i { display: block; height: 100%; background: linear-gradient(90deg, #7a3a12, var(--ember-hi)); transition: width .2s; }
.load-row.done .lr-pct { color: #8ee86f; }
.countdown { font-family: var(--serif); font-size: 96px; font-weight: 700; color: var(--gold-hi); text-shadow: 0 0 30px rgba(224,100,42,.7), 0 4px 0 #000; line-height: 1; }
.back-link { display: inline-block; margin-top: 12px; color: var(--ink-mute); font-size: 13px; }
.back-link:hover { color: var(--ink-dim); }
.rank-hint { font-size: 13px; color: var(--gold-hi); margin: 8px 0 4px; font-family: var(--serif); letter-spacing: .04em; min-height: 16px; }
#resultsPane .tagline { letter-spacing: .12em; text-transform: none; font-size: 14px; }
#resultTitle.victory { background: linear-gradient(180deg, #fff8e0, #f2d27a 50%, #c9a24a); -webkit-background-clip: text; background-clip: text; }
#resultTitle.defeat { background: linear-gradient(180deg, #ffd0c8, #c8202a 55%, #5a0a10); -webkit-background-clip: text; background-clip: text; }

/* results: the wide stats table */
.card.results-wide { width: min(780px, 96vw); }
#resultTable { overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--gold) rgba(255,255,255,.12); --fs-accent: var(--gold-hi); }
#resultTable::-webkit-scrollbar { height: 6px; }
#resultTable::-webkit-scrollbar-thumb { background: rgba(201,162,74,.6); border-radius: 3px; }
#resultTable .fs-table { width: max-content; min-width: 100%; font-size: .86rem; }
#resultTable .fs-table th, #resultTable .fs-table td { padding: 6px 9px; }
#resultAwards { --fs-accent: var(--gold-hi); }

/* ── breakpoints ──────────────────────────────────────────────────── */
/* ── the skill bar picker (K) ─────────────────────────────────────── */
/* Five slots on the left, the class's nine-skill pool on the right. Both are
   buttons and both are drop targets, so the same panel works with a mouse
   (hover explains, drag moves) and with a thumb (tap arms, tap commits). */
.loadout-panel { width: min(780px, 96vw); }
.ld-sub { color: var(--ink-dim); font-size: 12.5px; }
.ld-note { margin: 0 0 8px; font-size: 12.5px; }
.ld-layout { display: grid; grid-template-columns: minmax(0, 270px) minmax(0, 1fr); gap: 16px; align-items: start; }
.ld-side { min-width: 0; }
.ld-h { margin: 0 0 6px; font-family: var(--serif); font-size: 12px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi);
  border-bottom: 1px solid rgba(201,162,74,.2); padding-bottom: 3px; }
.ld-h small { font-family: var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink-mute); font-size: 11px; }
.ld-slots { display: grid; gap: 6px; }
.ld-pool { display: grid; grid-template-columns: repeat(auto-fill, minmax(172px, 1fr)); gap: 6px; }
.ld-slot, .ld-tile { position: relative; display: grid; align-items: center; gap: 8px; text-align: left; min-width: 0; font: inherit; color: var(--ink);
  background: linear-gradient(180deg, #17110f, #0d0a09); border: 1px solid #3a2c1c; border-radius: 8px; padding: 6px 8px;
  cursor: pointer; touch-action: manipulation; }
.ld-slot { grid-template-columns: 34px 34px minmax(0, 1fr); }
.ld-tile { grid-template-columns: 30px minmax(0, 1fr) auto; }
.ld-slot:hover, .ld-tile:hover { border-color: var(--gold); }
.ld-key { font-family: var(--serif); font-size: 11px; letter-spacing: .06em; color: var(--gold-hi); text-align: center; }
.ld-ico { width: 34px; height: 34px; border-radius: 6px; background: #100c0b; border: 1px solid #3a2c1c;
  display: flex; align-items: center; justify-content: center; color: var(--ember-hi); }
.ld-ico svg { width: 68%; height: 68%; }
.ld-tile .ld-ico { width: 30px; height: 30px; }
.ld-body { min-width: 0; display: block; }
.ld-name { display: block; font-family: var(--serif); font-size: 12.5px; letter-spacing: .03em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* names and the cost line WRAP rather than ellipse: "Hammer of the Ancients"
   cut to "Hammer of the …" is not a skill anybody can choose between, and it
   was being cut in the slot column on a landscape phone and in the pool at
   360 px ("Opens at le…"). The rows are auto-height, so wrapping costs nothing.*/
.ld-name, .ld-tile .ld-meta { white-space: normal; overflow: visible; line-height: 1.15; }
.ld-meta { display: block; font-size: 10.5px; color: var(--gold-hi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ld-on { font-family: var(--serif); font-size: 10.5px; letter-spacing: .06em; color: var(--gold-hi); white-space: nowrap; }
.ld-slot.empty .ld-name, .ld-tile.locked .ld-name { color: var(--ink-mute); }
.ld-slot.empty .ld-ico, .ld-tile.locked .ld-ico { color: #4a4038; }
.ld-slot.locked { opacity: .65; }
.ld-tile.locked { opacity: .6; cursor: default; }
.ld-tile.locked .ld-on, .ld-tile.locked .ld-meta { color: var(--ink-mute); }
.ld-tile.on { border-color: color-mix(in srgb, var(--c, #f2d27a) 55%, #3a2c1c); background: linear-gradient(180deg, #221a12, #100c0a); }
.ld-slot.armed, .ld-tile.armed { border-color: var(--gold-hi); box-shadow: 0 0 0 1px var(--gold-hi), 0 0 14px rgba(242,210,122,.35); }
.ld-slot.target { border-style: dashed; border-color: var(--gold); }
.ld-slot.over { border-color: var(--ember-hi); background: rgba(224,100,42,.2); }
.ld-slot.dragging, .ld-tile.dragging { opacity: .45; }
.ld-slot.pinned, .ld-tile.pinned { outline: 2px solid var(--gold-hi); }
.ld-hint { margin-top: 12px; text-align: center; }
/* an unsaved bar is a state, and the head is where the Save button is. The
   button has to LOOK like the one thing left to do — `primary-sm` is scoped to
   `.tt-actions` and did nothing here, so a live draft and a saved bar wore the
   same button. */
.loadout-panel.dirty .panel-head h2::after { content: " •"; color: var(--ember-hi); }
#ldSaveBtn:not(:disabled) { border-color: var(--gold); color: #1a1208; font-weight: 700;
  background: linear-gradient(180deg, var(--gold-hi), var(--gold)); }
#ldSaveBtn:not(:disabled):hover { filter: brightness(1.12); }
.tree-col.on-bar { border-color: rgba(201,162,74,.42); }

/* ── paragon (inside the character sheet) ─────────────────────────── */
.ch-paragon { margin-top: 16px; padding-top: 10px; border-top: 1px solid rgba(201,162,74,.2); }
.ch-para-h { margin: 0 0 4px; display: flex; gap: 10px; align-items: baseline; font-family: var(--serif); font-size: 12px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--gold-hi); }
.ch-para-pts { margin-left: auto; font-family: var(--sans); letter-spacing: 0; text-transform: none; font-size: 11.5px; color: var(--ink-mute); }
.ch-para-pts.has { color: var(--gold-hi); font-weight: 700; }
.ch-para-note { margin: 0 0 8px; font-size: 11.5px; line-height: 1.4; color: var(--ink-mute); }
.para-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); gap: 8px; }
.para-node { min-width: 0; padding: 7px 9px 8px; border: 1px solid rgba(201,162,74,.16); border-radius: 8px; background: rgba(255,255,255,.02); }
.para-node.has { border-color: rgba(201,162,74,.4); }
.para-node.full { opacity: .78; }
.pn-top { display: flex; align-items: baseline; gap: 8px; }
.pn-top b { font-family: var(--serif); font-size: 12.5px; letter-spacing: .04em; }
.pn-have { margin-left: auto; font-size: 11.5px; color: var(--gold-hi); text-align: right; }
.pn-per { margin-top: 1px; font-size: 10.5px; color: var(--ink-mute); }
.pn-bar { height: 4px; margin: 5px 0 6px; border-radius: 2px; background: #120e0c; border: 1px solid #3a2c1c; overflow: hidden; }
.pn-bar > i { display: block; height: 100%; background: linear-gradient(90deg, #7a5a1a, var(--gold-hi)); }
.pn-btns { display: flex; gap: 6px; }
.pn-add { flex: 1 1 0; padding: 3px 0; background: #1a1412; color: var(--gold-hi); border: 1px solid #4a3a24; border-radius: 6px;
  font: inherit; font-size: 12px; cursor: pointer; touch-action: manipulation; }
.pn-add:hover { border-color: var(--gold); }
.pn-add:disabled { opacity: .4; cursor: default; color: var(--ink-mute); }

/* ── the massacre streak ──────────────────────────────────────────── */
/* Middle-right EDGE: the tracker column owns the top-right, the touch cluster
   the bottom-right, and the fight is in the middle. Never takes the pointer. */
.streak-stack { position: absolute; right: calc(12px + env(safe-area-inset-right)); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px; width: min(240px, 34vw);
  text-align: right; pointer-events: none; opacity: 0; transition: opacity .7s ease-out; }
.streak-stack.in { opacity: 1; transition: opacity .1s ease-out; }
.streak-stack.out { opacity: 0; }
.streak-row { display: flex; flex-direction: column; align-items: flex-end; line-height: 1.06; }
.sr-name { font-family: var(--serif); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: #ffd06a;
  font-size: calc(15px + var(--k, 0) * 11px);   /* 26px caps it at the box width */
  text-shadow: 0 2px 6px #000, 0 0 calc(8px + var(--k, 0) * 18px) rgba(255,138,42,.85); }
.sr-kills { font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-dim); text-shadow: 0 1px 3px #000; }
.sr-xp { font-size: 11.5px; color: #b9a5ff; text-shadow: 0 1px 3px #000; }
.streak-row.old { opacity: .45; }
.streak-row.old .sr-name { font-size: 13px; color: var(--gold); text-shadow: 0 1px 3px #000; }
.streak-row.old .sr-kills, .streak-row.old .sr-xp { display: none; }
.streak-row.pop { animation: streak-pop .45s cubic-bezier(.2, 1.6, .4, 1); }
/* the rows are POOLED and re-used, and an author `display: flex` outranks the
   UA sheet's `[hidden] { display: none }` — without this a short new chain kept
   showing the tiers of the last one under it ("MASSACRE 5 kills" over a stale
   ANNIHILATION). Hiding a spare row has to be said here, not just in JS. */
.streak-row[hidden] { display: none; }
@keyframes streak-pop { from { transform: translateX(20px) scale(.82); opacity: 0; } to { transform: none; opacity: 1; } }

/* ── sets and ancients in the item tooltip ────────────────────────── */
.tt-ancient { margin-top: 3px; font-size: 11.5px; color: var(--r-ancient); }
.tt-set { margin-top: 6px; padding-top: 6px; border-top: 1px dashed rgba(95, 224, 122, .3); }
.tt-set-name { display: flex; gap: 8px; align-items: baseline; font-family: var(--serif); font-size: 13px; letter-spacing: .04em; color: var(--r-set); }
.tt-set-name small { margin-left: auto; font-family: var(--sans); font-size: 10.5px; letter-spacing: .06em; color: var(--ink-mute); }
.tt-set-b { margin-top: 2px; font-size: 11.5px; color: #47764f; }        /* dim = not earned yet */
.tt-set-b.on { color: var(--r-set); }
.tt-set-pieces { margin-top: 4px; font-size: 10.5px; color: var(--ink-mute); }
.tt-set-pieces .sp.on { color: var(--r-set); }
.tt-set-pieces .sp.this { text-decoration: underline; }
.tt-set-pieces .sp-dot { margin: 0 4px; }
.tt-set-next { margin-top: 4px; font-size: 11.5px; color: var(--gold-hi); }
.inv-cell.has.set, .eq-slot.has.set { box-shadow: inset 0 0 12px rgba(95, 224, 122, .32), 0 0 6px rgba(95, 224, 122, .32); }
.inv-cell.has.ancient, .eq-slot.has.ancient { box-shadow: inset 0 0 12px rgba(255, 208, 106, .38), 0 0 8px rgba(255, 208, 106, .42); }

@media (max-width: 900px) {
  :root { --sk: 52px; --pot: 44px; --globe: 76px; --gap: 5px; }
  .party { width: 150px; }
  .quests { width: 170px; font-size: 11px; }
  #minimap { width: 120px; height: 120px; }
  .inv-layout { grid-template-columns: 1fr; }
  .paperdoll { grid-template-columns: repeat(3, 56px); grid-auto-rows: 56px; }
  .ch-layout { grid-template-columns: 1fr; }
}
/* phones, either orientation: the gear joins the top-right column, because
   the bottom-right corner belongs to the touch cluster */
@media (max-width: 640px), (max-height: 460px) {
  .hud-gear { position: static; align-items: flex-end; }
  .hud-gear[open] { position: relative; }
  /* the popover hangs BELOW the gear here (the column is at the top of the
     screen), so it anchors to the top edge, not to the action bar */
  .gear-body { top: 40px; bottom: auto; right: 0; z-index: 8; max-height: calc(100vh - 130px); }
  .hbtn span { display: none; }
}
@media (max-width: 640px) {
  :root { --sk: 48px; --pot: 40px; --globe: 64px; --gap: 4px; }
  #minimap { width: 100px; height: 100px; }
  #minimap.hidden { display: none; }
  .quests { width: 150px; }
  .q-b .q-map { display: none; }
  .party { width: 120px; gap: 4px; }
  .pf { grid-template-columns: 26px 1fr; padding: 3px 6px 3px 3px; gap: 6px; }
  .pf-portrait { width: 26px; height: 26px; font-size: 12px; }
  .pf-name { font-size: 11px; }
  .hbtn { padding: 5px 8px; font-size: 11px; }
  /* the dialogue card moves under the party frames: the bottom of a phone is
     spoken for by the action bar, the boss bar and the touch cluster */
  .dialogue { width: calc(100vw - 190px); bottom: auto; top: calc(104px + env(safe-area-inset-top)); left: calc(10px + env(safe-area-inset-left)); padding: 6px 10px; }
  .dl-text { font-size: 12.5px; }
  .toasts { top: 44%; left: 10px; transform: none; align-items: flex-start; width: calc(100vw - 200px); }
  .toast { text-align: left; font-size: 12.5px; }
  .area-banner { top: 34%; }
  /* boss bar at the bottom, above the action bar (Dungeon Dive's placement):
     the top row is party frames / gear / minimap and there is no room left */
  .boss-bar { top: auto; bottom: calc(var(--globe) + 26px + env(safe-area-inset-bottom)); width: calc(100vw - 24px); }
  .boss-name { font-size: 12px; margin-bottom: 2px; }
  .boss-name small { display: none; }
  .boss-track { height: 8px; }
  /* the invitation sits under the top row (party frames left, tracker column right) */
  .invite-box { top: calc(196px + env(safe-area-inset-top)); width: calc(100vw - 24px); max-width: 340px; }
  .panel { max-height: 96vh; border-radius: 10px; }
  .panel-body { padding: 10px 12px 14px; }
  /* the tree head: title, reset and close on one row, the points line on its own */
  .tree-panel .panel-head { flex-wrap: wrap; gap: 8px 10px; }
  .tree-panel .panel-head h2 { white-space: nowrap; font-size: 16px; }
  .tree-panel .tree-sub { order: 5; flex-basis: 100%; font-size: 12px; }
  #respecBtn { padding: 5px 9px; font-size: 12px; }
  .inv-grid { gap: 4px; }
  .tooltip { width: 260px; font-size: 12px; }
  .class-card { flex-basis: calc((100% - 8px) / 2); min-height: 0; }   /* two across; the overlay scrolls */
  .class-card small { font-size: 11.5px; }
  #resultTable .fs-table { font-size: .78rem; }
  .card { padding: 16px 14px 12px; }
  .gamble-grid { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .shop-layout, .stash-layout { grid-template-columns: 1fr; }
  .float { font-size: 14px; } .float.crit { font-size: 26px; } .float.mine-hit { font-size: 18px; } .float.hurt { font-size: 20px; }
  /* the target frame owns the top-centre strip: on a phone the boss bar has
     moved to the bottom, so nothing else is up there */
  .target-frame { width: calc(100vw - 250px); min-width: 150px; padding: 4px 8px 5px; }
  #hud.bossing .target-frame { top: calc(10px + env(safe-area-inset-top)); }
  .tf-name { font-size: 12px; }
  .tf-rank { display: none; }
  .buff { width: 27px; height: 27px; }
  /* chat: the bottom of a phone is spoken for, so the log joins the left
     column under the dialogue card and the entry docks over the action bar */
  .chat-wrap { top: calc(150px + env(safe-area-inset-top)); bottom: auto; width: min(62vw, 250px); }
  #hud.talking .chat-wrap { top: calc(232px + env(safe-area-inset-top)); }   /* the NPC card owns this corner for its 6 s */
  .chat-line { font-size: 11.5px; padding: 2px 6px; }
  .chat-entry { position: fixed; left: 8px; right: 8px; bottom: calc(8px + env(safe-area-inset-bottom)); z-index: 9; }
  .gear-body { width: min(300px, calc(100vw - 20px)); }
  /* the picker stacks: the bar first, then the pool under it */
  .ld-layout { grid-template-columns: 1fr; gap: 12px; }
  .ld-pool { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  .loadout-panel .panel-head { flex-wrap: wrap; gap: 8px 10px; }
  .loadout-panel .panel-head h2 { white-space: nowrap; font-size: 16px; }
  .loadout-panel .ld-sub { order: 5; flex-basis: 100%; font-size: 12px; }
  #ldSaveBtn { padding: 5px 9px; font-size: 12px; }
  .ch-toolbar { flex-wrap: wrap; gap: 6px; }
  .para-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
  /* below the tracker column, above the touch cluster, and narrow enough to
     clear the toasts on the other side of the screen */
  .streak-stack { top: 58%; right: calc(8px + env(safe-area-inset-right)); width: min(46vw, 168px); }
  /* 16px is what keeps the longest name inside 168px, and 168px is what keeps
     the stack out of the toast column on the other side of the screen */
  .sr-name { font-size: calc(12px + var(--k, 0) * 4px); }
  .sr-kills, .sr-xp { font-size: 10.5px; }
  .para-node { padding: 6px 8px 7px; }
  .pn-have { font-size: 10.5px; }
}
/* portrait phone: skills on one row, globes flank the xp bar beneath, so the
   whole bar fits a 360 px screen (5 × 48 + 40 + gaps = 296 px). */
@media (max-width: 480px) and (orientation: portrait) {
  .action-bar { grid-template-columns: auto 1fr auto; grid-template-areas: "skills skills skills" "life xp res"; gap: 8px; width: calc(100vw - 16px); }
  #xpBar { align-self: center; }
  .boss-bar { bottom: calc(var(--globe) + var(--sk) + 24px + env(safe-area-inset-bottom)); }
  .prompt { bottom: calc(var(--globe) + var(--sk) + 62px + env(safe-area-inset-bottom)); font-size: 13px; }
  /* the skills sit on their own row here, so the buff row goes above them —
     and above the boss bar when there is one (the prompt then steps up too) */
  .buff-bar { bottom: calc(var(--globe) + var(--sk) + 24px + env(safe-area-inset-bottom)); width: calc(100vw - 16px); }
  #hud.bossing .buff-bar { bottom: calc(var(--globe) + var(--sk) + 54px + env(safe-area-inset-bottom)); }
  #hud.bossing .prompt { bottom: calc(var(--globe) + var(--sk) + 92px + env(safe-area-inset-bottom)); }
  .touch-cluster { bottom: calc(var(--globe) + var(--sk) + 62px + env(safe-area-inset-bottom)); grid-template-columns: 52px 52px 52px; grid-auto-rows: 52px; gap: 8px; }
  .tbtn { width: 52px; height: 52px; } .tbtn.tbtn-big { width: 64px; height: 64px; }
  .hud-bl { bottom: calc(var(--globe) + var(--sk) + 62px + env(safe-area-inset-bottom)); flex-direction: column; flex-wrap: nowrap; max-width: none; }
}
/* landscape phone: everything is short; pull the top clutter in */
@media (max-height: 460px) {
  :root { --sk: 44px; --pot: 38px; --globe: 60px; --gap: 4px; }
  .party { width: 130px; gap: 3px; }
  .quests { width: 150px; font-size: 11px; }
  #minimap { width: 80px; height: 80px; }
  .area-banner { top: 28%; }
  .toasts { top: 40%; }
  .boss-bar { top: calc(8px + env(safe-area-inset-top)); bottom: auto; width: 50vw; }
  .invite-box { top: calc(50px + env(safe-area-inset-top)); width: min(320px, 50vw); padding: 8px 12px; }
  .dialogue { top: calc(60px + env(safe-area-inset-top)); bottom: auto; width: 240px; padding: 6px 10px; }
  .dl-text { font-size: 12px; }
  .touch-cluster { bottom: calc(10px + env(safe-area-inset-bottom)); right: calc(8px + env(safe-area-inset-right)); grid-template-columns: 48px 48px 48px; grid-auto-rows: 48px; gap: 6px; }
  .tbtn { width: 48px; height: 48px; } .tbtn.tbtn-big { width: 58px; height: 58px; }
  .action-bar { left: 45%; }
  /* landscape keeps the boss bar at the top, so the target frame steps aside */
  .target-frame { width: min(280px, 46vw); }
  /* the boss bar is 44 px tall here and keeps the top of the screen, so the
     frame has to clear its track, not start inside it */
  #hud.bossing .target-frame { top: calc(58px + env(safe-area-inset-top)); }
  .chat-wrap { top: calc(120px + env(safe-area-inset-top)); bottom: auto; width: min(46vw, 260px); }
  .panel { max-height: 96vh; }
  .paperdoll { grid-template-columns: repeat(3, 44px); grid-auto-rows: 44px; }
  .inv-layout { grid-template-columns: 160px 1fr; }
  .streak-stack { top: 52%; width: min(34vw, 190px); }
  .sr-name { font-size: calc(13px + var(--k, 0) * 7px); }
  .ld-layout { grid-template-columns: minmax(0, 220px) minmax(0, 1fr); }
}
@media (pointer: coarse) {
  .inv-hint { display: none; }
  .skill:hover { border-color: #4a3a24; }
  /* a thumb needs a target, not a 22 px strip */
  .pn-add { padding: 8px 0; font-size: 13px; }
  .ld-slot, .ld-tile { padding: 8px; }
  .ld-slot:hover, .ld-tile:hover { border-color: #3a2c1c; }
  /* every other .inv-hint is a mouse hint and rightly hidden here, but this one
     is the ONLY written statement of how the picker works, and tap-then-tap is
     the only road on a phone: hiding it hides the instructions on the device
     that needs them. */
  .ld-hint { display: block; }
}

/* ── the streak, on a touch layout ────────────────────────────────── */
/* MEASURED, not reasoned: centred on the right edge the stack landed ON the
   touch cluster at 390x844 (447-532 over a cluster at 498-670), and inside it
   at 360x640. On a phone the cluster owns the bottom-right corner, so the stack
   is anchored ABOVE it and grows upward instead. Each `bottom` mirrors
   .touch-cluster's own anchor for that breakpoint, plus the cluster's height
   (3 x 56 + 2 x 10 = 172, or 3 x 48 + 2 x 6 = 156 in landscape) and a gap. */
@media (pointer: coarse) {
  .streak-stack { top: auto; transform: none;
    bottom: calc(var(--globe) + 44px + 182px + env(safe-area-inset-bottom)); }
}
@media (pointer: coarse) and (max-width: 480px) and (orientation: portrait) {
  .streak-stack { bottom: calc(var(--globe) + var(--sk) + 62px + 182px + env(safe-area-inset-bottom)); }
}
@media (pointer: coarse) and (max-height: 460px) {
  /* landscape leaves ~57 px between the quest tracker and the cluster: one
     tier fits there, a stack of four does not */
  .streak-stack { bottom: calc(10px + 166px + env(safe-area-inset-bottom)); }
  .streak-row.old { display: none; }
}

/* The in-world copy of the board (L) sits inside a .panel-body, which already
   supplies the frame — so it drops the panel chrome the lobby copy needs. */
#boardPanel .panel-body .leaderboard { margin-top: 0; padding: 0; background: none; border: none; }
