/* The WordGuess board, its keyboard, the start/pause gate and the rules list.
   Every colour comes from tokens.css.

   The page's furniture — header, gate, status bar, result panel, prev/next — is
   the acrostic's and the binary's, deliberately: three games are one product,
   and a player who knows where the pause button is on one should not have to
   look for it on the next. What is genuinely different here is the board and the
   keyboard, and that is where all the new work is.

   The acrostic's board is light tiles on a near-black panel, because a REVEALED
   letter has to land against its blank neighbours. The binary's is a printed
   grid, because it is filled in. This one is neither: it is six rows of five
   boxes that a player TYPES INTO, so it is drawn as a form — paper tiles, a thin
   rim, and a firm rim on the box your next letter goes in. */

/* A tile is sized from the viewport, with five across as the binding case. The
   clamp lands near 58px on a 390px phone, which is a comfortable tap target and
   leaves the six rows on one screen without scrolling — the whole game is
   re-reading the rows above, and a row you have to scroll to cannot be compared
   with the one under your thumb.

   --wg-w is declared HERE, on the grid, and not on :root. --wg-cols is an inline
   style on #grid (views/wordguess.ejs), so a :root rule computing
   `calc(... / var(--wg-cols))` would resolve against :root's own fallback
   whatever the puzzle is. It is the trap binary.css records at length; the note
   is repeated rather than referenced because the next person to add a sized
   board will be reading this file. */
.grid{
  --wg-cols:5;
  --wg-w:clamp(46px, calc((min(100vw, 420px) - 80px) / var(--wg-cols)), 64px);
  display:flex;flex-direction:column;gap:6px;align-items:center;
}

/* progress hairline pinned to the very top, above the masthead */
#line{
  position:fixed;top:0;left:0;height:3px;width:0;background:var(--accent);
  z-index:9;transition:width .35s var(--ease);
}
#line.go{width:100%}

/* ---------------- header ---------------- */
/* Lifted from binary.css unchanged. Same clock, same pause control, same
   dateline — see the note in acrostic.css on why the clock is set in the serif. */
.wrap header{
  padding:26px 0 14px;margin-bottom:20px;border-bottom:1px solid var(--rule);
  display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;
}
.wrap h1{
  font-family:var(--display);font-weight:700;font-size:clamp(26px,4.4vw,36px);
  letter-spacing:-.035em;line-height:1.05;margin:0;
}
.wrap h1 em{font-style:normal;color:var(--accent-ink)}
.dateline{
  flex-basis:100%;margin:6px 0 0;font-size:12px;letter-spacing:.01em;color:var(--dim);
}

/* ---------------- the board ---------------- */

.board{display:flex;justify-content:center;padding:8px 0 18px}

.wg-row{display:flex;gap:6px}

.wg-tile{
  width:var(--wg-w);height:var(--wg-w);
  display:flex;align-items:center;justify-content:center;
  background:var(--wg-tile);
  border:2px solid var(--wg-tile-line);
  border-radius:var(--radius-tile);
  font-family:var(--display);font-weight:700;
  font-size:calc(var(--wg-w) * .52);line-height:1;
  color:var(--wg-ink);text-transform:uppercase;
  /* The board is one big tap target and nothing on it is draggable, so a long
     press or a drag across it should not paint a selection. Same reason the
     acrostic sets this on .board (DESIGN.md §2.4). */
  user-select:none;-webkit-user-select:none;
  transition:border-color .1s var(--ease), transform .1s var(--ease);
}

/* A letter typed but not yet committed. The rim firms up and the tile gives a
   small pop, which is the whole feedback a keystroke gets — the tile is the
   field, so it has to look like something happened. */
.wg-tile.is-filled:not(.is-marked){
  border-color:var(--wg-tile-line-lit);
  transform:scale(1.04);
}

/* ---------------- the marks ---------------- */
/* Set together rather than per state, so a tile that is marked can never keep
   the typed rim or the pop. */
.wg-tile:not(.is-marked){box-shadow:var(--card-shadow)}
.wg-tile.is-marked{border-color:transparent;transform:none}
.wg-tile.is-exact  {background:var(--wg-exact);   color:var(--wg-exact-on)}
.wg-tile.is-present{background:var(--wg-present); color:var(--wg-present-on)}
.wg-tile.is-absent {background:var(--wg-absent);  color:var(--wg-absent-on)}

/* The flip. Each tile turns a quarter and comes back with its mark, staggered
   along the row by --fd, which public/js/wordguess.js sets per tile. It is a
   custom property rather than a chain of timers so a RESTORED game can set it to
   0ms and have the whole board land at once through the same code path.

   The colour is swapped at the half-way point by the keyframes' own timing: the
   class is already on the tile, and scaleY(0) is what hides the change. */
@keyframes wgflip{
  0%   {transform:scaleY(1)}
  50%  {transform:scaleY(0)}
  100% {transform:scaleY(1)}
}
.wg-tile.is-flip{
  animation:wgflip .36s var(--ease) both;
  animation-delay:var(--fd, 0ms);
}

/* A refused guess — too short, or not a word. The row shudders once and leaves
   nothing behind: no class stays, no tile is coloured, and the guess is still
   there to be edited. Marking the row would be marking something the game has
   explicitly NOT judged. */
@keyframes wgshake{
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-6px)}
  40%{transform:translateX(6px)}
  60%{transform:translateX(-4px)}
  80%{transform:translateX(4px)}
}
.wg-row.is-bad{animation:wgshake .4s var(--ease)}

@media (prefers-reduced-motion:reduce){
  .wg-tile.is-flip{animation:none}
  .wg-row.is-bad{animation:none}
  .wg-tile{transition:none}
}

/* ---------------- the keyboard ---------------- */
/* Both the readout and the input. Laid out as a keyboard rather than as A to Z
   because the letters are being typed, and a player hunting for one looks where
   their fingers already know it is. */

.keys{
  display:flex;flex-direction:column;gap:6px;align-items:center;
  margin:0 0 18px;
}
.krow{display:flex;gap:5px;justify-content:center;width:100%}
.kspacer{flex:.5}

.key{
  flex:1;min-width:0;max-width:44px;height:52px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--ui);font-weight:700;font-size:14px;
  color:var(--wg-key-ink);background:var(--wg-key);
  border:0;border-radius:var(--radius-tile);
  cursor:pointer;text-transform:uppercase;
  transition:background .12s var(--ease), color .12s var(--ease), transform .06s var(--ease);
}
.key{box-shadow:var(--card-shadow)}
.key:hover{background:var(--accent-soft)}
.key:active{transform:translateY(1px)}
.key.is-wide{flex:1.6;max-width:68px;font-size:11px;letter-spacing:.04em}
.key svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

/* A key wears the best mark that letter has ever earned — see `paintKeys` in
   wordguess.js. It climbs and never falls back, so these only ever get more
   specific as a game goes on. */
.key.is-exact  {background:var(--wg-exact);   color:var(--wg-exact-on)}
.key.is-present{background:var(--wg-present); color:var(--wg-present-on)}
.key.is-absent {background:var(--wg-absent);  color:var(--wg-absent-on)}
.key.is-exact:hover,.key.is-present:hover,.key.is-absent:hover{filter:brightness(1.08)}

/* ---------------- the swatches in the rules ---------------- */
/* Real marked tiles rather than the words "green" and "yellow". A rule that
   NAMES a colour is a rule that is wrong for anyone who cannot see that colour,
   so each swatch carries its wording beside it — which is also what the status
   line says after every guess. */
.wg-key{display:flex;align-items:center;gap:8px;margin:6px 0}
.wg-swatch{
  flex:none;width:26px;height:26px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--display);font-weight:700;font-size:14px;
  border-radius:var(--radius-tile);
}
.wg-swatch.is-exact  {background:var(--wg-exact);   color:var(--wg-exact-on)}
.wg-swatch.is-present{background:var(--wg-present); color:var(--wg-present-on)}
.wg-swatch.is-absent {background:var(--wg-absent);  color:var(--wg-absent-on)}

/* ---------------- the gate ---------------- */
/* Everything the player could study for free goes away behind it — the board,
   the keys, the status bar, the rules and the note. A paused game that still
   showed the marked rows would be a free hint, and a paused timer over a
   readable board is not pause at all (DESIGN.md §2.6). display:none rather than
   a blur, because a blurred board is still a board somebody can screenshot and
   sharpen. */
body.is-gated .playfield,
body.is-gated .board,
body.is-gated .keys,
body.is-gated .status,
body.is-gated .rules,
body.is-gated .note{display:none}
body:not(.is-gated) .gate{display:none}

.gate{
  min-height:300px;           /* the layout jump display:none costs, paid for here */
  display:flex;align-items:center;justify-content:center;
  margin-bottom:22px;
}
.gate-in{
  width:100%;max-width:460px;text-align:center;
  padding:30px 26px;border:1px solid var(--rule-firm);border-radius:var(--radius-card);
  background:var(--card);
}
.gate-kicker{
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-ink);
  margin-bottom:10px;
}
.gate-in h2{
  font-family:var(--display);font-weight:700;font-size:24px;letter-spacing:-.02em;
  margin:0 0 10px;
}
#gateNote{margin:0 0 18px;font-size:14px;color:var(--slate);line-height:1.5}
.gate-rules{
  text-align:left;margin:0 0 20px;padding:16px 18px;
  border:1px solid var(--rule);border-radius:var(--radius-card);
  background:var(--page);
}
.gate-rules-head{
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);
  margin-bottom:8px;
}
.gate-figures{margin-top:12px;font-size:12px;color:var(--dim)}

.btn{
  font:inherit;font-family:var(--ui);font-weight:700;font-size:15px;
  padding:11px 26px;cursor:pointer;color:var(--on-accent);background:var(--accent);
  border:1px solid var(--accent-deep);border-radius:var(--radius-pill);
}
.btn:hover{background:var(--accent-deep)}

/* ---------------- the status bar and the result ---------------- */

.entry{margin-bottom:26px}
.status{
  text-align:center;font-size:14px;color:var(--slate);min-height:22px;
  padding:0 10px;line-height:1.5;
}
.entry.done .status,
.entry.done .keys{display:none}

.result{display:none}
.entry.done .result{
  display:block;text-align:center;
  padding:26px 22px;border:1px solid var(--accent-deep);border-radius:var(--radius-card);
  background:var(--accent-soft);
}
.result .eyebrow{
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent-ink);
}
.result .final{
  font-family:var(--serif);font-weight:900;font-size:40px;line-height:1.1;
  font-variant-numeric:tabular-nums;color:var(--ink);margin:6px 0 2px;
}
.result .flabel{font-size:12px;color:var(--dim);margin-bottom:2px}
.result .ftime{font-size:12px;color:var(--dim);margin-bottom:18px}

/* What the word was. Written by wordguess.js when the game ends rather than
   rendered into the markup: the answer is already in window.PUZZLE and a second
   copy on the page buys nothing. `.result` is display:none until the game is
   over, which keeps it out of Ctrl+A and find-in-page either way (§2.4). */
.result .source{
  margin:0 0 20px;padding:16px 18px;
  border:1px solid var(--accent-deep);border-radius:var(--radius-card);
  background:var(--page);
}
.result .src-label{
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);
  margin-bottom:6px;
}
.result .src-name{
  font-family:var(--display);font-weight:700;font-size:26px;letter-spacing:.08em;
  color:var(--ink);
}

/* ---------------- the rules under the board, and the note ---------------- */

.rules{margin-bottom:26px}
.section-head{
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--dim);
  font-weight:700;margin:0 0 12px;padding-bottom:8px;border-bottom:1px solid var(--rule);
}
.rules-list{margin:0;padding-left:22px;font-size:14px;color:var(--slate);line-height:1.7}
.rules-list li{margin-bottom:4px}
.rules-list b{color:var(--ink)}

.note{
  font-size:13px;color:var(--slate);line-height:1.7;
  padding:16px 18px;border:1px solid var(--rule);border-radius:var(--radius-card);
  background:var(--card);margin:0 0 26px;
}
.note b{color:var(--ink)}

/* ---------------- narrow screens ---------------- */
@media (max-width:420px){
  .key{height:46px;font-size:13px}
  .key.is-wide{font-size:10px}
  .krow{gap:4px}
  .wg-row{gap:5px}
  .grid{gap:5px}
}
