:root {
  color-scheme: light dark;
  --bg: #fafafa;
  --panel-bg: #fff;
  --fg: #222;
  --muted: #666;
  --accent: #2463eb;
  --border: #ddd;
  --pre-bg: #f4f4f4;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #181818;
    --panel-bg: #202020;
    --fg: #eaeaea;
    --muted: #999;
    --accent: #7ea5ff;
    --border: #333;
    --pre-bg: #141414;
  }
}

* { box-sizing: border-box; }

/*
 * The browser UA sets `[hidden] { display: none }` at specificity (0,1,0),
 * but `.toolbar { display: flex }` and `.output-section { display: flex }`
 * below match that specificity and win by source order. Without this
 * override the `hidden` attribute we toggle from JS has no visual effect,
 * which stacks both toolbars / panels on top of each other and makes
 * "click Debug twice" look broken because `mode === 'debug'` blocks the
 * second click. !important keeps this a one-line guarantee no matter what
 * display rule a future class adds.
 */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 1rem 2rem 2rem;
  background: var(--bg);
  color: var(--fg);
  max-width: 1100px;
  margin-inline: auto;
}

header h1 {
  font-size: 1.8rem;
  margin: 0 0 0.2rem;
}

.tagline {
  margin: 0 0 1rem;
  color: var(--muted);
  font-size: 0.9rem;
}

.tagline a {
  color: var(--accent);
  text-decoration: none;
}
.tagline a:hover { text-decoration: underline; }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
  margin-bottom: 1rem;
  padding: 0.6rem 0.8rem;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
}

.toolbar label {
  font-size: 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

.toolbar input, .toolbar select {
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--bg);
  color: var(--fg);
  font: inherit;
}

/* Cap the picker so a long option label can't blow the toolbar
   row open. The dropdown itself still renders the full label
   in browsers that honor option width — only the closed select
   is constrained. */
.toolbar select { max-width: 18rem; }

.toolbar input[type="number"] { width: 9em; }

/* Force a wrap inside flex toolbars so anything after the
   break starts on a new row. Used in #toolbar-idle to drop
   Run/Debug onto their own row beneath the picker + inputs. */
.toolbar-row-break {
  flex-basis: 100%;
  height: 0;
}

.toolbar button {
  padding: 0.3rem 0.85rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 4px;
  font-weight: 600;
  cursor: pointer;
  font: inherit;
  line-height: 1.2;
  /* Disable iOS/Android double-tap zoom — important for the
     debug Step button which the user often taps in rapid
     succession. */
  touch-action: manipulation;
}

.toolbar button.secondary {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  font-weight: 500;
}

.toolbar button:disabled {
  opacity: 0.5;
  cursor: wait;
}

#version-badge {
  margin-left: auto;
  color: var(--muted);
  font-size: 0.8rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
}

main {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 800px) {
  main { grid-template-columns: 1fr; }
}

.editor-section label {
  display: block;
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0.5rem 0 0.25rem;
}

.hint { color: var(--muted); font-weight: normal; font-size: 0.8em; }

/* Source label + mode badge + toggle button on a single row. */
.editor-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0 0.25rem;
  flex-wrap: wrap;
}
.editor-header label {
  margin: 0;
}

/* Vim-style mode badge. NORMAL (default) is blue; INSERT is green.
   The user clicks the badge, the toggle button, or presses i / Esc
   to switch. */
.mode-badge {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: 0.15rem 0.45rem;
  border-radius: 3px;
  text-transform: uppercase;
}
.mode-badge.mode-normal {
  background: color-mix(in oklab, var(--accent) 18%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in oklab, var(--accent) 50%, transparent);
}
.mode-badge.mode-insert {
  background: color-mix(in oklab, #2da44e 22%, transparent);
  color: #2da44e;
  border: 1px solid color-mix(in oklab, #2da44e 60%, transparent);
}

/* Current typing direction badge — updated by palette clicks.
   In INSERT this also drives where each typed character lands. */
.dir-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em;
  height: 1.6em;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--accent);
  border: 1px solid color-mix(in oklab, var(--accent) 40%, transparent);
  border-radius: 3px;
  background: color-mix(in oklab, var(--accent) 8%, transparent);
}

.mode-toggle {
  font-size: 0.75rem;
  padding: 0.15rem 0.5rem;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  font-size: 0.75rem;
  touch-action: manipulation;
}
.mode-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.mode-hint {
  font-size: 0.72rem;
}
@media (max-width: 800px) {
  .mode-hint { display: none; }
}

/* Click-to-insert palette for the glyphs that aren't on a keyboard
   (the diagonals ↗ ↘ ↙ ↖ and the speed ops ≫ ≪). Sits above the
   source textarea; each button drops its glyph at the cursor. */
.glyph-palette {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.5rem;
  margin-bottom: 0.4rem;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
}

.glyph-compass {
  display: grid;
  grid-template-columns: repeat(3, auto);
  gap: 2px;
}

.glyph-extras {
  display: flex;
  gap: 2px;
}

.glyph-btn {
  width: 1.9em;
  height: 1.9em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--fg);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
  font-size: 1.05rem;
  line-height: 1;
  /* Same anti-double-tap-zoom treatment as the toolbar buttons. */
  touch-action: manipulation;
}
.glyph-btn:hover, .glyph-btn:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
  outline: none;
}
.glyph-btn:active {
  background: var(--panel-bg);
}

.glyph-hint { margin-left: auto; }

#source {
  width: 100%;
  min-height: 340px;
  padding: 0.6rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 14px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel-bg);
  color: var(--fg);
  resize: vertical;
  white-space: pre;
  overflow: auto;
  tab-size: 1;
}

/* Vim-style modal cues. NORMAL: thicker accent caret + faint
   accent border so it's clear navigation keys are live. INSERT:
   green caret + green border, signalling "type freely". */
body.mode-normal #source {
  caret-color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 40%, var(--border));
}
body.mode-insert #source {
  caret-color: #2da44e;
  border-color: color-mix(in oklab, #2da44e 50%, var(--border));
}

#stdin {
  width: 100%;
  padding: 0.5rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel-bg);
  color: var(--fg);
  resize: vertical;
}

.output-section {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.panel {
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--panel-bg);
  overflow: hidden;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 140px;
}

.panel-head {
  padding: 0.35rem 0.7rem;
  background: var(--pre-bg);
  border-bottom: 1px solid var(--border);
  font-size: 0.82rem;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
}

#exit-code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
}

.panel pre {
  margin: 0;
  padding: 0.6rem 0.8rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  white-space: pre-wrap;
  word-break: break-word;
  flex: 1;
  overflow: auto;
}

footer {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.8rem;
}

code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  background: var(--pre-bg);
  padding: 0 0.2em;
  border-radius: 3px;
}

/* Debug mode */

.debug-grid {
  grid-template-columns: 2fr 1fr;
  grid-auto-rows: min-content;
}

@media (max-width: 800px) {
  .debug-grid { grid-template-columns: 1fr; }
}

.panel-wide { grid-column: 1 / -1; }

.grid-view {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.25;
  white-space: pre;
  overflow: auto;
  padding: 0.6rem 0.8rem;
  max-height: 340px;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  /* Remove iOS tap highlight halo; we do our own feedback. */
  -webkit-tap-highlight-color: transparent;
  /* Disable double-tap zoom — rapid taps on the grid step the
     VM, and the user shouldn't accidentally pinch-zoom. */
  touch-action: manipulation;
}

.grid-view:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.grid-view:active {
  background: var(--pre-bg);
}

.tap-hint { display: none; }  /* shown only on touch pointers */

.ip-cell {
  background: var(--accent);
  color: #fff;
  border-radius: 2px;
  padding: 0 1px;
}

#state-view {
  margin: 0;
  padding: 0.5rem 0.8rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.6rem;
}

#state-view dt {
  color: var(--muted);
}

#state-view dd {
  margin: 0;
  overflow-wrap: anywhere;
}

#stack-view {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 13px;
  overflow: auto;
  max-height: 260px;
}

#stack-view .stack-body {
  margin: 0;
  padding: 0.5rem 0.8rem;
  white-space: pre;
  font-family: inherit;
  font-size: inherit;
}

#stack-view .stack-section + .stack-section {
  border-top: 1px solid var(--border);
}

#stack-view .stack-section-head {
  padding: 0.2rem 0.8rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  background: var(--pre-bg);
  border-bottom: 1px solid var(--border);
}

#stack-view .empty { color: var(--muted); font-style: italic; }

#stack-len { color: var(--muted); }

#debug-stdout {
  max-height: 160px;
}

.hint { color: var(--muted); font-weight: normal; font-size: 0.8em; margin-left: 0.5rem; }

/* ---------- Opcode reference ---------- */

.opcodes {
  margin-top: 1.5rem;
}

.opcodes details {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel-bg);
  padding: 0.5rem 0.9rem;
}

.opcodes summary {
  cursor: pointer;
  font-weight: 600;
  padding: 0.3rem 0;
  user-select: none;
}

.opcodes summary:focus { outline: none; }
.opcodes details[open] summary {
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.4rem;
}

.opcode-blurb {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0.4rem 0;
  line-height: 1.5;
}

.opcode-blurb a { color: var(--accent); }

.opcode-table-wrap { overflow-x: auto; }

.opcode-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
}

.opcode-table th,
.opcode-table td {
  padding: 0.32rem 0.55rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

.opcode-table thead th {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  background: var(--pre-bg);
  position: sticky;
  top: 0;
}

.opcode-table tbody tr:hover { background: var(--pre-bg); }

.opcode-table td:first-child {
  width: 4.5em;
  color: var(--muted);
  font-size: 0.8rem;
}

.opcode-table td:nth-child(2) {
  width: 5.5em;
  white-space: nowrap;
}

.opcode-table td:nth-child(2) code {
  font-size: 0.95rem;
  padding: 0.06em 0.32em;
  background: var(--pre-bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  margin-right: 0.15em;
}

.opcode-table td:nth-child(3) {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  white-space: nowrap;
  width: 7.5em;
}

.opcode-table td:nth-child(4) code {
  font-size: 0.85em;
  background: transparent;
  padding: 0;
}

/* ---------- Mobile ---------- */
/*
 * On narrow screens the editor and the debug panels stack vertically.
 * Without a sticky action bar the user has to scroll up to tap Step and
 * back down to see the grid/state update — the specific pain point the
 * user reported. We pin the debug toolbar to the bottom of the viewport
 * while in debug mode, hide the editor so the debug panels own the
 * full screen, and bump button touch targets to ≥44px.
 */
@media (max-width: 800px) {
  body { padding: 0.75rem 1rem 1rem; }

  /* iOS Safari auto-zooms when a focused input has font-size < 16px.
     Bump both editor textareas to 16px on mobile to suppress that
     zoom — the page would otherwise jump on every tap into the
     editor. Desktop sizes are unchanged. */
  #source, #stdin { font-size: 16px; }

  .toolbar {
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0.6rem;
  }

  .toolbar button {
    padding: 0.4rem 0.8rem;
    min-height: 38px;
  }

  .tap-hint { display: inline; }

  /* Sticky debug bar, only visible in debug mode. */
  body.debug-mode .toolbar-debug {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    margin: 0;
    border-radius: 0;
    border: none;
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.18);
    padding: 0.6rem 0.8rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
    z-index: 100;
    background: var(--panel-bg);
  }

  /* Reserve space at the page bottom so the last panel isn't clipped
     by the fixed toolbar. */
  body.debug-mode { padding-bottom: 5rem; }

  /* Editor takes the whole screen otherwise; hide it once the user has
     entered debug so the grid + state + stack + stdout are all visible
     without scrolling past an irrelevant textarea. */
  body.debug-mode .editor-section { display: none; }

  /* Compact the debug panels a bit so more fits in the first screen. */
  body.debug-mode .grid-view { max-height: 44vh; font-size: 12px; }
  body.debug-mode #stack-view { max-height: 28vh; }
  body.debug-mode #debug-stdout { max-height: 20vh; }

  /* The "hint" tagline to the right of the toolbar wraps weirdly on
     narrow screens; force a new line with reduced margin. */
  .toolbar-debug .hint {
    flex-basis: 100%;
    margin-left: 0;
    text-align: center;
  }
}
