/* ============================================
   VETUU — UI Styles
   HUD, action bar, frames, panels, overlays
   ============================================ */

/* ============================================
   GUI LAYER
   Single wrapper for all UI - enables clean toggle
   and establishes stacking context for all GUI elements
   ============================================ */
#gui-layer {
  position: fixed;
  inset: 0;
  z-index: 100; /* Above game world, establishes stacking context */
  pointer-events: none; /* Allow click-through - children re-enable */
  /* GPU layer for smooth opacity transition */
  transform: translate3d(0, 0, 0);
  transition: opacity var(--fade-snappy) ease-out;
}

/* 
   POINTER-EVENTS: Direct children of #gui-layer manage their own.
   
   Click-through containers (children opt-in):
   - #left-panel-column: none (map.css) → children: auto
   - #right-panel-column: none (map.css) → children: auto
   - #bottom-ui: none → complex hierarchy
   - #resize-overlay: none (only visible during resize)
   
   Interactive elements (explicitly set auto):
   - #fps-counter: auto (map.css)
   - #dialogue-panel: auto
   - #settings-menu: auto
   - #settings-shroud: none → .visible: auto
   - #worldmap-overlay: auto (worldmap.css)
   - #toast-debug-panel: auto
   - .safari-modal: auto
   
   Do NOT add a blanket #gui-layer > * rule - it overrides individual rules.
*/

/* GUI hidden state (Cmd/Ctrl + \) */
#gui-layer.hidden {
  opacity: 0;
  pointer-events: none !important;
}

#gui-layer.hidden > * {
  pointer-events: none !important;
}

/* ============================================
   GUI TOOLTIP
   Unified tooltip style for all GUI elements
   Usage: Add .gui-tooltip class, position with CSS,
   toggle visibility on parent :hover
   ============================================ */
.gui-tooltip {
  position: absolute;
  background: var(--bg-panel);
  padding: var(--gui-padding-sm) var(--gui-padding);
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--text-primary);
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade-snappy) ease, visibility var(--fade-snappy) ease;
  pointer-events: none;
  z-index: 100;
}

/* Common tooltip positions */
.gui-tooltip.above {
  bottom: calc(100% + var(--gui-padding-sm));
  left: 50%;
  transform: translate3d(-50%, 0, 0);
}

.gui-tooltip.below {
  top: calc(100% + var(--gui-padding-sm));
  left: 50%;
  transform: translate3d(-50%, 0, 0);
}

.gui-tooltip.left {
  right: calc(100% + var(--gui-padding-sm));
  top: 50%;
  transform: translate3d(0, -50%, 0);
}

.gui-tooltip.right {
  left: calc(100% + var(--gui-padding-sm));
  top: 50%;
  transform: translate3d(0, -50%, 0);
}

/* ============================================
   GUI PANEL - UNIFIED DRAGGABLE PANEL SYSTEM
   All draggable panels use .gui-panel class
   ============================================ */

/* Base behavior for all GUI panels (drag/resize/dock) */
.gui-panel {
  position: relative; /* Docked panels stay in flow */
  /* GPU layer via 3D transform context */
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
}

/* Visual styles for column panels (not frame wrappers) */
.gui-panel:not(.frame-wrapper) {
  background: var(--bg-panel-alpha);
  font-family: var(--font-display);
  min-width: 240px;
}

.gui-panel.hidden {
  display: none;
}

/* Undocked (floating) state */
.gui-panel.undocked {
  position: fixed;
  z-index: 30;
  pointer-events: auto;
}

.gui-panel.undocked:not(.frame-wrapper) {
  box-shadow: var(--shadow-md);
}

/* Actively dragging */
.gui-panel.dragging {
  cursor: grabbing;
  z-index: 40;
}

.gui-panel.dragging:not(.frame-wrapper) {
  box-shadow: var(--shadow-xl);
}

/* Resizing state */
.gui-panel.resizing {
  cursor: se-resize;
}

/* Near dock zone indicator */
.gui-panel.near-dock .redock-indicator {
  opacity: 1;
}

/* Panel header (drag handle) */
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--gui-padding);
  background: var(--alpha-white-03);
  border-bottom: 1px solid var(--frame-border);
  cursor: grab;
  user-select: none;
}

.panel-header:active {
  cursor: grabbing;
}

.panel-footer {
  padding: var(--gui-padding);
  background: var(--alpha-white-03);
  border-top: 1px solid var(--frame-border);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: center;
}

.panel-title {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.panel-controls {
  display: flex;
  gap: 0.25rem;
}

.panel-btn {
  width: 20px;
  height: 20px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  font-size: var(--font-size-md);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--fade-snappy) ease, background-color var(--fade-snappy) ease;
}

.gui-panel.undocked .panel-btn {
  opacity: 0.6;
}

.panel-btn:hover {
  opacity: 1;
  background: var(--alpha-white-10);
}

/* Resize handles - corners */
.resize-handle-se,
.resize-handle-sw,
.resize-handle-ne,
.resize-handle-nw {
  position: absolute;
  width: 14px;
  height: 14px;
  opacity: 0;
  transition: opacity var(--fade-snappy) ease;
  z-index: 10;
}

.resize-handle-se::after,
.resize-handle-sw::after,
.resize-handle-ne::after,
.resize-handle-nw::after {
  content: '';
  position: absolute;
  width: 6px;
  height: 6px;
  opacity: 0.5;
}

/* Corner positions and cursors */
.resize-handle-se {
  bottom: 2px;
  right: 2px;
  cursor: se-resize;
}
.resize-handle-se::after {
  bottom: 0;
  right: 0;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
}

.resize-handle-sw {
  bottom: 2px;
  left: 2px;
  cursor: sw-resize;
}
.resize-handle-sw::after {
  bottom: 0;
  left: 0;
  border-left: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
}

.resize-handle-ne {
  top: 2px;
  right: 2px;
  cursor: ne-resize;
}
.resize-handle-ne::after {
  top: 0;
  right: 0;
  border-right: 2px solid var(--text-muted);
  border-top: 2px solid var(--text-muted);
}

.resize-handle-nw {
  top: 2px;
  left: 2px;
  cursor: nw-resize;
}
.resize-handle-nw::after {
  top: 0;
  left: 0;
  border-left: 2px solid var(--text-muted);
  border-top: 2px solid var(--text-muted);
}

/* Resize handles - edge centers */
.resize-handle-n,
.resize-handle-s,
.resize-handle-e,
.resize-handle-w {
  position: absolute;
  opacity: 0;
  transition: opacity var(--fade-snappy) ease;
  z-index: 10;
}

/* Horizontal handles (top/bottom) */
.resize-handle-n,
.resize-handle-s {
  left: 50%;
  transform: translate3d(-50%, 0, 0);
  width: 40px;
  height: 10px;
  cursor: ns-resize;
}

/* Vertical handles (left/right) */
.resize-handle-e,
.resize-handle-w {
  top: 50%;
  transform: translate3d(0, -50%, 0);
  width: 10px;
  height: 40px;
  cursor: ew-resize;
}

/* Edge handle visual indicator (bar) */
.resize-handle-n::after,
.resize-handle-s::after,
.resize-handle-e::after,
.resize-handle-w::after {
  content: '';
  position: absolute;
  background: var(--text-muted);
  opacity: 0.5;
}

/* Horizontal bar for top/bottom */
.resize-handle-n::after,
.resize-handle-s::after {
  left: 50%;
  transform: translate3d(-50%, 0, 0);
  width: 24px;
  height: 2px;
}

/* Vertical bar for left/right */
.resize-handle-e::after,
.resize-handle-w::after {
  top: 50%;
  transform: translate3d(0, -50%, 0);
  width: 2px;
  height: 24px;
}

/* Edge handle positions */
.resize-handle-n {
  top: 0;
}
.resize-handle-n::after {
  top: 2px;
}

.resize-handle-s {
  bottom: 0;
}
.resize-handle-s::after {
  bottom: 2px;
}

.resize-handle-e {
  right: 0;
}
.resize-handle-e::after {
  right: 2px;
}

.resize-handle-w {
  left: 0;
}
.resize-handle-w::after {
  left: 2px;
}

/* Show resize handles on hover or while actively dragging */
.gui-panel:hover .resize-handle-se,
.gui-panel:hover .resize-handle-sw,
.gui-panel:hover .resize-handle-ne,
.gui-panel:hover .resize-handle-nw,
.gui-panel:hover .resize-handle-n,
.gui-panel:hover .resize-handle-s,
.gui-panel:hover .resize-handle-e,
.gui-panel:hover .resize-handle-w,
.gui-panel.dragging .resize-handle-se,
.gui-panel.dragging .resize-handle-sw,
.gui-panel.dragging .resize-handle-ne,
.gui-panel.dragging .resize-handle-nw,
.gui-panel.dragging .resize-handle-n,
.gui-panel.dragging .resize-handle-s,
.gui-panel.dragging .resize-handle-e,
.gui-panel.dragging .resize-handle-w {
  opacity: 1;
}

/* Redock indicator */
.redock-indicator {
  position: absolute;
  inset: -2px;
  border: 2px dashed var(--accent);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--fade-snappy) ease;
  display: flex;
  align-items: center;
  justify-content: center;
  background: oklch(0.58 0.075 205 / 0.1);
}

.redock-indicator span {
  background: var(--bg-panel);
  padding: 0.25rem 0.5rem;
  font-size: var(--font-size-xs);
  color: var(--accent);
}

/* ============================================
   CHARACTER SHEET
   ============================================ */
#character-sheet {
  position: relative;
  min-width: 240px;
  background: var(--bg-panel-alpha);
  font-family: var(--font-display);
}

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

/* When undocked, use fixed positioning */
#character-sheet.undocked {
  position: fixed;
}

/* Old header styles removed - now uses panel-header from ui-panel */

.sheet-close:hover {
  color: var(--text-primary);
}

#sheet-stats {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  padding: calc(var(--gui-padding) * 2) var(--gui-padding);
}

#sheet-level {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  padding: calc(var(--gui-padding) * 2) var(--gui-padding);
  border-top: 1px solid var(--alpha-white-05);
}

.stat {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  font-size: var(--font-size-sm);
}

.stat-label {
  width: 3rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  font-size: var(--font-size-xs);
  letter-spacing: 0.05em;
}

.stat-bar {
  flex: 1;
  height: 8px;
  background: var(--hp-bg);
  overflow: hidden;
}

.stat-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--player-hp-color);
  /* GPU-accelerated: scale3d instead of width */
  transform: scale3d(calc(var(--pct, 100) / 100), 1, 1);
  transform-origin: left center;
  transition: transform 0.2s ease;
}

/* Player stamina bar (renamed from sense) */
.stamina-bar { background: var(--player-stamina-bg); }
.stamina-bar .stat-fill { background: var(--player-stamina-color); }

/* Legacy alias for sense bar */
.sense-bar { background: var(--player-stamina-bg); }
.sense-bar .stat-fill { background: var(--player-stamina-color); }

.stat-value {
  width: 4rem;
  text-align: right;
  font-family: var(--font-numbers);
  font-size: var(--font-size-sm);
  color: var(--text-muted);
}

.stat-row {
  display: flex;
  gap: 0.75rem;
  padding-top: var(--gui-padding);
}

.stat-mini {
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
}

.stat-mini strong {
  color: var(--text-primary);
}

#level-badge {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

#level-badge strong {
  color: var(--color-rarity-legendary);
}

.xp-bar {
  flex: 1;
  height: 6px;
  background: var(--alpha-white-10);
  overflow: hidden;
}

.xp-bar .stat-fill {
  background: var(--color-rarity-legendary);
}

/* ============================================
   QUEST TRACKER
   ============================================ */
#quest-tracker {
  position: relative; /* Stay in flex flow when docked */
  background: var(--bg-panel-alpha);
  min-width: 240px;
  max-width: 400px;
  /* GPU layer for smooth drag/resize */
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  font-family: var(--font-display);
}

/* When undocked (dragged), take out of flex flow */
#quest-tracker.undocked {
  position: fixed;
}

#quest-list {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap);
  max-height: 200px;
  overflow-y: auto;
  padding: var(--gui-padding);
}

.quest-item {
  padding: var(--gui-padding) 0;
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.quest-item.active {
  color: var(--warning);
}

.quest-item .quest-name {
  display: block;
  font-weight: 600;
  margin-bottom: 0.15rem;
}

.quest-item .quest-objective {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  padding-left: 0.5rem;
}

.quest-item .quest-objective::before { content: '◦ '; }
.quest-item .quest-objective.complete::before {
  content: '✓ ';
  color: var(--success);
}

/* ============================================
   COMBAT LOG
   ============================================ */
#combat-log-container {
  position: relative;
  min-width: 240px;
  background: var(--bg-panel-alpha);
}

#combat-log-container.hidden {
  display: none;
}

/* When undocked, use fixed positioning */
#combat-log-container.undocked {
  position: fixed;
}

#combat-log {
  padding: var(--gui-padding);
  max-height: 150px;
  overflow-y: auto;
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.combat-log-line {
  padding: var(--gui-padding) 0;
  border-bottom: 1px solid var(--alpha-white-03);
}

.combat-log-line:last-child {
  border-bottom: none;
}

/* ============================================
   BOTTOM UI
   Main container for portraits and abilities rows
   
   POINTER-EVENTS HIERARCHY:
   - #bottom-ui: none (click-through container)
     - #interact-prompt: none (visual only)
     - #toast-container: none (visual only)
     - .bottom-dock-row: none (click-through)
       - .portrait-dock-zone: none (click-through)
         - .frame-wrapper: none (click-through)
           - .unit-frame: auto (interactive)
           - .frame-status-container: none
             - .effect-box: auto (hoverable)
             - .ability-box.on-cooldown: auto (hoverable)
       - #action-block: auto (interactive)
   ============================================ */
#bottom-ui {
  position: fixed;
  bottom: var(--gui-margin);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-margin);
  z-index: 10;
  pointer-events: none;
}

/* Bottom dock rows - interactive areas */
.bottom-dock-row {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: var(--gui-margin);
  pointer-events: none; /* Container click-through, children opt-in */
}

/* Portrait Row - fixed left and right dock zones */
#portrait-row {
  display: flex;
  justify-content: space-between;
  width: 100%;
  max-width: 600px;
  z-index: 2; /* Above abilities row */
  pointer-events: none; /* Don't block world clicks - children re-enable */
}

/* Fixed dock zones - maintain position even when empty */
.portrait-dock-zone {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: var(--gui-margin);
  min-width: 240px;
  pointer-events: none; /* Don't block clicks when empty - children re-enable */
}

#portrait-dock-left {
  align-items: flex-start;
}

#portrait-dock-right {
  align-items: flex-end;
}

/* Abilities Row - centered */
#abilities-row {
  justify-content: center;
  /* Width determined by content */
  width: fit-content;
  z-index: 1; /* Below portrait row */
  /* Maintain dock zone even when action-block is undocked */
  min-height: 40px;
}

/* ============================================
   ACTION BLOCK
   Draggable action bar container
   ============================================ */
#action-block {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--gui-margin-sm);
  /* GPU layer */
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  cursor: grab;
  pointer-events: auto; /* Interactive UI element */
}

#action-block:active {
  cursor: grabbing;
}

/* Only the action slot buttons should be clickable, not draggable */
#action-block .action-slot {
  cursor: pointer;
}

/* Undocked state */
#action-block.undocked {
  position: fixed;
  z-index: 30;
}

#action-block.dragging {
  cursor: grabbing;
  z-index: 40;
  box-shadow: var(--shadow-xl);
}

#action-block.near-dock .redock-indicator {
  opacity: 1;
}

/* ============================================
   UNIT FRAMES (Player & Target)
   Inside portrait row when docked
   ============================================ */
.unit-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-panel-alpha);
  min-width: 240px;
  /* GPU layer */
  backface-visibility: hidden;
  transform: translate3d(0, 0, 0);
  z-index: 10;
  cursor: grab;
  pointer-events: auto; /* Re-enable clicks (parent dock zone has none) */
}

.unit-frame:active {
  cursor: grabbing;
}

/* Unit frame content row (portrait + info) */
.unit-frame-content {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  padding: var(--gui-padding);
}

/* Resize handles inherit from .gui-panel resize handles */
.unit-frame .resize-handle-se,
.unit-frame .resize-handle-sw,
.unit-frame .resize-handle-ne,
.unit-frame .resize-handle-nw,
.unit-frame .resize-handle-n,
.unit-frame .resize-handle-s,
.unit-frame .resize-handle-e,
.unit-frame .resize-handle-w {
  position: absolute;
  z-index: 10;
  opacity: 0;
}

/* Show resize handles on hover (unit-frame only) or while actively dragging */
.unit-frame:hover .resize-handle-se,
.unit-frame:hover .resize-handle-sw,
.unit-frame:hover .resize-handle-ne,
.unit-frame:hover .resize-handle-nw,
.unit-frame:hover .resize-handle-n,
.unit-frame:hover .resize-handle-s,
.unit-frame:hover .resize-handle-e,
.unit-frame:hover .resize-handle-w,
.frame-wrapper.dragging .unit-frame .resize-handle-se,
.frame-wrapper.dragging .unit-frame .resize-handle-sw,
.frame-wrapper.dragging .unit-frame .resize-handle-ne,
.frame-wrapper.dragging .unit-frame .resize-handle-nw,
.frame-wrapper.dragging .unit-frame .resize-handle-n,
.frame-wrapper.dragging .unit-frame .resize-handle-s,
.frame-wrapper.dragging .unit-frame .resize-handle-e,
.frame-wrapper.dragging .unit-frame .resize-handle-w {
  opacity: 1;
}

/* Dock button for unit frames */
.unit-frame .dock-btn {
  position: absolute;
  top: var(--gui-padding-sm);
  right: var(--gui-padding-sm);
  opacity: 0;
  z-index: 10;
}

/* Show dock button when undocked (but not actively dragging) */
.frame-wrapper.undocked:not(.dragging) .unit-frame .dock-btn {
  opacity: 0.6;
}

.unit-frame .dock-btn:hover {
  opacity: 1;
}

.unit-frame.resizing {
  cursor: nwse-resize;
}

/* Frame wrapper undocked states (position/z-index handled by .gui-panel) */
.frame-wrapper.undocked .unit-frame {
  box-shadow: var(--shadow-md);
}

.frame-wrapper.dragging .unit-frame {
  box-shadow: var(--shadow-xl);
}

/* Legacy: unit-frame without wrapper (backwards compatibility) */
.unit-frame.undocked {
  position: fixed;
  z-index: 30;
  pointer-events: auto;
  box-shadow: var(--shadow-md);
}

.unit-frame.dragging {
  cursor: grabbing;
  z-index: 40;
  box-shadow: var(--shadow-xl);
}

.unit-frame.near-dock .redock-indicator {
  opacity: 1;
}

/* When docked to left/right columns, adjust styling */
.frame-wrapper.column-docked {
  width: 100%;
}

.frame-wrapper.column-docked .unit-frame {
  min-width: unset;
}

#player-frame {
  /* In portrait row: sits on left */
}

#target-frame {
  /* In portrait row: mirrored layout (details left, icon right) to face inward */
}

#target-frame.hidden {
  display: none;
}

/* Portrait wrapper - contains frame-portrait */
.portrait-wrapper {
  width: var(--size-portrait-md);
  height: var(--size-portrait-md);
}

.frame-portrait {
  position: relative;
  width: 100%;
  height: 100%;
  background: var(--frame-inner);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--portrait-icon-size);
  box-sizing: border-box;
}

/* Portrait level badge - small square showing level number */
.portrait-level {
  position: absolute;
  bottom: var(--gui-padding-sm);
  font-family: var(--font-numbers);
  font-size: var(--font-size-sm);
  color: var(--text-primary);
  background: var(--alpha-black-50);
  padding: var(--gui-padding-sm);
  line-height: 1;
  z-index: 5;
}

/* Player portrait: level hidden (shown in XP bar level boxes instead) */
.player-portrait .portrait-level {
  display: none;
}

/* Enemy/target portrait: level at bottom-right */
.enemy-portrait .portrait-level {
  right: var(--gui-padding-sm);
}

/* Swing timer SVG - inside frame-portrait, stretches to fill */
.frame-portrait .swing-timer-border {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  transition: opacity var(--fade-standard) ease;
  transform: translate3d(0, 0, 0);
}

/* Show when autoattacking - class added by JS to player-frame */
#player-frame.autoattacking .swing-timer-border {
  opacity: 1;
}

/* Portrait swing timer stroke styles */
.swing-timer-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
}

.swing-timer-fill {
  fill: none;
  stroke: var(--swing-color, var(--accent));
  stroke-width: 2;
  transform: translate3d(0, 0, 0);
}

/* Cooldown state: accent color */
#player-frame.swing-cooldown .swing-timer-fill {
  --swing-color: var(--accent);
}

/* Ready state: green */
#player-frame.swing-ready .swing-timer-fill {
  --swing-color: var(--success);
}

/* Target frame swing timer - uses danger color for enemy attacks */
#target-frame.autoattacking .swing-timer-border {
  opacity: 1;
}

#target-frame.swing-cooldown .swing-timer-fill {
  --swing-color: var(--danger);
}

#target-frame.swing-ready .swing-timer-fill {
  --swing-color: var(--danger-dark);
}


.frame-info {
  display: flex;
  flex-direction: column;
  gap: var(--gui-padding);
  flex: 1;
  min-width: 0; /* Allow scaling with container */
  width: 100%;
}

.frame-name-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.frame-name {
  font-family: var(--font-display);
  font-size: var(--frame-name-size);
  font-weight: 600;
  color: var(--text-primary);
}

.frame-level {
  font-family: var(--font-numbers);
  font-size: var(--frame-level-size);
  color: var(--color-rarity-legendary);
}

/* Container for HP/sense/stamina bars */
.frame-bars {
  display: flex;
  flex-direction: column;
  gap: var(--gui-padding-sm);
  width: 100%;
}

.frame-bar {
  position: relative;
  width: 100%;
  height: var(--size-bar-lg);
  background: var(--player-hp-bg);
  overflow: hidden;
}

/* Hide text in portrait bars - visual only */
.frame-bar-text {
  display: none;
}

/* Player stamina bar (renamed from sense) - scoped to player-frame */
#player-frame .frame-bar.stamina-bar {
  height: var(--size-bar-md);
  background: var(--player-stamina-bg);
}

/* Legacy alias for sense bar */
#player-frame .frame-bar.sense-bar {
  height: var(--size-bar-md);
  background: var(--player-stamina-bg);
}

.frame-hp-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: var(--player-hp-color);
  /* GPU-accelerated: scale3d instead of width */
  transform: scale3d(calc(var(--hp-pct, 100) / 100), 1, 1);
  transform-origin: left center;
  transition: transform 0.2s ease;
}

/* Stamina fill - base styles (mirrors .frame-hp-fill pattern) */
.frame-stamina-fill {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: var(--player-stamina-color);
  /* Use scaleX with width:100% instead of scale3d with calc - more reliable */
  transform: scaleX(var(--stamina-pct, 1));
  transform-origin: left center;
  transition: transform 0.2s ease;
}

/* Legacy alias for sense fill */
.frame-sense-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: var(--player-stamina-color);
  /* GPU-accelerated: scale3d instead of width */
  transform: scale3d(calc(var(--sense-pct, 100) / 100), 1, 1);
  transform-origin: left center;
  transition: transform 0.2s ease;
}

/* Target frame (enemies) - uses enemy colors */
#target-frame .frame-hp-fill {
  background: var(--enemy-hp-color);
}

/* Friendly NPC target - uses NPC colors */
#target-frame.friendly .frame-hp-fill {
  background: var(--npc-hp-color);
}


#target-frame.friendly .frame-level {
  color: var(--success);
}

/* Vehicle target (yellow/orange) */
#target-frame.vehicle .frame-hp-fill {
  background: var(--warning);
}


#target-frame.vehicle .frame-level {
  color: var(--warning);
}

/* Override traffic.css .vehicle position:absolute which breaks layout */
#target-frame.vehicle,
#target-frame.object {
  position: relative;
}


/* ============================================
   STAMINA BAR (for actors)
   ============================================ */
.frame-bar.stamina-bar {
  height: var(--size-bar-md);
  background: var(--stamina-bg);
}

/* Hide stamina bar for objects and vehicles (non-actors) */
#target-frame.object .frame-bar.stamina-bar,
#target-frame.vehicle .frame-bar.stamina-bar {
  display: none;
}

/* ============================================
   FUEL BAR (for vehicles)
   ============================================ */
.frame-bar.fuel-bar {
  height: var(--size-bar-md);
  background: var(--stamina-bg); /* Same base as stamina */
  display: none; /* Hidden by default */
}

/* Show fuel bar only for vehicles */
#target-frame.vehicle .frame-bar.fuel-bar {
  display: block;
}

.frame-fuel-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  /* Cyan/teal for battery charge - electric feel */
  background: linear-gradient(90deg, 
    oklch(0.70 0.140 195) 0%,
    oklch(0.65 0.160 185) 100%
  );
  transform: scale3d(calc(var(--fuel-pct, 100) / 100), 1, 1);
  transform-origin: left center;
  transition: transform 0.2s ease;
}

/* Low fuel warning state - shifts to red/orange */
.frame-fuel-fill.low-fuel {
  background: linear-gradient(90deg, 
    oklch(0.62 0.180 35) 0%,
    oklch(0.55 0.200 25) 100%
  );
  animation: fuel-pulse 1s ease-in-out infinite;
}

@keyframes fuel-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

/* Target frame stamina fill (enemies by default) */
#target-frame .frame-stamina-fill {
  background: var(--enemy-stamina-color);
}

/* Friendly NPC target uses NPC stamina color */
#target-frame.friendly .frame-stamina-fill {
  background: var(--npc-stamina-color);
}

/* ============================================
   FRAME WRAPPER (contains effects/abilities + unit-frame)
   Container is click-through, only unit-frame is interactive
   ============================================ */
.frame-wrapper {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--gui-margin-sm);
  width: 100%;
  min-width: 240px;
  pointer-events: none; /* Click-through - unit-frame opts in */
}

.frame-wrapper .unit-frame {
  cursor: grab;
}

.frame-wrapper .unit-frame:active {
  cursor: grabbing;
}

/* ============================================
   FRAME EFFECTS (Buffs/Debuffs Row)
   ============================================ */
/* Container for effects + abilities rows */
.frame-status-container {
  display: flex;
  flex-direction: column-reverse;
  gap: var(--gui-margin-sm);
  min-width: 240px;
  pointer-events: none; /* Click-through - children opt-in */
}

.frame-effects {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--gui-gap-sm);
  min-height: 24px; /* Reserve space even when empty */
}

.frame-buffs,
.frame-debuffs {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
  flex: 1; /* Each takes half the space */
}

.frame-buffs {
  justify-content: flex-start;
}

.frame-debuffs {
  justify-content: flex-end;
}

/* Individual buff/debuff box */
.effect-box {
  position: relative;
  width: var(--size-icon-md);
  height: var(--size-icon-md);
  background: var(--alpha-black-60);
  border: var(--frame-border-width) solid var(--alpha-white-20);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--effect-icon-size);
  cursor: help;
  pointer-events: auto; /* Hoverable for tooltip */
}

.effect-box:hover .gui-tooltip {
  opacity: 1;
  visibility: visible;
}

.effect-box.buff {
  border-color: var(--success);
}

.effect-box.debuff {
  border-color: var(--danger);
}

/* Duration timer text overlay */
.effect-box .effect-timer {
  position: absolute;
  bottom: calc(-1 * var(--gui-padding-sm));
  right: calc(-1 * var(--gui-padding-sm));
  font-size: var(--effect-timer-size);
  font-family: var(--font-numbers);
  color: var(--text-primary);
  background: var(--alpha-black-70);
  padding: var(--gui-padding-sm);
  line-height: 1;
  z-index: 3;
}

/* SVG stroke cooldown indicator for timed effects */
.effect-box .effect-cd-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
}

.effect-cd-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
}

.effect-cd-fill {
  fill: none;
  stroke-width: 2;
  stroke-linecap: square;
}

/* Dim icon when effect has duration (timed) */
.effect-box:not(.permanent) .effect-icon {
  opacity: 0.5;
}

/* Permanent effects - full brightness, no timer/stroke */
.effect-box.permanent .effect-timer,
.effect-box.permanent .effect-cd-svg {
  display: none;
}

/* ============================================
   FRAME ABILITIES (Cooldown Row)
   ============================================ */
.frame-abilities {
  display: flex;
  justify-content: flex-start;
  gap: var(--gui-gap-sm);
  min-height: 24px; /* Match effect row height */
  pointer-events: none; /* Click-through - children opt-in */
}

/* Mirror alignment for right dock (target frame) */
/* Right-side frames: mirrored layout (persists when undocked) */
.frame-wrapper:has([data-dock-side="right"]) .frame-effects {
  flex-direction: row-reverse;
}

.frame-wrapper:has([data-dock-side="right"]) .frame-buffs {
  justify-content: flex-end;
}

.frame-wrapper:has([data-dock-side="right"]) .frame-debuffs {
  justify-content: flex-start;
}

.frame-wrapper:has([data-dock-side="right"]) .frame-abilities {
  justify-content: flex-end;
}

/* Hide abilities row for non-hostile targets */
.frame-wrapper:has(#target-frame:not(.hostile)) .frame-abilities,
.frame-wrapper:has(#target-frame.hidden) .frame-abilities {
  display: none;
}


/* Individual ability cooldown box */
.ability-box {
  position: relative;
  width: var(--size-icon-md);
  height: var(--size-icon-md);
  background: var(--alpha-black-60);
  border: var(--frame-border-width) solid var(--alpha-white-20);
  display: none; /* Hidden by default - only show when on cooldown */
  align-items: center;
  justify-content: center;
  font-size: var(--ability-icon-size);
  cursor: help;
}

/* Only show ability icons when on cooldown (active) */
.ability-box.on-cooldown {
  display: flex;
  pointer-events: auto; /* Hoverable for tooltip when visible */
}

.ability-box:hover .gui-tooltip {
  opacity: 1;
  visibility: visible;
}

/* Cooldown overlay (fills from bottom) */
.ability-box .ability-cd-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  background: var(--alpha-black-70);
  transform: scale3d(1, calc(var(--cd-pct, 0) / 100), 1);
  transform-origin: bottom center;
  pointer-events: none;
  z-index: 1;
}

/* SVG stroke cooldown indicator (like Sprint) */
.ability-box .ability-cd-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
  opacity: 0;
  transition: opacity var(--fade-snappy) ease;
}

.ability-box.on-cooldown .ability-cd-svg {
  opacity: 1;
}

.ability-cd-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
}

.ability-cd-fill {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: square;
}

/* Cooldown timer text */
.ability-box .ability-cd-timer {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--ability-timer-size);
  font-family: var(--font-numbers);
  color: var(--text-primary);
  z-index: 3;
  opacity: 0;
}

.ability-box.on-cooldown .ability-cd-timer {
  opacity: 1;
}

/* Icon dimmed when on cooldown */
.ability-box.on-cooldown .ability-icon {
  opacity: 0.4;
}

.ability-icon {
  position: relative;
  z-index: 0;
  transition: opacity var(--fade-snappy) ease;
}

/* ============================================
   RESPONSIVE: Side column docking
   ============================================ */
/* When frame is docked to side columns, stack vertically */
.left-column .unit-frame,
.right-column .unit-frame {
  flex-direction: column;
}

/* Side column adjustments - keep left/right alignment */
.left-column .frame-effects,
.right-column .frame-effects {
  flex-wrap: wrap;
}

.left-column .frame-abilities,
.right-column .frame-abilities {
  flex-wrap: wrap;
}

/* Weakness display removed - combat simplification */

/* ============================================
   ACTION BAR
   ============================================ */
#action-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--gui-padding);
  background: var(--bg-panel-alpha);
  padding: var(--gui-padding);
  z-index: 20;
}

/* Old weapon section styles removed - replaced with weapon toggle slot */

#action-slots {
  display: flex;
  gap: 0.25rem;
  align-items: center;
}

.action-slot {
  position: relative;
  width: var(--size-slot);
  height: var(--size-slot);
  background: var(--frame-inner);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* GPU-friendly transitions */
  transition: opacity var(--fade-snappy) ease, background-color var(--fade-snappy) ease;
  /* Remove all focus outlines */
  outline: none;
  -webkit-tap-highlight-color: transparent;
}

/* Remove focus ring for mouse users */
.action-slot:focus:not(:focus-visible),
.action-slot:active {
  outline: none;
  box-shadow: none;
}

/* Subtle focus ring for keyboard users (Tab navigation) */
.action-slot:focus-visible {
  outline: 1px solid var(--alpha-white-40);
  outline-offset: 1px;
}

.action-slot:hover:not(.on-cooldown):not(.locked-slot) {
  background: var(--alpha-white-05);
}

.action-slot:hover .gui-tooltip {
  opacity: 1;
  visibility: visible;
}

.action-slot.active {
  /* No special styling - swing timer SVG handles visual feedback */
}

/* Disabled state - when targeting friendly NPC */
.action-slot.disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.action-slot.disabled::after {
  content: '';
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 3px,
    var(--alpha-black-30) 3px,
    var(--alpha-black-30) 6px
  );
}

.action-slot.on-cooldown {
  cursor: not-allowed;
}

/* GCD (Global Cooldown) active state - just dim, no border change */
.action-slot.gcd-active:not(.on-cooldown) {
  opacity: 0.7;
}

/* Cooldown overlay that fills from bottom to top */
.cooldown-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  background: var(--alpha-black-70);
  pointer-events: none;
  z-index: 5;
  /* GPU-accelerated: scale3d from bottom instead of height */
  transform: scale3d(1, calc(var(--cooldown-pct, 0) / 100), 1);
  transform-origin: bottom center;
  transition: transform 0.1s linear;
}

/* Cooldown timer text */
.cooldown-timer {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-numbers);
  font-size: var(--font-size-md);
  font-weight: bold;
  color: var(--text-primary);
  pointer-events: none;
  z-index: 6;
}

.slot-icon {
  font-size: var(--action-icon-size);
}

/* Labels hidden - icons only */
.slot-label {
  display: none;
  font-size: var(--action-label-size);
}

.slot-key {
  position: absolute;
  bottom: var(--gui-padding-sm);
  right: var(--gui-padding-sm);
  font-family: var(--font-numbers);
  font-size: var(--action-key-size);
  color: var(--text-muted);
  background: var(--alpha-black-50);
  padding: var(--gui-padding-sm);
}

/* Special slot - no unique border styling */
.special-slot {
  /* Uses default frame-border */
}

/* Action groups */
.action-group {
  display: flex;
  gap: 0.25rem;
  align-items: center;
}

/* Melee and ranged slots - no special styling, use default frame-border */
.melee-slot,
.ranged-slot {
  /* Uses default frame-border */
}

/* Swing timer styles moved to player portrait section above */

/* ============================================
   CAST/CHANNEL TIMER (SVG stroke - GPU accelerated)
   ============================================ */
.cast-slot-wrapper {
  position: relative;
  display: inline-flex;
}

.cast-timer-border {
  position: absolute;
  inset: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  transition: opacity var(--fade-standard) ease;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
}

/* Show when casting/channeling */
.cast-slot-wrapper.casting .cast-timer-border,
.cast-slot-wrapper.channeling .cast-timer-border {
  opacity: 1;
}

.cast-timer-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

.cast-timer-fill {
  fill: none;
  stroke: var(--cast-color, var(--accent));
  stroke-width: 2.5;
  stroke-linecap: square;
  stroke-linejoin: miter;
  transform: translate3d(0, 0, 0);
  /* PERF: Removed drop-shadow filter and will-change */
}

/* Channel state: melee color (blade flurry) */
.cast-slot-wrapper.channeling .cast-timer-fill {
  --cast-color: var(--melee-color, oklch(0.62 0.200 25));
}

/* Cast state: ranged color (charged shot) */
.cast-slot-wrapper.casting .cast-timer-fill {
  --cast-color: var(--ranged-color, oklch(0.72 0.140 220));
}

/* Sense ability slots - same style as weapon abilities */

/* Locked slot (level requirement not met) - appears blank */
.locked-slot {
  cursor: not-allowed;
  border-style: dashed;
  border-color: var(--alpha-white-10);
  background: var(--alpha-black-20);
}

/* Hide all content in locked slots to make them appear blank */
.locked-slot .slot-icon,
.locked-slot .slot-label,
.locked-slot .slot-key {
  visibility: hidden;
}

/* Show lock icon placeholder in center */
.locked-slot::before {
  content: '🔒';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%, -50%, 0);
  font-size: var(--font-size-md);
  opacity: 0.3;
}

/* Hidden ability slots (MSQ not yet revealed) */
/* Sense abilities are completely hidden until the MSQ reveals them */
#sense-abilities.hidden-abilities {
  display: none !important;
}

/* Utility slots - same style as weapon abilities */

/* ============================================
   SPRINT TIMER (SVG stroke - GPU accelerated)
   ============================================ */
.sprint-slot-wrapper {
  position: relative;
}

.sprint-timer-border {
  position: absolute;
  inset: -1px;
  width: calc(100% + 2px);
  height: calc(100% + 2px);
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  transition: opacity var(--fade-standard) ease;
  /* GPU layer via 3D transform */
  transform: translate3d(0, 0, 0);
}

/* Show when sprint buff is active */
.sprint-slot-wrapper.sprint-active .sprint-timer-border {
  opacity: 1;
}

/* Background track (subtle) */
.sprint-timer-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

/* Progress fill stroke */
.sprint-timer-fill {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linecap: square;
  stroke-linejoin: miter;
  /* GPU layer for performance */
  transform: translate3d(0, 0, 0);
  /* PERF: Removed drop-shadow filter and will-change */
  /* Transition set dynamically by JS for precise timing */
}

/* Buff active state - uses same style as cooldown */

/* ============================================
   XP ROW (anchored to bottom of screen)
   Level boxes flanking the XP bar with gap
   Width synced to action bar via JS (--xp-row-width)
   ============================================ */
#xp-row {
  display: flex;
  align-items: flex-end; /* Level boxes taller, XP bar aligns to bottom */
  justify-content: center;
  gap: var(--gui-gap); /* Gap between boxes and bar */
  pointer-events: auto;
  /* Reduce gap from abilities row above */
  margin-top: calc(-1.5 * var(--gui-margin));
  /* Extend to bottom edge by compensating for bottom-ui margin */
  margin-bottom: calc(-1 * var(--gui-margin));
}

/* Level boxes (current and next) - outside the bar */
.xp-level-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  min-width: 24px;
  height: 24px;
  background: var(--bg-panel-alpha);
  font-family: var(--font-mono);
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--text-primary);
}

/* ============================================
   XP BAR (inside xp-row)
   Width synced to action bar via JS
   ============================================ */
#xp-bar-container {
  position: relative;
  z-index: 25;
  width: var(--xp-row-width, 300px); /* Synced to action bar width via JS */
  min-width: 100px;
}

#xp-bar-track {
  position: relative;
  height: 8px;
  background: var(--bg-panel-alpha);
  overflow: hidden;
}

/* XP bar tooltip */
#xp-bar-container:hover .gui-tooltip {
  opacity: 1;
  visibility: visible;
}

#xp-bar-level {
  color: var(--color-rarity-legendary);
  font-weight: 600;
}

#xp-bar-progress {
  color: var(--text-secondary);
}

#xp-bar-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  background: var(--xp-color);
  /* GPU-accelerated: scale3d instead of width */
  transform: scale3d(calc(var(--xp-pct, 0) / 100), 1, 1);
  transform-origin: left center;
  transition: transform 0.4s ease-out;
}

#xp-bar-notches {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: space-evenly;
  pointer-events: none;
}

.xp-notch {
  width: 1px;
  height: 100%;
  background: var(--alpha-white-15);
}

/* XP bar text - inside the bar */
/* XP bar text hidden - using compact bar */

/* Rested XP bonus indicator (optional enhancement) */
#xp-bar-fill.rested::after {
  content: '';
  position: absolute;
  top: 0;
  left: 100%;
  height: 100%;
  width: 20%;
  background: linear-gradient(180deg, oklch(0.62 0.120 240) 0%, oklch(0.52 0.110 240) 50%, oklch(0.42 0.100 240) 100%);
  opacity: 0.6;
}

/* ============================================
   DIALOGUE PANEL
   Cinematic enter/exit with staggered backdrop
   ============================================ */
#dialogue-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  width: min(90vw, 600px);
  max-height: 80vh;
  overflow-y: auto;
  background: var(--bg-panel-alpha);
  /* Subtle hairline border */
  border: var(--border-hairline);
  font-family: var(--font-display);
  pointer-events: auto; /* Interactive when open */
  z-index: 200;
  /* Layered shadows for realistic depth */
  box-shadow: var(--shadow-lg);
  /* Closed state - above and small (behind) */
  opacity: 0;
  translate: -50% calc(-50% - 40px);
  scale: 0.8;
  /* Exit transition - anticipation easing (inverse of overshoot) */
  transition: 
    opacity 450ms cubic-bezier(0.36, 0, 0.66, -0.56),
    translate 450ms cubic-bezier(0.36, 0, 0.66, -0.56),
    scale 450ms cubic-bezier(0.36, 0, 0.66, -0.56),
    display 450ms allow-discrete,
    overlay 450ms allow-discrete;
}

/* Open state - fully visible and centered */
#dialogue-panel[open] {
  opacity: 1;
  translate: -50% -50%;
  scale: 1;
  /* Enter transition - overshoot easing for the arc */
  transition: 
    opacity 550ms cubic-bezier(0.34, 1.56, 0.64, 1),
    translate 550ms cubic-bezier(0.34, 1.56, 0.64, 1),
    scale 550ms cubic-bezier(0.34, 1.56, 0.64, 1),
    display 550ms allow-discrete,
    overlay 550ms allow-discrete;
  transition-delay: 200ms;
}

/* Entry point - where enter transition starts FROM */
@starting-style {
  #dialogue-panel[open] {
    opacity: 0;
    translate: -50% calc(-50% - 40px);
    scale: 0.8;
  }
}

/* Backdrop - cinematic shroud */
#dialogue-panel::backdrop {
  background: var(--bg-panel-alpha);
  opacity: 0;
  cursor: pointer;
  /* Exit: wait for box to mostly finish (450ms), then fade */
  transition: 
    opacity var(--fade-standard) ease-out,
    overlay var(--fade-standard) ease-out allow-discrete,
    display var(--fade-standard) ease-out allow-discrete;
  transition-delay: 350ms;
}

#dialogue-panel[open]::backdrop {
  opacity: 1;
  /* Enter: backdrop fades in immediately (box follows after) */
  transition-delay: 0ms;
}

@starting-style {
  #dialogue-panel[open]::backdrop {
    opacity: 0;
  }
}

/* Inner wrapper for flex gap (dialog element doesn't support gap) */
#dialogue-inner {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
}

/* Dialogue content wrapper - portrait + text side by side */
#dialogue-content {
  display: flex;
  gap: var(--gui-gap-lg);
}

/* Portrait - 2x the size of target frame portrait */
#dialogue-portrait {
  flex-shrink: 0;
  width: calc(var(--size-portrait-md) * 2);
  height: calc(var(--size-portrait-md) * 2);
  background: var(--frame-inner);
  display: flex;
  align-items: center;
  justify-content: center;
}

#dialogue-portrait .portrait-icon {
  font-size: calc(var(--portrait-icon-size) * 2);
}

/* Body - contains speaker name and text */
#dialogue-body {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
  flex: 1;
  min-width: 0; /* Allow text to wrap */
  padding: var(--gui-padding-sm) 0;
}

#dialogue-speaker {
  padding: 0 var(--gui-padding) 0 0;
  font-size: var(--font-size-md);
  font-weight: 600;
  color: var(--accent);
}

#dialogue-text {
  font-size: var(--font-size-xl);
  line-height: 1.5;
  color: var(--text-primary);
  min-height: calc(3 * 1.5 * var(--font-size-xl)); /* Stabilize height during typewriter */
}

#dialogue-choices {
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-sm);
  padding: 0;
}

.dialogue-choice {
  background: var(--frame-inner);
  border: none;
  padding: var(--gui-padding);
  text-align: left;
  font-family: inherit;
  font-size: var(--font-size-lg);
  color: var(--text-primary);
  cursor: pointer;
  /* Slow trail fade-out on release */
  transition: background-color 0.6s ease-out, color 0.6s ease-out;
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
}

.dialogue-choice:hover:not([disabled]),
.dialogue-choice.selected:not([disabled]) {
  background: var(--accent-hover);
  color: var(--text-primary);
  outline: none;
  /* Instant snap on hover */
  transition: none;
}

.dialogue-choice:hover:not([disabled]) .choice-text,
.dialogue-choice.selected:not([disabled]) .choice-text {
  color: var(--text-primary);
}

.dialogue-choice:focus {
  outline: none;
}

.dialogue-choice[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Previously selected dialogue options */
.dialogue-choice.previously-selected {
  background: var(--alpha-white-01);
}

.dialogue-choice.previously-selected .choice-text {
  color: var(--text-muted);
}

.dialogue-choice.previously-selected:hover:not([disabled]),
.dialogue-choice.previously-selected.selected:not([disabled]) {
  background: var(--alpha-white-05);
}

.dialogue-choice.previously-selected:hover:not([disabled]) .choice-text,
.dialogue-choice.previously-selected.selected:not([disabled]) .choice-text {
  color: var(--text-secondary);
}

.choice-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  background: var(--bg-dark);
  border: none;
  font-size: var(--font-size-sm);
  font-weight: bold;
  color: var(--text-primary);
  flex-shrink: 0;
  order: 1;
}

.choice-text {
  flex: 1;
  /* Slow trail fade-out on release */
  transition: color 0.6s ease-out, background-color 0.6s ease-out;
}

.dialogue-choice:hover .choice-text,
.dialogue-choice.selected .choice-text {
  /* Instant snap on hover */
  transition: none;
}

/* Quest icon for quest-related dialogue options */
.choice-quest-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  background: var(--warning);
  color: var(--bg-dark);
  font-size: var(--font-size-sm);
  font-weight: bold;
  flex-shrink: 0;
  margin-left: auto;
}

.dialogue-choice.previously-selected .choice-quest-icon {
  background: var(--text-muted);
}

/* Back/navigation options in dialogue */
.dialogue-choice.back-option,
.dialogue-choice.goodbye-option {
  margin-top: var(--gui-gap-md);
}

/* Back option - muted yellow on hover */
.dialogue-choice.back-option:hover,
.dialogue-choice.back-option.selected {
  background: var(--warning-subtle);
}

/* Goodbye option - red on hover */
.dialogue-choice.goodbye-option:hover,
.dialogue-choice.goodbye-option.selected {
  background: var(--danger-subtle);
}

/* ============================================
   INVENTORY PANEL
   ============================================ */
#inventory-panel {
  position: relative;
  min-width: 240px;
  background: var(--bg-panel-alpha);
  font-family: var(--font-display);
}

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

/* When undocked, use fixed positioning */
#inventory-panel.undocked {
  position: fixed;
}

#inventory-list {
  max-height: 200px;
  overflow-y: auto;
  padding: var(--gui-padding);
}

.inventory-item {
  display: flex;
  align-items: center;
  gap: var(--gui-gap);
  padding: var(--gui-padding);
  cursor: pointer;
}

.inventory-item:hover {
  background: var(--alpha-white-05);
}

.inventory-item-icon {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--font-size-sm);
  font-weight: bold;
}

.inventory-item-icon.green { background: var(--color-rarity-uncommon); }
.inventory-item-icon.blue { background: var(--color-rarity-rare); }
.inventory-item-icon.gold { background: var(--color-rarity-legendary); }

.inventory-item-info { flex: 1; }
.inventory-item-name { font-size: var(--font-size-md); font-weight: 600; }
.inventory-item-desc { font-size: var(--font-size-xs); color: var(--text-muted); }
.inventory-item-qty { font-size: var(--font-size-sm); color: var(--text-secondary); }

/* ============================================
   NOTIFICATIONS (Toasts & Prompts)
   Unified feedback system with color-coded left bars
   ============================================ */

/* Base notification styles */
.notification {
  background: var(--bg-panel);
  border-left: 3px solid var(--text-muted);
  padding: var(--gui-padding);
  font-family: var(--font-display);
  font-size: var(--font-size-md);
  color: var(--text-primary);
  pointer-events: none; /* Click-through - notifications are visual only */
}

/* Semantic color types */
.notification.info    { border-left-color: var(--info); }
.notification.success { border-left-color: var(--success); }
.notification.warning { border-left-color: var(--warning); }
.notification.error   { border-left-color: var(--danger); }
.notification.accent  { border-left-color: var(--accent); }

/* Game-specific types */
.notification.xp      { border-left-color: var(--xp-color); }
.notification.item    { border-left-color: var(--success); }
.notification.quest   { border-left-color: var(--warning); }

/* --- Interact Prompt --- 
   Quick fade in/out animation. Override global .hidden to allow transition. */
#interact-prompt {
  display: flex !important; /* Override global .hidden display:none */
  align-items: center;
  gap: var(--gui-gap);
  pointer-events: none;
  opacity: 1;
  transition: opacity var(--fade-snappy) ease-out;
}

#interact-prompt.hidden {
  opacity: 0;
}

#interact-prompt:empty { display: none !important; }

#interact-prompt kbd {
  background: var(--frame-inner);
  padding: var(--gui-padding-sm) var(--gui-padding);
  font-family: var(--font-numbers);
  font-size: var(--font-size-sm);
}

/* --- Comms Card (NPC phone calls) --- */
#comms-card {
  display: flex;
  align-items: flex-start;
  gap: var(--gui-gap-lg);
  background: var(--bg-panel-alpha);
  padding: calc(var(--gui-padding) * 2);
  max-width: 360px;
  pointer-events: auto;
  cursor: pointer;
}

#comms-card.hidden {
  display: none;
}

/* Enter animation */
#comms-card.comms-enter {
  animation: comms-in 0.3s ease forwards;
}

/* Exit animation */
#comms-card.comms-exit {
  animation: comms-out 0.3s ease forwards;
}

@keyframes comms-in {
  from {
    opacity: 0;
    transform: translate3d(0, 20px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes comms-out {
  from {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
  to {
    opacity: 0;
    transform: translate3d(0, -10px, 0);
  }
}

/* Portrait */
#comms-portrait {
  position: relative;
  flex-shrink: 0;
  width: var(--size-portrait-md);
  height: var(--size-portrait-md);
  background: var(--frame-inner);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--portrait-icon-size);
}

/* Stroke timer SVG - shows countdown before dismiss */
.comms-timer-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--fade-standard) ease;
}

#comms-card.countdown .comms-timer-svg {
  opacity: 1;
}

.comms-timer-track {
  fill: none;
  stroke: var(--alpha-white-08);
  stroke-width: 2;
}

.comms-timer-fill {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  /* Perimeter of 46x46 rect = 2*(46+46) = 184 */
  stroke-dasharray: 184;
  stroke-dashoffset: 0;
}

/* Content area */
#comms-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--gui-gap-lg);
  padding: var(--gui-padding-sm) 0;
}

/* Speaker row - name + wave animation */
#comms-speaker-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gui-gap);
}

#comms-speaker {
  color: var(--accent);
  font-family: var(--font-display);
  font-size: var(--font-size-md);
  font-weight: 600;
  text-transform: capitalize;
}

/* Sound wave animation */
#comms-wave {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 12px;
  opacity: 0;
  transition: opacity var(--fade-standard) ease-out;
}

#comms-card.typing #comms-wave {
  opacity: 1;
  transition: opacity var(--fade-snappy) ease-in;
}

#comms-wave span {
  display: block;
  width: 2px;
  height: 12px; /* Fixed max height - animation uses scaleY */
  background: var(--warning);
  border-radius: 1px;
  transform-origin: center center;
}

/* PERF: Each bar uses scaleY instead of height (GPU-accelerated) */
#comms-wave span:nth-child(1) {
  animation: comms-wave-1 0.42s ease-in-out infinite;
}
#comms-wave span:nth-child(2) {
  animation: comms-wave-2 0.55s ease-in-out infinite;
  animation-delay: 0.1s;
}
#comms-wave span:nth-child(3) {
  animation: comms-wave-3 0.38s ease-in-out infinite;
  animation-delay: 0.05s;
}
#comms-wave span:nth-child(4) {
  animation: comms-wave-4 0.48s ease-in-out infinite;
  animation-delay: 0.15s;
}

@keyframes comms-wave-1 {
  0%, 100% { transform: scale3d(1, 0.25, 1); }
  50% { transform: scale3d(1, 0.83, 1); }
}

@keyframes comms-wave-2 {
  0%, 100% { transform: scale3d(1, 0.42, 1); }
  35% { transform: scale3d(1, 1, 1); }
  70% { transform: scale3d(1, 0.5, 1); }
}

@keyframes comms-wave-3 {
  0%, 100% { transform: scale3d(1, 0.33, 1); }
  40% { transform: scale3d(1, 0.67, 1); }
  80% { transform: scale3d(1, 0.92, 1); }
}

@keyframes comms-wave-4 {
  0%, 100% { transform: scale3d(1, 0.25, 1); }
  60% { transform: scale3d(1, 0.75, 1); }
}

#comms-text {
  margin: 0;
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--font-size-xl);
  line-height: 1.4;
  text-wrap: pretty;
}

/* Typewriter word spans - prevent mid-word line breaks (shared by dialogue & comms) */
.tw-word {
  white-space: nowrap;
}

/* --- Toast Container --- */
#toast-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--gui-gap-sm);
  pointer-events: none; /* Click-through */
}

#toast-container:empty { display: none; }

/* Toast-specific: animation */
.toast {
  animation: toast-in 0.3s ease, toast-out 0.3s ease 2.7s forwards;
  white-space: nowrap;
}

@keyframes toast-in {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes toast-out {
  from { opacity: 1; }
  to { opacity: 0; }
}

/* --- Persistent Toasts (no auto-dismiss) --- */
.toast.persistent {
  animation: toast-in 0.3s ease forwards;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.toast.persistent.fade-out {
  animation: toast-out 0.2s ease forwards;
}

/* Error persistent toast - red border accent with subtle pulse */
.toast.persistent.error {
  border-left-color: var(--danger);
  animation: toast-in 0.3s ease, persistent-pulse 2s ease-in-out 0.3s infinite;
}

@keyframes persistent-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.8; }
}

/* --- Debug Panel (toggle via window.__vetuuShowToastDebug()) --- */
#toast-debug-panel {
  position: fixed;
  top: var(--gui-margin);
  right: var(--gui-margin);
  background: var(--bg-panel-alpha);
  border: var(--frame-border-width) solid var(--frame-border);
  padding: var(--gui-padding);
  z-index: 450;
  display: none;
  flex-direction: column;
  gap: var(--gui-gap-sm);
  max-width: 280px;
  pointer-events: auto; /* Interactive when visible */
}

#toast-debug-panel.visible {
  display: flex;
}

#toast-debug-panel .debug-title {
  font-family: var(--font-display);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding-bottom: var(--gui-padding-sm);
  border-bottom: 1px solid var(--alpha-white-05);
}

#toast-debug-panel .toast {
  animation: none;
  position: relative;
}

#toast-debug-panel .toast-type-label {
  position: absolute;
  top: 50%;
  right: var(--gui-padding);
  transform: translateY(-50%);
  font-size: var(--font-size-2xs);
  font-family: var(--font-mono);
  color: var(--text-muted);
  background: var(--alpha-black-50);
  padding: 2px 4px;
}

/* ============================================
   SETTINGS MENU
   ============================================ */

/* Shroud behind settings menu */
#settings-shroud {
  position: fixed;
  inset: 0;
  background: var(--alpha-black-70);
  z-index: 500; /* Above everything in GUI */
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade-quick) ease, visibility var(--fade-quick) ease;
  pointer-events: none; /* Click-through when hidden */
}

#settings-shroud.visible {
  opacity: 1;
  visibility: visible;
  pointer-events: auto; /* Clickable when visible */
}

#settings-menu {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%, -50%, 0) scale3d(0.95, 0.95, 1);
  background: var(--bg-panel);
  border: var(--frame-border-width) solid var(--frame-border);
  min-width: 320px;
  max-width: 400px;
  font-family: var(--font-display);
  z-index: 501; /* Above shroud */
  /* Hidden by default */
  display: none;
  opacity: 0;
  transition: opacity var(--fade-quick) ease, transform var(--fade-quick) ease;
  pointer-events: auto; /* Interactive when visible */
}

#settings-menu.visible {
  display: block;
  opacity: 1;
  transform: translate3d(-50%, -50%, 0) scale3d(1, 1, 1);
}

.settings-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--gui-padding);
  border-bottom: 1px solid var(--frame-border);
  background: var(--alpha-white-02);
}

.settings-header h2 {
  font-size: var(--font-size-lg);
  font-weight: 600;
  color: var(--text-primary);
}

.settings-close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--font-size-2xl);
  cursor: pointer;
  padding: 0;
  line-height: 1;
  transition: color 0.15s ease;
}

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

.settings-content {
  padding: var(--gui-padding);
  max-height: 60vh;
  overflow-y: auto;
}

.settings-section {
  margin-bottom: 1rem;
}

.settings-section:last-child {
  margin-bottom: 0;
}

.settings-section h3 {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 0.5rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid var(--alpha-white-05);
}

.controls-list {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.controls-list p {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 0.3rem;
}

.controls-list kbd {
  background: var(--frame-inner);
  border: var(--frame-border-width) solid var(--frame-border);
  padding: 0.1rem 0.3rem;
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  min-width: 1.5em;
  text-align: center;
}

/* ============================================
   GAMEPLAY SETTINGS (Nameplates)
   ============================================ */
.settings-group {
  margin-bottom: 0.625rem;
}

.settings-group:last-child {
  margin-bottom: 0;
}

.settings-label {
  display: block;
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin-bottom: 0.25rem;
}

.settings-radio-group {
  display: flex;
  gap: 2px;
  background: var(--frame-inner);
  border: 1px solid var(--frame-border);
  padding: 2px;
}

.settings-radio {
  flex: 1;
  display: flex;
  cursor: pointer;
}

.settings-radio input[type="radio"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.settings-radio span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 0.3rem 0.4rem;
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  text-align: center;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.settings-radio input[type="radio"]:checked + span {
  background: var(--accent);
  color: var(--bg-dark);
}

.settings-radio:hover span {
  color: var(--text-primary);
}

.settings-radio input[type="radio"]:checked + span:hover {
  color: var(--bg-dark);
}

/* ============================================
   ACCESSIBILITY SETTINGS
   ============================================ */
.settings-toggle {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.settings-toggle label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  font-size: var(--font-size-sm);
  color: var(--text-primary);
}

.settings-toggle input[type="checkbox"] {
  width: 14px;
  height: 14px;
  accent-color: var(--highlight);
  cursor: pointer;
}

.settings-hint {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  line-height: 1.3;
  margin-left: 22px;
}

#reset-btn {
  display: block;
  width: 100%;
  padding: var(--gui-padding);
  background: var(--danger-dark);
  border: var(--frame-border-width) solid var(--danger);
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  cursor: pointer;
  transition: background-color 0.15s ease;
}

#reset-btn:hover {
  background: var(--danger);
}

/* ============================================
   GRAPHICS SETTINGS
   ============================================ */
.graphics-info {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.browser-note {
  margin-bottom: 0.5rem;
  line-height: 1.4;
}

.browser-ok {
  color: var(--success);
}

.graphics-details {
  background: var(--frame-inner);
  border: var(--frame-border-width) solid var(--frame-border);
  padding: var(--gui-padding);
  margin-top: var(--gui-gap);
}

.graphics-details summary {
  cursor: pointer;
  font-weight: 500;
  color: var(--text-primary);
  font-size: var(--font-size-xs);
}

.graphics-details[open] summary {
  margin-bottom: 0.5rem;
}

.graphics-steps {
  margin: 0.5rem 0 0.5rem 1.2rem;
  padding: 0;
  font-size: var(--font-size-xs);
  line-height: 1.6;
}

.graphics-steps li {
  margin-bottom: 0.25rem;
}

.terminal-note {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  margin: 0.5rem 0 0.25rem;
}

.terminal-cmd {
  display: block;
  background: oklch(0.12 0.01 55);
  border: var(--frame-border-width) solid var(--frame-border);
  padding: 0.4rem 0.5rem;
  font-family: monospace;
  font-size: var(--font-size-2xs);
  color: var(--punch-cyan);
  word-break: break-all;
  user-select: all;
}

/* ============================================
   SAFARI MODAL
   ============================================ */
.safari-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate3d(-50%, -50%, 0);
  background: var(--bg-panel);
  border: var(--frame-border-width) solid var(--frame-border);
  padding: 0;
  max-width: 420px;
  width: 90vw;
  z-index: 500;
  pointer-events: auto; /* Interactive when open */
  font-family: var(--font-display);
}

.safari-modal::backdrop {
  background: oklch(0.08 0.015 55 / 0.85);
}

.safari-modal-content {
  padding: 1.25rem;
}

.safari-modal h2 {
  font-size: var(--font-size-xl);
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: 0.75rem;
}

.safari-modal > .safari-modal-content > p {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  line-height: 1.5;
  margin-bottom: 0.75rem;
}

.safari-modal .graphics-details {
  margin-bottom: 1rem;
}

.modal-note {
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  font-style: italic;
  margin-bottom: 1rem;
}

.modal-btn {
  display: block;
  width: 100%;
  padding: var(--gui-padding);
  background: var(--punch-cyan);
  border: none;
  color: var(--bg-base);
  font-family: var(--font-display);
  font-size: var(--font-size-md);
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.modal-btn:hover {
  background: oklch(0.75 0.15 195);
}

/* ============================================
   RESIZE OVERLAY
   ============================================ */
#resize-overlay {
  position: fixed;
  inset: 0;
  z-index: 900; /* Above everything except during active use */
  background: oklch(0.10 0.015 55);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--fade-snappy) ease-out, visibility var(--fade-snappy) ease-out;
  pointer-events: none;
}

#resize-overlay.visible {
  opacity: 1;
  visibility: visible;
}

.resize-overlay-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  color: var(--text-secondary);
  font-family: var(--font-display);
}

.resize-icon {
  font-size: var(--font-size-4xl);
  animation: resize-spin 1.5s linear infinite;
}

.resize-text {
  font-size: var(--font-size-lg);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

@keyframes resize-spin {
  from { transform: rotate3d(0, 0, 1, 0deg); }
  to { transform: rotate3d(0, 0, 1, 360deg); }
}

/* ============================================
   LOADING OVERLAY
   Initial game loading screen - fades out once ready
   ============================================ */
#loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000; /* Above everything */
  background: var(--bg-void);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  pointer-events: auto;
  /* Background fades slower - text disappears first */
  transition: opacity 3s ease-out;
}

#loading-overlay.fade-out {
  opacity: 0;
  pointer-events: none;
}

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

.loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.5rem;
  /* Text fades faster than background */
  transition: opacity 1s ease-out;
}

#loading-overlay.fade-out .loading-content {
  opacity: 0;
}

.loading-logo {
  font-family: var(--font-display);
  font-size: clamp(3rem, 10vw, 6rem);
  font-weight: 700;
  letter-spacing: 0.15em;
  color: var(--text-primary);
  /* Hold invisible until fonts ready - prevents FOUT during animation */
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

.loading-subtitle {
  font-family: var(--font-display);
  font-size: clamp(0.8rem, 2vw, 1rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-secondary);
  /* Hold invisible until fonts ready */
  opacity: 0;
  transform: translate3d(0, 18px, 0);
}

.loading-prompt {
  font-family: var(--font-display);
  font-size: clamp(0.7rem, 1.5vw, 0.9rem);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  /* Hold invisible until fonts ready - same as other elements */
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  margin-top: 1rem;
  cursor: pointer;
}

/* Staggered fade-lift animations - only start once fonts are loaded */
#loading-overlay.fonts-ready .loading-logo {
  animation: loading-fade-in 800ms ease-out 100ms both;
}

#loading-overlay.fonts-ready .loading-subtitle {
  animation: loading-fade-in 800ms ease-out 450ms both;
}

/* Prompt fades in after subtitle, then pulses when game is ready */
#loading-overlay.fonts-ready .loading-prompt {
  animation: loading-fade-in 800ms ease-out 800ms both;
}

#loading-overlay.fonts-ready.game-ready .loading-prompt {
  animation: loading-fade-in 800ms ease-out 800ms both,
             loading-prompt-pulse 2s ease-in-out 1.6s infinite;
}

@keyframes loading-fade-in {
  from {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@keyframes loading-prompt-pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 0.8; }
}

/* ============================================
   RESPONSIVE
   ============================================ */
@media (max-width: 900px) {
  .unit-frame {
    min-width: 160px;
  }
}

@media (max-width: 768px) {
  :root {
    --tile-size: 20px;
  }

  /* Remove panel min-width for mobile and constrain to column width */
  .gui-panel:not(.frame-wrapper),
  #quest-tracker,
  #combat-log-container,
  #inventory-panel,
  #character-sheet {
    min-width: 0;
    max-width: 100%;
  }

  /* Docked panels fill column width */
  #left-panel-column > .gui-panel,
  #right-panel-column > .gui-panel {
    width: 100%;
  }

  /* Remove min-width from portrait children */
  .frame-wrapper,
  .frame-status-container,
  .unit-frame {
    min-width: 0;
  }

  /* Prevent columns from overlapping */
  #left-panel-column {
    top: 0.5rem;
    left: 0.5rem;
    max-width: calc(50% - 1rem);
  }

  #right-panel-column {
    top: 0.5rem;
    right: 0.5rem;
    max-width: calc(50% - 1rem);
  }

  #minimap-container {
    min-width: 0;
    /* Keep square aspect ratio */
    aspect-ratio: 1 / 1;
  }

  #quest-tracker {
    max-width: 100%;
  }

  #bottom-ui {
    bottom: 0.5rem;
    width: 100%;
    padding: 0 0.5rem;
  }

  #portrait-row {
    min-width: auto;
    max-width: none;
    width: 100%;
  }

  .action-slot {
    width: 40px;
    height: 40px;
  }

  #weapon-display {
    display: none;
  }

  .unit-frame {
    padding: 0.25rem;
  }

  .portrait-wrapper { display: none; }
  #dialogue-portrait { display: none; }
  
  #settings-menu {
    min-width: 280px;
    max-width: 90vw;
  }

  #xp-bar-track {
    height: 6px;
  }

  .xp-level-box {
    width: 20px;
    min-width: 20px;
    height: 20px;
  }

  /* XP row: small gap from ability bar, flush with bottom */
  #xp-row {
    margin-top: calc(-1.5 * var(--gui-margin));
    margin-bottom: calc(-0.5 * var(--gui-margin));
  }
}

/* ============================================
   MOBILE (≤512px)
   Full-width panels and action bar
   ============================================ */
@media (max-width: 512px) {
  /* Portrait containers take 50% minus gap */
  .portrait-dock-zone {
    min-width: calc(50% - var(--gui-margin) / 2);
  }

  /* Ability/XP bar parent goes full width */
  #abilities-row {
    width: 100%;
  }

  #action-block {
    width: 100%;
    /* Pull ability bar down to sit in XP bar footprint */
    margin-bottom: calc(-1.5 * var(--gui-margin));
  }

  /* XP row: pull up to close gap with ability bar */
  #xp-row {
    margin-top: calc(-0.5 * var(--gui-margin));
    margin-bottom: calc(-0.5 * var(--gui-margin));
  }

  #action-bar {
    justify-content: center;
    background: var(--alpha-black-00);
  }

  /* All panels fill their parent column */
  #left-panel-column > .gui-panel,
  #right-panel-column > .gui-panel {
    width: 100%;
  }
}

/* ============================================
   PLAYER DEAD STATE
   Hide combat UI during death sequence
   ============================================ */
body.player-dead #player-frame,
body.player-dead #action-block,
body.player-dead #xp-row {
  display: none;
}
