/* LoCo League — all styles.
   Mobile first: the base rules are the phone layout, widened at the media query. */

:root {
  /* Gold and graphite. Gold is the action colour, graphite the furniture, and
     red is kept for the two things that are genuinely destructive or wrong. */
  --ink: #282a2e;
  --ink-soft: #33363b;
  --gold: #8a6410;          /* links, primary text on white: 5.37 on card */
  --gold-lift: #b08420;
  --amber: #d9a32c;         /* a background only. White on it fails at 2.28 */
  --danger: #9e2f28;
  --paper: #f5f4f1;
  --card: #ffffff;
  --text: #23252a;
  --muted: #6a6d74;
  --line: #e3e1db;

  --gold-line: #c9a227;

  /* One gradient, reused, so gold reads as a metal rather than as mustard. */
  --gold-metal: linear-gradient(160deg, #b8891a 0%, #d8ae3a 45%, #a87a12 100%);

  /* The previous names, kept pointing at the new colours. Every rule below
     still uses them, and renaming 30-odd call sites would be churn for no gain
     -- the palette is what changed, not what the token means. */
  --teal: var(--gold);
  --teal-lift: var(--gold-lift);

  --font-head: Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-body: -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto,
    system-ui, sans-serif;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

h1,
h2 {
  font-family: var(--font-head);
  line-height: 1.2;
  margin: 0 0 0.5rem;
}

h1 {
  font-size: 1.75rem;
}

h2 {
  font-size: 1.3rem;
}

p {
  margin: 0 0 0.75rem;
  max-width: 36rem;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--teal);
}

a:hover {
  color: var(--teal-lift);
}

:focus-visible {
  outline: 3px solid var(--teal-lift);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
}

.skip-link:focus {
  left: 0.5rem;
  top: 0.5rem;
  z-index: 2;
  background: var(--card);
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
}

/* --- Masthead ------------------------------------------------------------- */
/* One dark band carrying the name, the strapline and the menu. The site used to
   have a bar and then a separate nav strip, which was two pieces of furniture
   doing one job. */

.masthead {
  background:
    repeating-linear-gradient(115deg,
      rgba(255, 255, 255, 0.022) 0 2px,
      transparent 2px 9px),
    linear-gradient(180deg, #2f3237 0%, var(--ink) 100%);
  color: #fff;
  padding: 1.4rem 1.25rem 1.1rem;
  border-bottom: 3px solid transparent;
  border-image: var(--gold-metal) 1;
}

.masthead-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
}
.masthead-brand:hover .masthead-name { text-decoration: underline; }

.masthead-mark {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--gold-metal);
  color: #221c08;
  padding: 0.25rem 0.55rem;
  border-radius: 4px;
  font-size: 0.95rem;
  flex: none;
}

/* The name carries the gold now that the mark beside it has gone. A gradient
   rather than a flat fill, so it reads as the same metal as the rule below it. */
.masthead-name {
  font-family: var(--font-head);
  font-size: 1.7rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
  background: var(--gold-metal);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* A browser that cannot clip a background to text gets solid gold instead of
   nothing, which is the failure worth designing for. */
@supports not (background-clip: text) {
  .masthead-name { background: none; color: var(--gold-line); }
}

.masthead-strap {
  margin: 0.55rem 0 0;
  color: rgba(255, 255, 255, 0.74);
  font-size: 0.92rem;
}

.masthead-meta {
  margin: 0.8rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.78);
}

/* The menu, inside the band. A gold underline marks the current page, which the
   old grey strip could not show without inventing another colour. */
.masthead-nav {
  margin-top: 0.85rem;
  padding-top: 0.7rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.masthead-nav ul {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1.4rem;
  margin: 0;
  padding: 0;
}
.masthead-nav a {
  display: inline-block;
  color: rgba(255, 255, 255, 0.82);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.2rem 0;
  border-bottom: 2px solid transparent;
}
.masthead-nav a:hover,
.masthead-nav a:focus {
  color: #fff;
  border-bottom-color: rgba(255, 255, 255, 0.4);
}
.masthead-nav a[aria-current="page"] {
  color: #fff;
  border-bottom-color: var(--gold-line);
}
.masthead-nav a:focus-visible { outline-color: var(--gold-line); }

/* An inner page keeps the name, the strapline and the menu, and drops the
   meeting details. The header should not eat a phone screen on the way to
   something else. */
.masthead-compact { padding-bottom: 0.9rem; }
.masthead-compact .masthead-name { font-size: 1.3rem; }

/* --- Content -------------------------------------------------------------- */

main {
  flex: 1 0 auto;
  width: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: 1.5rem 1rem 2.5rem;
}

.lede {
  font-size: 1.05rem;
  color: var(--muted);
  margin-bottom: 1.5rem;
}

.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.1rem 1rem;
  margin-bottom: 1rem;
}

.meets-when {
  font-family: var(--font-head);
  font-size: 1.15rem;
}

/* Missing the sign-in time means missing the day, so it gets its own marked line. */
.meets-deadline {
  font-weight: 600;
  border-left: 4px solid var(--amber);
  padding-left: 0.7rem;
  margin-bottom: 0.85rem;
}

.meets-where {
  font-style: normal;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--ink);
  color: #c3cad6;
  padding: 1.5rem 1rem;
  font-size: 0.9rem;
}

.site-footer p {
  max-width: 44rem;
  margin-bottom: 0.4rem;
}

/* Nav entries for pages that are not built yet. Not links, so nothing 404s. */
.nav-soon {
  display: inline-block;
  padding: 0.5rem 0;
  font-size: 0.95rem;
  color: #8792a4;
  border-bottom: 3px solid transparent;
  cursor: default;
}

.page-subhead {
  font-family: var(--font-head);
  font-size: 1.15rem;
  color: var(--muted);
  margin-top: -0.35rem;
  margin-bottom: 1rem;
}

/* --- Numbered steps -------------------------------------------------------- */

.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
}

.step {
  counter-increment: step;
  position: relative;
  padding-left: 2.25rem;
  margin-bottom: 1.1rem;
}

.step:last-child {
  margin-bottom: 0;
}

.step::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.05rem;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: var(--ink);
  color: var(--amber);
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}

.step-heading {
  font-family: var(--font-head);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.2;
  margin: 0 0 0.15rem;
}

.panel-quiet {
  background: transparent;
  border-style: dashed;
}

.back-link {
  display: inline-block;
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
}

.screenshot {
  margin: 0.75rem 0;
}

.screenshot img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--card);
}

.screenshot figcaption {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 0.35rem;
}

/* --- Cards and events ------------------------------------------------------ */

.card-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1rem;
}

.badges {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.6rem;
  padding: 0;
}

.badge {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--card);
  background: var(--teal);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
}

.badge-note { background: var(--ink-soft); }

/* One colour per kind of event, so a Challenge is never mistaken for the weekly
   casual tournament at a glance. Casual is the quietest because it is the norm;
   the sanctioned and one-off events are the ones that need to stand out.
   Every pairing below clears 4.5:1 against its text colour. */
.badge-casual,
.badge-league   { background: var(--muted); }
.badge-challenge { background: var(--teal); }
.badge-cup       { background: #a8641a; }
.badge-prerelease { background: #6b4fa0; }
.badge-special   { background: var(--amber); color: var(--ink); }

/* --- Day groups ------------------------------------------------------------ */

.day-group {
  margin-bottom: 1.5rem;
}

.day-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 1.1rem;
  margin: 0 0 0.6rem;
  padding-bottom: 0.35rem;
  border-bottom: 2px solid var(--line);
}

/* A day carrying more than one event is boxed, so a double-header reads as one
   day rather than as two unrelated cards that happen to sit together. */
.day-group-multi {
  background: #eef1f5;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.9rem;
}

.day-group-multi .day-heading {
  border-bottom-color: #d3d9e2;
}

.day-count {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.event-when {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.2rem;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  font-weight: 600;
}

.event-time {
  color: var(--text);
  letter-spacing: 0;
  text-transform: none;
  font-variant-numeric: tabular-nums;
}

.event-name { margin-bottom: 0.5rem; }

.event-fee,
.event-note {
  margin: 0.5rem 0 0;
  font-size: 0.95rem;
  color: var(--muted);
}

.count {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}

.event-spots { margin-top: 0.75rem; }

.division-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 20rem;
  font-size: 0.95rem;
  color: var(--muted);
}

.division-list li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.25rem 0;
  border-bottom: 1px solid var(--line);
}

.division-list li:last-child { border-bottom: 0; }

/* --- Disclosures and forms -------------------------------------------------- */

.disclosure {
  margin-top: 0.85rem;
  border-top: 1px solid var(--line);
  padding-top: 0.75rem;
}

.disclosure summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--teal);
  padding: 0.25rem 0;
}

.disclosure summary:hover { color: var(--teal-lift); }

.register-form,
.cancel-form {
  margin-top: 0.5rem;
}

.field {
  margin: 0 0 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.field label {
  font-size: 0.9rem;
  font-weight: 600;
}

.field input {
  font: inherit;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--text);
  /* Keeps iOS from zooming in when a field is focused. */
  font-size: 1rem;
  max-width: 22rem;
}

.field-help {
  margin: -0.3rem 0 0.8rem;
  font-size: 0.85rem;
  color: var(--muted);
  max-width: 22rem;
}

.button {
  font: inherit;
  font-weight: 600;
  color: var(--card);
  background: var(--teal);
  border: 0;
  border-radius: 6px;
  padding: 0.6rem 1.1rem;
  cursor: pointer;
}

.button:hover { background: var(--teal-lift); }
.button:disabled { opacity: 0.6; cursor: default; }

.button-quiet {
  background: transparent;
  color: var(--teal);
  border: 1px solid var(--teal);
}

.button-quiet:hover { background: var(--paper); color: var(--teal-lift); }

.form-status {
  margin: 0.6rem 0 0;
  font-size: 0.95rem;
  max-width: 26rem;
}

.form-status.is-error {
  color: var(--text);
  border-left: 4px solid var(--amber);
  padding-left: 0.7rem;
}

.form-status.is-good {
  color: var(--text);
  border-left: 4px solid var(--teal);
  padding-left: 0.7rem;
}

/* --- Notices ---------------------------------------------------------------- */

.notice { color: var(--muted); margin: 0; }

.notice-problem {
  background: var(--card);
  border-left: 4px solid var(--amber);
  border-radius: 0 8px 8px 0;
  padding: 0.75rem 1rem;
  color: var(--text);
  max-width: 36rem;
}

.notice-quiet { padding: 0.75rem 0; }

/* --- Jump links ------------------------------------------------------------ */

.jump-nav {
  margin: 0 0 1.25rem;
}

.jump-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.jump-nav a {
  display: inline-block;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--card);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 600;
}

.jump-nav a:hover {
  border-color: var(--teal-lift);
}

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

/* Tables are the one thing allowed to scroll sideways on a narrow screen; the
   page itself never does. */
.table-wrap {
  overflow-x: auto;
  margin: 0.75rem 0 1rem;
}

.data-table {
  border-collapse: collapse;
  width: 100%;
  text-align: left;
}

.data-table th,
.data-table td {
  border-bottom: 1px solid var(--line);
  padding: 0.6rem 0.75rem 0.6rem 0;
  vertical-align: top;
}

.data-table thead th {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}

.data-table tbody th {
  font-weight: 600;
  padding-right: 1rem;
}

.data-table tbody tr:last-child th,
.data-table tbody tr:last-child td {
  border-bottom: 0;
}

.rank-name,
.badge-name,
.tier-name {
  font-family: var(--font-head);
}

.row-note,
.eligibility {
  display: block;
  font-weight: 400;
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: 0.15rem;
}

.eligibility {
  color: var(--teal);
  font-weight: 600;
}

.points-cell {
  text-align: right;
  width: 5rem;
  white-space: nowrap;
}

/* --- Section furniture ------------------------------------------------------ */

h3 {
  font-family: var(--font-head);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1.2;
  margin: 1.5rem 0 0.35rem;
}

.section-note {
  font-size: 0.9rem;
  color: var(--muted);
  margin-top: 1rem;
}

.release-window {
  margin-bottom: 0.5rem;
}

.callout {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--teal);
  border-radius: 0 8px 8px 0;
  padding: 0.85rem 1rem;
  margin: 1rem 0;
  font-weight: 600;
  max-width: none;
}

/* The steps list on the prize wall carries no headings, so the number needs to
   line up with the first line of text rather than a heading above it. */
.step > p:first-child {
  margin-top: 0;
}

/* --- Player lookup ---------------------------------------------------------- */

.lookup-form {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: 1rem;
}

.summary {
  margin-bottom: 1rem;
}

.summary-name {
  font-size: 1.4rem;
  margin-bottom: 0.35rem;
}

/* A star per season won. The year is written out beside it, so the meaning does
   not depend on recognising the symbol. */
.champion-stars {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.85rem;
}

.champion-star {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  background: var(--ink);
  color: var(--amber);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
}

.star { font-size: 0.95rem; line-height: 1; }
.star-year { font-variant-numeric: tabular-nums; }

.stat-grid {
  display: grid;
  gap: 0.75rem;
  margin: 0 0 1rem;
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  border-left: 3px solid var(--line);
  padding-left: 0.75rem;
}

.stat-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}

.stat-value {
  font-family: var(--font-head);
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.stat-extra {
  font-size: 0.85rem;
  color: var(--muted);
}

.badge-count { margin-bottom: 0.5rem; }

.badge-chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
}

.badge-chip {
  background: var(--teal);
  color: var(--card);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
  font-size: 0.85rem;
  font-weight: 600;
}

.past-seasons { margin-top: 1.25rem; }

.season-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 26rem;
}

.season-list li {
  display: flex;
  gap: 0.75rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--line);
  font-size: 0.95rem;
}

.season-list li:last-child { border-bottom: 0; }
.season-year { min-width: 3rem; }

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

.player-list {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.4rem;
}

.player-button {
  font: inherit;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  cursor: pointer;
  color: var(--text);
}

.player-button:hover {
  border-color: var(--teal-lift);
}

.player-label { font-weight: 600; }
.player-id { color: var(--muted); font-weight: 400; }

/* The summary sits above the list, so a long list never pushes it out of sight.
   On a wide screen the two sit side by side and the summary sticks while the
   list scrolls. On a phone it stays at the top and selecting a player scrolls
   back to it -- a card this tall cannot usefully be pinned to a small screen. */
.player-layout {
  display: grid;
  gap: 1rem;
  align-items: start;
}

.result-col:empty { display: none; }

/* One colour per badge, assigned by position in the season's list. Each clears
   4.5:1 against white. */
.badge-c0  { background: #1f7f76; }
.badge-c1  { background: #6b4fa0; }
.badge-c2  { background: #a8641a; }
.badge-c3  { background: #2b6cb0; }
.badge-c4  { background: #9b2c52; }
.badge-c5  { background: #2f7a3f; }
.badge-c6  { background: #7a5c1e; }
.badge-c7  { background: #3f5f8a; }
.badge-c8  { background: #8a3f6b; }
.badge-c9  { background: #1f6f8f; }
.badge-c10 { background: #b3452a; }
.badge-c11 { background: #4a6b1f; }
.badge-c12 { background: #7d2f3f; }

/* --- Professor tools -------------------------------------------------------- */

.tool-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.tool-card {
  display: block;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  text-decoration: none;
  color: var(--text);
}

.tool-card:hover { border-color: var(--teal-lift); }

.tool-name {
  display: block;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--teal);
  margin-bottom: 0.15rem;
}

.tool-note {
  display: block;
  font-size: 0.9rem;
  color: var(--muted);
}

.link-button {
  font: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: var(--teal);
  text-decoration: underline;
  cursor: pointer;
}

/* The bar a professor sees at the foot of every public page. It is a
   convenience, not a control: hiding it from everyone else protects nothing,
   and the database refuses the queries regardless. */
.prof-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--ink);
  color: var(--card);
  border-top: 3px solid var(--amber);
  z-index: 10;
  font-size: 0.9rem;
}

.prof-bar-inner {
  max-width: 46rem;
  margin: 0 auto;
  padding: 0.6rem 1rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

.prof-who {
  color: #c3cad6;
  flex: 1 1 100%;
  font-size: 0.8rem;
}

.prof-links {
  display: flex;
  gap: 1rem;
  flex: 1 1 auto;
}

.prof-bar a { color: var(--card); }

.prof-primary {
  font-weight: 700;
  color: var(--amber) !important;
}

.prof-signout {
  font: inherit;
  background: none;
  border: 1px solid #3a4a63;
  border-radius: 6px;
  color: #c3cad6;
  padding: 0.25rem 0.7rem;
  cursor: pointer;
}

.prof-bar :focus-visible { outline-color: var(--amber); }

/* Keeps the bar from covering the end of a page. */
.has-prof-bar .site-footer { padding-bottom: 4.5rem; }

@media (min-width: 34rem) {
  .prof-who { flex: 0 1 auto; }
}

@media (min-width: 34rem) {
  h1 {
    font-size: 2.1rem;
  }

  .card-list {
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    align-items: start;
  }

  .stat-grid {
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  }
}

@media (min-width: 52rem) {
  .player-layout {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  }

  .result-col {
    position: sticky;
    top: 1rem;
  }

  .list-col {
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
  }

  /* Wider: the band gets room, and a page of content stops stretching into
     lines nobody can track back from. */
  .masthead { padding: 1.7rem 2rem 1.2rem; }
  .masthead-name { font-size: 2.2rem; }
  .masthead-compact .masthead-name { font-size: 1.6rem; }

  .masthead-brand,
  .masthead-strap,
  .masthead-meta,
  .masthead-nav {
    max-width: 62rem;
    margin-left: auto;
    margin-right: auto;
  }
}

/* --- TDF upload ------------------------------------------------------------ */

.field select {
  font: inherit;
  font-size: 1rem;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--text);
  max-width: 26rem;
}

/* A checkbox sits beside its label rather than above it, unlike every other
   field: a stacked checkbox reads as a heading with an orphaned box. */
.field-inline {
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
}
.field-inline input {
  width: 1.1rem;
  height: 1.1rem;
  max-width: none;
  flex: none;
}
.field-inline label {
  font-weight: 400;
}

.summary-list {
  margin: 0.75rem 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.3rem 1rem;
  font-size: 0.95rem;
}
.summary-list dt {
  color: var(--muted);
}
.summary-list dd {
  margin: 0;
  font-weight: 600;
}

.attendee-list {
  max-height: 18rem;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 0.4rem;
  background: var(--paper);
}
.attendee {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.3rem 0.4rem;
  font-size: 0.95rem;
}

.tag {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
}
.tag-new {
  background: var(--amber);
  color: var(--ink);
}
.tag-added {
  background: var(--teal);
  color: var(--card);
}

/* The count of people about to be created is the one thing on this screen worth
   stopping for, so it gets the same treatment as a warning rather than sitting
   inline with the rest of the form. */
.warn-block {
  margin: 0.85rem 0;
  padding: 0.75rem 0.9rem;
  border-left: 4px solid var(--amber);
  background: var(--paper);
  border-radius: 0 6px 6px 0;
}
.warn-block p:first-child {
  margin-top: 0;
}
.warn-block .field-help {
  margin-bottom: 0;
}

.disclosure-body {
  padding-top: 0.5rem;
}

.search-results {
  display: grid;
  gap: 0.35rem;
  max-width: 26rem;
}

/* --- Visibility consent ----------------------------------------------------- */

/* Whether the player is public *right now* is the one thing a professor must
   read correctly before saying anything to a parent, so it gets stated plainly
   rather than inferred from two switches further down the card. */
.live-state {
  margin: 0.5rem 0;
  font-weight: 600;
  padding: 0.5rem 0.7rem;
  border-radius: 6px;
}
.live-state.is-on {
  background: #e8f4f2;
  border-left: 4px solid var(--teal);
}
.live-state.is-off {
  background: var(--paper);
  border-left: 4px solid var(--line);
  color: var(--muted);
}

.field-help.is-warning {
  color: var(--text);
  border-left: 4px solid var(--amber);
  padding-left: 0.7rem;
  max-width: 26rem;
}

.log-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
  display: grid;
  gap: 0.5rem;
}
.log-list li {
  display: grid;
  gap: 0.15rem;
  padding: 0.5rem 0.6rem;
  background: var(--paper);
  border-radius: 6px;
  font-size: 0.9rem;
}
.log-when {
  color: var(--muted);
  font-size: 0.8rem;
}
.log-note {
  color: var(--muted);
  font-style: italic;
}

/* The same row used as a link rather than a button. An anchor does not inherit
   the button reset, so the two need to agree explicitly. */
a.player-button {
  text-decoration: none;
  box-sizing: border-box;
}
a.player-button:hover .player-label {
  text-decoration: underline;
}

/* --- Manual attendance, players, drops -------------------------------------- */

.field textarea {
  font: inherit;
  font-size: 1rem;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--text);
  max-width: 26rem;
  resize: vertical;
}

.picker {
  margin-bottom: 0.5rem;
}

.tag-division {
  background: var(--ink-soft);
  color: var(--card);
}

/* An event row carries two things at once: which event it is, and how much is
   waiting on it. They stack on a phone and sit apart once there is room. */
.event-row {
  align-items: flex-start;
  flex-wrap: wrap;
}
.event-row-main {
  display: grid;
  gap: 0.15rem;
}
.event-row-counts {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.reg-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.6rem;
}
.reg-row {
  display: grid;
  gap: 0.25rem;
  padding: 0.7rem 0.8rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.reg-row p {
  margin: 0.3rem 0 0;
}
.reg-person {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* A drop nobody asked for is the one destructive click on these screens, so it
   gets its own weight rather than looking like every other button. */
.button-danger {
  background: var(--amber);
  color: var(--ink);
  border-color: var(--amber);
}
.confirm-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
/* A display declaration beats the browser's own [hidden] rule, so without this
   every confirm step renders open and confirms nothing. */
.confirm-row[hidden] {
  display: none;
}


/* --- Points ----------------------------------------------------------------- */

.stated-award {
  margin: 0.5rem 0;
  padding: 0.6rem 0.8rem;
  background: var(--paper);
  border-left: 4px solid var(--teal);
  border-radius: 0 6px 6px 0;
}

.balance {
  margin: 0.5rem 0 0.25rem;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}
.balance-number {
  font-family: var(--font-head);
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--teal);
  line-height: 1;
}

.ledger-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
  display: grid;
  gap: 0.4rem;
}
.ledger-row {
  display: grid;
  grid-template-columns: 3.2rem 1fr auto;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  background: var(--paper);
  border-radius: 6px;
  font-size: 0.95rem;
}
/* A reversed entry stays on the record and stays legible; it is struck through
   rather than removed, because the balance is the sum of what is still here. */
.ledger-row.is-voided .ledger-delta,
.ledger-row.is-voided .ledger-what > span:first-child {
  text-decoration: line-through;
  color: var(--muted);
}
.ledger-delta {
  font-family: var(--font-head);
  font-weight: 700;
  text-align: right;
}
.ledger-delta.is-up { color: var(--teal); }
.ledger-delta.is-down { color: var(--muted); }
.ledger-what {
  display: grid;
  gap: 0.1rem;
}
.ledger-row .form-status {
  grid-column: 1 / -1;
  margin: 0;
}
.tag-voided {
  background: var(--line);
  color: var(--muted);
}
.balance-number.is-negative {
  color: var(--amber);
}

/* --- Prize wall and events -------------------------------------------------- */

.item-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.4rem;
}
.item-row.is-retired .player-label {
  color: var(--muted);
}
.item-list .disclosure {
  margin-top: 0;
  border-top: none;
  padding-top: 0;
  background: var(--paper);
  border-radius: 6px;
}
.item-list summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.6rem 0.75rem;
}
.item-list .disclosure-body {
  padding: 0.25rem 0.75rem 0.75rem;
}

/* Save and retire sit on one line, and the retire confirmation replaces the
   retire button in place rather than pushing the form around. */
.item-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

/* A label that wraps its own input, used where a page of repeated fields would
   otherwise need a unique id for every one of them. */
.field label input,
.field label select {
  display: block;
  margin-top: 0.25rem;
  font-weight: 400;
}

/* display:flex on a summary drops the default disclosure marker, leaving a row
   that opens with nothing to say so. This puts the affordance back explicitly. */
.item-list summary {
  cursor: pointer;
  list-style: none;
}
.item-list summary::-webkit-details-marker {
  display: none;
}
.item-list summary::after {
  content: "\203A";
  margin-left: auto;
  color: var(--teal);
  font-size: 1.3rem;
  line-height: 1;
  transition: transform 0.15s ease;
}
.item-list details[open] > summary::after {
  transform: rotate(90deg);
}
.item-list summary:hover {
  background: #eef3f2;
  border-radius: 6px;
}

/* A wrapped input is not a flex child of .field, so it does not stretch the way
   the id-linked ones do. Without this the two styles of field are visibly
   different widths on the same page. */
.field label input,
.field label select {
  width: 100%;
  max-width: 22rem;
  box-sizing: border-box;
}

/* --- Trainer Card ----------------------------------------------------------- */

.rank-line {
  margin: 0.5rem 0 0.25rem;
}
.rank-name {
  font-family: var(--font-head);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--teal);
}

/* A badge is a toggle, so it has to read as earned or not at a glance. An
   unearned badge keeps its colour as an outline and fills in once awarded,
   rather than being a different colour, so the wall of them stays legible. */
.badge-toggles {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.75rem 0;
}
/* No background here on purpose. The badge-cN colour classes set it, and they
   are defined earlier in this file, so declaring one would win over all of them
   and leave an earned badge with white text on nothing. */
.badge-toggle {
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  display: grid;
  gap: 0.1rem;
  padding: 0.45rem 0.7rem;
  border-radius: 999px;
  cursor: pointer;
  text-align: center;
}
.badge-toggle:not(.is-earned) {
  background: transparent;
  border: 2px dashed var(--line);
  color: var(--muted);
}
.badge-toggle:not(.is-earned):hover {
  border-style: solid;
  color: var(--text);
}
.badge-toggle.is-earned {
  border: 2px solid transparent;
  color: var(--card);
}
.badge-toggle.is-earned:hover {
  border-color: var(--ink);
}
.badge-toggle-date {
  font-size: 0.7rem;
  font-weight: 400;
  opacity: 0.85;
}

.battle-toggles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(4.2rem, 1fr));
  gap: 0.5rem;
  margin: 0.75rem 0;
}
.battle-toggle {
  font: inherit;
  display: grid;
  gap: 0.2rem;
  justify-items: center;
  padding: 0.7rem 0.5rem;
  border-radius: 8px;
  border: 2px dashed var(--line);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.battle-toggle:hover {
  border-style: solid;
  color: var(--text);
}
.battle-toggle.is-won {
  border-style: solid;
  border-color: var(--teal);
  background: var(--teal);
  color: var(--card);
}
.battle-number {
  font-family: var(--font-head);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
}
.battle-state {
  font-size: 0.75rem;
}

/* --- Reference sections ----------------------------------------------------- */

.jump-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0 0 1rem;
  font-size: 0.95rem;
}

.section-heading {
  font-size: 1.5rem;
  margin: 1.5rem 0 0.25rem;
  padding-bottom: 0.3rem;
  border-bottom: 2px solid var(--line);
}

.reference-section {
  display: grid;
  gap: 0.75rem;
}

.tier-row {
  padding: 0.6rem 0.75rem;
  margin-bottom: 0.5rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.tier-row h5 {
  margin: 0 0 0.4rem;
  font-family: var(--font-head);
  font-size: 1rem;
}

/* --- Printable sheets ------------------------------------------------------- */

.sheet {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1.25rem;
  margin-top: 1rem;
}
.sheet-head {
  border-bottom: 2px solid var(--ink);
  padding-bottom: 0.6rem;
  margin-bottom: 1rem;
}
.sheet-head h2 {
  margin: 0 0 0.2rem;
}
.sheet-head p {
  margin: 0;
  color: var(--muted);
}
.sheet-sub {
  font-size: 0.9rem;
}
.sheet-section {
  margin-top: 1.5rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--line);
}
.sheet-group {
  margin-bottom: 1.25rem;
}
.sheet-group h3 {
  margin: 0.75rem 0 0.4rem;
  font-size: 1.05rem;
}

/* Tables are the one thing allowed to be wider than the page body, each in its
   own scroller, so a narrow phone never scrolls the whole document sideways. */
.sheet-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
  display: block;
  overflow-x: auto;
}
.sheet-table th,
.sheet-table td {
  text-align: left;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.sheet-table th {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  border-bottom-width: 2px;
}
/* An empty box to tick with a pen. It has to survive printing, so it is a border
   rather than a background colour that a printer may drop. */
.sheet-table .sheet-tick {
  width: 3rem;
}
.sheet-table tbody .sheet-tick::before {
  content: "";
  display: inline-block;
  width: 0.9rem;
  height: 0.9rem;
  border: 1px solid var(--ink);
  border-radius: 2px;
}
.sheet-foot {
  margin-top: 1.5rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line);
  font-size: 0.8rem;
  color: var(--muted);
}
.print-hint {
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--muted);
}

@media print {
  /* Everything that is not the sheet goes, so the paper carries the list and
     nothing else. No PDF library: this is the whole mechanism. */
  .no-print,
  .prof-bar,
  .skip-link {
    display: none !important;
  }

  body,
  .print-page {
    background: #ffffff;
    color: #000000;
    margin: 0;
    padding: 0;
  }

  .sheet {
    border: none;
    border-radius: 0;
    padding: 0;
    margin: 0;
    background: #ffffff;
  }

  .sheet-table {
    display: table;
    overflow: visible;
    font-size: 10pt;
  }
  .sheet-table th,
  .sheet-table td {
    border-bottom: 1px solid #999999;
    white-space: normal;
  }

  /* A division or tier should not be split across a page break if it fits, and a
     header must never be the last thing on a page. */
  .sheet-group {
    break-inside: avoid;
  }
  .sheet-head,
  .sheet-section,
  .sheet-group h3 {
    break-after: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr {
    break-inside: avoid;
  }

  a {
    color: #000000;
    text-decoration: none;
  }
}

.caps-block {
  margin: 0.75rem 0;
  padding: 0.75rem 0.9rem;
  background: var(--paper);
  border-radius: 6px;
}
.caps-block h4 {
  margin: 0 0 0.4rem;
}
/* Same trap as .confirm-row: a display declaration would beat the browser's own
   [hidden] rule and leave the block on screen. */
.caps-block[hidden] {
  display: none;
}

/* Flight PIN, on the professor event list only. It groups flights for the desk
   and means nothing to a player, so it never appears on the public schedule. */
.tag-flight {
  background: var(--paper);
  color: var(--muted);
  border: 1px solid var(--line);
}

/* The way in for a professor, in the footer of every public page. Quiet on
   purpose: a player has no use for it. Not hidden, though -- the admin pages are
   static files anyone can fetch, and row level security is what actually refuses
   them. */
.prof-signin {
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  font-size: 0.85rem;
}
.prof-signin a {
  color: rgba(255, 255, 255, 0.6);
}
.prof-signin a:hover,
.prof-signin a:focus {
  color: var(--card);
}

/* Demo only: lets the fixed bar be shown inline for a look. */
.bar-sample .prof-bar {
  position: static;
}

/* A player the public cannot see, shown to a professor browsing the player page. */
.tag-hidden {
  background: var(--line);
  color: var(--muted);
  font-size: 0.7rem;
}
.not-public {
  margin: 0.4rem 0;
  padding: 0.45rem 0.7rem;
  background: var(--paper);
  border-left: 4px solid var(--amber);
  border-radius: 0 6px 6px 0;
  font-size: 0.9rem;
}

/* The three screens a professor usually wants next, carrying the player with
   them. Only rendered when signed in. */
.admin-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  margin: 0.5rem 0 0.75rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.9rem;
  font-weight: 600;
}

/* The rank discount, next to the balance where a professor is already looking. */
.discount-note {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.7rem;
  background: #fdf3e2;
  border-left: 4px solid var(--amber);
  border-radius: 0 6px 6px 0;
  font-size: 0.9rem;
}

/* The rank discount, next to the balance where a professor is already looking. */
.discount-note {
  margin: 0.5rem 0 0;
  padding: 0.5rem 0.7rem;
  background: #fdf3e2;
  border-left: 4px solid var(--amber);
  border-radius: 0 6px 6px 0;
  font-size: 0.9rem;
}


/* --- Gold and graphite: the rest of it -------------------------------------- */

/* Cards were all the same grey border, so nothing looked more important than
   anything else. Shadow instead, and the card that matters gets a gold edge. */
.card {
  border: none;
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(20, 18, 10, 0.06),
              0 4px 14px rgba(20, 18, 10, 0.05);
}
.card-feature {
  border-top: 3px solid transparent;
  border-image: var(--gold-metal) 1;
  border-radius: 0 0 10px 10px;
}

/* A small gold line above a heading: every section gets the same way in. */
.eyebrow {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 0.2rem;
}

.rule {
  border: 0;
  height: 2px;
  background: var(--gold-metal);
  width: 3rem;
  margin: 0 0 1rem;
}

/* The site is about points, Sundays and badges, and they were set at body size
   beside their labels. */
.figure-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
  margin: 1rem 0;
  padding: 0.9rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.figure-row > div { text-align: center; }
.figure {
  display: block;
  font-family: var(--font-head);
  font-size: 2.4rem;
  line-height: 1;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: -0.02em;
}
.figure-label {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.3rem;
}

/* Gold that behaves like a metal. A flat fill reads cheap. */
.button {
  background: var(--gold-metal);
  border: none;
  color: #221c08;
  font-weight: 700;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset,
              0 1px 3px rgba(20, 18, 10, 0.25);
}
.button:hover { filter: brightness(1.06); }
.button-quiet {
  background: transparent;
  color: var(--gold);
  border: 2px solid var(--gold-line);
  box-shadow: none;
}
/* Red, where it means something. This used to be amber, so the destructive
   button looked like every other accent on the page. */
.button-danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #ffffff;
  box-shadow: none;
}

/* Tints that were left teal when the palette moved. */
.live-state.is-on {
  background: #f6efdc;
  border-left-color: var(--gold-line);
}
.form-status.is-good { border-left-color: var(--gold-line); }
.form-status.is-error { border-left-color: var(--danger); }
.item-list summary:hover { background: #f4efe2; }
.discount-note { background: #fdf6e6; }

/* --- The badge set ---------------------------------------------------------- */
/* A row of chips that stopped at whatever had been earned became a grid of all
   thirteen. Showing the empty slots is what makes a set read as a set, and it
   tells a player what is left to earn. */

.badge-grid {
  list-style: none;
  padding: 0;
  margin: 0.75rem 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.6rem, 1fr));
  gap: 0.6rem;
}
.badge-slot {
  display: grid;
  gap: 0.3rem;
  justify-items: center;
  text-align: center;
}
.badge-tile {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 12px;
  display: grid;
  place-items: center;
  padding: 0.35rem;
}
/* Filled from the artwork itself, with the darkened version as the ring so a
   pale badge still has an edge against a white card. */
.badge-slot.is-earned .badge-tile {
  /* --tile and --tile-edge are set per badge from the row. The fallback is for
     a badge whose colours have not been worked out yet. */
  background: var(--tile, var(--gold-line));
  box-shadow: inset 0 0 0 2px var(--tile-edge, var(--gold)),
              0 1px 3px rgba(20, 18, 10, 0.18);
}
.badge-slot.is-empty .badge-tile {
  border: 2px dashed var(--line);
  background: repeating-linear-gradient(45deg,
    rgba(0, 0, 0, 0.012) 0 6px, transparent 6px 12px);
}
/* The venue mark, filling the tile top to bottom behind the badge. It is a
   background, not an <img>: it is decoration, and a screen reader has no use
   for it. */
.badge-tile.has-backdrop {
  position: relative;
  overflow: hidden;
}
.badge-tile.has-backdrop::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("images/cc-logo.png");
  background-repeat: no-repeat;
  background-position: center;
  /* Contain, so the building keeps its shape: it is much taller than it is
     wide, so filling the height is as far as it goes. */
  background-size: auto 100%;
  opacity: 0.5;
}

.badge-art {
  position: relative;      /* above the backdrop */
  width: 90%;
  height: 90%;
  object-fit: contain;
  display: block;
  /* A little lift, so the art separates from the mark behind it. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
}
.badge-name {
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--text);
}
.badge-slot.is-empty .badge-name { color: var(--muted); font-weight: 400; }


/* --- Schedule --------------------------------------------------------------- */
/* The time is what a reader scans for, so it is the largest thing on the card. */
.day-heading {
  padding-bottom: 0.4rem;
  border-bottom: 2px solid transparent;
  border-image: var(--gold-metal) 1;
}
.event-time {
  font-family: var(--font-head);
  font-size: 1.55rem;
  font-weight: 700;
  color: var(--gold);
  letter-spacing: -0.02em;
}
.event-fee .count { font-weight: 700; color: var(--gold); }

/* The Trainer Card screen shows the same tiles, as buttons. A professor
   awarding a badge should be looking at what the player will see. */
.badge-grid-toggle { grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr)); }
.badge-button {
  font: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  display: grid;
  gap: 0.2rem;
  justify-items: center;
  width: 100%;
}
.badge-button:hover .badge-tile { filter: brightness(1.05); }
.badge-button:focus-visible { outline: 3px solid var(--gold-line); outline-offset: 2px; }
.badge-button .badge-toggle-date { font-size: 0.68rem; color: var(--muted); }

/* --- The Play! Pokemon mark ------------------------------------------------- */
/* Bottom right of every page. Under the footer text on a phone, beside it once
   there is room. */
.footer-mark {
  margin: 1rem 0 0;
  text-align: right;
}
/* The mark is black and red on transparent and would vanish into the dark
   footer. It sits on a light chip instead of being recoloured: inverting it
   turned the red cyan, and a brand mark in the wrong colours is worse than one
   that needed a background. */
.footer-mark img {
  width: 150px;
  height: auto;
  display: inline-block;
  background: #ffffff;
  padding: 0.5rem 0.7rem;
  border-radius: 8px;
}

@media (min-width: 42rem) {
  .site-footer {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
  }
  .site-footer > p:not(.footer-mark) { flex: 1 1 22rem; margin-right: 0; }
  .footer-mark { margin-top: 0; flex: none; }
}

/* --- Premier events --------------------------------------------------------- */
/* A League Cup or Challenge is a sanctioned event and reads differently from a
   casual Sunday, so it is marked rather than only labelled. */
.event-premier {
  position: relative;
  padding-right: 3.4rem;
}
.event-premier-mark {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  width: 2.1rem;
  height: auto;
  display: block;
}

/* --- Badge art, on the reference screen ------------------------------------- */
/* The colour comes from the picture, so the only way to know whether it looks
   right is to see it before saving. */
.art-preview-wrap {
  margin: 0.75rem 0;
  padding: 0.75rem;
  background: var(--paper);
  border-radius: 8px;
  width: max-content;
  min-width: 8rem;
}
.art-preview {
  width: 6rem;
  display: grid;
  gap: 0.3rem;
  justify-items: center;
  text-align: center;
  margin-top: 0.4rem;
}

/* A season heading on the Trainer Card, while a changeover has two running. */
.season-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 1rem 0 0.3rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--line);
  font-family: var(--font-head);
  font-size: 1rem;
}

/* Marked where it is awarded, because a professor cannot otherwise tell a
   secret badge from one every player can already see listed. */
.tag-secret {
  background: var(--ink-soft);
  color: var(--card);
}

/* A season's heading carries its own state beside the year. */
.reference-section .card > h3 {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.reference-section .card > h3 .count {
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--muted);
}

/* Retiring a season, under its badge list. Set apart from the badges above it,
   because it acts on all of them at once. */
.season-control {
  margin-top: 0.9rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}

/* A retired season is still readable -- it is history, not an error. */
.card.is-retired {
  background: var(--paper);
}
.card.is-retired h3 .count,
.card.is-retired .item-list {
  opacity: 0.85;
}

/* --- An event on a page of its own ------------------------------------------ */

/* The way from a schedule card to that event's own page. Quiet: it is a link a
   professor grabs to post, not a step a player has to take. */
.event-permalink {
  margin: 0.9rem 0 0;
  font-size: 0.9rem;
}

/* The link to post, on the admin event row. The field is readable and
   selectable as well as copyable, because clipboard access can be refused and a
   professor still has to be able to get the link off the screen. */
.share-block {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line);
}
.share-block h4 {
  margin: 0 0 0.3rem;
  font-family: var(--font-head);
  font-size: 1rem;
}
.share-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.5rem 0;
}
.share-url {
  font: inherit;
  font-size: 0.85rem;
  flex: 1 1 16rem;
  min-width: 0;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  color: var(--text);
}

/* On an event's own page the name is the page heading, so it carries an h1's
   weight. On the schedule the same class is an h3 inside a card. */
h1.event-name {
  margin: 0 0 0.25rem;
  font-size: 1.8rem;
}
h1.event-name + .event-when {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
}

/* Closing registration early, under the capacity panel. Set apart because it
   acts on the event as a whole and is not the Take registration checkbox. */
.closing-panel {
  margin-top: 1rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line);
}
.closing-panel h4 {
  margin: 0 0 0.3rem;
  font-family: var(--font-head);
  font-size: 1rem;
}

/* A label for a screen reader where a sighted reader needs none: a column of
   pictures does not want the word "Picture" written above it, but the column
   still has to be named. */
.hidden-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The badge picture at the end of its row on the programs page. Shrunk to its
   contents so the name and the task keep the width they need. */
.data-table .badge-cell {
  width: 1%;
  padding-left: 0.75rem;
  text-align: right;
  vertical-align: middle;
}
.badge-slot.is-bare {
  width: 3.2rem;
  display: inline-grid;
}
