/* ============================================================
   Phosphor — style.css
   Phosphor Amber theme ( swap --fg / --glow for green below )
   ============================================================ */

/* ── Local font ─────────────────────────────────────────────
   VT323 shipped locally; no CDN dependency.
   ─────────────────────────────────────────────────────────── */
@font-face {
  font-family: "VT323";
  font-style:  normal;
  font-weight: 400;
  font-display: block;
  src: url("fonts/VT323.woff2") format("woff2");
}

/* ── Theme Variables ────────────────────────────────────────
   To switch to Green phosphor, change:
     --fg:   #33ff77
     --glow: rgba(51, 255, 119, 0.55)
     --glow-soft: rgba(51, 255, 119, 0.20)
   ─────────────────────────────────────────────────────────── */
:root {
  --bg:          #0a0800;          /* near-black with warm tint  */
  --fg:          #ffb000;          /* amber phosphor             */
  --fg-dim:      #c08000;          /* dimmed amber for secondary */
  --fg-bright:   #ffd050;          /* highlights / headings      */
  --glow:        rgba(255, 176, 0, 0.60);
  --glow-soft:   rgba(255, 176, 0, 0.22);
  --scanline-bg: rgba(0, 0, 0, 0.10);
  --cursor-char: "_";
  --font-stack:  "VT323", "Courier New", Courier, monospace;
  --font-size:   20px;             /* default terminal size      */
  --dial-font-size: var(--font-size);
  --line-height: 1.45;
  --dial-tile-width: 4.8em;
}

/* ── Themed text selection ───────────────────────────────────── */
::selection {
  background: var(--fg);
  color: var(--bg);
  text-shadow: none;
}

::-moz-selection {
  background: var(--fg);
  color: var(--bg);
  text-shadow: none;
}

/* ── Reset / Base ───────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  line-height: var(--line-height);
  overflow: hidden;           /* terminal owns the scroll */
}

/* ── Blinking Cursor ────────────────────────────────────────── */
@keyframes blink {
  0%, 49%  { opacity: 1; }
  50%, 100%{ opacity: 0; }
}

.blink {
  animation: blink var(--cursor-blink-speed, 1.1s) step-end infinite;
}

/* ── CRT Power-Off Animation ───────────────────────────────── */
/*
   Stages:
     0  –  12%  : dim + brightness surge  (capacitor discharge)
    12  –  45%  : vertical collapse → thin horizontal scan line
    45  –  68%  : scan line contracts horizontally → single dot
    68  –  84%  : dot over-brightens (phosphor persistence)
    84  – 100%  : dot fades to black
*/
@keyframes crt-poweroff {
  0%   { opacity: 1;    transform: scaleY(1)     scaleX(1);      filter: brightness(1)    blur(0px);  }
  5%   { opacity: 1;    transform: scaleY(1.03)  scaleX(1);      filter: brightness(2.2)  blur(0px);  }
  12%  { opacity: 0.95; transform: scaleY(0.88)  scaleX(1);      filter: brightness(1.5)  blur(0px);  }
  28%  { opacity: 0.9;  transform: scaleY(0.09)  scaleX(1);      filter: brightness(3)    blur(1px);  }
  45%  { opacity: 1;    transform: scaleY(0.009) scaleX(1);      filter: brightness(6)    blur(2px);  }
  58%  { opacity: 1;    transform: scaleY(0.009) scaleX(0.12);   filter: brightness(9)    blur(3px);  }
  68%  { opacity: 1;    transform: scaleY(0.009) scaleX(0.012);  filter: brightness(14)   blur(4px);  }
  80%  { opacity: 0.9;  transform: scaleY(0.009) scaleX(0.012);  filter: brightness(20)   blur(5px);  }
  92%  { opacity: 0.1;  transform: scaleY(0.004) scaleX(0.006);  filter: brightness(0)    blur(1px);  }
  100% { opacity: 0;    transform: scaleY(0)     scaleX(0);      filter: brightness(0)    blur(0px);  }
}

.crt-poweroff {
  animation: crt-poweroff 1.6s ease-in forwards;
  transform-origin: center center;
  pointer-events: none;
}

/* ── CRT Screen-Wipe Glitch ─────────────────────────────────── */
@keyframes crt-wipe {
  0%   { opacity: 1;    transform: scaleY(1)    skewX(0deg);   filter: brightness(1)   blur(0px); }
  15%  { opacity: 0.85; transform: scaleY(0.96) skewX(-1.5deg); filter: brightness(2.2) blur(1px); }
  30%  { opacity: 0.3;  transform: scaleY(0.05) skewX(0deg);   filter: brightness(4)   blur(2px); }
  50%  { opacity: 0;    transform: scaleY(0)    skewX(0deg);   filter: brightness(0)   blur(0px); }
  65%  { opacity: 0;    transform: scaleY(0)    skewX(0deg);   filter: brightness(0)   blur(0px); }
  75%  { opacity: 0.25; transform: scaleY(0.04) skewX(1deg);   filter: brightness(3)   blur(1px); }
  88%  { opacity: 0.7;  transform: scaleY(0.92) skewX(-0.5deg);filter: brightness(1.5) blur(0px); }
  100% { opacity: 1;    transform: scaleY(1)    skewX(0deg);   filter: brightness(1)   blur(0px); }
}

.crt-wipe {
  animation: crt-wipe 0.3s steps(1, end);
  transform-origin: center center;
}

/* ── Scanlines Overlay ──────────────────────────────────────── */
#scanlines {
  pointer-events: none;
  position: fixed;
  inset: 0;
  z-index: 100;
  /* repeating horizontal stripes every 4px → 1px dark line + 3px gap
     4px period avoids resonance with common character heights (8/12/16px) */
  background: repeating-linear-gradient(
    to bottom,
    transparent            0px,
    transparent            3px,
    var(--scanline-bg)     3px,
    var(--scanline-bg)     4px
  );
}

/* ── CRT Vignette ───────────────────────────────────────────── */
/* Dark edges fading inwards — simulates CRT screen curvature.  */
#scanlines::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse at center,
    transparent            55%,
    rgba(0, 0, 0, 0.18)   75%,
    rgba(0, 0, 0, 0.42)   100%
  );
}

/* ── Terminal Container ─────────────────────────────────────── */
#terminal {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100vh;
  max-width: 960px;
  margin: 0 auto;
  padding: 1rem 1.5rem 0.75rem;
  /* Subtle CRT flicker — near-imperceptible brightness wobble adds life */
  animation: crt-flicker 8s linear infinite;
}

/* ── CRT Subtle Flicker ─────────────────────────────────────── */
@keyframes crt-flicker {
  0%   { opacity: 1;      }
  4%   { opacity: 0.983;  }
  8%   { opacity: 1;      }
  42%  { opacity: 0.99;   }
  44%  { opacity: 1;      }
  78%  { opacity: 0.986;  }
  80%  { opacity: 1;      }
  100% { opacity: 1;      }
}

/* ── Header ─────────────────────────────────────────────────── */
#header {
  flex-shrink: 0;
  padding: 0.35rem 0.45rem 0.5rem;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0.16));
  border: none;
  border-bottom: 1px solid var(--fg-dim);
  box-shadow:
    inset 0 0 18px rgba(0, 0, 0, 0.22),
    0 1px 8px var(--glow-soft);
  margin-bottom: 0.6rem;
}

#banner-row {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
  margin-bottom: 0.45rem;
}

#logo {
  flex-shrink: 0;
  height: 1.1em;
  width: auto;
  margin: 0;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: 0;
  filter:
    drop-shadow(0 0 6px var(--glow-soft))
    drop-shadow(0 0 2px rgba(255, 255, 255, 0.08));
}

#ascii-art {
  flex: 1 1 auto;
  min-width: 0;
  position: relative;
  /* Header banner uses its own measured cell width because fitBanner() sets an
     inline font-size that differs from .banner-output. */
  --banner-cell-w: var(--banner-header-cell-w, 1ch);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.72rem; /* base — fitBanner() scales this to fill the header */
  line-height: 1.02;
  letter-spacing: 0;
  white-space: pre;
  padding: 0.36rem 0.55rem 0.28rem;
  border: none;
  background: transparent;
  overflow-x: hidden;
  overflow-y: visible;
  max-width: 100%;
  margin-bottom: 0;
  text-shadow:
    0 0 2px rgba(0, 0, 0, 0.45),
    0 0 6px var(--glow-soft);
  box-shadow: none;
  opacity: 0.96;
  -webkit-mask-image: none;
  mask-image: none;
  font-kerning: none;
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0, "kern" 0;
  text-rendering: optimizeSpeed;
}

/* The header banner should look identical to the previous plain-text <pre>.
   We only use spans to lock the layout to a stable cell grid. */
#ascii-art .b-cell {
  color: inherit;
  text-shadow: inherit;
  opacity: inherit;
}

#ascii-art::before {
  content: none;
}

#ascii-art::after {
  content: none;
}

/* ── Banner segmented neon cell styling ─────────────────────── */
/* .banner-output is the inline variant rendered by the `banner` command  */
.banner-output {
  font-family: var(--font-stack);
  font-size: clamp(0.34rem, 1vw, 0.52rem);
  line-height: 1.02;
  letter-spacing: 0;
  white-space: pre;
  display: block;
  /* Cell width is measured in JS and stored on :root as --banner-output-cell-w.
     Using px avoids drift when the filled glyph falls back to a different font
     (1ch is based on the primary font's “0” width, not the fallback glyph). */
  --banner-cell-w: var(--banner-output-cell-w, 1ch);
  margin: 0.3rem 0 0.5rem;
  overflow-x: auto;
}

:is(#ascii-art, .banner-output) .b-cell {
  display: inline-block;
  position: relative;
  width: var(--banner-cell-w, 1ch);
  height: 1em;
  line-height: 1;
  vertical-align: top;
  color: var(--fg-bright);
  text-shadow:
    0 0 3px var(--glow),
    0 0 7px var(--glow-soft);
}

:is(#ascii-art, .banner-output) .b-cell.b-empty {
  color: transparent;
  text-shadow: none;
}

:is(#ascii-art, .banner-output) .b-cell.b-core {
  color: var(--fg);
  opacity: 0.96;
}

:is(#ascii-art, .banner-output) .b-cell.b-mid {
  color: var(--fg-bright);
  opacity: 0.94;
  text-shadow:
    0 0 3px var(--glow),
    0 0 8px var(--glow-soft);
}

/* b-edge: one step inside the rim — soft near-white transitioning to theme colour */
:is(#ascii-art, .banner-output) .b-cell.b-edge {
  color: var(--fg-bright);
  opacity: 0.97;
  text-shadow:
    0 0 3px var(--glow),
    0 0 9px var(--glow-soft);
}

:is(#ascii-art, .banner-output) .b-cell.b-rim {
  color: #dff6ff;
  opacity: 0.98;
  text-shadow:
    0 0 2px rgba(223, 246, 255, 0.85),
    0 0 7px var(--glow-soft);
}

:is(#ascii-art, .banner-output) .b-cell.b-node {
  color: #ffffff;
  text-shadow:
    0 0 3px rgba(255, 255, 255, 0.8),
    0 0 8px var(--glow-soft);
}

:is(#ascii-art, .banner-output) .b-cell.has-trace::before {
  display: none;
}

:is(#ascii-art, .banner-output) .b-cell.has-trace::after {
  display: none;
}

:is(#ascii-art, .banner-output) .b-cell.has-trace[data-j="0"]::after {
  display: none;
}

#status-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.2rem 1rem;
  color: var(--fg);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-shadow: 0 0 8px var(--glow-soft);
}

#status-label {
  color: var(--fg);
  opacity: 0.92;
  text-shadow: 0 0 8px var(--glow-soft);
}

#status-time {
  margin-left: auto;
  color: var(--fg-bright);
  font-variant-numeric: tabular-nums;
  text-align: right;
  text-shadow: 0 0 10px var(--glow-soft);
}

/* ── Speed-dial overlay (covers terminal below header) ──────── */
@keyframes dial-overlay-in {
  0%   { opacity: 0;   transform: scaleY(0.04); filter: brightness(4) blur(1px); }
  40%  { opacity: 0.8; transform: scaleY(1.02); filter: brightness(1.3); }
  100% { opacity: 1;   transform: scaleY(1);    filter: brightness(1); }
}

#speed-dial-wrap {
  position: absolute;
  top: var(--dial-overlay-top, 0);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  display: none;
  flex-direction: column;
  background: var(--bg);
  padding: 0 1.5rem 0.75rem;
  overflow-y: auto;
}

#speed-dial-wrap.visible {
  display: flex;
  animation: dial-overlay-in 0.22s ease-out forwards;
}

/* ── Overlay header row ──────────────────────────────────────── */
#dial-overlay-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid var(--fg-dim);
  padding-bottom: 0.4em;
  margin-bottom: 0.6em;
  flex-shrink: 0;
}

#dial-overlay-title {
  font-size: 0.8em;
  color: var(--fg-bright);
  letter-spacing: 0.1em;
  text-shadow: 0 0 8px var(--glow);
}

#dial-overlay-actions {
  display: flex;
  gap: 0.5em;
}

/* ── Shared class for buttons injected into the dial overlay header ── */
.dial-overlay-btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65rem;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

.dial-overlay-btn:hover,
.dial-overlay-btn:focus-visible {
  opacity: 1;
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

#dial-overlay-close {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65rem;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

#dial-overlay-close:hover,
#dial-overlay-close:focus-visible {
  opacity: 1;
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

/* ── [SETTINGS] trigger button in status-line ───────────────── */
#settings-panel-trigger {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65rem;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

#settings-panel-trigger:hover,
#settings-panel-trigger:focus-visible {
  opacity: 1;
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

#settings-panel-trigger.is-active {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  box-shadow: 0 0 6px var(--glow);
}

/* ── [DIALS] trigger button in status-line ───────────────────── */
#dial-overlay-open {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65rem;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

#dial-overlay-open:hover,
#dial-overlay-open:focus-visible {
  opacity: 1;
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

/* ── [EDIT] / [DONE] toggle button ──────────────────────────── */
#dial-edit-toggle {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65em;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

#dial-edit-toggle:hover,
#dial-edit-toggle:focus-visible {
  opacity: 1;
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

#dial-edit-toggle.is-active {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  opacity: 1;
  box-shadow: 0 0 6px var(--glow);
}

/* ── Dial Toolbar ────────────────────────────────────────────── */
#dial-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35em 0.7em;
  padding: 0.42em 0 0.42em;
  border-bottom: 1px solid var(--fg-dim);
  margin-bottom: 0.35em;
}

/* Left / density groups */
.dial-toolbar-group {
  display: flex;
  align-items: center;
  gap: 0.25em;
  flex-shrink: 0;
}

.dial-toolbar-group--density {
  margin-left: auto;
}

/* Action + density stepper buttons share a base style */
.dial-toolbar-btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.68em;
  line-height: 1;
  padding: 0.22em 0.6em;
  cursor: pointer;
  letter-spacing: 0.05em;
  user-select: none;
  white-space: nowrap;
  opacity: 1;
  transition:
    color       0.12s ease,
    border-color 0.12s ease,
    box-shadow  0.12s ease,
    opacity     0.12s ease;
}

.dial-toolbar-btn:hover,
.dial-toolbar-btn:focus-visible {
  color: var(--fg);
  border-color: var(--fg);
  opacity: 1;
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

.dial-toolbar-btn.is-active {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  opacity: 1;
  box-shadow: 0 0 6px var(--glow);
}

/* Narrow ± icon variant */
.dial-toolbar-btn--icon {
  padding: 0.22em 0.42em;
}

/* ── Search wrapper ───────────────────────────────────────────── */
.dial-toolbar-search {
  position: relative;
  flex: 1 1 8em;
  min-width: 5em;
  max-width: 22em;
  display: flex;
  align-items: center;
}

#dial-search-input {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.72em;
  line-height: 1;
  padding: 0.18em 1.4em 0.18em 0;
  outline: none;
  caret-color: var(--fg);
  letter-spacing: 0.04em;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

#dial-search-input::placeholder {
  color: var(--fg-dim);
  opacity: 0.5;
  letter-spacing: 0.07em;
}

#dial-search-input:focus {
  border-bottom-color: var(--fg);
  box-shadow: 0 1px 0 0 var(--glow-soft);
}

/* Clear (×) button inside search */
.dial-search-clear {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.65em;
  cursor: pointer;
  padding: 0 0.2em;
  line-height: 1;
  opacity: 0.6;
  transition: opacity 0.1s ease, color 0.1s ease;
}

.dial-search-clear:hover,
.dial-search-clear:focus-visible {
  opacity: 1;
  color: var(--fg);
  outline: none;
}

/* ── Density label ────────────────────────────────────────────── */
.dial-toolbar-density-label {
  font-family: var(--font-stack);
  font-size: 0.6em;
  color: var(--fg);
  letter-spacing: 0.08em;
  min-width: 4.2em;
  text-align: center;
  user-select: none;
}

/* ── Category chips row ───────────────────────────────────────── */
.dial-toolbar-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.28em;
  align-items: center;
  flex-basis: 100%;   /* force own row inside the flex-wrap toolbar */
  padding-top: 0.08em;
}

.dial-chip {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.61em;
  line-height: 1;
  padding: 0.16em 0.55em;
  cursor: pointer;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  user-select: none;
  opacity: 0.75;
  transition:
    color       0.1s ease,
    border-color 0.1s ease,
    box-shadow  0.1s ease,
    opacity     0.1s ease;
}

.dial-chip:hover,
.dial-chip:focus-visible {
  color: var(--fg);
  border-color: var(--fg);
  opacity: 1;
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

.dial-chip.is-active {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  opacity: 1;
  box-shadow: 0 0 6px var(--glow);
}

/* ── Keys popover ─────────────────────────────────────────── */
.dial-keys-popover {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  z-index: 200;
  display: none;
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.65), 0 0 8px var(--glow-soft);
  padding: 0.55em 0.85em 0.65em;
  min-width: 26em;
  font-family: var(--font-stack);
}

.dial-keys-popover.is-open {
  display: block;
}

.dial-keys-popover__title {
  font-size: 0.6em;
  letter-spacing: 0.12em;
  color: var(--fg-bright);
  margin-bottom: 0.55em;
  padding-bottom: 0.3em;
  border-bottom: 1px solid var(--fg-dim);
}

.dial-keys-popover table {
  border-collapse: collapse;
  width: 100%;
}

.dial-keys-popover tr + tr td {
  border-top: 1px solid color-mix(in srgb, var(--fg-dim) 30%, transparent);
}

.dial-keys-popover__key {
  white-space: nowrap;
  padding: 0.22em 0.9em 0.22em 0;
  vertical-align: middle;
}

.dial-keys-popover__key kbd {
  font-family: var(--font-stack);
  font-size: 0.62em;
  color: var(--fg-bright);
  border: 1px solid var(--fg-dim);
  padding: 0.1em 0.35em;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.dial-keys-popover__action {
  font-size: 0.62em;
  color: var(--fg-dim);
  letter-spacing: 0.04em;
  vertical-align: middle;
}

/* ── Persistent shortcut hint bar ────────────────────────────── */
.dial-toolbar-hint {
  flex-basis: 100%;
  font-family: var(--font-stack);
  font-size: 0.57em;
  color: var(--fg-dim);
  letter-spacing: 0.05em;
  opacity: 0.55;
  padding-top: 0.15em;
  user-select: none;
}

.dial-toolbar-hint kbd {
  font-family: var(--font-stack);
  font-size: 1em;
  color: var(--fg);
  letter-spacing: 0.03em;
}

.dial-toolbar-hint__cmd {
  color: var(--fg);
  font-style: italic;
}

/* ── Speed-dial Grid ────────────────────────────────────────── */
#speed-dial {
  display: flex;
  flex-direction: column;
  font-size: var(--dial-font-size);
  padding: 0.4em 0 0.65em;
  flex: 1 1 auto;
  overflow-y: auto;
}

/* ── Speed-dial Section ─────────────────────────────────────── */
/* Each DialStore category maps to a full-width .dial-section.  */
/* Named categories also get a .dial-group-header above the     */
/* .dial-section-body tile grid.                                */
.dial-section {
  width: 100%;
}

.dial-section-body {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45em;
  padding: 0.1em 0 0.4em;
}

.dial-tile {
  position: relative;       /* anchor for the ✕ remove button */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.28em;
  /* Explicit 4-value padding so bottom always matches top. */
  padding: 0.45em 0.6em 0.45em 0.6em;
  border: 1px solid var(--fg-dim);
  cursor: pointer;
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
  /* Keep every tile the same size (square). */
  height: var(--dial-tile-width);
  aspect-ratio: 1 / 1;
  user-select: none;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, background 0.15s ease,
              box-shadow 0.15s ease;
}

.dial-tile:hover {
  border-color: var(--fg);
  background: color-mix(in srgb, var(--fg) 7%, transparent);
  box-shadow: 0 0 8px var(--glow-soft);
}

.dial-tile:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
  box-shadow: 0 0 6px var(--glow);
}

/* ── Keyboard-reorder flash ─────────────────────────────────── */
/* Fixed amber colour so it always contrasts, regardless of theme */
@keyframes dial-tile-move-flash {
  0%   { outline: 2px solid #ffd050; outline-offset: 3px;
         box-shadow: 0 0 0 3px #ffd050, 0 0 16px rgba(255, 176, 0, 0.70); }
  65%  { outline: 2px solid #ffd050; outline-offset: 3px;
         box-shadow: 0 0 0 3px #ffd050, 0 0 16px rgba(255, 176, 0, 0.70); }
  100% { outline: 2px solid transparent;  outline-offset: 2px;
         box-shadow: none; }
}

.dial-tile--moved {
  animation: dial-tile-move-flash 0.5s ease-out forwards;
}

/* ── "+" Add tile ────────────────────────────────────────────── */
.dial-add-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
  height: var(--dial-tile-width);
  aspect-ratio: 1 / 1;
  border: 1px dashed var(--fg-dim);
  color: var(--fg-dim);
  cursor: pointer;
  user-select: none;
  opacity: 0.55;
  transition: opacity 0.15s ease, border-color 0.15s ease, color 0.15s ease,
              background 0.15s ease;
}

.dial-add-tile:hover,
.dial-add-tile:focus-visible {
  border-color: var(--fg);
  color: var(--fg);
  opacity: 1;
  background: color-mix(in srgb, var(--fg) 7%, transparent);
}

.dial-add-tile:focus-visible {
  outline: 2px solid var(--fg);
  outline-offset: 2px;
  box-shadow: 0 0 6px var(--glow);
}

.dial-add-tile__plus {
  font-size: 1.6em;
  line-height: 1;
  pointer-events: none;
}

/* ── Dial empty state (first-run onboarding) ─────────────────── */
.dial-empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.65em;
  padding: 1.1em 0.2em 1em;
  width: 100%;
}

.dial-empty-state__heading {
  font-family: var(--font-stack);
  font-size: 0.7em;
  letter-spacing: 0.2em;
  color: var(--fg-dim);
  opacity: 0.6;
  margin: 0;
  user-select: none;
}

.dial-empty-state__btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.82em;
  line-height: 1;
  padding: 0.36em 0.9em;
  cursor: pointer;
  letter-spacing: 0.07em;
  opacity: 1;
  transition: color 0.12s ease, border-color 0.12s ease,
              opacity 0.12s ease, box-shadow 0.12s ease;
  user-select: none;
}

.dial-empty-state__btn:hover,
.dial-empty-state__btn:focus-visible {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  opacity: 1;
  outline: none;
  box-shadow: 0 0 6px var(--glow);
}

.dial-empty-state__or {
  font-family: var(--font-stack);
  font-size: 0.62em;
  color: var(--fg-dim);
  opacity: 0.4;
  user-select: none;
  letter-spacing: 0.06em;
}

.dial-empty-state__kbd {
  font-family: var(--font-stack);
  font-size: 0.7em;
  color: var(--fg-dim);
  opacity: 0.7;
  margin: 0;
  letter-spacing: 0.04em;
}

.dial-empty-state__kbd kbd {
  font-family: var(--font-stack);
  font-size: 1em;
  color: var(--fg);
  border: 1px solid var(--fg-dim);
  padding: 0.1em 0.42em;
  letter-spacing: 0.08em;
  background: rgba(255, 255, 255, 0.04);
}

.dial-empty-state__tour-hint {
  font-family: var(--font-stack);
  font-size: 0.65em;
  color: var(--fg-dim);
  opacity: 0.5;
  margin: 0.4em 0 0;
  letter-spacing: 0.04em;
  border-top: 1px solid rgba(var(--fg-dim), 0.15);
  padding-top: 0.55em;
  width: 100%;
}

.dial-empty-state__tour-hint kbd {
  font-family: var(--font-stack);
  font-size: 1em;
  color: var(--fg-dim);
  border: 1px solid currentColor;
  padding: 0.05em 0.35em;
  letter-spacing: 0.08em;
  background: rgba(255, 255, 255, 0.04);
  opacity: 0.85;
}

/* ── Search / filter “no results” placeholder ─────────────── */
.dial-no-results {
  flex: 0 0 100%;
  width: 100%;
  padding: 0.65em 0.2em 0.8em;
  font-family: var(--font-stack);
  font-size: 0.7em;
  color: var(--fg-dim);
  letter-spacing: 0.2em;
  opacity: 0.55;
  user-select: none;
}

/* ── ✕ remove button (visible only in edit mode) ────────────── */
.dial-tile-remove {
  display: none;
  position: absolute;
  top: 2px;
  right: 2px;
  width: 1.15em;
  height: 1.15em;
  padding: 0;
  border: 1px solid var(--fg-dim);
  background: var(--bg);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.68em;
  line-height: 1;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  user-select: none;
  z-index: 20;
  transition: color 0.1s ease, border-color 0.1s ease, box-shadow 0.1s ease;
}

#speed-dial.is-edit-mode .dial-tile-remove {
  display: flex;
  width: 1.45em;
  height: 1.45em;
  font-size: 0.72em;
  border-color: var(--fg);
  color: var(--fg);
}

.dial-tile-remove:hover,
.dial-tile-remove:focus-visible {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  box-shadow: 0 0 4px var(--glow-soft);
  outline: none;
}

/* ── ⇄ move-to-category button (edit mode only) ───────────────── */
/* Mirrors the remove button in style; positioned bottom-left of tile.  */
.dial-tile-move {
  display: none;
  position: absolute;
  bottom: 2px;
  left: 2px;
  width: 1.45em;
  height: 1.45em;
  padding: 0;
  border: 1px solid var(--fg-dim);
  background: var(--bg);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.72em;
  line-height: 1;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  user-select: none;
  z-index: 20;
  transition: color 0.1s ease, border-color 0.1s ease, box-shadow 0.1s ease;
}

/* Only shown when edit mode is active AND multiple categories exist */
#speed-dial.is-edit-mode.has-multi-cats .dial-tile-move {
  display: flex;
}

.dial-tile-move:hover,
.dial-tile-move:focus-visible {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  box-shadow: 0 0 4px var(--glow-soft);
  outline: none;
}

/* Compact layout: shrink to fit shorter row height */
html.dial-layout--compact #speed-dial.is-edit-mode.has-multi-cats .dial-tile-move {
  width: 1.1em;
  height: 1.1em;
  font-size: 0.6em;
  bottom: 1px;
  left: 1px;
}

/* ── Edit mode: grab cursor + subtle pulse on tiles ─────────────── */
#speed-dial.is-edit-mode .dial-tile {
  cursor: grab;
}

#speed-dial.is-edit-mode .dial-tile:active {
  cursor: grabbing;
}

/* ── Manage mode: visible organisation state ─────────────────── */
/* Subtle grid-level indicator */
#speed-dial.is-edit-mode {
  outline: 1px dashed var(--fg-dim);
  outline-offset: 4px;
}

/* Drag-handle indicator — positioned-absolute so it doesn't
   affect the tile's internal flex layout. */
#speed-dial.is-edit-mode .dial-tile::before {
  content: '\283F';  /* \u283F \u22EF braille 2\00D73 dot-grid — universal drag-handle glyph */
  position: absolute;
  left: 3px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.68em;
  line-height: 1;
  color: var(--fg-dim);
  user-select: none;
  pointer-events: none;
  z-index: 6;
}

/* In compact mode the tiles are short rows; keep handle proportional */
html.dial-layout--compact #speed-dial.is-edit-mode .dial-tile::before {
  font-size: 0.6em;
  left: 2px;
}

/* Group-header drag handle + grab cursor in manage mode */
#speed-dial.is-edit-mode .dial-group-header {
  cursor: grab;
}

#speed-dial.is-edit-mode .dial-group-header:active {
  cursor: grabbing;
}

#speed-dial.is-edit-mode .dial-group-header::before {
  content: '\283F';
  font-size: 0.68em;
  color: var(--fg-dim);
  margin-right: 0.25em;
  flex-shrink: 0;
  user-select: none;
  pointer-events: none;
}

/* Suppress hover URL tooltip in manage mode — it clutters the UI */
#speed-dial.is-edit-mode .dial-tile[data-url]:not(.dial-tile--weather)::after {
  display: none;
}

/* ── URL tooltip on hover ───────────────────────────────────── */
.dial-tile[data-url]:not(.dial-tile--weather) {
  position: relative;
}

.dial-tile[data-url]:not(.dial-tile--weather)::after {
  content: attr(data-url);
  position: absolute;
  top: calc(100% + 5px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.62em;
  line-height: 1.35;
  padding: 0.18em 0.55em;
  white-space: nowrap;
  max-width: min(28em, calc(100vw - 2rem));
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;
  z-index: 200;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.55);
}

.dial-tile[data-url]:not(.dial-tile--weather):hover::after {
  opacity: 1;
}

.dial-favicon {
  width: 1em;
  height: 1em;
  display: block;
  image-rendering: -webkit-optimize-contrast;
  filter:
    drop-shadow(0 0 1px rgba(236, 251, 255, 0.85))
    drop-shadow(0 0 4px var(--glow-soft));
}

.dial-favicon[data-broken] {
  display: none;
}

/* ── Letter-box icon (local fallback — no external favicon requests) ── */
.dial-letter-icon {
  width: 1em;
  height: 1em;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78em;
  font-weight: 700;
  line-height: 1;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: none;
  border-radius: 2px;
  /* background-color applied via JS (deterministic per-label colour) */
}

.dial-icon-text {
  width: 1em;
  height: 1em;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2em;
  line-height: 1;
  color: var(--fg-bright);
  text-shadow:
    0 0 1px rgba(236, 251, 255, 0.85),
    0 0 5px var(--glow-soft);
}

.dial-label {
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.88em;
  line-height: 1.05;
  max-width: 100%;
  text-align: center;
  overflow-wrap: normal;
  word-break: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 1.05em;
}

html.dial-size--large .dial-label {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: break-word;
}

/* ── Dial Layout Modes ──────────────────────────────────────── */
/*
 * Three adaptive density modes applied via html.dial-layout--{mode}:
 *
 *   auto        – CSS auto-fill grid; tiles scale to fill available width
 *                 while staying square.  Default mode.
 *   comfortable – Classic square tiles (icon stacked above label).
 *                 Respects --dial-tile-width like the legacy behavior.
 *   compact     – Horizontal bar tiles (small icon + label side-by-side);
 *                 packs many more links per line without shrinking icons.
 */

/* ── Auto: grid auto-fill, tiles expand to fill rows evenly ── */
html.dial-layout--auto .dial-section-body {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--dial-tile-width), 1fr));
}

/* Dividers rely on literal row/column spacing, so auto-grid sections that
   contain them fall back to wrapped tiles. */
html.dial-layout--auto .dial-section-body.dial-section-body--has-divider {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45em;
}

html.dial-layout--auto .dial-tile,
html.dial-layout--auto .dial-add-tile {
  flex: none;
  width: 100%;
  height: auto; /* aspect-ratio: 1/1 from base rule keeps tiles square */
}

html.dial-layout--auto .dial-section-body.dial-section-body--has-divider .dial-tile,
html.dial-layout--auto .dial-section-body.dial-section-body--has-divider .dial-add-tile {
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
}

/* ── Comfortable: explicit square tiles, same as classic layout ── */
/* (The base .dial-tile rules already match comfortable, so we only  */
/*  need to ensure no auto/compact overrides bleed through.)         */
html.dial-layout--comfortable .dial-section-body {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45em;
}

html.dial-layout--comfortable .dial-tile {
  flex-direction: column;
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
  height: var(--dial-tile-width);
  aspect-ratio: 1 / 1;
  padding: 0.45em 0.6em;
  gap: 0.28em;
  justify-content: center;
  align-items: center;
}

html.dial-layout--comfortable .dial-add-tile {
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
  height: var(--dial-tile-width);
  aspect-ratio: 1 / 1;
}

/* ── Compact: horizontal bar tiles — icon left, label right ── */
html.dial-layout--compact .dial-section-body {
  display: flex;
  flex-wrap: wrap;
  gap: 0.28em 0.4em;
}

html.dial-layout--compact .dial-tile {
  flex-direction: row;
  flex: 0 0 auto;
  width: auto;
  min-width: 3.8em;
  max-width: 11em;
  height: 1.85em;
  aspect-ratio: unset;
  padding: 0 0.5em;
  gap: 0.32em;
  justify-content: flex-start;
  align-items: center;
}

/* Shrink icons to fit the narrower row height */
html.dial-layout--compact .dial-favicon,
html.dial-layout--compact .dial-letter-icon {
  width: 0.85em;
  height: 0.85em;
  flex-shrink: 0;
}

html.dial-layout--compact .dial-icon-text {
  font-size: 0.85em;
  width: 0.85em;
  height: 0.85em;
  flex-shrink: 0;
}

html.dial-layout--compact .dial-label {
  font-size: 0.78em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 0;
  text-align: left;
}

html.dial-layout--compact .dial-add-tile {
  flex-direction: row;
  width: auto;
  min-width: 2.5em;
  height: 1.85em;
  aspect-ratio: unset;
  padding: 0 0.6em;
}

html.dial-layout--compact .dial-add-tile__plus {
  font-size: 1em;
}

/* Suppress the hover URL tooltip in compact mode — it overlaps too much */
html.dial-layout--compact .dial-tile[data-url]:not(.dial-tile--weather)::after {
  display: none;
}

/* Weather tiles keep their internal column layout regardless of density */
html.dial-layout--compact .dial-tile--weather {
  flex-direction: column;
  min-width: var(--dial-tile-width);
  max-width: none;
  width: var(--dial-tile-width);
  height: var(--dial-tile-width);
  aspect-ratio: 1 / 1;
  padding: 0.45em 0.6em;
  align-items: stretch;
}

/* Dividers stay full-width in compact mode */
html.dial-layout--compact .dial-divider.row-divider {
  width: 100%;
  flex-shrink: 0;
}

/* Show text cursor on labels while in edit mode to hint they're renameable */
#speed-dial.is-edit-mode .dial-label,
#speed-dial.is-edit-mode .dial-group-label {
  cursor: text;
}

/* ── Manage mode: section-body category drop target ─────────── */
/* Sections receive a visible highlight while a tile hovers over them. */
#speed-dial.is-edit-mode .dial-section-body {
  min-height: 2em;           /* ensure empty body is still catchable area */
  transition: outline 0.1s, background 0.1s;
}

.dial-section-body.is-drop-target {
  outline: 1px dashed var(--fg);
  outline-offset: 3px;
  background: color-mix(in srgb, var(--fg) 5%, transparent);
}

/* ── Manage mode: empty-category drop slot ─────────────────── */
/* Rendered inside every named section body.  Shown only when the  */
/* section has no dial tiles (managed via .dial-section--empty).   */
.dial-section-empty-slot {
  display: none;
  flex: 0 0 100%;
  align-items: center;
  justify-content: center;
  min-height: 2.8em;
  border: 1px dashed var(--fg-dim);
  color: var(--fg-dim);
  font-size: 0.72em;
  letter-spacing: 0.14em;
  user-select: none;
  pointer-events: none;   /* enabled below when in manage mode */
  opacity: 0.55;
  transition: border-color 0.1s ease, color 0.1s ease,
              background 0.1s ease, opacity 0.1s ease;
}

/* Show the slot for empty named sections while manage mode is active */
#speed-dial.is-edit-mode .dial-section--empty .dial-section-empty-slot {
  display: flex;
  pointer-events: auto;
}

/* Drag-over highlight on the empty slot */
.dial-section-empty-slot.is-over {
  border-color: var(--fg-bright);
  color: var(--fg-bright);
  background: color-mix(in srgb, var(--fg) 10%, transparent);
  opacity: 1;
  box-shadow: 0 0 6px var(--glow-soft);
}

/* ── Inline label rename input ──────────────────────────────── */
.dial-label-input {
  display: block;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: inherit;
  line-height: inherit;
  text-align: center;
  text-transform: none;       /* override group-header uppercase */
  width: 100%;
  max-width: 100%;
  padding: 0;
  margin: 0;
  outline: none;
  caret-color: var(--fg);
  text-shadow: 0 0 4px var(--glow-soft);
  box-shadow: 0 2px 0 0 var(--glow-soft);
}

.dial-label-input:focus {
  border-bottom-color: var(--fg-bright);
  box-shadow: 0 2px 6px 0 var(--glow-soft);
  text-shadow: 0 0 6px var(--glow);
}

/* ── Weather Dial tile ──────────────────────────────────────── */
.dial-tile--weather {
  /* Weather tile uses 2 rows: (icon + temp) and location label.
     Stretch horizontally so row 1 can left/right align content.
     Extra vertical padding makes this tile — and therefore its entire
     flex row — slightly taller than the other rows. */
  align-items: stretch;
}

.dial-weather-row1 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  line-height: 1;
  height: 1em;
  min-height: 1em;
  overflow: hidden;
  min-width: 0;
}

.dial-weather-icon {
  font-size: 1em;
  line-height: 1;
  width: 1em;
  height: 1em;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  text-align: left;
  filter: drop-shadow(0 0 4px var(--glow-soft));
}

.dial-weather-temp {
  font-family: var(--font-stack);
  font-size: 0.88em;
  font-weight: 700;
  color: var(--fg-bright);
  text-shadow: 0 0 8px var(--glow);
  line-height: 1;
  min-height: 0;
  min-width: 0;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  text-align: right;
  letter-spacing: 0.05em;
}

/* City name reuses .dial-label */
.dial-tile--weather .dial-label {
  color: var(--fg-dim);
}

/* "updated Xm ago" sub-label */
.dial-weather-updated {
  font-family: var(--font-stack);
  font-size: 0.6em;
  color: var(--fg-dim);
  opacity: 0.55;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.3;
  min-height: 0.8em;
}

/* Subtle pulse while data is being fetched */
@keyframes weather-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.35; }
}

.dial-tile--weather.is-refreshing {
  animation: weather-pulse 1.4s ease-in-out infinite;
}

/* ── Speed-dial Divider ─────────────────────────────────────── */
.dial-divider {
  cursor: grab;
  user-select: none;
  flex-shrink: 0;
  position: relative;
  border-radius: 2px;
  transition: background 0.12s, border-color 0.12s;
}

/* Row divider — spans full width, forces items to next row */
.dial-divider.row-divider {
  width: 100%;
  height: 0.45em;
  border-top: 1px dashed var(--fg-dim);
}

html.dial-layout--auto .dial-divider.row-divider {
  grid-column: 1 / -1;
}

/* Column divider — narrow vertical bar, sits between tiles */
.dial-divider.col-divider {
  width: 0.45em;
  align-self: stretch;
  justify-self: center;
  border-left: 1px dashed var(--fg-dim);
}

/* Shared label base — invisible by default, fades in during drag */
.dial-divider.row-divider::after,
.dial-divider.col-divider::after {
  position: absolute;
  background: var(--bg);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  pointer-events: none;
  letter-spacing: 0.06em;
  opacity: 0;
  transition: color 0.1s, opacity 0.1s;
}

/* Row divider label */
.dial-divider.row-divider::after {
  content: '⟵  ROW  ⟶';
  left: 50%;
  top: 50%;
  transform: translate(-50%, -35%);
  font-size: 0.6em;
  padding: 0 0.28em;
}

/* Column divider label */
.dial-divider.col-divider::after {
  content: 'COL';
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotate(90deg);
  font-size: 0.54em;
  padding: 0 0.18em;
}

/* Labels appear only while a drag is in progress */
#speed-dial.is-dragging-dial .dial-divider::after {
  opacity: 1;
}

.dial-divider:hover {
  background: color-mix(in srgb, var(--fg) 6%, transparent);
}
.dial-divider.row-divider:hover {
  border-top-color: var(--fg);
}
.dial-divider.col-divider:hover {
  border-left-color: var(--fg);
}
#speed-dial.is-dragging-dial .dial-divider:hover::after {
  color: var(--fg);
}

.dial-divider.is-dragging {
  opacity: 0.4;
}

/* ── Speed-dial Group Header ───────────────────────────────── */
.dial-group-header {
  width: 100%;        /* full-width → always starts a new flex row */
  display: flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.18em 0.1em 0.12em;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid var(--fg-dim);
  margin-top: 0.25em;
  color: var(--fg-dim);
  font-size: 0.8em;
  letter-spacing: 0.08em;
  transition: color 0.1s, border-color 0.1s;
}

.dial-group-header:hover,
.dial-group-header:focus-visible {
  color: var(--fg);
  border-bottom-color: var(--fg);
  outline: none;
}

.dial-group-header:focus-visible {
  outline: 1px solid var(--fg);
  outline-offset: 2px;
}

.dial-group-chevron {
  font-size: 0.7em;
  line-height: 1;
  min-width: 0.8em;
  text-align: center;
  flex-shrink: 0;
  transition: color 0.1s;
}

.dial-group-label {
  flex: 1;
  text-transform: uppercase;
  font-family: var(--font-stack);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dial-group-count {
  flex-shrink: 0;
  font-size: 0.85em;
  opacity: 0.7;
}

/* Faded look when the group is collapsed */
.dial-group-header[data-collapsed="1"] {
  opacity: 0.65;
}

/* The tile/header currently being dragged: faded so it reads as "in flight" */
.dial-tile.is-dragging {
  opacity: 0.25;
  outline: 2px dashed var(--fg-dim);
  outline-offset: -2px;
}

/* Empty slot that slides around the grid during a drag to preview placement */
.dial-drag-placeholder {
  flex: 0 0 var(--dial-tile-width);
  width: var(--dial-tile-width);
  height: var(--dial-tile-width);
  border: 2px dashed var(--fg-dim);
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  box-sizing: border-box;
  /* The placeholder is a real drop target during live reordering. */
  pointer-events: auto;
  will-change: transform;
}

.dial-group-header.is-dragging {
  opacity: 0.4;
}

/* Visual cue while a drag hovers over a collapsed header (hover-to-expand). */
.dial-group-header.is-drag-hover {
  color: var(--fg);
  border-bottom-color: var(--fg-bright);
  box-shadow: 0 2px 8px var(--glow-soft);
  transition: color 0.1s, border-color 0.1s, box-shadow 0.15s;
}


.dial-group-add {
  flex-shrink: 0;
  background: none;
  border: 1px solid transparent;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.68em;
  line-height: 1;
  padding: 0.14em 0.42em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 0;
  transition: opacity 0.12s ease, color 0.12s ease, border-color 0.12s ease,
              box-shadow 0.12s ease;
  user-select: none;
}

.dial-group-header:hover .dial-group-add,
.dial-group-header:focus-within .dial-group-add {
  opacity: 0.6;
}

.dial-group-add:hover,
.dial-group-add:focus-visible {
  color: var(--fg);
  border-color: var(--fg-dim);
  opacity: 1 !important;
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

/* ── Drop Indicator ─────────────────────────────────────────── */
.dial-drop-indicator {
  position: fixed;
  z-index: 150;
  display: none;
  top: 0;
  left: 0;
  width: 2px;
  background: var(--fg);
  box-shadow: 0 0 8px var(--glow), 0 0 2px var(--fg);
  border-radius: 1px;
  pointer-events: none;
}

.dial-drop-indicator.visible {
  display: block;
}

/* ── Speed-dial Context Menu ─────────────────────────────────── */
#dial-ctx-menu {
  position: fixed;
  z-index: 200;
  display: none;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--fg);
  min-width: 120px;
  box-shadow: 0 0 16px var(--glow-soft), 0 4px 16px rgba(0, 0, 0, 0.55);
}

#dial-ctx-menu.visible {
  display: flex;
}

.ctx-menu-item {
  background: none;
  border: none;
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  padding: 0.3em 0.9em;
  text-align: left;
  cursor: pointer;
  line-height: var(--line-height);
  transition: background 0.1s ease, color 0.1s ease;
}

.ctx-menu-item:hover,
.ctx-menu-item--has-sub:hover {
  background: color-mix(in srgb, var(--fg) 13%, transparent);
  color: var(--fg-bright);
}

.ctx-menu-item:focus-visible {
  background: color-mix(in srgb, var(--fg) 13%, transparent);
  color: var(--fg-bright);
  outline: 1px solid var(--fg);
  outline-offset: -1px;
}

/* ── Context Menu — Group Submenu ────────────────────────────── */
.ctx-menu-item--has-sub {
  position: relative;
  user-select: none;
  padding: 0;           /* padding lives on the inner span */
}

.ctx-menu-item--has-sub > span {
  display: block;
  padding: 0.3em 0.9em;
  line-height: var(--line-height);
  cursor: pointer;
}

#dial-ctx-group-submenu {
  display: none;
  position: absolute;
  left: 100%;
  right: auto;
  top: 0;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--fg);
  min-width: 130px;
  z-index: 201;
  max-height: 70vh;
  overflow-y: auto;
}

#dial-ctx-group-submenu.visible {
  display: flex;
}

#dial-ctx-group-submenu .ctx-menu-item {
  white-space: nowrap;
}

/* ── Move-to-category picker ─────────────────────────────────── */
/* Compact popup for the ⇄ tile button — avoids needing right-click.  */

#dial-move-picker {
  position: fixed;
  z-index: 210;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--fg);
  min-width: 130px;
  max-height: 50vh;
  overflow-y: auto;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
}

.dial-move-picker__title {
  font-family: var(--font-stack);
  font-size: 0.6em;
  color: var(--fg-dim);
  padding: 0.35em 0.9em 0.25em;
  letter-spacing: 0.12em;
  user-select: none;
  border-bottom: 1px solid var(--fg-dim);
  opacity: 0.7;
}

.dial-move-picker__item {
  background: none;
  border: none;
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  padding: 0.3em 0.9em;
  text-align: left;
  cursor: pointer;
  line-height: var(--line-height);
  white-space: nowrap;
}

.dial-move-picker__item:hover,
.dial-move-picker__item:focus-visible {
  background: color-mix(in srgb, var(--fg) 13%, transparent);
  color: var(--fg-bright);
  outline: none;
}

/* ── Inline Dial Composer ────────────────────────────────────── */
/* Inline card that replaces the modal add-dial dialog.          */

.dial-composer {
  display: flex;
  align-items: flex-start;
  gap: 0.65em;
  padding: 0.5em 0.6em;
  border: 1px solid var(--fg-dim);
  background: var(--bg);
  margin-bottom: 0.45em;
  animation: dial-composer-in 0.12s ease;
}

@keyframes dial-composer-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Icon preview — mirrors a dial tile's icon area */
.dial-composer-preview {
  flex-shrink: 0;
  width: var(--dial-tile-width, 5em);
  height: var(--dial-tile-width, 5em);
  border: 1px solid var(--fg-dim);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: transparent;
}

.dial-composer-preview__none {
  font-family: var(--font-stack);
  font-size: 1.1em;
  color: var(--fg-dim);
  opacity: 0.35;
  user-select: none;
}

/* Input column */
.dial-composer-inputs {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.32em;
  min-width: 0;
}

.dial-composer-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  align-items: center;
}

/* All text inputs share an underline style */
.dial-composer-url,
.dial-composer-label,
.dial-composer-icon {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.72em;
  line-height: 1;
  padding: 0.18em 0.1em;
  outline: none;
  caret-color: var(--fg);
  letter-spacing: 0.03em;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.dial-composer-url   { flex: 2 1 11em; }
.dial-composer-label { flex: 1 1  7em; }
.dial-composer-icon  { flex: 2 1 11em; }

.dial-composer-url::placeholder,
.dial-composer-label::placeholder,
.dial-composer-icon::placeholder {
  color: var(--fg-dim);
  opacity: 0.5;
  letter-spacing: 0.06em;
}

.dial-composer-url:focus,
.dial-composer-label:focus,
.dial-composer-icon:focus {
  border-bottom-color: var(--fg);
  box-shadow: 0 1px 0 0 var(--glow-soft);
}

/* Category dropdown */
.dial-composer-cat {
  flex: 1 1 6em;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg-dim);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.68em;
  padding: 0.18em 0.1em;
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.12s ease;
}

.dial-composer-cat:focus {
  border-bottom-color: var(--fg);
  color: var(--fg);
  outline: none;
}

/* Actions row */
.dial-composer-actions {
  flex-wrap: nowrap;
  margin-top: 0.08em;
}

.dial-composer-error {
  flex: 1;
  font-family: var(--font-stack);
  font-size: 0.65em;
  color: #e06c75;
  min-height: 1em;
  line-height: 1.3;
}

.dial-composer-btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.68em;
  line-height: 1;
  padding: 0.2em 0.58em;
  cursor: pointer;
  letter-spacing: 0.05em;
  user-select: none;
  white-space: nowrap;
  transition: color 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}

.dial-composer-btn:hover,
.dial-composer-btn:focus-visible {
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

.dial-composer-btn--save {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  box-shadow: 0 0 4px var(--glow-soft);
}

.dial-composer-btn--save:hover,
.dial-composer-btn--save:focus-visible {
  box-shadow: 0 0 8px var(--glow);
}

/* ── Advanced side-sheet ─────────────────────────────────────────────────── */
.dial-side-sheet {
  position: fixed;
  inset: 0;
  z-index: 300;
  pointer-events: none;
}

.dial-side-sheet.is-open {
  pointer-events: auto;
}

.dial-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 0.18s ease;
}

.dial-side-sheet.is-open .dial-sheet-backdrop {
  opacity: 1;
}

.dial-sheet-panel {
  position: absolute;
  right: 0;
  top: 0;
  height: 100%;
  width: 22em;
  max-width: 88vw;
  background: var(--bg);
  border-left: 1px solid var(--fg);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.18s ease;
  overflow-y: auto;
}

.dial-side-sheet.is-open .dial-sheet-panel {
  transform: translateX(0);
}

.dial-sheet-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.7em 1em;
  border-bottom: 1px solid var(--fg-dim);
  gap: 0.5em;
}

.dial-sheet-title {
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  letter-spacing: 0.12em;
  text-shadow: 0 0 8px var(--glow);
  flex: 1;
}

.dial-sheet-close {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  cursor: pointer;
  padding: 0.15em 0.55em;
  letter-spacing: 0.05em;
  flex-shrink: 0;
}

.dial-sheet-close:hover {
  border-color: var(--fg);
  color: var(--fg-bright);
}

.dial-sheet-body {
  padding: 1em;
  display: flex;
  flex-direction: column;
  gap: 0.75em;
  flex: 1;
}

.dial-sheet-field {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
}

.dial-sheet-label {
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.72em;
  letter-spacing: 0.1em;
}

.dial-sheet-input {
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  padding: 0.3em 0.5em;
  outline: none;
  width: 100%;
  box-sizing: border-box;
}

.dial-sheet-input:focus {
  border-color: var(--fg);
}

.dial-sheet-actions {
  display: flex;
  gap: 0.5em;
}

.dial-sheet-error {
  color: #e06c75;
  font-size: 0.78em;
  min-height: 1em;
}

.dial-sheet-danger {
  margin-top: auto;
  padding-top: 1em;
  border-top: 1px solid #7a2a2a;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
}

.dial-sheet-danger-desc {
  color: var(--fg-dim);
  font-size: 0.78em;
  line-height: 1.4;
}

/* Shared button styles used by both the side sheet and old helper fns */
.dial-edit-btn--delete {
  border-color: #7a2a2a;
  color: #c97070;
}

.dial-edit-btn--delete:hover {
  border-color: #e06c75;
  color: #e06c75;
}

.dial-edit-btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  padding: 0.25em 0.85em;
  cursor: pointer;
  letter-spacing: 0.05em;
}

.dial-edit-btn:hover {
  border-color: var(--fg);
  color: var(--fg-bright);
}

/* ── Tile / header advanced button ([···]) ──────────────────────────────── */
.dial-tile-advanced {
  display: none;
  position: absolute;
  bottom: 2px;
  right: 2px;
  background: none;
  border: 1px solid transparent;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.62em;
  line-height: 1;
  padding: 0.1em 0.3em;
  cursor: pointer;
  letter-spacing: 0.04em;
  user-select: none;
}

.dial-group-advanced {
  display: none;
  background: none;
  border: 1px solid transparent;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.72em;
  padding: 0.15em 0.45em;
  cursor: pointer;
  letter-spacing: 0.04em;
  user-select: none;
}

#speed-dial.is-edit-mode .dial-tile-advanced,
#speed-dial.is-edit-mode .dial-group-advanced {
  display: inline-flex;
  align-items: center;
}

.dial-tile-advanced:hover,
.dial-group-advanced:hover {
  color: var(--fg);
  border-color: var(--fg-dim);
}

/* ── Settings Panel (modal overlay — matches #dial-edit-dialog) ── */
#settings-panel {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.72);
}

#settings-panel.visible {
  display: flex;
}

.settings-inner {
  background: var(--bg);
  border: 1px solid var(--fg);
  padding: 0.75rem 1rem 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 22em;
  max-width: calc(100vw - 2rem);
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  box-shadow: 0 0 24px var(--glow-soft), 0 4px 20px rgba(0, 0, 0, 0.5);
}

.settings-title {
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  letter-spacing: 0.1em;
  text-shadow: 0 0 8px var(--glow);
  margin-bottom: 0.2rem;
}

.settings-row {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.settings-label {
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  flex: 0 0 16ch;
  width: 16ch;
  min-width: 16ch;
  white-space: nowrap;
  letter-spacing: 0.06em;
}

.settings-select,
.settings-input {
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  padding: 0.2rem 0.5rem;
  outline: none;
}

.settings-select:focus,
.settings-select:focus-visible,
.settings-input:focus,
.settings-input:focus-visible {
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

.settings-input {
  flex: 1;
}


.settings-actions {
  display: flex;
  gap: 0.55rem;
  justify-content: flex-end;
  margin-top: 0.15rem;
}

.settings-btn {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  padding: 0.25rem 0.85rem;
  cursor: pointer;
  letter-spacing: 0.05em;
}

.settings-btn:hover,
.settings-btn:focus-visible {
  border-color: var(--fg);
  color: var(--fg-bright);
  outline: none;
  box-shadow: 0 0 6px var(--glow-soft);
}

/* ── Settings panel — onboarding hint block ─────────────────── */
.settings-onboarding-hint {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  margin-top: 0.35rem;
  padding-top: 0.6rem;
  font-family: var(--font-stack);
}

.settings-onboarding-hint__label {
  font-size: 0.62em;
  color: var(--fg-dim);
  letter-spacing: 0.18em;
  opacity: 0.55;
  margin-bottom: 0.1em;
}

.settings-onboarding-hint span:not(.settings-onboarding-hint__label) {
  font-size: 0.7em;
  color: var(--fg-dim);
  letter-spacing: 0.04em;
  opacity: 0.6;
  line-height: 1.3;
}

/* ── Output Area ────────────────────────────────────────────── */
#output {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0.4rem 0;
  scroll-behavior: smooth;
  /* hide scrollbar track on Chrome; keep scrollability */
  scrollbar-width: thin;
  scrollbar-color: var(--fg-dim) transparent;
}

#output::-webkit-scrollbar        { width: 6px; }
#output::-webkit-scrollbar-track  { background: transparent; }
#output::-webkit-scrollbar-thumb  {
  background: var(--fg-dim);
  border-radius: 3px;
  box-shadow: 0 0 4px var(--glow-soft);
}
#output::-webkit-scrollbar-thumb:hover {
  background: var(--fg);
}

/* ── Scroll-more hint ───────────────────────────────────────── */
#scroll-more {
  flex-shrink: 0;
  display: none;
  text-align: center;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.8rem;
  letter-spacing: 0.25em;
  padding: 0.15rem 0 0.05rem;
  animation: scroll-hint-pulse 1.5s ease-in-out infinite;
  user-select: none;
}

#scroll-more.visible {
  display: block;
  cursor: pointer;
  transition: opacity 0.5s ease;
}

/* Auto-dismiss fade-out state */
#scroll-more.visible.fading {
  opacity: 0;
  pointer-events: none;
}

@keyframes scroll-hint-pulse {
  0%, 100% { opacity: 0.35; }
  50%       { opacity: 0.9;  }
}

#scroll-more:hover {
  opacity: 1;
  animation: none;
  color: var(--fg);
  text-shadow: 0 0 6px var(--glow-soft);
}

/* Pager mode — persistent press-any-key prompt (overrides auto-dismiss) */
#scroll-more.pager-mode {
  color: var(--fg);
  letter-spacing: 0.2em;
  animation: scroll-hint-pulse 0.9s ease-in-out infinite;
  cursor: pointer;
}

/* Prevent the auto-dismiss fade-out from hiding the pager prompt */
#scroll-more.pager-mode.fading {
  opacity: 1;
  pointer-events: auto;
}

/* Wrapper inserted once per command so aria-live fires a single announcement */
.cmd-output-block {
  display: contents; /* no box of its own; children participate directly in #output layout */
}

/* Generic output line */
.line {
  display: block;
  white-space: pre-wrap;
  word-break: break-word;
  padding: 0.04em 0;
  text-shadow: 0 0 5px var(--glow-soft);
}

/* Echo of the command the user typed */
.line-cmd {
  color: var(--fg-bright);
  text-shadow: 0 0 8px var(--glow);
}

/* Normal response output */
.line-out {
  color: var(--fg);
}

/* Error */
.line-err {
  color: #ff6040;
  text-shadow: 0 0 8px rgba(255, 96, 64, 0.5);
}

/* Deprecation / soft warning */
.line-warn {
  color: #e8a030;
  text-shadow: 0 0 8px rgba(232, 160, 48, 0.45);
}

/* Informational / dim (e.g., usage hints) */
.line-info {
  color: var(--fg-dim);
}

/* Success confirmation */
.line-ok {
  color: #a0db50;
  text-shadow: 0 0 8px rgba(160, 219, 80, 0.4);
}

/* Section separator / decorative lines */
.line-sep {
  color: var(--fg-dim);
  user-select: none;
}

/* Bold heading inside output */
.line-head {
  color: var(--fg-bright);
  text-shadow: 0 0 10px var(--glow);
  letter-spacing: 0.06em;
}

/* ── cal command output ────────────────────────────────────── */
.cal-output {
  margin: 0.1em 0;
  font-family: inherit;
  font-size: inherit;
  line-height: 1.6;
  color: var(--fg);
  text-shadow: 0 0 5px var(--glow-soft);
}

.cal-output .cal-header {
  display: block;
  color: var(--fg-bright);
  text-shadow: 0 0 10px var(--glow);
  letter-spacing: 0.05em;
}

.cal-output .cal-days {
  display: block;
  color: var(--fg-dim);
}

.cal-today {
  color: var(--bg);
  background-color: var(--fg-bright);
  text-shadow: none;
  font-weight: bold;
  border-radius: 2px;
}

/* ── Input Row ──────────────────────────────────────────────── */
#input-row {
  flex-shrink: 0;
  position: relative;
  display: flex;
  cursor: text;
  align-items: center;
  padding: 0.35rem 0 0.5rem;
  border-top: 1px solid var(--fg-dim);
  margin-top: 0.4rem;
  /* keep the visible prompt/text glowing */
  text-shadow: 0 0 8px var(--glow);
  color: var(--fg-bright);
  white-space: pre;
  overflow: hidden;
  transition: border-color 0.2s ease;
}

/* Lift the top-border when the input is focused */
#input-row:focus-within {
  border-top-color: var(--fg);
}

/* The ">" prompt glyph */
.prompt-glyph {
  color: var(--fg-bright);
  flex-shrink: 0;
  text-shadow: 0 0 8px var(--glow);
}

/* Visible mirror of the hidden <input> value */
#input-display {
  white-space: pre;
  word-break: break-all;
}

/* Blinking underscore cursor */
#cursor {
  color: var(--fg-bright);
  line-height: 1;
}

/* The real <input> element — invisible but on top, captures keys */
#cmd-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  background: transparent;
  border: none;
  outline: none;
  color: transparent;
  caret-color: transparent;    /* we draw our own cursor */
  font-family: var(--font-stack);
  font-size: var(--font-size);
  cursor: text;
}

/* ── Reduced-Motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .blink {
    animation: none;        /* static underscore */
  }
  #scanlines {
    display: none;          /* no scanlines */
  }
  #terminal {
    animation: none;        /* no CRT flicker */
  }
  #output {
    scroll-behavior: auto;  /* no smooth scroll */
  }
  .crt-poweroff {
    animation-duration: 0.01s;
  }
  .crt-wipe {
    animation-duration: 0.01s;
  }
  #speed-dial-wrap.visible {
    animation: none;        /* no dial slide-in */
  }
  .dial-composer {
    animation: none;
  }
}

/* ── CRT Intensity ──────────────────────────────────────────── */
/*
   Controlled by applyPrefs() — sets html.crt--{level} class.
   Default (no class or .crt--medium) equals the stylesheet baseline.
   All effects are purely cosmetic; disabling them never breaks UI.
*/

/* OFF — strip every CRT effect ────────────────────────────── */
html.crt--off #scanlines               { display: none; }
html.crt--off #terminal                { animation: none; }
html.crt--off .crt-poweroff            { animation-duration: 0.01s; }
html.crt--off .crt-wipe                { animation-duration: 0.01s; }
html.crt--off #speed-dial-wrap.visible { animation: none; }

/* LOW — half-opacity scanlines, no flicker ─────────────────── */
html.crt--low #scanlines               { opacity: 0.45; }
html.crt--low #terminal                { animation: none; }

/* MEDIUM — baseline (no overrides; keyframes defined above) ─── */

/* HIGH — denser stripes, more vivid flicker, wider vignette ─── */
@keyframes crt-flicker-high {
  0%   { opacity: 1;     }
  3%   { opacity: 0.963; }
  6%   { opacity: 1;     }
  40%  { opacity: 0.978; }
  42%  { opacity: 0.938; }
  44%  { opacity: 1;     }
  76%  { opacity: 0.968; }
  78%  { opacity: 0.942; }
  80%  { opacity: 1;     }
  100% { opacity: 1;     }
}

html.crt--high #terminal {
  animation: crt-flicker-high 5s linear infinite;
}

html.crt--high #scanlines {
  /* Denser 3-px period scanline stripe */
  background: repeating-linear-gradient(
    to bottom,
    transparent            0px,
    transparent            2px,
    var(--scanline-bg)     2px,
    var(--scanline-bg)     3px
  );
}

html.crt--high #scanlines::after {
  /* Wider, darker corner vignette */
  background: radial-gradient(
    ellipse at center,
    transparent            42%,
    rgba(0, 0, 0, 0.28)   65%,
    rgba(0, 0, 0, 0.60)   100%
  );
}

/* HIGH + C64 / Apple II — horizontal jitter ────────────────
   Real composite-video CRTs suffered from horizontal sync
   instability; the image would occasionally slip 1-2 px left
   or right.  The effect is deliberately rare (low frame-budget
   keyframe density) and very short-range so it reads as
   authentic noise rather than a distraction.                   */
@keyframes crt-jitter {
  0%,  9%  { transform: translateX(0);    }
  10%      { transform: translateX(-1px); }
  11%      { transform: translateX(0);    }
  49%      { transform: translateX(0);    }
  50%      { transform: translateX(1px);  }
  51%      { transform: translateX(0);    }
  100%     { transform: translateX(0);    }
}

html.crt--high.mode--c64 #terminal,
html.crt--high.mode--appleIIGreen #terminal {
  /* Layer jitter on top of the high-intensity flicker animation */
  animation:
    crt-flicker-high 5s    linear   infinite,
    crt-jitter       0.25s steps(1) infinite;
}

/* ── Phosphor Persistence ──────────────────────────────────────
   Simulates the luminance decay of long-persistence phosphor
   coatings (P3 amber, P1 green) found in vintage terminals and
   oscilloscopes.  Characters appear to leave a brief glowing
   afterimage as the excited phosphor slowly de-energises.

   Activated by applyPrefs() as html.phosphor-persistence--on
   when crtIntensity = High AND the active theme is Amber or
   Green — the two phosphor types that historically exhibited
   the most visible persistence.

   Implementation note:
     • transition: color 0.2s ease-out — any programmatic colour
       change fades out rather than cutting hard, echoing the
       gradual luminance decay of the real coating.
     • The layered text-shadow builds three zones:
         – tight core  (2 px)  : the bright active phosphor dot
         – mid bloom   (10 px) : spread of the excited region
         – wide halo   (22/45 px): the slowly decaying afterglow
   All values reference the active palette vars so the effect
   adapts correctly to both Amber and Green.
─────────────────────────────────────────────────────────────── */

.phosphor-persistence {
  transition: color 0.2s ease-out;
  text-shadow:
    0 0  2px var(--fg),
    0 0 10px var(--glow),
    0 0 22px var(--glow-soft),
    0 0 45px var(--glow-soft);
}

html.phosphor-persistence--on #output,
html.phosphor-persistence--on #input-line {
  transition: color 0.2s ease-out;
  text-shadow:
    0 0  2px var(--fg),
    0 0 10px var(--glow),
    0 0 22px var(--glow-soft),
    0 0 45px var(--glow-soft);
}

/* ── User-controlled reduced-motion (manual preference override) ─
   Applied by applyPrefs() as html.reduced-motion--on when
   prefs.reducedMotion === true.  Provides explicit user control
   independent of the OS prefers-reduced-motion media query.
─────────────────────────────────────────────────────────────── */
html.reduced-motion--on .blink                   { animation: none; }
html.reduced-motion--on #scanlines               { display: none; }
html.reduced-motion--on #terminal                { animation: none; }
html.reduced-motion--on #output                  { scroll-behavior: auto; }
html.reduced-motion--on .crt-poweroff            { animation-duration: 0.01s; }
html.reduced-motion--on .crt-wipe                { animation-duration: 0.01s; }
html.reduced-motion--on #speed-dial-wrap.visible { animation: none; }
html.reduced-motion--on .dial-composer           { animation: none; }

/* ── Countdown timer in status line ────────────────────────── */
/* Applied to #status-time while a countdown is active */
#status-time.countdown-active {
  color: var(--fg-bright);
  text-shadow:
    0 0 4px var(--glow),
    0 0 14px var(--glow-soft);
  letter-spacing: 0.06em;
}

/* ── Countdown zero alert — flash the terminal border ──────── */
@keyframes countdown-terminal-flash {
  0%, 49% {
    outline: 2px solid var(--fg-bright);
    box-shadow:
      inset 0 0 18px var(--glow-soft),
      0 0 24px var(--glow);
  }
  50%, 100% {
    outline: 2px solid transparent;
    box-shadow: none;
  }
}

#terminal.countdown-alert {
  animation: countdown-terminal-flash 0.42s step-end 7;
}

/* ── Wide tablet / small laptop ────────────────────────────── */
@media (max-width: 1024px) {
  :root {
    --dial-tile-width: 4.2em;
  }
  #header {
    padding: 0.35rem 0.6rem 0.45rem;
  }
  #banner-row {
    gap: 0.5rem;
    margin-bottom: 0.4rem;
  }
}

/* ── Tablet portrait ────────────────────────────────────────── */
@media (max-width: 768px) {
  :root {
    --font-size: 18px;
    --dial-tile-width: 3.8em;
  }
  #header {
    padding: 0.28rem 0.45rem 0.38rem;
  }
  #banner-row {
    gap: 0.45rem;
    margin-bottom: 0.35rem;
  }
  #ascii-art {
    padding: 0.26rem 0.36rem 0.2rem;
    font-size: 0.56rem;
    line-height: 1.03;
  }
  #status-line {
    font-size: 0.75rem;
    gap: 0.1rem 0.45rem;
  }
}

/* ── Mobile landscape ───────────────────────────────────────── */
@media (max-height: 500px) and (orientation: landscape) {
  :root {
    --dial-tile-width: 3.4em;
  }
  #terminal {
    padding: 0.3rem 0.6rem 0.3rem;
  }
  #header {
    padding: 0.15rem 0.4rem 0.2rem;
  }
  #banner-row {
    gap: 0.3rem;
    margin-bottom: 0.2rem;
  }
  #ascii-art {
    display: none;
  }
  #status-line {
    font-size: 0.7rem;
  }
}

/* ── Small viewport tweaks ──────────────────────────────────── */
@media (max-width: 600px) {
  :root {
    --font-size: 16.8px;
  }
  #terminal {
    padding: 0.5rem 0.75rem 0.5rem;
  }
  #header {
    padding: 0.25rem 0.3rem 0.4rem;
  }
  #banner-row {
    gap: 0.45rem;
    margin-bottom: 0.35rem;
  }
  #logo {
    height: 1em;
    padding: 0;
  }
  #ascii-art {
    padding: 0.24rem 0.34rem 0.18rem;
    font-size: 0.52rem;
    line-height: 1.02;
  }
  #status-line {
    font-size: 0.72rem;
    gap: 0.12rem 0.5rem;
  }
  #status-time {
    width: 100%;
    margin-left: 0;
    text-align: left;
  }
}

/* ── Very small phones / narrow viewports (≤ 480 px) ────────── */
@media (max-width: 480px) {
  /* The toolbar switches to a two-row layout:
     row 1 — action buttons + search (stretch)
     row 2 — density control (hidden label, just the stepper buttons)
     row 3 — category chips (unchanged, already flex-wrap)
  */
  #dial-toolbar {
    gap: 0.28em 0.45em;
    padding: 0.35em 0 0.35em;
  }

  /* Search grows to take the remaining first-row width */
  .dial-toolbar-search {
    flex: 1 1 5em;
    max-width: none;
  }

  /* Density label: hide the text on very narrow viewports to save space.
     The stepper buttons’ aria-label attributes already convey the action. */
  .dial-toolbar-density-label {
    display: none;
  }

  /* Ensure the density group doesn’t push buttons onto orphaned lines */
  .dial-toolbar-group--density {
    gap: 0.18em;
  }

  /* Category chips: allow the chips to wrap naturally, but reduce gap */
  .dial-toolbar-chips {
    gap: 0.22em;
  }
}

/* ── Undo Delete Toast ───────────────────────────────────────── */
@keyframes toast-slide-in {
  from { transform: translateX(-50%) translateY(1.5em); opacity: 0; }
  to   { transform: translateX(-50%) translateY(0);     opacity: 1; }
}

@keyframes toast-slide-out {
  from { transform: translateX(-50%) translateY(0);     opacity: 1; }
  to   { transform: translateX(-50%) translateY(1.5em); opacity: 0; }
}

#dial-undo-toast {
  position: fixed;
  bottom: 2.4em;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--fg);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  padding: 0.35em 1em;
  z-index: 500;
  display: none;
  align-items: center;
  white-space: nowrap;
  box-shadow: 0 0 14px var(--glow-soft);
  pointer-events: none;
}

#dial-undo-toast.visible {
  display: flex;
  pointer-events: auto;
  animation: toast-slide-in 0.22s ease-out;
}

#dial-undo-toast.toast-hiding {
  display: flex;
  pointer-events: none;
  animation: toast-slide-out 0.25s ease-in forwards;
}

.dial-undo-toast-msg {
  color: var(--fg-dim);
}

.dial-undo-toast-btn {
  background: none;
  border: none;
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: var(--font-size);
  line-height: inherit;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.dial-undo-toast-btn:hover,
.dial-undo-toast-btn:focus-visible {
  color: var(--fg);
  text-shadow: 0 0 6px var(--glow);
  outline: none;
}

/* Prevent the toast from overflowing on small screens */
@media (max-width: 600px) {
  #dial-undo-toast {
    max-width: calc(100vw - 2rem);
    white-space: normal;
    text-align: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.2em 0.5em;
    bottom: 3.5em;  /* clear the input row on mobile */
  }

  .settings-inner {
    min-width: 0;
    width: calc(100vw - 2rem);
  }

  .settings-row {
    flex-wrap: wrap;
    gap: 0.35rem;
  }

  .settings-label {
    flex: 0 0 auto;
    width: auto;
    min-width: auto;
  }
}

/* ── ═══════════════════════════════════════════════════════
   Launch Panel
   ═══════════════════════════════════════════════════════ ─ */

/* ── [LAUNCH] trigger button in the overlay header ────────── */
#launch-panel-trigger {
  background: none;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.65em;
  line-height: 1;
  padding: 0.18em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  opacity: 1;
  transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease,
              box-shadow 0.15s ease;
  user-select: none;
}

#launch-panel-trigger:hover,
#launch-panel-trigger:focus-visible {
  opacity: 1;
  color: var(--fg);
  border-color: var(--fg);
  outline: none;
  box-shadow: 0 0 4px var(--glow-soft);
}

/* ── Full-screen overlay container ────────────────────────── */
#launch-panel {
  position: fixed;
  inset: 0;
  z-index: 350;           /* above dial grid (300) */
  pointer-events: none;   /* closed: let events through */
}

#launch-panel.is-open {
  pointer-events: auto;
}

/* ── Semi-transparent backdrop ────────────────────────────── */
.launch-panel__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: opacity 0.2s ease;
}

#launch-panel.is-open .launch-panel__backdrop {
  opacity: 1;
}

/* ── Panel card ────────────────────────────────────────────── */
.launch-panel__card {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 26em;
  max-width: 92vw;
  background: var(--bg);
  border-left: 1px solid var(--fg);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.22s ease;
  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.5);
}

#launch-panel.is-open .launch-panel__card {
  transform: translateX(0);
}

/* ── Panel header ──────────────────────────────────────────── */
.launch-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.65em 1em;
  border-bottom: 1px solid var(--fg-dim);
  flex-shrink: 0;
  gap: 0.5em;
}

.launch-panel__title {
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  letter-spacing: 0.14em;
  text-shadow: 0 0 8px var(--glow);
}

.launch-panel__close {
  background: none;
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: var(--dial-font-size);
  cursor: pointer;
  padding: 0.12em 0.5em;
  letter-spacing: 0.04em;
  flex-shrink: 0;
}

.launch-panel__close:hover,
.launch-panel__close:focus-visible {
  border-color: var(--fg);
  color: var(--fg-bright);
  outline: none;
}

/* ── Scrollable body ───────────────────────────────────────── */
.launch-panel__body {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 0.75em 1em;
  display: flex;
  flex-direction: column;
  gap: 1em;
  scrollbar-width: thin;
  scrollbar-color: var(--fg-dim) transparent;
}

.launch-panel__body::-webkit-scrollbar {
  width: 4px;
}
.launch-panel__body::-webkit-scrollbar-thumb {
  background: var(--fg-dim);
}

/* ── Section ───────────────────────────────────────────────── */
.launch-panel__section {
  display: flex;
  flex-direction: column;
  gap: 0.45em;
}

.launch-panel__section-title {
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.72em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-bottom: 1px solid var(--fg-dim);
  padding-bottom: 0.2em;
}

/* ── Quick-open list (recent / most-used) ──────────────────── */
.launch-panel__quick-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
}

.launch-panel__quick-item {
  background: none;
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.82em;
  padding: 0.22em 0.55em;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.35em;
  letter-spacing: 0.04em;
  transition: border-color 0.12s, color 0.12s, box-shadow 0.12s;
}

.launch-panel__quick-item:hover,
.launch-panel__quick-item:focus-visible {
  border-color: var(--fg);
  color: var(--fg-bright);
  box-shadow: 0 0 5px var(--glow-soft);
  outline: none;
}

.launch-panel__quick-label {
  max-width: 9em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.launch-panel__count-badge {
  color: var(--fg-dim);
  font-size: 0.78em;
  letter-spacing: 0.02em;
}

.launch-panel__mini-icon {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  flex-shrink: 0;
  color: var(--fg-dim);
}

/* ── Launch sets header row ────────────────────────────────── */
.launch-panel__sets-headrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5em;
}

.launch-panel__new-btn {
  background: none;
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.78em;
  padding: 0.16em 0.5em;
  cursor: pointer;
  letter-spacing: 0.05em;
  white-space: nowrap;
  flex-shrink: 0;
}

.launch-panel__new-btn:hover,
.launch-panel__new-btn:focus-visible {
  border-color: var(--fg);
  color: var(--fg-bright);
  outline: none;
}

/* ── Empty state ───────────────────────────────────────────── */
.launch-panel__empty {
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.82em;
  line-height: 1.5;
  padding: 0.4em 0;
}

/* ── Sets list ─────────────────────────────────────────────── */
.launch-panel__sets-list {
  display: flex;
  flex-direction: column;
  gap: 0.5em;
}

/* ── Single set row ────────────────────────────────────────── */
.launch-panel__set-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.5em;
  border: 1px solid var(--fg-dim);
  padding: 0.5em 0.65em;
  transition: border-color 0.12s;
}

.launch-panel__set-row:hover {
  border-color: var(--fg);
}

.launch-panel__set-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3em;
}

.launch-panel__set-name {
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: 0.88em;
  letter-spacing: 0.08em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.launch-panel__set-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.22em;
}

.launch-panel__tag {
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.72em;
  padding: 0.06em 0.32em;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.launch-panel__tag--missing {
  border-color: #e06c75;
  color: #e06c75;
  opacity: 0.7;
}

/* ── Set action buttons ────────────────────────────────────── */
.launch-panel__set-actions {
  display: flex;
  flex-direction: column;
  gap: 0.28em;
  flex-shrink: 0;
}

.launch-panel__set-btn {
  background: none;
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.78em;
  padding: 0.14em 0.45em;
  cursor: pointer;
  letter-spacing: 0.05em;
  white-space: nowrap;
  transition: border-color 0.12s, color 0.12s;
}

.launch-panel__set-btn:hover,
.launch-panel__set-btn:focus-visible {
  border-color: var(--fg);
  color: var(--fg-bright);
  outline: none;
}

.launch-panel__set-btn--run {
  border-color: var(--fg);
  color: var(--fg-bright);
}

.launch-panel__set-btn--run:hover,
.launch-panel__set-btn--run:focus-visible {
  box-shadow: 0 0 6px var(--glow-soft);
}

.launch-panel__set-btn--rm {
  color: var(--fg-dim);
}

.launch-panel__set-btn--rm:hover,
.launch-panel__set-btn--rm:focus-visible {
  border-color: #e06c75;
  color: #e06c75;
}

.launch-panel__set-btn--save {
  border-color: var(--fg);
  color: var(--fg-bright);
}

/* ── Inline editor card ────────────────────────────────────── */
.launch-panel__editor {
  border: 1px solid var(--fg);
  padding: 0.7em 0.8em;
  display: flex;
  flex-direction: column;
  gap: 0.55em;
  background: var(--bg);
  box-shadow: 0 0 12px var(--glow-soft);
}

.launch-panel__editor-title {
  color: var(--fg-bright);
  font-family: var(--font-stack);
  font-size: 0.8em;
  letter-spacing: 0.12em;
}

.launch-panel__field {
  display: flex;
  flex-direction: column;
  gap: 0.2em;
}

.launch-panel__field-label {
  display: flex;
  flex-direction: column;
  gap: 0.2em;
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.7em;
  letter-spacing: 0.1em;
}

.launch-panel__field-input {
  background: var(--bg);
  border: 1px solid var(--fg-dim);
  color: var(--fg);
  font-family: var(--font-stack);
  font-size: 0.88em;
  padding: 0.28em 0.45em;
  outline: none;
  width: 100%;
}

.launch-panel__field-input:focus {
  border-color: var(--fg);
}

.launch-panel__field-hint {
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.68em;
  line-height: 1.4;
  opacity: 0.8;
  word-break: break-all;
}

.launch-panel__editor-error {
  color: #e06c75;
  font-family: var(--font-stack);
  font-size: 0.78em;
  min-height: 0.9em;
}

.launch-panel__editor-btns {
  display: flex;
  gap: 0.4em;
}

/* ── Footer hint ───────────────────────────────────────────── */
.launch-panel__footer {
  flex-shrink: 0;
  padding: 0.55em 1em;
  border-top: 1px solid var(--fg-dim);
  color: var(--fg-dim);
  font-family: var(--font-stack);
  font-size: 0.68em;
  letter-spacing: 0.05em;
}

.launch-panel__footer kbd {
  color: var(--fg);
  border: 1px solid var(--fg-dim);
  padding: 0.05em 0.28em;
  font-family: var(--font-stack);
  font-size: 1em;
}

/* ── Responsive: narrow viewports ─────────────────────────── */
@media (max-width: 600px) {
  .launch-panel__card {
    width: 100%;
    max-width: 100%;
    border-left: none;
    border-top: 1px solid var(--fg);
    top: auto;
    bottom: 0;
    height: 75vh;
    transform: translateY(100%);
  }

  #launch-panel.is-open .launch-panel__card {
    transform: translateY(0);
  }
}

/* ══════════════════════════════════════════════════════════════
   Virtual Monitor — CRT display for Lua phos.draw() output
   ══════════════════════════════════════════════════════════════ */

/* Backdrop / full-screen overlay */
#lua-modal {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh;
  background: rgba(0, 0, 0, 0.9);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

/* CRT outer chassis — bezel + deep-green glow */
#lua-crt-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

/* The screen surface */
#lua-output {
  width: fit-content;
  min-width: 58ch;   /* never narrower than the 52-char frame + indent */
  max-width: 88vw;
  height: 80vh;
  background: var(--bg);
  border: 20px solid #222; /* CRT bezel */
  border-radius: 50px;
  padding: 20px;
  box-shadow: inset 0 0 50px var(--glow);
  overflow: hidden;
  color: var(--fg);
  /* Strict 1:1 character-cell ratio */
  font-family: 'VT323', monospace;
  font-size: 1.5rem;
  line-height: 1.0;        /* Essential for map alignment */
  letter-spacing: 0.1ch;
  white-space: pre;        /* Keeps newlines intact */
  display: inline-block;   /* Helps center the grid */
}

/* "ESC TO QUIT" hint + QUIT button beneath the monitor */
#lua-controls {
  display: flex;
  align-items: center;
  gap: 1.4em;
  color: var(--fg-dim);
  font-family: var(--font-mono, monospace);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  user-select: none;
}

#lua-quit-btn {
  background: transparent;
  border: 1px solid var(--fg-dim);
  border-radius: 4px;
  color: var(--fg-dim);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  padding: 0.15em 0.7em;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

#lua-quit-btn:hover,
#lua-quit-btn:focus-visible {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  outline: none;
}

/* Hide utility — toggled by JS */
#lua-modal.hidden {
  display: none;
}

/* ============================================================
   C64 Emulator Overlay
   Mirrors the structure of #lua-modal / #lua-crt-frame.
   The <iframe> is injected dynamically into #c64-crt-frame.
   ============================================================ */
#c64-modal {
  position: fixed;
  top: 0; left: 0;
  width: 100vw; height: 100vh;
  background: rgba(0, 0, 0, 0.9);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

/* CRT outer chassis — bezel + deep-green glow */
#c64-crt-frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: min(90vw, 900px);
  height: min(85vh, 675px);
}

/* Dynamically-injected <iframe> fills the remaining space above the controls */
#c64-crt-frame iframe {
  flex: 1;
  width: 100%;
  min-height: 0;
  border: none;
  display: block;
}

/* "ESC TO QUIT" hint + QUIT button beneath the monitor */
#c64-controls {
  display: flex;
  align-items: center;
  gap: 1.4em;
  color: var(--fg-dim);
  font-family: var(--font-mono, monospace);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  user-select: none;
}

#c64-quit-btn {
  background: transparent;
  border: 1px solid var(--fg-dim);
  border-radius: 4px;
  color: var(--fg-dim);
  font-family: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  padding: 0.15em 0.7em;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

#c64-quit-btn:hover,
#c64-quit-btn:focus-visible {
  color: var(--fg-bright);
  border-color: var(--fg-bright);
  outline: none;
}

/* Hide utility — toggled by JS */
#c64-modal.hidden {
  display: none;
}

/* ============================================================
   Hardware Emulation Classes
   Apply to the <html> element to cascade into all nested
   terminal components.

   Usage:
     document.documentElement.classList.add('mode--c64');

   Each mode overrides --font-stack and --font-size on :root
   via a higher-specificity html selector.  Additional
   hardware-specific structural rules follow each variable
   block.
   ============================================================ */

/* ── Commodore 64 ───────────────────────────────────────────
   Chunky uppercase PETSCII-style rendering.  The thick bezel
   border on #terminal mimics the C64's iconic brown-plastic
   monitor surround.
   ─────────────────────────────────────────────────────────── */
html.mode--c64 {
  --font-stack: "C64 Pro Mono", "C64 Pro", "PetMe64", "VT323",
                "Courier New", Courier, monospace;
  --font-size:  22px;
  /* Hardware-accurate character grid: 40 columns × 25 rows */
  --grid-cols:  40;
  --grid-rows:  25;
}

/* Full-width terminal layout for all hardware emulation modes. */
html.mode--c64 #terminal,
html.mode--apple2 #terminal,
html.mode--appleIIGreen #terminal,
html.mode--appleIIColor #terminal,
html.mode--nes #terminal,
html.mode--gameBoy #terminal,
html.mode--gameboy #terminal {
  width:     100vw;
  max-width: 100vw;
  margin:    0;
}

html.mode--c64 #terminal {
  /* C64 bezel border */
  border:       10px solid var(--fg-dim);
  border-radius: 6px;
  box-shadow:
    0 0 0 3px var(--bg),
    0 0 0 5px var(--fg-dim);
}

/* C64 readability tweaks:
   - keep pixel text crisp by reducing glow blur
   - lighten overlay darkness to preserve contrast on deep-blue background */
html.mode--c64 #ascii-art,
html.mode--c64 .line,
html.mode--c64 .line-cmd,
html.mode--c64 .line-head,
html.mode--c64 #input-row,
html.mode--c64 .prompt-glyph {
  text-shadow: none;
}

html.mode--c64 #scanlines {
  opacity: 0.7;
}

html.mode--c64 #scanlines::after {
  background: radial-gradient(
    ellipse at center,
    transparent            63%,
    rgba(0, 0, 0, 0.12)   82%,
    rgba(0, 0, 0, 0.26)   100%
  );
}

/* ── Apple II ───────────────────────────────────────────────
   Crisp, slanted monospace reminiscent of the Apple II's
   character ROM output on a green-phosphor composite display.
   ─────────────────────────────────────────────────────────── */
html.mode--apple2 {
  --font-stack: "Print Char 21", "Apple2", "PR Number 3",
                "VT323", "Courier New", Courier, monospace;
  --font-size:  18px;
}

/* Font + hardware-accurate character grid — Apple II text screen: 40 cols × 24 rows. */
html.mode--appleIIGreen {
  --font-stack: "Print Char 21", "Apple2", "PR Number 3",
                "VT323", "Courier New", Courier, monospace;
  --font-size:  18px;
  /* Hardware-accurate character grid: 40 columns × 24 rows */
  --grid-cols:  40;
  --grid-rows:  24;
}

/* NTSC composite color fringing — the Apple II drove a standard
   NTSC signal; pixels on adjacent columns bleed chrominance into
   one another, producing a 1-px magenta shadow on the left edge
   and a 1-px cyan shadow on the right edge of each character.   */
html.mode--appleIIGreen .line {
  text-shadow:
    -1px 0 0 rgba(255, 0, 255, 0.30),   /* magenta left bleed  */
     1px 0 0 rgba(0, 255, 255, 0.30);   /* cyan   right bleed  */
}

/* ── Game Boy ───────────────────────────────────────────────
   Small, dense pixel font scaled to fit the Game Boy's
   limited 160 × 144 LCD resolution aesthetic.
   ─────────────────────────────────────────────────────────── */
html.mode--gameboy {
  --font-stack: "Early GameBoy", "Pixel GameBoy", "VT323",
                "Courier New", Courier, monospace;
  --font-size:  14px;
}

/* Non-backlit reflective LCD — the original DMG screen had no
   backlight; ambient light reflected off a semi-opaque LCD panel
   giving a washed-out, warm-tinted, low-contrast appearance.    */
html.mode--gameBoy #terminal {
  filter: contrast(0.8) sepia(0.5) brightness(0.9);
}
