/* Mobile first. The board and keyboard share the viewport height, so the
   whole game fits on a phone screen without scrolling. */

:root {
  color-scheme: dark;
  --bg: #121213;
  --text: #f8f8f8;
  --muted: #a1a1aa;
  --border: #3a3a3c;
  --border-active: #565758;
  --hit: #538d4e;
  --present: #b59f3b;
  --miss: #3a3a3c;
  --key: #818384;
  --gap: 5px;
  --key-gap: 5px;

  /* How far the end-of-game card sits below centre. */
  --result-drop: 16dvh;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Browsers wait to see if a tap is the start of a double-tap-to-zoom, which
   makes repeated taps on a key zoom the page instead of repeating the key.
   `manipulation` drops double-tap zoom on controls; pinch zoom still works. */
button { touch-action: manipulation; }

body {
  margin: 0;
  height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  overflow: hidden;
}

[hidden] { display: none !important; }

/* --- Game --- */

.game {
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* --- Header --- */

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px calc(12px + env(safe-area-inset-right)) 10px calc(12px + env(safe-area-inset-left));
  border-bottom: 1px solid var(--border);
}

.bar h1 a { color: inherit; text-decoration: none; }

.bar h1 {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
}

/* --- Account (header) --- */

.account { position: relative; }

.bar-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 55vw;
  padding: 7px 12px;
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--border-active);
  border-radius: 6px;
  cursor: pointer;
}
.bar-button:hover { background: #1f1f21; }

.player-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.caret { font-size: .7rem; color: var(--muted); }

.menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 10;
  display: grid;
  min-width: 180px;
  padding: 6px;
  background: #1f1f21;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
}
.menu button,
.menu a {
  padding: 10px 12px;
  font: inherit;
  font-size: .95rem;
  text-align: left;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.menu a { text-decoration: none; }
.menu button:hover,
.menu a:hover { background: #2a2a2d; }
.menu .menu-danger { color: #fca5a5; }

/* Sets the destructive item apart from the everyday ones. */
.menu-separator {
  height: 1px;
  margin: 6px 4px;
  background: var(--border);
}

/* --- Layout --- */

main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 8px calc(6px + env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) calc(6px + env(safe-area-inset-left));
}

/* --- Board --- */

.game-note {
  margin: 0;
  max-width: 340px;
  font-size: .8rem;
  color: var(--muted);
  text-align: center;
}

.board {
  display: grid;
  gap: var(--gap);
  flex: 0 1 auto;
  min-height: 0;
  padding: 8px 0;
}

.row {
  display: grid;
  grid-auto-flow: column;
  gap: var(--gap);
  justify-content: center;
}

.tile {
  display: grid;
  place-items: center;
  width: min(62px, 14vw);
  aspect-ratio: 1;
  font-size: clamp(1.4rem, 7vw, 2rem);
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
  border: 2px solid var(--border);
  user-select: none;
}

.tile[data-filled] {
  border-color: var(--border-active);
  animation: pop 100ms ease-out;
}

.tile[data-colour="hit"]     { background: var(--hit);     border-color: var(--hit); }
.tile[data-colour="present"] { background: var(--present); border-color: var(--present); }
.tile[data-colour="miss"]    { background: var(--miss);    border-color: var(--miss); }

/* Reveal each tile in turn, so the row reads left to right. */
.tile[data-reveal] { animation: flip 480ms ease forwards; }

.row[data-invalid] { animation: shake 500ms ease; }

@keyframes pop {
  from { transform: scale(.92); }
  to   { transform: scale(1); }
}

@keyframes flip {
  0%   { transform: rotateX(0); }
  50%  { transform: rotateX(90deg); }
  100% { transform: rotateX(0); }
}

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-7px); }
  40%, 60% { transform: translateX(7px); }
}

/* --- Toast --- */

.toast {
  min-height: 2rem;
  padding: 6px 0;
  font-size: .875rem;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
  opacity: 0;
  transition: opacity 140ms ease;
}

.toast[data-show] { opacity: 1; }
.toast[data-tone="error"] { color: #fca5a5; }

/* --- Keyboard --- */

.keyboard {
  width: 100%;
  max-width: 500px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-bottom: 4px;
}

/* One shared column grid for every row, so a letter is the same width
   everywhere. Key placement is set by app.js from the KEYBOARD config. */
.keys {
  display: grid;
  grid-template-columns: repeat(var(--keyboard-columns, 20), 1fr);
  /* No grid gap: a key spans several columns and a gap would open up inside
     it. The spacing comes from key margins instead. */
  margin: 0 calc(var(--key-gap) / -2);
}

.key {
  min-width: 0;
  margin: 0 calc(var(--key-gap) / 2);
  height: clamp(44px, 7.5dvh, 58px);
  padding: 0 2px;
  font-family: inherit;
  font-size: clamp(.7rem, 3.4vw, .9rem);
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text);
  background: var(--key);
  border: 0;
  border-radius: 4px;
  cursor: pointer;
}

.key:active { filter: brightness(1.25); }
.key[data-wide] { font-size: clamp(.6rem, 2.8vw, .75rem); }

.key[data-colour="hit"]     { background: var(--hit); }
.key[data-colour="present"] { background: var(--present); }
.key[data-colour="miss"]    { background: var(--miss); color: var(--muted); }

/* --- Result dialog --- */

.result {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0, 0, 0, .72);
}

.result[hidden] { display: none; }

.card {
  width: 100%;
  max-width: 320px;
  padding: 26px 22px;
  text-align: center;
  background: #1f1f21;
  border: 1px solid var(--border);
  border-radius: 12px;

  /* Nudged down from centre so the board above stays visible. */
  position: relative;
  top: var(--result-drop);
}

.card h2 {
  margin: 0 0 8px;
  font-size: 1.5rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.card p { margin: 0 0 20px; color: var(--muted); }

/* The score is the first thing to read on a win, so it is the biggest thing
   on the card. The unit beside it is a label, not part of the number. */
.score {
  margin: 0 0 4px;
  font-size: 2rem;    /* Font size of score in game won pop-up */
  font-weight: 700;
  line-height: 1.1;
  color: var(--hit);
}
.score[hidden] { display: none; }
.score span {
  /* A space sits between the two in the markup, so a screen reader reads
     "8.42 points"; this is the optical gap on top of it. */
  margin-left: 4px;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.card strong { color: var(--text); letter-spacing: .1em; text-transform: uppercase; }

.primary {
  width: 100%;
  padding: 13px;
  font: inherit;
  font-weight: 600;
  color: #fff;
  background: var(--hit);
  border: 0;
  border-radius: 8px;
  cursor: pointer;
}

.primary:hover { background: #4a7d46; }
.primary:disabled { opacity: .6; cursor: default; }

/* The delete confirmation sits in the middle, not below centre like the
   result card: there is no board to keep in view behind it. */
.card-centred { top: 0; }

.actions { display: flex; gap: 10px; }
.actions button {
  flex: 1;
  padding: 13px;
  font: inherit;
  font-weight: 600;
  border-radius: 8px;
  cursor: pointer;
}
.secondary { color: var(--text); background: transparent; border: 1px solid var(--border-active); }
.secondary:hover { background: #2a2a2d; }
.danger { color: #fff; background: #b42318; border: 0; }
.danger:hover { background: #9a1c13; }
.actions button:disabled { opacity: .6; cursor: default; }

:where(button, input):focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
