/* styles.css — arcade-neon dark theme for the Neovim keymap trainer.
   Designed for focus: high contrast, one thing on screen at a time, big
   satisfying feedback, and a "reduce motion" path for everything animated. */

:root {
  --bg: #0b0e14;
  --bg-2: #11151f;
  --panel: #161b26;
  --panel-2: #1c2230;
  --border: #2a3244;
  --text: #e6ebf5;
  --muted: #8b95ab;
  --accent: #7dd3fc;
  --good: #86efac;
  --bad: #fca5a5;
  --hint: #fcd34d;
  --shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  --font:
    ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  color: var(--text);
  background: radial-gradient(
      1200px 700px at 50% -10%,
      #16203a 0%,
      var(--bg) 55%
    )
    fixed;
  overflow-x: hidden;
}

/* faint animated grid backdrop */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(rgba(125, 211, 252, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(125, 211, 252, 0.05) 1px, transparent 1px);
  background-size: 44px 44px;
  mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 70%);
  pointer-events: none;
  z-index: 0;
}

#fx {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 60;
}

#app {
  position: relative;
  z-index: 1;
  max-width: 960px;
  margin: 0 auto;
  padding: 24px 20px 60px;
  min-height: 100%;
}

/* ── screens ─────────────────────────────────────────────────────────── */
.screen {
  display: none;
  animation: fade 0.25s ease;
}
.screen.active {
  display: block;
}
@keyframes fade {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* ── home header ─────────────────────────────────────────────────────── */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.brand h1 {
  font-size: 30px;
  margin: 0;
  letter-spacing: -0.5px;
}
.brand .glow {
  color: var(--accent);
  text-shadow: 0 0 18px rgba(125, 211, 252, 0.5);
}
.brand p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 14px;
}
.toolbar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* rank card */
.rank {
  background: linear-gradient(135deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px 18px;
  display: flex;
  align-items: center;
  gap: 16px;
  box-shadow: var(--shadow);
  margin-bottom: 22px;
}
.rank-badge {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 74px;
  height: 74px;
  border-radius: 14px;
  background: radial-gradient(circle at 40% 30%, #24304a, #131826);
  border: 1px solid var(--border);
  flex: 0 0 auto;
}
#rank-level {
  font-weight: 800;
  font-size: 22px;
  color: var(--accent);
}
.rank-badge small {
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 1px;
}
.rank-body {
  flex: 1;
  min-width: 200px;
}
.rank-line {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
#rank-title {
  font-weight: 700;
  font-size: 18px;
}
#rank-xp {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.bar {
  height: 10px;
  background: #0c1119;
  border-radius: 99px;
  overflow: hidden;
  margin: 8px 0 6px;
  border: 1px solid var(--border);
}
.bar > span {
  display: block;
  height: 100%;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--accent), #a78bfa);
  transition: width 0.5s ease;
}
#rank-next {
  color: var(--muted);
  font-size: 12px;
}
.rank-side {
  text-align: center;
  flex: 0 0 auto;
}
.rank-side b {
  display: block;
  font-size: 18px;
}
.rank-side span {
  color: var(--muted);
  font-size: 11px;
}

/* ── buttons ─────────────────────────────────────────────────────────── */
.btn {
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 9px 14px;
  cursor: pointer;
  transition:
    transform 0.08s ease,
    background 0.15s ease,
    border-color 0.15s ease;
}
.btn:hover {
  background: #252c3d;
  border-color: #3a445c;
}
.btn:active {
  transform: translateY(1px) scale(0.98);
}
.btn.primary {
  background: linear-gradient(135deg, var(--accent), #a78bfa);
  color: #0b0e14;
  border: none;
  box-shadow: 0 6px 20px rgba(125, 211, 252, 0.25);
}
.btn.primary:hover {
  filter: brightness(1.06);
}
.btn.big {
  font-size: 17px;
  padding: 14px 26px;
  border-radius: 12px;
}
.btn.ghost {
  background: transparent;
}
.btn.danger:hover {
  border-color: var(--bad);
  color: var(--bad);
}

.cta-row {
  display: flex;
  gap: 12px;
  align-items: center;
  margin: 20px 0 26px;
  flex-wrap: wrap;
}
.cta-row .hint-text {
  color: var(--muted);
  font-size: 13px;
}

/* ── section heading ─────────────────────────────────────────────────── */
.section-h {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  font-size: 13px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.section-h::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--border);
}

/* ── world grid ──────────────────────────────────────────────────────── */
#world-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}
.world-tile {
  text-align: left;
  font-family: inherit;
  color: var(--text);
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 16px;
  cursor: pointer;
  transition:
    transform 0.12s ease,
    border-color 0.15s ease,
    box-shadow 0.15s ease;
  position: relative;
  overflow: hidden;
}
.world-tile::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--accent);
  opacity: 0.9;
}
.world-tile:hover:not(.locked) {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
}
.world-tile.locked {
  opacity: 0.5;
  cursor: not-allowed;
  filter: grayscale(0.6);
}
.world-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.world-icon {
  font-size: 30px;
}
.world-title {
  font-weight: 800;
  font-size: 17px;
  margin: 10px 0 4px;
}
.world-blurb {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.45;
  min-height: 36px;
}
.world-foot {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 12px;
  flex-wrap: wrap;
}
.world-count {
  font-size: 12px;
  color: var(--muted);
}
.world-badge {
  font-size: 11px;
  font-weight: 700;
  color: var(--good);
  background: rgba(134, 239, 172, 0.12);
  padding: 2px 8px;
  border-radius: 99px;
}
.world-lock {
  font-size: 12px;
  color: var(--muted);
}

/* progress ring */
.ring-bg {
  fill: none;
  stroke: #0c1119;
  stroke-width: 4;
}
.ring-fg {
  fill: none;
  stroke-width: 4;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  transition: stroke-dashoffset 0.6s ease;
}
.ring-label {
  fill: var(--muted);
  font-size: 10px;
  font-family: var(--mono);
  font-weight: 700;
}

/* ── play screen ─────────────────────────────────────────────────────── */
.play-hud {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
#play-world {
  font-weight: 700;
}
.hud-spacer {
  flex: 1;
}
.hud-metric {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}
.hud-metric small {
  color: var(--muted);
  font-weight: 500;
  font-size: 11px;
  margin-right: 4px;
}
#hud-combo {
  opacity: 0;
  transform: scale(0.8);
  transition: 0.15s ease;
  color: var(--hint);
  font-weight: 800;
}
#hud-combo.show {
  opacity: 1;
  transform: scale(1);
}
#round-count {
  color: var(--muted);
  font-size: 13px;
  margin-bottom: 6px;
}
.play-bar {
  height: 6px;
  background: #0c1119;
  border-radius: 99px;
  overflow: hidden;
  border: 1px solid var(--border);
  margin-bottom: 22px;
}
#progress-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--accent), #a78bfa);
  transition: width 0.4s ease;
}

.card {
  background: linear-gradient(160deg, var(--panel), var(--panel-2));
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 30px 26px;
  box-shadow: var(--shadow);
  text-align: center;
  position: relative;
}
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 20px;
  padding: 1px;
  background: linear-gradient(160deg, var(--accent), transparent 60%);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0.4;
  pointer-events: none;
}
.card-chip {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 12px;
  border-radius: 99px;
  margin-bottom: 14px;
}
.card-label {
  font-size: 15px;
  color: var(--accent);
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.card-prompt {
  font-size: 25px;
  font-weight: 700;
  line-height: 1.35;
  margin: 8px auto 18px;
  max-width: 620px;
}
.mastery-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: 16px;
}
.dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #2a3244;
}
.dot.on {
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
}
.prompt-instr {
  color: var(--muted);
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  margin-bottom: 12px;
}

/* pressed keys live area */
.pressed {
  min-height: 60px;
  display: flex;
  gap: 12px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

/* keycaps */
.kc-group {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  transition: transform 0.1s ease;
}
.kc-group.lit .kc {
  border-color: var(--accent);
  color: var(--text);
  box-shadow:
    0 3px 0 #0a2a3a,
    0 0 14px rgba(125, 211, 252, 0.35);
}
.kc {
  font-family: var(--mono);
  font-size: 18px;
  font-weight: 700;
  min-width: 40px;
  height: 46px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text);
  background: linear-gradient(180deg, #232a3a, #171d29);
  border: 1px solid #384158;
  border-radius: 9px;
  box-shadow:
    0 3px 0 #0c1119,
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.kc-wide {
  min-width: 96px;
}
.kc-leader {
  position: relative;
}
.kc-leader::after {
  content: "leader";
  position: absolute;
  bottom: -14px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  color: var(--muted);
  letter-spacing: 1px;
}
.kc-plus {
  color: var(--muted);
  font-weight: 700;
  font-size: 13px;
}

/* answer reveal */
.answer-reveal {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px dashed var(--border);
}
.answer-reveal.hidden {
  display: none;
}
.reveal-keys {
  display: flex;
  gap: 12px;
  justify-content: center;
  margin-bottom: 10px;
}
.reveal-alt {
  color: var(--muted);
  font-size: 12px;
  font-family: var(--mono);
  margin-bottom: 6px;
}
.reveal-mnemonic {
  color: var(--hint);
  font-size: 14px;
}

/* feedback banner */
.feedback {
  min-height: 26px;
  margin-top: 16px;
  font-weight: 700;
  font-size: 16px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.feedback.show {
  opacity: 1;
}
.feedback.good {
  color: var(--good);
}
.feedback.bad {
  color: var(--bad);
}
.feedback.hint {
  color: var(--hint);
}

.play-foot {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 22px;
}

/* ── on-screen keypad (touch input) ───────────────────────────────────────
   Phones/tablets have no Ctrl key, so touch devices type on this instead of
   the OS soft keyboard. Hidden on desktop (keyboard-driven there). */
.keypad {
  display: none;
}
body.touch .keypad {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 18px auto 0;
  max-width: 520px;
  user-select: none;
  -webkit-user-select: none;
}
.kp-row {
  display: flex;
  gap: 7px;
  justify-content: center;
}
.kp-key {
  flex: 1 1 0;
  min-width: 0;
  height: 52px;
  padding: 0 4px;
  font-family: var(--mono);
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  background: linear-gradient(180deg, #232a3a, #171d29);
  border: 1px solid #384158;
  border-radius: 9px;
  box-shadow:
    0 3px 0 #0c1119,
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
  cursor: pointer;
  touch-action: manipulation;
  transition: transform 0.05s ease;
}
.kp-key:active {
  transform: translateY(2px);
  box-shadow:
    0 1px 0 #0c1119,
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.kp-mod {
  font-family: var(--font);
  font-size: 14px;
  color: var(--muted);
}
.kp-mod.armed {
  color: #0b0e14;
  background: linear-gradient(180deg, var(--accent), #4bb8ee);
  border-color: var(--accent);
  box-shadow:
    0 3px 0 #0a2a3a,
    0 0 14px rgba(125, 211, 252, 0.5);
}
.kp-space {
  flex: 4 1 0;
  font-family: var(--font);
  font-size: 13px;
  letter-spacing: 2px;
  color: var(--muted);
}

/* ── results ─────────────────────────────────────────────────────────── */
.results-wrap {
  text-align: center;
  padding-top: 20px;
}
.results-crown {
  font-size: 56px;
}
#results-world {
  font-size: 28px;
  margin: 6px 0;
}
#results-grade {
  color: var(--muted);
  margin-bottom: 6px;
}
#results-rank {
  color: var(--accent);
  font-weight: 700;
  margin-bottom: 22px;
}
.results-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  max-width: 560px;
  margin: 0 auto 26px;
}
.rstat {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px 8px;
}
.rstat b {
  display: block;
  font-size: 26px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.rstat span {
  color: var(--muted);
  font-size: 12px;
}
.results-btns {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ── cheat sheet ─────────────────────────────────────────────────────── */
.cheat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 18px;
}
.cheat-section {
  margin-bottom: 26px;
}
.cheat-h {
  margin: 0 0 10px;
  font-size: 18px;
}
.cheat-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 10px;
  border-radius: 10px;
}
.cheat-row:hover {
  background: var(--panel);
}
.cheat-keys {
  display: flex;
  gap: 8px;
  flex: 0 0 190px;
}
.cheat-keys .kc {
  height: 34px;
  min-width: 30px;
  font-size: 14px;
  padding: 0 8px;
}
.cheat-keys .kc-wide {
  min-width: 72px;
}
.cheat-keys .kc-leader::after {
  content: "";
}
.cheat-info {
  display: flex;
  flex-direction: column;
  flex: 1;
}
.cheat-label {
  font-weight: 700;
}
.cheat-prompt {
  color: var(--muted);
  font-size: 13px;
}
.cheat-mastered {
  color: var(--hint);
  font-size: 18px;
}

/* ── animations ──────────────────────────────────────────────────────── */
.shake {
  animation: shake 0.4s ease;
}
@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-10px);
  }
  40% {
    transform: translateX(9px);
  }
  60% {
    transform: translateX(-6px);
  }
  80% {
    transform: translateX(4px);
  }
}

.hidden {
  display: none !important;
}

/* ── mobile soft-keyboard plumbing ───────────────────────────────────── */
/* The hidden field that summons the on-screen keyboard. It must stay in the
   layout (display:none would stop it opening the keyboard) but invisible and
   un-tappable. 16px font-size stops iOS Safari from zooming when it focuses. */
#mobile-input {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  margin: 0;
  opacity: 0;
  font-size: 16px;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  pointer-events: none;
}

/* respect the OS / user preference for reduced motion */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 560px) {
  #app {
    padding: 16px 14px 44px;
  }
  .brand h1 {
    font-size: 26px;
  }
  .card {
    padding: 22px 16px;
  }
  .card-prompt {
    font-size: 20px;
  }
  .results-stats {
    grid-template-columns: repeat(2, 1fr);
  }
  .cheat-keys {
    flex-basis: 130px;
  }
  /* Big, thumb-friendly primary actions that fill the width. */
  .cta-row {
    flex-direction: column;
    align-items: stretch;
  }
  .cta-row .btn.big {
    width: 100%;
  }
  .cta-row .hint-text {
    text-align: center;
  }
  .btn.big {
    font-size: 16px;
    padding: 13px 18px;
  }
  /* Roomier keycaps so they're easy to read on a phone. */
  .kc {
    font-size: 16px;
    min-width: 36px;
    height: 42px;
  }
  .pressed {
    gap: 8px;
  }
  .world-tile {
    padding: 14px;
  }
  .play-foot {
    flex-wrap: wrap;
  }
  /* Fit ten keys across a narrow phone. */
  .kp-key {
    height: 46px;
    font-size: 16px;
  }
}

/* Single-column worlds on the narrowest phones. */
@media (max-width: 380px) {
  #world-grid {
    grid-template-columns: 1fr;
  }
}
