/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

:root {
  color-scheme: dark light;
  --bg: #111418;
  --surface: #1a1e24;
  --text: #e8eaed;
  --text-dim: #9aa4b2;
  --accent: #22b573;
  --border: #2a2f37;
  --danger: #ff6b6b;
  --warning: #ffd23f;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  padding-bottom: 4.5rem; /* room for the fixed bottom nav */
}

.app-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}

.app-header__brand {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 700;
}

.app-header__crown {
  width: 1.1rem;
  height: 1.1rem;
}

.app-header__account {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--text-dim);
  text-decoration: none;
}

.app-header__account strong {
  color: var(--text);
}

.role-badge {
  text-transform: uppercase;
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  padding: 0.15rem 0.4rem;
  border-radius: 0.25rem;
  background: var(--border);
  color: var(--text);
}

.role-badge--admin {
  background: var(--accent);
  color: #fff;
}

.app-main {
  max-width: 40rem;
  margin: 0 auto;
  padding: 1rem;
}

.flash {
  padding: 0.6rem 0.9rem;
  border-radius: 0.4rem;
  margin: 0 0 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
}

.flash--alert {
  border-color: var(--danger);
  color: var(--danger);
}

.flash--warning {
  border-color: var(--warning);
  color: var(--warning);
}

.button,
.link-button {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 0.4rem;
  padding: 0.6rem 1rem;
  font-size: 1rem;
  text-decoration: none;
  cursor: pointer;
}

.link-button {
  background: transparent;
  color: var(--text-dim);
  padding: 0;
  font-size: 0.85rem;
  text-decoration: underline;
}

.sign-in {
  min-height: 80vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  text-align: center;
}

/* Shared by the sign-in screen and the landing page -- same brand
   lockup (crown + wordmark), each page just sets its own bottom margin. */
.brand-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-size: 2.25rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: -0.02em;
}

/* Sized under the title's own line-height so the crown rides alongside
   the text instead of stretching the header row to fit it. */
.brand-crown {
  width: 2.1rem;
  height: 2.1rem;
  flex-shrink: 0;
}

.sign-in__title {
  margin: 0 0 3rem;
}

/* The one button on the page that's deliberately not .button's solid-accent
   fill (2025 app's card-button treatment) -- a dark bordered pill that
   lifts and picks up the accent color on hover, carrying the real Google
   "G" instead of a plain label. */
.button--google {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  min-width: 12.5rem;
  padding: 0.875rem 1.5rem;
  border: 2px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
  color: var(--text);
  font-size: 1rem;
  font-weight: 500;
  text-decoration: none;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.button--google:hover {
  background: color-mix(in srgb, var(--surface) 100%, white 8%);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.button--google:active {
  transform: translateY(0);
}

.button--google__icon {
  flex-shrink: 0;
}

.marketing {
  margin: 0 auto;
  padding: 3rem 0;
}

.marketing__hero {
  text-align: center;
  margin-bottom: 2.5rem;
}

.marketing__title {
  margin: 0 0 0.5rem;
}

.marketing__tagline {
  color: var(--text-dim);
  font-size: 1.1rem;
  margin: 0;
}

.marketing__section {
  margin-bottom: 2rem;
}

.marketing__section h2 {
  font-size: 1rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin: 0 0 0.5rem;
}

.marketing__section p {
  line-height: 1.6;
  margin: 0;
}

/* Landing page's What/How/Why: even vertical rhythm between whatever mix
   of paragraph, diagram, and example board a section holds. */
.marketing__section--intro {
  margin-bottom: 2.75rem;
}

/* Beats .marketing__section p's margin: 0 (same specificity would lose
   the tiebreak to source order otherwise). */
.marketing__section.marketing__section--intro > * + * {
  margin-top: 1.25rem;
}

.marketing__cta {
  text-align: center;
  margin-top: 2.5rem;
}

.marketing__cta .button {
  padding: 0.875rem 2rem;
  font-size: 1.05rem;
  border-radius: 0.75rem;
}

/* The top-of-page CTA -- same green .button, just louder than the
   closing one so it reads as the primary action, not a repeat of it. */
.marketing__cta--top {
  margin-top: 0;
  margin-bottom: 2.75rem;
}

.marketing__cta--top .button {
  padding: 1.1rem 2.75rem;
  font-size: 1.25rem;
  border-radius: 0.85rem;
}

/* Season archives' entry point on the landing page -- a bordered card
   (same language as .marketing__season-card) instead of a small dim
   link, kept last on the page since it's the secondary path. */
.marketing__archive-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.marketing__archive-link:hover {
  border-color: var(--accent);
}

.marketing__archive-link-body {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.marketing__archive-link-title {
  font-weight: 600;
}

.marketing__archive-link-sub {
  color: var(--text-dim);
  font-size: 0.85rem;
}

.marketing__archive-link-arrow {
  color: var(--text-dim);
  font-size: 1.2rem;
  flex-shrink: 0;
}

.marketing--wide {
  max-width: 42rem;
}

.marketing__eyebrow {
  margin: 0 0 1rem;
}

.marketing__eyebrow a {
  color: var(--text-dim);
  font-size: 0.9rem;
  text-decoration: none;
}

.marketing__season-disclaimer {
  color: var(--text-dim);
  font-size: 0.9rem;
  line-height: 1.6;
  margin: 0 0 2rem;
}

.marketing__table-wrap {
  overflow-x: auto;
}

.marketing__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.marketing__table th,
.marketing__table td {
  padding: 0.6rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.marketing__table th {
  color: var(--text-dim);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}

.marketing__table--standings tr:first-child td {
  color: var(--accent);
  font-weight: 600;
}

/* Truncates the name with an ellipsis instead of forcing the whole
   standings table wider than a phone screen -- Score stays on-screen
   without side-scrolling. */
.marketing__table td.marketing__table-player {
  max-width: 6.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Rk only ever holds a single digit -- give Player the room instead. */
.marketing__table-rank {
  width: 1.4rem;
  padding-right: 0.35rem;
}

.marketing__net {
  font-variant-numeric: tabular-nums;
}

.marketing__net--top {
  color: var(--accent);
  font-weight: 600;
}

@media (max-width: 30rem) {
  .marketing__table--weekly .marketing__net {
    font-size: 0.8rem;
  }
}

.marketing__swatch {
  display: inline-block;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  margin-right: 0.5rem;
}

/* Season archives index */
.marketing__season-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.marketing__season-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.marketing__season-card:hover {
  border-color: var(--accent);
}

.marketing__season-card-year {
  color: var(--text);
  font-weight: 600;
  font-size: 1.1rem;
}

/* Charts (season recap) */
.marketing__section--charts {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
}

.marketing__figure {
  margin: 0;
}

.marketing__figure-caption {
  color: var(--text-dim);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 0.75rem;
}

.marketing__chart {
  width: 100%;
  height: auto;
  overflow: visible;
}

.marketing__chart-value,
.marketing__chart-tick {
  fill: var(--text-dim);
  font-size: 12px;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

.marketing__chart-value {
  fill: var(--text);
}

.marketing__chart-gridline {
  stroke: var(--border);
  stroke-width: 1;
}

.marketing__chart-leader {
  stroke: var(--text-dim);
  stroke-width: 1;
}

.marketing__table-toggle {
  margin-top: 1rem;
}

.marketing__table-toggle summary {
  color: var(--text-dim);
  font-size: 0.85rem;
  cursor: pointer;
}

.marketing__table-toggle .marketing__table-wrap {
  margin-top: 0.75rem;
}

/* How It Works figures */
.hiw__weight-diagram {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.25rem;
}

.hiw__weight-card {
  flex: 1 1 12rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  background: var(--surface);
}

.hiw__weight-card-title {
  font-weight: 600;
}

.hiw__weight-card-sub {
  color: var(--text-dim);
  font-size: 0.8rem;
}

.hiw__weight-bar {
  display: flex;
  gap: 2px;
  height: 2.5rem;
}

/* Same fill/border/shadow recipe as shared/_chip's tiers (--chip-color /
   --chip-shadow), just stretched into a proportional bar instead of a
   fixed badge -- the weight diagram should read as the same idea as the
   real slot chip, not its own color scheme. */
.hiw__weight-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--chip-shadow);
  border-radius: 0.25rem;
  background: var(--chip-color);
  color: #14171c;
  font-family: "Courier New", monospace;
  font-weight: 800;
  font-size: 0.9rem;
  letter-spacing: -0.03em;
  box-shadow: 2px 2px 0 var(--chip-shadow), inset 0 -3px 0 rgb(0 0 0 / 0.2);
}

.hiw__weight-slot--full {
  flex: 3;
  --chip-color: #ff2e88;
  --chip-shadow: #c41e68;
}

.hiw__weight-slot--major {
  flex: 2;
  --chip-color: #00d9ff;
  --chip-shadow: #0099b8;
}

.hiw__weight-slot--minor {
  flex: 1;
  --chip-color: #ffb800;
  --chip-shadow: #cc8e00;
}

.hiw__timeline {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.75rem;
}

.hiw__timeline-step {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding-top: 1.5rem;
  border-top: 2px solid var(--border);
}

.hiw__timeline-dot {
  position: absolute;
  top: -5px;
  left: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

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

.hiw__timeline-detail {
  color: var(--text-dim);
  font-size: 0.8rem;
  line-height: 1.4;
}

/* The scoring walkthrough's equation -- the "3×" is shared/_chip, the same
   slot badge the real app uses, not a marketing-only lookalike. */
.hiw__equation {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.65rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
  font-size: 1.15rem;
  font-weight: 600;
}

.hiw__equation-op {
  color: var(--text-dim);
  font-weight: 400;
}

.hiw__equation-result {
  color: var(--accent);
}

/* A major + minor pick's equations sharing one frame -- one grid across
   both rows (each .hiw__equation drops to display: contents and donates
   its five cells to it) so chip/×/value/=/result line up column by
   column instead of each row centering on its own. */
.hiw__equation-group {
  display: grid;
  grid-template-columns: repeat(5, auto);
  justify-content: center;
  justify-items: center;
  align-items: center;
  column-gap: 0.75rem;
  row-gap: 0.5rem;
  padding: 0.65rem;
  border: 1px solid var(--border);
  border-radius: 0.75rem;
}

.hiw__equation-group .hiw__equation {
  display: contents;
}

@media (max-width: 30rem) {
  .hiw__timeline {
    grid-template-columns: 1fr 1fr;
  }
}

.bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom);
}

.bottom-nav__tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  text-align: center;
  padding: 0.6rem 0.25rem;
  color: var(--text-dim);
  text-decoration: none;
}

.bottom-nav__icon {
  width: 1.4rem;
  height: 1.4rem;
}

.bottom-nav__label {
  font-size: 0.65rem;
}

.bottom-nav__tab--active {
  color: var(--accent);
  font-weight: 600;
}

.week-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.week-header h1 {
  font-size: 1.25rem;
  margin: 0;
}

.week-header__nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  color: var(--accent);
  text-decoration: none;
  font-size: 1.75rem;
  line-height: 1;
}

.week-header__nav--disabled {
  color: var(--text-dim);
  opacity: 0.5;
}

.week-header__window {
  color: var(--text-dim);
  font-size: 0.85rem;
  margin: 0.25rem 0 1.5rem;
  text-align: center;
}

.empty-state {
  color: var(--text-dim);
}

.game-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.5rem;
  margin-bottom: 0.75rem;
}

.game-card--voided {
  opacity: 0.6;
}

.game-card__header {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}

.game-card__kickoff {
  font-weight: 400;
  color: var(--text-dim);
  font-size: 0.85rem;
  white-space: nowrap;
}

.game-card__voided-note {
  color: var(--danger);
  margin: 0;
}

.game-card__grid {
  display: grid;
  grid-template-columns: 1fr repeat(3, minmax(3rem, 1fr));
  align-items: center;
  gap: 0.1rem;
}

.game-card__col-label {
  font-size: 0.65rem;
  letter-spacing: 0.03em;
  color: var(--text-dim);
  text-align: center;
}

.game-card__team {
  font-size: 0.8rem;
  font-weight: 600;
}

.market-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1rem;
  width: 100%;
  min-height: 3rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0.4rem;
  padding: 0.3rem 0.2rem;
  color: var(--text);
  font-family: inherit;
  cursor: pointer;
}

.market-btn__price {
  font-size: 0.95rem;
  font-weight: 700;
}

.market-btn__point {
  display: block;
  min-height: 1.1em;
  font-size: 0.75rem;
  color: var(--text-dim);
}

.market-btn--locked {
  opacity: 0.5;
  cursor: default;
}

.market-btn--empty {
  color: var(--text-dim);
}

/* Marks a market as the walkthrough's pick (home/_game's selected_market) --
   full opacity even when also --locked, so it reads as chosen, not dimmed. */
.market-btn.market-btn--selected {
  opacity: 1;
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 18%, var(--bg));
}

.home-header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
}

.home-header h1 {
  font-size: 1.25rem;
  margin: 0;
}

/* M10 #9 -- small, out of the way of the board above it. */
.home-footnote {
  margin-top: 1.75rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 0.8rem;
  text-align: center;
}

.home-footnote a {
  color: var(--text-dim);
}

/* Shield (NFL) / football (NCAAF) glyph (Font Awesome, SportIconHelper),
   prefixing a pick's description everywhere one shows up (board/profile/
   leaderboard's shared pick row, My Picks' slot cards), each game card's
   own header, and the home sport filter where nothing's picked yet. */
.sport-icon {
  margin-right: 0.3em;
  color: var(--text-dim);
  flex: none;
}

/* No description text follows it (the sport filter's icon-only NFL/NCAAF
   buttons) -- the default right margin above assumes text follows and
   otherwise pushes the glyph off-center in its button. */
.sport-icon--standalone {
  margin-right: 0;
}

.sport-icon--win {
  color: #4caf7d;
}

.sport-icon--loss {
  color: var(--danger);
}

.sport-icon--push,
.sport-icon--void {
  color: var(--warning);
}

/* The pick-config modal -- centered on the page (a bottom sheet was tried
   first; feedback was it should sit in the middle), via a native <dialog>'s
   own inset:0 + margin:auto centering rather than fighting it. */
.sheet {
  position: fixed;
  inset: 0;
  margin: auto;
  width: min(92vw, 26rem);
  max-height: 85vh;
  border: none;
  border-radius: 0.75rem;
  padding: 0;
  background: var(--surface);
  color: var(--text);
}

.sheet::backdrop {
  background: rgb(0 0 0 / 0.5);
}

.sheet__content {
  padding: 1.25rem;
  overflow-y: auto;
}

.sheet__label {
  font-weight: 600;
  margin: 0 0 0.75rem;
}

.sheet fieldset {
  border: none;
  padding: 0;
  margin: 0.75rem 0;
}

.sheet legend {
  font-size: 0.75rem;
  color: var(--text-dim);
  padding: 0;
  margin-bottom: 0.4rem;
}

.sheet__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1rem;
  margin-top: 0.75rem;
}

.filter-bar {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.filter-bar__team {
  flex: 1 1 10rem;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.4rem;
  padding: 0.5rem 0.6rem;
  color: var(--text);
  /* iOS Safari auto-zooms on focus for any input under 16px, and never
     zooms back out -- keep this at 1rem to avoid that trap. */
  font-size: 1rem;
}

/* A button-group radio: the label itself is the aesthetic control, a plain
   radio sits underneath (opacity: 0, but real size/position) for native
   form semantics and keyboard/Capybara interaction. Shared by the sport
   filter and the pick dialog's reveal choice, so this pattern lives once. */
.toggle-group {
  display: flex;
  gap: 0.4rem;
}

.toggle-btn {
  position: relative;
}

.toggle-btn__input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.toggle-btn__label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 0.4rem;
  font-size: 0.8rem;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Sport filter only -- its NFL/NCAAF buttons are icon-only, and the icon
   glyph's own line-height doesn't match plain text's, so "All" and the two
   icon buttons came out different heights at the shared padding-driven size
   above. A fixed height fixes that, but it doesn't belong on every
   toggle-group (it made the board's Player/Kickoff sort toggle needlessly
   huge), so it's scoped here instead of on .toggle-btn__label itself. */
.toggle-group--filter .toggle-btn__label {
  height: 2.6rem;
  padding: 0 0.9rem;
  font-size: 0.85rem;
}

/* Outline + text only, no tinted fill -- keeps green meaning one thing in
   the pick dialog (the "Place pick" button, the one solid-green surface)
   instead of also filling every selected pill. */
.toggle-btn__input:checked + .toggle-btn__label {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

/* Reveal choice icons (lock/eye, RevealIconHelper) -- currentColor so they
   pick up the label's own color, dim when unselected and green when
   checked, same as the text beside them. */
.toggle-btn__icon {
  width: 1rem;
  height: 1rem;
  flex: none;
}

.slot-picker {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
}

.slot-picker__option {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.5rem;
  border-radius: 0.5rem;
  cursor: pointer;
}

/* Hidden but real (opacity, not display:none) -- the chip is the aesthetic
   control; this just keeps native radio semantics/keyboard behavior. */
.slot-picker__input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

/* Selected state: bigger + a deeper drop shadow, same offset-sprite style as
   the resting chip, rather than a ring around it -- a ring sat outside the
   chip's own offset shadow and read as misaligned with it. */
.slot-picker__input:checked ~ .chip {
  transform: translateY(-2px) scale(1.15);
  box-shadow: 5px 7px 0 var(--chip-shadow), inset 0 -4px 0 rgb(0 0 0 / 0.2);
}

.slot-picker__label {
  font-size: 0.8rem;
  /* Room for the checked chip's scale-up above (:checked ~ .chip) to grow
     into without covering the label. */
  padding-top: 0.35rem;
}

/* All-in/major/minor badge (ui.md) -- the multiplier itself is the sprite,
   bold and color-coded per tier, everywhere the slot choice shows up: the
   pick dialog's slot picker, My Picks' slot cards, the board. */
.chip {
  --chip-color: var(--text-dim);
  --chip-shadow: #14171c;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.2rem;
  height: 2.2rem;
  padding: 0 0.35rem;
  background: var(--chip-color);
  color: #14171c;
  font-family: "Courier New", monospace;
  font-weight: 800;
  font-size: 1rem;
  letter-spacing: -0.03em;
  border: 2px solid var(--chip-shadow);
  border-radius: 0.25rem;
  box-shadow: 2px 2px 0 var(--chip-shadow), inset 0 -3px 0 rgb(0 0 0 / 0.2);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

/* Fill + a matching darker shadow per tier -- hot pink/cyan/gold reads more
   distinctly at a glance than the previous gold/violet/green, and each
   tier's shadow is a shade of its own fill rather than the flat near-black
   every chip used before. */
.chip--all_in {
  --chip-color: #ff2e88;
  --chip-shadow: #c41e68;
}

.chip--major {
  --chip-color: #00d9ff;
  --chip-shadow: #0099b8;
}

.chip--minor {
  --chip-color: #ffb800;
  --chip-shadow: #cc8e00;
}

/* Leaderboard standings' rank 1-3, full size -- same chip shape as the
   tiers above, medal tones instead. */
.chip--gold {
  --chip-color: #f1c542;
  --chip-shadow: #b3861a;
}

.chip--silver {
  --chip-color: #c7ccd6;
  --chip-shadow: #868c99;
}

.chip--bronze {
  --chip-color: #cd8c52;
  --chip-shadow: #8f5d2e;
}

/* The pick row's compact chip (shared/_chip size: "sm") -- the row already
   has a name/description doing most of the talking, so the slot badge
   shrinks to match instead of anchoring the row's height. */
.chip--sm {
  min-width: 1.5rem;
  height: 1.5rem;
  font-size: 0.65rem;
  border-width: 1px;
  box-shadow: 1px 1px 0 var(--chip-shadow), inset 0 -2px 0 rgb(0 0 0 / 0.2);
}

.chip--lg {
  min-width: 3.4rem;
  height: 3.4rem;
  font-size: 1.4rem;
  box-shadow: 3px 3px 0 var(--chip-shadow), inset 0 -4px 0 rgb(0 0 0 / 0.2);
}

.my-slots,
.board {
  margin-bottom: 1.5rem;
}

.my-slots h2,
.board h2 {
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.slot-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.5rem;
  margin-bottom: 0.5rem;
}

/* Left-aligned as one group (chip, then description) rather than
   space-between spreading them across the row -- an optional "auto" badge
   is the only thing that gets pushed to the far right. */
.slot-card__header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.slot-card__description {
  flex: 1 1 auto;
  min-width: 0;
}

.slot-card__auto {
  margin-left: auto;
}

.slot-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 0.25rem;
}

/* Icon-only -- no "Remove" text label (aria-label/title carry it instead). */
.slot-card__remove {
  display: inline-flex;
  align-items: center;
  color: var(--danger);
  background: none;
  border: none;
  padding: 0;
  font-size: 0.8rem;
  cursor: pointer;
}

.slot-card__reveal {
  color: var(--text-dim);
  font-size: 0.85rem;
}

.slot-card__meta {
  margin: 0.5rem 0;
  color: var(--text-dim);
  font-size: 0.85rem;
}

.slot-card__result {
  font-weight: 600;
  margin: 0;
}

.slot-card__result--win {
  color: #4caf7d;
}

.slot-card__result--loss {
  color: var(--danger);
}

.slot-card__result--push,
.slot-card__result--void {
  color: var(--warning);
}

/* Sort toggle -- underline tabs, not buttons (docs/specs/ui.md): the
   selected one gets an accent underline + text, plain text/no border the
   rest of the time, since this is a lightweight in-page control next to
   the board, not a primary decision point. */
.board-sort {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
  color: var(--text-dim);
}

/* Same padding-bottom + transparent border as .board-sort__text below --
   the label has no underline of its own, but it needs the identical box
   model so align-items: center lines its text up with the tabs' baseline
   instead of centering a shorter box against their taller (bordered) one. */
.board-sort__label {
  display: inline-block;
  padding-bottom: 0.2rem;
  border-bottom: 2px solid transparent;
}

.board-sort__tab {
  position: relative;
}

.board-sort__input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

/* Also used as a plain link (Profile's sort, no radio/JS behind it -- a
   real navigation instead, since Team grouping's tie-break is server-side
   logic, not something worth re-deriving in JS) -- color/no-underline reset
   so it reads the same as the Week board's <span> version. */
.board-sort__text {
  display: inline-block;
  padding-bottom: 0.2rem;
  border-bottom: 2px solid transparent;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.board-sort__input:checked + .board-sort__text,
.board-sort__text--active {
  color: var(--accent);
  font-weight: 600;
  border-bottom-color: var(--accent);
}

/* Board group header (sort_controller): the small-caps-ish label treatment,
   same family as the app's other section headers (profile-history's
   per-period header) -- Kickoff sort's default look, one per exact kickoff
   time, labelled with that time (PicksHelper#pick_kickoff_label). */
.board-group-header {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-dim);
  margin: 1rem 0 0.25rem;
}

.board-group-header:first-child {
  margin-top: 0;
}

/* Player sort's own header -- same slot in the layout, but styled to match
   .pick-row__player below (white, larger) instead of the small/gray
   default above: the row's own name moves into this header (see the
   data-sort-mode rules below), so the header takes over that look. */
.board-group-header--player {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: normal;
  color: var(--text);
}

/* Shared pick row (docs/specs/ui.md) -- slot chip + description, with a
   right-aligned result; who placed it and its kickoff time are each
   optional (picks/_row's show_name/show_kickoff locals). One visual unit
   reused by the board and profile pick history; page-specific wrappers
   (.board-row, etc.) stay purely structural (JS hooks, list semantics) and
   add no styling of their own. */
.pick-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border);
}

/* Profile's pick history opts out of show_name -- one line left instead of
   two stacked ones, so the chip centers against it rather than pinning to
   a top line that no longer exists. */
.pick-row--compact {
  align-items: center;
}

.pick-row__body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.pick-row__who {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.pick-row__player {
  font-weight: 600;
  white-space: nowrap;
}

/* The board's own default (Kickoff sort): shown; hidden once Player sort
   takes over -- see the data-sort-mode rules below. flex: 0 0 auto keeps it
   sized to its own text within .pick-row__description-wrap's flex layout,
   trailing the description or wrapping to its own line as a whole unit. */
.pick-row__kickoff {
  flex: 0 0 auto;
  font-size: 0.75rem;
  color: var(--text-dim);
  white-space: nowrap;
}

/* Pairs the description with its points value as their own flex row (not
   points floated to the top of the whole .pick-row) -- align-items: flex-end
   pins points to the description's last line, so a one-line description
   still reads like points sit right beside it, but a wrapped one doesn't
   strand points up top away from the text it belongs to. */
.pick-row__description-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.5rem;
}

/* Holds the description and (board-only) its trailing kickoff time
   together, wrapping the kickoff to its own line on narrow widths rather
   than crowding the last line of a long description. */
.pick-row__description-wrap {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.5rem;
}

.pick-row__description {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 0.85rem;
}

/* The board's two sort tabs share one fully-rendered row (sort_controller
   only reorders/regroups, never re-renders) -- .board's own data-sort-mode
   (kickoff by default, matching the checked radio; sort_controller updates
   it on switch) picks which of the row's own name/kickoff shows: Kickoff
   groups already say when, so the row keeps its name and drops its
   kickoff; Player groups already say who (and their rank/points), so the
   row drops its name and keeps its kickoff, trailing the description. */
.board[data-sort-mode="kickoff"] .pick-row__kickoff {
  display: none;
}

.board[data-sort-mode="player"] .pick-row__who {
  display: none;
}

.pick-row__description--hidden {
  color: var(--text-dim);
}

.pick-row__points {
  flex-shrink: 0;
  font-weight: 600;
  white-space: nowrap;
  text-align: right;
}

.pick-row__points--pending {
  color: var(--text-dim);
}

.pick-row__points--win {
  color: #4caf7d;
}

.pick-row__points--loss {
  color: var(--danger);
}

.pick-row__points--push,
.pick-row__points--void {
  color: var(--warning);
}

.table-scroll {
  overflow-x: auto;
}

.admin-tabs {
  display: flex;
  gap: 0.25rem;
  overflow-x: auto;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--border);
}

.admin-tabs__tab {
  padding: 0.5rem 0.75rem;
  color: var(--text-dim);
  text-decoration: none;
  font-size: 0.85rem;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}

.admin-tabs__tab--active {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}

table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
}

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

th {
  color: var(--text-dim);
  font-weight: 600;
  font-size: 0.8rem;
}

.admin-inline-form {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.profile-auto-pick {
  margin: -0.25rem 0 1rem;
  color: var(--text-dim);
}

.profile-stats {
  margin-bottom: 1.5rem;
  color: var(--text-dim);
}

.profile-history__group {
  margin-bottom: 1.25rem;
}

.profile-history__group-header {
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  margin: 0 0 0.25rem;
}

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

/* The .pick-row inside each <li> already owns padding/border -- the <li>
   itself is just list semantics. */

/* Settings -- a stack of small cards (2025 app's pattern), one setting (or
   group of related settings) per card, instead of one long bare form. */
.settings-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.setting-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.6rem 0.75rem;
}

.setting-card__label {
  display: block;
  font-size: 0.75rem;
  letter-spacing: 0.03em;
  color: var(--text-dim);
  margin-bottom: 0.25rem;
}

.setting-card__value {
  font-size: 1rem;
}

/* Shared by the Account row (email + Log out) and the Role row (badge +
   Admin link) -- label/value on the left, an action on the right. */
.setting-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.setting-card__hint {
  font-size: 0.8rem;
  color: var(--text-dim);
  margin: 0.15rem 0 0.6rem;
}

/* Nickname/auto-pick: field + its own Save button, one row, never wrapping
   to a second line even on a narrow phone -- the field shrinks (min-width:
   0 overrides its own flex-basis auto, which would otherwise refuse to
   shrink below its content) rather than pushing Save down or off-screen. */
.setting-card__inline-form {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
}

.setting-card__inline-form .text-input {
  flex: 1 1 auto;
  min-width: 0;
}

.setting-card__inline-form .button--compact {
  flex: 0 0 auto;
}

.text-input {
  display: block;
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0.4rem;
  padding: 0.55rem 0.7rem;
  color: var(--text);
  /* iOS Safari auto-zooms on focus for any input under 16px, and never
     zooms back out -- keep this at 1rem to avoid that trap. */
  font-size: 1rem;
}

.text-input:focus {
  outline: none;
  border-color: var(--accent);
}

/* Every button on Settings is one of these inline, sits-next-to-its-field
   ones (Log out next to the account email, Save next to each card's own
   field) -- same colors as .button, just a smaller footprint than the
   solid full-width default. */
.settings-list .button--compact {
  width: auto;
  padding: 0.35rem 0.75rem;
  font-size: 0.8rem;
}

.button--danger {
  background: var(--danger);
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #f5f6f8;
    --surface: #ffffff;
    --text: #1a1e24;
    --text-dim: #5b6472;
    --border: #dde1e6;
  }
}


/* ---------------------------------------------------------------------
   Leaderboard: one card per player, three columns -- rank | name + record/
   streak | trend + points -- so the rank badge and the trend/points group
   can center vertically against the two-line name column instead of
   pinning to its top line. Rank 1-3 use the same chip badge the pick slots
   use (gold/silver/bronze here).
   ------------------------------------------------------------------ */

.standings-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.standings-card {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 0.75rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  padding: 0.5rem;
}

.standings-card__rank-col {
  display: flex;
  align-items: center;
  justify-content: center;
}

.standings-card__rank {
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--text-dim);
}

.standings-card__info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.standings-card__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}

.standings-card__meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  color: var(--text-dim);
}

.standings-card__dot {
  opacity: 0.6;
}

.standings-card__totals {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* White for the podium (rank 1-3); everyone else's total is the same
   neutral gray as their record/streak line -- no green/red anywhere on
   this card, the numbers speak for themselves. */
.standings-card__points {
  font-family: "Courier New", monospace;
  font-weight: 700;
  font-size: 1rem;
  color: var(--text);
  white-space: nowrap;
}

.standings-card__points--muted {
  color: var(--text-dim);
}

.standings-trend {
  flex: none;
  display: block;
  width: 3.25rem;
  height: 1.15rem;
}

.standings-trend polyline {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  opacity: 0.85;
}
