:root {
  --panel-bg: rgba(12, 16, 28, 0.82);
  --panel-border: rgba(255, 255, 255, 0.12);
  --accent: #6ee7b7;
  --text: #e8ecf4;
  --text-dim: #9aa3b5;
  /* Gold means reward, and the control that collects it. Seeded from the
     values already hand-copied through this file so nothing shifts. */
  --gold: #fbbf24;
  --gold-soft: #f4d88a;
  --gold-deep: #8a6320;
  --gold-ink: #2a1d05;
  /* Soft periwinkle for skill rank gains (distinct from gold level-ups). */
  --skill: #b8b0ff;
  /* Dusty sage for field-herb loot names (Vale Sage, Silvernettle). */
  --sage: #b5c9a4;
  /* Party chat channel: cyan, distinct from mint accent and nametag colors. */
  --chat-party: #5ee4f0;
  /* Whisper channel: fuchsia, distinct from party cyan and system grey. */
  --chat-whisper: #e879f9;
  --done: #86efac;
  --hud-edge: 14px;
  --minimap-top: 84px;
  --minimap-size: 180px;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  color: var(--text);
  background: #0b0e17;
}

/* Shared in-world UI primitives. Feature panels compose these instead of
   inventing their own chrome, type, and control palette. */
.ui-surface {
  color: var(--text);
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}

.ui-panel-header {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 32px;
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.ui-button,
.ui-close-button {
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.05s;
}

.ui-button {
  min-height: 32px;
  padding: 7px 11px;
}

.ui-button:hover,
.ui-close-button:hover {
  border-color: var(--accent);
  background: rgba(110, 231, 183, 0.1);
}

.ui-button:active,
.ui-close-button:active {
  transform: scale(0.98);
}

.ui-button:focus-visible,
.ui-close-button:focus-visible,
.ui-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.ui-button.is-primary {
  border-color: rgba(110, 231, 183, 0.48);
  background: rgba(110, 231, 183, 0.14);
  color: #caffec;
}

.ui-button.is-primary:hover {
  background: rgba(110, 231, 183, 0.22);
}

.ui-button.is-quiet {
  border-color: transparent;
  background: transparent;
  color: var(--text-dim);
}

.ui-button.is-quiet:hover {
  border-color: var(--panel-border);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text);
}

.ui-button.is-danger {
  color: #fca5a5;
}

.ui-button.is-danger:hover {
  border-color: rgba(248, 113, 113, 0.55);
  background: rgba(248, 113, 113, 0.1);
}

.ui-close-button {
  width: 28px;
  height: 28px;
  margin-left: auto;
  padding: 0;
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
}

.ui-input {
  width: 100%;
  min-height: 36px;
  padding: 8px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  outline: none;
  color-scheme: dark;
}

.ui-input option {
  color: var(--text);
  background-color: #141824;
}

.ui-input:focus {
  border-color: var(--accent);
}

.ui-card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
}

.ui-status-pill {
  display: inline-flex;
  align-items: center;
  min-height: 20px;
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ui-modal {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: center;
  padding: 16px;
}

.ui-modal-scrim {
  position: absolute;
  inset: 0;
  background: rgba(4, 6, 12, 0.56);
  backdrop-filter: blur(3px);
}

.ui-modal-card {
  position: relative;
  width: min(420px, calc(100vw - 32px));
  padding: 14px 16px 16px;
}

#game-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.hidden {
  display: none !important;
}

/* ---------- Login overlay ---------- */

#login-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at 30% 20%, rgba(110, 231, 183, 0.10), transparent 55%),
    radial-gradient(ellipse at 75% 80%, rgba(96, 165, 250, 0.10), transparent 55%),
    #0b0e17;
  z-index: 20;
}

#login-form {
  width: min(340px, 90vw);
  padding: 34px 32px 28px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  display: flex;
  flex-direction: column;
}

#login-form h1 {
  margin: 0;
  font-size: 30px;
  letter-spacing: 2px;
  text-align: center;
  background: linear-gradient(90deg, #6ee7b7, #60a5fa);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

#login-form .subtitle {
  margin: 4px 0 22px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
  letter-spacing: 1px;
}

#login-form label {
  font-size: 12px;
  color: var(--text-dim);
  margin: 10px 0 5px;
  text-transform: uppercase;
  letter-spacing: 1px;
}

#login-form input {
  padding: 11px 12px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 15px;
  outline: none;
  transition: border-color 0.15s;
}

#login-form input:focus {
  border-color: var(--accent);
}

#login-form button {
  margin-top: 22px;
  padding: 12px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(90deg, #34d399, #3b82f6);
  color: #071018;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 1px;
  cursor: pointer;
  transition: filter 0.15s, transform 0.05s;
}

#login-form button:hover {
  filter: brightness(1.12);
}

#login-form button:active {
  transform: scale(0.98);
}

#login-error {
  min-height: 18px;
  margin: 12px 0 0;
  text-align: center;
  color: #f87171;
  font-size: 13px;
}

/* Progress panel: same card as #login-form, so the swap reads as one screen. */
#login-progress {
  width: min(340px, 90vw);
  padding: 34px 32px 30px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}

#login-progress h1 {
  margin: 0 0 24px;
  font-size: 30px;
  letter-spacing: 2px;
  text-align: center;
  background: linear-gradient(90deg, #6ee7b7, #60a5fa);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

#login-progress-track {
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--panel-border);
  overflow: hidden;
}

#login-progress-fill {
  width: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #34d399, #3b82f6);
  /* Eases between stage steps so the bar glides instead of jumping. */
  transition: width 0.25s ease-out;
}

#login-progress-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-dim);
  letter-spacing: 0.5px;
}

#login-progress-percent {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--text);
}

/* ---------- HUD ---------- */

#hud-help {
  position: relative;
  z-index: 10;
}

#help-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: min(680px, calc(100vw - 28px));
  max-height: min(84vh, 720px);
  display: flex;
  flex-direction: column;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}

#help-panel.hidden {
  display: none;
}

#help-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px 0;
}

#help-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

#help-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#help-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.1);
}

#help-body {
  padding: 12px 16px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
}

#help-desktop,
#help-touch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  align-items: stretch;
}

.help-section {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

.help-section h3 {
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--accent);
}

.help-section ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.help-section li {
  font-size: 13px;
  line-height: 1.4;
  color: var(--text-dim);
}

.help-section kbd {
  display: inline-block;
  min-width: 1.2em;
  padding: 1px 6px;
  margin-right: 2px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.35;
  text-align: center;
}

.help-tips li {
  padding-left: 0.9em;
  position: relative;
}

.help-tips li::before {
  content: '·';
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}

@media (max-width: 560px) {
  #help-panel {
    width: min(420px, calc(100vw - 24px));
  }

  #help-desktop,
  #help-touch {
    grid-template-columns: 1fr;
  }
}

/* ---------- Corner HUD actions ---------- */

#hud-top-right {
  position: fixed;
  top: 12px;
  right: var(--hud-edge);
  display: flex;
  align-items: flex-start;
  gap: 8px;
  z-index: 10;
}

#hud-top-right-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}

#fps-meter {
  min-width: 64px;
  max-width: 280px;
  padding: 8px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  text-align: center;
  line-height: 1.35;
  user-select: none;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
  pointer-events: none;
}

#fps-meter.fps-meter-hitch {
  color: var(--gold);
  border-color: rgba(232, 197, 71, 0.55);
  background: rgba(80, 40, 10, 0.72);
}

#sky-time-preview {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}

#sky-time-preview.hidden {
  display: none;
}

#sky-time-preview button {
  flex: 1;
  min-width: 0;
  padding: 5px 8px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: rgba(232, 236, 242, 0.78);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  line-height: 1.2;
}

#sky-time-preview button:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

#sky-time-preview button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

#sky-time-preview button.selected {
  color: #0f1720;
  background: var(--accent);
}

#weather-force-preview {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 2px;
  max-width: 280px;
  padding: 3px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
}

#weather-force-preview.hidden {
  display: none;
}

#weather-force-preview button {
  min-width: 0;
  padding: 4px 7px;
  border: none;
  border-radius: 999px;
  background: transparent;
  color: rgba(232, 236, 242, 0.78);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  line-height: 1.2;
}

#weather-force-preview button:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

#weather-force-preview button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

#weather-force-preview button.selected {
  color: #0f1720;
  background: var(--accent);
}

#hud-actions {
  position: fixed;
  right: var(--hud-edge);
  bottom: var(--hud-edge);
  display: flex;
  gap: 8px;
  align-items: flex-end;
  z-index: 10;
}

#hud-top-right > button {
  padding: 8px 14px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  cursor: pointer;
  transition: filter 0.15s;
}

#settings-btn,
#admin-render-btn,
#emote-menu-btn,
#style-menu-btn,
#builder-btn,
#content-menu-btn,
#damage-immunity-btn,
#spellbook-btn,
#skills-btn,
#friends-btn,
#hud-help-toggle {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 50%;
  color: var(--accent);
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.3);
  transition: filter 0.15s, border-color 0.15s, transform 0.15s;
}

#settings-btn svg,
#admin-render-btn svg,
#emote-menu-btn svg,
#style-menu-btn svg,
#builder-btn svg,
#content-menu-btn svg,
#damage-immunity-btn svg,
#spellbook-btn svg,
#skills-btn svg,
#friends-btn svg,
#hud-help-toggle svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

#hud-help-toggle svg {
  width: 26px;
  height: 26px;
  stroke-width: 2.6;
}

#hud-top-right > button:hover,
#settings-btn:hover,
#admin-render-btn:hover,
#emote-menu-btn:hover,
#style-menu-btn:hover,
#builder-btn:hover,
#content-menu-btn:hover,
#damage-immunity-btn:hover,
#spellbook-btn:hover,
#skills-btn:hover,
#friends-btn:hover,
#hud-help-toggle:hover {
  filter: brightness(1.25);
}

#settings-btn:hover,
#admin-render-btn:hover,
#emote-menu-btn:hover,
#style-menu-btn:hover,
#builder-btn:hover,
#content-menu-btn:hover,
#damage-immunity-btn:hover,
#spellbook-btn:hover,
#skills-btn:hover,
#friends-btn:hover,
#hud-help-toggle:hover {
  border-color: rgba(110, 231, 183, 0.55);
  transform: translateY(-2px);
}

#settings-btn:focus-visible,
#admin-render-btn:focus-visible,
#emote-menu-btn:focus-visible,
#style-menu-btn:focus-visible,
#builder-btn:focus-visible,
#content-menu-btn:focus-visible,
#damage-immunity-btn:focus-visible,
#spellbook-btn:focus-visible,
#skills-btn:focus-visible,
#friends-btn:focus-visible,
#hud-help-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

#settings-btn[aria-expanded='true'],
#admin-render-btn[aria-expanded='true'],
#emote-menu-btn[aria-expanded='true'],
#style-menu-btn[aria-expanded='true'],
#builder-btn[aria-expanded='true'],
#content-menu-btn[aria-expanded='true'],
#damage-immunity-btn[aria-pressed='true'],
#spellbook-btn[aria-expanded='true'],
#skills-btn[aria-expanded='true'],
#friends-btn[aria-expanded='true'],
#hud-help-toggle[aria-expanded='true'] {
  border-color: rgba(110, 231, 183, 0.72);
  background: rgba(110, 231, 183, 0.16);
}

/* ---------- Admin world builder ---------- */

body.builder-active #game-canvas {
  cursor: crosshair;
}

#builder-btn {
  color: var(--gold);
}

#hud-top-right #admin-render-btn {
  display: grid;
  place-items: center;
  flex: 0 0 42px;
  width: 42px;
  height: 42px;
  margin: 0;
  padding: 0;
  color: var(--gold);
}

#hud-top-right #admin-render-btn svg {
  display: block;
  justify-self: center;
  align-self: center;
}

#content-menu-btn {
  color: #a78bfa;
  position: relative;
}

.admin-presence-count {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #34d399;
  color: #052e1c;
  font-size: 10px;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

#content-menu-panel {
  min-width: 168px;
}

#damage-immunity-btn {
  color: #93c5fd;
}

#builder-panel {
  position: fixed;
  left: 20px;
  top: 50%;
  transform: translateY(-50%);
  width: min(310px, calc(100vw - 40px));
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px;
  background: rgba(12, 16, 28, 0.94);
  border: 1px solid rgba(251, 191, 36, 0.38);
  border-radius: 12px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(10px);
  z-index: 12;
  user-select: none;
}

#builder-header {
  display: flex;
  align-items: center;
  gap: 10px;
}

#builder-header > div {
  display: flex;
  align-items: center;
  gap: 8px;
}

#builder-title {
  font-size: 16px;
  font-weight: 700;
}

#builder-admin-badge {
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(251, 191, 36, 0.13);
  border: 1px solid rgba(251, 191, 36, 0.35);
  color: #fbbf24;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

#builder-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#builder-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.builder-tab {
  padding: 7px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.builder-tab:hover {
  border-color: rgba(251, 191, 36, 0.4);
  color: var(--text);
}

.builder-tab.selected {
  border-color: rgba(251, 191, 36, 0.58);
  background: rgba(251, 191, 36, 0.12);
  color: #fbbf24;
}

#builder-mode-paint,
#builder-mode-props {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

#builder-help,
#builder-prop-help,
#builder-save-state,
#builder-prop-save-state {
  margin: 0;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.45;
}

.builder-label {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

#builder-materials,
#builder-prop-kinds,
#builder-prop-styles,
#builder-prop-tools {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
}

#builder-prop-styles {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

#builder-prop-styles[data-count="2"] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.builder-prop-style {
  flex-direction: column;
  gap: 4px;
  padding: 8px 6px;
}

.builder-prop-style-chip {
  width: 18px;
  height: 18px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 5px;
  background-color: var(--material-color);
}

#builder-prop-count-row {
  margin: 0;
  color: var(--text-dim);
  font-size: 11px;
}

#builder-prop-count {
  color: #fbbf24;
  font-weight: 700;
}

#builder-prop-count.near-cap {
  color: #f59e0b;
}

#builder-prop-count.at-cap {
  color: #f87171;
}

#builder-prop-tools {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

#builder-prop-place-palette {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

#builder-prop-place-palette.hidden {
  display: none;
}

#builder-prop-undo {
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}

#builder-prop-undo:hover {
  border-color: rgba(251, 191, 36, 0.58);
  background: rgba(251, 191, 36, 0.09);
}

#builder-prop-undo-hint {
  margin: 0;
  color: var(--text-dim);
  font-size: 10px;
  line-height: 1.4;
}

/* ---- Pins tab ---- */

#builder-mode-pins {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#builder-mode-pins.hidden {
  display: none;
}

#builder-pin-kinds {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px;
}

#builder-pin-tools {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 7px;
}

.builder-chip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  padding: 7px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 11px;
  cursor: pointer;
}

.builder-chip:hover,
.builder-chip.selected {
  border-color: rgba(251, 191, 36, 0.58);
  background: rgba(251, 191, 36, 0.09);
}

.builder-chip i {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 4px;
}

#builder-pin-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.builder-pin-field {
  display: grid;
  grid-template-columns: 74px 1fr;
  align-items: center;
  gap: 8px;
}

.builder-pin-field input,
.builder-pin-field select {
  min-width: 0;
  padding: 6px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.28);
  color: var(--text);
  font: inherit;
  font-size: 11px;
}

.builder-pin-field input:focus,
.builder-pin-field select:focus {
  outline: none;
  border-color: rgba(251, 191, 36, 0.58);
}

.builder-pin-note {
  margin: 0;
  color: var(--text-dim);
  font-size: 10px;
  line-height: 1.4;
}

#builder-pin-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 190px;
  overflow-y: auto;
}

.builder-pin-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  font-size: 11px;
  text-align: left;
  cursor: pointer;
}

.builder-pin-row:hover,
.builder-pin-row.selected {
  border-color: rgba(251, 191, 36, 0.58);
  background: rgba(251, 191, 36, 0.09);
}

.builder-pin-row i {
  width: 10px;
  height: 10px;
  border-radius: 3px;
}

.builder-pin-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.builder-pin-xz {
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  font-size: 10px;
}

#builder-pin-count {
  color: #fbbf24;
  font-weight: 700;
}

#builder-pin-save-state {
  margin: 0;
  color: var(--text-dim);
  font-size: 10px;
}

#builder-pin-hint {
  margin: 0;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.45;
}

.builder-material,
.builder-prop-option {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 7px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 11px;
  text-align: left;
  cursor: pointer;
}

.builder-prop-option {
  justify-content: center;
  text-align: center;
}

.builder-material:hover,
.builder-material.selected,
.builder-prop-option:hover,
.builder-prop-option.selected {
  border-color: rgba(251, 191, 36, 0.58);
  background: rgba(251, 191, 36, 0.09);
}

.builder-material-chip {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 6px;
  background-color: var(--material-color);
  background-image:
    radial-gradient(circle at 30% 25%, rgba(255, 255, 255, 0.18) 0 2px, transparent 3px),
    radial-gradient(circle at 70% 70%, rgba(0, 0, 0, 0.2) 0 2px, transparent 3px);
}

#builder-radius-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 7px 10px;
}

#builder-radius {
  grid-column: 1 / -1;
  width: 100%;
  accent-color: #fbbf24;
}

#builder-radius-value {
  grid-column: 2;
  grid-row: 1;
  color: #fbbf24;
  font-size: 11px;
  font-weight: 700;
}

#builder-save-state,
#builder-prop-save-state {
  display: flex;
  align-items: center;
  gap: 7px;
}

#builder-save-state span,
#builder-prop-save-state span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #34d399;
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.65);
}

/* ---------- Admin item templates ---------- */

#item-editor-panel {
  position: fixed;
  inset: 5vh 4vw;
  display: flex;
  flex-direction: column;
  min-width: 760px;
  max-width: 1120px;
  max-height: 820px;
  margin: auto;
  padding: 14px 16px;
  background: rgba(10, 14, 25, 0.97);
  border: 1px solid rgba(167, 139, 250, 0.48);
  border-radius: 14px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.68);
  backdrop-filter: blur(12px);
  z-index: 14;
}

#item-editor-header,
#item-editor-header > div {
  display: flex;
  align-items: center;
  gap: 9px;
}

#item-editor-header {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--panel-border);
}

#item-editor-title {
  font-size: 17px;
  font-weight: 750;
}

.admin-badge {
  padding: 2px 7px;
  border: 1px solid rgba(167, 139, 250, 0.42);
  border-radius: 999px;
  background: rgba(167, 139, 250, 0.12);
  color: #c4b5fd;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

.content-readonly-badge {
  padding: 2px 7px;
  border: 1px solid rgba(251, 191, 36, 0.46);
  border-radius: 999px;
  background: rgba(251, 191, 36, 0.1);
  color: #fcd34d;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

.content-editor-readonly input[readonly],
.content-editor-readonly textarea[readonly],
.content-editor-readonly select:disabled,
.content-editor-readonly input[type="checkbox"]:disabled {
  opacity: 0.78;
  cursor: default;
}

#item-editor-close {
  margin-left: auto;
  width: 30px;
  height: 30px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 19px;
  cursor: pointer;
}

#item-editor-body {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 14px;
  min-height: 0;
  padding-top: 14px;
}

#item-editor-sidebar {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 0;
  padding-right: 12px;
  border-right: 1px solid var(--panel-border);
}

#item-editor-list-tools {
  display: flex;
  gap: 7px;
  align-items: stretch;
}

#item-editor-search,
#item-editor-form input,
#item-editor-form select,
#item-editor-form textarea {
  width: 100%;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font: inherit;
  outline: none;
}

/* Native <select> popups inherit page text color but often use a light OS
   menu — force a dark color-scheme + explicit option colors so labels stay readable. */
#item-editor-form select {
  color-scheme: dark;
}

#item-editor-form select option {
  color: #e8ecf4;
  background-color: #141824;
}

#item-editor-search {
  flex: 1;
  min-width: 0;
  padding: 9px 10px;
  font-size: 12px;
}

#item-editor-filters {
  position: relative;
  flex: 0 0 auto;
}

#item-editor-filters-btn {
  height: 100%;
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 11px;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
}

#item-editor-filters-btn:hover,
#item-editor-filters-btn[aria-expanded='true'],
#item-editor-filters-btn.active {
  border-color: rgba(167, 139, 250, 0.64);
  background: rgba(167, 139, 250, 0.11);
  color: #ddd6fe;
}

#item-editor-filters-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 168px;
  max-height: 320px;
  overflow-y: auto;
  padding: 8px;
  background: rgba(12, 16, 28, 0.98);
  border: 1px solid rgba(167, 139, 250, 0.45);
  border-radius: 10px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55);
}

#item-editor-filters-menu.hidden {
  display: none;
}

.item-editor-filters-heading {
  margin: 4px 2px 2px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.6px;
  text-transform: uppercase;
}

.item-editor-filters-heading:first-child {
  margin-top: 0;
}

.item-editor-filter-option {
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: 11px;
  text-align: left;
  cursor: pointer;
}

.item-editor-filter-option:hover,
.item-editor-filter-option.selected {
  border-color: rgba(167, 139, 250, 0.45);
  background: rgba(167, 139, 250, 0.12);
}

.item-editor-filter-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 2px;
  padding: 6px 8px;
  color: var(--text);
  font-size: 11px;
  cursor: pointer;
}

.item-editor-filter-toggle input {
  width: auto;
  accent-color: #a78bfa;
}

#item-editor-search:focus,
#item-editor-form input:focus,
#item-editor-form select:focus,
#item-editor-form textarea:focus {
  border-color: rgba(167, 139, 250, 0.72);
}

#item-editor-create-actions,
#item-editor-footer {
  display: flex;
  gap: 7px;
}

#item-editor-create-actions button,
#item-editor-footer button {
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 11px;
  font-weight: 650;
  cursor: pointer;
}

#item-editor-create-actions button:hover,
#item-editor-footer button:hover {
  border-color: rgba(167, 139, 250, 0.64);
  background: rgba(167, 139, 250, 0.11);
}

#item-editor-list {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
  overflow-y: auto;
}

.item-template-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.item-template-row:hover,
.item-template-row.selected {
  border-color: rgba(167, 139, 250, 0.5);
  background: rgba(167, 139, 250, 0.1);
}

.item-template-row.archived {
  opacity: 0.52;
}

.item-template-row strong {
  overflow: hidden;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-template-row span {
  color: var(--text-dim);
  font-size: 11px;
}

.item-template-row .template-rev {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
}

#item-editor-form {
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
  overflow-y: auto;
  padding-right: 4px;
}

#item-editor-feedback {
  padding: 7px 9px;
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 7px;
  background: rgba(248, 113, 113, 0.09);
  color: #fca5a5;
  font-size: 11px;
}

#item-editor-feedback.success {
  border-color: rgba(52, 211, 153, 0.45);
  background: rgba(52, 211, 153, 0.09);
  color: #6ee7b7;
}

#item-editor-preview {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px;
  border: 1px solid var(--panel-border);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.035);
}

#item-editor-preview img {
  width: 58px;
  height: 58px;
}

#item-editor-preview > div {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

#item-editor-preview-summary,
#item-editor-revision {
  color: var(--text-dim);
  font-size: 12px;
}

#item-editor-form.dirty #item-editor-revision {
  color: #f3c56b;
}

#item-editor-form [aria-invalid='true'] {
  border-color: #e66f6f;
  box-shadow: 0 0 0 2px rgba(230, 111, 111, 0.16);
}

.item-form-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px;
}

.item-form-grid label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.55px;
  text-transform: uppercase;
}

.item-form-grid input,
.item-form-grid select,
.item-form-grid textarea {
  padding: 7px 8px;
  font-size: 12px;
  text-transform: none;
}

.item-form-wide {
  grid-column: 1 / -1;
}

.item-editor-primary-drops {
  margin: 0;
  padding: 7px 9px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.35;
}

#item-editor-flags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 15px;
  padding: 8px 0;
  border-top: 1px solid var(--panel-border);
  border-bottom: 1px solid var(--panel-border);
}

#item-editor-save:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

#item-editor-save.saving:disabled {
  cursor: wait;
}

#item-editor-flags label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-dim);
  font-size: 12px;
}

#item-editor-flags input {
  width: auto;
  accent-color: #a78bfa;
}

#item-editor-footer {
  justify-content: flex-end;
}

#item-editor-archive {
  margin-right: auto;
  color: #fca5a5 !important;
}

#item-editor-save {
  border-color: rgba(167, 139, 250, 0.55) !important;
  background: rgba(167, 139, 250, 0.16) !important;
  color: #ddd6fe !important;
}

@media (max-width: 820px) {
  #item-editor-panel {
    inset: 2vh 2vw;
    min-width: 0;
  }

  #item-editor-body {
    grid-template-columns: 190px minmax(0, 1fr);
  }

  .item-form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------- Admin loot table editor ---------- */

#loot-editor-panel,
#shop-editor-panel {
  position: fixed;
  inset: 5vh 4vw;
  display: flex;
  flex-direction: column;
  min-width: 760px;
  max-width: 1040px;
  max-height: 820px;
  margin: auto;
  padding: 14px 16px;
  background: rgba(10, 14, 25, 0.97);
  border: 1px solid rgba(240, 171, 252, 0.45);
  border-radius: 14px;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.68);
  backdrop-filter: blur(12px);
  z-index: 14;
}

#loot-editor-header,
#shop-editor-header,
#accounts-header,
#loot-editor-header > div,
#shop-editor-header > div,
#accounts-header > div {
  display: flex;
  align-items: center;
  gap: 9px;
}

#loot-editor-header,
#shop-editor-header,
#accounts-header {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--panel-border);
}

#loot-editor-title,
#shop-editor-title,
#accounts-panel-title {
  font-size: 17px;
  font-weight: 750;
}

#loot-editor-close,
#shop-editor-close,
#accounts-close {
  margin-left: auto;
  width: 30px;
  height: 30px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 19px;
  cursor: pointer;
}

#loot-editor-body,
#shop-editor-body,
#accounts-body {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 14px;
  min-height: 0;
  padding-top: 14px;
}

#loot-editor-sidebar,
#shop-editor-sidebar,
#accounts-sidebar {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 0;
  padding-right: 12px;
  border-right: 1px solid var(--panel-border);
}

#loot-editor-list,
#shop-editor-list,
#accounts-list {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
  overflow-y: auto;
}

.loot-table-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.loot-table-row:hover,
.loot-table-row.selected {
  border-color: rgba(240, 171, 252, 0.5);
  background: rgba(240, 171, 252, 0.1);
}

.loot-table-row strong {
  font-size: 12px;
}

.loot-table-row span {
  color: var(--text-dim);
  font-size: 11px;
}

.loot-table-row .template-rev {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
}

#loot-editor-form,
#shop-editor-form,
#accounts-form {
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
  overflow-y: auto;
  padding-right: 4px;
}

#loot-editor-feedback,
#shop-editor-feedback,
#accounts-feedback {
  padding: 7px 9px;
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 7px;
  background: rgba(248, 113, 113, 0.09);
  color: #fca5a5;
  font-size: 12px;
}

#loot-editor-feedback.success,
#shop-editor-feedback.success,
#accounts-feedback.success {
  border-color: rgba(52, 211, 153, 0.45);
  background: rgba(52, 211, 153, 0.09);
  color: #6ee7b7;
}

#loot-editor-summary,
#shop-editor-summary {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

#accounts-summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.accounts-identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

#accounts-title {
  font-size: 16px;
  font-weight: 750;
  line-height: 1.2;
}

#accounts-badges {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.account-badge.is-online {
  color: #6ee7b7;
  border-color: rgba(52, 211, 153, 0.4);
  background: rgba(52, 211, 153, 0.12);
}

.account-badge.is-admin {
  color: #ddd6fe;
  border-color: rgba(167, 139, 250, 0.45);
  background: rgba(167, 139, 250, 0.14);
}

.account-badge.is-immune {
  color: #93c5fd;
  border-color: rgba(147, 197, 253, 0.4);
  background: rgba(147, 197, 253, 0.12);
}

.account-badge.is-banned {
  color: #fca5a5;
  border-color: rgba(248, 113, 113, 0.45);
  background: rgba(248, 113, 113, 0.12);
}

#loot-editor-revision,
#shop-editor-revision {
  color: var(--text-dim);
  font-size: 12px;
}

#loot-editor-form.dirty #loot-editor-revision,
#shop-editor-form.dirty #shop-editor-revision {
  color: #f3c56b;
}

/* A stock list is far shorter than a loot table: hug the content instead of
   inheriting the loot panel's full-height box. */
#shop-editor-panel {
  inset: 8vh 4vw auto;
  max-width: 720px;
  min-width: 520px;
}

.loot-gold-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}

.loot-gold-grid label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.55px;
  text-transform: uppercase;
}

.loot-gold-grid input,
.loot-drop-row input,
.loot-drop-row select,
.shop-stock-row select,
.shop-stock-row input {
  width: 100%;
  padding: 7px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  outline: none;
  color-scheme: dark;
}

.loot-drop-row select option,
.shop-stock-row select option {
  color: #e8ecf4;
  background-color: #141824;
}

.loot-drops-head,
.loot-drop-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1.6fr) 76px 56px 56px 56px 56px 34px;
  gap: 7px;
  align-items: center;
}

.loot-drops-head {
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.55px;
  text-transform: uppercase;
}

.loot-drops-head span:first-child {
  grid-column: 1 / span 2;
}

#loot-editor-drops,
#shop-editor-drops {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.loot-drop-icon {
  width: 36px;
  height: 36px;
  min-width: 36px;
  padding: 0;
  overflow: hidden;
}

.loot-drop-icon .inv-item,
.loot-drop-icon img {
  width: 100%;
  height: 100%;
}

.shop-stock-head,
.shop-stock-row {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr) 84px 34px;
  gap: 7px;
  align-items: center;
}

.shop-stock-head {
  padding: 0 2px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.55px;
  text-transform: uppercase;
}

.loot-drop-remove {
  width: 34px;
  height: 34px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: #fca5a5;
  font-size: 16px;
  cursor: pointer;
}

#loot-editor-add-drop,
#shop-editor-add-stock {
  align-self: flex-start;
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
}

#loot-editor-add-drop:hover,
#shop-editor-add-stock:hover,
#loot-editor-footer button:hover,
#shop-editor-footer button:hover {
  border-color: rgba(240, 171, 252, 0.64);
  background: rgba(240, 171, 252, 0.11);
}

.loot-editor-preview {
  margin: 0;
  padding: 7px 9px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.4;
}

#loot-editor-footer,
#shop-editor-footer {
  display: flex;
  justify-content: flex-end;
  gap: 7px;
}

#loot-editor-footer button,
#shop-editor-footer button {
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
}

#loot-editor-save {
  border-color: rgba(240, 171, 252, 0.55) !important;
  background: rgba(240, 171, 252, 0.16) !important;
  color: #f5d0fe !important;
}

/* Shop editor is the same primary action in the purple of the admin content
   button, rather than the loot editor's pink. */
#shop-editor-save {
  border-color: rgba(167, 139, 250, 0.55) !important;
  background: rgba(167, 139, 250, 0.16) !important;
  color: #ddd6fe !important;
}

#loot-editor-save:disabled,
#shop-editor-save:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

#loot-editor-save.saving:disabled,
#shop-editor-save.saving:disabled {
  cursor: wait;
}

/* ---------- Admin ops console ---------- */

#accounts-panel {
  position: fixed;
  top: 10vh;
  left: 50%;
  transform: translateX(-50%);
  width: 880px;
  height: 560px;
  display: flex;
  flex-direction: column;
  min-width: 720px;
  max-width: 96vw;
  max-height: 90vh;
  padding: 12px 14px;
  border-color: rgba(240, 171, 252, 0.4);
  z-index: 14;
  overflow: hidden;
}

#accounts-body,
#admin-run-pane {
  flex: 1;
  min-height: 0;
}

#accounts-form {
  overflow-y: auto;
}

#accounts-header {
  flex: none;
  justify-content: space-between;
}

.admin-ops-title {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.admin-seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--panel-border);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.03);
}

.admin-seg .ui-button {
  min-height: 26px;
  padding: 4px 10px;
}

.admin-seg .ui-button.is-active,
.admin-seg .ui-button[aria-selected='true'] {
  background: rgba(167, 139, 250, 0.18);
  border-color: rgba(167, 139, 250, 0.45);
  color: #ddd6fe;
}

#accounts-filters {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
}

#accounts-search,
#accounts-filter-seg {
  grid-column: 1 / -1;
}

#accounts-filter-seg {
  display: flex;
}

#accounts-filter-seg .ui-button {
  flex: 1;
}

#accounts-refresh {
  min-width: 32px;
  min-height: 32px;
  padding: 4px 8px;
}

#accounts-sort {
  width: 100%;
  min-width: 0;
  min-height: 32px;
  padding: 4px 8px;
}

.account-row strong {
  display: flex;
  align-items: center;
  gap: 6px;
}

.account-row > strong,
.account-row > span {
  grid-column: 1;
}

.account-row > .account-badge {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  font-size: 10px;
}

.account-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #34d399;
  box-shadow: 0 0 6px rgba(52, 211, 153, 0.7);
  flex: none;
}

.account-list-empty {
  margin: 8px 4px;
  color: var(--text-dim);
  font-size: 12px;
}

#accounts-toolbar {
  display: flex;
  flex: none;
  gap: 6px;
}

.admin-icon-btn {
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  padding: 0;
  display: grid;
  place-items: center;
}

.admin-icon-btn svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.admin-icon-btn.is-on {
  color: #93c5fd;
  border-color: rgba(147, 197, 253, 0.55);
  background: rgba(147, 197, 253, 0.16);
}

#accounts-facts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 6px;
}

.account-fact {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 7px 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
}

.account-fact-label {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.account-fact-value {
  overflow: hidden;
  color: var(--text);
  font-size: 13px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#accounts-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 2px;
}

.account-action {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.account-action-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}

.account-field {
  display: flex;
  flex: 1 1 108px;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.account-field .ui-input {
  min-height: 32px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.account-action-row > .ui-button,
.account-action-row > .ui-input {
  flex: 0 0 auto;
}

.account-action-row > .ui-input {
  flex: 1 1 140px;
  min-height: 32px;
}

.account-note {
  margin: 0;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.4;
}

#accounts-pw-result {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  color: var(--text-dim);
  font-size: 12px;
}

#accounts-pw-value {
  color: var(--text);
}

.account-history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.account-history-head h4 {
  margin: 0;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.account-history-head label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text-dim);
  font-size: 11px;
}

#accounts-history {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 180px;
  margin: 8px 0 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

#accounts-history li {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  color: var(--text-dim);
  font-size: 11px;
}

#accounts-history time {
  flex: none;
  opacity: 0.8;
}

.account-history-empty {
  color: var(--text-dim);
  font-size: 12px;
}

#admin-run-pane {
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden;
  padding-top: 14px;
}

#admin-run-tabs {
  flex: none;
  align-self: flex-start;
}

.admin-run-section {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.admin-run-tools {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  gap: 6px;
}

.admin-run-tools .ui-input {
  flex: 1 1 160px;
  min-height: 32px;
}

.admin-run-tools .ui-button.is-active {
  background: rgba(167, 139, 250, 0.18);
  border-color: rgba(167, 139, 250, 0.45);
  color: #ddd6fe;
}

.admin-run-grid {
  display: grid;
  flex: 1;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 8px;
  align-content: start;
  min-height: 0;
  overflow-y: auto;
}

.admin-run-grid > .account-note {
  grid-column: 1 / -1;
  margin: 8px 2px;
}

.admin-run-groups {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  min-height: 0;
  overflow-y: auto;
}

.admin-run-group-title {
  margin: 0 0 6px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.admin-run-groups .admin-run-grid {
  flex: none;
  overflow: visible;
}

.admin-run-groups > .account-note {
  margin: 8px 2px;
}

.admin-run-card {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  grid-template-rows: auto auto;
  gap: 4px 8px;
  align-items: center;
  padding: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
}

/* .inv-item is absolute/inset for bag slots; without a sized relative box it
   fills the whole Admin window (one giant item icon, actions clipped). */
.admin-run-card > .inv-item {
  position: relative;
  inset: auto;
  grid-row: 1 / span 2;
  width: 36px;
  height: 36px;
  pointer-events: auto;
}

.admin-run-card-name {
  overflow: hidden;
  font-size: 12px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin-run-card-actions {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
}

.admin-run-card-actions .ui-button {
  min-height: 26px;
  padding: 3px 8px;
}

.admin-run-coords {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.admin-run-coords .ui-input {
  width: 96px;
  min-height: 32px;
}

/* ---------- Appearance editor ---------- */

#style-panel {
  position: fixed;
  top: 50%;
  left: auto;
  right: 24px;
  transform: translateY(-50%);
  width: min(360px, 92vw);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 12;
  user-select: none;
}

#style-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

#style-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#style-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#style-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.1);
}

.style-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.style-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.style-hair-cycle {
  display: flex;
  align-items: center;
  gap: 10px;
}

.style-hair-cycle button {
  width: 32px;
  height: 32px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--accent);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.style-hair-cycle button:hover {
  background: rgba(255, 255, 255, 0.12);
}

.style-choice-row {
  flex-wrap: wrap;
}

.style-choice-row button {
  flex: 1 1 auto;
  min-width: 62px;
  padding-inline: 8px;
  font-size: 11px;
}

.style-choice-row button.selected,
.style-choice-row button[aria-pressed="true"] {
  color: #f5eedc;
  border-color: #9f8250;
  background: rgba(111, 90, 54, 0.7);
}

#style-lashes-toggle {
  width: auto;
  padding: 0 14px;
  font-size: 14px;
}

#style-lashes-toggle[aria-pressed='true'] {
  border-color: var(--accent);
  color: var(--accent);
}

#style-hair-name {
  flex: 1;
  text-align: center;
  font-size: 15px;
  font-weight: 600;
}

.style-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.style-swatch {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: 2px solid rgba(255, 255, 255, 0.15);
  padding: 0;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}

.style-swatch:hover {
  filter: brightness(1.1);
}

.style-swatch.selected {
  border-color: var(--accent);
  box-shadow:
    0 0 0 2px rgba(110, 231, 183, 0.35),
    inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}

.style-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

.style-actions button {
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.style-actions button:hover:not(:disabled) {
  filter: brightness(1.15);
}

#style-apply {
  background: rgba(110, 231, 183, 0.18);
  border-color: rgba(110, 231, 183, 0.45);
  color: var(--accent);
}

#style-apply:disabled {
  opacity: 0.45;
  cursor: default;
}

#emote-menu,
#content-menu {
  position: relative;
}

#emote-menu-panel,
#content-menu-panel {
  position: absolute;
  top: auto;
  bottom: calc(100% + 8px);
  right: 0;
  min-width: 120px;
  padding: 8px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

#emote-menu-panel.hidden,
#content-menu-panel.hidden {
  display: none;
}

#emote-menu-panel button,
#content-menu-panel button {
  padding: 8px 12px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

#emote-menu-panel button:hover,
#content-menu-panel button:hover {
  background: rgba(255, 255, 255, 0.08);
}

#walk-indicator {
  position: fixed;
  bottom: 168px;
  left: 50%;
  transform: translateX(-50%);
  padding: 4px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  z-index: 10;
  pointer-events: none;
}

#walk-indicator.hidden {
  display: none;
}

/* ---------- Minimap + full map ---------- */

#minimap {
  position: fixed;
  top: var(--minimap-top);
  left: var(--hud-edge);
  width: var(--minimap-size);
  height: var(--minimap-size);
  border: 2px solid rgba(168, 181, 169, 0.72);
  border-radius: 50%;
  background: #203a2b;
  box-shadow:
    0 10px 30px rgba(0, 0, 0, 0.42),
    inset 0 0 22px rgba(0, 0, 0, 0.38);
  overflow: hidden;
  /* Interactive so it can be dragged and right-clicked anywhere (uiLayout.js).
     The cost is that hold-RMB look will not *start* with the cursor over the
     minimap, exactly like every other panel. Once a look is underway the
     pointer is locked, so crossing this corner mid-turn changes nothing. */
  pointer-events: auto;
  user-select: none;
  z-index: 9;
}

#minimap.hidden {
  display: none;
}

/* Transparent period/weather strip above the minimap (quest-tracker chrome).
   map.js pin-follows getBoundingClientRect each frame; defaults match until drag. */
#minimap-chrono {
  position: fixed;
  top: calc(var(--minimap-top) - 22px);
  left: var(--hud-edge);
  width: var(--minimap-size);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  z-index: 9;
  pointer-events: none;
  user-select: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
  font: 600 12px/1.2 'Segoe UI', system-ui, sans-serif;
  color: rgba(232, 236, 242, 0.92);
  white-space: nowrap;
  box-sizing: border-box;
}

#minimap-chrono.hidden,
#minimap.hidden + #minimap-chrono {
  display: none;
}

.minimap-chrono-period {
  letter-spacing: 0.02em;
}

.minimap-chrono-label {
  color: rgba(232, 236, 242, 0.78);
  font-weight: 500;
  font-size: 11px;
}

.minimap-chrono-weather {
  flex: 0 0 14px;
  width: 14px;
  height: 14px;
  position: relative;
}

.minimap-chrono-weather::before {
  content: '';
  position: absolute;
  inset: 0;
  background: currentColor;
  -webkit-mask: no-repeat center / contain;
  mask: no-repeat center / contain;
}

.minimap-chrono-weather[data-stage='clear'] {
  display: none;
}

.minimap-chrono-weather[data-stage='overcast'],
.minimap-chrono-weather[data-stage='mist'] {
  color: #b8c4d0;
}
.minimap-chrono-weather[data-stage='overcast']::before,
.minimap-chrono-weather[data-stage='mist']::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 18a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 18H6.5z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 18a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 18H6.5z'/%3E%3C/svg%3E");
}

.minimap-chrono-weather[data-stage='drizzle'],
.minimap-chrono-weather[data-stage='rain'],
.minimap-chrono-weather[data-stage='pour'] {
  color: #9eb8d4;
}
.minimap-chrono-weather[data-stage='drizzle']::before,
.minimap-chrono-weather[data-stage='rain']::before,
.minimap-chrono-weather[data-stage='pour']::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 14a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 14H6.5zM8 16.2l-1 3.3h1.2l1-3.3zm4 0l-1 3.3h1.2l1-3.3zm4 0l-1 3.3h1.2l1-3.3z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 14a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 14H6.5zM8 16.2l-1 3.3h1.2l1-3.3zm4 0l-1 3.3h1.2l1-3.3zm4 0l-1 3.3h1.2l1-3.3z'/%3E%3C/svg%3E");
}

.minimap-chrono-weather[data-stage='storm'] {
  color: #e8d48a;
}
.minimap-chrono-weather[data-stage='storm']::before {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 13a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 13h-5.2l1.8-4.2h-2.3L9.8 16h2.4L11 20.5 16.2 13H6.5z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='black' d='M6.5 13a4.5 4.5 0 0 1-.4-9 6 6 0 0 1 11.6-1.5A4.2 4.2 0 0 1 19 13h-5.2l1.8-4.2h-2.3L9.8 16h2.4L11 20.5 16.2 13H6.5z'/%3E%3C/svg%3E");
}

#admin-position-readout {
  position: fixed;
  top: calc(var(--minimap-top) + var(--minimap-size) + 8px);
  left: var(--hud-edge);
  width: var(--minimap-size);
  padding: 4px 6px;
  background: rgba(12, 16, 28, 0.82);
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  color: var(--gold);
  font: 700 11px/1.2 ui-monospace, SFMono-Regular, Consolas, monospace;
  letter-spacing: 0.02em;
  text-align: center;
  white-space: nowrap;
  z-index: 9;
  pointer-events: none;
  user-select: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}

#admin-position-readout.hidden,
#minimap.hidden ~ #admin-position-readout {
  display: none;
}

#minimap-canvas,
#map-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.map-north {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  color: #f8fafc;
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.9);
  pointer-events: none;
}

#map-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(4, 8, 12, 0.58);
  backdrop-filter: blur(3px);
  z-index: 14;
  user-select: none;
}

#map-overlay.hidden {
  display: none;
}

#map-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  max-width: calc(100vw - 36px);
  max-height: calc(100vh - 36px);
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.62);
}

#map-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
}

.map-header-left {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

#map-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#map-shortcut {
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
}

#map-zone {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text);
  text-align: center;
  white-space: nowrap;
}

#map-close {
  justify-self: end;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#map-close:hover {
  color: var(--text);
  border-color: var(--accent);
}

#map-canvas-wrap {
  position: relative;
  width: min(72vmin, 720px);
  max-width: calc(100vw - 66px);
  aspect-ratio: 1;
  border: 1px solid rgba(168, 181, 169, 0.65);
  border-radius: 8px;
  overflow: hidden;
  background: #203a2b;
}

#map-admin-hint {
  position: absolute;
  left: 10px;
  bottom: 10px;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(16, 22, 20, 0.78);
  color: var(--text);
  font-size: 11px;
  pointer-events: none;
}

#map-player-tip {
  position: fixed;
  z-index: 22;
  padding: 4px 8px;
  border-radius: 6px;
  background: rgba(10, 14, 24, 0.94);
  border: 1px solid var(--panel-border);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
  pointer-events: none;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
  white-space: nowrap;
}

#map-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 18px;
  color: var(--text-dim);
  font-size: 11px;
}

#map-legend span {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.map-key {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.8);
}

.map-key-you {
  background: #34d399;
}

.map-key-player {
  background: #60a5fa;
}

.map-key-fire {
  background: #f59e0b;
}

.map-key-vendor {
  border-radius: 2px;
  background: #6ee7b7;
}

.map-key-pond {
  background: #4aa6a0;
  border-color: #c5eadc;
}

.map-key-quest {
  background: #fbbf24;
  border-color: #3b2606;
}

@media (max-width: 720px), (max-height: 620px) {
  :root {
    --minimap-size: 144px;
  }

  #hud-actions {
    bottom: 86px;
  }

  #hotbar-2 {
    gap: 3px;
    padding: 6px;
    max-height: calc(100vh - 200px);
  }

  #hotbar-2 .hotbar-slot {
    width: 40px;
    height: 40px;
  }

  #map-panel {
    gap: 7px;
    padding: 10px;
  }

  #map-canvas-wrap {
    width: min(68vmin, 620px);
  }
}

/* ---------- Draggable / lockable windows (uiLayout.js) ---------- */

/* Every registered window gets .ui-draggable and its handle .ui-handle. Panels
   use their existing title bar; the minimap, the quest tracker, and chat have
   no title bar, so the whole element is the handle (drag or right-click
   anywhere in them) rather than carrying a visible grip badge that would
   clutter the HUD. */
.ui-handle {
  cursor: grab;
  touch-action: none;
  user-select: none;
}

.ui-draggable.dragging {
  box-shadow: 0 26px 64px rgba(0, 0, 0, 0.62);
}

.ui-draggable.dragging .ui-handle {
  cursor: grabbing;
}

.ui-draggable.ui-locked .ui-handle {
  cursor: default;
}

/* Text fields inside a whole-element handle keep their own cursor and let you
   select what you typed; uiLayout also refuses to start a drag on them. */
.ui-handle input,
.ui-handle textarea,
.ui-handle select {
  cursor: auto;
  user-select: auto;
}

#ui-context-menu {
  position: fixed;
  /* Above party (34) and other HUD panels; below dungeon loading / death. */
  z-index: 50;
  min-width: 150px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  backdrop-filter: blur(8px);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.55);
}

#ui-context-menu.hidden {
  display: none;
}

#action-sheet {
  position: fixed;
  z-index: 31;
  min-width: 160px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  backdrop-filter: blur(8px);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.55);
}

#action-sheet.hidden {
  display: none;
}

.action-sheet-item {
  padding: 10px 12px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}

.action-sheet-item:hover,
.action-sheet-item:active {
  background: rgba(255, 255, 255, 0.08);
}

.ui-context-item {
  padding: 7px 10px;
  border: none;
  border-radius: 6px;
  background: none;
  color: var(--text);
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.ui-context-item:hover {
  background: rgba(255, 255, 255, 0.09);
}

.ui-context-item.is-active {
  color: var(--accent);
}

.ui-context-item.is-danger {
  color: #fca5a5;
}

.ui-context-item.is-danger:hover {
  background: rgba(248, 113, 113, 0.1);
}

.ui-context-sep {
  height: 1px;
  margin: 3px 4px;
  background: var(--panel-border);
}

/* Chat SE resize grip: only while unlocked. The host already positions
   itself (fixed); absolute children resolve against that box. */
.ui-resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  touch-action: none;
  z-index: 2;
  /* Two-bar corner mark, faint until hover. */
  background:
    linear-gradient(135deg, transparent 55%, rgba(255, 255, 255, 0.35) 55%, rgba(255, 255, 255, 0.35) 62%, transparent 62%),
    linear-gradient(135deg, transparent 70%, rgba(255, 255, 255, 0.35) 70%, rgba(255, 255, 255, 0.35) 78%, transparent 78%);
  opacity: 0.45;
}

.ui-resize-handle:hover,
.ui-draggable.resizing .ui-resize-handle {
  opacity: 0.95;
}

.ui-draggable.ui-locked .ui-resize-handle {
  display: none;
}

/* ---------- Admin render window (draggable) ---------- */

#admin-render-panel {
  position: fixed;
  top: 72px;
  right: 18px;
  width: 340px;
  padding: 0 0 10px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.5);
  z-index: 13;
  user-select: none;
}

#admin-render-panel.hidden {
  display: none;
}

/* Cursor + drag shadow come from the shared .ui-handle / .ui-draggable rules. */
#admin-render-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--panel-border);
}

#admin-render-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

#admin-render-badge {
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(110, 231, 183, 0.16);
  color: var(--accent);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

#admin-render-close {
  margin-left: auto;
  width: 24px;
  height: 24px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

#admin-render-close:hover {
  color: var(--text);
}

#admin-render-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 12px 0;
}

.admin-win-section {
  margin: 6px 0 0;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.admin-win-section:first-child {
  margin-top: 0;
}

.admin-win-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.admin-win-field-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text-dim);
}

.admin-win-perf-live {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
}

.admin-win-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 14px;
}

.admin-win-stat,
.admin-win-phase {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
}

.admin-win-stat span,
.admin-win-phase span {
  color: var(--text-dim);
}

.admin-win-stat b,
.admin-win-phase b {
  color: var(--accent);
  font-weight: 650;
  text-align: right;
}

.admin-win-phases {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-top: 6px;
  border-top: 1px solid var(--panel-border);
}

.admin-win-phase.is-head span,
.admin-win-phase.is-head b {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text-dim);
}

.admin-win-perf-baseline {
  margin: 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.admin-win-perf-log {
  margin: 0;
  max-height: 120px;
  overflow: auto;
  padding: 8px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(0, 0, 0, 0.28);
  color: var(--text-dim);
  font-size: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  white-space: pre-wrap;
  user-select: text;
}

.admin-win-perf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-self: stretch;
}

.admin-win-perf-copy {
  padding: 5px 10px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}

.admin-win-perf-copy:hover {
  background: rgba(255, 255, 255, 0.1);
}

.admin-win-strips {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The strips were right-aligned corner furniture; inside the window they read
   left-to-right like every other row. */
.admin-win-strips #sky-time-preview,
.admin-win-strips #weather-force-preview {
  justify-content: flex-start;
  max-width: none;
  box-shadow: none;
}

.admin-win-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 2px;
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
}

.admin-win-row input[type='checkbox'] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

.admin-win-row select {
  padding: 4px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 11px;
  cursor: pointer;
}

.admin-win-diag {
  margin: 4px 2px 0;
  font-size: 10px;
  line-height: 1.35;
  color: var(--text-dim, #a8b5a9);
  word-break: break-word;
}

.admin-win-note {
  margin: 8px 2px 0;
  font-size: 10px;
  line-height: 1.4;
  color: var(--text-dim);
}

.admin-win-warn {
  color: #d4a15c;
}

/* ---------- Settings panel ---------- */

#settings-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(880px, 96vw);
  max-height: min(78vh, 640px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 16px 16px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 14;
}

#settings-panel.hidden {
  display: none;
}

#settings-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

#settings-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#settings-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#settings-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.1);
}

#settings-body {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 14px;
  min-height: 0;
}

#settings-rail {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.settings-tab {
  padding: 8px 10px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--text-dim);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-align: left;
  cursor: pointer;
}

.settings-tab:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
}

.settings-tab.selected {
  color: var(--accent);
  border-color: var(--panel-border);
  background: rgba(255, 255, 255, 0.07);
}

#settings-sections {
  overflow-y: auto;
  padding-right: 4px;
  min-height: 0;
}

.settings-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.settings-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 9px 4px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  cursor: pointer;
}

.settings-row-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.settings-row-label {
  font-size: 13px;
  color: var(--text);
}

.settings-row-hint {
  font-size: 11px;
  line-height: 1.35;
  color: var(--text-dim);
}

.settings-toggle {
  width: 17px;
  height: 17px;
  accent-color: var(--accent);
  cursor: pointer;
}

.settings-range {
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-range input[type='range'] {
  width: 132px;
  accent-color: var(--accent);
  cursor: pointer;
}

.settings-range output {
  min-width: 40px;
  font-size: 12px;
  color: var(--text-dim);
  text-align: right;
}

.settings-select,
.settings-bind {
  padding: 6px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
}

.settings-bind {
  min-width: 92px;
  font-weight: 600;
  letter-spacing: 0.4px;
}

.settings-bind.capturing {
  color: var(--accent);
  border-color: rgba(110, 231, 183, 0.55);
}

/* Keybinds flow into two columns so the Controls tab stops needing a scrollbar:
   the panel has plenty of width and the rows are short. */
.settings-binds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  column-gap: 24px;
  align-content: start;
}

.settings-note,
.settings-now-playing,
.settings-version {
  margin: 8px 4px 4px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--text-dim);
}

/* Build footer: pushed to the bottom of the section and set apart by a rule,
   since it is a fact about the client rather than another preference. */
.settings-version {
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--panel-border);
  opacity: 0.75;
  letter-spacing: 0.02em;
}

.settings-reset {
  align-self: flex-start;
  margin: 6px 4px;
  padding: 6px 12px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 12px;
  cursor: pointer;
}

.settings-reset:hover {
  color: var(--text);
}

/* ---------- In-world chat bubbles ---------- */

/* Bubbles are screen space, not world geometry: they hold one constant apparent
   size at every distance instead of ballooning as you walk up to someone. The
   layer sits in the minimap / tracker band, under every panel, and never eats a
   click. chatBubbles.js positions each child with transform. */
#chat-bubble-layer {
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  overflow: hidden;
}

.chat-bubble {
  position: absolute;
  left: 0;
  top: 0;
  max-width: 220px;
  padding: 5px 10px;
  /* Frosted paper: light enough that the world peeks through, with a short blur
     so ink stays readable over grass, water, or a busy silhouette. */
  background: rgba(252, 252, 254, 0.68);
  border: 1px solid rgba(20, 26, 40, 0.12);
  border-radius: 10px;
  color: #161a24;
  font-size: 13px;
  line-height: 1.35;
  text-align: center;
  backdrop-filter: blur(5px);
  -webkit-backdrop-filter: blur(5px);
  /* Soft lift only. A heavy shadow made the bubble read as a solid sticker. */
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  /* Two lines, then ellipsis. The transcript carries the full message. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
  will-change: transform, opacity;
}

/* Tail toward the speaker (left side). Drawn as two stacked triangles so the
   1px border reads as a continuous outline around the point. Fill matches the
   bubble body. */
.chat-bubble::before,
.chat-bubble::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  margin-top: -6px;
}

.chat-bubble::before {
  left: -7px;
  border-right: 7px solid rgba(20, 26, 40, 0.12);
}

.chat-bubble::after {
  left: -5px;
  border-right: 7px solid rgba(252, 252, 254, 0.68);
}

/* ---------- Chat ---------- */

#chat {
  position: fixed;
  left: 14px;
  bottom: 14px;
  width: min(360px, 85vw);
  display: flex;
  flex-direction: column;
  gap: 6px;
  z-index: 10;
  /* Settings "chat opacity". The input keeps full opacity so a faded transcript
     never makes the thing you type into hard to read. */
  --chat-opacity: 1;
  /* Text size presets (uiLayout right-click menu). Small = today's sizes. */
  --chat-font: 13.5px;
  --chat-input-font: 14px;
}

#chat[data-text-size="md"] {
  --chat-font: 15.5px;
  --chat-input-font: 16px;
}

#chat[data-text-size="lg"] {
  --chat-font: 17.5px;
  --chat-input-font: 18px;
}

#chat-messages {
  opacity: var(--chat-opacity);
  max-height: 220px;
  overflow-y: auto;
  padding: 10px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  font-size: var(--chat-font);
  line-height: 1.5;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
}

#chat-messages .msg {
  overflow-wrap: break-word;
}

#chat-messages .msg .name {
  font-weight: 700;
}

#chat-messages .msg.system {
  color: var(--text-dim);
  font-style: italic;
}

#chat-messages .msg.party {
  color: var(--chat-party);
}

#chat-messages .msg.whisper {
  color: var(--chat-whisper);
}

#chat-messages .chat-prefix {
  font-weight: 700;
  margin-right: 0.15em;
}

#chat-messages .msg.tone-celebrate {
  color: var(--gold);
  font-style: normal;
  font-weight: 600;
}

#chat-messages .msg.tone-skill {
  color: var(--skill);
  font-style: normal;
}

#chat-messages .msg.tone-gamble {
  color: color-mix(in srgb, var(--accent) 72%, var(--gold-soft));
  font-style: normal;
  font-weight: 600;
  text-shadow: 0 0 10px color-mix(in srgb, var(--accent) 24%, transparent);
}

#chat-messages .msg.tone-gamble-loss {
  color: color-mix(in srgb, var(--accent) 42%, var(--text-dim));
  font-style: normal;
  font-weight: 500;
}

/* Keep the colored join/leave name upright so it reads against the italic rest. */
#chat-messages .msg.system .name {
  font-style: normal;
}

/* Equippable loot names: white against the dim system line. */
#chat-messages .msg.system .item-name {
  color: #fff;
  font-style: normal;
  font-weight: 600;
}

/* Treasure boxes: warm oat gold, so they do not read as gear. */
#chat-messages .msg.system .item-name-box {
  color: var(--gold-soft);
}

/* Field herbs: dusty sage, so they read as plants rather than mats or gear. */
#chat-messages .msg.system .item-name-herb {
  color: var(--sage);
}

/* Catch names: catalog rarity color only. Stay italic with the system line, never bold. */
#chat-messages .msg.system .item-name-rarity {
  font-weight: 400;
}

#chat-input {
  padding: 9px 12px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: var(--panel-bg);
  color: var(--text);
  font-size: var(--chat-input-font);
  outline: none;
  opacity: 0.65;
  transition: opacity 0.15s, border-color 0.15s;
}

#chat-input:focus {
  opacity: 1;
  border-color: var(--accent);
}

/* ---------- HUD dock (status + hotbar) ---------- */

#hud-dock {
  position: fixed;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  /* 10 slots × 48 + 9 gaps × 8 + horizontal padding 20 */
  width: 572px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  z-index: 10;
  user-select: none;
  overflow: visible;
}

/* Status cap + special action + buff tray share the top row. The charsheet
   keeps the old dock width so HP/XP bars do not stretch with the 10-slot
   hotbar below. */
#charsheet-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.03);
}

#charsheet {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 0 0 268px;
  width: 268px;
  min-width: 0;
}

#charsheet-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}

#charsheet-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
  font-weight: 700;
}

#charsheet-level {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--accent);
}

/* Timed buffs/debuffs: leftover width after the cap and special-action cell.
   :empty hides the tray so an idle dock matches the old empty top-right. */
#status-effects {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  gap: 6px;
}

#status-effects:empty {
  display: none;
}

.status-effect {
  position: relative;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;
}

.status-effect.is-buff {
  border-color: rgba(74, 222, 128, 0.55);
}

.status-effect.is-debuff {
  border-color: rgba(248, 113, 113, 0.65);
}

.status-effect.is-cancellable {
  cursor: pointer;
}

.status-effect .inv-item img {
  width: 100%;
  height: 100%;
  display: block;
}

.status-effect .hotbar-cd {
  inset: 2px;
  border-radius: 4px;
  opacity: 1;
}

.status-effect-count {
  position: absolute;
  right: 2px;
  bottom: 1px;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px #000;
  pointer-events: none;
  z-index: 3;
  font-variant-numeric: tabular-nums;
}

#hotbar {
  display: flex;
  gap: 8px;
  justify-content: center;
  padding: 8px 10px;
}

/* Click-only second bar: same slot chrome as #hotbar, stacked on the right
   rail. Sized to its ten cells rather than stretching top-to-bottom, then
   capped so it stays between #hud-top-right and #hud-actions. */
#hotbar-2 {
  position: fixed;
  right: var(--hud-edge);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  z-index: 10;
  user-select: none;
  overflow: visible;
  max-height: calc(100vh - 148px);
}

/* Contextual special action, parked beside the status cap so the number row
   stays a clean binding strip. */
#special-action {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(58, 120, 150, 0.22);
  border-color: rgba(142, 200, 224, 0.35);
}
#special-action.hidden {
  display: none;
}
/* Nothing to do here yet (off the bank, no tackle): visible so the control does
   not appear and vanish, but plainly not ready. */
#special-action.is-blocked {
  opacity: 0.45;
  cursor: default;
}
#special-action.is-blocked:hover {
  border-color: var(--panel-border);
}
#special-action-glyph {
  width: 26px;
  height: 26px;
  margin-bottom: 8px;
  color: #bfe4f2;
}
#special-action-glyph svg {
  width: 100%;
  height: 100%;
}
/* Status sits inside the 48px cell so showing the button never grows the dock. */
#special-action-label {
  position: absolute;
  left: 2px;
  right: 2px;
  bottom: 2px;
  font-size: 8px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  line-height: 1;
}
/* Line out: a calm blue wash under the cooldown wipe. */
#special-action.is-waiting {
  background: rgba(46, 104, 150, 0.5);
  border-color: rgba(120, 190, 230, 0.55);
}
#special-action.is-waiting #special-action-glyph {
  color: #9fd8ef;
}
/* A fish is on. This is the one moment the button has to be unmissable. */
#special-action.is-bite {
  background: rgba(206, 148, 46, 0.5);
  border-color: var(--gold-soft);
  animation: special-bite 0.45s ease-in-out infinite alternate;
}
#special-action.is-bite #special-action-glyph {
  color: #ffe9b0;
}
#special-action.is-bite #special-action-label {
  color: var(--gold-soft);
}
@keyframes special-bite {
  from { box-shadow: 0 0 0 rgba(240, 190, 90, 0); }
  to { box-shadow: 0 0 16px 3px rgba(240, 190, 90, 0.65); }
}
@media (prefers-reduced-motion: reduce) {
  #special-action.is-bite {
    animation: none;
    box-shadow: 0 0 14px 2px rgba(240, 190, 90, 0.6);
  }
}

.hotbar-slot {
  position: relative;
  width: 48px;
  height: 48px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  cursor: pointer;
}

.hotbar-slot.drag-over {
  border-color: var(--accent);
  background: rgba(110, 231, 183, 0.18);
}

.hotbar-slot.dragging {
  opacity: 0.45;
}

.hotbar-slot:hover {
  border-color: rgba(110, 231, 183, 0.55);
}

.hotbar-key {
  position: absolute;
  top: 2px;
  left: 5px;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-dim);
  pointer-events: none;
  z-index: 3;
}

.hotbar-count {
  position: absolute;
  right: 4px;
  bottom: 2px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px #000;
  pointer-events: none;
  z-index: 3;
}

/* Dim clock wipe while a spell or healing potion is on cooldown (--cd 1→0). */
.hotbar-cd {
  position: absolute;
  inset: 3px;
  border-radius: 6px;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  background: conic-gradient(
    from -90deg,
    rgba(0, 0, 0, 0.62) 0deg,
    rgba(0, 0, 0, 0.62) calc(var(--cd, 0) * 360deg),
    transparent calc(var(--cd, 0) * 360deg)
  );
}

.hotbar-slot.on-cooldown .hotbar-cd {
  opacity: 1;
}

/* Bound item with zero stock / unlearned spell: keep the binding visible but muted. */
.hotbar-slot.depleted .inv-item {
  opacity: 0.35;
  filter: grayscale(0.8);
}

@media (prefers-reduced-motion: reduce) {
  /* The turn-in button keeps its static gold face and glow, it just stops
     shimmering and breathing. Same for the New quest ribbon shine. */
  .dialogue-quest,
  .dialogue-quest.is-offer .dialogue-quest-ribbon,
  .dialogue-btn.is-turnin,
  .dialogue-btn.is-turnin::after {
    animation: none;
  }
  .dialogue-btn.is-turnin::after {
    display: none;
  }
  .dialogue-quest.is-offer .dialogue-quest-ribbon {
    background-position: 40% 50%;
  }
}

#charsheet .bar,
#dash-stats .bar,
#inspect-stats .bar {
  position: relative;
  height: 16px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

#charsheet .bar-fill,
#dash-stats .bar-fill,
#inspect-stats .bar-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0%;
  transition: width 0.25s ease;
}

#health-bar .bar-fill,
#dash-health-bar .bar-fill,
#inspect-health-bar .bar-fill {
  background: linear-gradient(90deg, #ef4444, #f87171);
}

#xp-bar .bar-fill,
#dash-xp-bar .bar-fill,
#inspect-xp-bar .bar-fill {
  background: linear-gradient(90deg, #34d399, #60a5fa);
}

#charsheet .bar-text,
#dash-stats .bar-text,
#inspect-stats .bar-text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}

/* ---------- Inventory panel ---------- */

#inventory-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(960px, 96vw);
  max-height: min(90vh, 680px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 12;
  user-select: none;
}

#inventory-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

#inventory-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#inventory-gold {
  margin-left: auto;
  font-size: 13px;
  font-weight: 600;
  color: #fbbf24;
}

#inventory-close {
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#inventory-close:hover {
  color: var(--text);
  border-color: var(--accent);
}

/* ---------- Character dashboard (stats | doll + portrait | inventory) ----------
   Sized so the worst case (17 equip slots + 16+10+6 grid slots at 6 columns)
   always fits — no overflow, so a scrollbar can never appear. */

#dash-body {
  display: flex;
  gap: 14px;
  align-items: stretch;
}

/* Left column: identity, HP/XP bars, attributes, golden gear info. */
#dash-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 200px;
  flex-shrink: 0;
  padding: 10px 12px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

#dash-identity {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

#dash-name {
  font-size: 14px;
  font-weight: 700;
}

#dash-level {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--accent);
}

#dash-stats h3 {
  margin: 6px 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

#dash-statlist {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.dash-stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 12.5px;
  line-height: 1.25;
}

.dash-stat .stat-label {
  color: var(--text-dim);
  min-width: 0;
}

.dash-stat .stat-right {
  display: inline-flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 5px;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.dash-stat .stat-value {
  font-weight: 600;
}

.dash-stat .stat-mod {
  font-size: 11px;
  font-weight: 650;
}

.dash-stat .stat-mod.buff {
  color: #4ade80;
}

.dash-stat .stat-mod.debuff {
  color: #f87171;
}

/* Golden info: average item level + gear-granted abilities. */
#dash-fancy {
  margin-top: auto;
  padding: 10px;
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-radius: 10px;
  background: rgba(251, 191, 36, 0.07);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#dash-ilvl {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

#dash-ilvl-value {
  font-size: 26px;
  font-weight: 800;
  color: #fbbf24;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.45);
}

#dash-ilvl-label {
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
}

#dash-abilities {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.dash-ability {
  font-size: 12px;
  font-weight: 700;
  color: #fbbf24;
  text-shadow: 0 0 10px rgba(251, 191, 36, 0.4);
}

.dash-ability .ability-desc {
  display: block;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--text-dim);
  text-shadow: none;
}

/* Center column: armor slots | portrait viewport + weapon row | jewelry. */
#dash-doll {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  padding: 10px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

#doll-armor,
#doll-jewelry {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

#doll-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

#portrait-canvas {
  width: 170px;
  height: 386px; /* armor column height minus the weapon row below */
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: radial-gradient(ellipse at 50% 30%, rgba(110, 231, 183, 0.08), rgba(0, 0, 0, 0.25));
  cursor: grab;
}

#doll-hands {
  display: flex;
  gap: 6px;
}

.equip-slot {
  position: relative;
  width: 44px;
  height: 44px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  cursor: pointer;
}

/* Faint watermark inside empty slots instead of labels below them. */
.equip-slot:empty::after {
  content: attr(data-watermark);
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.6px;
  color: var(--text-dim);
  opacity: 0.4;
  pointer-events: none;
}

/* ---------- Inspect Player (stats + doll, no bags) ---------- */

#inspect-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* Stats (200) + doll (armor/portrait/jewelry); snug with a little side room. */
  width: min(550px, 96vw);
  max-height: min(90vh, 720px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 18px 16px;
  z-index: 12;
  user-select: none;
}

#inspect-header {
  display: flex;
  align-items: center;
  gap: 12px;
}

#inspect-title {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

#inspect-close {
  margin-left: auto;
}

#inspect-body {
  display: flex;
  gap: 14px;
  align-items: stretch;
}

#inspect-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 200px;
  flex-shrink: 0;
  padding: 10px 12px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

#inspect-identity {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

#inspect-name {
  font-size: 14px;
  font-weight: 700;
}

#inspect-level {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--accent);
}

#inspect-stats h3 {
  margin: 6px 0 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

#inspect-statlist {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

#inspect-fancy {
  margin-top: auto;
  padding: 10px;
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-radius: 10px;
  background: rgba(251, 191, 36, 0.07);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

#inspect-ilvl {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

#inspect-ilvl-value {
  font-size: 26px;
  font-weight: 800;
  color: #fbbf24;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.45);
}

#inspect-ilvl-label {
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-dim);
}

#inspect-abilities {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

#inspect-doll {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  padding: 10px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
}

#inspect-doll-armor,
#inspect-doll-jewelry {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

#inspect-doll-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

#inspect-portrait-canvas {
  width: 170px;
  height: 386px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: radial-gradient(ellipse at 50% 30%, rgba(110, 231, 183, 0.08), rgba(0, 0, 0, 0.25));
  cursor: grab;
}

#inspect-doll-hands {
  display: flex;
  gap: 6px;
}

#inspect-doll .equip-slot {
  cursor: default;
}

/* Right column: bag equip header, filter chips, one consolidated grid. */
#dash-inv {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

#dash-bagslots {
  display: flex;
  align-items: center;
  gap: 6px;
}

#dash-bags-label {
  margin-right: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

#dash-filters {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}

.dash-chip {
  padding: 3px 10px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-dim);
  cursor: pointer;
}

.dash-chip:hover {
  border-color: rgba(110, 231, 183, 0.55);
  color: var(--text);
}

.dash-chip.selected {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(110, 231, 183, 0.1);
}

/* One continuous grid; each cell is tinted by the container that provides it
   (bp neutral, bag1 cool, bag2 warm) so equipped-bag capacity reads at a
   glance without separate sections. */
#dash-grid {
  display: grid;
  grid-template-columns: repeat(7, 48px);
  gap: 6px;
  align-content: start;
}

.inv-slot.slot-bag1 {
  background: rgba(110, 160, 255, 0.1);
}

.inv-slot.slot-bag2 {
  background: rgba(255, 170, 110, 0.1);
}

/* Filter chips dim non-matching stacks; cells stay put (addresses are
   positional) and stay interactive. */
.inv-slot.filtered-out .inv-item {
  opacity: 0.25;
  filter: saturate(0.15);
}

#dash-inv-footer {
  margin-top: auto;
  display: flex;
  justify-content: flex-end;
}

#dash-sort {
  padding: 5px 12px;
  font-size: 11.5px;
  font-weight: 600;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  cursor: pointer;
}

#dash-sort:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Shared by trade/vendor bag grids (8 columns). */
.inv-grid {
  display: grid;
  grid-template-columns: repeat(8, 48px);
  gap: 6px;
}

.inv-slot {
  position: relative;
  width: 48px;
  height: 48px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  cursor: pointer;
}

.inv-slot:hover,
.equip-slot:hover {
  border-color: rgba(110, 231, 183, 0.55);
}

.inv-slot.dragging {
  opacity: 0.45;
}

.inv-slot.is-source,
.equip-slot.is-source {
  opacity: 0.35;
}

.inv-item {
  position: absolute;
  inset: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: none;
  background: transparent;
  overflow: hidden;
  pointer-events: none;
}

.inv-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}

.inv-item .qty {
  position: absolute;
  right: 3px;
  bottom: 1px;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.85);
  z-index: 1;
}

#inv-cursor {
  position: fixed;
  width: 44px;
  height: 44px;
  pointer-events: none;
  z-index: 20;
  transform: translate(8px, 8px);
}

#inv-cursor .inv-item {
  inset: 0;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45);
}

#inv-tooltip {
  position: fixed;
  z-index: 21;
  max-width: 220px;
  padding: 8px 10px;
  background: rgba(10, 14, 24, 0.94);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  font-size: 12px;
  line-height: 1.4;
  pointer-events: none;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
}

#inv-tooltip .tip-name {
  font-weight: 700;
  margin-bottom: 2px;
}

#inv-tooltip .tip-type,
#inv-tooltip .tip-description {
  color: var(--text-dim);
  font-size: 11px;
  margin-bottom: 4px;
}

#inv-tooltip .tip-type {
  text-transform: capitalize;
}

#inv-tooltip .tip-description {
  text-transform: none;
}

#inv-tooltip .tip-rank {
  color: var(--gold-soft);
  font-size: 11px;
  margin-bottom: 4px;
}

#inv-tooltip .tip-unique {
  color: #e8b84a;
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 4px;
}

#inv-tooltip .tip-req {
  color: #f87171;
  font-size: 11px;
  font-weight: 600;
  margin-bottom: 2px;
}

#inv-tooltip .tip-mod {
  color: var(--accent);
  font-size: 11px;
}

#inv-tooltip .tip-stack {
  color: var(--text-dim);
  font-size: 11px;
  margin-top: 4px;
}

/* ---------- Trade ---------- */

#trade-request,
#trade-waiting {
  position: fixed;
  top: 72px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 14;
  padding: 12px 16px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.45);
  color: var(--text);
  font-size: 13px;
  text-align: center;
}

#trade-request p,
#trade-waiting p {
  margin: 0 0 10px;
}

#trade-waiting-cancel {
  padding: 6px 14px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

#trade-request-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
}

#trade-request-actions button,
#trade-accept-btn {
  padding: 6px 14px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

#trade-request-accept,
#trade-accept-btn {
  border-color: rgba(110, 231, 183, 0.55);
  color: var(--accent);
}

#trade-request-actions button:hover,
#trade-accept-btn:hover:not(:disabled) {
  filter: brightness(1.15);
}

#trade-accept-btn:disabled {
  opacity: 0.65;
  cursor: default;
}

#trade-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, 94vw);
  max-height: min(85vh, 720px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 13;
  user-select: none;
  overflow: auto;
}

#trade-header {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  font-weight: 600;
}

#trade-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#trade-close:hover {
  color: var(--text);
  border-color: var(--accent);
}

#trade-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.trade-side h3 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.trade-slots {
  display: grid;
  grid-template-columns: repeat(3, 48px);
  gap: 6px;
  margin-bottom: 10px;
}

.trade-gold-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 8px;
}

#trade-your-gold {
  width: 88px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: rgba(0, 0, 0, 0.25);
  color: #fbbf24;
  font-size: 13px;
  font-weight: 600;
}

#trade-their-gold {
  font-size: 13px;
  font-weight: 600;
  color: #fbbf24;
  margin-bottom: 8px;
}

.trade-accept-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

#trade-your-accepted,
#trade-their-accepted {
  font-size: 12px;
  color: var(--text-dim);
}

#trade-their-accepted.is-accepted,
#trade-your-accepted {
  color: var(--accent);
  font-weight: 600;
}

#trade-bags {
  border-top: 1px solid var(--panel-border);
  padding-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 220px;
  overflow: auto;
}

.trade-bag h4 {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.trade-bag-grid {
  grid-template-columns: repeat(auto-fill, 48px);
}

#trade-hint {
  margin: 0;
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
}

/* ---------- Vendor shop ----------
   Sized so 10 ware cards (2×5) + a 7-col bag grid + 8 buyback slots always
   fit — no overflow, so a scrollbar can never appear. */

#shop-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(880px, 96vw);
  max-height: min(90vh, 680px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 13;
  user-select: none;
  overflow: hidden;
}

#shop-header {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  font-weight: 600;
}

#shop-gold {
  margin-left: auto;
  color: #fbbf24;
  font-size: 13px;
}

#shop-close {
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#shop-close:hover {
  color: var(--text);
  border-color: var(--accent);
}

#shop-services {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  max-height: min(28vh, 220px);
  overflow-y: auto;
  padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.18);
}

#shop-services.hidden {
  display: none;
}

#shop-services h3 {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

.shop-services-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.shop-service {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 3px solid var(--gold-soft);
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.22);
}

.shop-service-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1 1 180px;
}

.shop-service-icon {
  position: relative;
  inset: auto;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
}

.shop-service-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.shop-service-desc {
  margin: 2px 0 0;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.4;
}

.shop-service-action {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.shop-service-cost {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--gold-soft);
  font-size: 12px;
  font-weight: 600;
}

.shop-service-cost.is-unaffordable {
  color: #fca5a5;
}

.shop-service-btn {
  padding: 6px 10px;
  border: 1px solid rgba(251, 191, 36, 0.45);
  border-radius: 8px;
  background: rgba(251, 191, 36, 0.14);
  color: #fde68a;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.shop-service-btn:hover {
  border-color: rgba(251, 191, 36, 0.7);
  background: rgba(251, 191, 36, 0.22);
}

.shop-service-btn.is-unaffordable {
  border-color: rgba(248, 113, 113, 0.4);
  background: rgba(248, 113, 113, 0.1);
  color: #fca5a5;
}

#shop-body {
  display: flex;
  gap: 14px;
  align-items: stretch;
  min-height: 0;
}

#shop-buy,
#shop-sell {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

#shop-buy {
  flex: 1.1;
}

#shop-sell {
  flex: 1;
}

#shop-buy h3,
#shop-sell h3,
#shop-buyback-section h3 {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.shop-sell-sub {
  font-weight: 500;
  letter-spacing: 0.4px;
  text-transform: none;
  opacity: 0.7;
  margin-left: 4px;
}

/* 2-column ware cards — 10 stock items = 5 rows, no scroll. */
#shop-wares {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  align-content: start;
}

.shop-ware {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease, transform 0.12s ease;
}

.shop-ware:hover:not(:disabled) {
  border-color: rgba(110, 231, 183, 0.55);
  background: rgba(110, 231, 183, 0.08);
  transform: translateY(-1px);
}

.shop-ware:disabled,
.shop-ware.owned {
  opacity: 0.55;
  cursor: default;
}

.shop-ware.unaffordable {
  opacity: 0.55;
}

.shop-ware.unaffordable .shop-ware-price {
  color: #f87171;
}

.shop-ware.skill-locked {
  opacity: 0.55;
}

.shop-ware.skill-locked .shop-ware-price {
  color: #f87171;
}

.shop-ware-icon {
  flex: 0 0 auto;
  pointer-events: none;
}

.shop-ware-info {
  flex: 1;
  min-width: 0;
  pointer-events: none;
}

.shop-ware-name {
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shop-ware-price {
  font-size: 11px;
  color: #fbbf24;
  font-weight: 600;
}

.shop-ware-ribbon {
  position: absolute;
  top: 4px;
  right: 6px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--accent);
  pointer-events: none;
}

/* Consolidated bag grid — same 7-col + tint classes as #dash-grid. */
#shop-bags {
  display: grid;
  grid-template-columns: repeat(7, 48px);
  gap: 6px;
  align-content: start;
}

/* Favorite of the day. The one thing on this panel a player has no other way to
   learn, so it gets a real card rather than a line of text: gold leading edge,
   a slow sheen crossing it, and the item's own icon so the thing being named is
   the thing you go and look for in the grid below. */
.shop-favorite {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  overflow: hidden;
  padding: 9px 11px;
  border: 1px solid rgba(251, 191, 36, 0.6);
  border-left: 4px solid var(--gold);
  border-radius: 9px;
  background:
    linear-gradient(100deg, rgba(251, 191, 36, 0.2), rgba(251, 191, 36, 0.06) 62%),
    rgba(26, 18, 7, 0.72);
  box-shadow:
    inset 0 0 22px rgba(251, 191, 36, 0.14),
    0 0 0 1px rgba(251, 191, 36, 0.14),
    0 3px 12px rgba(0, 0, 0, 0.4);
}

/* The sheen is decoration, so it is skipped for anyone who asked for less
   motion; the card still reads exactly the same without it. */
.shop-favorite::after {
  content: '';
  position: absolute;
  inset: 0 auto 0 -40%;
  width: 40%;
  background: linear-gradient(
    100deg,
    transparent,
    rgba(255, 235, 180, 0.16) 45%,
    rgba(255, 235, 180, 0.26) 55%,
    transparent
  );
  pointer-events: none;
  animation: shop-favorite-sheen 4.5s ease-in-out infinite;
}

@keyframes shop-favorite-sheen {
  0%, 62% { transform: translateX(0); opacity: 0; }
  70% { opacity: 1; }
  100% { transform: translateX(350%); opacity: 0; }
}

.shop-favorite-frame {
  position: relative;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(211, 165, 74, 0.65);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.32);
}

.shop-favorite-frame .shop-favorite-icon {
  position: absolute;
  inset: 3px;
  width: auto;
  height: auto;
}

.shop-favorite-copy {
  flex: 1 1 auto;
  min-width: 0;
}

/* Filled, not gold-on-dark. Every price in this panel is already gold text, so
   a gold label reads as one more price and skims straight past; inverting it is
   what makes the row announce itself as a callout instead of a number. */
.shop-favorite-kicker {
  display: inline-block;
  margin: 0;
  padding: 2px 7px;
  border-radius: 999px;
  background: linear-gradient(180deg, #fde68a, var(--gold));
  color: var(--gold-ink);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.9px;
  text-transform: uppercase;
}

.shop-favorite-name {
  margin: 3px 0 0;
  color: #fff6e4;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
}

.shop-favorite-pay {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin: 3px 0 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.shop-favorite-unit {
  color: var(--gold-soft);
  font-weight: 700;
}

/* The bonus is deliberately not gold: it is the one number that has to be
   readable as *different* from the prices all around it, so it borrows the
   green this game already uses for a value that went up. */
.shop-favorite-bonus {
  padding: 1px 7px;
  border: 1px solid rgba(134, 239, 172, 0.5);
  border-radius: 999px;
  background: rgba(134, 239, 172, 0.14);
  color: var(--done);
  font-weight: 800;
  letter-spacing: 0.2px;
}

/* The matching stacks in the grid below, so the card's name resolves to
   something you can point at without reading forty cells. */
#shop-bags .inv-slot.is-favorite {
  border-color: rgba(251, 191, 36, 0.75);
  box-shadow:
    inset 0 0 12px rgba(251, 191, 36, 0.22),
    0 0 0 1px rgba(251, 191, 36, 0.35),
    0 0 12px rgba(251, 191, 36, 0.3);
  animation: shop-favorite-pulse 2.6s ease-in-out infinite;
}

@keyframes shop-favorite-pulse {
  0%, 100% { box-shadow:
    inset 0 0 12px rgba(251, 191, 36, 0.18),
    0 0 0 1px rgba(251, 191, 36, 0.3),
    0 0 8px rgba(251, 191, 36, 0.22); }
  50% { box-shadow:
    inset 0 0 14px rgba(251, 191, 36, 0.3),
    0 0 0 1px rgba(251, 191, 36, 0.5),
    0 0 16px rgba(251, 191, 36, 0.42); }
}

@media (prefers-reduced-motion: reduce) {
  .shop-favorite::after { animation: none; opacity: 0; }
  #shop-bags .inv-slot.is-favorite { animation: none; }
}

/* Sell line in the shared item tooltip when this is today's pick. */
#inv-tooltip .tip-mod.is-favorite {
  color: var(--gold);
  font-weight: 700;
}

/* Quantity stepper popover (Shift-click a stackable ware).
   Positioned fixed by JS so it is never clipped by the panel. */
.shop-qty-popover {
  position: fixed;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid rgba(110, 231, 183, 0.55);
  border-radius: 10px;
  background: rgba(12, 18, 28, 0.96);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.55);
}

.shop-qty-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shop-qty-row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.shop-qty-step,
.shop-qty-max,
.shop-qty-buy,
.shop-qty-cancel {
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  padding: 3px 8px;
}

.shop-qty-step {
  width: 28px;
  padding: 3px 0;
}

.shop-qty-step:hover,
.shop-qty-max:hover,
.shop-qty-buy:hover,
.shop-qty-cancel:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.shop-qty-input {
  width: 48px;
  padding: 3px 4px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.35);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
}

.shop-qty-input::-webkit-outer-spin-button,
.shop-qty-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.shop-qty-input[type='number'] {
  -moz-appearance: textfield;
  appearance: textfield;
}

.shop-qty-total {
  font-size: 12px;
  font-weight: 600;
  color: #fbbf24;
}

.shop-qty-actions {
  display: flex;
  gap: 6px;
}

.shop-qty-buy {
  border-color: rgba(110, 231, 183, 0.55);
  color: var(--accent);
}

.shop-qty-buy:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Buyback row — fixed 8 slots along the bottom. */
#shop-buyback-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-top: 1px solid var(--panel-border);
  padding-top: 8px;
}

#shop-buyback {
  display: grid;
  grid-template-columns: repeat(8, 48px);
  gap: 6px;
}

.shop-buyback-slot.unaffordable {
  opacity: 0.55;
}

.shop-buyback-slot.unaffordable::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(248, 113, 113, 0.45);
  pointer-events: none;
}

#shop-hint {
  margin: 0;
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
}

/* ---------- Death overlay ---------- */

/* Storm lightning flash — opacity driven by lightning.js (pointer-events none). */
#lightning-flash {
  position: fixed;
  inset: 0;
  background: #dfeaff;
  opacity: 0;
  pointer-events: none;
  z-index: 12;
}

#death-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 8, 14, 0.72);
  z-index: 15;
  pointer-events: none;
}

#death-panel {
  padding: 28px 40px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  text-align: center;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
}

#death-panel h2 {
  margin: 0 0 8px;
  font-size: 28px;
  letter-spacing: 1px;
  color: #f87171;
}

#death-panel p {
  margin: 0;
  color: var(--text-dim);
  font-size: 14px;
  letter-spacing: 0.5px;
}

/* Dialogue / notice board (Phase 7.3; quest cards redesigned in 8.2b) */
#dialogue-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  /* uiLayout.js clears this transform on drag, so nothing here may animate it. */
  transform: translate(-50%, -50%);
  width: min(452px, 92vw);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background:
    radial-gradient(120% 70% at 50% -10%, rgba(251, 191, 36, 0.09), transparent 62%),
    var(--panel-bg);
  border: 1px solid rgba(255, 236, 190, 0.16);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 13;
  user-select: none;
}

#dialogue-header {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.3px;
}

#dialogue-npc-badge {
  display: flex;
  align-items: center;
  color: var(--accent);
}

#dialogue-npc-badge:empty {
  display: none;
}

#dialogue-npc-badge.is-ready {
  color: var(--gold);
}

.dialogue-npc-mark svg {
  width: 20px;
  height: 20px;
}

/* Gold hairline that separates the speaker from what they are offering. */
#dialogue-rule {
  height: 1px;
  margin-top: -4px;
  background: linear-gradient(90deg, transparent, rgba(244, 216, 138, 0.6), transparent);
}

#dialogue-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#dialogue-close:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.12);
}

#dialogue-body {
  display: flex;
  flex-direction: column;
  gap: 9px;
  max-height: 58vh;
  overflow-y: auto;
}

/* Trinke's collection is a display cabinet, not another stack of offer cards.
   The class is set only while that subview is open, so every other NPC keeps
   the compact dialogue width. */
#dialogue-panel.is-keepsake-view {
  width: min(660px, 95vw);
}

#dialogue-panel.is-keepsake-view #dialogue-body {
  max-height: min(82vh, 700px);
}

.keepsake-cabinet {
  position: relative;
  isolation: isolate;
  min-height: 590px;
  padding: 86px 48px 46px;
  overflow: hidden;
  border-radius: 8px;
  background: #211410;
  box-shadow:
    inset 0 0 34px rgba(0, 0, 0, 0.74),
    0 8px 22px rgba(0, 0, 0, 0.38);
}

.keepsake-cabinet-art {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  user-select: none;
}

.keepsake-plaque {
  position: absolute;
  z-index: 1;
  top: 25px;
  left: 50%;
  min-width: 236px;
  padding: 8px 24px 7px;
  transform: translateX(-50%);
  border: 1px solid #d1a04a;
  border-radius: 5px;
  background: linear-gradient(180deg, #70401f, #3d2114);
  box-shadow:
    inset 0 1px 0 rgba(255, 234, 174, 0.24),
    0 3px 8px rgba(0, 0, 0, 0.42);
  color: #ffe7a0;
  text-align: center;
}

.keepsake-plaque h2 {
  margin: 0;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.7px;
  white-space: nowrap;
  text-shadow: 0 1px 1px #160a06;
}

.keepsake-progress {
  margin: 3px 0 0;
  color: #e2c58b;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.45px;
  text-transform: uppercase;
}

.keepsake-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 18px 12px;
}

.keepsake-niche {
  grid-column: span 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  min-height: 208px;
  padding: 14px 8px 12px;
  border: 1px solid rgba(235, 193, 112, 0.29);
  border-radius: 38px 38px 8px 8px;
  background:
    radial-gradient(85% 52% at 50% 12%, rgba(255, 221, 156, 0.09), transparent 72%),
    rgba(12, 9, 10, 0.7);
  box-shadow:
    inset 0 0 18px rgba(0, 0, 0, 0.72),
    0 2px 0 rgba(218, 164, 75, 0.3);
  text-align: center;
}

.keepsake-niche:nth-child(4) {
  grid-column: 2 / span 2;
}

.keepsake-niche:nth-child(5) {
  grid-column: 4 / span 2;
}

.keepsake-niche.is-complete {
  border-color: rgba(116, 232, 174, 0.5);
  background:
    radial-gradient(85% 52% at 50% 12%, rgba(255, 226, 157, 0.16), transparent 72%),
    rgba(12, 17, 14, 0.7);
  box-shadow:
    inset 0 0 22px rgba(0, 0, 0, 0.64),
    0 0 0 1px rgba(52, 211, 153, 0.12),
    0 2px 0 rgba(218, 164, 75, 0.32);
}

.keepsake-icon-frame {
  position: relative;
  flex: 0 0 84px;
  width: 84px;
  height: 84px;
  margin-bottom: 7px;
  border: 2px solid rgba(211, 165, 74, 0.68);
  border-radius: 11px;
  background: rgba(0, 0, 0, 0.35);
  box-shadow:
    inset 0 0 12px rgba(0, 0, 0, 0.72),
    0 2px 5px rgba(0, 0, 0, 0.5);
}

/* Inventory chips are absolute by default because they normally fill a bag
   slot. Pin this copy to the cabinet's larger portrait frame. */
.keepsake-icon-frame .keepsake-icon {
  position: relative;
  inset: auto;
  width: 100%;
  height: 100%;
  border-radius: 9px;
}

.keepsake-niche.is-missing .keepsake-icon img {
  filter: brightness(0.58) saturate(0.68);
}

.keepsake-icon-shade {
  position: absolute;
  inset: 0;
  border-radius: 9px;
  background: rgba(5, 7, 10, 0.2);
  pointer-events: none;
}

.keepsake-check {
  position: absolute;
  z-index: 2;
  top: -8px;
  right: -8px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 27px;
  height: 27px;
  border: 2px solid #baf6d8;
  border-radius: 50%;
  background: #157a50;
  color: #ecfff6;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.56);
}

.keepsake-check svg {
  width: 18px;
  height: 18px;
}

.keepsake-item-name {
  margin: 0;
  color: #f8ead0;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 14px;
  line-height: 1.2;
}

.keepsake-status {
  margin: 4px 0 8px;
  color: #9da4ab;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.65px;
  text-transform: uppercase;
}

.keepsake-niche.is-complete .keepsake-status {
  color: #6ee7b7;
}

.keepsake-niche .dialogue-quest-action {
  justify-content: center;
  width: 100%;
  margin-top: auto;
}

.keepsake-niche .dialogue-btn {
  justify-content: center;
  max-width: 100%;
  padding: 5px 9px;
  border-color: rgba(215, 177, 103, 0.42);
  background: rgba(79, 44, 24, 0.7);
  font-size: 10.5px;
  line-height: 1.2;
  text-align: center;
  white-space: normal;
}

#dialogue-panel.is-keepsake-view .keepsake-niche .dialogue-btn:hover {
  border-color: #d6aa58;
  background: rgba(112, 64, 31, 0.86);
}

.keepsake-niche .dialogue-btn:focus-visible {
  outline-color: #f5d487;
}

@media (max-width: 560px) {
  #dialogue-panel.is-keepsake-view {
    width: min(440px, 94vw);
  }

  .keepsake-cabinet {
    min-height: 770px;
    padding: 84px 30px 44px;
  }

  .keepsake-plaque {
    top: 24px;
    min-width: 210px;
    padding-inline: 18px;
  }

  .keepsake-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 10px;
  }

  .keepsake-niche,
  .keepsake-niche:nth-child(4) {
    grid-column: auto;
  }

  .keepsake-niche:nth-child(5) {
    grid-column: 1 / -1;
    justify-self: center;
    width: calc(50% - 5px);
  }
}

@media (max-width: 380px) {
  .keepsake-cabinet {
    padding-inline: 24px;
  }

  .keepsake-icon-frame {
    flex-basis: 74px;
    width: 74px;
    height: 74px;
  }

  .keepsake-item-name {
    font-size: 12.5px;
  }
}

/* One speech unit: every spoken line shares type and a single left bar. */
.dialogue-speech-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 2px 0 2px 11px;
  border-left: 2px solid rgba(255, 255, 255, 0.18);
}

.dialogue-speech-block .dialogue-line {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: #f2f5fa;
}

.dialogue-line {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--text);
}

/* Hub topic list: navigation only; Accept / Learn / Improve live on details. */
.dialogue-topics {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.dialogue-topic {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px 9px 11px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}

.dialogue-topic:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.16);
}

.dialogue-topic:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.dialogue-topic.is-ready {
  border-left-color: var(--gold);
  background: rgba(251, 191, 36, 0.07);
}

.dialogue-topic.is-ready .dialogue-topic-glyph {
  color: var(--gold);
}

.dialogue-topic.is-offer .dialogue-topic-glyph {
  color: var(--accent);
}

.dialogue-topic.is-lessons {
  border-left-color: #a78bfa;
}

.dialogue-topic.is-lessons .dialogue-topic-glyph {
  color: #c4b5fd;
}

.dialogue-topic.is-improve {
  border-left-color: #60a5fa;
}

.dialogue-topic.is-improve .dialogue-topic-glyph {
  color: #93c5fd;
}

.dialogue-topic.is-training {
  border-left-color: var(--gold-soft);
}

.dialogue-topic.is-training .dialogue-topic-glyph {
  color: var(--gold-soft);
}

.dialogue-topic.is-wares {
  border-left-color: #f0c256;
}

.dialogue-topic.is-wares .dialogue-topic-glyph {
  color: var(--gold);
}

.dialogue-topic.is-keepsake {
  border-left-color: #5eead4;
}

.dialogue-topic.is-keepsake .dialogue-topic-glyph {
  color: #5eead4;
}

.dialogue-topic-glyph {
  display: flex;
  flex: 0 0 auto;
  color: var(--accent);
}

.dialogue-topic-glyph svg {
  width: 20px;
  height: 20px;
}

.dialogue-topic-title {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dialogue-topic-count {
  flex: 0 0 auto;
  min-width: 1.4em;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.dialogue-topic-chevron {
  flex: 0 0 auto;
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  opacity: 0.7;
}

#dialogue-panel.is-hub-view #dialogue-body {
  max-height: none;
  overflow: visible;
}

/* --- Quest card ------------------------------------------------------- */

.dialogue-quest {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px 11px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
  animation: dlg-card-in 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.dialogue-quest.is-ready {
  border-left-color: var(--gold);
  background: rgba(251, 191, 36, 0.07);
  box-shadow:
    inset 0 0 24px rgba(251, 191, 36, 0.1),
    0 0 0 1px rgba(251, 191, 36, 0.22);
}

.dialogue-quest-ribbon {
  position: absolute;
  top: 8px;
  right: 11px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* Offer ribbon: gold leaf lettering so a new quest is obvious before the title. */
.dialogue-quest.is-offer .dialogue-quest-ribbon {
  font-size: 10px;
  letter-spacing: 0.7px;
  color: #f0c256;
  background-image: linear-gradient(
    110deg,
    #c9922f 0%,
    #ffe9a8 32%,
    #fff8dc 48%,
    #fbbf24 62%,
    #c9922f 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 7px rgba(251, 191, 36, 0.55));
  animation: dlg-gold-shine 2.8s ease-in-out infinite;
}

.dialogue-quest.is-ready .dialogue-quest-ribbon {
  color: var(--gold);
  text-shadow: 0 0 10px rgba(251, 191, 36, 0.5);
}

.dialogue-quest-head {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  /* Reserve the ribbon's corner so a long title cannot run under it. */
  padding-right: 112px;
}

.dialogue-quest-badge {
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--accent);
}

.dialogue-quest-badge svg {
  width: 24px;
  height: 24px;
}

.dialogue-quest.is-ready .dialogue-quest-badge {
  color: var(--gold);
  filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.55));
}

.dialogue-quest-title {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}

.dialogue-quest.is-ready .dialogue-quest-title {
  color: #ffe9b8;
}

.dialogue-quest-desc {
  margin: 3px 0 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-dim);
}

.dialogue-objs {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.dialogue-obj {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 13px;
  color: var(--text-dim);
}

.dialogue-obj.done {
  color: var(--text);
}

.ui-glyph {
  display: flex;
  flex: 0 0 auto;
}

.dialogue-glyph svg {
  width: 14px;
  height: 14px;
}

.dialogue-obj .dialogue-glyph {
  color: rgba(255, 255, 255, 0.28);
}

.dialogue-obj.done .dialogue-glyph {
  color: var(--done);
}

/* Shared SVG mark parts: fills follow currentColor, strokes stay hairline.
   Every mark built by glyphs.js carries `ui-glyph`, so a new container styles
   itself by sizing svg alone instead of joining a growing selector list. */
.ui-glyph .g-mark {
  fill: currentColor;
}

.ui-glyph .g-shield {
  fill: currentColor;
  fill-opacity: 0.18;
  stroke: currentColor;
  stroke-width: 1.6;
}

.ui-glyph .g-stroke {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ui-glyph .g-hole {
  fill: none;
  stroke: rgba(0, 0, 0, 0.45);
  stroke-width: 1.4;
}

/* --- Rewards ---------------------------------------------------------- */

.dialogue-rewards {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding-top: 7px;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
}

.dialogue-rewards-label {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-dim);
}

.dialogue-reward-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px 3px 5px;
  border: 1px solid rgba(251, 191, 36, 0.28);
  border-radius: 5px;
  background: rgba(251, 191, 36, 0.1);
  font-size: 12px;
  color: var(--gold-soft);
}

.dialogue-chip-glyph {
  display: flex;
  color: var(--gold);
}

.dialogue-chip-glyph svg {
  width: 14px;
  height: 14px;
}

/* The shared inventory chip is absolutely positioned by default. */
.dialogue-reward-chip .inv-item {
  position: relative;
  inset: auto;
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
}

/* --- Actions ---------------------------------------------------------- */

.dialogue-quest-action {
  display: flex;
  justify-content: flex-end;
}

#dialogue-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
}

/* No footer Close button: the header × (and Escape) dismiss the panel. When
   there are no panel-wide actions left, collapse the row so a quest-only talk
   does not leave an empty button strip. */
#dialogue-actions:empty {
  display: none;
}

.dialogue-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 6px 14px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  overflow: hidden;
  transition: filter 0.15s ease, background 0.12s ease, border-color 0.12s ease,
    transform 0.05s ease;
}

.dialogue-btn-glyph {
  display: flex;
  flex: 0 0 auto;
}

.dialogue-btn-glyph svg {
  width: 15px;
  height: 15px;
}

.dialogue-btn:active {
  transform: scale(0.98);
}

.dialogue-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.dialogue-btn.is-quiet:hover,
.dialogue-btn.is-secondary:hover {
  background: rgba(255, 255, 255, 0.14);
}

.dialogue-btn.is-secondary:hover {
  border-color: rgba(110, 231, 183, 0.55);
}

.dialogue-btn.is-primary {
  border-color: var(--accent);
  background: rgba(110, 231, 183, 0.1);
  color: var(--accent);
  font-weight: 600;
}

.dialogue-btn.is-primary:hover {
  background: rgba(110, 231, 183, 0.2);
}

/* The one gold control in the panel: a finished quest should be obvious
   before its label is read. */
.dialogue-btn.is-turnin {
  padding: 8px 18px;
  border: 1px solid var(--gold-deep);
  background: linear-gradient(180deg, #ffe9a8, #f0c256 45%, #c9922f);
  color: var(--gold-ink);
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.3px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(0, 0, 0, 0.2),
    0 0 18px rgba(251, 191, 36, 0.35);
  animation: dlg-breathe 2.2s ease-in-out infinite alternate;
}

.dialogue-btn.is-turnin::after {
  content: '';
  position: absolute;
  top: -40%;
  bottom: -40%;
  left: 0;
  width: 42%;
  pointer-events: none;
  transform: skewX(-18deg);
  background: linear-gradient(
    90deg,
    transparent,
    rgba(255, 255, 255, 0.68),
    transparent
  );
  animation: dlg-sheen 3.2s ease-in-out infinite;
}

.dialogue-btn.is-turnin:hover {
  filter: brightness(1.08);
}

.dialogue-btn.is-turnin:focus-visible {
  outline-color: var(--gold-soft);
}

/* --- Offer cards: training, services, lessons -------------------------- */

/* Every offer is a card that owns its own button, the way quests already did.
   A label with a detached control in the footer row was the reason a player
   could not tell which button belonged to which line. */

.dialogue-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dialogue-section-label {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
}

.dialogue-skill,
.dialogue-service,
.dialogue-lesson {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 3px solid var(--skill-color, var(--accent));
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.22);
}

.dialogue-lesson {
  border-left-color: #a78bfa;
}

.dialogue-lesson.is-locked {
  border-left-color: rgba(255, 255, 255, 0.18);
  opacity: 0.72;
}

/* Tonight's Feast is a hall you look into, not a stack of offer cards: the
   backdrop is static art, and everything live (banner, laid plates, the runner
   that doubles as the progress track) is DOM above it, the same split the
   Keepsake Cabinet uses. The class is set only while this subview is open. */
#dialogue-panel.is-feast-view {
  width: min(700px, 95vw);
}

#dialogue-panel.is-feast-view #dialogue-body {
  gap: 12px;
  max-height: min(82vh, 720px);
}

.feast-hall {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  padding: 15px 20px 14px;
  overflow: hidden;
  border: 1px solid rgba(235, 178, 98, 0.3);
  border-radius: 10px;
  background: #241610;
  box-shadow:
    inset 0 0 40px rgba(0, 0, 0, 0.6),
    0 8px 22px rgba(0, 0, 0, 0.4);
  text-align: center;
}

.feast-hall-art {
  position: absolute;
  z-index: -1;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  user-select: none;
}

/* Hall lights lift as the table fills, so the room itself reports progress. */
.feast-hall::after {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: radial-gradient(120% 78% at 50% 88%, rgba(255, 178, 74, 0.16), transparent 70%);
  opacity: calc(0.2 + 0.13 * var(--stage-step, 0));
  transition: opacity 0.6s ease;
  pointer-events: none;
}

.feast-hall[data-stage='1'] { --stage-step: 1; }
.feast-hall[data-stage='2'] { --stage-step: 2; }
.feast-hall[data-stage='3'] { --stage-step: 3; }
.feast-hall[data-stage='4'] { --stage-step: 4; }

.feast-banner {
  position: relative;
  padding: 6px 26px 7px;
  border: 1px solid rgba(233, 190, 116, 0.62);
  border-radius: 4px;
  background: linear-gradient(180deg, #7c4622, #40210f);
  box-shadow:
    inset 0 1px 0 rgba(255, 232, 176, 0.24),
    0 4px 10px rgba(0, 0, 0, 0.45);
}

/* Two short cords pin the banner to the hall beam behind it. */
.feast-banner::before,
.feast-banner::after {
  content: '';
  position: absolute;
  top: -14px;
  width: 1px;
  height: 14px;
  background: rgba(226, 186, 122, 0.6);
}

.feast-banner::before { left: 16px; }
.feast-banner::after { right: 16px; }

.feast-kicker {
  margin: 0;
  color: #e2bb7e;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
}

.feast-title {
  margin: 1px 0 0;
  color: #ffeec2;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 23px;
  font-weight: 700;
  letter-spacing: 0.5px;
  line-height: 1.1;
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(20, 8, 4, 0.9);
}

.feast-speech {
  max-width: 52ch;
  margin: 8px 0 0;
  color: #f0dcc0;
  font-size: 12.5px;
  font-style: italic;
  line-height: 1.45;
  text-shadow: 0 1px 3px rgba(12, 6, 3, 0.9);
}

/* The laid table: one seat per eighth of the goal, filled with real dish
   icons so the spread reads as several cooks rather than one plate cloned. */
.feast-table {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin: 0 0 9px;
}

.feast-seat {
  position: relative;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 1px dashed rgba(255, 226, 168, 0.26);
  border-radius: 50%;
  background: rgba(20, 10, 5, 0.34);
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.4);
}

.feast-seat.is-set {
  border-style: solid;
  border-color: rgba(247, 205, 128, 0.72);
  background:
    radial-gradient(70% 70% at 50% 30%, rgba(255, 224, 160, 0.22), transparent 72%),
    rgba(24, 14, 9, 0.7);
  box-shadow:
    inset 0 0 10px rgba(0, 0, 0, 0.6),
    0 0 12px rgba(255, 182, 74, 0.28);
}

/* Inventory chips are absolute because they normally fill a bag slot. Pin
   this copy inside the round place setting. */
.feast-seat .feast-seat-dish {
  position: absolute;
  inset: 4px;
  width: auto;
  height: auto;
}

.feast-seat .feast-seat-dish img {
  border-radius: 50%;
}

.feast-seat.is-fresh {
  animation: feast-plate-land 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
  animation-delay: calc(var(--seat, 0) * 90ms);
}

/* The trestle table: plates along the top, the runner down the middle. */
.feast-plank {
  position: relative;
  width: 100%;
  margin-top: 14px;
  padding: 12px 14px 10px;
  border: 1px solid rgba(120, 74, 40, 0.9);
  border-radius: 7px;
  background:
    repeating-linear-gradient(
      90deg,
      rgba(0, 0, 0, 0.09) 0 1px,
      transparent 1px 74px
    ),
    linear-gradient(180deg, #7a4a28, #40230f);
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 160, 0.16),
    0 6px 14px rgba(0, 0, 0, 0.5);
}

/* Table edge, so the board reads as a plank with thickness. */
.feast-plank::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: -4px;
  left: 0;
  height: 4px;
  border-radius: 0 0 7px 7px;
  background: #2a1509;
}

.feast-track {
  position: relative;
  height: 18px;
  overflow: hidden;
  border: 1px solid rgba(245, 181, 66, 0.5);
  border-radius: 999px;
  background: rgba(22, 12, 7, 0.86);
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.7);
}

.feast-track-fill {
  width: var(--fill, 0%);
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #8c401b 0%, #dc841f 46%, #ffd46a 100%);
  box-shadow: 0 0 12px rgba(255, 187, 65, 0.6);
  transition: width 0.62s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Milestone marks the hall passes at 25 / 50 / 75 percent. They are ticks at
   the rim rather than full bars, because the 50% mark lands exactly behind the
   centred count and read as a stray slash through it. */
.feast-notch {
  position: absolute;
  top: 0;
  left: var(--at, 0%);
  width: 2px;
  height: 3px;
  background: rgba(255, 236, 190, 0.34);
}

.feast-notch::after {
  content: '';
  position: absolute;
  top: 15px;
  left: 0;
  width: 2px;
  height: 3px;
  background: inherit;
}

.feast-notch.is-passed {
  background: rgba(255, 246, 219, 0.92);
  box-shadow: 0 0 6px rgba(255, 214, 120, 0.9);
}

.feast-track-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff5d6;
  font-size: 10.5px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  /* The count crosses its own fill, so it carries a dark rim rather than a
     single drop shadow that vanishes against the gold end of the gradient. */
  text-shadow:
    0 0 3px rgba(24, 10, 2, 0.95),
    0 1px 2px rgba(0, 0, 0, 0.9),
    1px 0 1px rgba(24, 10, 2, 0.8),
    -1px 0 1px rgba(24, 10, 2, 0.8);
}

.feast-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 7px;
}

.feast-chip {
  padding: 2px 8px;
  border: 1px solid rgba(255, 226, 168, 0.26);
  border-radius: 999px;
  background: rgba(18, 10, 6, 0.5);
  color: #e9d3ad;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

.feast-chip.is-yours {
  border-color: rgba(110, 231, 183, 0.4);
  color: var(--accent);
  text-transform: none;
  letter-spacing: 0.2px;
}

.feast-chip.is-reward {
  border-color: rgba(255, 226, 168, 0.4);
  color: #f7e6c4;
  text-transform: none;
}

.feast-chip.is-gold {
  border-color: rgba(251, 191, 36, 0.55);
  color: var(--gold);
}

/* Today's giving is done: the quota chip goes quiet rather than red, since
   finishing a daily is an accomplishment and not a warning. */
.feast-chip.is-yours.is-capped {
  border-color: rgba(255, 226, 168, 0.2);
  color: var(--text-dim);
}

/* The next rung is guidance, so it sits below the earned chips in weight. */
.feast-chip.is-next {
  border-color: rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text-dim);
  text-transform: none;
  letter-spacing: 0.2px;
  font-weight: 600;
}

/* The plates a donation just bought, floating off the runner. */
.feast-gain {
  position: absolute;
  bottom: 62px;
  left: 50%;
  color: var(--gold);
  font-size: 20px;
  font-weight: 800;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85);
  opacity: 0;
  pointer-events: none;
  animation: feast-gain-float 1.15s ease-out both;
}

.feast-countdown {
  margin: 8px 0 0;
  color: #d8bf9c;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.feast-hall.is-called {
  border-color: rgba(251, 191, 36, 0.6);
  box-shadow:
    inset 0 0 44px rgba(251, 191, 36, 0.14),
    0 0 0 1px rgba(251, 191, 36, 0.3),
    0 8px 22px rgba(0, 0, 0, 0.4);
}

.feast-hall.is-called .feast-track {
  box-shadow:
    inset 0 1px 4px rgba(0, 0, 0, 0.7),
    0 0 16px rgba(255, 187, 65, 0.55);
}

.feast-hall.is-called-by-you {
  animation: cookout-feast-pop 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.feast-hall.is-called-by-you .feast-track {
  animation: cookout-bar-flare 0.9s ease-out;
}

/* What you can carry to the table: a shelf of plates, not a column of rows. */
.feast-dishes {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.feast-dishes-label {
  margin: 0;
  color: var(--gold-soft);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
}

.feast-dish-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px;
}

.feast-dish {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 8px 8px 8px;
  border: 1px solid rgba(255, 236, 190, 0.16);
  border-radius: 9px;
  background:
    radial-gradient(90% 60% at 50% 0%, rgba(255, 208, 138, 0.08), transparent 70%),
    rgba(255, 255, 255, 0.035);
  text-align: center;
  transition: border-color 0.16s ease, background-color 0.16s ease, transform 0.16s ease;
}

.feast-dish:hover {
  border-color: rgba(247, 205, 128, 0.5);
  background:
    radial-gradient(90% 60% at 50% 0%, rgba(255, 208, 138, 0.14), transparent 70%),
    rgba(255, 255, 255, 0.06);
  transform: translateY(-1px);
}

.feast-dish-frame {
  position: relative;
  width: 62px;
  height: 62px;
  margin-bottom: 6px;
  border: 1px solid rgba(211, 165, 74, 0.55);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.34);
  box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.65);
}

.feast-dish-frame .feast-dish-icon {
  position: absolute;
  inset: 3px;
  width: auto;
  height: auto;
}

.feast-dish-have,
.feast-dish-worth {
  position: absolute;
  z-index: 2;
  padding: 1px 5px;
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 800;
  line-height: 1.35;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.feast-dish-have {
  right: -5px;
  bottom: -4px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(10, 12, 18, 0.9);
  color: #e8ecf4;
}

.feast-dish-worth {
  top: -6px;
  left: -6px;
  border: 1px solid rgba(251, 191, 36, 0.6);
  background: rgba(50, 30, 6, 0.94);
  color: var(--gold);
}

.feast-dish-name {
  margin: 0 0 3px;
  color: #f6e9d3;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
}

/* What Nessa pays for this plate. On the card because choosing between plates
   is the decision: the purse and the +weight badge are the two halves of it. */
.feast-dish-pay {
  margin: 0 0 7px;
  color: var(--gold);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.feast-dish .dialogue-quest-action {
  justify-content: center;
  width: 100%;
  margin-top: auto;
}

.feast-dish .dialogue-btn {
  justify-content: center;
  width: 100%;
  padding: 4px 8px;
  font-size: 10.5px;
}

/* A capped cook keeps their shelf: the plates are still theirs and still worth
   points, so the cards dim rather than disappear. */
.feast-dish.is-capped {
  opacity: 0.55;
}

.feast-dish.is-capped:hover {
  transform: none;
  border-color: rgba(255, 236, 190, 0.16);
}

.feast-empty.is-capped {
  border-color: rgba(251, 191, 36, 0.34);
  color: var(--gold-soft);
}

.feast-empty {
  margin: 0;
  padding: 12px 14px;
  border: 1px dashed rgba(255, 236, 190, 0.2);
  border-radius: 9px;
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.5;
  text-align: center;
}

@media (max-width: 560px) {
  #dialogue-panel.is-feast-view {
    width: min(470px, 94vw);
  }

  .feast-seat {
    width: 34px;
    height: 34px;
  }

  .feast-dish-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .feast-title {
    font-size: 18px;
  }
}

.dialogue-service {
  border-left-color: var(--gold-soft);
}

.dialogue-skill-head,
.dialogue-service-head,
.dialogue-lesson-head {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.dialogue-skill-icon,
.dialogue-service-icon,
.dialogue-lesson-icon {
  position: relative;
  inset: auto;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
}

.dialogue-skill-head .skill-meter {
  flex: 1;
  min-width: 0;
}

.dialogue-skill-desc,
.dialogue-service-desc,
.dialogue-lesson-desc {
  margin: 0;
  color: var(--text-dim);
  font-size: 11.5px;
  line-height: 1.45;
}

.dialogue-service-title,
.dialogue-lesson-title {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
}

.dialogue-skill-note {
  margin-right: auto;
  color: var(--text-dim);
  font-size: 11px;
}

.dialogue-quest-action {
  align-items: center;
  gap: 8px;
}

/* Spark / gold spend rows stay on one line next to the action button. */
.dialogue-quest-action.is-spend {
  flex-wrap: nowrap;
}

/* A price, not a button: the cost reads before the control that spends it. */
.dialogue-cost {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  color: var(--gold-soft);
  font-size: 12.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.dialogue-cost.unaffordable {
  color: #f87171;
}

/* What the purse holds, beside what it costs. Dimmed so the price still reads
   first and the pair never looks like two prices. */
.dialogue-cost.is-balance {
  color: var(--text-dim);
  font-weight: 500;
}

.dialogue-cost .dialogue-chip-glyph svg {
  width: 13px;
  height: 13px;
}

.dialogue-btn.is-unaffordable {
  opacity: 0.7;
}

.dialogue-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

/* --- Skill meter ------------------------------------------------------- */

/* Shared by the dialogue panel, the spellbook, and the lockbox summary, so
   the two ranks that decide a box read the same wherever they appear. */

.skill-meter {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.skill-meter .skill-icon {
  position: relative;
  inset: auto;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
}

.skill-copy {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.skill-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.skill-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.skill-rank {
  flex: 0 0 auto;
  color: var(--skill-color, var(--accent));
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

.skill-rank.is-untrained {
  color: var(--text-dim);
  font-weight: 600;
}

/* Rank at a glance. Ranks past the level cap stay visible as hollow marks
   rather than vanishing, so the ceiling is something to work toward. */
.skill-pips {
  display: flex;
  gap: 3px;
}

.skill-pip {
  width: 9px;
  height: 9px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.05);
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.skill-pip.filled {
  border-color: var(--skill-color, var(--accent));
  background: var(--skill-color, var(--accent));
  box-shadow: 0 0 6px color-mix(in srgb, var(--skill-color, var(--accent)) 60%, transparent);
}

.skill-pip.locked {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.12);
  background: none;
}

.skill-progress {
  display: flex;
  align-items: center;
  gap: 8px;
}

.skill-bar {
  position: relative;
  flex: 1;
  height: 5px;
  min-width: 0;
  overflow: hidden;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.09);
}

.skill-bar-fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--skill-color, var(--accent)) 55%, #ffffff 10%),
    var(--skill-color, var(--accent))
  );
  transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.skill-value {
  flex: 0 0 auto;
  color: var(--text-dim);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
}

.skill-meter.is-compact {
  gap: 8px;
}

.skill-meter.is-compact .skill-name {
  font-size: 12px;
}

/* Rank-up: the meter it happened on flashes gold once. */
.dialogue-skill.is-rankup {
  animation: skill-rankup 0.9s ease-out;
}

.dialogue-skill.is-rankup .skill-pip.filled:last-of-type {
  animation: skill-pip-pop 0.5s ease-out;
}

@keyframes skill-rankup {
  0% {
    border-left-color: var(--gold);
    box-shadow: 0 0 0 rgba(251, 191, 36, 0);
  }
  25% {
    border-left-color: var(--gold);
    box-shadow: 0 0 22px rgba(251, 191, 36, 0.45);
  }
  100% {
    box-shadow: 0 0 0 rgba(251, 191, 36, 0);
  }
}

@keyframes skill-pip-pop {
  0% {
    transform: scale(1);
  }
  45% {
    transform: scale(1.9);
  }
  100% {
    transform: scale(1);
  }
}

/* Cards arrive in reading order, matching the entrance quest cards already
   use. Counted by type, since a section's first child is its label span and
   the panel body interleaves dialogue lines with cards. Capped at three steps
   so a long panel does not crawl in from the bottom. */
.dialogue-skill,
.dialogue-service,
.dialogue-lesson {
  animation: dlg-card-in 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.dialogue-quest:nth-of-type(2),
.dialogue-skill:nth-of-type(2),
.dialogue-service:nth-of-type(2),
.dialogue-lesson:nth-of-type(2) {
  animation-delay: 0.05s;
}

.dialogue-quest:nth-of-type(n + 3),
.dialogue-skill:nth-of-type(n + 3),
.dialogue-service:nth-of-type(n + 3),
.dialogue-lesson:nth-of-type(n + 3) {
  animation-delay: 0.1s;
}

/* A live rank or purchase rebuild is not a fresh topic open: skip entrance. */
.is-live-patch.dialogue-skill,
.is-live-patch.dialogue-lesson,
.is-live-patch.dialogue-service,
.is-live-patch .dialogue-skill,
.is-live-patch .dialogue-lesson,
.is-live-patch .dialogue-service {
  animation: none;
}

/* The lockbox panel draws the same two meters, demoted to a footer strip below
   a divider so they stop competing with the box for the top of the panel. */
#lockbox-skills {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--panel-border);
}

/* Too narrow to reserve a corner: the ribbon drops into the flow above the
   title instead of squeezing it. It is already the card's first child. */
@media (max-width: 460px) {
  .dialogue-quest-ribbon {
    position: static;
  }

  .dialogue-quest-head {
    padding-right: 0;
  }
}

@keyframes dlg-card-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes cookout-feast-pop {
  0% {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
    box-shadow:
      inset 0 0 24px rgba(251, 191, 36, 0.2),
      0 0 0 1px rgba(251, 191, 36, 0.45);
  }
  55% {
    transform: translateY(0) scale(1.01);
    box-shadow:
      inset 0 0 28px rgba(251, 191, 36, 0.22),
      0 0 18px rgba(251, 191, 36, 0.4);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes feast-plate-land {
  0% {
    opacity: 0;
    transform: translateY(-9px) scale(0.72);
  }
  62% {
    opacity: 1;
    transform: translateY(1px) scale(1.06);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes feast-gain-float {
  0% {
    opacity: 0;
    transform: translate(-50%, 6px) scale(0.85);
  }
  22% {
    opacity: 1;
    transform: translate(-50%, -2px) scale(1.08);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -34px) scale(1);
  }
}

@keyframes cookout-bar-flare {
  0% {
    box-shadow: 0 0 8px rgba(255, 187, 65, 0.35);
  }
  35% {
    box-shadow: 0 0 22px rgba(255, 210, 90, 1);
  }
  100% {
    box-shadow: 0 0 14px rgba(255, 187, 65, 0.45);
  }
}

@keyframes dlg-breathe {
  from {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.55),
      inset 0 -1px 0 rgba(0, 0, 0, 0.2),
      0 0 14px rgba(251, 191, 36, 0.28);
  }
  to {
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.55),
      inset 0 -1px 0 rgba(0, 0, 0, 0.2),
      0 0 22px rgba(251, 191, 36, 0.5);
  }
}

/* The sweep occupies the first quarter of the cycle, so it reads as an
   occasional glint rather than a strobe. */
@keyframes dlg-sheen {
  0% {
    transform: translateX(-140%) skewX(-18deg);
  }
  25%,
  100% {
    transform: translateX(240%) skewX(-18deg);
  }
}

@keyframes dlg-gold-shine {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}

/* Cracking a box is a focus moment, so the panel dims what is behind it. The
   scrim is pointer-events:none on purpose: this panel is draggable and has
   never been modal, so it takes the map overlay's look without its
   click-swallowing. */
#lockbox-scrim { position: fixed; inset: 0; background: rgba(4,6,12,.55); backdrop-filter: blur(3px); z-index: 13; pointer-events: none; }
/* Darker and blurred where every other modal sits at --panel-bg: this one is
   read against a full inventory grid. Warm border matches #dialogue-panel. */
#lockbox-panel { position: fixed; top: 50%; left: 50%; transform: translate(-50%,-50%); width: min(560px,94vw); padding: 14px 16px; background: radial-gradient(120% 70% at 50% -10%, rgba(251,191,36,.09), transparent 62%), rgba(10,13,22,.94); backdrop-filter: blur(10px); border: 1px solid rgba(255,236,190,.16); border-radius: 12px; box-shadow: 0 20px 65px rgba(0,0,0,.65); z-index: 14; user-select: none; }
#lockbox-header { display:flex; align-items:center; font-weight:700; color:#f1ce83; }
#lockbox-close { margin-left:auto; width:28px; height:28px; color:var(--text); background:rgba(255,255,255,.06); border:1px solid var(--panel-border); border-radius:8px; }
#lockbox-tier { margin-left:10px; font-weight:500; font-size:12px; color:var(--text-dim); }

/* The box picture is the interface: the canvas holds the prop, and the badges
   are HTML projected onto it by lockboxView.anchors(), so the click targets
   keep hover, focus, and aria without a raycaster. */
#lockbox-hero { position:relative; height:240px; margin:8px 0 4px; overflow:visible; }
#lockbox-canvas { display:block; width:100%; height:100%; cursor:grab; }
#lockbox-hero.is-hit { animation:lb-shake .42s ease-out; }
#lockbox-hero.is-hit::after { content:''; position:absolute; inset:0; background:radial-gradient(60% 60% at 50% 55%, rgba(248,113,113,.42), transparent 70%); pointer-events:none; animation:lb-flash .42s ease-out; }
@keyframes lb-shake { 0%,100% { transform:translateX(0); } 20% { transform:translateX(-7px); } 40% { transform:translateX(6px); } 60% { transform:translateX(-4px); } 80% { transform:translateX(2px); } }
@keyframes lb-flash { from { opacity:1; } to { opacity:0; } }

/* Opened treasure sits on the box itself, not stranded under the primary. */
#lockbox-loot {
  position:absolute; left:50%; bottom:10px; z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:6px;
  width:min(92%, 420px); transform:translateX(-50%);
  pointer-events:none;
}
#lockbox-loot:not(.hidden) { pointer-events:auto; }
#lockbox-loot.is-reveal { animation:lb-loot-pop .45s ease-out; }
#lockbox-loot-banner {
  margin:0; text-align:center; font-size:22px; font-weight:800;
  letter-spacing:.04em; line-height:1.15;
  background:linear-gradient(105deg, #b9a86a 0%, #fff8dc 18%, #e6d7a0 38%, #fffef6 52%, #cfc07e 72%, #f3e8b8 100%);
  background-size:220% 100%;
  -webkit-background-clip:text; background-clip:text;
  color:transparent; -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 0 12px rgba(255, 246, 210, 0.4));
  animation:lb-loot-shimmer 2.6s ease-in-out infinite;
}
#lockbox-loot-tray {
  display:flex; flex-wrap:wrap; gap:8px; align-items:center; justify-content:center;
  padding:8px 10px; border-radius:14px;
  border:1px solid rgba(255,236,190,.28);
  background:rgba(6,9,16,.72);
  box-shadow:0 0 28px rgba(251,191,36,.18), 0 8px 24px rgba(0,0,0,.45);
}
/* Gold matches the item chip frame: dark card, shiny coin pile, glowing amount. */
.lb-loot-gold {
  position:relative; width:72px; height:72px; padding:0; border-radius:12px;
  border:1px solid rgba(255,220,140,.4); background:rgba(0,0,0,.32);
  box-shadow:0 0 20px rgba(251,191,36,.28); cursor:pointer; overflow:hidden;
}
.lb-loot-gold:hover {
  border-color:rgba(255,236,190,.7);
  box-shadow:0 0 26px rgba(251,191,36,.45);
  filter:brightness(1.08);
}
.lb-loot-gold-art {
  position:absolute; inset:4px; display:block; pointer-events:none;
}
.lb-loot-gold-stack {
  display:block; width:100%; height:100%;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.55));
}
.lb-loot-gold-shine {
  position:absolute; inset:-20% -40%;
  background:linear-gradient(
    115deg,
    transparent 35%,
    rgba(255,248,220,.55) 48%,
    rgba(255,255,255,.75) 52%,
    transparent 65%
  );
  transform:translateX(-60%) rotate(8deg);
  animation:lb-gold-shine 2.8s ease-in-out infinite;
  pointer-events:none;
}
.lb-loot-gold-sparkle {
  position:absolute; width:5px; height:5px; border-radius:50%;
  background:radial-gradient(circle, #fffef6 0%, #ffe08a 45%, transparent 72%);
  box-shadow:0 0 6px rgba(255,236,190,.9);
  pointer-events:none;
  animation:lb-gold-twinkle 1.8s ease-in-out infinite;
}
.lb-loot-gold-sparkle.s1 { top:10px; left:12px; animation-delay:0s; }
.lb-loot-gold-sparkle.s2 { top:18px; right:11px; width:4px; height:4px; animation-delay:.55s; }
.lb-loot-gold-sparkle.s3 { bottom:22px; left:22px; width:3px; height:3px; animation-delay:1.1s; }
.lb-loot-gold-amt {
  position:absolute; inset:0; z-index:1;
  display:flex; align-items:center; justify-content:center;
  font-size:18px; font-weight:800; letter-spacing:.02em; line-height:1;
  color:#fff6d0;
  text-shadow:
    0 0 10px rgba(251,191,36,.95),
    0 0 4px rgba(0,0,0,.9),
    0 1px 2px rgba(0,0,0,.9);
  pointer-events:none;
}
.lb-loot-item {
  position:relative; width:72px; height:72px; padding:0; border-radius:12px;
  border:1px solid rgba(255,236,190,.28); background:rgba(0,0,0,.32);
  box-shadow:0 0 16px rgba(142,200,224,.16); cursor:pointer; overflow:hidden;
}
.lb-loot-item:hover { border-color:rgba(255,236,190,.55); filter:brightness(1.1); }
.lb-loot-item .inv-item { inset:6px; }
@keyframes lb-loot-pop {
  from { opacity:0; transform:translateX(-50%) translateY(14px) scale(.92); }
  to { opacity:1; transform:translateX(-50%) translateY(0) scale(1); }
}
@keyframes lb-loot-shimmer {
  0%, 100% { background-position:0% 50%; }
  50% { background-position:100% 50%; }
}
@keyframes lb-gold-shine {
  0%, 55% { transform:translateX(-70%) rotate(8deg); opacity:0; }
  65% { opacity:.9; }
  80%, 100% { transform:translateX(70%) rotate(8deg); opacity:0; }
}
@keyframes lb-gold-twinkle {
  0%, 100% { opacity:.15; transform:scale(.6); }
  40% { opacity:1; transform:scale(1.15); }
  70% { opacity:.35; transform:scale(.8); }
}
@media (prefers-reduced-motion: reduce) {
  #lockbox-loot.is-reveal { animation:none; }
  #lockbox-loot-banner {
    animation:none; background:none; color:#f0e6b8; -webkit-text-fill-color:#f0e6b8; filter:none;
  }
  .lb-loot-gold-shine, .lb-loot-gold-sparkle { animation:none; opacity:.45; }
  .lb-loot-gold-shine { transform:translateX(0) rotate(8deg); opacity:.2; }
}

/* Ephemeral outcome line under the hero: challenge results and boxError land
   here while the panel is open, so they are not lost behind the blur scrim. */
#lockbox-status { min-height:1.4em; margin:2px 0 0; text-align:center; font-size:13px; font-weight:600; color:var(--text-dim); }
#lockbox-status.is-ok { color:var(--done); }
#lockbox-status.is-warn { color:var(--gold-soft); }
#lockbox-status.is-danger { color:#f87171; }

/* Trap = shield above the lid, lock = keyhole on the plate. Chrome is an SVG
   shell with a stroke in currentColor (same hue as the glyph), not clip-path,
   so the outline actually shows against the wood. */
.lb-badge {
  position:absolute; left:0; top:0; display:flex; align-items:center; justify-content:center;
  width:42px; height:42px; padding:0; color:var(--text);
  background:transparent; border:none; border-radius:0;
  cursor:default; transition:opacity .12s linear, filter .12s linear;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.75));
}
.lb-badge-trap { width:48px; height:54px; }
.lb-badge-lock { width:42px; height:54px; }
.lb-badge-shell-wrap { position:absolute; inset:0; pointer-events:none; }
.lb-badge-shell { display:block; width:100%; height:100%; overflow:visible; }
.lb-badge-shell .lb-badge-fill { fill:rgba(8,11,19,.94); }
.lb-badge-shell .lb-badge-ring {
  fill:none; stroke:currentColor; stroke-width:3; stroke-linejoin:round; stroke-linecap:round;
}
.lb-badge .lb-badge-glyph { position:relative; z-index:1; display:flex; }
.lb-badge .lb-badge-glyph svg { width:22px; height:22px; }
.lb-badge-trap .lb-badge-glyph svg { width:20px; height:20px; }
.lb-badge-lock .lb-badge-glyph { margin-top:-4px; }
.lb-badge.is-live { cursor:pointer; }
.lb-badge.is-live:hover { filter:brightness(1.2) drop-shadow(0 1px 3px rgba(0,0,0,.75)); }
.lb-badge.is-unknown { color:var(--gold); }
.lb-badge.is-unknown .lb-badge-fill { fill:rgba(40,28,8,.96); }
.lb-badge.is-warn { color:var(--gold); }
.lb-badge.is-warn .lb-badge-fill { fill:rgba(40,28,8,.96); }
.lb-badge.is-danger { color:#f87171; }
.lb-badge.is-danger .lb-badge-fill { fill:rgba(40,12,12,.96); }
.lb-badge.is-done { color:var(--done); }
.lb-badge.is-done .lb-badge-fill { fill:rgba(10,28,16,.96); }
.lb-badge.is-spent { color:#fca5a5; }
.lb-badge.is-spent .lb-badge-fill { fill:rgba(36,14,14,.96); }
/* Only a badge that wants something pulses, so the panel has one focal point. */
.lb-badge.is-live.is-unknown, .lb-badge.is-live.is-warn { animation:lb-pulse 1.9s ease-in-out infinite; }
.lb-badge.is-live.is-danger { animation:lb-pulse 1.15s ease-in-out infinite; }
@keyframes lb-pulse {
  0%,100% { filter: drop-shadow(0 0 5px currentColor) drop-shadow(0 1px 3px rgba(0,0,0,.75)); }
  50% { filter: drop-shadow(0 0 1px currentColor) drop-shadow(0 1px 3px rgba(0,0,0,.75)); }
}

/* Radial dial: same 0..1 the server scores, swept around the mechanism being
   worked. conic-gradient for the band is the .hotbar-cd cooldown trick. */
#lockbox-dial { --lb-band:rgba(110,231,183,.5); position:absolute; width:150px; height:150px; margin:-75px 0 0 -75px; border-radius:50%; outline:none; cursor:pointer; }
#lockbox-dial::before { content:''; position:absolute; inset:0; border-radius:50%; border:1px solid rgba(255,255,255,.16); background:rgba(6,9,16,.35); }
#lockbox-dial-band { position:absolute; inset:0; border-radius:50%; -webkit-mask:radial-gradient(closest-side, transparent 70%, #000 71%); mask:radial-gradient(closest-side, transparent 70%, #000 71%); }
#lockbox-dial-marker { position:absolute; inset:0; }
#lockbox-dial-marker::before { content:''; position:absolute; left:50%; top:4px; width:3px; height:30px; margin-left:-1.5px; background:#fff0a8; border-radius:2px; box-shadow:0 0 9px #fff0a8; }

#lockbox-stage { margin:2px 0 0; text-align:center; font-size:11px; font-weight:800; letter-spacing:.09em; color:var(--gold-soft); }
#lockbox-readout { display:grid; gap:4px; margin:10px 0 8px; text-align:center; }
.lb-readout-row { color:var(--text); font-size:15px; font-weight:600; letter-spacing:.02em; }

.lb-chip { display:inline-flex; align-items:center; padding:3px 9px; font-size:12px; color:var(--text-dim); background:rgba(255,255,255,.05); border:1px solid var(--panel-border); border-radius:999px; }
.lb-chip.is-rank { flex:0 0 auto; color:var(--gold-soft); }
.lb-chip.is-bad { color:#f87171; border-color:rgba(248,113,113,.4); }
select.lb-chip { cursor:pointer; }

#lockbox-controls { display:flex; flex-wrap:wrap; gap:10px; align-items:center; justify-content:space-between; margin:10px 0; }
#lockbox-approach { display:flex; gap:0; }
.lb-pill { padding:5px 13px; font-size:12px; color:var(--text-dim); background:rgba(255,255,255,.04); border:1px solid var(--panel-border); cursor:pointer; }
.lb-pill:first-child { border-radius:999px 0 0 999px; }
.lb-pill:last-child { border-radius:0 999px 999px 0; }
.lb-pill + .lb-pill { border-left:none; }
.lb-pill.is-on { color:var(--gold-ink); background:var(--gold-soft); border-color:var(--gold-soft); font-weight:700; }
.lb-pill:disabled { opacity:.4; cursor:default; }

.lb-btn { display:inline-flex; gap:7px; align-items:center; justify-content:center; padding:7px 12px; color:var(--text); background:rgba(255,255,255,.05); border:1px solid var(--panel-border); border-radius:8px; cursor:pointer; }
.lb-btn svg { width:14px; height:14px; }
.lb-btn:disabled { opacity:.45; cursor:default; }
/* One primary control, full width, so "what next" is never in doubt. */
.lb-btn.is-primary { width:100%; padding:11px; font-size:15px; font-weight:700; color:var(--gold-ink); background:linear-gradient(180deg,#fde68a,var(--gold)); border-color:rgba(255,236,190,.5); }
.lb-btn.is-quiet { padding:5px 10px; font-size:12px; color:var(--text-dim); background:none; border-color:transparent; text-decoration:underline; text-underline-offset:3px; }
.lb-btn.is-quiet:hover:not(:disabled) { color:var(--text); }
.lb-btn.is-risky { color:#f87171; }

#lockbox-primary { margin-top:4px; }
#lockbox-hint { margin:6px 0 0; font-size:12px; color:#f87171; text-align:center; }
#lockbox-secondary { display:flex; flex-wrap:wrap; gap:4px; justify-content:center; margin-top:6px; }
#lockbox-contents { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:10px; }
.lb-gold { color:var(--gold); font-weight:700; }
#box-editor-panel {
  position: fixed;
  inset: 5vh 4vw;
  z-index: 16;
  display: flex;
  flex-direction: column;
  min-width: 760px;
  max-width: 1040px;
  max-height: 820px;
  margin: auto;
  padding: 14px 16px;
  overflow: hidden;
  border: 1px solid rgba(240, 171, 252, 0.45);
  border-radius: 14px;
  background: rgba(10, 14, 25, 0.97);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.68);
  backdrop-filter: blur(12px);
}

#box-editor-header,
#box-editor-header > div {
  display: flex;
  align-items: center;
  gap: 9px;
}

#box-editor-header {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--panel-border);
}

#box-editor-title {
  font-size: 17px;
  font-weight: 750;
}

#box-editor-close {
  width: 30px;
  height: 30px;
  margin-left: auto;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 19px;
  cursor: pointer;
}

#box-editor-close:hover {
  border-color: rgba(240, 171, 252, 0.64);
  background: rgba(240, 171, 252, 0.11);
  color: var(--text);
}

#box-editor-body {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 14px;
  min-height: 0;
  padding-top: 14px;
}

#box-editor-list {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 0;
  padding-right: 12px;
  overflow-y: auto;
  border-right: 1px solid var(--panel-border);
}

#box-editor-list button {
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr);
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--text);
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.box-editor-icon {
  width: 38px;
  height: 38px;
  min-width: 38px;
  padding: 0;
  overflow: hidden;
  pointer-events: none;
}

.box-editor-icon .inv-item,
.box-editor-icon img {
  width: 100%;
  height: 100%;
}

.box-editor-row-details {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.box-editor-row-details strong {
  overflow: hidden;
  color: var(--text);
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.box-editor-row-details > span {
  color: var(--text-dim);
  font-size: 11px;
}

#box-editor-list button:hover,
#box-editor-list button.selected {
  border-color: rgba(240, 171, 252, 0.5);
  background: rgba(240, 171, 252, 0.1);
}

#box-editor-form {
  display: flex;
  flex-direction: column;
  gap: 11px;
  min-width: 0;
  padding-right: 4px;
  overflow-y: auto;
}

#box-editor-feedback {
  padding: 7px 9px;
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 7px;
  background: rgba(248, 113, 113, 0.09);
  color: #fca5a5;
  font-size: 12px;
}

#box-editor-feedback.success {
  border-color: rgba(52, 211, 153, 0.45);
  background: rgba(52, 211, 153, 0.09);
  color: #6ee7b7;
}

#box-editor-form input,
#box-editor-form select,
#box-editor-form textarea {
  width: 100%;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  outline: none;
  color-scheme: dark;
}

#box-editor-form input:focus,
#box-editor-form select:focus,
#box-editor-form textarea:focus {
  border-color: rgba(240, 171, 252, 0.72);
  box-shadow: 0 0 0 2px rgba(240, 171, 252, 0.1);
}

#box-editor-form select option {
  color: #e8ecf4;
  background-color: #141824;
}

#box-editor-form textarea {
  min-height: 70px;
  font-family: ui-monospace, monospace;
  line-height: 1.4;
  resize: vertical;
}

#box-editor-form .box-editor-flag {
  flex-direction: row;
  align-items: center;
  align-self: end;
  min-height: 34px;
  cursor: pointer;
}

#box-editor-form .box-editor-flag input {
  width: auto;
  accent-color: #d8a34a;
}

#box-editor-footer {
  display: flex;
  justify-content: flex-end;
  gap: 7px;
}

#box-editor-footer button {
  padding: 7px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  cursor: pointer;
}

#box-editor-footer button:hover {
  border-color: rgba(240, 171, 252, 0.64);
  background: rgba(240, 171, 252, 0.11);
}

#box-editor-save {
  border-color: rgba(240, 171, 252, 0.55) !important;
  background: rgba(240, 171, 252, 0.16) !important;
  color: #f5d0fe !important;
}

@media (max-width: 820px) {
  #box-editor-panel {
    inset: 2vh 2vw;
    min-width: 0;
  }

  #box-editor-body {
    grid-template-columns: 190px minmax(0, 1fr);
  }

  #box-editor-form .item-form-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Spellbook (Phase 8.2) */
#spellbook-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(620px, 94vw);
  max-height: min(78vh, 680px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 12;
  user-select: none;
}

#spellbook-header {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 700;
}

#spellbook-shortcut {
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 5px;
  color: var(--text-dim);
  font-size: 11px;
}

#spellbook-sparks {
  color: var(--gold-soft);
  font-size: 11px;
  font-weight: 600;
}

#spellbook-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  cursor: pointer;
}

#spellbook-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

#spellbook-filters button {
  padding: 5px 10px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-dim);
  cursor: pointer;
}

#spellbook-filters button.selected {
  border-color: var(--accent);
  color: var(--accent);
  background: rgba(110, 231, 183, 0.1);
}

#spellbook-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  overflow-y: auto;
  /* The panel is a capped flex column: without this the grid refuses to shrink
     and pushes the skills section past the bottom edge. */
  min-height: 0;
}

.spellbook-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 3px solid #8fa0bd;
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.spellbook-card.school-targeted_magic { border-left-color: #ef7a55; }
.spellbook-card.school-restoration { border-left-color: #69c98d; }
.spellbook-card.school-utility_magic { border-left-color: #f0ca67; }
.spellbook-card:hover { background: rgba(255, 255, 255, 0.08); }
.spellbook-card { cursor: grab; }
.spellbook-card.dragging { opacity: 0.45; cursor: grabbing; }
.spellbook-card .inv-item {
  position: relative;
  inset: auto;
  flex: 0 0 54px;
  width: 54px;
  height: 54px;
}

.spellbook-copy,
.spellbook-card-head,
.spellbook-description,
.spellbook-meta,
.spellbook-binding {
  display: block;
}

.spellbook-copy { min-width: 0; flex: 1; }
.spellbook-card-head { display: flex; gap: 8px; justify-content: space-between; }
.spellbook-rank-pips {
  display: inline-flex;
  gap: 2px;
  margin-left: auto;
}
.spellbook-rank-pips > span {
  width: 6px;
  height: 6px;
  margin-top: 4px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
}
.spellbook-rank-pips > span.filled {
  border-color: var(--gold-soft);
  background: var(--gold-soft);
}
.spellbook-description { margin-top: 3px; color: var(--text-dim); font-size: 11.5px; }
.spellbook-meta { margin-top: 6px; color: #bac8d8; font-size: 10.5px; line-height: 1.4; }
.spellbook-binding { margin-top: 6px; color: var(--accent); font-size: 10.5px; font-weight: 600; }
.spellbook-ready { color: #86efac; font-size: 11px; }
.spellbook-ready.cooling { color: #fbbf24; }
.spellbook-empty { grid-column: 1 / -1; color: var(--text-dim); text-align: center; }
#spellbook-hint { margin: 0; color: var(--text-dim); font-size: 11px; text-align: center; }

/* Skills panel (O). Same card chrome as the spellbook; skills render through
   the shared skill meter, so this only owns grouping and spacing. */
#skills-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(460px, 94vw);
  max-height: min(78vh, 660px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.55);
  z-index: 12;
  user-select: none;
}

#skills-header {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 700;
}

#skills-shortcut {
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 5px;
  color: var(--text-dim);
  font-size: 11px;
}

#skills-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  cursor: pointer;
}

#skills-list {
  display: flex;
  flex-direction: column;
  gap: 9px;
  overflow-y: auto;
  min-height: 0;
}

#skills-list h4 {
  margin: 6px 0 -2px;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

#skills-list h4:first-child { margin-top: 0; }

.skills-card {
  padding: 10px 11px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-left: 3px solid var(--skill-color, #8fa0bd);
  border-radius: 9px;
  background: rgba(0, 0, 0, 0.22);
}

.skills-desc {
  margin: 7px 0 0;
  color: var(--text-dim);
  font-size: 11.5px;
  line-height: 1.4;
}

.skills-cap {
  margin: 5px 0 0;
  color: #bac8d8;
  font-size: 10.5px;
}

.skills-empty {
  margin: 0;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.5;
}

#friends-btn {
  position: relative;
}

#friends-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(420px, 94vw);
  max-height: min(78vh, 640px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 12px;
  z-index: 12;
  user-select: none;
}

#friends-shortcut {
  padding: 2px 7px;
  border: 1px solid var(--panel-border);
  border-radius: 5px;
  color: var(--text-dim);
  font-size: 11px;
}

#friends-close {
  margin-left: auto;
}

#friends-add-form label,
.friends-section-title {
  display: block;
  margin: 0 0 4px;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
}

.friends-add-row {
  display: flex;
  gap: 8px;
}

.friends-add-row .ui-input {
  flex: 1 1 auto;
}

#friends-incoming,
#friends-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-y: auto;
  min-height: 0;
}

.friends-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.friends-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.friends-row .ui-status-pill.is-online {
  color: var(--accent);
}

.friends-empty {
  margin: 0;
  color: var(--text-dim);
  font-size: 12px;
}

.quest-entry-reward { color: var(--gold-soft); }

/* Confirmation modal (confirmDialog.js) --------------------------------- */

/* The one prompt in the game. It layers over whatever panel opened it rather
   than replacing it, and the scrim dims without blurring: a player agreeing to
   a fee should still be able to read the card the fee is for. */
#confirm-modal {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
}

#confirm-scrim {
  position: absolute;
  inset: 0;
  background: rgba(4, 6, 12, 0.45);
  animation: confirm-scrim-in 0.16s ease-out both;
}

#confirm-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(360px, 90vw);
  padding: 16px 18px;
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(251, 191, 36, 0.07), transparent 60%),
    var(--panel-bg);
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  user-select: none;
  animation: confirm-in 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
}

#confirm-card.is-danger {
  border-color: rgba(248, 113, 113, 0.4);
}

#confirm-head {
  display: flex;
  align-items: center;
  gap: 9px;
}

#confirm-title {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.2px;
}

#confirm-mark {
  display: flex;
  color: var(--gold-soft);
}

#confirm-card.is-danger #confirm-mark {
  color: #f87171;
}

.confirm-glyph svg {
  width: 20px;
  height: 20px;
}

#confirm-body {
  margin: 0;
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.5;
}

#confirm-choice {
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 54px;
  padding: 8px 10px;
}

#confirm-choice.hidden {
  display: none;
}

#confirm-choice-mark {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border: 1px solid color-mix(in srgb, var(--accent) 42%, var(--panel-border));
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  color: var(--accent);
}

.confirm-choice-glyph,
.confirm-choice-glyph svg {
  width: 25px;
  height: 25px;
}

#confirm-choice-copy {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

#confirm-choice-copy small {
  color: var(--text-dim);
  font-size: 8px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

#confirm-choice-copy strong {
  color: var(--text);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 18px;
}

#confirm-card.is-gamble {
  width: min(390px, 90vw);
  gap: 11px;
  overflow: hidden;
  border-color: color-mix(in srgb, var(--gold) 30%, var(--panel-border));
  background:
    radial-gradient(circle at 8% 0%, color-mix(in srgb, var(--gold) 15%, transparent), transparent 48%),
    radial-gradient(circle at 92% 10%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 42%),
    var(--panel-bg);
}

#confirm-card.is-gamble::after {
  content: '';
  position: absolute;
  right: -46px;
  top: -52px;
  width: 138px;
  height: 138px;
  border: 1px solid color-mix(in srgb, var(--gold) 18%, transparent);
  border-radius: 50%;
  pointer-events: none;
}

#confirm-card.is-gamble #confirm-head {
  min-height: 38px;
}

#confirm-card.is-gamble #confirm-mark {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid color-mix(in srgb, var(--gold) 38%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--gold) 9%, transparent);
}

#confirm-card.is-gamble #confirm-title {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 20px;
}

#confirm-card.is-gamble #confirm-choice {
  background:
    linear-gradient(100deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent 68%),
    rgba(0, 0, 0, 0.2);
}

#confirm-card.is-gamble #confirm-cost {
  position: absolute;
  right: 18px;
  bottom: 17px;
}

#confirm-card.is-gamble .confirm-cost-chip {
  min-height: 30px;
  padding-inline: 12px;
  border-color: color-mix(in srgb, var(--gold) 44%, transparent);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  color: var(--gold-soft);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 14px;
}

#confirm-card.is-gamble #confirm-actions {
  justify-content: flex-start;
  padding-right: 92px;
}

#confirm-card.is-gamble #confirm-ok {
  border-color: color-mix(in srgb, var(--accent) 68%, transparent);
  box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 10%, transparent);
}

.confirm-cost-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border: 1px solid rgba(251, 191, 36, 0.3);
  border-radius: 999px;
  background: rgba(251, 191, 36, 0.1);
  color: var(--gold-soft);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.confirm-cost-chip.unaffordable {
  border-color: rgba(248, 113, 113, 0.35);
  background: rgba(248, 113, 113, 0.1);
  color: #f87171;
}

.confirm-cost-chip .dialogue-chip-glyph svg {
  width: 14px;
  height: 14px;
}

#confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 2px;
}

#confirm-actions button {
  padding: 7px 16px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, transform 0.05s ease;
}

#confirm-actions button:hover {
  background: rgba(255, 255, 255, 0.14);
}

#confirm-actions button:active {
  transform: scale(0.98);
}

#confirm-actions button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

#confirm-ok {
  border-color: var(--accent);
  background: rgba(110, 231, 183, 0.12);
  color: var(--accent);
  font-weight: 600;
}

#confirm-ok:hover {
  background: rgba(110, 231, 183, 0.22);
}

#confirm-card.is-danger #confirm-ok {
  border-color: rgba(248, 113, 113, 0.55);
  background: rgba(248, 113, 113, 0.12);
  color: #f87171;
}

#confirm-card.is-danger #confirm-ok:hover {
  background: rgba(248, 113, 113, 0.2);
}

@keyframes confirm-in {
  from {
    opacity: 0;
    transform: scale(0.96) translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes confirm-scrim-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* Motion here is feedback, never information: every state above is also
   carried by color, position, or text. */
@media (prefers-reduced-motion: reduce) {
  #confirm-card,
  #confirm-scrim,
  .dialogue-skill,
  .dialogue-service,
  .dialogue-lesson,
  .dialogue-quest,
  .dialogue-skill.is-rankup,
  .dialogue-skill.is-rankup .skill-pip.filled:last-of-type,
  .feast-hall.is-called-by-you,
  .feast-hall.is-called-by-you .feast-track,
  .feast-seat.is-fresh,
  .feast-gain {
    animation: none;
  }

  .feast-track-fill {
    transition: none;
  }

  .skill-bar-fill {
    transition: none;
  }
}

/* Quest log (Phase 7.4) */
#quest-panel {
  position: fixed;
  top: 72px;
  right: 16px;
  width: min(340px, 92vw);
  /* Tall enough for the active chain plus a full Crossingvale completed list
     without a scrollbar on a normal desktop viewport. */
  max-height: min(88vh, 860px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  z-index: 12;
  user-select: none;
  overflow: hidden;
}

#quest-header {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 600;
}

#quest-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#quest-list {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* Prefer growing the panel over scrolling; keep overflow as a last resort
     on short viewports rather than a standing scrollbar. */
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Section heads for the log's Active / Completed halves. Quiet and small: they
   separate two lists, they are not content themselves. */
.quest-section-title {
  margin: 2px 0 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.quest-section-title:not(:first-child) {
  margin-top: 6px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.quest-entry {
  padding: 8px 10px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
}

/* A turned-in quest is history: it recedes so the active list stays the thing
   the eye lands on, and it carries no controls to reach for. */
.quest-entry.done {
  padding: 5px 10px;
  border-color: rgba(255, 255, 255, 0.05);
  background: rgba(0, 0, 0, 0.12);
}

.quest-entry-title {
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 4px;
}

.quest-entry.done .quest-entry-title {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-weight: 500;
  color: var(--text-dim);
}

.quest-entry-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Level at turn-in, parked on the right of the completed row. */
.quest-entry-level {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-dim);
  opacity: 0.8;
}

.quest-entry-check {
  flex-shrink: 0;
  color: var(--done, #86efac);
}

.quest-entry-check svg {
  width: 13px;
  height: 13px;
}

.quest-entry-obj {
  margin: 2px 0;
  font-size: 12px;
  color: var(--text-dim);
}

.quest-entry-obj.done {
  color: #86efac;
  text-decoration: line-through;
}

.quest-entry-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

.quest-abandon {
  padding: 4px 10px;
  border: 1px solid rgba(248, 113, 113, 0.45);
  border-radius: 7px;
  background: rgba(248, 113, 113, 0.1);
  color: #fca5a5;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
}

.quest-abandon:hover {
  border-color: rgba(248, 113, 113, 0.7);
  background: rgba(248, 113, 113, 0.18);
}

/* Corner tracker: same entries as the log, quieter and out of the way. It sits
   under the minimap on the left, where nothing else competes for space, until
   the player drags it somewhere else (uiLayout.js). */
#quest-tracker {
  position: fixed;
  left: var(--hud-edge);
  /* Derived from the minimap rather than a magic number: at the old 250px it
     overlapped the minimap's box and only looked clear because it is a circle. */
  top: calc(var(--minimap-top) + var(--minimap-size) + 16px);
  width: min(230px, 40vw);
  display: flex;
  flex-direction: column;
  gap: 6px;
  z-index: 9;
  /* Interactive for the same reason as #minimap: drag / right-click anywhere. */
  pointer-events: auto;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}

body.admin-position-readout-visible #quest-tracker {
  top: calc(var(--minimap-top) + var(--minimap-size) + 42px);
}

#quest-tracker.hidden {
  display: none;
}

.quest-track-title {
  margin: 0 0 2px;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
}

.quest-track-obj {
  margin: 1px 0;
  font-size: 12px;
  line-height: 1.35;
  color: rgba(232, 236, 242, 0.86);
}

.quest-track-obj.done {
  color: #86efac;
}

.quest-empty {
  margin: 0;
  font-size: 13px;
  color: var(--text-dim);
}


/* ---------- Tablet touch play (html.touch-play) ---------- */

#touch-controls {
  position: fixed;
  inset: 0;
  z-index: 8;
  pointer-events: none;
}

#touch-controls.hidden {
  display: none;
}

#touch-stick {
  position: absolute;
  left: max(16px, env(safe-area-inset-left));
  bottom: max(96px, env(safe-area-inset-bottom));
  width: 128px;
  height: 128px;
  border-radius: 50%;
  background: rgba(12, 16, 24, 0.28);
  border: 2px solid rgba(180, 200, 220, 0.28);
  pointer-events: auto;
  touch-action: none;
}

#touch-stick-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 52px;
  height: 52px;
  margin: -26px 0 0 -26px;
  border-radius: 50%;
  background: rgba(200, 220, 240, 0.42);
  border: 2px solid rgba(255, 255, 255, 0.35);
  pointer-events: none;
  will-change: transform;
}

#touch-look {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 42%;
  pointer-events: auto;
  touch-action: none;
}

#touch-actions {
  position: absolute;
  right: max(14px, env(safe-area-inset-right));
  bottom: max(96px, env(safe-area-inset-bottom));
  display: grid;
  grid-template-columns: repeat(2, 64px);
  gap: 10px;
  pointer-events: auto;
  z-index: 1;
}

#touch-actions button {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid rgba(180, 200, 220, 0.4);
  background: rgba(12, 16, 24, 0.55);
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
  touch-action: none;
  user-select: none;
}

#touch-actions button:active,
#touch-actions button.is-active {
  background: rgba(80, 140, 120, 0.55);
  border-color: rgba(160, 230, 200, 0.65);
}

#touch-attack {
  background: rgba(90, 36, 36, 0.62);
}

#touch-rotate-hint {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  margin: 0;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(12, 16, 24, 0.78);
  border: 1px solid var(--panel-border);
  color: var(--text);
  font-size: 13px;
  pointer-events: none;
}

#touch-rotate-hint.hidden {
  display: none;
}

#chat-row {
  display: flex;
  gap: 6px;
  align-items: stretch;
}

#chat-row #chat-input {
  flex: 1;
  min-width: 0;
}

#chat-focus-btn {
  flex: 0 0 auto;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: var(--panel-bg);
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
}

#chat-focus-btn.hidden {
  display: none;
}

html.touch-play #hud-dock {
  bottom: max(18px, env(safe-area-inset-bottom));
}

/* Keep Style / Settings / Emotes clear of the Jump / Attack cluster. */
html.touch-play #hud-actions {
  bottom: auto;
  top: max(56px, env(safe-area-inset-top));
  right: max(12px, env(safe-area-inset-right));
  flex-direction: column;
}

html.touch-play #hotbar-2 {
  right: max(76px, calc(env(safe-area-inset-right) + 64px));
  max-height: calc(100vh - 160px);
  gap: 4px;
}

html.touch-play #hotbar-2 .hotbar-slot {
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
}

html.touch-play #chat {
  left: max(14px, env(safe-area-inset-left));
  bottom: max(210px, calc(env(safe-area-inset-bottom) + 196px));
  width: min(320px, 42vw);
}

html.touch-play #hud-actions button,
html.touch-play .hotbar-slot {
  min-width: 52px;
  min-height: 52px;
}

html.touch-play .hotbar-slot {
  width: 52px;
  height: 52px;
}

html.touch-play #hud-dock {
  /* 10 slots × 52 + 9 gaps × 8 + horizontal padding 20 */
  width: 612px;
}

html.touch-play #charsheet {
  flex-basis: 286px;
  width: 286px;
}

html.touch-play #fullscreen-btn:not(.hidden) {
  font-weight: 700;
}

html.touch-play #inventory-panel,
html.touch-play #shop-panel,
html.touch-play #trade-panel,
html.touch-play #quest-panel,
html.touch-play #dialogue-panel,
html.touch-play #spellbook-panel,
html.touch-play #skills-panel,
html.touch-play #friends-panel,
html.touch-play #settings-panel {
  max-height: min(92vh, 900px);
  overflow: auto;
}

html.touch-play #spellbook-panel {
  width: min(620px, 96vw);
}

html.touch-play #spellbook-list {
  grid-template-columns: 1fr;
}

html.touch-play #inventory-panel {
  min-width: min(960px, 96vw);
  width: min(960px, 96vw);
}

html.touch-play #shop-panel {
  min-width: min(520px, 94vw);
}

html.touch-play .shop-ware-qty {
  margin-top: 4px;
  padding: 4px 8px;
  border-radius: 6px;
  border: 1px solid rgba(180, 200, 220, 0.35);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
}

#shop-hint-touch.hidden,
#help-touch.hidden,
#help-desktop.hidden {
  display: none;
}

/* Pond fishing panel (sibling of the lockbox timing UI). */
#fishing-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(360px, 92vw);
  padding: 14px 16px;
  background: rgba(10, 13, 22, 0.94);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 236, 190, 0.16);
  border-radius: 12px;
  box-shadow: 0 20px 65px rgba(0, 0, 0, 0.65);
  z-index: 14;
  user-select: none;
}
#fishing-header {
  display: flex;
  align-items: center;
  font-weight: 700;
  color: #8ec8e0;
  margin-bottom: 10px;
}
#fishing-cancel {
  margin-left: auto;
  width: 28px;
  height: 28px;
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
}
/* Catch celebration: champagne gold (cool, not amber), soft shimmer. */
#fishing-catch-banner {
  margin: 2px 0 6px;
  text-align: center;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: 0.04em;
  line-height: 1.15;
  background: linear-gradient(
    105deg,
    #b9a86a 0%,
    #fff8dc 18%,
    #e6d7a0 38%,
    #fffef6 52%,
    #cfc07e 72%,
    #f3e8b8 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 12px rgba(255, 246, 210, 0.4));
  animation: fishing-catch-shimmer 2.6s ease-in-out infinite;
}
@keyframes fishing-catch-shimmer {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}
@media (prefers-reduced-motion: reduce) {
  #fishing-catch-banner {
    animation: none;
    background: none;
    color: #f0e6b8;
    -webkit-text-fill-color: #f0e6b8;
    filter: none;
  }
}
/* Rod tackle: the same chrome as the fishing panel, since it is the same tool. */
#tackle-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(380px, 92vw);
  padding: 14px 16px;
  background: rgba(10, 13, 22, 0.94);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 236, 190, 0.16);
  border-radius: 12px;
  box-shadow: 0 20px 65px rgba(0, 0, 0, 0.65);
  z-index: 15;
  user-select: none;
}
#tackle-header {
  display: flex;
  align-items: center;
  font-weight: 700;
  color: #8ec8e0;
  margin-bottom: 10px;
}
#tackle-close {
  margin-left: auto;
  width: 28px;
  height: 28px;
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--panel-border);
  border-radius: 8px;
}
#tackle-slots {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.tackle-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 10px 8px;
  border-radius: 10px;
  border: 1px solid var(--panel-border);
  background: rgba(0, 0, 0, 0.28);
}
.tackle-slot-label {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.tackle-cell {
  position: relative;
  width: 46px;
  height: 46px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.04);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
/* .inv-item is absolute/inset for bag slots; without a positioned cell it
   fills the whole fixed tackle panel (a giant bait icon with no chrome). */
.tackle-cell .inv-item {
  inset: 2px;
}
.tackle-slot-note {
  font-size: 12px;
  color: var(--text);
  min-height: 1.2em;
  text-align: center;
}
.tackle-strip {
  padding: 3px 10px;
  font-size: 11px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-dim);
  cursor: pointer;
}
.tackle-strip:disabled {
  opacity: 0.35;
  cursor: default;
}
#tackle-hint {
  margin: 10px 0 8px;
  font-size: 12px;
  color: var(--text-dim);
  text-align: center;
}
#tackle-bag-label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}
#tackle-bag {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 34px;
}
.tackle-offer {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px 4px 4px;
  border-radius: 8px;
  border: 1px solid var(--panel-border);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text);
  font-size: 12px;
  cursor: pointer;
}
.tackle-offer .inv-item {
  position: relative;
  inset: auto;
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
}
.tackle-offer:hover:not(:disabled) {
  border-color: rgba(142, 200, 224, 0.5);
  background: rgba(58, 120, 150, 0.32);
}
.tackle-offer:disabled {
  opacity: 0.4;
  cursor: default;
}
.tackle-empty {
  font-size: 12px;
  color: var(--text-dim);
}
#fishing-dial {
  --marker: 0.5;
  --target: 0.5;
  --width: 0.2;
  position: relative;
  width: 140px;
  height: 140px;
  margin: 8px auto;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background:
    conic-gradient(
      from calc((var(--target) - var(--width) / 2) * 360deg),
      rgba(110, 231, 183, 0.55) 0deg,
      rgba(110, 231, 183, 0.55) calc(var(--width) * 360deg),
      transparent calc(var(--width) * 360deg)
    ),
    rgba(6, 9, 16, 0.35);
}
#fishing-dial::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 6px;
  width: 3px;
  height: 28px;
  margin-left: -1.5px;
  background: #fff0a8;
  border-radius: 2px;
  box-shadow: 0 0 9px #fff0a8;
  transform-origin: 50% 64px;
  transform: rotate(calc(var(--marker) * 360deg));
}
/* Landed catch: the dial's seat becomes a large inventory portrait. */
#fishing-catch {
  position: relative;
  width: 128px;
  height: 128px;
  margin: 8px auto 4px;
  border-radius: 16px;
  border: 1px solid rgba(255, 236, 190, 0.28);
  background: rgba(0, 0, 0, 0.32);
  box-shadow: 0 0 28px rgba(142, 200, 224, 0.22);
  overflow: hidden;
}
/* .inv-item defaults to absolute/inset for bag slots; pin it to this frame. */
#fishing-catch .inv-item {
  inset: 8px;
}
#fishing-status {
  min-height: 2.4em;
  margin: 8px 0;
  color: var(--text);
  font-size: 13px;
  text-align: center;
}
#fishing-primary {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border-radius: 8px;
  border: 1px solid rgba(142, 200, 224, 0.35);
  background: rgba(58, 120, 150, 0.45);
  color: #e8f6fc;
  font-weight: 700;
  cursor: pointer;
}
#fishing-primary:disabled {
  opacity: 0.5;
  cursor: default;
}
/* Phase 10 party and Hollowroot HUD.
   Always-on roster is quest-tracker family chrome (transparent shell + text
   shadow), not a .ui-surface panel. Member rows keep compact glass chips so HP
   bars stay readable over bright sky. Invite / ready / rewards modals stay
   full surfaces. Drag and lock live on #party-header only so row RMB menus
   do not fight the window Lock menu. */
#party-panel {
  position: fixed;
  /* Left rail, under the quest tracker (which is itself under the minimap).
     The tracker's height varies with how many quests are tracked, so this
     clears a few entries; the player can drag it anywhere (uiLayout.js). */
  left: var(--hud-edge);
  top: calc(var(--minimap-top) + var(--minimap-size) + 236px);
  width: 220px;
  z-index: 34;
  display: flex;
  flex-direction: column;
  gap: 6px;
  user-select: none;
  overflow: visible;
  background: transparent;
  border: none;
  box-shadow: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}
/* Glassless overlay: do not paint the shared panel drag shadow. */
#party-panel.ui-draggable.dragging {
  box-shadow: none;
}
/* The HUD is revealed behind the login overlay so its first layout happens
   under the progress bar (main.js), but this panel outranks that overlay's
   z-index, so it would otherwise sit on top of the loading screen. Hide it
   with visibility, not display, so it still lays out early. */
#login-overlay:not(.hidden) ~ #hud #party-panel {
  visibility: hidden;
}
#party-header {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 0;
  padding: 0 2px;
}
.party-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.02em;
}
#party-lock {
  margin-left: auto;
  color: var(--gold-soft);
  text-shadow: none;
}
#party-roster {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 0;
}
.party-member {
  position: relative;
  padding: 6px 8px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  background: rgba(8, 12, 22, 0.55);
  backdrop-filter: blur(4px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
  text-shadow: none;
}
.party-member.is-interactive {
  cursor: pointer;
}
.party-member.is-targeted {
  border-color: rgba(74, 168, 255, 0.85);
  box-shadow:
    0 0 0 1px rgba(74, 168, 255, 0.45),
    0 2px 12px rgba(74, 168, 255, 0.22);
}
.party-member.offline {
  opacity: 0.48;
}
.party-member-name {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  color: var(--text);
  font-size: 12px;
  font-weight: 650;
  line-height: 1.3;
}
/* Direct child only: the level / Offline chip. The leader crown is a span too,
   and it lives one level down inside the title box, where it keeps its own gold. */
.party-member-name > span {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 500;
}
.party-member-title {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
}
.party-leader-glyph {
  color: var(--gold);
}
.party-leader-glyph svg {
  width: 13px;
  height: 13px;
}
.party-health {
  height: 6px;
  margin-top: 5px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.5);
}
.party-health i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #34d399, var(--accent));
}
#party-actions,
#dungeon-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0;
}
#party-actions .ui-button {
  flex: 0 0 auto;
  min-height: 28px;
  padding: 5px 10px;
  text-shadow: none;
}
#party-loot {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 2px;
}
#party-loot.hidden {
  display: none;
}
.party-loot-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.party-loot-modes .ui-button {
  min-height: 26px;
  padding: 4px 8px;
  font-size: 11px;
  text-shadow: none;
}
#dungeon-actions .ui-button {
  flex: 1 1 auto;
  text-shadow: none;
}
#dungeon-actions {
  padding-top: 2px;
  margin-top: 2px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
#dungeon-progress {
  display: grid;
  gap: 3px;
  padding: 0 2px;
  color: rgba(232, 236, 242, 0.78);
  font-size: 11px;
  line-height: 1.4;
}
.dungeon-progress-row:first-child {
  color: var(--text);
}
#dungeon-rewards-header {
  padding: 0 0 11px;
  border-bottom: 1px solid var(--panel-border);
}
#dungeon-rewards-header > div {
  display: grid;
  gap: 2px;
}
#dungeon-rewards-header small {
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.dungeon-rewards-open.ui-button {
  border-color: var(--gold-deep);
  color: var(--gold-soft);
}
.dungeon-rewards-open .ui-status-pill {
  min-width: 20px;
  justify-content: center;
  margin-left: 4px;
  border-color: var(--gold-deep);
  color: var(--gold-soft);
}
#party-prompt-card {
  z-index: 1;
}
#party-prompt-card .ui-panel-header {
  padding-bottom: 9px;
  border-bottom: 1px solid var(--panel-border);
}
#party-prompt-text {
  margin: 12px 0;
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.5;
}
#party-invite-form {
  display: grid;
  gap: 6px;
  margin-bottom: 12px;
}
#party-invite-form label {
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
#party-prompt-status {
  display: grid;
  gap: 6px;
  margin: 0 0 12px;
}
.party-ready-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  font-size: 12px;
}
.party-ready-row .is-ready {
  border-color: rgba(110, 231, 183, 0.34);
  color: var(--done);
}
.party-ready-row .is-declined {
  border-color: rgba(248, 113, 113, 0.4);
  color: #fca5a5;
}
#party-prompt-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 14px;
}
#dungeon-rewards {
  z-index: 96;
}
#dungeon-rewards-card {
  width: min(920px, calc(100vw - 32px));
  max-height: min(86vh, 780px);
  padding: 16px 18px 18px;
  overflow: hidden;
  background:
    radial-gradient(circle at 12% 0%, rgba(110, 231, 183, 0.09), transparent 32%),
    radial-gradient(circle at 88% 100%, rgba(110, 231, 183, 0.055), transparent 38%),
    var(--panel-bg);
}
#dungeon-rewards-intro {
  margin: 10px 0 0;
  color: var(--text-dim);
  font-size: 12px;
  line-height: 1.45;
}
#dungeon-rewards-status {
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px solid var(--gold-deep);
  border-radius: 8px;
  color: var(--gold-soft);
  background: rgba(0, 0, 0, 0.22);
  font-size: 12px;
}
#dungeon-rewards-list {
  display: grid;
  gap: 18px;
  max-height: calc(min(86vh, 780px) - 112px);
  margin-top: 12px;
  padding: 2px 4px 4px 0;
  overflow-y: auto;
}
.dungeon-reward-group {
  display: grid;
  gap: 9px;
}
.dungeon-reward-group-header {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 12px;
}
.dungeon-reward-group-header > div {
  display: grid;
  gap: 5px;
}
.dungeon-reward-source {
  width: max-content;
  border-color: rgba(110, 231, 183, 0.32);
  color: var(--accent);
}
.dungeon-reward-group h3 {
  margin: 0;
  color: var(--text);
  font-size: 16px;
  letter-spacing: 0.01em;
}
.dungeon-reward-option-count {
  padding-bottom: 2px;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.dungeon-reward-choices {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}
.dungeon-reward-choices.is-choice-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.dungeon-reward-choice {
  position: relative;
  display: grid;
  grid-template-columns: 86px minmax(0, 1fr);
  gap: 12px;
  min-width: 0;
  padding: 12px;
  overflow: hidden;
  border-color: color-mix(in srgb, var(--reward-rarity) 38%, var(--panel-border));
  background:
    linear-gradient(145deg, color-mix(in srgb, var(--reward-rarity) 7%, transparent), transparent 55%),
    rgba(0, 0, 0, 0.24);
  animation: dungeon-reward-reveal 0.34s ease-out both;
  animation-delay: calc(var(--reward-choice-index) * 70ms);
}
.dungeon-reward-choice::after {
  content: '';
  position: absolute;
  inset: -60% 55% -60% -35%;
  pointer-events: none;
  transform: rotate(18deg) translateX(-75%);
  background: linear-gradient(90deg, transparent, rgba(110, 231, 183, 0.09), transparent);
  animation: dungeon-rootglass-sheen 5.4s ease-in-out infinite;
}
.dungeon-reward-icon {
  position: relative;
  align-self: start;
  width: 86px;
  height: 86px;
  padding: 5px;
  border: 1px solid color-mix(in srgb, var(--reward-rarity) 48%, var(--panel-border));
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.28);
  box-shadow: 0 0 22px color-mix(in srgb, var(--reward-rarity) 15%, transparent);
}
.dungeon-reward-icon .inv-item,
.dungeon-reward-icon .inv-item img {
  width: 100%;
  height: 100%;
}
.dungeon-reward-facts {
  position: relative;
  z-index: 1;
  min-width: 0;
}
.dungeon-reward-facts h4 {
  margin: 0;
  font-size: 14px;
  line-height: 1.25;
}
.dungeon-reward-meta {
  margin-top: 2px;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.dungeon-reward-description {
  min-height: 34px;
  margin: 8px 0 7px;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.45;
}
.dungeon-reward-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  color: var(--text);
  font-size: 11px;
}
.dungeon-reward-stats .ui-status-pill {
  color: var(--gold-soft);
}
.dungeon-reward-comparison {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 8px;
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--panel-border);
  color: var(--text-dim);
  font-size: 10px;
}
.dungeon-reward-comparison strong {
  flex-basis: 100%;
  color: var(--text-dim);
  font-size: 10px;
}
.dungeon-reward-comparison .is-better { color: var(--done); }
.dungeon-reward-comparison .is-worse { color: #fca5a5; }
.dungeon-reward-comparison .is-neutral { color: var(--text-dim); }
.dungeon-reward-claim.ui-button {
  position: relative;
  z-index: 1;
  grid-column: 1 / -1;
  width: 100%;
  min-height: 38px;
  border-color: var(--gold-deep);
  background: linear-gradient(180deg, #ffe9a8, #f0c256 48%, #c9922f);
  color: var(--gold-ink);
  font-size: 12px;
  font-weight: 750;
  box-shadow: 0 0 18px rgba(251, 191, 36, 0.18);
}
.dungeon-reward-claim.ui-button:hover:not(:disabled) {
  border-color: var(--gold-soft);
  background: linear-gradient(180deg, #fff0ba, #f6cf6d 48%, #d49c38);
}
.dungeon-reward-claim.ui-button:focus-visible {
  outline-color: var(--gold-soft);
}
.dungeon-reward-claim:disabled {
  cursor: wait;
  filter: saturate(0.45);
  opacity: 0.72;
}
@keyframes dungeon-reward-reveal {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes dungeon-rootglass-sheen {
  0%, 68% { transform: rotate(18deg) translateX(-75%); }
  88%, 100% { transform: rotate(18deg) translateX(340%); }
}
@media (max-width: 760px) {
  #dungeon-rewards-card { padding: 14px; }
  .dungeon-reward-choices.is-choice-grid { grid-template-columns: 1fr; }
  .dungeon-reward-description { min-height: 0; }
}
@media (max-width: 460px) {
  .dungeon-reward-choice { grid-template-columns: 68px minmax(0, 1fr); padding: 10px; }
  .dungeon-reward-icon { width: 68px; height: 68px; }
  .dungeon-reward-group-header { align-items: start; }
  .dungeon-reward-option-count { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .dungeon-reward-choice,
  .dungeon-reward-choice::after {
    animation: none;
  }
}
#dungeon-loading {
  position: fixed; inset: 0; z-index: 110; display: grid; place-items: center;
  color: var(--text); background: radial-gradient(circle, rgba(19, 33, 43, .94), rgba(5, 8, 14, .99));
  text-align: center;
}
#dungeon-loading h2 { margin: 0 0 8px; font-size: 27px; font-weight: 750; }
#dungeon-loading p { color: var(--text-dim); }

/* Hearth cooking station: skillet hero + fish chips on shared UI chrome. */
#cook-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* uiLayout.js clears this transform on drag, so nothing here may animate it. */
  width: min(760px, calc(100vw - 24px));
  max-height: min(86vh, 620px);
  padding: 14px 16px;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: 10px;
  user-select: none;
}
#cook-panel.hidden {
  display: none;
}
#cook-station {
  position: relative;
  display: grid;
  grid-template-columns: minmax(250px, 0.82fr) minmax(0, 1.45fr);
  grid-template-areas: "hero recipes";
  gap: 10px;
  min-height: 0;
  flex: 1;
}
#cook-hero {
  grid-area: hero;
  position: relative;
  min-height: 364px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  background: radial-gradient(ellipse at 50% 80%, rgba(105, 48, 18, 0.46), rgba(8, 10, 14, 0.42));
}
#cook-skillet {
  display: block;
  width: 100%;
  height: 100%;
}
#cook-castbar {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 8px;
  height: 16px;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
  border: 1px solid rgba(245, 181, 66, 0.48);
  border-radius: 999px;
  background: rgba(25, 14, 8, 0.8);
  box-shadow: 0 0 10px rgba(245, 157, 45, 0.2);
}
#cook-castbar-fill {
  width: 0%;
  height: 100%;
  opacity: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #8c401b 0%, #dc841f 46%, #ffd46a 100%);
  box-shadow: 0 0 12px rgba(255, 187, 65, 0.6);
}
#cook-castbar-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  color: #fff5d6;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
}
#cook-panel.is-cooking #cook-castbar-fill {
  opacity: 1;
  animation: cook-cast-fill var(--cook-ms, 2400ms) linear forwards,
    cook-cast-shimmer 1.1s ease-in-out infinite;
}
#cook-panel.is-cooking #cook-castbar-label {
  opacity: 1;
}
@keyframes cook-cast-fill {
  from { width: 0%; }
  to { width: 100%; }
}
@keyframes cook-cast-shimmer {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.2); }
}
@media (prefers-reduced-motion: reduce) {
  #cook-panel.is-cooking #cook-castbar-fill {
    animation: cook-cast-fill var(--cook-ms, 2400ms) linear forwards;
  }
}
#cook-reveal {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 12px;
  border-radius: 10px;
  background: rgba(18, 13, 10, 0.93);
  backdrop-filter: blur(8px);
}
#cook-reveal.hidden {
  display: none;
}
#cook-reveal-banner {
  margin: 2px 0 4px;
  color: var(--gold-soft);
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.03em;
  line-height: 1.2;
  text-align: center;
  filter: drop-shadow(0 0 10px rgba(245, 181, 66, 0.32));
}
#cook-reveal-icon {
  position: relative;
  width: 112px;
  height: 112px;
  margin: 4px auto 2px;
  overflow: hidden;
  border: 1px solid rgba(245, 181, 66, 0.38);
  border-radius: 16px;
  background: rgba(0, 0, 0, 0.32);
  box-shadow: 0 0 24px rgba(245, 157, 45, 0.18);
}
#cook-reveal-icon .inv-item {
  inset: 8px;
}
#cook-list {
  grid-area: recipes;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(3, minmax(0, 1fr));
  gap: 8px;
  overflow: visible;
  min-height: 0;
}
#cook-panel.is-cooking .cook-card {
  pointer-events: none;
}
.cook-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 9px;
  cursor: pointer;
}
.cook-card.is-locked {
  opacity: 0.72;
}
.cook-card.is-selected {
  border-color: rgba(245, 181, 66, 0.46);
  background: rgba(245, 157, 45, 0.08);
}
.cook-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.cook-card-head .inv-item {
  position: relative;
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
}
.cook-card-titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.cook-card-name {
  font-weight: 700;
  color: var(--text);
}
.cook-card-meta {
  font-size: 12px;
  color: var(--text-dim);
}
.cook-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.cook-card-costs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.cook-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px 2px 2px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.22);
}
.cook-chip .inv-item {
  position: relative;
  inset: auto;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
}
.cook-chip-count {
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.cook-chip.is-short .cook-chip-count {
  color: #f87171;
}
.cook-card-action {
  display: flex;
  justify-content: flex-end;
  flex: 0 0 auto;
}
@media (max-width: 680px) {
  #cook-panel {
    width: min(520px, calc(100vw - 16px));
    max-height: calc(100vh - 16px);
    padding: 10px;
  }
  #cook-station {
    grid-template-columns: 1fr;
    grid-template-areas:
      "hero"
      "recipes";
  }
  #cook-hero {
    min-height: 116px;
    height: 116px;
  }
  #cook-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: repeat(3, auto);
  }
  .cook-card {
    padding: 6px 7px;
  }
  .cook-card-meta {
    font-size: 11px;
  }
  .cook-chip .inv-item {
    width: 24px;
    height: 24px;
    flex-basis: 24px;
  }
}

/* Crossing Cup: illustrated table card, mark medallions, and stake chips on
   the shared in-world surface/card/button chrome. */
#gamble-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(500px, calc(100vw - 24px));
  max-height: min(88vh, 720px);
  padding: 14px 16px 16px;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: 9px;
  overflow: hidden auto;
  isolation: isolate;
  user-select: none;
}

#gamble-panel::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0 0 auto;
  height: 190px;
  background:
    radial-gradient(circle at 16% 0%, color-mix(in srgb, var(--gold) 18%, transparent), transparent 54%),
    radial-gradient(circle at 88% 10%, color-mix(in srgb, var(--accent) 13%, transparent), transparent 48%);
  pointer-events: none;
}

#gamble-header {
  padding-bottom: 2px;
}

#gamble-header > span {
  font-size: 15px;
  letter-spacing: 0.055em;
}

#gamble-hero {
  position: relative;
  display: grid;
  grid-template-columns: 82px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 92px;
  padding: 10px 12px 10px 8px;
  overflow: hidden;
  background:
    linear-gradient(115deg, color-mix(in srgb, var(--gold) 10%, transparent), transparent 42%),
    color-mix(in srgb, var(--panel-bg) 82%, transparent);
}

#gamble-hero::after {
  content: '';
  position: absolute;
  right: -32px;
  bottom: -54px;
  width: 150px;
  height: 120px;
  border: 1px solid color-mix(in srgb, var(--gold) 18%, transparent);
  border-radius: 50%;
  transform: rotate(-18deg);
  pointer-events: none;
}

.gamble-crest {
  width: 82px;
  height: 82px;
  color: var(--gold-soft);
  filter: drop-shadow(0 7px 12px rgba(0, 0, 0, 0.4));
}

.gamble-crest svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.gamble-crest-halo {
  fill: color-mix(in srgb, var(--gold) 11%, transparent);
  stroke: color-mix(in srgb, var(--gold-soft) 42%, transparent);
  stroke-width: 1.5;
}

.gamble-crest-ring {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linejoin: round;
}

.gamble-crest-cup {
  fill: color-mix(in srgb, var(--gold-deep) 72%, var(--panel-bg));
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linejoin: round;
}

.gamble-crest-rim,
.gamble-crest-bone {
  fill: var(--text);
  stroke: currentColor;
  stroke-width: 2;
  stroke-linejoin: round;
}

.gamble-crest-mark {
  fill: var(--accent);
  stroke: color-mix(in srgb, var(--text) 72%, transparent);
  stroke-width: 1.4;
}

.gamble-crest-pip {
  fill: var(--gold-soft);
}

.gamble-hero-copy {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.gamble-kicker {
  color: var(--gold-soft);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.gamble-hero-copy strong {
  color: var(--text);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 22px;
  line-height: 1.05;
}

.gamble-hero-copy > span:last-child {
  max-width: 230px;
  color: var(--text-dim);
  font-size: 11px;
  line-height: 1.35;
}

#gamble-purse {
  margin: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: auto auto;
  align-content: center;
  justify-items: end;
  min-width: 76px;
  min-height: 52px;
  padding: 6px 9px;
  border-color: color-mix(in srgb, var(--gold) 42%, var(--panel-border));
  background: color-mix(in srgb, var(--gold) 9%, transparent);
  color: var(--gold-soft);
  line-height: 1;
}

.gamble-purse-label {
  grid-column: 1 / -1;
  color: var(--text-dim);
  font-size: 8px;
  letter-spacing: 0.12em;
}

.gamble-purse-value {
  color: var(--gold);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 21px;
  line-height: 1;
}

.gamble-purse-unit {
  align-self: end;
  padding: 0 0 2px 3px;
  color: var(--gold-soft);
  font-size: 8px;
}

.gamble-section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 2px;
  padding: 0 2px;
}

.gamble-section-heading span {
  color: var(--text);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.gamble-section-heading small {
  color: var(--text-dim);
  font-size: 9px;
}

#gamble-marks {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.gamble-mark {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 5px;
  min-height: 88px;
  padding: 8px 7px 7px;
  overflow: hidden;
  cursor: pointer;
  border: 1px solid transparent;
  color: var(--text-dim);
  transition: transform 0.14s ease, border-color 0.15s, background 0.15s, color 0.15s;
}

.gamble-mark::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 32%, color-mix(in srgb, currentColor 9%, transparent), transparent 48%);
  opacity: 0;
  transition: opacity 0.15s;
  pointer-events: none;
}

.gamble-mark:hover {
  border-color: var(--panel-border);
  color: var(--text);
  transform: translateY(-1px);
}

.gamble-mark:hover::before,
.gamble-mark.is-selected::before {
  opacity: 1;
}

.gamble-mark.is-selected {
  border-color: color-mix(in srgb, var(--accent) 78%, transparent);
  background: color-mix(in srgb, var(--accent) 9%, rgba(0, 0, 0, 0.2));
  color: var(--accent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 16%, transparent);
}

.gamble-mark:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.gamble-mark-medallion {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid color-mix(in srgb, var(--gamble-mark-color, currentColor) 42%, transparent);
  border-radius: 50%;
  background:
    radial-gradient(circle at 36% 28%, color-mix(in srgb, var(--gamble-mark-color, currentColor) 16%, transparent), transparent 55%),
    color-mix(in srgb, var(--panel-bg) 72%, transparent);
  box-shadow:
    inset 0 0 0 3px color-mix(in srgb, var(--gamble-mark-color, currentColor) 7%, transparent),
    0 6px 14px rgba(0, 0, 0, 0.24);
}

.gamble-mark-glyph {
  width: 27px;
  height: 27px;
  color: var(--gamble-mark-color, var(--text-dim));
}

.gamble-mark-glyph svg {
  width: 27px;
  height: 27px;
}

.gamble-mark-label {
  position: relative;
  color: var(--text);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 15px;
}

.gamble-mark.is-selected .gamble-mark-label {
  color: var(--text);
}

#gamble-stakes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 7px;
}

.gamble-stake {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  padding: 7px 9px;
  text-align: left;
}

.gamble-stake-name {
  color: var(--text-dim);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.gamble-stake-value {
  color: var(--text);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 15px;
  line-height: 1;
}

.gamble-stake.is-primary .gamble-stake-name,
.gamble-stake.is-primary .gamble-stake-value {
  color: inherit;
}

.gamble-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 42px;
  padding: 9px 14px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 14px;
  letter-spacing: 0.025em;
}

.gamble-submit-glyph,
.gamble-submit-glyph svg {
  width: 18px;
  height: 18px;
}

#gamble-balance {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 25px;
  margin: 0;
  padding: 4px 8px;
  border-color: color-mix(in srgb, var(--gold) 42%, var(--panel-border));
  background: color-mix(in srgb, var(--gold) 9%, transparent);
  color: var(--gold-soft);
}

.gamble-balance-glyph,
.gamble-balance-glyph svg {
  width: 15px;
  height: 15px;
  color: var(--gold);
}

#gamble-balance strong {
  color: var(--gold);
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 14px;
}

#gamble-balance span:last-child {
  color: var(--text-dim);
  font-size: 9px;
  letter-spacing: 0.04em;
}

#gamble-payouts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 7px 9px;
  background: color-mix(in srgb, var(--panel-bg) 70%, transparent);
}

#gamble-payouts span {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  color: var(--text-dim);
  font-size: 9px;
  line-height: 1.2;
  text-align: center;
}

#gamble-payouts span + span {
  border-left: 1px solid var(--panel-border);
}

#gamble-payouts strong {
  color: var(--text);
  font-size: 10px;
}

#gamble-hint {
  margin: 0;
  padding: 0 4px;
  color: var(--gold-soft);
  font-size: 10px;
  line-height: 1.35;
  text-align: center;
}

@media (max-width: 520px), (max-height: 680px) {
  #gamble-panel {
    gap: 7px;
  }

  #gamble-hero {
    grid-template-columns: 64px minmax(0, 1fr) auto;
    min-height: 74px;
    padding-block: 7px;
  }

  .gamble-crest {
    width: 62px;
    height: 62px;
  }

  .gamble-hero-copy strong {
    font-size: 19px;
  }

  .gamble-hero-copy > span:last-child,
  .gamble-section-heading small {
    display: none;
  }

  .gamble-mark {
    min-height: 82px;
    padding-top: 6px;
  }

  .gamble-mark-medallion {
    width: 39px;
    height: 39px;
  }

  .gamble-mark-glyph,
  .gamble-mark-glyph svg {
    width: 23px;
    height: 23px;
  }
}

/* Elowen brew station: kettle hero + recipe chips on ui-surface chrome. */
#brew-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  /* uiLayout.js clears this transform on drag, so nothing here may animate it. */
  transform: translate(-50%, -50%);
  width: min(440px, 92vw);
  max-height: min(78vh, 680px);
  padding: 14px 16px;
  z-index: 15;
  display: flex;
  flex-direction: column;
  gap: 10px;
  user-select: none;
}
#brew-panel.hidden {
  display: none;
}
#brew-station {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  flex: 1;
}
#brew-hero {
  position: relative;
  height: 176px;
  flex: 0 0 176px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: radial-gradient(ellipse at 50% 78%, rgba(52, 32, 18, 0.55), rgba(8, 10, 16, 0.35));
}
#brew-kettle {
  display: block;
  width: 100%;
  height: 100%;
}
#brew-castbar {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 8px;
  height: 16px;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
  border-radius: 999px;
  border: 1px solid rgba(184, 176, 255, 0.38);
  background: rgba(12, 10, 24, 0.72);
  box-shadow: 0 0 10px rgba(184, 176, 255, 0.18);
}
#brew-castbar-fill {
  width: 0%;
  height: 100%;
  border-radius: inherit;
  opacity: 0;
  background: linear-gradient(90deg, #4a2f9a 0%, #7c5cff 48%, var(--skill) 100%);
  box-shadow: 0 0 12px rgba(184, 176, 255, 0.55);
}
#brew-castbar-label {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #f4f0ff;
  opacity: 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}
#brew-panel.is-brewing #brew-castbar-fill {
  opacity: 1;
  animation: brew-cast-fill var(--brew-ms, 2400ms) linear forwards,
    brew-cast-shimmer 1.2s ease-in-out infinite;
}
#brew-panel.is-brewing #brew-castbar-label {
  opacity: 1;
}
@keyframes brew-cast-fill {
  from {
    width: 0%;
  }
  to {
    width: 100%;
  }
}
@keyframes brew-cast-shimmer {
  0%,
  100% {
    filter: brightness(1);
  }
  50% {
    filter: brightness(1.22);
  }
}
@media (prefers-reduced-motion: reduce) {
  #brew-panel.is-brewing #brew-castbar-fill {
    animation: brew-cast-fill var(--brew-ms, 2400ms) linear forwards;
  }
}
#brew-reveal {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 12px;
  border-radius: 10px;
  background: rgba(12, 16, 28, 0.92);
  backdrop-filter: blur(8px);
}
#brew-reveal.hidden {
  display: none;
}
#brew-reveal-banner {
  margin: 2px 0 4px;
  text-align: center;
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 0.03em;
  line-height: 1.2;
  background: linear-gradient(
    105deg,
    var(--sage) 0%,
    #fff8dc 28%,
    var(--gold-soft) 52%,
    var(--sage) 100%
  );
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 0 10px rgba(181, 201, 164, 0.35));
  animation: brew-reveal-shimmer 2.6s ease-in-out infinite;
}
@keyframes brew-reveal-shimmer {
  0%,
  100% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
}
@media (prefers-reduced-motion: reduce) {
  #brew-reveal-banner {
    animation: none;
    background: none;
    color: var(--gold-soft);
    -webkit-text-fill-color: var(--gold-soft);
    filter: none;
  }
}
#brew-reveal-icon {
  position: relative;
  width: 112px;
  height: 112px;
  margin: 4px auto 2px;
  border-radius: 16px;
  border: 1px solid rgba(181, 201, 164, 0.35);
  background: rgba(0, 0, 0, 0.32);
  box-shadow: 0 0 24px rgba(110, 231, 183, 0.16);
  overflow: hidden;
}
#brew-reveal-icon .inv-item {
  inset: 8px;
}
#brew-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
  min-height: 0;
  flex: 1;
}
#brew-panel.is-brewing .brew-card {
  pointer-events: none;
}
.brew-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 12px;
  cursor: pointer;
}
.brew-card.is-locked {
  opacity: 0.72;
}
.brew-card.is-selected {
  border-color: rgba(110, 231, 183, 0.42);
  background: rgba(110, 231, 183, 0.08);
}
.brew-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.brew-card-head .inv-item {
  position: relative;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
}
.brew-card-titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.brew-card-name {
  font-weight: 700;
  color: var(--text);
}
.brew-card-meta {
  font-size: 12px;
  color: var(--text-dim);
}
.brew-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.brew-card-costs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.brew-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px 2px 2px;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.22);
}
.brew-chip .inv-item {
  position: relative;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  inset: auto;
}
.brew-chip-count {
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.brew-chip.is-short .brew-chip-count {
  color: #f87171;
}
.brew-gold-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 8px 3px 6px;
  border: 1px solid rgba(251, 191, 36, 0.38);
  border-radius: 999px;
  background: rgba(251, 191, 36, 0.14);
  color: var(--gold-soft);
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.brew-gold-chip .dialogue-chip-glyph {
  color: var(--gold);
}
.brew-gold-chip .dialogue-chip-glyph svg {
  width: 14px;
  height: 14px;
}
.brew-gold-chip.is-short {
  opacity: 0.72;
}
.brew-card-action {
  display: flex;
  justify-content: flex-end;
  flex: 0 0 auto;
}
#brew-balance {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  margin: 0;
  color: var(--gold);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
#brew-balance .dialogue-chip-glyph {
  color: var(--gold);
}
#brew-balance .dialogue-chip-glyph svg {
  width: 16px;
  height: 16px;
}
