/* Legibility only. Design is deliberately out of scope for this slice — the point is to
   find out whether the grader is any good when a person actually talks to it. */

:root {
  --ink: #171717;
  --muted: #5f5f5f;
  --line: #e2e0db;
  --bg: #faf9f6;
  --card: #fff;
  --accent: #1d4ed8;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 -apple-system, "Segoe UI", system-ui, sans-serif;
}

main { max-width: 720px; margin: 0 auto; padding: 32px 20px 64px; }

h1 { font-size: 28px; margin: 0 0 8px; }
h2 { font-size: 18px; margin: 0 0 12px; }
h3 { font-size: 15px; margin: 0 0 4px; }

.sub { color: var(--muted); margin: 0 0 28px; }
.hint { color: var(--muted); font-size: 14px; margin: 0 0 10px; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px;
  margin-bottom: 20px;
}

.loading { color: var(--muted); margin: 0; }

/* --- the hand ---------------------------------------------------------- */

.hand-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
/* Card tiles. The SUIT SYMBOL carries the suit; red/black is a second signal on top of
   it, never the only one. */
.cards { display: inline-flex; gap: 4px; vertical-align: middle; }
.card-tile {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  padding: 4px 7px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-weight: 700;
  line-height: 1.1;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .06);
}
.card-tile.red { color: #b3261e; }
.card-tile.black { color: #16181d; }
.cards.hole .card-tile { font-size: 22px; padding: 7px 10px; }
.cards.small .card-tile { font-size: 13px; padding: 2px 5px; border-radius: 4px; }
.card-suit { font-size: .95em; }
.seat, .game { color: var(--muted); font-size: 14px; }
.game { margin: 4px 0 16px; }

/* Streets.
   The action gets its OWN ROW. The previous layout squeezed street, board, action and pot
   into four columns with the board on a fixed 110px, so a five-card turn or river board
   overflowed its cell and ran straight over the action text. Fixed structurally rather
   than by widening a number: nothing here depends on how many cards a street has, so a
   five-card board cannot collide with anything at any width. */
.streets { list-style: none; margin: 0 0 16px; padding: 0; }
.streets li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "street board pot"
    "action action action";
  gap: 6px 12px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  font-size: 14px;
  align-items: center;
}
.street {
  grid-area: street;
  font-weight: 600;
  text-transform: capitalize;
  min-width: 56px;
}
.board { grid-area: board; display: flex; flex-wrap: wrap; gap: 4px; }
.pot { grid-area: pot; color: var(--muted); white-space: nowrap; justify-self: end; }
.action { grid-area: action; color: var(--ink); }

@media (max-width: 520px) {
  /* Narrow: the pot drops under the board rather than fighting it for width. */
  .streets li {
    grid-template-columns: auto 1fr;
    grid-template-areas:
      "street board"
      "pot pot"
      "action action";
  }
  .pot { justify-self: start; }
}

.history {
  background: #f4f1ea;
  border-radius: 10px;
  padding: 12px 14px;
  margin: 0 0 16px;
}
.history h3 { margin: 0 0 4px; }
.history p { margin: 0; font-size: 15px; }

.decision { border-top: 2px solid var(--ink); padding-top: 14px; }
.decision p { margin: 0 0 4px; }
.legal, .stacks { color: var(--muted); font-size: 14px; }
.final-board { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.final-board-label { font-weight: 600; }

/* --- the input --------------------------------------------------------- */

textarea {
  width: 100%;
  font: 16px/1.6 inherit;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  resize: vertical;
  background: #fff;
  color: inherit;
}
textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.actions { display: flex; align-items: center; gap: 14px; margin-top: 14px; }

button {
  font: 600 16px inherit;
  padding: 12px 24px;
  min-height: 44px;
  border: 0;
  border-radius: 10px;
  background: var(--ink);
  color: #fff;
  cursor: pointer;
}
button:disabled { background: var(--muted); cursor: progress; }

#status { color: var(--muted); font-size: 14px; }

/* --- the result -------------------------------------------------------- */

/* The coach's take: the first thing read, and the only thing some players will read. */
.coach { margin: 0 0 20px; }
.coach h2 { margin-bottom: 8px; }
.coach p { margin: 0 0 6px; font-size: 17px; line-height: 1.5; }

.breakdown-cat { margin: 0 0 18px; }
.breakdown-cat h3 { font-size: 14px; margin: 0 0 6px; }

.total { margin: 0 0 16px; }
.total-n { font-size: 40px; }
.total-max { color: var(--muted); font-size: 20px; }

.cats { list-style: none; margin: 0; padding: 0; }
.cats > li { padding: 12px 0; border-top: 1px solid var(--line); }
.cat-head { display: flex; justify-content: space-between; gap: 16px; font-size: 15px; }
.cat-label { font-weight: 600; }
.cat-score { color: var(--muted); white-space: nowrap; }

.detail { margin: 8px 0 0 0; padding-left: 12px; border-left: 3px solid var(--line); }
.detail h4 { margin: 0 0 3px; font-size: 13px; font-weight: 600; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em; }
.detail ul { margin: 0; padding-left: 18px; font-size: 14px; }
.detail li { margin: 2px 0; }
.detail.heard { border-left-color: #7a9a6f; }
.detail.gap { border-left-color: #c08a3e; }
.detail.maybe { border-left-color: #b4553f; }
.cost { margin: 6px 0 0; font-size: 13px; color: var(--muted); }

/* Collapsed detail. Native <details>, so it is keyboard-reachable and announced without
   any JavaScript behind it. Only the LONG lists live in here — never anything that
   explains why a category lost points. */
.more { margin-top: 8px; }
.more > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--muted);
  padding: 3px 0;
  min-height: 24px;
}
.more > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.more[open] > summary { margin-bottom: 6px; }
.more .detail { margin-top: 6px; }

.missed { margin-top: 20px; padding-top: 16px; border-top: 2px solid var(--ink); }
.missed p { margin: 0; }

.unscorable { margin: 0; }
.provisional { color: var(--muted); font-size: 13px; margin: 20px 0 0; }

footer { color: var(--muted); font-size: 13px; text-align: center; }

/* --- the launch surface: landing, gate, hand navigation ----------------- */
/* Added 2026-09-02 for the Saturday alpha. Same restraint as the rest of the file: this
   is legibility and hierarchy, not a design pass. The one thing it does insist on is
   that the honest section reads as prominently as the sales pitch, because on this
   product that section IS the pitch. */

.lede { margin-bottom: 28px; }
.lede h1 { font-size: 32px; line-height: 1.2; margin-bottom: 12px; }
.lede .sub { font-size: 17px; margin-bottom: 20px; }
.lede-actions { flex-wrap: wrap; }

button.primary { background: var(--accent); }
/* Links that act as buttons. Same target size as a real one — 44px, thumb-sized. */
.primary-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 12px 24px;
  border-radius: 10px;
  background: var(--ink);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}
.ghost {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--muted);
  text-decoration: underline;
}
.primary-link:focus-visible, .ghost:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.plain { margin: 0; padding-left: 20px; }
.plain li { margin: 0 0 8px; }
.spaced { margin-top: 22px; }

/* The "what you are actually buying" block. Marked rather than tucked away: it is the
   section a buyer is most likely to be annoyed about not having read. */
.plain-truth { border-left: 4px solid var(--ink); }

input[type="text"] {
  font: 16px inherit; /* 16px exactly — anything smaller makes iOS zoom on focus. */
  padding: 12px 14px;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: inherit;
  flex: 1 1 180px;
  min-width: 0;
}
input[type="text"]:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

.hands { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px; }
.hand-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.hand-link.current { background: var(--ink); color: #fff; border-color: var(--ink); }

.gate { border-left: 4px solid var(--accent); }
.gate .actions { flex-wrap: wrap; }

.checking { font-size: 24px; }

footer a { color: var(--muted); }

/* Visible to a screen reader, not to the eye. For the label on the code box, where a
   visible label beside a placeholder would just be the same word twice. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- the player loop ---------------------------------------------------- */
/* Added 2026-09-02: the result needs somewhere to go next, and the whole thing has to
   work at a width where a phone keyboard is already taking half the screen. */

.hand-count { color: var(--muted); font-size: 13px; margin: -14px 0 24px; }

/* The two ways forward, under the result. Separated from the score above so they read as
   "what now" rather than as part of the breakdown. */
.result-actions {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
  gap: 10px;
}

/* "Try this hand again" is a real <button> because it does something on this page rather
   than going anywhere. Quieter than the primary action, same 44px target. */
button.secondary {
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
}
button.secondary:hover { border-color: var(--ink); }

/* --- narrow phones ------------------------------------------------------ */
/* 375px is the floor this is designed for, and at that width the old padding plus the
   card border left the transcript box under 300px wide. */
@media (max-width: 430px) {
  main { padding: 20px 14px 48px; }
  .card { padding: 16px 14px; border-radius: 12px; }

  h1 { font-size: 24px; }
  .lede h1 { font-size: 26px; }

  /* Full-width, stacked, thumb-reachable. Side-by-side at this width gives two buttons
     that are each too narrow to read and too close together to hit. */
  .actions { flex-direction: column; align-items: stretch; gap: 10px; }
  .actions button,
  .actions .primary-link,
  .actions .ghost { width: 100%; justify-content: center; text-align: center; }
  /* The status line reads as a caption under the button rather than a squeezed column. */
  #status { text-align: center; }

  /* The board is the one thing here with a real risk of pushing the page sideways: five
     card tiles in a row inside a fixed grid column. `.board` already wraps; the tiles
     themselves did not, so a five-card river could still overflow its cell. The street
     layout above this breakpoint is already handled at 520px — nothing is restated here.
     A page that scrolls horizontally on a phone is the bug players notice first. */
  .cards { flex-wrap: wrap; }
  .card-tile { flex: 0 0 auto; }

  .total-n { font-size: 34px; }
  .cat-head { font-size: 14px; }
}

/* --- the wait ----------------------------------------------------------- */
/* Grading takes as long as it takes. The page's job is to make that legible: something
   moving, a count, and a change of message if it runs long. */

.progress { display: inline-flex; align-items: center; gap: 8px; }

/* THE HIDDEN STATE HAS TO WIN, EXPLICITLY.
   The browser's own `[hidden] { display: none }` is a UA rule, so ANY author rule setting
   `display` beats it — including the one directly above. The result was a spinner that never
   went away: the markup carried `hidden`, JavaScript set `hidden = true` on every completion
   path, and the element stayed on screen anyway, next to a button that had finished. Found
   in Raj's first saved-progress pilot, 2026-09-02.
   `.progress[hidden]` outranks `.progress` on specificity, so this holds wherever it sits. */
.progress[hidden] { display: none !important; }

/* The wait note, same treatment. A <p> is block by default so the UA rule would hold on its
   own — but "it would have been fine anyway" is what was true of the spinner too, right up
   until an author rule was added above it. Stated explicitly so it stays true. */
.wait-note { margin: 10px 0 0; }
.wait-note[hidden] { display: none !important; }

.spinner {
  width: 16px;
  height: 16px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* Motion is a preference some people set for a medical reason. The indicator still has to
   indicate, so it pulses in place instead of spinning. */
@media (prefers-reduced-motion: reduce) {
  /* IT STILL HAS TO INDICATE. `animation: none` would be the easy reading of the
     preference and the wrong one: the person who set it still needs to know something is
     happening. Spinning is replaced by a slow opacity pulse — no movement, no rotation,
     still alive. The ring keeps its accent arc so it does not read as a static dot. */
  .spinner { animation: pulse 1.6s ease-in-out infinite; border-top-color: var(--accent); }
  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
}

/* Tabular figures so the number does not jitter the line as it counts past 9. */
.elapsed {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  min-width: 3ch;
}

/* The example thought, inside the coach's take. Quoted and set apart, because it is a
   sentence the player might have said rather than a sentence the app is asserting. */
.coach p.example {
  border-left: 3px solid var(--line);
  padding-left: 12px;
  color: var(--ink);
}

/* --- accounts, consent and progress ------------------------------------- */

.account-bar { margin: 0 0 12px; font-size: 13px; min-height: 20px; }
.account-link { color: var(--accent); }

/* The consent control. The checkbox is 20px and the whole row is a hit target, because a
   consent decision must not be a thing you miss with your thumb. */
.consent-row { display: flex; align-items: flex-start; gap: 10px; margin: 4px 0 8px; }
.consent-row input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  flex: 0 0 auto;
  accent-color: var(--accent);
}
.consent-row label { cursor: pointer; }

/* Destructive, and it looks it. Not red-on-red — the border carries the warning so the
   label stays readable, including for a colour-blind reader. */
button.danger {
  background: var(--card);
  color: #b3261e;
  border: 1px solid #b3261e;
  font-weight: 600;
}
button.danger:hover { background: #fdf3f2; }

.signal { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.signal h3, .recent h3 { font-size: 14px; margin: 0 0 6px; }
.recent { margin-top: 20px; }
