/* math-hacking-session styles */

#landing,
#session,
#reveal {
  display: none;
}

body[data-state="landing"]  #landing  { display: block; }
body[data-state="session"]  #session  { display: block; }
body[data-state="review"]   #session  { display: block; }
body[data-state="reveal"]   #reveal   { display: block; }

/* ── Mobile layout guideline ─────────────────────────────────────────────────
 *
 * Mobile target: 360 px viewport (smallest common modern Android, ~10% global
 * share per 2026 StatCounter data; covers ~95% of mobile traffic when paired
 * with the 375 / 390 / 414+ iPhone/Android tiers). Legacy 320 px is rare
 * enough to defer.
 *
 * Effective content width budget:
 *   360 px viewport
 *   −  2× 1rem body padding (= 32 px)
 *   −  2× 1.25rem .terminal-body horizontal padding (= 40 px)
 *   ─────────────────────────────────────────────
 *   = 288 px usable content width on a 360 px phone
 *
 * --mobile-min-content-width is the budget that any single-line element should
 * fit within. Wider than this on a 360 px viewport → flag as a visual ding
 * and decide whether to (a) wrap, (b) shrink font, (c) drop column gaps,
 * or (d) accept overflow. New features should be vetted against this number
 * before merge.
 *
 * Known at-risk surfaces (audit 2026-06-06):
 *   - .picker-row — RESOLVED. CSS Grid at .picker-list level with
 *     `display: contents` on rows; streak field dropped; long handles
 *     wrap and push rank to next grid row (column alignment preserved).
 *   - .decrypt-row — RESOLVED. flex-wrap on the row; bar shrinks to
 *     min-width 10ch then wraps; "12 hacks" hidden.
 *   - .status-line during gameplay — left alone (already wraps OK per
 *     UX check).
 *   - .session-input-line — RESOLVED. answer-input is now flex:1 1 12ch
 *     so the [ skip ] [ submit ] buttons wrap to row 2 when narrow.
 * ──────────────────────────────────────────────────────────────────────── */

/* ── Terminal Theme ── */
:root {
  --bg: #0a0a0a;
  --fg: #00ff41;
  --accent: #00cc33;
  --dim: #007a1e;
  --font: 'Courier New', Courier, monospace;
  /* See "Mobile layout guideline" comment block above for derivation. */
  --mobile-min-content-width: 288px;
}
* { box-sizing: border-box; }
body { background: var(--bg); color: var(--fg); font-family: var(--font); margin: 0; padding: 1rem; min-height: 100vh; }
.terminal-window { max-width: 800px; margin: 2rem auto; border: 1px solid var(--dim); }
.terminal-header { background: var(--dim); color: var(--bg); padding: 0.3rem 0.75rem; font-size: 0.85em; user-select: none; }
.terminal-body { padding: 1rem 1.25rem; line-height: 1.8; }
/* The `hidden` attribute must win over component display rules
   (e.g. .prompt-line sets display:flex, which would otherwise show it). */
[hidden] { display: none !important; }
.boot-log { color: var(--dim); }
.boot-line { color: var(--dim); white-space: pre-wrap; }
/* Inline KaTeX math (e.g. the y=mx+b catchphrase) should read as terminal
   text, not a textbook: inherit the dim green and size; let KaTeX own spacing. */
.boot-line .katex { color: inherit; font-size: inherit; }
.boot-init-cmd { color: var(--fg); }
.boot-logo {
  color: var(--fg);
  white-space: pre;
  line-height: 1.1;
  margin: 0.75rem 0;
  /* Shrunk min + min-shrink so the ~48-char ASCII art fits inside the
     288 px content budget at 360 px viewport (was clamp(0.45rem,
     2.4vw, 0.85rem) which kept the logo at ~8.6 px font → 385 px wide,
     overflowing by ~99 px). */
  font-size: clamp(0.3rem, 1.8vw, 0.85rem);
}
.prompt-line { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; }
.prompt-arrow { color: var(--fg); }
/* Blank line above the (prompt-less) start button — see landing-ui spec §7. */
#boot-start-line { margin-top: 1.2em; }
.start-btn { background: transparent; border: 1px solid var(--fg); color: var(--fg); font-family: inherit; font-size: inherit; cursor: pointer; padding: 0.2em 0.75em; letter-spacing: 0.05em; }
.start-btn:hover { background: var(--fg); color: var(--bg); }
.start-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Disabled state — used by the rename/delete chips when the [N] new-handle
   row is selected (no profile to operate on), and by the handle-create
   confirm button while validation is failing. */
.start-btn:disabled,
.start-btn.dossier-chip-disabled {
  color: var(--dim);
  border-color: var(--dim);
  cursor: not-allowed;
  opacity: 0.5;
}
.start-btn:disabled:hover,
.start-btn.dossier-chip-disabled:hover {
  background: transparent;
  color: var(--dim);
  border-color: var(--dim);
}

/* engagement-v4: muted secondary CTA. Same shape as .start-btn, dimmed colors,
   slightly thinner border, no fill on hover — signals "this is here but not
   the path you'd take by default". */
.start-btn-muted { color: var(--dim); border-color: var(--dim); }
.start-btn-muted:hover { background: transparent; color: var(--fg); border-color: var(--fg); }

/* engagement-v4: landing greeting. Inherits .boot-line dim color; matches the
   catchphrase aesthetic so the eye reads "another prompt-less reveal line",
   not a UI chrome element. */
.landing-greeting { margin-top: 0.4em; color: var(--fg); }

/* engagement-v4 (post-feedback): secondary block below the primary
   [ press to start ] button. Single-line layout — dim label and muted
   button sit on one row ("Not you? [ switch ]"). Wraps on very narrow
   viewports so the button drops below the label. The 2.4em top margin
   creates a visible empty line between the primary CTA and the muted
   secondary line, so the eye reads two distinct sections rather than
   one stack of buttons. */
.landing-secondary-block {
  margin-top: 2.4em;
  display: flex;
  align-items: center;
  gap: 0.6em;
  flex-wrap: wrap;
}
.landing-secondary-label { color: var(--dim); font-size: 0.9em; }

#switch-user-screen { margin-top: 1.2em; }

/* Handle-create form follows the same layout as the rename block:
   typewriter heading on row 1, then a body that reveals after the
   typewriter finishes (Enter name: / > input / spacer / buttons).
   The body text inherits the same dim color treatment as rename. */
.handle-prompt { color: var(--dim); }
.handle-prompt .handle-prompt-row { margin-bottom: 0.25rem; }
.handle-prompt .handle-prompt-row.prompt-line { margin-top: 0.5rem; }
.handle-prompt-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* ── Session Screen ── */
.status-line { color: var(--accent); margin-bottom: 0.75rem; font-size: 0.9em; letter-spacing: 0.02em; }
.status-line .status-group { white-space: nowrap; }
.progress-bar { color: var(--dim); }
/* No inner scroll: at most 15 problems, so let the log grow naturally and
   let the whole page scroll if needed. */
.session-log { min-height: 4rem; margin-bottom: 0.5rem; }
.session-log .log-ok { color: var(--accent); }
.session-log .log-err { color: #cc3333; }
.session-log .log-entry { display: block; }
.problem-prompt { color: var(--fg); margin-bottom: 0.5rem; min-height: 1.5em; font-size: 1.1em; }
.answer-input {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg);
  color: var(--fg);
  font-family: inherit;
  font-size: inherit;
  outline: none;
  /* Note: handle-input + dossier-rename-input override these widths via
     their own rules. The session #answer-input (game answer) takes the
     ~38vw width set in the session input section below. */
  flex: 1 1 12ch;
  min-width: 6ch;
  caret-color: var(--fg);
  padding: 0.1em 0;
}
/* Session-specific override: game-answer input is exactly the math drill
   field — capped at ~38% of the viewport so it doesn't dominate the row.
   The 6em min-width keeps it usable on narrow viewports. */
#answer-input {
  flex: 0 0 38vw;
  width: 38vw;
  min-width: 6em;
  max-width: 38vw;
}
.answer-input:focus { border-bottom-color: var(--accent); }
.submit-btn {
  background: transparent;
  border: 1px solid var(--dim);
  color: var(--dim);
  font-family: inherit;
  font-size: 0.8em;
  cursor: pointer;
  padding: 0.1em 0.5em;
  margin-left: 0.5rem;
}
.submit-btn:hover { background: var(--dim); color: var(--bg); }
.submit-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .typewriter-char { animation: none !important; }
}

/* ── Skip log entry ── */
.session-log .log-skip { color: #aa9900; }

/* ── Firewall-blocked shake (Slice 3) ── */
.firewall-status { min-height: 1.2em; font-size: 0.85em; color: #cc6633; }
@keyframes firewall-shake {
  0%   { transform: translateX(0); }
  20%  { transform: translateX(-6px); }
  40%  { transform: translateX(6px); }
  60%  { transform: translateX(-4px); }
  80%  { transform: translateX(4px); }
  100% { transform: translateX(0); }
}
.firewall-blocked {
  animation: firewall-shake 600ms ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .firewall-blocked {
    animation: none;
  }
}

/* Two-line breathing-room between the status line and the current
   problem. Targets ~2 line-heights at the surrounding 1.8 line-height. */
.problem-spacer { height: 2.4em; }

/* Submit row sits below the input row. Light top margin gives it
   breathing room without dominating the layout. */
#session-submit-row { margin-top: 0.6em; }

/* ── Session: skip + lucky buttons ── */
.session-input-line { flex-wrap: wrap; gap: 0.4rem; }
.session-action-btn {
  background: transparent;
  border: 1px solid var(--dim);
  color: var(--dim);
  font-family: inherit;
  font-size: 0.8em;
  cursor: pointer;
  padding: 0.1em 0.5em;
}
.session-action-btn:hover { background: var(--dim); color: var(--bg); }
.session-action-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.session-action-btn[disabled] { opacity: 0.3; cursor: default; pointer-events: none; }

/* ── Decryption header (ALWAYS visible at top of #session) ── */
.decrypt-header { margin-bottom: 0.5rem; padding: 0.2rem 0; }
/* Both rows (Decrypting bar + Password chars) use flex-wrap so a wide
   element drops to its own line on narrow viewports rather than
   overflowing horizontally. Bar/chars shrink to a sensible min-width
   first; below that, flex-wrap kicks in. */
.decrypt-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; line-height: 1.6; }
.decrypt-label { color: var(--accent); min-width: 11ch; flex: 0 0 auto; }
.decrypt-bar { color: var(--fg); letter-spacing: 0.05em; flex: 1 1 0; min-width: 10ch; overflow: hidden; }
/* Drop min-width so the pct sits right after the bar (no padding column).
   Use a tighter left margin to override the row's 0.5rem flex gap. */
.decrypt-pct { color: var(--dim); flex: 0 0 auto; margin-left: -0.25rem; }
.decrypt-chars { letter-spacing: 0.15em; font-family: var(--font); font-size: 1.1em; flex: 1 1 auto; min-width: 10ch; overflow-wrap: anywhere; }
.decrypt-char--bright { color: var(--fg); font-weight: bold; }
.decrypt-char--dim { color: var(--dim); }
/* Hide "12 hacks" — keeps the bar row clean under the 288px mobile
   budget (the count is implicit in the bar fill + pct anyway). */
.hack-counter { display: none; }
.decrypt-lucky-btn {
  background: transparent;
  border: 1px solid var(--dim);
  color: var(--dim);
  font-family: inherit;
  font-size: 0.8em;
  cursor: pointer;
  padding: 0.1em 0.5em;
  margin-left: auto;
}
.decrypt-lucky-btn:hover { background: var(--dim); color: var(--bg); }
.decrypt-lucky-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.decrypt-lucky-btn[disabled] { opacity: 0.3; cursor: default; pointer-events: none; }
.decrypt-divider { border: none; border-top: 1px dashed var(--dim); margin: 0.3rem 0 0.75rem 0; }

/* ── Box-style review / reveal ── */
.box-review {
  border: 1px solid var(--dim);
  margin-bottom: 1rem;
  font-size: 0.9em;
}
.box-header {
  background: var(--dim);
  color: var(--bg);
  padding: 0.2rem 0.75rem;
  font-size: 0.85em;
  user-select: none;
  letter-spacing: 0.05em;
}
.reveal-header { background: var(--fg); }
.box-body { padding: 0.6rem 1rem; }
.box-summary-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.25rem; }
.box-label { color: var(--dim); min-width: 9ch; }
.box-score { color: var(--fg); min-width: 7ch; }
.box-bar { letter-spacing: 0; color: var(--fg); }
.box-pct { color: var(--dim); min-width: 4ch; }
.box-avgtime { color: var(--fg); }
.box-divider { color: var(--dim); margin: 0.5rem 0 0.25rem; }
.box-type-row { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.15rem; }
.box-type-icon { color: var(--accent); min-width: 2ch; }
.box-type-label { color: var(--dim); min-width: 5ch; }
.box-type-score { color: var(--fg); min-width: 5ch; }
.box-type-pct { color: var(--dim); min-width: 4ch; }
.box-type-time { color: var(--dim); }
.box-actions { margin-top: 0.5rem; }
.box-btn {
  background: transparent;
  border: 1px solid var(--dim);
  color: var(--dim);
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  padding: 0.1em 0.6em;
}
.box-btn:hover { background: var(--dim); color: var(--bg); }
.box-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.box-details-section { margin-top: 0.25rem; }
.box-detail-row {
  display: flex; gap: 0.5rem; font-size: 0.85em;
  padding: 0.1em 0; border-bottom: 1px solid var(--dim);
}
.box-detail-num { color: var(--dim); min-width: 4ch; }
.box-detail-problem { flex: 2; color: var(--fg); }
.box-detail-expected { flex: 1; color: var(--accent); }
.box-detail-input { flex: 1; color: var(--fg); }
.box-detail-time { color: var(--dim); min-width: 5ch; }

/* ── Reveal page ── */
.box-review--reveal .box-header { letter-spacing: 0.1em; }
.reveal-brute { color: #ff4444; font-weight: bold; margin-bottom: 0.5rem; }
.reveal-row { margin-bottom: 0.25rem; color: var(--dim); }
.reveal-accent { color: var(--fg); }
.reveal-steps { margin: 0.5rem 0; }
.reveal-step { color: var(--accent); margin-bottom: 0.15rem; }
.reveal-footer { margin-top: 0.5rem; color: var(--dim); letter-spacing: 0.05em; }
.reveal-stats { border-top: 1px solid var(--dim); padding-top: 0.5rem; }

/* ── Password Box overlay ── */
.pw-box-overlay {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.85);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
}
.pw-box-overlay[hidden] { display: none !important; }
.pw-box-inner {
  border: 1px solid var(--fg);
  box-shadow: 0 0 20px var(--fg);
  background: var(--bg);
  padding: 1.5rem 2rem;
  min-width: 30ch;
  max-width: 50ch;
  font-family: var(--font);
}
.pw-box-msg { color: var(--fg); margin-bottom: 1rem; line-height: 1.5; }
.pw-box-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
.pw-box-label { color: var(--dim); white-space: nowrap; }
.pw-box-arrow { color: var(--fg); }
.pw-box-input {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg);
  color: var(--fg);
  font-family: inherit;
  font-size: inherit;
  outline: none;
  flex: 1;
  min-width: 10ch;
  caret-color: var(--fg);
  padding: 0.1em 0;
}
.pw-box-input:focus { border-bottom-color: var(--accent); }
.pw-action-row { gap: 0.75rem; margin-top: 0.75rem; }
.pw-box-btn {
  background: transparent;
  border: 1px solid var(--fg);
  color: var(--fg);
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  padding: 0.2em 0.75em;
  letter-spacing: 0.05em;
}
.pw-box-btn:hover { background: var(--fg); color: var(--bg); }
.pw-box-btn:focus { outline: 2px solid var(--accent); outline-offset: 2px; }
.pw-box-flash {
  margin-top: 0.5rem;
  min-height: 1.2em;
  font-weight: bold;
}
.pw-box-flash--denied { color: #ff4444; }

/* ── Boot post-catchphrase spacing + whoami prompt ── */
.boot-breathing-room { height: 1.2em; }

/* ── Dossier block ── */
.dossier { margin: 0.5rem 0; font-size: 0.9em; font-family: var(--font); color: var(--dim); }
/* white-space: pre-wrap preserves the padding inside the key cell. */
.dossier-line { line-height: 1.8; letter-spacing: 0.03em; white-space: pre-wrap; }
/* The dossier prompt `> math-hax --login` matches the bright-green
   `> math-hax --init` line that appears during boot (.boot-init-cmd). */
.dossier-prompt { color: var(--fg); }
.dossier-key { color: var(--dim); }
.dossier-value { color: var(--accent); }
.dossier-encrypted { color: var(--dim); }
.rank-zero { color: var(--fg); text-shadow: 0 0 5px var(--accent); }

/* ── Profile picker ── */
/* Picker rows: shared CSS Grid so num/handle/rank columns align across rows
   (table-like). Each <li> uses display: contents so its three field spans
   participate in the parent <ul>'s grid. A long handle wraps inside its
   grid cell (overflow-wrap: anywhere) which pushes the rank to the next
   grid row in the SAME rank column — visually the rank stays "aligned to
   the column" even when its row's handle wrapped. */
.picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  color: var(--dim);
  font-family: var(--font);
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0 0.75rem;
  align-items: baseline;
  line-height: 1.8;
  cursor: pointer;
}
.picker-row { display: contents; }
.picker-row[aria-selected="true"] > * { color: var(--fg); }
.picker-row-num    { grid-column: 1; }
.picker-row-handle { grid-column: 2; min-width: 0; overflow-wrap: anywhere; }
.picker-row-rank   { grid-column: 3; }

/* ── Dossier actions (rename / delete chips) ── */
.dossier-actions { margin-top: 0.5rem; display: flex; gap: 0.5rem; }
.dossier-delete-armed { color: #cc6633; }
/* Body text in the rename block reads as dim (matches unhighlighted picker
   rows). The heading row keeps `.prompt-arrow` / `.boot-init-cmd` overrides
   so its `>` + `math-hax --rename` shows as bright fg — consistent with the
   `> math-hax --select` / `> math-hax --login` lines elsewhere. Buttons,
   input, and hint each define their own color and aren't affected. */
.dossier-rename-block {
  margin-top: 0.5rem;
  color: var(--dim);
}
/* flex-wrap: wrap so the NEW: row (label + input + [confirm] + [cancel])
   doesn't blow past the 288px mobile content budget — input + buttons drop
   to row 2 when the viewport is narrow. Same pattern used by
   .session-input-line / .decrypt-row elsewhere in this file. */
.dossier-rename-block .dossier-rename-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
  flex-wrap: wrap;
}
.dossier-rename-input {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--fg);
  color: var(--fg);
  font-family: inherit;
  font-size: inherit;
  outline: none;
  /* Mobile budget: flex so the input absorbs leftover width; min-width
     keeps the field readable when squeezed; at desktop widths the input
     stays around 14ch by basis. */
  flex: 1 1 12ch;
  min-width: 8ch;
  max-width: 14ch;
  caret-color: var(--fg);
  padding: 0.1em 0;
}
.dossier-rename-input:focus { border-bottom-color: var(--accent); }
.dossier-rename-hint { color: var(--dim); font-size: 0.85em; margin-top: 0.2rem; }

/* ── Handle prompt ── */
.handle-prompt { margin-top: 0.75rem; }
.handle-label { color: var(--accent); font-size: 0.9em; display: block; margin-bottom: 0.25rem; }
.handle-input { width: 14ch; }
.handle-error { color: #ff4444; font-size: 0.85em; min-height: 1.2em; margin-top: 0.2rem; }
/* No inner scroll: the review list holds at most 15 problems, so let it
   grow to its natural height and let the whole page scroll if needed. */
.review-list-container {
  margin-bottom: 1rem;
}
.review-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.review-item {
  padding: 0.15em 0;
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
}
.review-item[data-correct="true"] .review-marker,
.review-item[data-correct="true"] .review-tag { color: var(--accent); }
.review-item[data-correct="false"] .review-marker,
.review-item[data-correct="false"] .review-tag { color: #ff4444; }
.review-item .review-line { color: var(--fg); flex: 1; }
