/* ========================================
   SHARED TERMINAL THEME
   Used by: character-builder, character-manager
   ======================================== */

/* ===== CSS VARIABLES ===== */
:root {
  /* ===== THEME FOUNDATION (HSL-based) ===== */
  /* Terminal Green Theme */
  --theme-terminal-h: 120;
  --theme-terminal-s: 100%;
  --theme-terminal-l-bright: 50%;
  --theme-terminal-l-dim: 27%;
  
  /* Sheet Teal Theme */
  --theme-teal-h: 181;
  --theme-teal-s: 100%;
  --theme-teal-l-bright: 41%;
  --theme-teal-l-dim: 45%;
  
  /* Modal Yellow Theme */
  --theme-yellow-h: 48;
  --theme-yellow-s: 100%;
  --theme-yellow-l-bright: 64%;
  --theme-yellow-l-dim: 75%;
  
  /* Cyan Accent Theme */
  --theme-cyan-h: 180;
  --theme-cyan-s: 100%;
  --theme-cyan-l-bright: 50%;
  --theme-cyan-l-dim: 27%;
  
  /* Danger/Error Theme */
  --theme-error-h: 0;
  --theme-error-s: 100%;
  --theme-error-l: 50%;
  
  /* Warning Theme */
  --theme-warning-h: 39;
  --theme-warning-s: 100%;
  --theme-warning-l: 50%;
  
  /* ===== DERIVED COLOR TOKENS ===== */
  /* Background & Neutrals */
  --terminal-bg: #0a0a0a;
  --scrollbar-track-color: #050505;
  
  /* Terminal Green Tokens */
  --terminal-fg: hsl(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright));
  --terminal-dim: hsl(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-dim));
  --terminal-border: hsl(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright));
  --terminal-hover: hsla(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright), 0.1);
  
  /* Cyan Accent Tokens */
  --terminal-accent: hsl(var(--theme-cyan-h), var(--theme-cyan-s), var(--theme-cyan-l-bright));
  --terminal-accent-dim: hsl(var(--theme-cyan-h), var(--theme-cyan-s), var(--theme-cyan-l-dim));
  
  /* Yellow Modal/Warning Tokens */
  --terminal-warning: hsl(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright));
  --modal-accent: hsl(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright));
  --modal-accent-dim: hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.75);
  
  /* Error Token */
  --terminal-error: hsl(var(--theme-error-h), var(--theme-error-s), var(--theme-error-l));
  
  /* Teal Sheet Tokens */
  --sheet-accent: hsl(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright));
  --sheet-accent-dim: hsl(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim));
  --sheet-border-color: hsl(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright));
  --sheet-label-color: hsl(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim));
  --sheet-value-color: hsl(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright));
  --sheet-box-border-color: hsl(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim));
  --sheet-box-bg: hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.08);
  --sheet-ability-box-bg: hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.08);
  
  /* Scrollbar Tokens (derived from terminal green) */
  --scrollbar-thumb-color: hsla(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-dim), 0.45);
  --scrollbar-thumb-hover-color: hsla(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright), 0.85);

  /* Radial background glow color (animated on <body>) */
  --terminal-glow-color: hsla(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright), 0.28);
  
  /* Generic UI theme tokens (used by buttons, inputs, etc.) */
  /* Default = green terminal theme */
  --ui-border-color: var(--terminal-border);
  --ui-fg-color: var(--terminal-fg);
  --ui-dim-color: var(--terminal-dim);
  --ui-primary-bg-color: var(--terminal-border);
  --ui-on-primary-color: var(--terminal-bg);
  
  /* Typography */
  --font-family: 'Google Sans Code', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'Google Sans Code', 'Courier New', Courier, monospace;
  --font-size-base: 16px;
  --font-size-large: 20px;
  --font-size-small: 14px;
  --line-height: 1.6;
  
  /* Spacing */
  --spacing-xs: 4px;
  --spacing-sm: 8px;
  --spacing-md: 16px;
  --spacing-lg: 24px;
  --spacing-xl: 32px;
  
  /* Layout */
  --max-width: 1400px;
  --split-ratio: 50%;
  
  /* Animation */
  --transition-speed: 0.3s;
  --typewriter-speed: 30ms;
  
  /* Overflow Button Configuration */
  --overflow-icon-size: 14px;
  --overflow-dot-size: 3px;
  --overflow-dot-offset: 1px; /* distance from top/bottom edges */
  --overflow-animation-duration: 180ms;
  --overflow-animation-easing: cubic-bezier(0.2, 0.8, 0.2, 1.05);
  --overflow-opacity-duration: 120ms;
  --overflow-border-radius-duration: 160ms;
}

/* Theme helpers: add to any container to switch UI accent colors */
.ui-theme-green {
  --ui-border-color: var(--terminal-border);
  --ui-fg-color: var(--terminal-fg);
  --ui-dim-color: var(--terminal-dim);
  --ui-primary-bg-color: var(--terminal-border);
  --ui-on-primary-color: var(--terminal-bg);
}

.ui-theme-teal {
  --ui-border-color: var(--sheet-accent);
  --ui-fg-color: var(--sheet-accent);
  --ui-dim-color: var(--sheet-accent-dim);
  --ui-primary-bg-color: var(--sheet-accent);
  --ui-on-primary-color: var(--terminal-bg);
}

/* ===== BASE STYLES ===== */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;

  /* Custom scrollbars (Firefox) */
  scrollbar-width: thin;
  scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}

/* Custom scrollbars (WebKit browsers) */
*::-webkit-scrollbar {
  /* 4px thumb + 8px margin on either side = 20px reserved area */
  width: 20px;
  height: 20px;
}

*::-webkit-scrollbar-track {
  background: var(--scrollbar-track-color);
}

*::-webkit-scrollbar-thumb {
  background-color: var(--scrollbar-thumb-color);
  border-radius: 0;
  /* Vertical: 4px thumb with 8px side margins */
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  background-clip: padding-box;
}

*::-webkit-scrollbar-thumb:horizontal {
  /* Horizontal: 4px thumb with 8px top/bottom margins */
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  background-clip: padding-box;
}

*::-webkit-scrollbar-thumb:hover {
  background-color: var(--scrollbar-thumb-hover-color);
}

body {
  font-family: var(--font-mono);
  font-size: var(--font-size-base);
  line-height: var(--line-height);
  background-color: #000000;
  /* Subtle dot grid over pure black background */
  background-image: radial-gradient(rgba(255, 255, 255, 0.09) 1px, transparent 1px);
  background-size: 20px 20px;
  background-position: 0 0;
  color: var(--terminal-fg);
  overflow-x: hidden;
  padding: 64px;
  min-height: 100vh;
  /* Create a stacking context so the glow pseudo-element can sit behind content */
  position: relative;
  z-index: 0;
}

/* Large radial light source behind the terminal.
   - Rendered as a pseudo-element so we can smoothly animate hue.
   - Sits above the black + dot background but below all terminal content. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  margin: auto;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(
    ellipse at center,
    hsla(var(--theme-terminal-h), var(--theme-terminal-s), var(--theme-terminal-l-bright), 0.22) 0,
    transparent 78%
  );
  /* Slightly larger than the viewport so it always extends beyond the terminal */
  background-size: 120% 110%;
  background-position: center;
  filter: hue-rotate(0deg);
  /* Slowly cycle the glow hue: green → teal → yellow → back to green */
  animation: terminal-glow-hue-cycle 36s linear infinite;
}

/* ===== TERMINAL FRAME ===== */
.terminal-frame,
.terminal-container {
  background-color: var(--terminal-bg);
  border: 1px solid var(--terminal-border);
  border-radius: 8px;
  /* Soft, diffuse shadow to ground the terminal on top of the animated glow */
  box-shadow:
    0 24px 80px rgba(0, 0, 0, 0.7),
    0 0 1px rgba(0, 0, 0, 0.9);
  overflow: hidden;
  max-width: var(--max-width);
  margin: 0 auto;
  height: calc(100vh - 128px);
  position: relative;
  display: flex;
  flex-direction: column;
}

/* ===== TERMINAL HEADER ===== */
.terminal-header {
  padding: var(--spacing-md);
  border-bottom: 1px solid var(--terminal-border);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.terminal-title {
  font-size: var(--font-size-base);
  color: var(--terminal-accent);
}

.terminal-footer {
  padding: var(--spacing-sm);
  border-top: 1px solid var(--terminal-border);
  text-align: center;
  color: var(--terminal-dim);
  font-size: var(--font-size-small);
}

/* ===== SHARED SPLIT LAYOUT ===== */
.split-layout {
  flex: 1;
  display: flex;
  width: 100%;
  min-height: 0;
  overflow: hidden;
}

.left-panel {
  flex: 1;
  padding: var(--spacing-xl);
  border-right: 1px solid var(--terminal-border);
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}

.right-panel {
  flex: 1;
  padding: var(--spacing-xl);
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}

/* ===== SHARED SPLASH LAYOUT ===== */
.splash-content {
  flex: 1;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-xl);
  gap: calc(var(--spacing-xl) * 2);
  text-align: left;
  min-height: calc(100vh - 128px);
}

.splash-art {
  font-size: 3px;
  line-height: 1;
  color: var(--terminal-fg);
  white-space: pre;
  font-family: monospace;
  letter-spacing: 1.5px;
  text-align: center;
  overflow: auto;
  max-height: 80vh;
}

.splash-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.splash-title {
  font-size: var(--font-size-large);
  color: var(--terminal-accent);
  margin-bottom: var(--spacing-sm);
}

.splash-subtitle {
  font-size: var(--font-size-base);
  color: var(--terminal-dim);
  margin-bottom: var(--spacing-md);
}

.splash-prompt {
  color: var(--terminal-fg);
  animation: blink 1.5s infinite;
}

/* ===== SHARED TOAST NOTIFICATION ===== */
.toast-notification {
  /* Anchor inside the nearest terminal container/frame, not the viewport */
  position: absolute;
  bottom: 16px;
  left: 16px;
  /* Start fully off-screen to the left so the entrance animation is obvious */
  transform: translateX(-140%) translateY(0);

  /* Extra padding so the toast reads as a more prominent, self-contained panel */
  padding: 12px 20px;
  /* Use a solid black background so the toast reads clearly against the UI. */
  background: #000000;
  color: var(--terminal-warning);
  border: 1px solid var(--terminal-warning);
  box-shadow:
    0 0 0 1px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.6),
    0 0 16px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.55),
    0 0 32px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.36);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: var(--font-size-small);
  text-align: left;
  z-index: 9999;
  opacity: 0;
  /* Allow interaction so the close button is clickable */
  pointer-events: auto;
  max-width: min(480px, 100% - 32px);
  /* Reserve space on the right for the dismiss button so text never sits under it */
  padding-right: 48px;

  /* Slide in horizontally from the left edge with a soft, very subtle bouncy easing curve */
  transition:
    opacity 0.5s cubic-bezier(0.22, 0.7, 0.3, 1.02),
    transform 0.8s cubic-bezier(0.22, 0.7, 0.3, 1.02);
}

.toast-notification.show {
  opacity: 1;
  transform: translateX(0) translateY(0);
  /* Continuous, subtle breathing glow while the toast is visible */
  animation: toast-glow 2.1s ease-in-out 0.15s infinite;
}

/* Message text inside toast */
.toast-message {
  display: block;
  /* Ensure long messages wrap instead of overflowing */
  word-break: break-word;
}

/* Wrapper for the dismiss button, pinned to the right and vertically centered */
.toast-dismiss-wrapper {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
}

/* Close button pinned to the right */
.toast-dismiss {
  border: none;
  background: transparent;
  color: inherit;
  font: inherit;
  padding: 0;
  cursor: pointer;
  line-height: 1;
  opacity: 0.9;
  transition:
    transform 0.15s ease-out,
    opacity 0.15s ease-out,
    text-shadow 0.15s ease-out;
}

.toast-dismiss:hover,
.toast-dismiss:focus-visible {
  opacity: 1;
  text-shadow: 0 0 8px currentColor;
  /* Match modal close button behavior: a simple quarter-turn spin on hover/focus */
  transform: rotate(90deg);
  outline: none;
}

@keyframes toast-glow {
  0% {
    box-shadow:
      0 0 0 1px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.5),
      0 0 14px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.45),
      0 0 28px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.3);
  }
  50% {
    box-shadow:
      0 0 0 1px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.8),
      0 0 20px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.7),
      0 0 40px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.45);
  }
  100% {
    box-shadow:
      0 0 0 1px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.5),
      0 0 14px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.45),
      0 0 28px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-bright), 0.3);
  }
}

/* ===== SHARED CHARACTER SHEET LAYOUT ===== */
.character-sheet {
  border: 1px solid var(--sheet-border-color);
  padding: var(--spacing-md);
  max-width: 100%;
  overflow-wrap: break-word;
  
  /* Use teal UI theme tokens inside the sheet */
  --ui-border-color: var(--sheet-accent);
  --ui-fg-color: var(--sheet-accent);
  --ui-dim-color: var(--sheet-accent-dim);
  --ui-primary-bg-color: var(--sheet-accent);
  --ui-on-primary-color: var(--terminal-bg);

  /* Teal scrollbars inside character sheets */
  --scrollbar-track-color: hsl(var(--theme-teal-h), 70%, 7%);
  --scrollbar-thumb-color: hsla(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim), 0.5);
  --scrollbar-thumb-hover-color: hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.9);
}

.sheet-title-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: var(--spacing-md);
  padding-bottom: var(--spacing-sm);
}

/* Wrapper for inline header actions (e.g., Edit + overflow menu) */
.sheet-title-actions {
  display: flex;
  /* Top-align inline header buttons (Edit + overflow) so their borders
     and glows line up visually along the top edge. */
  align-items: flex-start;
  gap: var(--spacing-sm);
  flex-shrink: 0;
  white-space: nowrap;
}

.sheet-title {
  color: var(--sheet-accent);
  font-size: var(--font-size-large);
  font-weight: bold;
  line-height: 1.1;
  letter-spacing: 0.03em;
  flex: 1 1 auto;
  min-width: 0;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

.sheet-title-buttons {
  display: flex;
  gap: var(--spacing-sm);
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  position: relative;
}

/* ===== OVERFLOW BUTTON COMPONENT (Three dots → X animation) =====
   
   MARKUP PATTERN (reusable):
   <button class="terminal-btn-small selector-trigger overflow-trigger">
     <span class="sheet-actions-icon" aria-hidden="true">
       <span class="sheet-actions-dot dot-1"></span>
       <span class="sheet-actions-dot dot-2"></span>
       <span class="sheet-actions-dot dot-3"></span>
     </span>
   </button>
   
   The .is-open class is automatically added by toggleSelectorMenu() to trigger
   the animation. Use .overflow-trigger for new overflow menus, or 
   .sheet-actions-trigger for backward compatibility. */
   
.sheet-actions-trigger,
.overflow-trigger {
  position: relative;
  padding-left: 10px;
  padding-right: 10px;
  /* Use the same geometry as .terminal-btn-small so heights match exactly */
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.sheet-actions-icon {
  position: relative;
  display: inline-block;
  width: var(--overflow-icon-size);
  height: var(--overflow-icon-size);
}

/* Center the three dots perfectly within the icon box by anchoring
   at 50% and using translateX(-50%). This avoids the slight horizontal
   offset that happened when mixing margin-left with transforms. */
.sheet-actions-dot {
  position: absolute;
  left: 50%;
  width: var(--overflow-dot-size);
  height: var(--overflow-dot-size);
  border-radius: 999px;
  background-color: currentColor;
  transform: translateX(-50%);
  transition:
    transform var(--overflow-animation-duration) var(--overflow-animation-easing),
    width var(--overflow-animation-duration) var(--overflow-animation-easing),
    height var(--overflow-animation-duration) var(--overflow-animation-easing),
    border-radius var(--overflow-border-radius-duration) ease-out,
    opacity var(--overflow-opacity-duration) ease-out;
}

.sheet-actions-dot.dot-1 {
  top: var(--overflow-dot-offset);
}

.sheet-actions-dot.dot-2 {
  top: 50%;
  transform: translate(-50%, -50%);
}

.sheet-actions-dot.dot-3 {
  bottom: var(--overflow-dot-offset);
}

/* Morph animation: dots → X when trigger is open */
.sheet-actions-trigger.is-open .sheet-actions-dot.dot-1,
.overflow-trigger.is-open .sheet-actions-dot.dot-1 {
  opacity: 0;
}

.sheet-actions-trigger.is-open .sheet-actions-dot.dot-2,
.overflow-trigger.is-open .sheet-actions-dot.dot-2 {
  /* Keep left: 50% to maintain horizontal centering */
  width: 14px;
  height: 2px;
  border-radius: 1px;
  transform: translate(-50%, -50%) rotate(45deg);
}

.sheet-actions-trigger.is-open .sheet-actions-dot.dot-2::after,
.overflow-trigger.is-open .sheet-actions-dot.dot-2::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: currentColor;
  border-radius: 1px;
  transform: rotate(90deg);
}

.sheet-actions-trigger.is-open .sheet-actions-dot.dot-3,
.overflow-trigger.is-open .sheet-actions-dot.dot-3 {
  opacity: 0;
}

/* Ensure sheet header buttons (Rename / Change Level / Print, etc.)
   all share the exact same height and vertical alignment */
.character-sheet .sheet-title-buttons .terminal-btn-small,
.character-sheet .sheet-title-buttons .button-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

/* Make leading icon glyphs (e.g., ✎, ⎙, ◉) a consistent visual size so they
  read as icons next to 14px button labels. */
.character-sheet .sheet-title-buttons .terminal-btn-small::first-letter,
.character-sheet .sheet-title-buttons .button-secondary::first-letter,
.character-sheet .sheet-header-action .terminal-btn-small::first-letter,
.character-sheet .sheet-header-action .button-secondary::first-letter {
  font-size: 18px;
  line-height: 1;
}

/* Manager-specific inline Edit button in the sheet header */
.character-sheet .sheet-edit-btn {
  /* Reuse small button geometry but keep it slightly more prominent than
     the overflow trigger so it's the primary affordance. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

/* Inline Edit button icon (✎) should match other button icon sizing. */
.character-sheet .sheet-edit-btn::first-letter {
  font-size: 18px;
  line-height: 1;
}

.sheet-section {
  margin-bottom: var(--spacing-lg);
}

.sheet-header {
  color: var(--sheet-accent);
  font-size: var(--font-size-base);
  margin-bottom: var(--spacing-sm);
  border-bottom: 1px solid var(--sheet-accent-dim);
  padding-bottom: var(--spacing-xs);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* Optional variant for headers that should not show the dividing line
   below the title (used by certain sections in the builder sheet). */
.sheet-header--no-divider {
  border-bottom: none;
}

.sheet-header-title {
  flex: 1;
  font-weight: bold;
}

.sheet-header-action {
  flex-shrink: 0;
}

/* Teal buttons inside character sheet */
.character-sheet .button-secondary,
.character-sheet .terminal-btn,
.character-sheet .terminal-btn-small,
.character-sheet .prompt-modal-btn {
  /* Use a semi-transparent teal so sheet header actions read clearly
     dimmer than bright accents and values. */
  border-color: hsla(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim), 0.6);
  color: hsla(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim), 0.8);
}

.character-sheet .button-secondary:hover:not(:disabled),
.character-sheet .terminal-btn:hover:not(:disabled),
.character-sheet .terminal-btn-small:hover:not(:disabled),
.character-sheet .prompt-modal-btn:hover:not(:disabled) {
  background: hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.15);
  border-color: hsla(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim), 0.9);
  color: hsla(var(--theme-teal-h), calc(var(--theme-teal-s) * 0.67), var(--theme-teal-l-dim), 1);
  box-shadow: 0 0 10px hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.3);
}

.character-sheet .prompt-modal-btn.primary,
.character-sheet .terminal-btn-primary {
  background-color: var(--sheet-accent);
  border-color: var(--sheet-accent);
  color: var(--terminal-bg);
}

.character-sheet .prompt-modal-btn.primary:hover:not(:disabled),
.character-sheet .terminal-btn-primary:hover:not(:disabled) {
  background-color: var(--sheet-accent);
  box-shadow: 0 0 15px hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.5);
}

.sheet-content {
  color: var(--sheet-value-color);
}

.stat-line {
  display: flex;
  justify-content: space-between;
  padding: var(--spacing-xs) 0;
}

.stat-label {
  color: var(--sheet-label-color);
}

.stat-value {
  color: var(--sheet-value-color);
}

/* Combat stats grid */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-sm);
  margin-top: var(--spacing-sm);
}

.stat-box {
  text-align: center;
  border: 1px solid var(--sheet-box-border-color);
  padding: var(--spacing-sm);
  background: var(--sheet-box-bg);
}

.stat-box-label {
  color: var(--sheet-label-color);
  font-size: var(--font-size-small);
  margin-bottom: var(--spacing-xs);
}

/* Combined value styles for stats and abilities */
.stat-box-value,
.ability-score {
  color: var(--sheet-value-color);
  font-weight: bold;
}

/* Ability scores grid */
.ability-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--spacing-sm);
  margin-top: var(--spacing-sm);
}

.ability-box {
  border: 1px solid var(--sheet-box-border-color);
  padding: var(--spacing-xs);
  background: var(--sheet-ability-box-bg);
  text-align: center;
}

.ability-name {
  color: var(--sheet-label-color);
  font-size: var(--font-size-small);
  margin-bottom: var(--spacing-xs);
}

.ability-modifier {
  color: var(--sheet-value-color);
  font-size: var(--font-size-small);
  display: inline;
  margin-left: 0.25em;
}

/* Character sheet-specific text utilities */
.character-sheet .terminal-text {
  color: var(--sheet-value-color);
}

.character-sheet .terminal-text-dim,
.character-sheet .text-dim {
  color: var(--sheet-label-color);
}

.character-sheet .terminal-text-accent {
  color: var(--sheet-accent);
}

/* Character sheet inputs/selects use teal borders and focus states */
.character-sheet .terminal-input,
.character-sheet .terminal-select,
.character-sheet .terminal-textarea {
  border-color: var(--sheet-accent-dim);
  color: var(--sheet-value-color);
}

.character-sheet .terminal-input:focus,
.character-sheet .terminal-select:focus,
.character-sheet .terminal-textarea:focus {
  border-color: var(--sheet-accent);
  box-shadow: 0 0 5px hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.5);
}

/* ===== INPUT ELEMENTS ===== */
.terminal-input,
.terminal-select,
.terminal-textarea {
  background-color: var(--terminal-bg);
  border: 1px solid var(--terminal-border);
  color: var(--terminal-fg);
  padding: var(--spacing-sm) var(--spacing-md);
  font-family: var(--font-mono);
  font-size: var(--font-size-base);
  width: 100%;
  transition: all var(--transition-speed);
}

.terminal-input:focus,
.terminal-select:focus,
.terminal-textarea:focus {
  outline: none;
  border-color: var(--terminal-accent);
  box-shadow: 0 0 5px hsla(var(--theme-cyan-h), var(--theme-cyan-s), var(--theme-cyan-l-bright), 0.5);
}

.terminal-select {
  cursor: pointer;
  width: auto;
  min-width: 200px;
}

.terminal-textarea {
  resize: vertical;
}

/* ===== BUTTONS ===== */

/* Base button style - used by both naming conventions */
.terminal-btn,
.button-primary {
  background: transparent;
  /* Default = dimmed stroke so options feel low-friction until focused/hovered */
  border: 1px solid var(--ui-dim-color);
  /* Default text is also dimmed; hover/focus/selected promote to bright theme color. */
  color: var(--ui-dim-color);
  padding: var(--spacing-xs) var(--spacing-sm);
  font-family: var(--font-mono);
  font-size: var(--font-size-small);
  cursor: pointer;
  transition: all var(--transition-speed);
  text-align: left;
}

/* Hover/keyboard-focus (non-selected): bright outline + translucent themed background.
   Uses ui-* tokens so the effect respects the active color theme (green / teal / yellow). */
.terminal-btn:hover:not(:disabled),
.button-primary:hover:not(:disabled):not(.is-selected),
.button-primary.is-focused:not(.is-selected) {
  border-color: var(--ui-border-color);
  color: var(--ui-fg-color);
  background: color-mix(in srgb, var(--ui-primary-bg-color) 18%, transparent);
}

.terminal-btn:disabled,
.button-primary:disabled:not(.is-selected) {
  opacity: 0.6;
  cursor: not-allowed;
}

.terminal-btn:disabled:hover,
.button-primary:disabled:not(.is-selected):hover {
  background: transparent;
}

/* Secondary/Small button */
.terminal-btn-small,
.button-secondary {
  background: transparent;
  border: 1px solid var(--ui-dim-color);
  color: var(--ui-dim-color);
  padding: var(--spacing-xs) var(--spacing-sm);
  font-family: var(--font-mono);
  font-size: var(--font-size-small);
  cursor: pointer;
  transition: all var(--transition-speed);
}

.terminal-btn-small:hover:not(:disabled),
.button-secondary:hover:not(:disabled) {
  /* Use themed foreground token so hover color matches the active UI theme
     (green by default, teal in sheets, yellow in modals, etc.). */
  border-color: var(--ui-fg-color);
  color: var(--ui-fg-color);
}

/* Teal-themed small buttons (e.g., builder EXIT) should also get a subtle
   teal background glow on hover instead of the default green tint. */
.ui-theme-teal.terminal-btn-small:hover:not(:disabled) {
  background: hsla(var(--theme-teal-h), var(--theme-teal-s), var(--theme-teal-l-bright), 0.15);
  border-color: var(--sheet-accent);
  color: var(--sheet-accent);
}

/* Filled primary button (character manager style) */
.terminal-btn-primary {
  background-color: var(--ui-primary-bg-color);
  color: var(--ui-on-primary-color);
  border: 1px solid var(--ui-primary-bg-color);
  text-transform: uppercase;
  font-weight: bold;
}

.terminal-btn-primary:hover:not(:disabled) {
  /* Invert style on hover:
     - Solid fill becomes transparent
     - Text + border use the primary color */
  background-color: transparent;
  color: var(--ui-primary-bg-color);
  border-color: var(--ui-primary-bg-color);
}

.terminal-btn-primary:disabled {
  /* Theme-agnostic disabled state: neutral, slightly dimmed */
  background-color: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.35);
  opacity: 0.7;
  cursor: not-allowed;
}

/* Warning button */
.terminal-btn-warning {
  background: transparent;
  border: 1px solid hsl(var(--theme-warning-h), var(--theme-warning-s), var(--theme-warning-l));
  color: hsl(var(--theme-warning-h), var(--theme-warning-s), var(--theme-warning-l));
  padding: var(--spacing-sm) var(--spacing-md);
  font-family: var(--font-mono);
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: all var(--transition-speed);
}

.terminal-btn-warning:hover:not(:disabled) {
  background-color: hsla(var(--theme-warning-h), var(--theme-warning-s), var(--theme-warning-l), 0.1);
}

/* Danger button */
.terminal-btn-danger {
  background: transparent;
  border: 1px solid var(--terminal-error);
  color: var(--terminal-error);
  padding: var(--spacing-sm) var(--spacing-md);
  font-family: var(--font-mono);
  font-size: var(--font-size-base);
  cursor: pointer;
  transition: all var(--transition-speed);
}

.terminal-btn-danger:hover:not(:disabled) {
  background-color: hsla(var(--theme-error-h), var(--theme-error-s), var(--theme-error-l), 0.1);
}

/* ===== SELECTOR LISTBOX (shared trigger + menu pattern) ===== */

.selector-shell {
  position: relative;
  display: inline-block;
}

.selector-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  text-align: left;
  white-space: nowrap;
  gap: var(--spacing-xs);
}

.selector-trigger-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

.selector-caret {
  margin-left: var(--spacing-xs);
  font-size: 12px;
  opacity: 0.8;
  transition: transform 180ms ease-out, opacity 160ms ease-out;
}

.selector-trigger.is-open .selector-caret {
  transform: rotate(180deg);
  opacity: 1;
}

.selector-trigger.is-open {
  border-color: var(--ui-dim-color);
  color: var(--ui-dim-color);
  background-color: rgba(0, 0, 0, 0.6);
}

.selector-menu {
  position: absolute;
  min-width: 200px;
  /* Let listbox grow with content but cap it so it never gets absurdly wide.
     Also respect small viewports by clamping to viewport width with padding. */
  max-width: min(360px, calc(100vw - 32px));
  background: var(--terminal-bg);
  border: 1px solid var(--ui-border-color);
  border-radius: 4px;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.7);
  z-index: 20;

  transform-origin: center center;
  transform: translateY(-4px) scaleY(0.15);
  opacity: 0;
  pointer-events: none;

  transition:
    transform 190ms cubic-bezier(0.2, 0.8, 0.2, 1.05),
    opacity 140ms ease-out,
    box-shadow 200ms ease-out;
}

.selector-menu.is-open {
  transform: translateY(0) scaleY(1);
  opacity: 1;
  pointer-events: auto;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.9);
}

/* Sheet-level selector menus (header + portrait) should be perfectly
   centered on the trigger without the global vertical offset. */
.sheet-actions-menu.selector-menu,
.portrait-actions-menu.selector-menu {
  transform: scaleY(0.15);
}

.sheet-actions-menu.selector-menu.is-open,
.portrait-actions-menu.selector-menu.is-open {
  transform: scaleY(1);
}

.selector-option {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 6px 12px;
  background: transparent;
  border: none;
  color: var(--ui-fg-color);
  text-align: left;
  font-family: var(--font-mono);
  font-size: 12px;
  cursor: pointer;
  gap: 8px;
}

.selector-option:hover,
.selector-option:focus {
  /* Themed tint based on active UI context:
     - Default terminal frame: terminal green (via ui tokens)
     - Character sheet: teal (overrides ui tokens inside sheet)
     - Modals: yellow (overrides ui tokens inside modal) */
  background-color: color-mix(in srgb, var(--ui-primary-bg-color) 20%, transparent);
  /* Keep text in the bright themed foreground color so it never inverts. */
  color: var(--ui-fg-color);
}

.selector-option-icon {
  width: 18px;
  text-align: center;
  flex-shrink: 0;
  font-size: 18px;
}

.selector-option-label {
  flex: 1;
}

/* Link-style button */
.link-button {
  background: none;
  border: none;
  /* Use themed foreground token so links respect the active UI theme.
     - Default terminal: terminal accent green
     - Character sheet: teal accent via sheet overrides
     - Modals: yellow accent via modal overrides */
  color: var(--ui-fg-color);
  font-family: var(--font-mono);
  font-size: inherit;
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
  transition: color var(--transition-speed), text-shadow var(--transition-speed);
}

.link-button:hover {
  /* On hover, keep the same themed color but add a subtle glow. */
  color: var(--ui-fg-color);
  text-shadow: 0 0 5px var(--ui-fg-color);
}

/* Links inside modals follow the modal's yellow text theme */
.modal .terminal-link,
.modal .link-button {
  color: var(--modal-accent);
}

.modal .terminal-link:hover,
.modal .link-button:hover {
  color: var(--modal-accent);
  text-shadow: 0 0 5px var(--modal-accent);
}

/* Button group layout utilities */
.button-group {
  display: flex;
  gap: var(--spacing-md);
  margin-top: var(--spacing-lg);
}

.button-group button {
  flex: 1;
}

/* Character Builder specific button states */

/* Focused (via keyboard) but not selected:
   - Reuse the same bright outline as hover, plus an explicit outline ring. */
.button-primary.is-focused:not(.is-selected) {
  outline: 1px solid var(--ui-border-color);
  outline-offset: 0;
}

.button-primary.is-focused {
  margin-bottom: 0 !important;
}

.button-primary.is-focused.is-selected {
  outline: 1px solid var(--ui-border-color);
  outline-offset: 0;
}

/* "Locked" (other options after a selection): keep clickable but visually secondary. */
.button-primary.is-locked:not(.is-selected) {
  opacity: 0.9;
  cursor: pointer;
  background: transparent;
  border-color: var(--ui-dim-color);
}

.button-primary.is-locked:not(.is-selected):hover {
  border-color: var(--ui-border-color);
  background: color-mix(in srgb, var(--ui-primary-bg-color) 14%, transparent);
}

/* Selected option = primary fill using themed ui-primary tokens. */
.button-primary.is-selected,
.button-primary.is-selected:disabled,
.button-primary.is-selected:hover,
.button-primary.is-selected:disabled:hover {
  background: var(--ui-primary-bg-color) !important;
  color: var(--ui-on-primary-color) !important;
  border-color: var(--ui-primary-bg-color) !important;
  opacity: 1 !important;
  cursor: pointer !important;
}

/* ===== PRINT STYLES ===== */

@media print {
  /* Compact, sheet-focused layout */
  html,
  body {
    margin: 0;
    padding: 0;
    background: #fff;
    color: #000;
    font-size: 12px;
  }

  /* Don't force a full viewport-height page before content */
  body {
    min-height: 0 !important;
  }

  /* Hide global chrome: headers, footers, sidebars, modals */
  .terminal-header,
  .terminal-footer,
  .left-panel,
  .welcome-modal,
  .modal,
  .terminal-status {
    display: none !important;
  }

  /* Layout containers expand naturally and don't clip content */
  .terminal-frame,
  .terminal-container,
  .manager-screen,
  .split-layout,
  .left-panel,
  .right-panel {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
    border: none;
    box-shadow: none;
    padding: 0;
  }

  .character-sheet {
    background: #fff;
    color: #000;
    box-shadow: none;
    border: none;
    width: 100%;
    margin: 0 !important;
  }

  /* Force all text inside the sheet to print as black for maximum legibility */
  .character-sheet,
  .character-sheet * {
    color: #000 !important;
  }
  
  /* For print, prefer the original DALL-E image instead of ASCII:
     - Hide ASCII block
     - Show original image even if it was hidden on screen */
  .character-sheet .ascii-portrait {
    display: none !important;
  }

  .character-sheet .original-portrait {
    display: block !important;
    visibility: visible !important;
    max-width: 100%;
    height: auto;
  }

  /* Denser grids for combat stats and abilities in print */
  .character-sheet .stat-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
  }

  .character-sheet .ability-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
  }

  /* Keep whole sections together on a page and tighten spacing */
  .character-sheet .sheet-section {
    page-break-inside: avoid;
    margin-bottom: 8px;
    padding-bottom: 4px;
  }

  .character-sheet .sheet-header {
    padding-bottom: 2px;
    margin-bottom: 2px;
  }

  .character-sheet .sheet-header-title {
    font-size: 0.9em;
  }

  /* Hide sheet header buttons (PRINT/RENAME/EDIT/etc.) in printout */
  .sheet-title-actions,
  .sheet-title-actions *,
  .sheet-title-buttons,
  .sheet-title-buttons * {
    display: none !important;
  }
}

/* ===== MODAL BASE ===== */
.modal {
  display: none;
  /* Confine modal overlay to the bounds of the terminal container instead of the full viewport.
     The nearest positioned ancestor (e.g., .terminal-frame / .terminal-container) acts as the
     containing box. */
  position: absolute;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 1000;
  /* Keep background dimmed but sharp — no blur */
  backdrop-filter: none;
  /* Modal-specific UI tokens (yellow theme) */
  --ui-border-color: var(--modal-accent);
  --ui-fg-color: var(--modal-accent);
  --ui-dim-color: var(--modal-accent-dim);
  --ui-primary-bg-color: var(--modal-accent);
  --ui-on-primary-color: var(--terminal-bg);
  /* Yellow-themed scrollbars inside modals */
  --scrollbar-track-color: hsl(var(--theme-yellow-h), 100%, 5%);
  --scrollbar-thumb-color: hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.6);
  --scrollbar-thumb-hover-color: hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.9);
}

.modal.show {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Fade the dimmed overlay in when the modal opens */
  animation: modal-overlay-open 220ms cubic-bezier(0.2, 0.8, 0.2, 1.05) forwards;
}

.modal.show.closing {
  /* Keep layout active while close animation runs */
  display: flex;
  /* Fade the dimmed overlay out as the modal collapses */
  animation: modal-overlay-close 200ms cubic-bezier(0.2, 0.8, 0.2, 1.05) forwards;
}

.modal-content {
  background-color: var(--terminal-bg);
  border: 2px solid var(--modal-accent);
  border-radius: 4px;
  max-width: 700px;
  width: 90%;
  /* Keep the modal fully within the terminal frame, even on short viewports.
     Height is constrained relative to the terminal container (via .modal),
     with internal scrolling handled by .modal-body. */
  max-height: calc(100% - 48px);
  box-shadow: 0 20px 60px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.35);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform-origin: center center;
}

/* Modal open animation:
   - Mirrors selector listbox behavior: scaleY from center + fade in
   - Applied whenever a modal gains the .show class
   - Disabled while the modal is in the .closing state so the close animation
     can take over cleanly. */
.modal.show:not(.closing) .modal-content {
  animation: modal-open 220ms cubic-bezier(0.2, 0.8, 0.2, 1.05) forwards;
}

/* Modal close animation:
   - Reverse of modal-open
   - Shrinks back toward the center when the modal is closing */
.modal.show.closing .modal-content {
  animation: modal-close 200ms cubic-bezier(0.2, 0.8, 0.2, 1.05) forwards;
}

.modal-header {
  padding: var(--spacing-lg) var(--spacing-lg) var(--spacing-sm) var(--spacing-lg);
  border-bottom: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-title {
  font-size: var(--font-size-large);
  color: var(--modal-accent);
  font-weight: normal;
}

.modal-close {
  background: none;
  border: none;
  color: var(--modal-accent);
  font-size: 20px;
  cursor: pointer;
  padding: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all var(--transition-speed);
}

.modal-close:hover {
  color: var(--modal-accent);
  transform: rotate(90deg);
}

.modal-body {
  padding: 24px;
  flex: 1 1 auto;
  overflow-y: auto;
}

.modal-footer {
  padding: var(--spacing-lg);
  border-top: none;
  display: flex;
  gap: var(--spacing-sm);
  justify-content: flex-end;
}

/* Modal-specific text theming (yellow) */
.modal .terminal-text,
.modal .terminal-text-accent {
  color: var(--modal-accent);
  /* Match global body-copy spacing inside modals as well */
  margin-bottom: var(--spacing-md);
}

.modal .terminal-text-small,
.modal .terminal-text-dim {
  color: var(--modal-accent-dim);
}

/* Extra breathing room for portrait prompt subhead above textarea */
.modal .portrait-modal-subhead {
  margin-bottom: var(--spacing-md);
}

/* Modal-specific input theming (yellow) */
.modal .terminal-input,
.modal .terminal-textarea,
.modal .terminal-select {
  border-color: hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.6);
  color: var(--modal-accent);
}

.modal .terminal-input::placeholder,
.modal .terminal-textarea::placeholder {
  color: var(--modal-accent-dim);
}

.modal .terminal-input:focus,
.modal .terminal-textarea:focus,
.modal .terminal-select:focus {
  border-color: var(--modal-accent);
  box-shadow: 0 0 5px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.5);
}

/* Modal primary buttons: use the same invert-on-hover behavior as other
   primary CTAs (e.g., "+ NEW CHARACTER"), but add a subtle yellow glow. */
.modal .terminal-btn-primary:hover:not(:disabled) {
  box-shadow: 0 0 15px hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.5);
}

/* Modal secondary/cancel buttons: use modal-yellow hover treatment instead of
   the default terminal green background so they respect the modal color theme. */
.modal .terminal-btn:hover:not(:disabled):not(.terminal-btn-primary):not(.terminal-btn-warning):not(.terminal-btn-danger) {
  background-color: hsla(var(--theme-yellow-h), var(--theme-yellow-s), var(--theme-yellow-l-dim), 0.12);
  border-color: var(--ui-fg-color);
  color: var(--ui-fg-color);
}

/* ===== TYPOGRAPHY ===== */
.terminal-text {
  color: var(--terminal-fg);
  /* Add consistent paragraph-style spacing below body-copy text */
  margin-bottom: var(--spacing-md);
}

.terminal-text-dim {
  color: var(--terminal-dim);
}

.terminal-text-accent {
  color: var(--terminal-accent);
}

.terminal-text-warning {
  color: var(--terminal-warning);
}

.terminal-text-error {
  color: var(--terminal-error);
}

/* Accent + weight emphasis */
.terminal-text-strong {
  color: var(--terminal-accent);
  font-weight: bold;
}

.terminal-text-small {
  font-size: var(--font-size-small);
}

.terminal-text-large {
  font-size: var(--font-size-base);
}

/* ===== UTILITY CLASSES ===== */
.cursor-pointer {
  cursor: pointer;
}

.text-center {
  text-align: center;
}

.hidden {
  display: none;
}

.show {
  display: block;
}

/* ===== SHARED ANIMATIONS ===== */
@keyframes blink {
  0%, 50% {
    opacity: 1;
  }
  51%, 100% {
    opacity: 0;
  }
}

/* Modal open animation: expand vertically from center, similar to selector listboxes */
@keyframes modal-open {
  0% {
    transform: scaleY(0.15);
    opacity: 0;
  }
  100% {
    transform: scaleY(1);
    opacity: 1;
  }
}

/* Modal close animation: shrink vertically back toward center */
@keyframes modal-close {
  0% {
    transform: scaleY(1);
    opacity: 1;
  }
  100% {
    transform: scaleY(0.15);
    opacity: 0;
  }
}

/* Overlay open/close animations:
   - Keep the background dimmer in sync with the modal content animation
   - Open: fade from transparent to 60% black
   - Close: fade back to transparent as the modal collapses */
@keyframes modal-overlay-open {
  0% {
    background-color: rgba(0, 0, 0, 0);
  }
  100% {
    background-color: rgba(0, 0, 0, 0.6);
  }
}

@keyframes modal-overlay-close {
  0% {
    background-color: rgba(0, 0, 0, 0.6);
  }
  100% {
    background-color: rgba(0, 0, 0, 0);
  }
}

/* Background glow hue animation:
   - Start from terminal green (120°)
   - Rotate hue toward teal (~180°)
   - Then toward yellow (~60°)
   - Back to green */
@keyframes terminal-glow-hue-cycle {
  0%, 20% {
    filter: hue-rotate(0deg);
  }
  33%, 53% {
    /* Approx. teal/cyan */
    filter: hue-rotate(60deg);
  }
  66%, 86% {
    /* Approx. yellow */
    filter: hue-rotate(-60deg);
  }
  100% {
    filter: hue-rotate(0deg);
  }
}

/* ===== RESPONSIVE BASE ===== */
@media (max-width: 768px) {
  body {
    padding: var(--spacing-md);
  }
  
  .terminal-frame,
  .terminal-container {
    border-radius: 8px;
    height: calc(100vh - 32px);
  }
  
  .terminal-header {
    padding: var(--spacing-sm);
  }
  
  .terminal-title {
    font-size: var(--font-size-base);
  }
  
  .button-group {
    flex-direction: column;
  }

  .splash-content {
    flex-direction: column;
    gap: var(--spacing-xl);
    padding: var(--spacing-lg);
  }
  
  .splash-art {
    font-size: 2px;
    max-height: 40vh;
  }
  
  .splash-text {
    align-items: center;
    text-align: center;
  }
}

/* ===== SPINNER CUBE (shared snippet) =====
   Usage:
   <div class="spinner-cube-scene">
     <div class="spinner-cube-tilt">
       <div class="spinner-cube">
         <div class="spinner-cube-face spinner-cube-face-front"></div>
         <div class="spinner-cube-face spinner-cube-face-back"></div>
         <div class="spinner-cube-face spinner-cube-face-right"></div>
         <div class="spinner-cube-face spinner-cube-face-left"></div>
         <div class="spinner-cube-face spinner-cube-face-top"></div>
         <div class="spinner-cube-face spinner-cube-face-bottom"></div>
       </div>
     </div>
   </div>

   Per-instance overrides (optional):
   <div
     class="spinner-cube-scene"
     style="
       --spinner-cube-size: 16px;
       --spinner-cube-perspective: 40px;
       --spinner-cube-border-width: 1px;
       --spinner-cube-speed: 1.2s;
       --spinner-cube-tilt-x: 0deg;
       --spinner-cube-tilt-y: 0deg;
       --spinner-cube-fill-opacity: 0.08;
     "
   >
   */

:root {
  /* Cube size scales with font-size using em units so it looks consistent
     across different text sizes (narrator vs portrait sections) */
  --spinner-cube-size: 0.75em;
  --spinner-cube-depth: calc(var(--spinner-cube-size) / 2);
  --spinner-cube-border-width: 0.5px;
  /* Default perspective for spinner cubes (matches comparison row #6) */
  --spinner-cube-perspective: 20px;
  --spinner-cube-speed: 1s;
  --spinner-cube-tilt-x: 0deg;
  --spinner-cube-tilt-y: 0deg;
  --spinner-cube-fill-opacity: 0.05;
}

.spinner-cube-scene {
  width: calc(var(--spinner-cube-size) * 3);
  height: calc(var(--spinner-cube-size) * 3);
  perspective: var(--spinner-cube-perspective);
  perspective-origin: center center;
  display: inline-block;
  vertical-align: middle;
  /* Unified inline spacing between cube and following text */
  margin-right: 0.25em;
  /* Force GPU acceleration and own compositing layer */
  will-change: transform;
  transform-style: preserve-3d;
  position: relative;
  /* Keep cube vertically centered relative to surrounding text */
  transform: translateY(0);
}

.spinner-cube-scene > * {
  transform-style: preserve-3d;
}

.spinner-cube-tilt {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  transform-style: preserve-3d;
  position: relative;
}

.spinner-cube {
  width: var(--spinner-cube-size);
  height: var(--spinner-cube-size);
  position: relative;
  transform-style: preserve-3d;
  /* Rotate around the center of the cube (50% 50% 0) which is already
     centered in the tilt container by flexbox */
  transform-origin: 50% 50% 0;
  animation: spinner-cube-spin var(--spinner-cube-speed) linear infinite;
}

.spinner-cube-face {
  position: absolute;
  width: var(--spinner-cube-size);
  height: var(--spinner-cube-size);
  /* Use the current UI foreground color when available (sheet teal, modal yellow, etc.),
     falling back to terminal accent green. */
  border: var(--spinner-cube-border-width) solid var(--ui-fg-color, var(--terminal-accent));
  box-sizing: border-box;
  background: color-mix(
    in srgb,
    var(--ui-fg-color, var(--terminal-accent)) calc(var(--spinner-cube-fill-opacity) * 100%),
    transparent
  );
  box-shadow:
    inset 0 0 12px color-mix(in srgb, var(--ui-fg-color, var(--terminal-accent)) 35%, transparent),
    0 0 8px color-mix(in srgb, var(--ui-fg-color, var(--terminal-accent)) 30%, transparent);
}

.spinner-cube-face-front {
  transform: translateZ(var(--spinner-cube-depth));
}

.spinner-cube-face-back {
  transform: rotateY(180deg) translateZ(var(--spinner-cube-depth));
}

.spinner-cube-face-right {
  transform: rotateY(90deg) translateZ(var(--spinner-cube-depth));
}

.spinner-cube-face-left {
  transform: rotateY(-90deg) translateZ(var(--spinner-cube-depth));
}

.spinner-cube-face-top {
  transform: rotateX(90deg) translateZ(var(--spinner-cube-depth));
}

.spinner-cube-face-bottom {
  transform: rotateX(-90deg) translateZ(var(--spinner-cube-depth));
}

@keyframes spinner-cube-spin {
  from {
    transform: rotateY(0deg);
  }
  to {
    transform: rotateY(360deg);
  }
}

/* Cube spinner maintains consistent 8px right margin in all contexts */

/* Global overrides for cube defaults – ensure all loaders share a stable,
   centered 3D geometry even when earlier variables are missing or invalid. */
:root {
  --spinner-cube-size: 0.75em;
  --spinner-cube-depth: calc(var(--spinner-cube-size) / 2);
  --spinner-cube-border-width: 0.5px;
  --spinner-cube-perspective: 32px;
  --spinner-cube-speed: 1s;
  --spinner-cube-tilt-x: 0deg;
  --spinner-cube-tilt-y: 0deg;
  --spinner-cube-fill-opacity: 0.05;
}

/* Keep the cube vertically centered relative to the text baseline. This
   only adjusts the offset; width/height and other properties come from
   the main .spinner-cube-scene rule above. */
.spinner-cube-scene {
  transform: translateY(0);
}

/* Final fallback for cube variables using a valid :root selector so that
   all loaders (builder, manager, and demos) share the same geometry. */
:root {
  --spinner-cube-size: 0.75em;
  --spinner-cube-depth: calc(var(--spinner-cube-size) / 2);
  --spinner-cube-border-width: 0.5px;
  --spinner-cube-perspective: 32px;
  --spinner-cube-speed: 1s;
  --spinner-cube-tilt-x: 0deg;
  --spinner-cube-tilt-y: 0deg;
  --spinner-cube-fill-opacity: 0.05;
}

:root {
  --spinner-cube-size: 0.75em;
  --spinner-cube-depth: calc(var(--spinner-cube-size) / 2);
  --spinner-cube-border-width: 0.5px;
  --spinner-cube-perspective: 32px;
  --spinner-cube-speed: 1s;
  --spinner-cube-tilt-x: 0deg;
  --spinner-cube-tilt-y: 0deg;
  --spinner-cube-fill-opacity: 0.05;
}

