:root {
  --bg: #0b0f16;
  --panel-bg: #10161f;
  --panel-border: #263042;
  --text: #e5edf5;
  --text-dim: #8fa2b8;
  --accent: #3ee6c6;
  --accent-bright: #7cf7dd;
  --accent-warm: #ffb454;
  --danger: #ff6b6b;
  --address-bus: #ffb454;
  --data-bus: #3ee6c6;
  font-family: "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic", sans-serif;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  height: 100%;
}

#app {
  display: flex;
  flex-direction: column;
  /* Must be a hard height, not min-height: a long program (e.g. bubble
     sort's ~100 lines) would otherwise make the whole page grow to fit
     the code panel's content, pushing the CPU diagram below the fold
     instead of the code panel scrolling internally within its own
     bounded area. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.app-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  background: var(--panel-bg);
  border-bottom: 1px solid var(--panel-border);
}

.app-header h1 {
  font-size: 1.2rem;
  margin: 0;
  color: var(--accent-bright);
  letter-spacing: 0.04em;
}

.tutorial-btn {
  background: transparent;
  color: var(--text-dim);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.72rem;
  cursor: pointer;
}
.tutorial-btn:hover {
  color: var(--accent-bright);
  border-color: var(--accent);
}

.pipeline-indicator {
  display: flex;
  gap: 6px;
}

.pipeline-stage {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--panel-border);
  font-size: 0.7rem;
  color: var(--text-dim);
  letter-spacing: 0.05em;
}

.pipeline-stage--active {
  background: var(--accent);
  color: #04241f;
  border-color: var(--accent);
}

.debugger-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-left: auto;
}

.debugger-controls button {
  background: #182231;
  color: var(--text);
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  font-size: 0.85rem;
}

.debugger-controls button:hover {
  border-color: var(--accent);
  color: var(--accent-bright);
}

.speed-control {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: var(--text-dim);
}

.clock-count {
  font-variant-numeric: tabular-nums;
  color: var(--accent-warm);
  font-size: 0.8rem;
}

.mobile-tabs {
  display: none;
}

.layout {
  flex: 1;
  display: grid;
  grid-template-columns: 340px 1fr 300px;
  grid-template-rows: repeat(3, 1fr);
  gap: 10px;
  padding: 10px;
  min-height: 0;
}

#panel-code {
  grid-column: 1;
  grid-row: 1 / 4;
}
#panel-diagram {
  grid-column: 2;
  grid-row: 1 / 4;
}
#panel-registers {
  grid-column: 3;
  grid-row: 1;
}
#panel-ram {
  grid-column: 3;
  grid-row: 2;
}
#panel-stats {
  grid-column: 3;
  grid-row: 3;
}

/* Each of these is the scrollable content area of a panel that shares the
   right column with two others. Without flex:1 + min-height:0, a child
   only takes its natural content height instead of being bounded by the
   panel's actual available space, so overflow-y:auto on the grandchild
   (.ram-grid, .stats-root's own children) never actually engages - the
   content just gets clipped by the panel's own overflow:hidden instead of
   scrolling (the exact bug reported for the RAM panel: only the first
   handful of the 256 bytes were visible, with no way to scroll to the
   rest). Mirrors the same fix already applied to .editor-root/.code-lineview. */
#register-root,
#ram-root {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

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

.panel-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  border-bottom: 1px solid var(--panel-border);
}

.panel-header select,
.panel-header button {
  margin-left: auto;
  background: #182231;
  color: var(--text);
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 0.75rem;
}

.editor-hint {
  padding: 2px 10px;
  font-size: 0.68rem;
  color: var(--text-dim);
}

.panel-subheader {
  padding: 6px 10px 2px;
  font-size: 0.7rem;
  color: var(--text-dim);
  letter-spacing: 0.08em;
}

.editor-root {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}

.code-textarea,
.code-lineview {
  flex: 1;
  min-height: 0;
  width: 100%;
  overflow-y: auto;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.82rem;
  line-height: 1.5;
  padding: 8px 10px;
  white-space: pre;
}

.code-textarea {
  background: transparent;
  color: var(--text);
  border: none;
  resize: none;
}

.code-textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

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

.code-line {
  padding: 0 4px;
  border-radius: 3px;
}

.code-line--active {
  background: rgba(62, 230, 198, 0.18);
  color: var(--accent-bright);
}

.code-line--breakpointable {
  cursor: pointer;
  position: relative;
  padding-left: 14px;
}
.code-line--breakpointable:hover {
  background: rgba(255, 180, 84, 0.1);
}
.code-line--breakpoint::before {
  content: "";
  position: absolute;
  left: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--danger);
}
.code-line--breakpoint {
  color: var(--danger);
}
.code-line--breakpoint.code-line--active {
  background: rgba(255, 107, 107, 0.22);
}

.code-error {
  margin: 0;
  padding: 6px 10px;
  color: var(--danger);
  font-size: 0.78rem;
  white-space: pre-wrap;
}

.machine-code {
  margin: 0;
  padding: 6px 10px 10px;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.72rem;
  color: var(--text-dim);
  max-height: 120px;
  overflow-y: auto;
}

.cpu-diagram {
  flex: 1;
  width: 100%;
  min-height: 0;
}

.explain-text {
  padding: 8px 12px;
  border-top: 1px solid var(--panel-border);
  font-size: 0.85rem;
  color: var(--accent-bright);
  min-height: 2.4em;
}

/* SVG diagram */
.bus-rail {
  stroke-width: 2;
}
.bus-rail--address {
  stroke: var(--address-bus);
  opacity: 0.5;
}
.bus-rail--data {
  stroke: var(--data-bus);
  opacity: 0.5;
}
.bus-rail-label {
  font-size: 11px;
  fill: var(--text-dim);
}

.component-box {
  fill: #16202e;
  stroke: var(--panel-border);
  stroke-width: 1.5;
}
.component-label {
  fill: var(--text-dim);
  font-size: 11px;
  text-anchor: middle;
}
.component-value {
  fill: var(--accent-bright);
  font-size: 13px;
  font-family: "SFMono-Regular", Consolas, monospace;
  text-anchor: middle;
}

.component-box--flash,
.component-box--flash-write,
.component-box--flash-alu,
.component-box--flash-flag,
.component-box--flash-pc,
.component-box--flash-decode,
.component-box--flash-stack,
.component-box--flash-halt {
  animation: flashPulse 0.55s ease-out;
}

@keyframes flashPulse {
  0% {
    fill: var(--accent);
    stroke: var(--accent-bright);
  }
  100% {
    fill: #16202e;
    stroke: var(--panel-border);
  }
}

.bus-token rect {
  fill: #0b0f16;
  stroke: var(--accent-bright);
  stroke-width: 1.5;
}
.bus-token text {
  fill: var(--accent-bright);
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 11px;
}
.bus-token--address rect {
  stroke: var(--address-bus);
}
.bus-token--address text {
  fill: var(--address-bus);
}

.register-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  font-family: "SFMono-Regular", Consolas, monospace;
}
.register-table th,
.register-table td {
  padding: 4px 8px;
  text-align: right;
  border-bottom: 1px solid var(--panel-border);
}
.register-table th:first-child,
.register-table td:first-child {
  text-align: left;
  color: var(--text-dim);
}
.register-row--active {
  background: rgba(62, 230, 198, 0.12);
}

.flags-view {
  display: flex;
  gap: 8px;
  padding: 8px 10px;
}
.flag {
  padding: 3px 8px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  font-size: 0.75rem;
  color: var(--text-dim);
  font-family: "SFMono-Regular", Consolas, monospace;
}
.flag--on {
  background: var(--accent);
  color: #04241f;
  border-color: var(--accent);
}

.array-view-root {
  padding: 8px 10px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.array-view-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.array-view-label {
  font-size: 0.68rem;
  color: var(--text-dim);
}
.array-view-cells {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.array-view-cell {
  background: #131b26;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 4px 8px;
  min-width: 34px;
  text-align: center;
  font-family: "SFMono-Regular", Consolas, monospace;
}
.array-view-index {
  font-size: 0.6rem;
  color: var(--text-dim);
}
.array-view-value {
  font-size: 0.95rem;
  color: var(--accent-bright);
}
.array-view-cell--active {
  border-color: var(--accent);
  background: rgba(62, 230, 198, 0.15);
}

.ram-grid {
  display: grid;
  grid-template-columns: repeat(16, 1fr);
  gap: 2px;
  padding: 8px;
  overflow-y: auto;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.65rem;
}
.ram-cell {
  text-align: center;
  padding: 2px 0;
  border-radius: 3px;
  color: var(--text-dim);
  background: #131b26;
}
.ram-cell--active {
  background: var(--accent);
  color: #04241f;
  font-weight: bold;
}

.stats-root {
  flex: 1;
  padding: 8px 10px;
  overflow-y: auto;
  min-height: 0;
}
.stats-intro {
  margin: 0 0 8px;
  font-size: 0.72rem;
  color: var(--text-dim);
}
.stats-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.stats-card {
  background: #131b26;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 6px 8px;
}
.stats-value {
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 1.05rem;
  color: var(--accent-bright);
}
.stats-label {
  font-size: 0.62rem;
  color: var(--text-dim);
  margin-top: 2px;
}
.stats-breakdown-title {
  font-size: 0.7rem;
  color: var(--text-dim);
  letter-spacing: 0.06em;
  margin-bottom: 4px;
}
.stats-breakdown {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.stats-breakdown-row {
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 0.72rem;
  color: var(--text);
  display: flex;
  justify-content: space-between;
  padding: 2px 4px;
}
.stats-breakdown-row--empty {
  color: var(--text-dim);
  font-family: inherit;
}

/* The backdrop itself is transparent and click-through: the dimming
   effect instead comes from .onboarding-highlight's huge box-shadow on
   the real element being introduced, so the actual UI stays visible
   (and even usable) behind the tutorial instead of a generic modal. */
.onboarding {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  pointer-events: none;
}
.onboarding[hidden] {
  display: none;
}
.onboarding-card {
  position: relative;
  z-index: 52;
  pointer-events: auto;
  background: var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: 12px;
  padding: 24px;
  max-width: 380px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
.onboarding-highlight {
  position: relative;
  /* Must stay below .onboarding's z-index (50): this lives in the normal
     page stacking context (not inside the overlay), so if it ever
     out-ranked the overlay, the highlighted element's own content (e.g.
     the SVG diagram) would paint over the onboarding card sitting inside
     the overlay's stacking context, hiding it entirely. Low enough to
     stay under the overlay, high enough to sit above sibling panels. */
  z-index: 10;
  box-shadow:
    0 0 0 3px var(--accent),
    0 0 24px 4px rgba(62, 230, 198, 0.5),
    0 0 0 9999px rgba(4, 8, 14, 0.75);
  border-radius: 10px;
  transition: box-shadow 0.2s ease;
}
.onboarding-card h2 {
  margin-top: 0;
  color: var(--accent-bright);
  font-size: 1.05rem;
}
.onboarding-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}
.onboarding-actions button {
  background: #182231;
  color: var(--text);
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 6px 14px;
  cursor: pointer;
}
#onboarding-next {
  background: var(--accent);
  color: #04241f;
  border-color: var(--accent);
  font-weight: 600;
}

.toast-root {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
  max-width: 320px;
  pointer-events: none;
}
.toast {
  background: var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 0.78rem;
  color: var(--text);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  cursor: pointer;
  pointer-events: auto;
}
.toast--visible {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 900px) {
  .toast-root {
    left: 12px;
    right: 12px;
    bottom: 60px;
    max-width: none;
  }
}

@media (max-width: 900px) {
  .mobile-tabs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 10px 8px;
    background: var(--panel-bg);
    border-bottom: 1px solid var(--panel-border);
  }
  .mobile-tabs-hint {
    flex-basis: 100%;
    font-size: 0.72rem;
    color: var(--accent-bright);
  }
  .mobile-tab {
    background: #182231;
    color: var(--text);
    border: 1px solid var(--panel-border);
    border-radius: 999px;
    padding: 9px 16px;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
  }
  .mobile-tab--active {
    background: var(--accent);
    color: #04241f;
    border-color: var(--accent);
  }
  /* Draws the eye to the tab bar right after load, since a first-time
     visitor otherwise sees only the CODE panel and may not realize the
     diagram/registers/RAM live behind these tabs (a real gap a user hit:
     they didn't notice the tabs existed at all). Settles after a few
     pulses so it doesn't nag. */
  .mobile-tabs--attention .mobile-tab:not(.mobile-tab--active) {
    animation: tabAttentionPulse 1.6s ease-in-out 3;
  }
  @keyframes tabAttentionPulse {
    0%,
    100% {
      box-shadow: none;
    }
    50% {
      box-shadow: 0 0 0 2px var(--accent-warm);
    }
  }

  .layout {
    display: block;
    padding: 8px;
    /* #app now clips overflow (see the desktop layout fix above), so on
       mobile - where only one panel is visible at a time via tabs -
       .layout itself needs to be the scroll container for that panel's
       content instead of relying on the page to grow. */
    overflow-y: auto;
  }
  .panel {
    display: none;
    margin-bottom: 10px;
    min-height: 60vh;
  }
  .panel--mobile-active {
    display: flex;
  }

  .debugger-controls {
    margin-left: 0;
    width: 100%;
    justify-content: space-between;
  }
}
