/* wild-games
   ------------------------------------------------------------------------
   One stylesheet for the whole site, served under a name that contains a hash
   of its contents so it is fetched once and then never again.

   It is written as tokens first and components second. Anything a page wants
   to look different about should be a variable here rather than a style
   attribute there, because these pages are read on a phone on the way to the
   arena and on a laptop while working out who owes whom, and those two want
   the same decisions made once. */

/* ---------------------------------------------------------------- tokens */

:root {
  color-scheme: light dark;

  /* Surfaces, furthest to nearest. Four of them rather than two: a page, the
     cards on it, the things that sit on a card, and a well for the things
     that sit under one. */
  --bg: #f5f4f0;
  --surface: #ffffff;
  --raised: #faf9f6;
  --sunken: #edece7;

  --text: #17201b;
  --muted: #63706a;
  --faint: #909a94;
  --line: #e3e2dc;
  --line-strong: #cfcec7;

  /* The team's forest green, which is the one colour this site could not be
     any other colour. The red and the wheat are the rest of the sweater: red
     carries money and danger, wheat carries the thing somebody wants. */
  --accent: #17553d;
  --accent-hover: #0f3a29;
  --accent-text: #ffffff;
  --accent-weak: #e7f0eb;
  --accent-line: #c6dcd0;

  --gold: #8a6400;
  --gold-bg: #fbf1d8;
  --gold-line: #eddcb0;

  --red: #a6192e;
  --red-bg: #fbeaec;

  --error-bg: #fbeaec;
  --error-text: #931528;
  --ok-bg: #e7f2ea;
  --ok-text: #1c6b39;
  --warn-bg: #fdf2e0;
  --warn-text: #855313;

  /* One radius scale, one shadow scale. */
  --r-sm: 8px;
  --r-md: 11px;
  --r-lg: 16px;
  --r-xl: 22px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(23, 32, 27, 0.05);
  --shadow-md: 0 1px 3px rgba(23, 32, 27, 0.06), 0 6px 16px -6px rgba(23, 32, 27, 0.10);
  --shadow-lg: 0 2px 6px rgba(23, 32, 27, 0.07), 0 18px 40px -18px rgba(23, 32, 27, 0.20);

  --font-display: ui-serif, "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --page: 1080px;
  --gutter: 28px;

  /* Tapping. 44px is the smallest thing a thumb hits reliably, and half of
     what this site is for gets done one-handed. */
  --tap: 44px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f1512;
    --surface: #171e1a;
    --raised: #1f2723;
    --sunken: #0c1210;

    --text: #edf2ee;
    --muted: #9aa8a0;
    --faint: #74817a;
    --line: #2a332e;
    --line-strong: #3b453f;

    --accent: #4fbc8a;
    --accent-hover: #6fd0a3;
    --accent-text: #06170f;
    --accent-weak: #14291f;
    --accent-line: #244634;

    --gold: #eab308;
    --gold-bg: #2c2410;
    --gold-line: #4a3c14;

    --red: #f5808f;
    --red-bg: #35171c;

    --error-bg: #35171c;
    --error-text: #ffb3be;
    --ok-bg: #142a1d;
    --ok-text: #8fd6a6;
    --warn-bg: #2f2611;
    --warn-text: #f0cd8a;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 1px 3px rgba(0, 0, 0, 0.45), 0 6px 16px -6px rgba(0, 0, 0, 0.6);
    --shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.5), 0 18px 40px -18px rgba(0, 0, 0, 0.75);
  }
}

/* ------------------------------------------------------------------ base */

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  padding: var(--gutter) var(--gutter) 64px;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.6 var(--font-body);
  -webkit-font-smoothing: antialiased;
}

/* Signed out pages are a single centred card; signed in pages are a page. */
body.centred {
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: var(--gutter);
}

main {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 34px;
  box-shadow: var(--shadow-md);
}

main.wide {
  max-width: var(--page);
  padding: 32px 34px 38px;
}

h1, h2, h3 { color: var(--text); }

h1 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}

h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.01em;
}

h3 { margin: 0; font-size: 16px; font-weight: 650; }

p { margin: 0 0 20px; color: var(--muted); font-size: 15px; }
p.tight { margin-bottom: 8px; }

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); }

strong { font-weight: 650; }

/* Amounts, counts and dates line up in a column when they are tabular. */
.amount, .num, .count, .money { font-variant-numeric: tabular-nums; }

::selection { background: var(--accent-weak); color: var(--text); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* ----------------------------------------------------------------- icons */

/* Font Awesome is loaded from a kit, which may not be configured. Everything
   is labelled in words as well, so a missing kit is a site without icons
   rather than a site with holes in it. The fixed box keeps a label in the
   same place either way. */
.ico {
  display: inline-block;
  width: 1.05em;
  text-align: center;
  flex: none;
}

.ico-accent { color: var(--accent); }
.ico-muted { color: var(--faint); }
.ico-gold { color: var(--gold); }
.ico-red { color: var(--red); }

/* ------------------------------------------------------------------- nav */

.bar {
  width: 100%;
  max-width: var(--page);
  margin: 0 auto 22px;
}

/* One row, always. A second row of chrome above every page costs more than
   the address it was wrapping to fit, so the account is what gives way: it
   shortens to the name before the @ and truncates from there. */
nav {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 4px;
  padding: 7px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 12px 0 8px;
  margin-right: 4px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}

.brand .ico { color: var(--accent); font-size: 17px; }
.brand:hover { color: var(--text); }

nav a.tab {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: var(--r-sm);
  font-size: 14px;
  font-weight: 550;
  text-decoration: none;
  color: var(--muted);
  white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease;
}

nav a.tab:hover { background: var(--sunken); color: var(--text); }

nav a.tab.on {
  background: var(--accent-weak);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}

nav .spacer { flex: 1; }

/* Whose session this is, which is also the way to your own profile. */
nav a.who:hover { color: var(--text); }
nav a.who.on { color: var(--accent); }

nav .who {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  padding: 0 6px;
  font-size: 13px;
  color: var(--faint);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

nav form { margin: 0; flex: none; }
nav form button { white-space: nowrap; }

/* The count of requests waiting, on the claims link. It is the one thing on
   this site that somebody outside is waiting on, so it is the one thing that
   gets to shout. */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 19px;
  height: 19px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--red);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

@media (prefers-color-scheme: dark) {
  .badge { color: #2a0c12; }
}

/* The bottom bar a phone gets instead of the top one. */
.tabbar { display: none; }

/* ----------------------------------------------------------------- forms */

label {
  display: block;
  margin-bottom: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

input[type=email], input[type=text], input[type=url], input[type=number],
input[type=date], input[type=time], input[type=search], input[type=tel],
select, textarea {
  width: 100%;
  min-height: var(--tap);
  padding: 11px 13px;
  margin-bottom: 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--raised);
  color: var(--text);
  font: inherit;
  font-size: 15px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}

input::placeholder, textarea::placeholder { color: var(--faint); }

input:hover, select:hover, textarea:hover { border-color: var(--muted); }

input:focus, select:focus, textarea:focus {
  outline: none;
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-weak);
}

textarea { min-height: 220px; resize: vertical; font-size: 14px; line-height: 1.6; }

/* A textarea holding a pasted schedule is read as a table, so it is monospaced
   and does not wrap - a wrapped line looks like two games. */
textarea.paste {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  white-space: pre;
  overflow-x: auto;
}

/* A control sized by what is in it rather than by the width of its column. */
select.inline, input.inline {
  width: auto;
  min-height: 36px;
  margin: 0;
  padding: 7px 10px;
  font-size: 13.5px;
}

input.inline.money { width: 100px; text-align: right; }

/* --------------------------------------------------------------- buttons */

button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 11px 18px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--accent-text);
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease,
              box-shadow 0.12s ease, transform 0.06s ease;
}

button:hover { background: var(--accent-hover); }
button:active { transform: translateY(1px); }
button:disabled { opacity: 0.45; cursor: default; transform: none; }
button.block { width: 100%; }

button.quiet {
  min-height: 38px;
  padding: 9px 15px;
  background: var(--surface);
  color: var(--text);
  border-color: var(--line-strong);
  font-size: 14px;
  font-weight: 550;
  box-shadow: var(--shadow-sm);
}

button.quiet:hover { background: var(--raised); border-color: var(--muted); }

.card button.quiet, .game button.quiet, td button.quiet { box-shadow: none; }

button.link {
  min-height: 0;
  width: auto;
  padding: 4px 2px;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 13px;
  font-weight: 550;
  text-decoration: underline;
  text-underline-offset: 2px;
}

button.link:hover { background: none; color: var(--accent); }

button.danger { color: var(--red); }
button.danger:hover { color: var(--red); background: var(--red-bg); border-color: var(--red); }

/* A row of controls that should wrap rather than overflow on a phone. */
.actions-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* --------------------------------------------------------------- banners */

.banner {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  flex-wrap: wrap;
  padding: 13px 15px;
  margin-bottom: 20px;
  border-radius: var(--r-md);
  font-size: 14.5px;
  line-height: 1.5;
  background: var(--error-bg);
  color: var(--error-text);
}

.banner .ico { margin-top: 3px; }
.banner > span { flex: 1 1 240px; }
.banner a { color: inherit; font-weight: 600; }
.banner.ok { background: var(--ok-bg); color: var(--ok-text); }
.banner.warn { background: var(--warn-bg); color: var(--warn-text); }
.banner ul { margin: 6px 0 0; padding-left: 18px; }

/* ---------------------------------------------------------------- layout */

.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding-top: 20px;
  margin-top: 26px;
  border-top: 1px solid var(--line);
}

.row form { margin: 0; }

.who { font-size: 13px; color: var(--faint); overflow-wrap: anywhere; }
.muted-small { font-size: 13.5px; color: var(--muted); }

.list-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin: 34px 0 6px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--line);
}

.list-head h1, .list-head h2 { margin: 0; }
.list-head h2 { display: flex; align-items: center; gap: 9px; }
.list-head h2 .ico { color: var(--accent); font-size: 15px; }
.list-head.plain { border-bottom: 0; padding-bottom: 0; }
.list-head.first { margin-top: 0; }

.empty {
  margin: 16px 0 0;
  padding: 26px 20px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--raised);
  font-size: 14.5px;
  color: var(--muted);
  text-align: center;
}

.empty .ico { display: block; width: auto; font-size: 24px; color: var(--faint); margin-bottom: 10px; }

.fields { display: flex; gap: 16px; }
.fields > div { flex: 1; min-width: 0; }
.fields > div.narrow { flex: 0 0 130px; }
.fields > div.wide { flex: 2; }

/* A checkbox and the words that go with it, as one thing to hit. The words are
   half of a 44px target and the box on its own is a quarter of one. */
.tick {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: var(--tap);
  font-weight: 400;
  cursor: pointer;
}

.tick input { width: auto; min-height: 0; margin: 0; }

/* Text that is only there for a screen reader. Every icon on this site has
   words beside it except the ones that are the whole control, and those need
   their words somewhere. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* The heading at the top of a page, with the season picker beside it. */
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.page-head h1 { margin: 0; }
.page-head .sub { margin: 2px 0 0; font-size: 14px; color: var(--muted); }

/* ----------------------------------------------------------------- pills */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 2px 5px 2px 0;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--raised);
  color: var(--muted);
  font-size: 12px;
  font-weight: 550;
  line-height: 18px;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: middle;
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}

a.pill:hover { border-color: var(--muted); color: var(--text); }
.pill.on { background: var(--accent); color: var(--accent-text); border-color: transparent; }

/* A pill that is really a button. */
a.pill.action {
  min-height: 38px;
  padding: 8px 15px;
  background: var(--accent);
  border-color: transparent;
  color: var(--accent-text);
  font-size: 14px;
  font-weight: 600;
}

a.pill.action:hover { background: var(--accent-hover); color: var(--accent-text); }

/* The statuses, coloured so a season can be read down the right hand edge
   without reading any of the words. */
.pill.st-going { background: var(--accent-weak); color: var(--accent); border-color: var(--accent-line); }
.pill.st-available { background: var(--gold-bg); color: var(--gold); border-color: var(--gold-line); }
.pill.st-claimed { background: var(--warn-bg); color: var(--warn-text); border-color: transparent; }
.pill.st-sold { background: var(--ok-bg); color: var(--ok-text); border-color: transparent; }
.pill.st-unused { background: var(--red-bg); color: var(--red); border-color: transparent; }

/* What one person said. The two that are a claim on the tickets carry the
   colour; the rest are legible and quiet, because a row where every pill is
   shouting says no more than a row where none of them is. */
.pill.mk-want { background: var(--gold-bg); color: var(--gold); border-color: var(--gold-line); }
.pill.mk-self { background: var(--accent-weak); color: var(--accent); border-color: var(--accent-line); }
.pill.mk-unsure { color: var(--warn-text); border-color: var(--line-strong); }
.pill.mk-cant { color: var(--muted); text-decoration: line-through; }
/* Nothing said yet is drawn as an outline waiting to be filled in, because it
   is the one answer that is still owed. */
.pill.mk-none { color: var(--muted); border-style: dashed; }

.pill.type { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }

/* How a game finished. A win and a loss are the only two things worth telling
   apart at a glance, so a game lost in overtime is drawn as the loss it was
   and says "OT" for the point it was worth. */
.pill.result { font-variant-numeric: tabular-nums; font-weight: 650; }
.pill.result.won { background: var(--ok-bg); color: var(--ok-text); border-color: transparent; }
.pill.result.lost { background: var(--red-bg); color: var(--red); border-color: transparent; }

.result { font-variant-numeric: tabular-nums; }
.facts .result.won { color: var(--ok-text); }
.facts .result.lost { color: var(--red); }

/* ----------------------------------------------------------------- stats */

/* The row of numbers that was along the bottom of the spreadsheet. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 20px 0 4px;
}

.stat {
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--raised);
}

.stat .label {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.stat .label .ico { color: var(--faint); font-size: 11px; }

.stat .value {
  margin-top: 5px;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.stat .note { margin-top: 2px; font-size: 12.5px; color: var(--faint); }
.stat.good .value { color: var(--ok-text); }
.stat.owed .value { color: var(--red); }

/* How much of the package has come back. */
.meter {
  width: 100%;
  height: 5px;
  margin-top: 10px;
  border-radius: var(--r-pill);
  background: var(--sunken);
  overflow: hidden;
}

.meter > span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 0.25s ease;
}

/* ----------------------------------------------------------------- games */

.month {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 26px 0 8px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.games { margin: 0; padding: 0; list-style: none; }

/* Every row is coloured by what is happening with its pair, so a season can be
   read down the page without reading a word of it. One pair of variables per
   status, set on the row and used by everything inside it - the alternative was
   five rules each for the rule down the edge, the date block and the dropdown,
   and they would have drifted apart the first time a status was added. */
.game {
  --state: var(--line-strong);
  --state-line: var(--line);
  --state-bg: transparent;

  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 12px 4px 12px 13px;
  border-bottom: 1px solid var(--line);
  border-left: 3px solid var(--state);
  border-radius: 3px 0 0 3px;
}

.game.st-going     { --state: var(--accent);    --state-line: var(--accent-line); --state-bg: var(--accent-weak); }
.game.st-available { --state: var(--gold);      --state-line: var(--gold-line);   --state-bg: var(--gold-bg); }
.game.st-claimed   { --state: var(--warn-text); --state-line: transparent;        --state-bg: var(--warn-bg); }
.game.st-sold      { --state: var(--ok-text);   --state-line: transparent;        --state-bg: var(--ok-bg); }
.game.st-unused    { --state: var(--red);       --state-line: transparent;        --state-bg: var(--red-bg); }

/* Undecided is the one status that should not shout. It is the absence of a
   decision, and colouring it would make a season nobody has been through yet
   look like a season where everything is happening. */
.game.st-undecided { --state: var(--line-strong); --state-line: var(--line); --state-bg: transparent; }

.game:last-child { border-bottom: 0; }

/* A game that has been played is done with rather than gone. It keeps its
   colour and loses its weight - far enough back to skim past, near enough to
   read, because most of a season is in the past by February and a page that is
   mostly ghosts is a page nobody opens. */
.game.past { opacity: 0.72; }

/* The date, drawn as a block so a season can be scanned down its left edge. */
.game .date {
  flex: none;
  width: 52px;
  padding: 6px 0 7px;
  border: 1px solid var(--state-line);
  border-radius: var(--r-md);
  background: var(--state-bg);
  text-align: center;
  text-decoration: none;
  color: var(--text);
  line-height: 1.15;
}

/* An undecided game has no colour to lend the block, so it borrows the page's
   own instead of coming out as a hole in the list. */
.game.st-undecided .date { background: var(--raised); }

.game .date .mon {
  display: block;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--state);
}

.game .date .num { display: block; font-size: 19px; font-weight: 650; }
.game .date .dow { display: block; font-size: 10.5px; color: var(--faint); }
.game .date:hover { border-color: var(--accent); }

.game .what { flex: 1 1 220px; min-width: 0; }

.game .what h3 { font-size: 16px; font-weight: 650; letter-spacing: -0.01em; }
.game .what h3 a { color: var(--text); text-decoration: none; }
.game .what h3 a:hover { color: var(--accent); }

.game .meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--faint);
}

.game .marks { margin-top: 7px; }

/* The right hand end: what is happening with the pair, and what it is worth. */
.game .state {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: flex-end;
  flex: 0 1 auto;
}

.game .state .money { font-size: 13.5px; font-weight: 650; color: var(--muted); }

/* The price tag on a pair that is out on a marketplace right now. It is small
   on purpose: it is a fact about a game rather than what is happening to it,
   and the status beside it is the thing worth reading first. */
.game .state .tag {
  display: inline-flex;
  align-items: center;
  color: var(--gold);
  font-size: 14px;
}

/* The dropdown is the status, so it is coloured like one. It is a control
   rather than a label, so it keeps its border and its arrow - a select that
   looked exactly like the pill beside it would be a pill nobody tried to
   click. */
select.inline.state-picker {
  border-color: var(--state-line);
  background-color: var(--state-bg);
  color: var(--state);
  font-weight: 600;
}

.game.st-undecided select.inline.state-picker {
  background-color: var(--raised);
  color: var(--muted);
  font-weight: 550;
}

/* And the answer beside it, for the one person whose answer is a control. The
   colours are the pill's, so your own row and the other person's read the
   same. */
select.inline.mk-want { border-color: var(--gold-line); background-color: var(--gold-bg); color: var(--gold); }
select.inline.mk-self { border-color: var(--accent-line); background-color: var(--accent-weak); color: var(--accent); }
select.inline.mk-unsure { color: var(--warn-text); }
select.inline.mk-cant { color: var(--muted); }
select.inline.mk-none { color: var(--muted); border-style: dashed; }

/* ---------------------------------------------------------------- cards */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 16px;
  margin-top: 18px;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition: box-shadow 0.16s ease, transform 0.16s ease, border-color 0.16s ease;
}

.card:hover, .card:focus-within {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}

.card .body { display: flex; flex-direction: column; flex: 1; padding: 16px 17px 17px; }
.card h3 { margin: 0 0 5px; font-family: var(--font-display); font-size: 18px; font-weight: 600; }
.card .meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--faint); }
.card .spacer { flex: 1; min-height: 12px; }
.card .price { font-size: 15px; font-weight: 650; font-variant-numeric: tabular-nums; }

/* The band along the top of a card on the share page, standing in for the
   photograph a cookbook would have. */
.card .band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 17px;
  background: linear-gradient(120deg, var(--accent), var(--accent-hover));
  color: var(--accent-text);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.card .band .ico { color: inherit; }

/* ---------------------------------------------------------------- tables */

.scroll {
  overflow-x: auto;
  margin-top: 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

table { width: 100%; border-collapse: collapse; font-size: 14.5px; }

th {
  padding: 12px 14px;
  background: var(--raised);
  border-bottom: 1px solid var(--line);
  text-align: left;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  white-space: nowrap;
}

td { padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--raised); }
tr.bad td { background: var(--error-bg); }
tr.bad:hover td { background: var(--error-bg); }

/* A row that reads fine and is worth a second look. It is not red, because it
   is not wrong - it is a guess, and a guess drawn as an error teaches people to
   ignore errors. */
tr.odd td { background: var(--warn-bg); }
tr.odd:hover td { background: var(--warn-bg); }
td.actions { white-space: nowrap; text-align: right; }
td.actions button { margin-left: 8px; }
td.number { text-align: right; font-variant-numeric: tabular-nums; }

/* A column holding nothing but a dropdown, sized by what is in it rather than
   by a guessed pixel width. */
.col-pick { width: 1%; white-space: nowrap; }

/* --------------------------------------------------------------- details */

/* One game's page: the facts, then the things that can be changed about it. */
.facts { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0 0; padding: 0; list-style: none; }

.facts li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--raised);
  font-size: 13.5px;
  color: var(--text);
}

.facts .ico { color: var(--accent); }
.facts .label { color: var(--muted); }

/* A panel of related controls, so a long form reads as three short ones. */
.panel {
  margin-top: 18px;
  padding: 20px 22px 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.panel > h2 { margin-bottom: 14px; display: flex; align-items: center; gap: 9px; }
.panel > h2 .ico { color: var(--accent); font-size: 15px; }
.panel > p { font-size: 13.5px; }

/* The share link, sitting there to be copied. */
.copy {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  background: var(--accent-weak);
  font-size: 14px;
}

.copy code {
  flex: 1 1 240px;
  min-width: 0;
  overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  color: var(--accent);
}

/* -------------------------------------------------------- asking for one */

/* The request form on the share page, folded into the card it belongs to. It
   is a details element rather than a dialog because whoever this link gets
   forwarded to is a stranger on an unknown browser: this opens with no
   javascript at all, and a button that quietly does nothing is the one failure
   that page cannot afford. */
details.claim summary {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 11px 18px;
  border-radius: var(--r-md);
  background: var(--accent);
  color: var(--accent-text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background 0.12s ease;
}

details.claim summary::-webkit-details-marker { display: none; }
details.claim summary:hover { background: var(--accent-hover); }
details.claim summary .ico { color: inherit; }
details.claim[open] summary { border-radius: var(--r-md) var(--r-md) 0 0; }

details.claim form {
  padding: 18px 16px 4px;
  border: 1px solid var(--accent-line);
  border-top: 0;
  border-radius: 0 0 var(--r-md) var(--r-md);
  background: var(--raised);
}

details.claim form input, details.claim form textarea { margin-bottom: 12px; }

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

/* The claim form on the share page. A dialog rather than a second page: the
   person is looking at the game they want, and taking that off the screen to
   ask for their name is how a two-field form gets abandoned. */
dialog {
  width: min(440px, calc(100vw - 32px));
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
}

dialog::backdrop { background: rgba(10, 16, 13, 0.55); }
dialog h2 { margin-bottom: 4px; font-family: var(--font-display); font-size: 21px; }

/* ---------------------------------------------------------------- phones */

@media (max-width: 900px) {
  :root { --gutter: 14px; }

  body { padding-bottom: calc(var(--tap) + 34px + env(safe-area-inset-bottom)); }
  body.centred { padding-bottom: var(--gutter); }

  main { padding: 22px 16px 26px; border-radius: var(--r-lg); }
  main.wide { padding: 20px 14px 26px; }

  h1 { font-size: 25px; }

  .fields { flex-direction: column; gap: 0; }
  .fields > div.narrow { flex: 1; }

  /* The top bar keeps the name and the way out; the links move to a bar along
     the bottom, where a thumb can reach them one-handed. */
  nav a.tab { display: none; }
  nav .who { display: none; }
  nav { padding: 9px 12px; }

  .tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 10;
    display: flex;
    justify-content: space-around;
    gap: 2px;
    padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--line);
    box-shadow: 0 -6px 24px -14px rgba(0, 0, 0, 0.3);
  }

  .tabbar a {
    position: relative;
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: var(--tap);
    padding: 5px 2px;
    border-radius: var(--r-sm);
    font-size: 10.5px;
    font-weight: 600;
    color: var(--faint);
    text-decoration: none;
  }

  .tabbar a .ico { font-size: 17px; width: auto; }
  .tabbar a.on { color: var(--accent); background: var(--accent-weak); }
  .tabbar .badge { position: absolute; top: 2px; right: 50%; margin-right: -20px; }

  /* A game's controls go under the game rather than beside it, so nothing is
     squeezed to two words a line. */
  .game { flex-wrap: wrap; gap: 12px; }
  .game .what { flex: 1 1 auto; }
  .game .state { flex: 1 1 100%; justify-content: flex-start; padding-left: 66px; }

  .stats { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
  .stat { padding: 12px 13px; }
  .stat .value { font-size: 20px; }

  .cards { grid-template-columns: 1fr; gap: 12px; }

  .panel { padding: 16px 14px 4px; }
}

/* Anything that would move, for a person who has asked things not to. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  .card:hover, .card:focus-within { transform: none; }
}

/* Nothing here is meant for paper except a schedule, and that wants the list
   and none of the software around it. */
@media print {
  body { padding: 0; background: #fff; color: #000; }
  .bar, .tabbar, button, select, .copy { display: none !important; }
  main, main.wide { max-width: none; border: 0; box-shadow: none; padding: 0; }
  .game { break-inside: avoid; }
}
