:root {
  --bg: #12141c;
  --panel: #1c1f2b;
  --panel-edge: #2b3042;
  --ink: #eef1f8;
  --dim: #8891a8;
  --accent: #6ee7a8;
  --accent-dim: #2f7a58;
  --on-accent: #0d1117; /* text on an accent-filled button */
  --bad: #ff8b7a;
  --good: #6ee7a8;
  --font: 'Avenir Next', 'Segoe UI', system-ui, sans-serif;
}

/* Light mode. Every colour in the game routes through the tokens above, so the whole
   theme is this one block - plus the lives colours further down, which have to be
   re-picked rather than reused: the dark amber and red are unreadable on white. */
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f2f4f8;
    --panel: #ffffff;
    --panel-edge: #d3d8e2;
    --ink: #171a23;
    --dim: #5a627a;
    --accent: #17825a;
    --accent-dim: #7fc4a4;
    --on-accent: #ffffff;
    --bad: #b5372a;
    --good: #17825a;
  }
}

/* The whole board warms up as lives run out: green at three, amber at two, red at
   one. Everything keyed to --accent (timer bar, hearts, filled slots, buttons)
   follows along. data-lives is pinned at 1 on the game-over screen. */
body[data-lives='2'] {
  --accent: #f5c451;
  --accent-dim: #7d6222;
}

body[data-lives='1'] {
  --accent: #ff6f5e;
  --accent-dim: #82322a;
}

@media (prefers-color-scheme: light) {
  body[data-lives='2'] {
    --accent: #9a6b06;
    --accent-dim: #e8c778;
    --on-accent: #ffffff;
  }

  body[data-lives='1'] {
    --accent: #b5372a;
    --accent-dim: #eda79c;
    --on-accent: #ffffff;
  }
}

* {
  box-sizing: border-box;
}

/* our display rules would otherwise beat the browser's [hidden] { display: none } */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  min-height: 100vh;
  /* dvh tracks the viewport as mobile browser chrome slides away; plain vh counts the
     area behind it, so the page is taller than what you can see and shifts as you scroll */
  min-height: 100dvh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 1.5rem 1rem;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
}

/* margin:auto rather than align-items:center. Both centre, but when the board is taller
   than the viewport, centring pushes the top out of reach above the scroll origin - and
   the top is where the clock lives. */
.game,
.landing {
  margin: auto;
}

.game {
  width: 100%;
  max-width: 30rem;
  /* sits above the back easter-egg layer and below the front one, so a set piece
     can play behind the board without ever covering the clock */
  position: relative;
  z-index: 2;
}

/* ---- landing page ---- */

.landing {
  width: 100%;
  max-width: 30rem;
}

.title {
  margin: 0 0 1.75rem;
  font-size: 2.6rem;
  letter-spacing: 0.02em;
  text-align: center;
  color: var(--accent);
}

.setup {
  margin: 0 0 2rem;
}

.levels {
  margin: 0 0 1rem;
  padding: 0;
  border: none;
}

.levels legend {
  padding: 0 0 0.6rem;
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
}

.level {
  display: block;
  margin-bottom: 0.5rem;
  cursor: pointer;
}

/* the native radio is hidden, but still focusable and still the source of truth */
.level input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.level-body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0.95rem;
  border: 1px solid var(--panel-edge);
  border-radius: 0.6rem;
  background: var(--panel);
}

.level-name {
  font-weight: 600;
}

.level-time {
  font-size: 0.85rem;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}

.level:hover .level-body {
  border-color: var(--accent-dim);
}

.level input:checked + .level-body {
  border-color: var(--accent);
  background: var(--panel-edge);
}

.level input:checked + .level-body .level-name {
  color: var(--accent);
}

.level input:focus-visible + .level-body {
  outline: 2px solid var(--accent-dim);
  outline-offset: 1px;
}

.start {
  width: 100%;
  padding: 0.85rem;
  font-size: 1.05rem;
}

.how h2 {
  margin: 0 0 0.6rem;
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
}

.how ol {
  margin: 0;
  padding-left: 1.2rem;
  color: var(--dim);
  line-height: 1.55;
}

.how li {
  margin-bottom: 0.35rem;
}

.copyright {
  margin-top: 2.5rem;
  text-align: center;
  font-size: 0.8rem;
  color: var(--dim); /* --panel-edge was too low-contrast to read */
}

/* ---- heads-up display ---- */

.hud {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
}

.stat-label {
  font-size: 0.7rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
}

.stat-value {
  font-size: 1.35rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.stat-timer .stat-value.low {
  color: var(--bad);
}

.heart {
  color: var(--accent);
}

.heart.spent {
  color: var(--panel-edge);
}

.timer-bar {
  height: 5px;
  border-radius: 3px;
  background: var(--panel-edge);
  overflow: hidden;
  margin-bottom: 0.6rem;
}

.controls {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 1rem;
}

.ghost {
  padding: 0.3rem 0.8rem;
  border: 1px solid var(--panel-edge);
  background: none;
  color: var(--dim);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ghost:hover {
  border-color: var(--accent-dim);
  color: var(--ink);
  filter: none;
}

/* while paused the board dims, so it reads as stopped rather than just quiet */
.paused .slots,
.paused .timer-bar {
  opacity: 0.35;
}

.timer-fill {
  height: 100%;
  width: 100%;
  background: var(--accent);
  /* no transition: the 100ms tick is already smooth, and a transition makes the
     bar visibly sweep whenever a new round snaps it back to full */
}

/* ---- word slots ---- */

.slots {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.slot {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 0.85rem;
  border: 1px solid var(--panel-edge);
  border-radius: 0.6rem;
  background: var(--panel);
}

.slot-len {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  display: grid;
  place-items: center;
  border-radius: 0.4rem;
  background: var(--panel-edge);
  color: var(--dim);
  font-size: 0.85rem;
  font-weight: 700;
}

.slot-word {
  font-size: 1.1rem;
  letter-spacing: 0.08em;
  color: var(--dim);
}

.slot.filled {
  border-color: var(--accent-dim);
}

.slot.filled .slot-len {
  background: var(--accent-dim);
  color: var(--ink);
}

.slot.filled .slot-word {
  color: var(--accent);
  font-weight: 600;
}

/* an empty slot shows dashes for the letters it wants */
.slot:not(.filled) .slot-word::before {
  content: '– – – – – – –';
  letter-spacing: normal;
}

.slot:not(.filled)#slot-2 .slot-word::before {
  content: '– –';
}
.slot:not(.filled)#slot-3 .slot-word::before {
  content: '– – –';
}
.slot:not(.filled)#slot-4 .slot-word::before {
  content: '– – – –';
}
.slot:not(.filled)#slot-5 .slot-word::before {
  content: '– – – – –';
}
.slot:not(.filled)#slot-6 .slot-word::before {
  content: '– – – – – –';
}

/* ---- entry ---- */

.entry {
  display: flex;
  gap: 0.5rem;
}

input,
button {
  font: inherit;
  border-radius: 0.6rem;
}

input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--panel-edge);
  background: var(--panel);
  color: var(--ink);
  letter-spacing: 0.08em;
}

input:focus {
  outline: 2px solid var(--accent-dim);
  outline-offset: 1px;
}

button {
  padding: 0.7rem 1.1rem;
  border: none;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  cursor: pointer;
}

button:hover {
  filter: brightness(1.08);
}

/* ---- messages and game over ---- */

.message {
  min-height: 1.4rem;
  margin: 0.85rem 0 0;
  text-align: center;
  font-size: 0.95rem;
  color: var(--dim);
}

.message.bad {
  color: var(--bad);
}

.message.good {
  color: var(--good);
}

.over {
  margin-top: 1.5rem;
  padding: 1.25rem;
  border: 1px solid var(--panel-edge);
  border-radius: 0.75rem;
  background: var(--panel);
  text-align: center;
}

.over h2 {
  margin: 0 0 0.5rem;
  font-size: 1.4rem;
}

.over p {
  margin: 0 0 0.5rem;
  color: var(--dim);
}

.over strong {
  color: var(--ink);
}

.over-best {
  color: var(--accent) !important;
}

.over button {
  margin-top: 0.5rem;
}

/* scoped to beat the `.over p` margin above */
.over .over-menu {
  margin: 0.9rem 0 0;
  font-size: 0.85rem;
}

.over-menu a {
  color: var(--dim);
}

.over-menu a:hover {
  color: var(--ink);
}

/* ---- small screens ----------------------------------------------------- */

/* Touch devices get proper targets. Kept behind pointer:coarse so the desktop
   layout is not padded out for a problem it does not have. */
@media (pointer: coarse) {
  .ghost {
    min-height: 44px;
    padding: 0.5rem 1.1rem;
  }

  .over-menu a {
    display: inline-block;
    padding: 0.6rem 1rem;
  }
}

/* Narrow phones: claw back horizontal padding and drop the title a size. */
@media (max-width: 420px) {
  body {
    padding: 1rem 0.7rem;
  }

  /* five stats on a narrow phone: shrink the labels and let the row breathe less */
  .hud {
    gap: 0.25rem;
  }

  .stat-label {
    font-size: 0.58rem;
    letter-spacing: 0.04em;
  }

  .title {
    font-size: 2.1rem;
    margin-bottom: 1.25rem;
  }

  .stat-value {
    font-size: 1.2rem;
  }

  .slot {
    gap: 0.65rem;
    padding: 0.55rem 0.7rem;
  }
}

/* Short viewports - a landscape phone above all. The board is 539px tall by default,
   which pushes the clock off the top of a 375px-tall screen. Everything here buys
   vertical room. */
@media (max-height: 640px) {
  body {
    padding: 0.6rem 0.7rem;
  }

  .hud {
    margin-bottom: 0.4rem;
  }

  .stat-label {
    font-size: 0.6rem;
  }

  .stat-value {
    font-size: 1.05rem;
  }

  .timer-bar {
    margin-bottom: 0.4rem;
  }

  .controls {
    margin-bottom: 0.5rem;
  }

  .slots {
    margin-bottom: 0.6rem;
    gap: 0.35rem;
  }

  .slot {
    padding: 0.35rem 0.7rem;
    gap: 0.6rem;
  }

  .slot-len {
    width: 1.35rem;
    height: 1.35rem;
    font-size: 0.75rem;
  }

  .slot-word {
    font-size: 1rem;
  }

  input,
  button {
    padding: 0.5rem 0.9rem;
  }

  .message {
    min-height: 1.1rem;
    margin-top: 0.5rem;
    font-size: 0.85rem;
  }
}

/* Landscape has width to spare and no height at all, so the ladder splits into two
   columns. This is what actually makes the clock visible on a landscape phone. */
@media (max-height: 640px) and (orientation: landscape) {
  .game {
    max-width: 44rem;
  }

  .slots {
    grid-template-columns: 1fr 1fr;
    column-gap: 0.6rem;
  }

  .entry {
    max-width: 32rem;
    margin: 0 auto;
  }
}
