/* One stylesheet, no build step, no framework - a decision from lot 5 that
   still holds. Everything below is plain CSS that every current browser
   understands. */

:root {
  /* A reading column. Text running the full width of a 1900px screen is what
     makes a page look unfinished, more than any missing decoration. */
  --measure: 46rem;

  /* One spacing scale, used everywhere, rather than the browser's defaults. */
  --gap-xs: 0.25rem;
  --gap-s: 0.5rem;
  --gap: 1rem;
  --gap-l: 1.75rem;
  --gap-xl: 2.5rem;

  --ink: #17191c;
  --ink-soft: #5b6167;
  --line: #e2e5e9;
  --line-strong: #c9ced4;
  --bg: #fcfcfb;
  --surface: #ffffff;
  --accent: #1f6feb;
  --warn: #b3261e;
  --right-bg: #e7f5ea;
  --right-ink: #17692a;
  --wrong-bg: #fdecec;

  --radius: 8px;
}

/* The palette is tokenised, so the dark theme is a redefinition rather than a
   second stylesheet. */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e8eaed;
    --ink-soft: #9aa1a9;
    --line: #2b2f34;
    --line-strong: #3d434a;
    --bg: #14161a;
    --surface: #1b1e23;
    --accent: #6ea8fe;
    --warn: #f28b82;
    --right-bg: #1d3b26;
    --right-ink: #8fd6a2;
    --wrong-bg: #3b1f1f;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0 var(--gap) var(--gap-xl);
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

header,
main {
  max-width: var(--measure);
  margin-inline: auto;
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap);
  padding: var(--gap) 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--gap-l);
}

.brand {
  font-weight: 650;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--ink);
}

header form { display: flex; align-items: center; gap: var(--gap-s); margin: 0; }
header span { color: var(--ink-soft); font-size: 0.875rem; }

h1 {
  font-size: 1.75rem;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 var(--gap-l);
}

h2 {
  font-size: 1.125rem;
  line-height: 1.3;
  margin: var(--gap-l) 0 var(--gap-xs);
}

h3 { font-size: 1rem; margin: 0 0 var(--gap-xs); }
p { margin: 0 0 var(--gap-s); }
a { color: var(--accent); }

/* --- Buttons ------------------------------------------------------------ */

button {
  font: inherit;
  font-weight: 550;
  padding: 0.65rem 1.1rem;
  border: 1px solid var(--ink);
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--bg);
  cursor: pointer;
}

/* An irreversible action and a harmless one must not look alike. "Save the
   draft" is secondary; "validate for good" is the filled one. */
button.secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
  font-weight: 500;
}

button.link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font-weight: 400;
  text-decoration: underline;
}

.actions { display: flex; flex-wrap: wrap; gap: var(--gap-s); margin-top: var(--gap-l); }

/* --- Forms -------------------------------------------------------------- */

.stack { display: flex; flex-direction: column; gap: var(--gap); max-width: 22rem; }
.stack label { display: flex; flex-direction: column; gap: var(--gap-xs); }
.stack input {
  font: inherit;
  padding: 0.65rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}

.messages { list-style: none; padding: 0; margin: 0 0 var(--gap-l); }
.messages li {
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
}
.messages li.error, .error { color: var(--warn); border-color: currentColor; }

/* --- Journeys ----------------------------------------------------------- */

.journey {
  padding: var(--gap) 0 var(--gap-l);
  border-bottom: 1px solid var(--line);
}
.journey:last-of-type { border-bottom: 0; }

/* --- The table, which is the point of the whole application -------------- */

.table-scroll {
  overflow-x: auto;
  /* Let it breathe past the reading column: fifteen rows and five columns
     need the room, and it is the one thing on the page that does. */
  margin-inline: calc(var(--gap) * -1);
  padding-inline: var(--gap);
}

table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }

th, td {
  padding: 0.55rem 0.5rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
  white-space: nowrap;
}

th {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

/* The rank and the fixture stay put while the picks scroll: on a phone you
   otherwise lose track of which match you are reading. */
th:first-child, td:first-child { position: sticky; left: 0; width: 2.2rem; }
th:nth-child(2), td:nth-child(2) { position: sticky; left: 2.2rem; }
th:first-child, td:first-child,
th:nth-child(2), td:nth-child(2) {
  background: var(--bg);
  z-index: 1;
}
td:nth-child(2), th:nth-child(2) { border-right: 1px solid var(--line); }

td.pick, th.pick { text-align: center; width: 2.6rem; font-weight: 600; }
td.result, th.result { border-left: 1px solid var(--line); }

/* Comfortable to tap on a phone: the whole cell is the target, not the dot. */
td.pick label { display: block; padding: 0.35rem 0; cursor: pointer; }
td.pick input[type="radio"] { width: 1.35rem; height: 1.35rem; margin: 0; }

.crowd { color: var(--ink-soft); font-size: 0.85rem; }
.against-crowd { font-weight: 700; color: var(--accent); }

/* A verdict, not a decoration: colour alone would fail a colour-blind reader,
   so the cell is also weighted and struck through. */
td.pick.right { background: var(--right-bg); color: var(--right-ink); }
td.pick.wrong { background: var(--wrong-bg); color: var(--warn); text-decoration: line-through; }
td.pick.result { font-weight: 700; }

/* A checkbox and its name read as one target, and wrap on a narrow screen. */
.tick {
  display: inline-flex;
  align-items: center;
  gap: var(--gap-xs);
  margin: 0 var(--gap) var(--gap-s) 0;
  cursor: pointer;
}
.tick input { width: 1.1rem; height: 1.1rem; }

/* --- The board ----------------------------------------------------------- */

/* Not an error state. With two settled journeys this is what most of the page
   says, so it should read as calm rather than as a warning. */
.empty {
  color: var(--ink-soft);
  background: var(--surface);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius);
  padding: var(--gap);
  margin: var(--gap) 0;
}

.note {
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.headline {
  font-size: 1.1rem;
}

/* The range never wraps away from its rate: split across two lines they read
   as two separate numbers, which is the misreading this page exists to stop. */
.interval .range {
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  margin-left: 0.4em;
}

header nav {
  display: flex;
  gap: var(--gap);
}

/* A band whose record sits badly with what was announced. Deliberately quiet:
   it marks something worth a second look, not an alarm, and at this volume it
   will usually be a false one. */
.flagged th[scope="row"] {
  border-left: 3px solid var(--warn);
  padding-left: var(--gap-s);
}

/* An announced jackpot. Marked because it is the one thing on these pages that
   is known before the deadline and changes what a stake is worth - but quietly,
   since one observation is not a rule. */
.jackpot {
  color: var(--right-ink);
}

/* The scout's page: where it changed the grid, and what it found. The colour is
   never the only signal - the changed pick is also set in bold. */
tr.changed td { background: var(--right-bg); }
.finding { border-left: 3px solid var(--line); padding-left: var(--gap); margin-top: var(--gap-l); }
.finding h2 { font-size: 1rem; margin-bottom: var(--gap-s); }
.finding ul { margin: 0 0 var(--gap-s); padding-left: var(--gap); }
.recipe { margin-bottom: var(--gap-l); }
.recipe ol, .recipe ul { padding-left: var(--gap-l); }
