/* Ticket Window. See docs/DESIGN.md. */

@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/oswald-700.cedd65736210.woff2") format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/inter-400.cef6d3a6737e.woff2") format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/inter-600.ca03b7ee20d3.woff2") format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/inter-700.64d12f9f7d82.woff2") format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/jetbrains-mono-400.3fb54ef45e30.woff2") format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/jetbrains-mono-600.dba84cb55691.woff2") format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/jetbrains-mono-700.b9c90042b2e0.woff2") format('woff2');
}

:root {
  --ground: #E7EBEA;
  --surface: #FFFFFF;
  --surface-2: #DCE2DF;
  /* Ticket paper. In dark mode it sits between the ground and --line so printed rules stay visible. */
  --paper: #FFFFFF;
  --paper-lift: 0 3px 7px rgba(0, 0, 0, .16);
  --paper-lift-hover: 0 6px 13px rgba(0, 0, 0, .22);
  --ink: #1A2422;
  --ink-mute: #57635F;
  --accent: #1D3557;
  --accent-2: #E8A33D;
  --accent-2-text: #8E5A0B;
  --accent-text: #ffffff;
  --win: #00966B;
  --loss: #D2551A;
  --line: #CBD3CE;
  --marker: #C23B2E;
  /* A week you topped the league: the trophies' gold, which reads on either ground. */
  --week-top: #D4A62A;
  --marker-dried: #8B7355;
  --medal-gold: #9A7209;
  --medal-silver: #6B7681;
  --medal-bronze: #8A5A33;
  --shelf: #1D3557;
  --shelf-ink: #FFFFFF;
  --shelf-mute: #C9D2DE;
  --shelf-medal: #F3F5F4;

  --f-display: 'Oswald', ui-rounded, -apple-system, "Segoe UI", system-ui, sans-serif;
  --f-body: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --f-mono: 'JetBrains Mono', ui-monospace, "SF Mono", Menlo, monospace;

  /* Native controls follow the active theme. */
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ground: #14181A;
    --surface: #1D2224;
    --surface-2: #262C2E;
  --paper: #232A2C;
    --ink: #ECEFEC;
    --ink-mute: #92A19B;
    --accent: #6E93C9;
    --accent-2: #E0A857;
    --accent-2-text: #E0A857;
    --accent-text: #000000;
    --win: #2FBF8F;
    --loss: #E37142;
    --line: #303838;
    --marker: #E2574A;
    --marker-dried: #9C8564;
    --medal-gold: #E3B341;
    --medal-silver: #B9C2C9;
    --medal-bronze: #C68A5B;
    --shelf: #1D3557;
    --shelf-ink: #FFFFFF;
    --shelf-mute: #C9D2DE;
    --shelf-medal: #F3F5F4;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --ground: #14181A;
  --surface: #1D2224;
  --surface-2: #262C2E;
  --paper: #232A2C;
  --ink: #ECEFEC;
  --ink-mute: #92A19B;
  --accent: #6E93C9;
  --accent-2: #E0A857;
  --accent-2-text: #E0A857;
  --accent-text: #000000;
  --win: #2FBF8F;
  --loss: #E37142;
  --line: #303838;
  --marker: #E2574A;
  --marker-dried: #9C8564;
  --medal-gold: #E3B341;
  --medal-silver: #B9C2C9;
  --medal-bronze: #C68A5B;
  --shelf: #1D3557;
  --shelf-ink: #FFFFFF;
  --shelf-mute: #C9D2DE;
  --shelf-medal: #F3F5F4;
  color-scheme: dark;
}
:root[data-theme="light"] {
  --ground: #E7EBEA;
  --surface: #FFFFFF;
  --surface-2: #DCE2DF;
  --paper: #FFFFFF;
  --paper-lift: 0 3px 7px rgba(0, 0, 0, .16);
  --paper-lift-hover: 0 6px 13px rgba(0, 0, 0, .22);
  --ink: #1A2422;
  --ink-mute: #57635F;
  --accent: #1D3557;
  --accent-2: #E8A33D;
  --accent-2-text: #8E5A0B;
  --accent-text: #ffffff;
  --win: #00966B;
  --loss: #D2551A;
  --line: #CBD3CE;
  --marker: #C23B2E;
  --marker-dried: #8B7355;
  --medal-gold: #9A7209;
  --medal-silver: #6B7681;
  --medal-bronze: #8A5A33;
  --shelf: #1D3557;
  --shelf-ink: #FFFFFF;
  --shelf-mute: #C9D2DE;
  --shelf-medal: #F3F5F4;
  color-scheme: light;
}

* { box-sizing: border-box; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--f-body);
  -webkit-font-smoothing: antialiased;
}

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

/* Names link everywhere but keep their row's color; the link shows on hover and focus. */
a.username { color: inherit; text-decoration: none; }
@media (hover: hover) {
  a.username:hover { text-decoration: underline; text-underline-offset: 2px; }
}
a.username:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; border-radius: 3px; }

.page {
  max-width: 480px;
  margin: 0 auto;
  padding: 0 16px 48px;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 16px 14px;
  max-width: 480px;
  margin: 0 auto;
}
.site-header .brand {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 19px;
  text-decoration: none;
  color: var(--ink);
}
.site-header .account {
  display: flex;
  align-items: center;
  min-width: 0;
  font-size: 13px;
  color: var(--ink-mute);
}
.site-header .account a { margin-left: 10px; }
.site-header .logout-form { display: inline; margin-left: 10px; }
.site-header .account > a,
.site-header .account > form,
.site-header .account > button {
  flex-shrink: 0;
}
.icon-link {
  display: inline-flex;
  align-items: center;
  position: relative;
  vertical-align: middle;
  color: var(--ink-mute);
}
.icon-link:hover { color: var(--accent); }
.notification-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  display: inline-block;
  min-width: 15px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent-2);
  color: #000000;
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  line-height: 15px;
}
.site-header .logout-button {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; cursor: pointer;
}

.league-indicator {
  flex: 1 1 auto;
  min-width: 0;
  margin-right: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-mute);
}
.league-switcher {
  display: inline-block;
  flex: 1 1 auto;
  min-width: 0;
  margin-right: 10px;
  position: relative;
}
.league-switcher summary {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
  color: var(--ink-mute);
}
.league-switcher summary::-webkit-details-marker { display: none; }
.league-switcher summary::after {
  content: "▾";
  display: inline-block;
  margin-left: 4px;
  font-size: 10px;
  transition: transform .15s ease;
}
.league-switcher[open] summary::after { transform: rotate(180deg); }
.league-switcher ul {
  list-style: none;
  margin: 4px 0 0;
  padding: 6px;
  position: absolute;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(27, 35, 30, .1);
  min-width: 140px;
  z-index: 10;
}
.league-switcher li form { margin: 0; }
.league-switcher li button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 6px 8px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
  border-radius: 6px;
}
.league-switcher li button:hover {
  background: var(--surface-2);
}

.messages { list-style: none; margin: 0 0 16px; padding: 0; }
.messages li {
  background: var(--surface);
  border: 1.5px solid var(--win);
  color: var(--win);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 13.5px;
  font-weight: 600;
  margin-bottom: 8px;
}
.messages li.error { border-color: var(--loss); color: var(--loss); }

@media (prefers-reduced-motion: no-preference) {
  .messages li { animation: message-in .35s ease-out; }
  @keyframes message-in {
    from { opacity: 0; transform: translateY(-6px); }
    to { opacity: 1; transform: translateY(0); }
  }
}

.form-errors {
  background: var(--surface);
  border: 1.5px solid var(--loss);
  color: var(--loss);
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 13.5px;
  margin-bottom: 16px;
}
.form-errors p { margin: 0 0 4px; }
.form-errors p:last-child { margin-bottom: 0; }

.screen-head { padding: 4px 0 16px; }
.week-label,
.screen-eyebrow {
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 4px;
}
.screen-head h1 { font-family: var(--f-display); font-size: 26px; font-weight: 700; margin: 0 0 14px; }
/* Under a profile's name: that it's private. */
.profile-note { margin: -6px 0 0; font-size: 14px; color: var(--ink-mute); }
/* Report, quiet at the foot of someone else's profile. */
.profile-report { margin: 28px 0 0; font-size: 13px; }
.profile-report a { color: var(--ink-mute); }
.leagues-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.leagues-head h1 { margin-bottom: 0; }
.leagues-head-action {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  text-decoration: none; white-space: nowrap; margin-bottom: 14px;
}
/* Season pass on the leagues page: ticket paper and frame, but no torn edge or stub. */
.pass-rack { list-style: none; margin: 0 0 20px; padding: 0; }
.pass-rack li {
  margin-bottom: 14px;
  /* Shadow on the wrapper, since a mask on the same element would cut it. */
  filter: drop-shadow(var(--paper-lift));
}

/* Shape and paper come from the shared ticket chrome below. */
.season-pass {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 15px 18px 15px;
  color: var(--ink);
  text-decoration: none;
  /* Mono like the ticket body. */
  font-family: var(--f-mono);
}
.season-pass:focus-visible {
  /* Negative offset keeps the ring inside the mask. */
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}

.pass-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pass-kind {
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.pass-flag { width: 9px; height: 9px; border-radius: 50%; background: var(--marker); flex: none; }
/* Matches .ticket-matchup. */
.pass-name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1.55;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Leaders, plus your own line when you're not among them, in three aligned columns. */
/* Standings once there are any, otherwise who's in and when it opens, so the pass keeps its shape. */
.pass-band {
  padding: 9px 0;
  border-top: 1px dashed var(--line);
  border-bottom: 1px dashed var(--line);
  font-size: 12px;
  color: var(--ink-mute);
}
.pass-standings {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 3px 10px;
  align-items: baseline;
}
.pass-preseason { display: flex; justify-content: space-between; gap: 12px; }
.pass-standing { display: contents; }
.pass-standing b { font-weight: 700; color: var(--ink-mute); }
.pass-standing-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pass-standing-line { font-variant-numeric: tabular-nums; }
.pass-standing.is-you .pass-standing-who,
.pass-standing.is-you .pass-standing-line,
.pass-standing.is-you b { color: var(--ink); font-weight: 700; }

/* League setup as bordered mono tags. Confidence shows only when it's on. */
.pass-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.pass-tag {
  font-size: 9.5px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 2px 5px;
  line-height: 1.4;
}

/* One mark per week, filled once every game that week is picked. */
/* Wide enough apart that two ringed weeks side by side, or one above the other, clear. */
.pass-punches { display: flex; flex-wrap: wrap; gap: 8px; }
/* Solid ring; at 9px dashes just look like grit. */
.pass-punch {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--ink-mute);
  opacity: .5;
}
/* Every game picked, in the ticket's ink: red and green are kept for results. */
.pass-punch.is-punched {
  background: var(--ink);
  border-color: var(--ink);
  opacity: 1;
}
/* A finished week, as the week rail marks it: the fill is how your picks went, and a ring
   says you topped the league that week (gold) or finished last (ink). */
.pass-punch.result-winning { background: var(--win); border-color: var(--win); opacity: 1; }
.pass-punch.result-losing { background: var(--loss); border-color: var(--loss); opacity: 1; }
.pass-punch.result-even { background: var(--ink-mute); border-color: var(--ink-mute); opacity: 1; }
.pass-punch.finish-top { box-shadow: 0 0 0 1.5px var(--paper), 0 0 0 3px var(--week-top); }
.pass-punch.finish-bottom { box-shadow: 0 0 0 1.5px var(--paper), 0 0 0 3px var(--ink); }
/* Fill for punched, a box-shadow ring for the current week, so both can show. */
.pass-punch.is-current {
  opacity: 1;
  box-shadow: 0 0 0 1.5px var(--paper), 0 0 0 3px var(--accent);
}
.pass-punch.is-live {
  background: var(--accent-2);
  border-color: var(--accent-2);
  opacity: 1;
}

.pass-status { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-mute); }
/* --marker, since marigold on white is too faint for the one thing to act on. */
.pass-status b { color: var(--marker); font-weight: 700; }
.season-pass.needs-you::before { border-color: var(--marker); opacity: .55; }

/* An empty rack slot: same shape, blank, dashed outline. */
/* An invite holds its Accept and Decline, so it isn't one link like a league's pass. */
.season-pass.is-invite .submit-row-multi { padding-top: 6px; }
.season-pass.is-invite .button { padding: 10px 16px; }
.season-pass.is-unissued { background: transparent; color: var(--ink-mute); }
.season-pass.is-unissued::before { border-style: dashed; opacity: .4; }
.season-pass.is-unissued::after { display: none; }
.season-pass.is-unissued .pass-name { color: var(--ink-mute); }
.season-pass.is-unissued .pass-status { font-family: var(--f-body); font-size: 13px; }

@media (hover: hover) {
  .pass-rack li:hover { filter: drop-shadow(var(--paper-lift-hover)); }
  .season-pass:hover .pass-name { color: var(--accent); }
}
@media (prefers-reduced-motion: no-preference) {
  .pass-rack li { transition: filter .18s ease; }
  .season-pass .pass-name { transition: color .18s ease; }
}

.league-head { display: flex; align-items: center; gap: 10px; }
.settings-gear {
  text-decoration: none;
  font-size: 20px;
  line-height: 1;
  color: var(--ink-mute);
  margin-bottom: 14px;
}
.settings-gear:hover { color: var(--accent); }

.section-label {
  font-family: var(--f-mono); font-size: 15px; font-weight: 700; letter-spacing: .04em;
  color: var(--ink); margin: 32px 0 12px;
}
.section-label:first-child { margin-top: 8px; }

/* A matrix's section label shares a line with its orientation toggle. */
.matrix-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 32px 0 10px; }
.matrix-head .section-label { margin: 0; }
.matrix-orient { display: inline-flex; border: 1.5px solid var(--line); border-radius: 999px; padding: 2px; flex-shrink: 0; }
.stats-mode-toggle { margin-top: 4px; }
/* One attribute switches every figure, so a switch is one relayout.
   !important because these elements set their own display. */
.program-page[data-edition="su"] [data-stat-value="ats"],
.program-page[data-edition="ats"] [data-stat-value="su"],
.program-page[data-span="all"] [data-span-value="season"],
.program-page[data-span="season"] [data-span-value="all"] { display: none !important; }
.matrix-orient-btn {
  font-family: var(--f-body); font-size: 11px; font-weight: 700; color: var(--ink-mute);
  background: none; border: 0; border-radius: 999px; padding: 4px 10px; cursor: pointer;
}
.matrix-orient-btn.is-active { background: var(--accent); color: var(--accent-text); }
.matrix-dash { color: var(--ink-mute); }

.section-subhead {
  display: flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: 12.5px; color: var(--ink-mute);
  margin: 18px 0 8px;
}
.section-subhead:first-child { margin-top: 0; }
.trophy-tag {
  font-family: var(--f-mono); font-size: 9px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); border: 1.5px solid var(--accent);
  border-radius: 999px; padding: 2px 7px;
}
.trophy-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.trophy-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 13px; }
.trophy-rank { font-family: var(--f-mono); color: var(--ink-mute); width: 1.4em; flex-shrink: 0; }
.trophy-who { flex: 1; font-weight: 700; }
.trophy-count { font-family: var(--f-mono); color: var(--ink-mute); font-variant-numeric: tabular-nums; }
.trophy-cat { color: var(--ink-mute); }
.notification-unread { border-left: 3px solid var(--accent-2); padding-left: 8px; }
.trophy-note { font-size: 11px; color: var(--ink-mute); }
.trophy-link { font-size: 13px; font-weight: 600; text-decoration: none; }
.trophy-link::after { content: " \2192"; }

.mode-banner {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 4px; border-bottom: 2px dashed var(--line);
}
.mode-chip {
  font-family: var(--f-body); font-weight: 700; font-size: 11.5px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--ink-mute);
}
.mode-chip.is-on { background: var(--accent); color: var(--accent-text); }
a.mode-progress { text-decoration: none; font-weight: 700; }
.mode-progress {
  font-family: var(--f-mono); font-size: 11px; color: var(--ink-mute);
  margin-left: auto; font-variant-numeric: tabular-nums;
}
/* Same red as the week rail's picks-due ring. */
.mode-progress.is-due { color: var(--marker); font-weight: 700; }
/* Lines that moved your way, in the stub's Better Line color. */
.mode-progress.is-better { color: var(--accent-2-text); font-weight: 700; }


.confidence-chip {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line);
}
.confidence-chip > span:first-child { font-size: 11.5px; font-weight: 600; color: var(--ink-mute); }

.confidence-stepper { display: flex; align-items: center; gap: 10px; }
.stepper-btn {
  width: 26px; height: 26px; flex: 0 0 auto;
  font-family: var(--f-display); font-size: 14px; line-height: 1;
  border: 2px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink); cursor: pointer;
}
.stepper-btn:hover { border-color: var(--accent); color: var(--accent); }
.stepper-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* A rank needs a pick; the stepper dims as one control until it has one. */
.confidence-stepper:has(.confidence-input:disabled) { opacity: .5; }
.confidence-stepper:has(.confidence-input:disabled) .stepper-btn { cursor: not-allowed; }
.confidence-stepper:has(.confidence-input:disabled) .stepper-btn:hover { border-color: var(--line); color: var(--ink); }
.is-kicked-off .detail-hero-stub,
.is-kicked-off .pick-clear,
.is-kicked-off .sheet-matchup { opacity: .5; }

.confidence-input {
  width: 34px; text-align: center;
  font-family: var(--f-display); font-weight: 700; font-size: 16px;
  border: 2px solid var(--line); border-radius: 8px; padding: 4px 2px;
  background: var(--surface); color: var(--ink);
  /* The stepper buttons drive the value, so hide the native spin controls. */
  -moz-appearance: textfield;
  appearance: textfield;
}
.confidence-input::-webkit-outer-spin-button,
.confidence-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Confidence tray, shared by the ticket and the pick sheet. */
.confidence-help,
.sheet-help { font-size: 13.5px; color: var(--ink-mute); margin: 0 0 12px; }

/* Sticky, so it has to be a sibling of the games. z-index sits under the toast and stamp. */
.confidence-tray {
  position: sticky; top: 0; z-index: 30;
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 10px 0; margin-bottom: 12px;
  background: var(--ground);
  border-bottom: 2px dashed var(--line);
}
.tray-chip {
  min-width: 30px; height: 30px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  font-variant-numeric: tabular-nums;
  border: 2px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink);
}
/* Used numbers are dimmed, never struck; a strike only ever means lost. */
.tray-chip.is-used {
  background: var(--surface-2); color: var(--ink-mute);
  border-color: transparent;
}
.tray-chip.is-locked { opacity: .55; }
.tray-chip.is-dup {
  background: var(--surface); color: var(--loss);
  border-color: var(--loss); text-decoration: none;
}

.confidence-row {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.confidence-row.has-error { border-bottom-color: var(--loss); }
.confidence-row-kickoff {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .08em;
  color: var(--ink-mute); margin-bottom: 4px;
}
.confidence-row-matchup { display: flex; align-items: center; gap: 6px; font-size: 13.5px; }
.confidence-row-matchup .at { color: var(--ink-mute); }
.confidence-your-pick {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: 8px; font-size: 11.5px; font-weight: 600; color: var(--ink-mute);
}

/* The unpicked side is dimmed, not hidden, so the matchup stays readable. */
.confidence-teams { display: inline-flex; align-items: center; gap: 6px; }
.confidence-team { cursor: pointer; display: inline-flex; opacity: .42; transition: opacity .12s ease; }
.confidence-team.is-picked { opacity: 1; }
/* :has keeps it live without a reload; is-picked is the fallback. */
.confidence-team:has(input:checked) { opacity: 1; }
.confidence-team:not(:has(input:checked)) { opacity: .42; }
/* Hidden but focusable, so keyboards and screen readers get a real radio group. */
.confidence-team input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.confidence-team:has(input:focus-visible) .team-badge {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (hover: hover) {
  .confidence-team:hover { opacity: .75; }
  .confidence-team.is-picked:hover { opacity: 1; }
}
.confidence-locked,
.sheet-locked { font-size: 12px; font-weight: 600; color: var(--ink-mute); }
.confidence-pick-first { font-size: 12.5px; font-weight: 600; }
.confidence-row-errors {
  flex-basis: 100%; font-size: 12.5px; color: var(--loss); font-weight: 600;
}
.confidence-row-errors p { margin: 0; }

/* Two ends: up one level on the left, across on the right. */
.page-nav { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.page-nav-side {
  margin: 4px 0 14px; font-weight: 600; font-size: 13px;
  color: var(--ink-mute); text-decoration: none;
}
.page-nav-side:hover, .page-nav .back:hover { color: var(--accent); }

.back { display: inline-block; margin: 4px 0 14px; font-weight: 600; font-size: 13px; color: var(--ink-mute); text-decoration: none; }

/* Game ticket. Sharp corners and a jittered outline so it reads as a printed card. */
/* A dashed rule separates each game's card from the next. */
/* Shared ticket chrome for the game ticket and the season pass: chamfered corners, scalloped
   edges and a printed frame. Always px, so a cut is the same size everywhere. */
.ticket-card-wrap { margin-bottom: 28px; padding-bottom: 22px; border-bottom: 2px dashed var(--line); }

/* Shadow on the wrapper, since masking on the ticket would cut it. One shadow for both themes. */
.ticket-card-wrap,
.detail-hero-wrap { filter: drop-shadow(var(--paper-lift)); }

/* Type scales with .detail-hero-main's width, so the longest team name fits at every size
   without a breakpoint. */
.detail-hero { position: relative; display: flex; margin-bottom: 14px; }

.detail-hero.is-intact,
.season-pass {
  --chamfer: 9px;
  --scallop-r: 4px;
  --scallop-pitch: 14px;
  position: relative;
  background: var(--paper);
  /* Corners cut at an angle, as on a printed admission ticket. */
  clip-path: polygon(
    var(--chamfer) 0, calc(100% - var(--chamfer)) 0,
    100% var(--chamfer), 100% calc(100% - var(--chamfer)),
    calc(100% - var(--chamfer)) 100%, var(--chamfer) 100%,
    0 calc(100% - var(--chamfer)), 0 var(--chamfer)
  );
  /* Scallops on both vertical edges, intersected. Without mask-composite you just lose them. */
  -webkit-mask-image:
    radial-gradient(circle var(--scallop-r) at left center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r)),
    radial-gradient(circle var(--scallop-r) at right center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
  mask-image:
    radial-gradient(circle var(--scallop-r) at left center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r)),
    radial-gradient(circle var(--scallop-r) at right center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
  -webkit-mask-size: 100% var(--scallop-pitch);
  mask-size: 100% var(--scallop-pitch);
  -webkit-mask-repeat: repeat-y;
  mask-repeat: repeat-y;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* The printed frame: a solid rule and a dashed one inside it, inset past the cuts. */
.detail-hero.is-intact::before,
.season-pass::before {
  content: '';
  position: absolute;
  inset: 5px;
  border: 2px solid var(--ink);
  opacity: .3;
  pointer-events: none;
}
.detail-hero.is-intact::after,
.season-pass::after {
  content: '';
  position: absolute;
  inset: 9px;
  border: 1px dashed var(--ink);
  opacity: .2;
  pointer-events: none;
}

.is-intact .detail-hero-stub { border-left: 2px dashed var(--line); }

/* A locked game's stub tears off: two pieces with a gap, each keeping its outer chamfers
   and scallops while the torn edge stays raw. */
.detail-hero.is-torn { gap: 5px; }
.is-torn .detail-hero-main,
.is-torn .detail-hero-stub {
  --chamfer: 9px;
  --scallop-r: 4px;
  --scallop-pitch: 14px;
  position: relative;
  background: var(--paper);
  -webkit-mask-size: 100% var(--scallop-pitch);
  mask-size: 100% var(--scallop-pitch);
  -webkit-mask-repeat: repeat-y;
  mask-repeat: repeat-y;
}
.is-torn .detail-hero-main {
  transform: rotate(-0.5deg);
  /* Chamfers on the left; the right is the ragged edge it tore along. */
  clip-path: polygon(
    var(--chamfer) 0, 100% 0,
    calc(100% - 3px) 12%, 100% 24%, calc(100% - 3px) 37%, 100% 50%,
    calc(100% - 3px) 63%, 100% 76%, calc(100% - 3px) 88%, 100% 100%,
    var(--chamfer) 100%, 0 calc(100% - var(--chamfer)), 0 var(--chamfer)
  );
  -webkit-mask-image: radial-gradient(circle var(--scallop-r) at left center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
  mask-image: radial-gradient(circle var(--scallop-r) at left center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
}
.is-torn .detail-hero-stub {
  transform: rotate(0.8deg);
  clip-path: polygon(
    0 0, calc(100% - var(--chamfer)) 0, 100% var(--chamfer),
    100% calc(100% - var(--chamfer)), calc(100% - var(--chamfer)) 100%, 0 100%,
    3px 88%, 0 76%, 3px 63%, 0 50%, 3px 37%, 0 24%, 3px 12%
  );
  -webkit-mask-image: radial-gradient(circle var(--scallop-r) at right center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
  mask-image: radial-gradient(circle var(--scallop-r) at right center, transparent calc(var(--scallop-r) - .5px), #000 var(--scallop-r));
}
/* Frame only on real ticket edges, not the torn one. */
.is-torn .detail-hero-main::before {
  content: ''; position: absolute; inset: 5px 0 5px 5px;
  border: 2px solid var(--ink); border-right: 0;
  opacity: .3; pointer-events: none;
}
.is-torn .detail-hero-stub::before {
  content: ''; position: absolute; inset: 5px 5px 5px 0;
  border: 2px solid var(--ink); border-left: 0;
  opacity: .3; pointer-events: none;
}
/* A column, so the odds row can sit at the bottom. */
.detail-hero-main {
  /* 19px bottom so the content clears the inset frame by the same 12px as the rule above. */
  flex: 1; min-width: 0; padding: 14px 14px 19px; font-family: var(--f-mono);
  display: flex; flex-direction: column;
  container-type: inline-size;
}
.ticket-eyebrow { font-size: 10.5px; letter-spacing: .18em; color: var(--ink-mute); display: flex; justify-content: space-between; }
/* On the week page the eyebrow links to the game page. */
a.ticket-eyebrow {
  text-decoration: none; gap: 10px;
  /* Tinted strip so it reads as tappable, not as a heading. */
  margin: -2px -4px 2px; padding: 5px 8px 6px;
  border-radius: 6px;
  /* Tighter than the unlinked eyebrow so date and status fit one line. */
  letter-spacing: .04em; font-size: 10px;
  flex-wrap: nowrap;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  border-bottom: 1.5px solid color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent);
}
@media (hover: hover) {
  a.ticket-eyebrow:hover {
    background: color-mix(in srgb, var(--accent) 14%, transparent);
  }
  a.ticket-eyebrow:hover .ticket-eyebrow-arrow { transform: translateX(2px); }
}
a.ticket-eyebrow:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
/* The status keeps its own color. */
a.ticket-eyebrow .ticket-eyebrow-end { color: var(--ink-mute); }
a.ticket-eyebrow .ticket-eyebrow-end.ticket-live { color: var(--accent-2-text); }
/* The date truncates first, so the status stays visible. */
a.ticket-eyebrow > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket-eyebrow-end { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; flex: none; }
.ticket-eyebrow-arrow {
  font-size: 14px; line-height: 1; font-weight: 700; color: var(--accent);
  transition: transform .12s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .ticket-eyebrow-arrow { transition: none; }
}

/* Venue sits with the date, above the matchup. */
.ticket-venue { margin-top: 6px; font-size: 10.5px; letter-spacing: .08em; color: var(--ink-mute); text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Accented so an international game stands out. */
.venue-international { color: var(--accent); font-weight: 700; }

.ticket-matchup { margin-top: 14px; font-size: min(15px, calc(5.16cqw - 0.6px)); font-weight: 600; letter-spacing: .01em; line-height: 1.55; text-transform: uppercase; }
/* Name and score are separate tracks, so a long name truncates before the score. */
.ticket-matchup div { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: baseline; }
.ticket-matchup .side { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Never split the record. It stays inside .side; anything new in this grid row must be a column. */
.ticket-matchup .side-record { white-space: nowrap; }
.ticket-matchup .at { display: block; }
.ticket-matchup .score {
  font-family: var(--f-display); font-size: 1.2em; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink-mute);
}
.ticket-matchup .score.is-ahead { color: var(--ink); }
.ticket-matchup .at { color: var(--ink-mute); font-weight: 400; padding: 1px 0; }
.ticket-matchup .fav { position: relative; }
/* On .side, not .fav: .fav is the grid row, and an ::after there becomes a grid item. */
/* Sized in em so the star scales with the fluid ticket type. */
.ticket-matchup .fav .side::after { content: "\2605"; font-size: 1.25em; margin-left: 5px; color: var(--accent-2); vertical-align: baseline; }

/* Only wraps the odds row, and is left out when there are no odds. */
.ticket-details {
  margin-top: 10px; padding-top: 12px; border-top: 2px dashed var(--line);
  font-size: 11px; color: var(--ink-mute);
  /* Takes the spare height and centers the numbers, so the rule stays under the matchup. */
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
}
.ticket-details b { color: var(--ink); font-weight: 700; }

/* Three columns, two rows: labels over values, so each number sits under its team.
   minmax(0, ...) so a narrow ticket shrinks instead of overflowing into the stub. */
.ticket-odds-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto) minmax(0, 1fr);
  row-gap: 5px; column-gap: 8px;
  font-size: 11px; letter-spacing: .08em;
  /* line-height 1 so the boxes hug the glyphs; row-gap gives the spacing. */
  line-height: 1;
}
.ticket-odds-label { text-align: center; color: var(--ink-mute); }
/* Every value in full ink. */
.ticket-odds-value { text-align: center; color: var(--ink); font-weight: 600; overflow-wrap: anywhere; }

/* 28.5% of the ticket, with a min-width so the badge and circle fit on narrow screens. */
.detail-hero-stub {
  width: 28.5%; min-width: 96px; flex-shrink: 0; padding: 12px 8px;
  display: flex; flex-direction: column; align-items: stretch; justify-content: center; gap: 4px;
}
/* No visible input to recolor, so the divider turns red. */
.detail-hero-stub.has-error { border-left-color: var(--loss); border-left-style: solid; }
.stub-team-errors {
  font-size: 10.5px; color: var(--loss); font-weight: 600; text-align: center;
}
.stub-team-errors p { margin: 0; }
.stub-label {
  font-family: var(--f-body); font-size: 8.5px; font-weight: 600; color: var(--ink-mute);
  text-transform: uppercase; letter-spacing: .06em; text-align: center; margin-bottom: 5px;
}
.stub-final-label { color: var(--ink-mute); font-style: italic; }
/* The heading names the state of the two numbers below. */
.stub-moved-label { color: var(--accent-2-text); }
/* Same red as the picks-due ring: an open pick. */
.stub-unpicked-label { color: var(--marker); }
/* Always three columns, so the badge stays put when a side has no spread. minmax keeps the
   outer tracks from shrinking below their content. */
.stub-team-row { display: grid; grid-template-columns: minmax(min-content, 1fr) auto minmax(min-content, 1fr); align-items: center; }
.stub-spread { font-family: var(--f-mono); font-size: 9px; color: var(--ink-mute); justify-self: center; }
/* Fixed width so 2- and 3-letter badges match. */
.stub-team-row .team-badge {
  width: 2.6em; padding: 3px 2px; font-size: 10px; border-radius: 5px; justify-self: center;
}

/* Same grid as the team rows, so "@" lines up with the badges. */
.stub-at-row { display: grid; grid-template-columns: minmax(min-content, 1fr) auto minmax(min-content, 1fr); align-items: center; margin: 1px 0; }
.stub-at { grid-column: 2; justify-self: center; font-family: var(--f-display); font-weight: 700; font-size: 12px; color: var(--ink-mute); }

/* The circle is the pick control; padding and negative margin enlarge the tap target. */
.punch-circle-label { justify-self: center; cursor: pointer; padding: 6px; margin: -6px; position: relative; }
.punch-circle-label input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.punch-circle-label.is-disabled { cursor: default; }

/* Dashed circle for both teams; the picked one gets the drawn X (.marker-x).
   inline-block, or the span ignores its width and height. */
.punch-circle {
  display: inline-block;
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px dashed var(--ink-mute);
  position: relative; flex-shrink: 0; justify-self: center;
}
.punch-circle-label input:focus-visible + .punch-circle { outline: 2px solid var(--accent-2); outline-offset: 2px; }

/* Mark visibility and the draw-in run on JS classes (is-picked, is-drawing), not :checked,
   so there's no flash of finished ink. Server-rendered picks get is-picked only. */
/* Sized and centered explicitly: the SVG has no intrinsic size, so an inset wouldn't stretch it. */
.marker-x {
  position: absolute;
  top: 50%; left: 50%;
  width: 26px; height: 26px;
  transform: translate(-50%, -50%) rotate(-8deg);
  opacity: 0;
}
.punch-circle.is-picked .marker-x { opacity: 1; }
/* dasharray 1 2 with dashoffset 2 keeps the hidden state mid-gap, so no stray dot shows. */
.marker-x path { stroke: var(--marker); stroke-width: 3; stroke-linecap: round; fill: none; stroke-dasharray: 1 2; stroke-dashoffset: 0; }
.punch-circle.is-drawing .marker-x path { stroke-dashoffset: 2; animation: draw-stroke .32s ease-out forwards; }
.punch-circle.is-drawing .marker-x path:last-child { animation-delay: .22s; }
@keyframes draw-stroke { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
  .punch-circle.is-drawing .marker-x path { animation: none; stroke-dashoffset: 0; }
}
/* Locked: dried ink is the disabled look. */
.is-torn .marker-x path { stroke: var(--marker-dried); opacity: .8; }

/* Line marks on the stub: after a move your way, the held line and a Take chip for the new
   one; taking it strikes the held line, drawn like the X. Markup in _stub_line.html; see
   .marker-x for the dasharray. */
.stub-lines {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  justify-self: center; padding: 2px 5px; line-height: 1.15;
}
.stub-line-old {
  position: relative;
  display: flex; align-items: baseline; gap: 3px;
  font-family: var(--f-mono); font-size: 9px;
  font-variant-numeric: tabular-nums;
}
/* The old line stays legible under its strike. */
.stub-line-old { color: var(--ink-mute); opacity: .75; }

/* Settled: your line over the kickoff line; the heading reads "Yours / Kickoff". */
.stub-lines.is-settled { gap: 1px; padding: 2px 3px; }
.stub-line-mine,
.stub-line-close,
.stub-line-now {
  font-family: var(--f-mono); font-size: 9px; font-variant-numeric: tabular-nums;
}
.stub-line-mine { color: var(--ink); font-weight: 700; }
.stub-line-close { color: var(--ink-mute); font-size: 8px; }
/* Moved against the pick: nothing to take, only where the line is now. */
.stub-line-now { color: var(--ink-mute); font-size: 8px; }

.mark-strike {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none; overflow: visible;
  width: 108%; height: 14px;
}
.mark-strike path {
  stroke: var(--marker); stroke-width: 2; stroke-linecap: round; fill: none;
  stroke-dasharray: 1 2; stroke-dashoffset: 0;
}
/* Unmarked until you take the new line. Class-driven like .marker-x. */
.mark-strike { opacity: 0; }
.stub-lines.is-taken .mark-strike { opacity: 1; }
.stub-lines.is-drawing .mark-strike path {
  stroke-dashoffset: 2; animation: draw-stroke .34s ease-out forwards;
}
@media (prefers-reduced-motion: reduce) {
  .stub-lines.is-drawing .mark-strike path { animation: none; stroke-dashoffset: 0; }
}

/* The Take chip, on the stub and the sheet: the new number in --accent-2, turning --win with
   a check once taken. Padding and negative margin enlarge the stub's small target. */
.stub-take { position: relative; cursor: pointer; padding: 6px; margin: -6px; }
.stub-take input,
.sheet-take input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.stub-take-chip,
.sheet-take-chip {
  display: inline-flex; align-items: center; gap: 3px;
  border: 1.5px solid var(--accent-2); border-radius: 999px;
  background: color-mix(in srgb, var(--accent-2) 18%, transparent);
  font-family: var(--f-mono); font-weight: 700; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.stub-take-chip { padding: 2px 6px; font-size: 9px; }
.take-verb { font-family: var(--f-display); letter-spacing: .02em; }
.take-check { display: none; width: 1em; height: 1em; }
.take-check path { fill: none; stroke: var(--win); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.stub-lines.is-taken .stub-take-chip,
.sheet-line.is-taking .sheet-take-chip {
  border-color: var(--win); background: color-mix(in srgb, var(--win) 12%, transparent);
}
.stub-lines.is-taken .take-verb,
.sheet-line.is-taking .take-verb { display: none; }
.stub-lines.is-taken .take-check,
.sheet-line.is-taking .take-check { display: inline; }
.stub-take input:focus-visible + .stub-take-chip,
.sheet-take input:focus-visible + .sheet-take-chip { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Held after a save: a plain number, nothing left to take. */
.is-held .stub-take-chip,
.is-held .sheet-take-chip { border-color: transparent; background: none; padding: 0; }
.is-held .take-verb,
.is-held .take-check,
.stub-lines.is-held .stub-line-old { display: none; }
.stub-take:has(input:disabled),
.sheet-take:has(input:disabled) { cursor: default; }
/* "Better than your -3.5.", under the stub's teams. */
.stub-take-note { margin: 2px 0 0; font-size: 8.5px; line-height: 1.3; color: var(--ink-mute); text-align: center; }

/* Your pick moved to the other side, so this line dims instead of disappearing. */
.stub-lines.is-superseded { opacity: .4; }
.stub-lines.is-superseded .stub-take { cursor: default; pointer-events: none; }

/* Once torn, nothing on the stub is a control and the ink has dried. */
.is-torn .mark-strike path { stroke: var(--marker-dried); opacity: .8; }

.stat-line-group { margin-bottom: 16px; display: flex; flex-direction: column; gap: 11px; }
.stat-line { display: flex; justify-content: space-between; font-size: 13.5px; }
.stat-label { color: var(--ink-mute); }
.stat-value { font-family: var(--f-mono); font-weight: 600; font-variant-numeric: tabular-nums; }

.pick-block { background: var(--surface); border-radius: 16px; padding: 16px; margin-bottom: 14px; }
.pick-block-label { font-weight: 700; font-size: 12px; color: var(--ink-mute); margin: 0 0 10px; }
.pick-block > input[type="text"],
.pick-block > input[type="email"],
.pick-block > select,
.pick-block > textarea {
  display: block; width: 100%; font: inherit; font-size: 14px; padding: 9px 10px;
  border: 1.5px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink);
}

/* Standings board: name cards in ticket paper on a printed rail, with a deficit bar.
   Markup in _standings_board.html. */
.board { list-style: none; margin: 0; padding: 4px 0 24px; display: flex; flex-direction: column; gap: 7px; }

/* The rail: a hairline under each card, inset past its edges; none under the last. */
.board-slot { position: relative; padding-bottom: 7px; }
.board-slot::after {
  content: '';
  position: absolute; left: 10px; right: 10px; bottom: 0;
  border-bottom: 1px solid var(--line);
}
.board-slot:last-child { padding-bottom: 0; }
.board-slot:last-child::after { display: none; }

.board-card {
  position: relative;
  display: grid;
  /* Fixed stat column so bars line up across rows. 44px fits "18-0" and ".000". */
  grid-template-columns: 24px minmax(0, 1fr) 44px;
  align-items: center;
  /* Keeps the gap figure and the W-L apart. */
  column-gap: 15px;
  padding: 10px 12px;
  background: var(--paper);
  box-shadow: var(--paper-lift);
  /* A radius, not a chamfer, so the leader's inset ring closes at the corners. */
  border-radius: 8px;
}
.board-card.is-confidence { grid-template-columns: 24px minmax(0, 1fr) 64px; }
/* An Everyone board's ranks run to "T158", so its rank column fits the longest it shows. */
.board.is-everyone .board-card { grid-template-columns: calc(var(--rank-chars) * 11px + 2px) minmax(0, 1fr) 44px; }
.board.is-everyone .board-card.is-confidence { grid-template-columns: calc(var(--rank-chars) * 11px + 2px) minmax(0, 1fr) 64px; }

/* Where an Everyone board skips rows. */
.board-more {
  display: flex; align-items: center; gap: 10px; padding: 2px 12px;
  font-family: var(--f-mono); font-size: 11px; color: var(--ink-mute);
}
.board-more::before, .board-more::after { content: ''; flex: 1; border-bottom: 1px dashed var(--line); }

.board-rank {
  font-family: var(--f-display); font-weight: 700; font-size: 19px;
  line-height: 1; text-align: right;
  color: var(--ink-mute); font-variant-numeric: tabular-nums;
}

.board-body { min-width: 0; }
.board-who {
  margin: 0 0 5px;
  font-weight: 700; font-size: 14.5px; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.board-you {
  margin-left: 6px; padding: 1px 5px;
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--accent); border: 1px solid var(--accent); border-radius: 3px;
  vertical-align: 1px;
}

/* Deficit bar from the baseline (0 points or .500) to the leader; see _attach_board_extras. */
/* Label above the bar, so the track is always full width. */
.board-gauge { display: flex; flex-direction: column; gap: 4px; }
.board-bar { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.board-bar span { display: block; height: 100%; background: var(--ink-mute); border-radius: 2px; }

.board-figures { text-align: right; line-height: 1.15; }
/* On the week page the record also opens that player's picks. */
.board-figures-link { color: inherit; text-decoration: none; }
.board-stat {
  display: block;
  font-family: var(--f-mono); font-weight: 700; font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.board-stat small { font-size: 9.5px; font-weight: 400; color: var(--ink-mute); margin-left: 2px; }
.board-sub { font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute); font-variant-numeric: tabular-nums; }

.board-gap {
  font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
/* The unit rides with the number; the board has no header row. */
.board-gap small { font-size: 8.5px; letter-spacing: .06em; margin-left: 2px; }
.board-lead {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--accent-2-text);
}

/* Leader: the accent ring and confetti. */
.board-card.is-leader { overflow: hidden; box-shadow: var(--paper-lift), inset 0 0 0 2px var(--accent-2); }
.board-card.is-leader .board-rank { color: var(--accent-2-text); }
.board-card.is-leader .board-bar span { background: var(--accent-2); }

/* The reader's own card. */
.board-card.is-you .board-bar span { background: var(--accent); }
.board-card.is-you.is-leader .board-bar span { background: var(--accent-2); }

/* Pick sheet outcomes: a stamp when settled, quiet text while in play. */
.sheet-verdict {
  display: inline-block; padding: 2px 7px;
  font-family: var(--f-display); font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  border: 2px solid currentColor; border-radius: 4px;
  transform: rotate(-2deg);
}
.sheet-verdict.is-hit { color: var(--win); }
.sheet-verdict.is-miss { color: var(--loss); }
.sheet-verdict.is-push { color: var(--accent-2-text); }

.sheet-standing {
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
.sheet-standing.is-hit { color: var(--win); }
.sheet-standing.is-miss { color: var(--loss); }
.sheet-standing.is-push { color: var(--accent-2-text); }

/* Tray chips carry the pick's result. Color is the direction (hit, miss, push) and fill is
   whether it's settled: outlined while in play, solid once graded. Push is accent-2 either way.
   See views._decorate_tray. */
a.tray-chip { text-decoration: none; }
/* The tray chip beside a game, one size smaller. Every state rule applies unchanged. */
.tray-chip.is-inline {
  min-width: 22px; height: 22px; padding: 0 3px;
  font-size: 12px; border-width: 1.5px; border-radius: 6px;
}
/* The only strike, and only once settled: the number is gone. */
.tray-chip.is-settled.is-miss { text-decoration: line-through; }

.tray-chip.is-settled.is-hit {
  background: var(--win); border-color: var(--win); color: var(--surface);
}
.tray-chip.is-settled.is-miss {
  background: var(--loss); border-color: var(--loss); color: var(--surface);
}
.tray-chip.is-settled.is-push { background: var(--accent-2); border-color: var(--accent-2); color: var(--surface); }
.tray-chip.is-running.is-hit { border-color: var(--win); color: var(--win); }
.tray-chip.is-running.is-miss { border-color: var(--loss); color: var(--loss); }
.tray-chip.is-running.is-push { border-color: var(--accent-2); color: var(--accent-2-text); }
@media (hover: hover) {
  a.tray-chip:hover { border-color: var(--accent); }
}
a.tray-chip:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }

/* Clears the sticky tray when a chip links to a game. */
.ticket-card-wrap, .sheet-row { scroll-margin-top: 84px; }

/* Week rail: the season's weeks as links, in the pass's punch style. Markup in _week_rail.html. */
.week-rail { margin: 0 0 18px; }
/* The due ring's caption, in the same red. */
.rail-due-note {
  margin: -10px 0 14px; font-size: 12px; color: var(--marker); font-weight: 600;
}
.rail-strip {
  display: flex; gap: 4px; list-style: none; margin: 0; padding: 2px 0 8px;
  overflow-x: auto;
  /* clip, not hidden: hidden would make this a vertical scroll container too. */
  overflow-y: clip;
}
.rail-strip li { flex: none; }
.rail-week {
  display: block; width: 34px; text-align: center;
  text-decoration: none; color: var(--ink-mute);
  font-family: var(--f-mono); font-size: 10px; font-weight: 700;
  padding: 2px 0;
}
.rail-mark {
  display: block; width: 18px; height: 18px; margin: 0 auto 4px;
  border-radius: 50%; border: 2px solid var(--line);
}
.rail-num { display: block; }

/* Playoff rounds get wider cells, smaller type and wrapping, since the names don't fit 34px. */
.rail-week.is-playoff {
  width: 66px; font-size: 8.5px; line-height: 1.25;
  overflow-wrap: break-word;
}
.rail-split {
  align-self: stretch; width: 0; margin: 0 6px;
  border-left: 1px dashed var(--line);
}

/* Four channels: inner fill is when the week is, the ring is your picks, the pulse is in play,
   and the outer ring is the week you're viewing. Fill rules come before ring rules. */

/* Inner fill: when the week is. */
/* Future weeks keep the plain .rail-mark outline: no fill, no claim. */
.rail-week.is-past .rail-mark { background: var(--ink-mute); border-color: var(--ink-mute); }
.rail-week.is-past { color: var(--ink); }
.rail-week.is-current .rail-mark { background: var(--accent); border-color: var(--accent); }
.rail-week.is-current { color: var(--accent); }

/* A finished week: the fill is how your picks went (even keeps the past grey), and the ring
   where that left you in the league, gold on top and ink at the bottom. */
.rail-week.is-past.result-winning .rail-mark { background: var(--win); border-color: var(--win); }
.rail-week.is-past.result-losing .rail-mark { background: var(--loss); border-color: var(--loss); }
.rail-week.is-past.finish-top .rail-mark { border-color: var(--week-top); border-width: 3px; }
.rail-week.is-past.finish-bottom .rail-mark { border-color: var(--ink); border-width: 3px; }

/* In play: the fill pulses amber. */
/* Amber on the fill, since the ring shows your picks. Static amber reads with motion off. */
.rail-week.is-live .rail-mark { background: var(--accent-2); border-color: var(--accent-2); }
.rail-week.is-live { color: var(--accent-2-text); }
/* The pulse animation is with the other live indicators below. */

/* Ring: your picks. */
/* Dashed red: this week wants picks. Only the current week (see week_rail.picks_due). */
.rail-week.picks-due .rail-mark {
  border-color: var(--marker); border-style: dashed; border-width: 3px;
}
/* Solid green: all picked, and ranked where it matters. Can run ahead, never on a past week. */
.rail-week.picks-in .rail-mark {
  border-color: var(--win); border-style: solid; border-width: 3px;
}

/* Outer ring: navigation. */
/* Hover is a lighter version of the viewed week's ring, and comes first so the viewed week
   keeps its full ring while hovered. */
@media (hover: hover) {
  .rail-week:hover .rail-mark {
    box-shadow: 0 0 0 2px var(--ground), 0 0 0 4px var(--ink-mute);
  }
}
.rail-week.is-viewed .rail-mark { box-shadow: 0 0 0 2px var(--ground), 0 0 0 4px var(--ink); }

.rail-week:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; border-radius: 4px; }

/* Live week: tickets carry their own score once games start. */
.mode-chip.is-live {
  color: var(--accent-2-text); border-color: var(--accent-2); font-weight: 700;
}
.ticket-live { color: var(--accent-2-text); font-weight: 700; }

/* Every live indicator pulses on the same timing. Text fades opacity; the rail mark animates
   its fill so its ring keeps meaning your picks. Static amber is the resting state. */
@keyframes live-pulse { 50% { opacity: .45; } }
@keyframes rail-live-pulse {
  50% { background-color: color-mix(in srgb, var(--accent-2) 30%, transparent); }
}
@media (prefers-reduced-motion: no-preference) {
  .mode-chip.is-live,
  .ticket-live,
  .sheet-live { animation: live-pulse 1.9s ease-in-out infinite; }
  .rail-week.is-live .rail-mark { animation: rail-live-pulse 1.9s ease-in-out infinite; }
}

/* Settled next to provisional; the running cell is tinted so they don't read as one number. */
.week-score { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 0; }
.week-score-cell {
  flex: 1 1 0; min-width: 128px;
  padding: 8px 11px; border-radius: 10px;
  background: var(--surface); box-shadow: 0 1px 0 var(--line);
}
.week-score-cell.is-running {
  background: color-mix(in srgb, var(--accent-2) 10%, var(--surface));
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent-2) 30%, transparent);
}
.week-score-cell dt {
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-mute);
  margin-bottom: 3px;
}
.week-score-cell.is-running dt { color: var(--accent-2-text); }
.week-score-cell dd {
  margin: 0; display: flex; align-items: baseline; gap: 2px;
  font-variant-numeric: tabular-nums;
}
.week-score-cell dd b {
  font-family: var(--f-display); font-size: 19px; line-height: 1; color: var(--ink);
}
.week-score-of { font-family: var(--f-mono); font-size: 13px; color: var(--ink-mute); }
.week-score-rec { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-mute); margin-left: 5px; }

/* A game in play gets quiet text; a graded result gets a stamp. */
.stub-standing {
  display: block; margin-top: 8px; text-align: center;
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-mute);
}
.stub-standing.is-hit { color: var(--win); }
.stub-standing.is-miss { color: var(--loss); }
.stub-standing.is-push { color: var(--accent-2-text); }
.stub-standing b { font-weight: 700; }

/* The settled verdict, rotated and outlined like the confirm stamp. */
.stub-verdict {
  display: block; width: fit-content; margin: 10px auto 2px;
  padding: 3px 10px;
  font-family: var(--f-display); font-size: 14px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  border: 2.5px solid currentColor; border-radius: 5px;
  transform: rotate(-3deg);
}
.stub-verdict.is-hit { color: var(--win); }
.stub-verdict.is-miss { color: var(--loss); }
.stub-verdict.is-push { color: var(--accent-2-text); }
/* What the pick earned or cost, in confidence points. */
.stub-verdict-pts {
  display: inline-block; margin-left: 5px; padding-left: 6px;
  border-left: 1.5px solid currentColor;
  font-family: var(--f-mono); font-size: 12px;
}
.stub-verdict.is-miss .stub-verdict-pts { text-decoration: line-through; }
/* Marks a default-strategy pick, muted since it isn't part of the result. */
.stub-auto-tag {
  display: inline-block; margin-left: 4px; padding: 1px 4px;
  font-family: var(--f-mono); font-size: 8px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-mute); border: 1px solid currentColor; border-radius: 3px;
  vertical-align: middle;
}

/* Public league directory: the landing page's pass without the punch strip or standings. */
.season-pass.is-directory { cursor: default; }
.season-pass.is-directory .pass-name {
  display: block; text-decoration: none; color: inherit;
}
.season-pass.is-directory .pass-name:hover { color: var(--accent); }
.pass-enroll { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.pass-enroll form { margin: 0; }
.pass-join {
  font-family: var(--f-display); font-weight: 700; font-size: 12px;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent); background: transparent;
  border: 1.5px solid var(--accent); border-radius: 999px;
  padding: 4px 14px; cursor: pointer;
}
.pass-join:hover { background: var(--accent); color: var(--surface); }
/* Will Call's Open leagues: the directory's pass, its + a fixed round column. */
.pass-notice { display: block; margin-top: 2px; font-family: var(--f-body); font-size: 12px; }
.pass-plus {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  font-family: var(--f-display); font-weight: 700; font-size: 24px; line-height: 1;
  color: var(--accent); background: transparent; border: 1.5px solid var(--accent); cursor: pointer;
}
.pass-plus:hover { background: var(--accent); color: var(--surface); }

/* Box scores, two rows a game. The loser's line drops back so the outcome reads first. */
.boxscores { list-style: none; margin: 0 0 24px; padding: 4px 0 0; display: flex; flex-direction: column; gap: 8px; }
.boxscore {
  background: var(--surface); border-radius: 12px; padding: 10px 12px;
  box-shadow: 0 1px 0 var(--line);
}
.boxscore-link { display: block; text-decoration: none; color: var(--ink); }
.boxscore-side {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 9px;
  padding: 3px 0;
  color: var(--ink-mute);
}
.boxscore-side.is-winner { color: var(--ink); }
.boxscore-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px;
}
.boxscore-side.is-winner .boxscore-name { font-weight: 700; }
.boxscore-score {
  font-family: var(--f-display); font-size: 17px; font-weight: 700;
  font-variant-numeric: tabular-nums; min-width: 26px; text-align: right;
}
/* No result yet, so neither side drops back. */
.boxscore.is-pending .boxscore-side { color: var(--ink-mute); }
.boxscore-note {
  margin: 5px 0 0;
  font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute);
}
.boxscore-note:empty { display: none; }

/* Award list: the trophy name leads, the criterion sits under it. */
.award-list { list-style: none; margin: 0 0 24px; padding: 4px 0 0; display: flex; flex-direction: column; gap: 10px; }
.award {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 10px 12px;
  background: var(--surface); border-radius: 12px;
  border-left: 3px solid var(--accent-2);
}
.award-body { flex: 1; min-width: 0; }
.award-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.award-name { font-family: var(--f-display); font-weight: 700; font-size: 14px; }
.award-winners { font-size: 13px; font-weight: 700; color: var(--accent); }
.award-note { font-family: var(--f-mono); font-size: 10.5px; font-weight: 400; color: var(--ink-mute); }
/* How often a weekly trophy went out this season, kept small on the name's line. */
.award-count {
  font-family: var(--f-mono); font-size: 11px; font-weight: 700;
  color: var(--ink-mute); font-variant-numeric: tabular-nums;
}
.award-desc { margin: 4px 0 0; font-size: 12px; color: var(--ink-mute); line-height: 1.35; }

/* Weekly trophies list their winners below instead of on the heading line. */
.award.is-weekly { border-left-color: var(--line); }
.award-runs { list-style: none; margin: 8px 0 0; padding: 0; }
.award-runs li {
  display: flex; align-items: baseline; gap: 9px;
  padding: 4px 0; border-top: 1px solid var(--line);
  font-size: 12.5px;
}
.award-when {
  font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute);
  min-width: 58px; flex: none;
}
.award-who { font-weight: 700; }
.award-runs .award-note { margin-left: auto; text-align: right; }

/* The record book: denser and flatter than the standings board, with rules instead of cards. */
.book-totals { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 22px; padding: 0; }
.book-total {
  flex: 1 1 0; min-width: 74px;
  padding: 8px 10px; border-radius: 10px; background: var(--surface);
  box-shadow: 0 1px 0 var(--line);
}
.book-total dt {
  font-family: var(--f-mono); font-size: 9px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; color: var(--ink-mute);
  margin: 0 0 3px;
}
.book-total dd {
  margin: 0; font-family: var(--f-display); font-size: 18px; line-height: 1;
  font-variant-numeric: tabular-nums;
}

.book-head {
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase;
  margin: 26px 0 6px; padding-bottom: 5px;
  border-bottom: 2px solid var(--ink);
}

.book-standings, .book-seasons, .book-trophies { list-style: none; margin: 0; padding: 0; }
.book-row, .book-season {
  display: flex; align-items: baseline; gap: 10px;
  padding: 8px 2px; border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.book-trophy {
  padding: 8px 2px; border-bottom: 1px solid var(--line); font-size: 13px;
}
.book-row:last-child, .book-season:last-child, .book-trophy:last-child { border-bottom: 0; }

.book-rank {
  font-family: var(--f-display); font-size: 13px; color: var(--ink-mute);
  min-width: 18px; font-variant-numeric: tabular-nums;
}
.book-who { flex: 1; min-width: 0; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The dash is a fixed column, so every row's hyphen lines up. */
.book-record {
  font-family: var(--f-mono); font-weight: 700; font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: baseline; flex: none;
}
.book-w { min-width: 4ch; text-align: right; }
.book-l { min-width: 4ch; text-align: left; }
.book-dash { padding: 0 1px; color: var(--ink-mute); }
.book-pct { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-mute); font-variant-numeric: tabular-nums; }
/* The span of seasons behind the record. */
.book-span {
  font-family: var(--f-mono); font-size: 10px; color: var(--ink-mute);
  min-width: 62px; text-align: right; flex: none;
}

.book-season-year {
  font-family: var(--f-mono); font-weight: 700; font-size: 12px;
  flex: 1; color: var(--ink);
}
.book-champion { font-weight: 700; text-align: right; }
.book-inprogress {
  font-family: var(--f-mono); font-size: 10px; font-weight: 400;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent-2-text);
}

.book-subhead {
  font-family: var(--f-mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-mute);
  margin: 14px 0 2px;
}
.book-subhead:first-of-type { margin-top: 8px; }
/* The trophy name shrinks, the holders don't: a clipped holder name is unreadable. */
.book-trophy-id { margin: 0 0 4px; display: flex; align-items: baseline; gap: 6px; }
/* Wraps instead of clipping. */
.book-trophy-name { font-weight: 700; }
/* Muted, so the medals carry the only color in the row. */
.book-trophy-count { font-family: var(--f-mono); font-size: 11.5px; color: var(--ink-mute); font-weight: 700; flex: none; }
/* Gold, silver, bronze in their own columns. */
.book-trophy-holders {
  margin: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 8px;
  font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute);
}
.book-trophy-holders .book-holder {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.book-trophy-holders b { color: inherit; font-weight: 700; }
/* Metal colors darkened for light mode and lifted for dark so they read as text. */
.book-holder { color: var(--ink-mute); }
.book-holder.medal-gold   { color: var(--medal-gold); font-weight: 700; }
.book-holder.medal-silver { color: var(--medal-silver); font-weight: 700; }
.book-holder.medal-bronze { color: var(--medal-bronze); font-weight: 700; }

/* Profile career line: a few numbers set in the data face. */
.career {
  display: flex; gap: 8px; margin: 0 0 8px; padding: 0;
}
.career-cell {
  flex: 1;
  padding: 9px 10px;
  background: var(--surface); border-radius: 10px;
}
.career-cell dt {
  font-family: var(--f-mono); font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink-mute); margin: 0 0 3px;
}
.career-cell dd {
  margin: 0;
  font-family: var(--f-mono); font-size: 15px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.career-cell dd small { font-size: 9.5px; font-weight: 400; color: var(--ink-mute); margin-left: 2px; }

.season-history { list-style: none; margin: 0 0 24px; padding: 4px 0 0; }
.season-row {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 2px; border-bottom: 1px solid var(--line);
}
.season-row:last-child { border-bottom: 0; }
.season-row.is-empty { color: var(--ink-mute); font-size: 13.5px; }
.season-row-who { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.season-row-year { font-family: var(--f-mono); font-weight: 700; font-size: 13px; }
.season-row-league {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; color: var(--ink-mute);
}
.season-row-finish { font-family: var(--f-display); font-size: 14px; color: var(--ink-mute); }
.season-row-finish b { font-size: 16px; color: var(--ink); }
.season-row-finish small { font-size: 10px; margin-left: 3px; }
.season-row-record {
  min-width: 52px; text-align: right;
  font-family: var(--f-mono); font-size: 12px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Account links, one per row. */
.account-links { list-style: none; margin: 0 0 24px; padding: 4px 0 0; }
.account-links li { padding: 9px 2px; border-bottom: 1px solid var(--line); }
.account-links li:last-child { border-bottom: 0; }
.account-links a { font-size: 14px; }

/* League detail tags reuse .pass-tag. */
.league-tags { display: flex; flex-wrap: wrap; gap: 5px; margin: 0 0 4px; }

.roster { list-style: none; margin: 0 0 24px; padding: 4px 0 0; }
.roster-row {
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--line);
}
.roster-row:last-child { border-bottom: 0; }
.roster-who { font-weight: 700; font-size: 14px; }
.roster-role {
  font-family: var(--f-mono); font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-mute);
}
/* Pushed right, so a member with no record keeps a full-width name. */
.roster-record {
  margin-left: auto;
  font-family: var(--f-mono); font-size: 12.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.board-scale {
  margin: -16px 0 24px; padding-left: 2px;
  font-family: var(--f-mono); font-size: 10.5px; color: var(--ink-mute);
}

.board-empty {
  margin: 4px 0 24px; padding: 18px 14px;
  border: 1.5px dashed var(--line); border-radius: 12px;
  color: var(--ink-mute); font-size: 13.5px; text-align: center;
}

.pick-matrix-wrap {
  overflow-x: auto;
  margin: 0 0 20px;
}
.pick-matrix {
  border-collapse: collapse;
  font-size: 12px;
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
}
.pick-matrix th, .pick-matrix td {
  padding: 6px 8px;
  text-align: center;
  white-space: nowrap;
}
.pick-matrix thead th {
  color: var(--ink-mute);
  font-weight: 700;
  font-family: var(--f-body);
  border-bottom: 1.5px solid var(--line);
}
/* Where numbered weeks end and playoff rounds begin: a vertical rule in the users view and a
   horizontal one in the weeks view, dashed like the week rail's divider. */
.pick-matrix th.matrix-split,
.pick-matrix td.matrix-split { border-left: 2px dashed var(--line); }
.pick-matrix tr.matrix-split-row th,
.pick-matrix tr.matrix-split-row td { border-top: 2px dashed var(--line); }
/* Some air either side so it reads as a seam. */
.pick-matrix th.matrix-split,
.pick-matrix td.matrix-split { padding-left: 12px; }
.pick-matrix thead th a {
  color: inherit;
  text-decoration: none;
}
.pick-matrix tbody th {
  text-align: left;
  font-family: var(--f-body);
  font-weight: 700;
  color: var(--ink);
}
.pick-matrix tbody tr:nth-child(even) {
  background: var(--surface-2);
}
/* Freezes the name column while the matrix scrolls; needs a background to hide what scrolls under. */
.pick-matrix th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  box-shadow: 1px 0 0 var(--line);
}
.pick-matrix tbody tr:nth-child(even) th:first-child {
  background: var(--surface-2);
}
/* A finished week's top score, boxed in the rail's gold. Every record keeps the box's room,
   so a column is as wide whoever topped it. */
.matrix-record {
  display: inline-block;
  padding: 0 4px;
  border: 2px solid transparent;
  border-radius: 5px;
}
.matrix-record.is-top { border-color: var(--week-top); }
.matrix-pick {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  border-radius: 4px;
  border: 2px solid;
  font-family: var(--f-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .02em;
}
.matrix-pick-tie {
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--ink-mute);
}
/* Confidence value for a graded pick, apart from the team badge. Struck through on a miss. */
.matrix-pts-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  margin-left: 4px;
  padding: 1px 5px;
  border-radius: 4px;
  border: 1.5px solid currentColor;
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 700;
  vertical-align: middle;
}
.matrix-pts-pill.is-hit { color: var(--win); }
.matrix-pts-pill.is-miss { color: var(--loss); text-decoration: line-through; }
/* A push earns half, so it isn't struck. */
.matrix-pts-pill.is-push { color: var(--accent-2-text); }
/* The stake on an ungraded pick, in neutral ink. */
.matrix-pts-pill.is-staked { color: var(--ink-mute); }

/* Confetti for the #1 row (docs/DESIGN.md, Motion). Randomized per piece in picks/confetti.py.
   Hidden without motion; the leader's outline is the reduced-motion version. */
.confetti {
  position: absolute;
  border-radius: 1px;
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .confetti { animation: confetti-fall 3.6s ease-in infinite; }
}

@keyframes confetti-fall {
  0%   { transform: translateY(-4px) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  65%  { opacity: 1; }
  100% { transform: translateY(var(--fall, 24px)) rotate(var(--rot, 50deg)); opacity: 0; }
}

.submit-row { padding-top: 4px; }
/* Save picks, fixed to the bottom of the viewport on both pick pages and kept to .page's width. */
.save-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  max-width: 480px;
  margin: 0 auto;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: 0 -8px 20px -12px rgba(0, 0, 0, .35);
  z-index: 40;
}
/* Room for the bar so it never covers the last game. */
#week-picks-form, #pick-sheet-form {
  padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px));
}
/* The error toast sits above the bar. */
body:has(.save-bar) .error-toast { bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }
.save-bar-actions { display: flex; gap: 10px; }
.save-bar-actions > .button { flex: 1; width: auto; }
/* 2:1 so Save's summary text fits without Undo shrinking to nothing. */
.save-bar-actions #save-picks { flex: 2; }
.save-bar-actions #undo-picks { flex: 1; }
/* Side-by-side buttons (Accept/Decline); .button is full width otherwise. */
.submit-row-multi { display: flex; gap: 10px; padding-top: 4px; }
.submit-row-multi form { flex: 1; }
.button {
  display: inline-block;
  font-family: var(--f-display); font-weight: 700; font-size: 15px;
  background: var(--accent); color: var(--accent-text); border: 0;
  padding: 13px 20px; border-radius: 12px; cursor: pointer; width: 100%;
  text-align: center; text-decoration: none;
  box-sizing: border-box;
}
.button:hover { filter: brightness(1.05); }
.button.is-submitting {
  opacity: .6;
  pointer-events: none;
  cursor: not-allowed;
}
/* Dimmed, not disabled, so it stays tappable. */
.button.is-idle { opacity: .55; }
.button.is-idle:hover { filter: none; }

/* Destructive actions: --loss, outlined so it's quieter than the primary button. */
.button-danger {
  background: transparent; color: var(--loss); border: 2px solid var(--loss);
  padding: 11px 20px;
}
.button-danger:hover { background: var(--loss); color: var(--accent-text); filter: none; }

/* Secondary action: outlined and muted. */
.button.is-quiet {
  background: transparent; color: var(--ink-mute); border: 1.5px solid var(--line);
}
.button.is-quiet:hover { color: var(--loss); border-color: var(--loss); filter: none; }

/* Shared confirmation dialog (confirm-dialog.js). */
.confirm-dialog {
  border: none; border-radius: 14px; padding: 20px;
  width: calc(100% - 48px); max-width: 320px;
  background: var(--paper); color: var(--ink); box-shadow: var(--paper-lift-hover);
}
.confirm-dialog::backdrop { background: rgba(0, 0, 0, .5); }
.confirm-dialog-message { margin: 0 0 16px; font-size: 15px; line-height: 1.4; }
.confirm-dialog .submit-row-multi > button { flex: 1; }

/* Autofill toolbar on both pick forms: labelled selects, then the button that applies them.
   See _pick_tools.html. */
.pick-tools {
  display: flex; flex-direction: column; gap: 12px;
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
/* One labelled control: its label sits tight above its select. */
.pick-tool { display: flex; flex-direction: column; gap: 6px; }
.pick-tools-label {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-mute);
}
.pick-tools-select {
  width: 100%; box-sizing: border-box;
  font-family: var(--f-body); font-size: 14px; color: var(--ink);
  background: var(--surface-2); border: 1.5px solid var(--line);
  border-radius: 9px; padding: 10px 12px;
}
.pick-tools-select:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 1px; }

/* Full-width week clear. */
.pick-clear-week { margin: 0 0 18px; }

/* Per-game clear: a quiet text action, the same on the ticket and the sheet. */
.pick-clear {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--f-body); font-size: 12px; color: var(--ink-mute);
  text-decoration: underline; text-underline-offset: 2px;
}
.pick-clear:hover { color: var(--loss); }
.pick-clear:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; border-radius: 2px; }
.pick-clear-row { margin-top: 12px; text-align: right; }

.member-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.member-row-actions { display: flex; align-items: center; gap: 10px; }
.member-row-action { background: none; border: 0; padding: 0; font-size: 12px; color: var(--ink-mute); text-decoration: underline; cursor: pointer; }
.member-row-action:hover { color: var(--accent); }
.member-row-action-remove:hover { color: var(--loss); }

.season-block h2 a { color: inherit; text-decoration: none; }

.login-form { background: var(--surface); border-radius: 16px; padding: 20px; margin-top: 16px; }
.login-form p { margin: 0 0 12px; }
.login-form label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-mute); margin-bottom: 4px; }
.login-form input[type="text"],
.login-form input[type="email"],
.login-form input[type="password"] {
  width: 100%; padding: 10px 12px; border-radius: 10px; border: 2px solid var(--line);
  font-size: 15px; background: var(--ground); color: var(--ink);
}
/* Public or private: each choice a row, its words beside the radio. */
.login-form .profile-choice { border: 0; padding: 0; margin: 0 0 12px; min-width: 0; }
.login-form .profile-choice legend { padding: 0; margin-bottom: 6px; font-size: 12.5px; font-weight: 600; color: var(--ink-mute); }
.login-form .profile-choice label {
  display: flex; gap: 10px; align-items: flex-start; margin: 0 0 8px;
  font-size: 14px; font-weight: 400; line-height: 1.4; color: var(--ink);
}
.login-form .profile-choice input { flex: none; margin-top: 3px; accent-color: var(--accent); }
.login-form .profile-choice .pick-block-help { display: block; margin: 4px 0 0; }
/* Cloudflare's "are you a person" check, spaced like a field. */
.login-form .turnstile { margin: 0 0 12px; }

.auth-links { margin-top: 14px; font-size: 13px; color: var(--ink-mute); }

/* A page of running text, like the privacy policy. */
.prose { max-width: 62ch; }
.prose p, .prose li { line-height: 1.5; margin: 0 0 10px; }
.prose ul { margin: 0 0 6px; padding-left: 20px; }

/* Confirm stamp (docs/DESIGN.md), fixed to the viewport so it works on any page. */
.confirm-stamp {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-8deg);
  opacity: 0;
  pointer-events: none;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: .1em;
  color: var(--win);
  border: 4px solid var(--win);
  border-radius: 12px;
  padding: 12px 26px;
  background: var(--surface);
  text-transform: uppercase;
  box-shadow: 0 16px 40px -12px rgba(30, 40, 25, .45);
  z-index: 50;
  transition: opacity .2s ease;
}
.confirm-stamp.is-visible { opacity: 1; }

/* Error toast for fetch saves (error-toast.js), at the bottom near the Save button. */
.error-toast {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%) translateY(8px);
  max-width: min(520px, calc(100vw - 32px));
  opacity: 0;
  pointer-events: none;
  background: var(--surface);
  border: 1.5px solid var(--loss);
  color: var(--loss);
  border-radius: 12px;
  padding: 11px 16px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  box-shadow: 0 16px 40px -12px rgba(30, 40, 25, .45);
  z-index: 60;
}
.error-toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
  cursor: pointer;
}
/* Notice toasts: something still wants you, not a failure. Same red as the picks-due ring. */
.error-toast.is-notice { border-color: var(--marker); color: var(--marker); }

@media (prefers-reduced-motion: no-preference) {
  .error-toast { transition: opacity .2s ease, transform .2s ease; }
  /* Slow fade out; the fade in is quick. */
  .error-toast.is-leaving { transition: opacity .9s ease, transform .9s ease; }
}

@media (prefers-reduced-motion: no-preference) {
  .confirm-stamp.is-visible { animation: stamp-in .4s cubic-bezier(.34, 1.56, .64, 1); }
  @keyframes stamp-in {
    0% { transform: translate(-50%, -50%) scale(2.4) rotate(-14deg); opacity: 0; }
    100% { transform: translate(-50%, -50%) scale(1) rotate(-8deg); opacity: 1; }
  }
}

/* Trophy case (docs/DESIGN.md). Tier comes from a class, not an inline style. */
.trophy-subhead {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
  margin: 24px 0 10px;
}

/* Most Backed and Most Faded side by side in one card; the divider is the first column's border. */
.affinity-mode { margin: 0 0 6px; }
.affinity-card {
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--surface); border-radius: 14px;
  padding: 14px 0; margin: 0 0 14px;
}
.affinity-col { padding: 0 14px; min-width: 0; }
.affinity-col:first-child { border-right: 1px solid var(--line); }
.affinity-col-head {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-mute); margin: 0 0 10px;
}
/* Badge and count on one line, the bar on its own line below. */
.affinity-list {
  display: flex; flex-direction: column; gap: 12px;
  list-style: none; margin: 0; padding: 0; font-size: 13px;
}
.affinity-row-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-bottom: 5px;
}
.affinity-bar { height: 9px; background: var(--surface-2); border-radius: 4px; overflow: hidden; }
.affinity-bar span { display: block; height: 100%; border-radius: 4px; }
/* Faded uses --marker, not --loss: fading a team isn't losing. */
.affinity-bar.is-backed span { background: var(--win); }
.affinity-bar.is-faded span { background: var(--marker); }
.affinity-count {
  font-family: var(--f-mono); font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* Banners, one per row. */
.trophy-grid {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.trophy-chip {
  position: relative;
  background: var(--surface);
  border-radius: 14px;
  padding: 14px 16px;
  box-shadow: 0 1px 2px rgba(27, 35, 30, .06), 0 4px 14px rgba(27, 35, 30, .05);
  border: 2.5px solid var(--tier-color, var(--line));
  cursor: pointer;
}
.trophy-summary-row {
  display: flex;
  align-items: center;
  gap: 14px;
}
/* flex: 1 so every banner's name starts at the same x. */
.trophy-summary-text { flex: 1; min-width: 0; }
.trophy-chip.is-unearned {
  cursor: default;
  opacity: .4;
  border-color: var(--line);
}

.trophy-chip.tier-bronze   { --tier-color: #9C7A54; }
.trophy-chip.tier-silver   { --tier-color: #9CA3AA; }
.trophy-chip.tier-gold     { --tier-color: #D4A62A; }
.trophy-chip.tier-platinum { --tier-color: #5D6FA3; }
.trophy-chip.tier-diamond  { --tier-color: #2FA8E0; overflow: visible; }

/* Trophy object: a medal for a weekly award, a plaque for a season one, art above and stars
   below. The art plate is a fixed slot for real artwork later. */
.trophy-object { position: relative; flex: none; display: block; }
.trophy-body {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  box-sizing: border-box;
}
.trophy-plate { display: grid; place-items: center; }
.trophy-monogram {
  font-family: var(--f-display); font-weight: 700;
  line-height: 1; color: var(--tier-color, var(--ink-mute));
}
/* Placeholder emoji art (templatetags/trophy_art.py), sized to fill the object.
   line-height 1 so emoji metrics don't open the plate. */
.trophy-art { font-size: 44px; line-height: 1; }
.trophy-object.is-plaque .trophy-art { font-size: 36px; }
.trophy-object.is-stamp .trophy-art { font-size: 0.78em; }

/* Art is grayscaled and tinted to the tier so frame and art match. Untiered objects keep
   the emoji's color; unearned ones stay gray. */
.trophy-object.is-unearned .trophy-art { filter: grayscale(1) contrast(1.05); }
.tier-bronze   .trophy-art { filter: grayscale(1) sepia(1) hue-rotate(-6deg)  saturate(0.85) brightness(0.95); }
.tier-silver   .trophy-art { filter: grayscale(1) sepia(1) hue-rotate(170deg) saturate(0.3)  brightness(1.05); }
.tier-gold     .trophy-art { filter: grayscale(1) sepia(1) hue-rotate(8deg)   saturate(1.7)  brightness(1.05); }
.tier-platinum .trophy-art { filter: grayscale(1) sepia(1) hue-rotate(188deg) saturate(0.8); }
.tier-diamond  .trophy-art { filter: grayscale(1) sepia(1) hue-rotate(162deg) saturate(1.9)  brightness(1.05); }

/* Game line chart, drawn like a printed program: hairlines, mono margins, one inked line.
   Points from the home side (see picks/charts.py). No fills. */
.line-chart { margin: 18px 0 0; }
.line-chart figcaption {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin-bottom: 6px;
}
.line-chart-title {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-mute);
}
.line-chart-key {
  display: flex; gap: 10px; flex-wrap: wrap;
  font-family: var(--f-mono); font-size: 9.5px; color: var(--ink-mute);
}
/* A swatch each, so the key needs no colour words. */
.line-chart-key span::before {
  content: ''; display: inline-block; width: 12px; height: 0;
  border-top-width: 2px; margin-right: 4px; vertical-align: middle;
}
.key-margin::before  { border-top-style: solid;  border-top-color: var(--ink); }
.key-closing::before { border-top-style: dashed; border-top-color: var(--accent-2); }
.key-locked::before  { border-top-style: dashed; border-top-color: var(--accent); }

/* Stretches to the ticket's width at a fixed height, so a wide screen doesn't exaggerate swings. */
.line-chart svg { display: block; width: 100%; height: 140px; }

.chart-grid   { stroke: var(--line); stroke-width: .5; }
.chart-zero   { stroke: var(--line); stroke-width: 1.2; }
.chart-tick {
  font-family: var(--f-mono); font-size: 7px; fill: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.chart-closing { stroke: var(--accent-2); stroke-width: 1.2; stroke-dasharray: 5 3; }
.chart-locked  { stroke: var(--accent);   stroke-width: 1.2; stroke-dasharray: 3 3; }
.chart-margin  { stroke: var(--ink); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-final   { fill: var(--ink); }
/* Quarter boundaries: full-height hairlines. */
.chart-period {
  stroke: var(--line); stroke-width: .5; stroke-dasharray: 2 3; opacity: .9;
}
.chart-period-label {
  font-family: var(--f-mono); font-size: 6.5px; fill: var(--ink-mute);
  letter-spacing: .06em;
}
.line-chart-foot {
  margin: 6px 0 0; font-family: var(--f-mono); font-size: 9.5px;
  color: var(--ink-mute); line-height: 1.5;
}

/* Medal: struck metal, one surface, no plates. */
/* Sized for artwork; the art area is about 58px inside the rim. */
.trophy-object.is-medal .trophy-body {
  width: 78px; height: 78px; padding: 9px 0 8px;
  justify-content: center; gap: 3px;
  border: 2.5px solid var(--tier-color, var(--line));
  border-radius: 50%;
  background: var(--surface-2);
}
.trophy-object.is-medal .trophy-monogram { font-size: 30px; }

/* Plaque: the ticket chamfer and two engraving plates. The outline is two clipped layers,
   since a border would be cut by the clip-path. */
.trophy-object.is-plaque .trophy-body {
  width: 72px; height: 88px; padding: 7px;
  justify-content: space-between; gap: 5px;
  background: var(--tier-color, var(--line));
  clip-path: polygon(
    10px 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%, 0 10px
  );
}
.trophy-object.is-plaque .trophy-body::before {
  content: '';
  position: absolute; inset: 2.5px;
  background: var(--surface-2);
  clip-path: polygon(
    8.5px 0, calc(100% - 8.5px) 0, 100% 8.5px, 100% 100%, 0 100%, 0 8.5px
  );
}
/* Above the inset fill, which would otherwise cover them. */
.trophy-object.is-plaque .trophy-plate { position: relative; }
/* Separate plates for the art and the lettering, like a real plaque. */
.trophy-object.is-plaque .trophy-plate {
  width: 100%; border: 1px solid var(--tier-color, var(--line));
  background: color-mix(in srgb, var(--tier-color, var(--line)) 12%, transparent);
}
.trophy-object.is-plaque .trophy-plate.is-art { flex: 1; }
.trophy-object.is-plaque .trophy-plate.is-rarity { padding: 3px 0; }
.trophy-object.is-plaque .trophy-monogram { font-size: 26px; }

/* Unearned keeps its shape, so the case shows gaps. */
.trophy-object.is-unearned .trophy-body { border-color: var(--line); background: transparent; }
.trophy-object.is-plaque.is-unearned .trophy-body { background: var(--line); }
.trophy-object.is-plaque.is-unearned .trophy-body::before { background: var(--ground); }
.trophy-object.is-unearned .trophy-plate { border-color: var(--line); background: transparent; }
.trophy-object.is-unearned .trophy-monogram { color: var(--line); }

/* Tier colors, set on the object since it also renders outside a chip. */
.trophy-object.tier-bronze   { --tier-color: #9C7A54; }
.trophy-object.tier-silver   { --tier-color: #9CA3AA; }
.trophy-object.tier-gold     { --tier-color: #D4A62A; }
.trophy-object.tier-platinum { --tier-color: #5D6FA3; }
.trophy-object.tier-diamond  { --tier-color: #2FA8E0; }

/* A global trophy as an object (flair): the shelf's navy medal in its amber ring. */
.trophy-object.is-global { --tier-color: var(--accent-2); }
.trophy-object.is-global .trophy-body { background: var(--shelf); }

/* The global trophies' shelf above the case: navy, bigger than the case, each band opening to
   every win. Fixed medal and count columns, so bands line up whatever their lines say. */
.global-shelf { display: flex; flex-direction: column; gap: 10px; margin: 0 0 18px; }
.global-trophy {
  --tier-color: var(--accent-2);
  background: var(--shelf); color: var(--shelf-ink);
  border-radius: 14px; padding: 16px;
}
.global-trophy summary {
  display: grid; grid-template-columns: 96px minmax(0, 1fr) 4ch; align-items: center; gap: 16px;
  list-style: none; cursor: pointer;
}
.global-trophy summary::-webkit-details-marker { display: none; }
.global-medal {
  display: grid; place-items: center; width: 96px; height: 96px; box-sizing: border-box;
  border: 3px solid var(--accent-2); border-radius: 50%;
  background: var(--shelf-medal); color: var(--shelf);
  font-family: var(--f-display); font-weight: 700; font-size: 30px; line-height: 1;
}
.global-medal.is-season { font-size: 24px; }
.global-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.global-kicker { font-family: var(--f-display); font-weight: 600; font-size: 13px; color: var(--accent-2); }
.global-name { font-weight: 700; font-size: 16px; line-height: 1.25; }
.global-line { font-family: var(--f-mono); font-size: 11px; color: var(--shelf-mute); }
/* Room for "×999", so every band's text column is the same width. */
.global-count {
  font-family: var(--f-mono); color: var(--shelf-mute); font-variant-numeric: tabular-nums; text-align: right;
}
.global-wins {
  display: flex; flex-direction: column; gap: 8px; list-style: none;
  margin: 14px 0 0; padding: 12px 0 0; border-top: 1px solid var(--shelf-mute);
  font-family: var(--f-mono); font-size: 12px;
}
.global-wins li { display: flex; flex-direction: column; gap: 2px; }
.global-shared { color: var(--shelf-mute); }
.global-trophy .flair-toggle { color: var(--shelf-mute); }
.global-trophy .flair-toggle.is-on, .global-trophy .flair-hint { color: var(--shelf-ink); }
.global-trophy .flair-box { background: transparent; border-color: var(--shelf-mute); }

/* Pick flair on the trophy itself: a submit button styled as a checkbox, no JS. */
.flair-pick { margin: 10px 0 0; }
.flair-toggle {
  display: flex; align-items: center; gap: 7px;
  padding: 0; border: 0; background: none; cursor: pointer;
  font-family: var(--f-body); font-size: 12px; color: var(--ink-mute);
}
.flair-box {
  flex: none; width: 14px; height: 14px;
  border: 1.5px solid var(--line); border-radius: 4px;
  background: var(--surface);
}
.flair-toggle.is-on { color: var(--ink); font-weight: 600; }
/* Only on the worn one, and quieter than the label it follows. */
.flair-hint { color: var(--ink-mute); font-weight: 400; }
.flair-toggle.is-on .flair-box {
  border-color: var(--tier-color, var(--accent));
  background: var(--tier-color, var(--accent));
  /* The same drawn tick the tickets use, cut from the box. */
  clip-path: polygon(
    14% 46%, 0 60%, 38% 100%, 100% 26%, 86% 12%, 38% 72%
  );
  border-radius: 0;
}
@media (hover: hover) {
  .flair-toggle:hover .flair-box { border-color: var(--accent); }
}

/* Your profile's team menu, above the trophy case's flair toggles. */
.team-flair-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0 0 14px; }
.team-flair-form label { font-weight: 600; font-size: 14px; }
.team-flair-form select { min-width: 0; max-width: 100%; }

/* A team worn as flair: the ticket's badge at the stamp's size, on the name's baseline. */
.team-badge.is-flair {
  min-width: 0; padding: 0.08em 0.32em; margin-right: 0.3em;
  border-width: 0.1em; border-radius: 0.28em;
  font-size: 0.64em; line-height: 1.15; letter-spacing: .02em; vertical-align: 0.12em;
}

/* Stamp: the inline mark beside a username. Keeps only shape and tier color.
   Sized in em and sitting on the baseline, so it fits every size a name is set at. */
.trophy-object.is-stamp {
  display: inline-block; vertical-align: baseline; margin-right: 0.28em;
}
.trophy-object.is-stamp .trophy-body {
  width: 0.92em; height: 0.92em; padding: 0; gap: 0;
  border-width: 0.13em;
}
.trophy-object.is-stamp.is-plaque .trophy-body {
  width: 0.78em; height: 0.98em;
  /* Percentages, not pixels, so the chamfer scales with the box. */
  clip-path: polygon(22% 0, 78% 0, 100% 17%, 100% 100%, 0 100%, 0 17%);
}
.trophy-object.is-stamp.is-plaque .trophy-body::before {
  inset: 0.11em;
  clip-path: polygon(20% 0, 80% 0, 100% 15%, 100% 100%, 0 100%, 0 15%);
}
/* Nothing inside survives at this size. */
.trophy-object.is-stamp .trophy-plate { border: 0; background: none; width: auto; }
.trophy-object.is-stamp .trophy-plate.is-rarity,
.trophy-object.is-stamp .trophy-stars { display: none; }
.trophy-object.is-stamp .trophy-monogram { font-size: 0.62em; }

/* Rarity stars in two rows (1, 2, 1+2, 2+2, 2+3) so each count has its own silhouette. */
.trophy-stars {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
}
.star-row { display: flex; gap: 1.5px; line-height: 0; }
.star-row i {
  /* 7px: a ten-point polygon reads as a dot below about six. */
  display: block; width: 7px; height: 7px;
  background: var(--tier-color, var(--ink-mute));
  clip-path: polygon(
    50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
    50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%
  );
}
/* Unearned stars still show the difficulty. */
.trophy-object.is-unearned .star-row i { background: var(--line); }

.trophy-chip summary {
  list-style: none;
}
.trophy-chip summary::-webkit-details-marker { display: none; }

.trophy-summary-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.trophy-summary-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.trophy-name {
  display: block;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 15px;
}
.trophy-count {
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--ink-mute);
  align-self: flex-start;
}
.trophy-description {
  font-size: 13px;
  color: var(--ink-mute);
  margin: 2px 0 0;
}

.trophy-holes {
  display: flex;
  gap: 7px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1.5px dashed var(--line);
  align-items: center;
}
.trophy-holes .hole {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid var(--line);
  background: var(--ground);
}
.trophy-holes .hole.filled {
  border-color: var(--tier-color);
  background: var(--tier-color);
  box-shadow: inset 0 0 0 2px var(--surface);
}
.trophy-holes .tier-word {
  margin-left: auto;
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tier-color);
}

.trophy-award-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 12px 0 0;
  border-top: 1.5px dashed var(--line);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.trophy-award-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
}
.trophy-award-list .when { color: var(--ink); }
.trophy-award-list .when a,
.trophy-award-list .note a {
  color: inherit;
  text-decoration: none;
}
.trophy-award-list .note {
  font-family: var(--f-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
  font-size: 12px;
}

.season-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.season-links li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 13.5px;
}

.standings-link { font-size: 13px; font-weight: 600; text-decoration: none; }
.standings-link::after { content: " \2192"; }

.empty-season {
  background: var(--surface); border-radius: 14px; padding: 16px; margin: 10px 0 4px;
  font-size: 13.5px; color: var(--ink-mute);
}
.empty-season p { margin: 0 0 8px; }
.empty-season p:last-child { margin-bottom: 0; }

/* The way into a season you haven't joined, marker-edged so it's the first thing you see. */
.join-prompt {
  background: var(--surface); border-radius: 14px; padding: 16px; margin: 10px 0 14px;
  border-left: 3px solid var(--marker);
}
.join-prompt-head { margin: 0 0 6px; font-size: 14.5px; font-weight: 700; color: var(--ink); }
.join-prompt-body { margin: 0; font-size: 13px; color: var(--ink-mute); }
.join-prompt .submit-row { margin-bottom: 0; }


.field-row { margin-bottom: 12px; }
.field-row label { display: block; font-size: 12.5px; font-weight: 600; color: var(--ink-mute); margin-bottom: 4px; }
.field-row input, .field-row select {
  width: 100%; font: inherit; font-size: 14px; padding: 9px 10px;
  border: 1.5px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--ink);
}
.field-row-check { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.field-row-check label { font-size: 13.5px; font-weight: 600; margin: 0; }
.pick-block-help { font-size: 12.5px; color: var(--ink-mute); margin: 10px 0 12px; }


/* Phones. Only the few things that are worst at 430px and below; no wholesale re-layout. */
@media (max-width: 430px) {
  /* 8px back for content, on the page and the header. */
  .page { padding-left: 12px; padding-right: 12px; }
  .site-header { padding-left: 12px; padding-right: 12px; }

  .detail-hero-stub { padding-left: 6px; padding-right: 6px; }

  /* Wraps instead of truncating, so "(International)" stays visible. */
  .ticket-venue { white-space: normal; overflow: visible; text-overflow: clip; }

  /* Smaller once the column is narrower. */
  .screen-head h1 { font-size: 23px; }
}

/* Diamond glint (docs/DESIGN.md, Motion): a brief flash, only with motion allowed. */
.glint {
  position: absolute;
  width: 30px;
  height: 30px;
  opacity: .6;
  pointer-events: none;
  transform: rotate(var(--rot, 0deg));
  filter: drop-shadow(0 0 5px var(--tier-diamond, #2FA8E0));
}
.glint::before,
.glint::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  background: linear-gradient(90deg, transparent, #2FA8E0 30%, #FFFFFF 50%, #2FA8E0 70%, transparent);
}
.glint::before { width: 30px; height: 3.5px; transform: translate(-50%, -50%); }
.glint::after  { width: 3.5px; height: 30px; transform: translate(-50%, -50%); }

.glint.g1 { top: -12px; right: 26px; --rot: 6deg; }
.glint.g2 { top: 4px; right: -12px; width: 22px; height: 22px; --rot: -12deg; }
.glint.g2::before { width: 22px; }
.glint.g2::after  { height: 22px; }
.glint.g3 { bottom: -11px; right: 58px; width: 20px; height: 20px; --rot: 20deg; }
.glint.g3::before { width: 20px; }
.glint.g3::after  { height: 20px; }
.glint.g4 { top: 32%; left: -12px; --rot: -8deg; }

@media (prefers-reduced-motion: no-preference) {
  .glint { animation: glint-flash 4.8s ease-in-out infinite; }
  .glint.g1 { animation-delay: 0s; }
  .glint.g2 { animation-delay: 1.2s; }
  .glint.g3 { animation-delay: 2.4s; }
  .glint.g4 { animation-delay: 3.6s; }
}

@keyframes glint-flash {
  0%   { opacity: .15; transform: rotate(var(--rot, 0deg)) scale(.5); }
  18%  { opacity: 1;   transform: rotate(var(--rot, 0deg)) scale(1.15); }
  30%  { opacity: 1;   transform: rotate(var(--rot, 0deg)) scale(1.05); }
  45%  { opacity: .2;  transform: rotate(var(--rot, 0deg)) scale(.6); }
  100% { opacity: .15; transform: rotate(var(--rot, 0deg)) scale(.5); }
}

.theme-toggle {
  background: none;
  border: 1.5px solid var(--line);
  border-radius: 999px;
  padding: 4px 10px;
  font: inherit;
  font-family: var(--f-body);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-mute);
  cursor: pointer;
  margin-left: 10px;
}
.theme-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.team-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 3px 10px;
  border-radius: 6px;
  border: 2px solid;
  font-family: var(--f-display);
  min-width: 4.2em;
}

.line-lock-note {
  font-family: var(--f-body);
  font-size: 12px;
  color: var(--ink-mute);
  margin: 0 0 10px;
}

/* No box or divider, so it reads as commentary on the ticket above. Just spacing. */
.insights-panel {
  padding: 10px 0 0;
  margin: 10px 0 0;
}
.insights-heading {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--f-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-mute); margin: 0 0 8px;
}
.insights-heading:not(:first-child) { margin-top: 12px; }
.insight-line {
  font-size: 13px; margin: 0 0 6px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.insight-line:last-child { margin-bottom: 0; }
.insight-line-muted { color: var(--ink-mute); font-size: 12px; }
.insights-more { font-size: 13px; font-weight: 600; margin: 12px 0 0; }
/* Rest as a heading over one row per team, so the two sides can't wrap into each other. */
/* Room below, so the next insight's badge doesn't read as a third row here. */
.insight-rest { margin: 0 0 12px; }
.insight-rest-head {
  font-size: 13px; margin: 0 0 4px;
  display: flex; align-items: center; gap: 6px;
}
/* Badge, rest condition, record; shared columns so both teams line up. */
.insight-rest-rows {
  display: grid; grid-template-columns: auto auto 1fr;
  gap: 5px 10px; align-items: center;
  /* Indented under its heading. */
  padding-left: 10px;
  font-size: 12.5px; color: var(--ink-mute);
}
.insight-rest-side { display: contents; }
.insight-rest-days { font-family: var(--f-mono); font-size: 11.5px; letter-spacing: .04em; }
.insight-rest-rows b {
  color: var(--ink); font-weight: 700;
  font-family: var(--f-mono); font-variant-numeric: tabular-nums;
}


/* One row per team, badge in a fixed column, so the numbers line up. */
/* font-size matches .insight-line so the badge matches the head-to-head badge. */
.team-form { display: grid; grid-template-columns: auto 1fr; gap: 6px 10px; align-items: center; margin-top: 10px; font-size: 13px; }
.team-form-row { display: contents; }
.team-form-stats { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; font-size: 12.5px; color: var(--ink-mute); }
.team-form-stat b { color: var(--ink); font-weight: 700; font-family: var(--f-mono); font-variant-numeric: tabular-nums; margin-left: 3px; }
/* Marks the row's figures as ATS; straight-up leagues show nothing. */
.team-form-mode {
  font-family: var(--f-mono); font-size: 9.5px; letter-spacing: .08em;
  color: var(--ink-mute); border: 1px solid var(--line); border-radius: 4px;
  padding: 1px 4px; line-height: 1.4;
}

/* Stats program: the dashboard set as a printed game program, scoped under .program so the
   shared classes elsewhere are untouched. No section numbers. */
.program-masthead {
  padding: 2px 0 14px;
  border-bottom: 4px double var(--line);
  margin-bottom: 6px;
}
.program-eyebrow {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--ink-mute); margin: 0 0 6px;
}
.program-masthead h1 {
  font-family: var(--f-display); font-weight: 700; font-size: 30px;
  letter-spacing: .01em; line-height: 1.05; margin: 0;
}
.program-edition {
  font-family: var(--f-mono); font-size: 11px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-mute); margin: 8px 0 0;
  font-variant-numeric: tabular-nums;
}

/* Which edition you're reading: two sides of the same sheet. */
.program-reading {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 3px 12px;
  margin: 12px 0 4px;
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .12em;
  text-transform: uppercase;
}
.program-reading-label { color: var(--ink-mute); }
.program-edition-btn {
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  background: none; border: 0; padding: 2px 0; cursor: pointer;
  color: var(--ink-mute); border-bottom: 2px solid transparent;
}
.program-edition-btn.is-active { color: var(--ink); border-bottom-color: var(--accent-2); }
.program-edition-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Standing head: label, then a rule running out to the margin. */
.program-head {
  display: flex; align-items: center; gap: 10px;
  font-family: var(--f-display); font-weight: 700; font-size: 14px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink);
  margin: 30px 0 11px;
}
.program-head::after {
  content: ""; flex: 1 1 auto;
  border-top: 2px solid var(--ink); opacity: .22;
}
.program-note {
  font-size: 12px; color: var(--ink-mute); margin: -4px 0 12px; line-height: 1.45;
}

/* Dot leaders from the container's ::after, placed between the two spans. */
.program-lines { display: flex; flex-direction: column; gap: 9px; margin: 0 0 20px; font-size: 13px; }
.program-line { display: flex; align-items: baseline; }
.program-line .k { order: 1; flex: none; color: var(--ink-mute); }
.program-line::after {
  content: ""; order: 2; flex: 1 1 auto; min-width: 14px;
  margin: 0 7px 4px; border-bottom: 1px dotted var(--line);
}
.program-line .v {
  order: 3; flex: none;
  font-family: var(--f-mono); font-weight: 600; font-variant-numeric: tabular-nums;
}

/* Right-aligned figures, left labels, hairlines between rows only. */
.program-table-wrap { overflow-x: auto; margin: 0 0 22px; }
.program-table {
  border-collapse: collapse; width: 100%;
  font-family: var(--f-mono); font-size: 12px; font-variant-numeric: tabular-nums;
}
.program-table thead th {
  font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-mute); font-weight: 700; white-space: nowrap;
  text-align: right; padding: 0 0 7px 14px;
  border-bottom: 1.5px solid var(--line);
}
.program-table thead th:first-child { text-align: left; padding-left: 0; }
.program-table tbody th {
  text-align: left; font-weight: 400; color: var(--ink-mute);
  padding: 7px 14px 7px 0; white-space: nowrap;
}
.program-table tbody td { text-align: right; padding: 7px 0 7px 14px; white-space: nowrap; }
.program-table tbody tr + tr th,
.program-table tbody tr + tr td { border-top: 1px dotted var(--line); }

/* Streak leaders are numbered; the order is the information. */
.program-ranks { list-style: none; margin: 0 0 20px; padding: 0; font-size: 12.5px; }
.program-ranks li {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 0; border-bottom: 1px dotted var(--line);
}
.program-ranks li:last-child { border-bottom: 0; }
.program-rank {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: .08em;
  color: var(--ink-mute); flex: none; min-width: 2.4em;
}
.program-ranks .who { flex: 1 1 auto; }
.program-ranks .len {
  font-family: var(--f-mono); font-weight: 700; font-variant-numeric: tabular-nums; flex: none;
}
.program-subhead {
  font-family: var(--f-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-mute); margin: 16px 0 6px;
}

.program-colophon {
  margin-top: 30px; padding-top: 12px; border-top: 1px solid var(--line);
  font-family: var(--f-mono); font-size: 10px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-mute); line-height: 1.7;
}

/* The program as a bound page: ticket paper, lift and frame, no chamfers or scallops.
   The left edge is the spine the turn pivots on. */
.program-page {
  position: relative;
  background: var(--paper);
  box-shadow: var(--paper-lift);
  padding: 20px 18px 22px 22px;
  margin: 4px 0 8px;
}
.program-page::before {
  content: '';
  position: absolute; inset: 6px 6px 6px 10px;
  border: 2px solid var(--ink);
  opacity: .22;
  pointer-events: none;
}
/* Bound edge: a double rule down the spine side. */
.program-page::after {
  content: '';
  position: absolute; top: 0; bottom: 0; left: 4px;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  width: 3px;
  pointer-events: none;
}
.program-page > :first-child { margin-top: 0; }
.program-page > :last-child { margin-bottom: 0; }

/* The eyebrow carries the masthead. */
.program-eyebrow {
  font-size: 12px;
  letter-spacing: .32em;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 8px;
}

/* Editions read as two tabs. */
.program-reading { gap: 3px 18px; margin: 14px 0 2px; font-size: 11px; }

/* Switch between the ticket and the sheet, as a wide, obvious target. */
.view-switch {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin: 12px 0 4px;
  padding: 10px 14px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  text-decoration: none;
  color: var(--ink);
}
.view-switch:hover { border-color: var(--accent); }
.view-switch-label { font-family: var(--f-display); font-weight: 700; font-size: 14px; }
.view-switch-label::after { content: " \2192"; color: var(--accent); }
/* Going back to the tickets: the arrow leads. */
.view-switch.is-back .view-switch-label::after { content: none; }
/* \00a0 because a trailing space in `content` collapses. */
.view-switch.is-back .view-switch-label::before { content: "\2190\00a0"; color: var(--accent); }
.view-switch-note {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .04em;
  color: var(--ink-mute); text-align: right;
}

/* Pick sheet rows: [ yours live | AWAY | @ | HOME | live yours ], then the rank and result.
   The live line gets marked; the outer spot shows a held line. The badges never shift. */
.sheet-row {
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px;
}
.sheet-row.has-error { border-bottom-color: var(--loss); }
/* The row's top line links to the game, in a lighter version of the ticket's tinted strip. */
.sheet-row-kickoff {
  flex-basis: 100%;
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .08em;
  color: var(--ink-mute);
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  text-decoration: none;
  margin: -1px -6px 1px; padding: 3px 6px 4px;
  border-radius: 5px;
}
/* The date truncates first, like the ticket. */
.sheet-row-kickoff > span:first-child {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sheet-row-end { flex: none; display: inline-flex; align-items: baseline; gap: 2px; }
/* The status keeps its own color. */
.sheet-live { color: var(--accent-2-text); }
.sheet-row-arrow { transition: transform .12s ease; }
@media (hover: hover) {
  a.sheet-row-kickoff:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
  a.sheet-row-kickoff:hover .sheet-row-arrow { transform: translateX(2px); }
}
a.sheet-row-kickoff:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .sheet-row-arrow { transition: none; }
}
.sheet-matchup {
  /* Basis 0, so a long side wraps nothing until the row truly hasn't room. */
  flex: 1 1 0;
  display: grid;
  /* The sides split what the badges and @ leave equally, so the badges sit in the same place
     on every row whatever lines, held lines or Take a side shows. */
  grid-template-columns: 1fr max-content max-content max-content 1fr;
  align-items: center;
  gap: 4px;
  font-size: 13px;
}
.sheet-side { display: flex; align-items: center; gap: 4px; }
.sheet-side.is-away { justify-content: flex-end; }
.sheet-at { color: var(--ink-mute); font-size: 12px; text-align: center; }

.sheet-line,
.sheet-yours {
  font-family: var(--f-mono); font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}
/* Live lines hug the badges; held lines sit just outside them. */
.sheet-side.is-away .sheet-yours { text-align: right; align-items: flex-end; }
.sheet-side.is-home .sheet-yours { text-align: left; align-items: flex-start; }

/* Selected: the live line you're on. */
.sheet-line.is-selected { color: var(--ink); font-weight: 700; }
/* Taking it: the line you'd lock if you saved now, in --win. */
.sheet-line.is-taking { color: var(--win); font-weight: 700; }
/* Under a row whose line moved your way: the Take chip and what it beats, centered as in the
   app. It only applies while the pick is on that side, and goes once the new line is held. */
.sheet-take-row {
  flex-basis: 100%;
  display: flex; justify-content: center; align-items: center; gap: 8px;
}
.sheet-take-row:has(.sheet-take:not(.is-selected)) { opacity: .4; }
.sheet-take-row:has(.sheet-take.is-held) { display: none; }
.sheet-take { position: relative; cursor: pointer; }
.sheet-take-chip { padding: 2px 7px; font-size: 11px; }
.sheet-take:not(.is-selected) { pointer-events: none; }
.sheet-take-note { font-size: 12.5px; color: var(--ink-mute); }
/* Hidden whether taken or not; iOS Safari otherwise paints the native checkbox. */
.sheet-line input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  -webkit-appearance: none; appearance: none; background: transparent;
}

/* The line you hold, struck and dimmed once you give it up. Captioned "yours". */
.sheet-yours { display: inline-flex; flex-direction: column; line-height: 1.15; }
.sheet-yours-value { font-weight: 600; color: var(--ink); }
.sheet-yours-tag {
  font-size: 8.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-mute); opacity: .8;
}
.sheet-yours.is-dropped .sheet-yours-value {
  text-decoration: line-through;
  color: var(--ink-mute);
  opacity: .7;
  font-weight: 400;
}
.sheet-yours.is-dropped .sheet-yours-tag { opacity: .45; }

.sheet-team { display: inline-flex; cursor: pointer; opacity: .42; transition: opacity .12s ease; }
.sheet-team.is-picked { opacity: 1; }
.sheet-team input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.sheet-team:has(input:focus-visible) .team-badge {
  outline: 2px solid var(--accent); outline-offset: 2px;
}
@media (hover: hover) {
  .sheet-team:hover { opacity: .75; }
  .sheet-team.is-picked:hover { opacity: 1; }
}

/* The rank's slot and the result's (see .sheet-slot), the same width on every row. */
.sheet-row-control {
  flex: none; display: flex; align-items: center; gap: 7px;
}
/* A phone has no room for a stepper beside the matchup, so while a week has steppers every
   row's controls take a line of their own, at the right. */
@media (max-width: 480px) {
  .has-steppers .sheet-row-control { flex-basis: 100%; justify-content: flex-end; }
}
/* A changed rank is marked like a taken line: not saved yet. */
.confidence-stepper.is-changed .confidence-input {
  color: var(--win); font-weight: 700; border-color: var(--win);
}
.sheet-row-errors {
  flex-basis: 100%; font-size: 12.5px; color: var(--loss); font-weight: 600;
}
.sheet-row-errors p { margin: 0; }

/* Someone else's week (player_week.html): their name, then the week, over read-only rows. */
.player-week-name { margin-bottom: 2px; }
/* A sheet's rank and result slots. Each stacks what it holds in one cell, and the result's
   hidden sizer holds every result and Clear, so the slot is as wide as the widest. */
.sheet-slot { display: inline-grid; align-items: center; justify-items: start; min-height: 22px; }
.sheet-slot > *, .sheet-result-sizer > * { grid-area: 1 / 1; }
.sheet-rank-slot { min-width: 26px; justify-items: center; }
/* As wide as the stepper: two 26px buttons and a 34px box, 10px apart. */
.sheet-rank-slot.holds-stepper { min-width: 106px; }
.sheet-result-sizer { display: grid; visibility: hidden; }
/* Before kickoff: a lock where they've picked, an empty box where they haven't. */
.sheet-placeholder {
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); border-radius: 6px;
  color: var(--ink-mute);
}
.sheet-rank-slot .sheet-placeholder { width: 22px; height: 22px; }
.sheet-result-slot .sheet-placeholder { align-self: stretch; justify-self: stretch; }
.lock-icon { width: 9px; height: 10.5px; }
.player-week-of {
  margin: 0 0 10px; font-family: var(--f-mono); font-size: 12px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-mute);
}
/* A profile's links to their current weeks in the leagues you share. */
.player-weeks { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.player-weeks a { font-weight: 600; color: var(--accent); text-decoration: none; }
.player-weeks a:hover { text-decoration: underline; }

/* Ranking on the ticket, under the game's stats. */
.confidence-rank {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px;
  margin-top: 10px;
}
.confidence-rank-label {
  font-family: var(--f-mono); font-size: 10.5px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-mute);
}
.confidence-rank.has-error .confidence-input { border-color: var(--loss); }
.confidence-rank-errors {
  flex-basis: 100%; font-size: 12.5px; color: var(--loss); font-weight: 600;
}
.confidence-rank-errors p { margin: 0; }

/* The Everyone boards: the caption, your rank card or why you're not on it, and the pages. */
.everyone-caption { margin: -8px 0 0; color: var(--ink-mute); font-size: 13.5px; }
.everyone-card {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0 0 14px; padding: 14px 16px;
  background: var(--paper); border-radius: 8px; box-shadow: var(--paper-lift);
  color: var(--ink); text-decoration: none;
}
a.everyone-card:hover { box-shadow: var(--paper-lift-hover); }
.everyone-card-place, .everyone-card-figures { display: flex; flex-direction: column; gap: 2px; }
.everyone-card-figures { align-items: flex-end; }
.everyone-card-title { font-size: 13px; color: var(--ink-mute); }
.everyone-card-rank { font-family: var(--f-display); font-weight: 700; font-size: 30px; line-height: 1; }
.everyone-card-rank small { font-size: 18px; color: var(--ink-mute); }
.everyone-card-stat { font-family: var(--f-mono); font-weight: 700; font-size: 18px; }
.everyone-card-stat small { font-size: 12px; font-weight: 400; color: var(--ink-mute); }
.everyone-card-standing { font-family: var(--f-mono); font-size: 11px; color: var(--ink-mute); }
.everyone-note { margin: 0 0 14px; color: var(--ink-mute); font-size: 13.5px; }
.everyone-pages {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0 0 24px; font-size: 14px;
}
.everyone-pages a { display: inline-flex; align-items: center; min-height: 44px; font-weight: 600; }
.everyone-pages span:not(:empty) { font-family: var(--f-mono); font-size: 12px; color: var(--ink-mute); }

/* The standings switch: the league's board or Everyone, and Points or Record within Everyone. */
.pill-switch {
  display: flex; gap: 4px; margin: 0 0 8px; padding: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
}
.pill-switch a {
  flex: 1; min-width: 0; min-height: 36px; padding: 0 12px;
  border-radius: 999px; color: var(--ink-mute); font-size: 13px; font-weight: 600;
  line-height: 36px; text-align: center; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pill-switch a[aria-current="true"] { background: var(--accent); color: var(--accent-text); }
.pill-switch a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pill-switch.is-small { max-width: 240px; }
.pill-switch.is-small a { min-height: 30px; line-height: 30px; font-size: 12.5px; }
.standings-switchable .everyone-caption { margin: 0 0 12px; padding: 0 6px; }
.everyone-all { margin: -12px 0 24px; text-align: center; }
.everyone-all a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px; font-weight: 600; font-size: 14px; }

/* Wins by Week (season_graph.html): the chart beside its players, which wrap under it on a phone. */
.standings-links { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.graph-choice {
  display: inline-grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px;
  margin: 0 0 16px; padding: 3px; border-radius: 10px; background: var(--surface-2);
}
.graph-choice-button {
  min-height: 40px; padding: 0 18px; border: 0; border-radius: 8px; background: transparent;
  font: inherit; font-weight: 600; font-size: 14px; color: var(--ink-mute); cursor: pointer;
}
.graph-choice-button[aria-pressed="true"] { background: var(--surface); color: var(--accent); box-shadow: 0 1px 3px rgba(0, 0, 0, .18); }
.graph-layout { display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start; margin-bottom: 24px; }
.graph-card { background: var(--surface); border-radius: 12px; box-shadow: var(--paper-lift); padding: 14px 16px; }
.graph-chart-card { flex: 999 1 560px; min-width: 0; }
.graph-list { flex: 1 1 260px; min-width: 0; padding-top: 4px; }
.graph-chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.graph-chart [hidden] { display: none; }
.graph-grid { stroke: var(--surface-2); stroke-width: 1; }
.graph-axis { font-family: var(--f-mono); font-size: 12px; fill: var(--ink-mute); }
.graph-line path { fill: none; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.graph-line.is-default path { stroke: var(--ink); }
.graph-line.is-default circle, .graph-line.is-default .graph-end { fill: var(--ink); }
.graph-end { font-family: var(--f-mono); font-size: 12px; font-weight: 600; }
/* On a phone the drawing shrinks to half size, so its words and dots grow to stay readable. */
@media (max-width: 600px) {
  .graph-axis, .graph-end { font-size: 22px; }
  .graph-line circle { r: 6; }
  .graph-line.is-you circle { r: 9; }
}
.graph-caption, .graph-note { margin: 10px 2px 0; font-size: 13px; color: var(--ink-mute); }
/* Fixed columns, so a hidden line's row keeps its shape. */
.graph-row {
  display: grid; grid-template-columns: 40px 18px minmax(0, 1fr) 10ch; align-items: center; gap: 8px;
  width: 100%; min-height: 44px; padding: 0; border: 0; border-bottom: 1px solid var(--surface-2);
  background: none; font: inherit; color: var(--ink); text-align: left; cursor: pointer;
}
.graph-rank { font-weight: 700; color: var(--ink-mute); font-size: 14px; white-space: nowrap; }
.graph-swatch { --swatch: var(--ink); width: 14px; height: 14px; box-sizing: border-box; border-radius: 4px; border: 2px solid var(--swatch); background: var(--swatch); }
.graph-swatch.is-default { --swatch: var(--ink); }
.graph-name { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.graph-row.is-you .graph-name { font-weight: 700; }
.graph-record { font-family: var(--f-mono); font-size: 13px; text-align: right; }
.graph-row[aria-pressed="false"] .graph-swatch { background: transparent; }
.graph-row[aria-pressed="false"] .graph-name, .graph-row[aria-pressed="false"] .graph-record { color: var(--ink-mute); }
