/*
 * "Glory Days" gridiron theme for every non-admin page (see layouts/main.html.erb
 * and shared/_gridiron_header.html.erb). Admin pages stay on the plain layout -
 * scoped entirely under body.gridiron-body so nothing here can leak there.
 *
 * Colors pulled directly from the real league crest (app/assets/images/
 * glory_days_crest.png), not invented: navy #1E2850, crimson #DC1432,
 * near-black #141414. Brass/gold is the one color NOT in the crest - reserved
 * for earned moments only (weekly high score, playoff wins), not primary UI.
 *
 * Bootstrap's stylesheet double-loads on every page (stylesheet_link_tag :app
 * globs vendor/bootstrap.min.css a second time after application.css) and its
 * utility classes carry !important, so overrides of Bootstrap class names need
 * matching !important + a two-class-deep selector to reliably win regardless
 * of load order - same pattern already used for .draft-order-table and the
 * War Room page elsewhere in this file.
 */

body.gridiron-body {
  --gr-night: #0D1220;
  --gr-navy: #1E2850;
  --gr-navy-light: #283563;
  --gr-crimson: #DC1432;
  --gr-crimson-dark: #A80F26;
  --gr-chalk: #F5F3EC;
  --gr-steel: #8A8F9C;
  --gr-brass: #C9A227;
  --gr-brass-bright: #E8C468;
  --gr-line: #2A3358;
  --gr-win-green: #2F9E44;
  /* Same green as --gr-win-green, but specifically for *text* on this
     theme's own dark card backgrounds - --gr-win-green itself reads too
     dark there (confirmed live), so text uses this lighter shade instead
     while borders/fills/pulses keep using --gr-win-green unchanged. Light
     mode (below) just points this back at --gr-win-green, since the
     original shade is plenty legible on a light card. */
  --gr-win-text: #6FC784;

  background: var(--gr-night);
  background-image: repeating-linear-gradient(
    100deg,
    rgba(255, 255, 255, 0.012) 0px,
    rgba(255, 255, 255, 0.012) 60px,
    transparent 60px,
    transparent 120px
  );
  color: var(--gr-chalk);
  font-family: "Barlow", -apple-system, BlinkMacSystemFont, sans-serif;
  min-height: 100vh;
}

/* Light mode - a manual toggle (light_mode_controller.js), not a
   prefers-color-scheme media query, scoped to just the Scores, NFL
   Scoreboard, and Matchup pages (the only three with the toggle in their
   header) rather than this whole dark-by-default site. Built for outdoor/
   bright-sun readability specifically, which doesn't correlate with
   whatever light/dark mode the device's OS happens to be in - a sunny
   stadium doesn't care that your phone is set to dark mode.
   .gr-light overrides this same block's custom properties, so every rule
   elsewhere in this file that already reads var(--gr-*) re-themes for
   free - only rules with their own hardcoded (non-variable) dark-specific
   color need a separate .gr-light override, and those live next to the
   rule they're overriding rather than being duplicated up here. */
body.gridiron-body.gr-light {
  --gr-night: #F4F1E8;
  --gr-navy: #FFFFFF;
  --gr-navy-light: #EEF0F7;
  --gr-crimson: #C31230;
  --gr-crimson-dark: #A80F26;
  --gr-chalk: #1C2340;
  --gr-steel: #5B6170;
  --gr-brass: #8A6A16;
  --gr-brass-bright: #96701A;
  --gr-line: #DEE1EC;
  --gr-win-green: #2F9E44;
  /* The dark-mode-only lighter shade (see --gr-win-text above) isn't
     needed once the card itself is light - the original --gr-win-green is
     already legible here, so just point back at it instead of a third
     color. */
  --gr-win-text: var(--gr-win-green);

  background-image: none;
}

body.gridiron-body a {
  color: var(--gr-crimson);
}

body.gridiron-body h1,
body.gridiron-body h2,
body.gridiron-body h3 {
  font-family: "Anton", "Barlow", sans-serif;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--gr-chalk);
}

body.gridiron-body .text-muted {
  color: var(--gr-steel) !important;
}

/* ---------- Header ---------- */

.gr-header {
  background: var(--gr-navy);
  border-bottom: 3px solid var(--gr-crimson);
}

.gr-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.6rem 0;
}

.gr-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--gr-chalk) !important;
}

.gr-crest {
  width: 44px;
  height: 44px;
}

.gr-wordmark {
  font-family: "Anton", sans-serif;
  font-size: 1.3rem;
  line-height: 1;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.gr-wordmark small {
  display: block;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  color: var(--gr-crimson);
  font-weight: 600;
}

.gr-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.gr-nav-link {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gr-chalk) !important;
  text-decoration: none;
  padding: 0.4rem 0.7rem;
  border-radius: 2px;
}

.gr-nav-link:hover {
  background: var(--gr-crimson);
}

.gr-nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 34px;
  height: 34px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--gr-line);
  border-radius: 2px;
  cursor: pointer;
}

.gr-nav-toggle-bar {
  display: block;
  height: 2px;
  margin: 0 7px;
  background: var(--gr-chalk);
}

/* Phone-size only: hide the full nav behind a hamburger toggle instead of
 * letting it wrap onto several lines under the brand (.gr-nav's flex-wrap
 * still handles tablet-width squeeze above this breakpoint just fine). The
 * open nav drops into its own full-width row via flex-basis rather than an
 * absolutely-positioned overlay, since .gr-header-inner is already a
 * wrapping flex row - one less thing to keep in sync with header height.
 */
@media (max-width: 767.98px) {
  .gr-nav-toggle {
    display: flex;
  }

  .gr-nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
    order: 3;
  }

  .gr-nav.gr-nav-open {
    display: flex;
  }

  .gr-nav .gr-nav-link {
    padding: 0.65rem 0.75rem;
    border-bottom: 1px solid var(--gr-line);
  }
}

/* ---------- Generic Bootstrap component reskin ---------- */

body.gridiron-body .card {
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  color: var(--gr-chalk);
}

body.gridiron-body .card-header {
  background: rgba(0, 0, 0, 0.2);
  border-bottom-color: var(--gr-line);
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.85rem;
}

body.gridiron-body .table {
  --bs-table-bg: transparent;
  --bs-table-striped-bg: rgba(255, 255, 255, 0.035);
  --bs-table-color: var(--gr-chalk);
  --bs-table-striped-color: var(--gr-chalk);
  --bs-border-color: var(--gr-line);
}

/*
 * Matchup detail page (starters vs bench). Bootstrap's .table-active sets
 * --bs-table-color-state to --bs-table-active-color, which gridiron.css
 * never overrides (only --bs-table-color/--bs-table-striped-color above),
 * so relying on that class rendered starter rows in the default dark
 * Bootstrap text color instead of this theme's chalk white - custom classes
 * instead, set directly on the cells rather than through Bootstrap's table
 * CSS-variable chain.
 */
body.gridiron-body .mp-starter td {
  color: var(--gr-chalk) !important;
  font-weight: 700;
}

body.gridiron-body .mp-bench td {
  color: var(--gr-steel) !important;
}

/* Visually splits starters from bench (the last starter row is usually the
   K) - brighter and thicker than the table's own subtle --gr-line row
   borders, which are too faint to read as an intentional section break. */
body.gridiron-body .mp-last-starter td {
  border-bottom: 2px solid var(--gr-chalk) !important;
}

body.gridiron-body .table thead th {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.72rem;
  color: var(--gr-steel);
  border-bottom-width: 2px;
  border-bottom-color: var(--gr-crimson);
}

body.gridiron-body .form-control,
body.gridiron-body .form-select {
  background-color: var(--gr-navy);
  border-color: var(--gr-line);
  color: var(--gr-chalk);
}

/* .form-select's dropdown arrow is a background-image, so the rule above
   must use background-color (not the background shorthand, which would wipe
   it out). Bootstrap's default arrow SVG is also dark-gray (#343a40) -
   invisible against this theme's dark navy - so it's recolored to chalk
   here via the same CSS variable Bootstrap's own dark-mode variant uses. */
body.gridiron-body .form-select {
  --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23F5F3EC' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

body.gridiron-body .form-control:focus,
body.gridiron-body .form-select:focus {
  background-color: var(--gr-navy);
  color: var(--gr-chalk);
  border-color: var(--gr-crimson);
  box-shadow: 0 0 0 0.2rem rgba(220, 20, 50, 0.25);
}

body.gridiron-body .form-control::placeholder {
  color: var(--gr-steel);
}

body.gridiron-body .nav-pills .nav-link {
  color: var(--gr-chalk);
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 0.03em;
}

body.gridiron-body .nav-pills .nav-link.active {
  background: var(--gr-crimson);
}

body.gridiron-body .btn-close {
  filter: invert(1) grayscale(100%) brightness(1.6);
}

body.gridiron-body .modal-content {
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  color: var(--gr-chalk);
}

body.gridiron-body .modal-header {
  border-bottom-color: var(--gr-line);
}

body.gridiron-body .list-group-item {
  background: transparent;
  border-color: var(--gr-line);
  color: var(--gr-chalk);
}

body.gridiron-body .data-table-clickable-row:hover {
  background: rgba(220, 20, 50, 0.12) !important;
}

/*
 * .draft-order-table (teams-as-columns draft grid, shared with the admin
 * Draft Board) hardcodes a plain black border in application.css, which is
 * invisible against this page's dark background - override to the theme's
 * line color instead.
 */
body.gridiron-body table.draft-order-table th,
body.gridiron-body table.draft-order-table td {
  border-color: var(--gr-line);
}

/* Filled cells get a light Bootstrap "*-subtle" position background (see
 * ApplicationHelper#draft_position_bg_class) - force dark text there since
 * this page's default chalk-white text is unreadable on a light background. */
body.gridiron-body table.draft-order-table td[class*="bg-"] {
  color: #212529 !important;
}

/*
 * Tabulator tables (Players/Leagues/Teams listings). The vendored theme
 * (tabulator_bootstrap5.min.css) hardcodes white backgrounds on several
 * DISTINCT selectors, not just .tabulator itself - .tabulator-table and
 * .tabulator-header have their own #fff, and .tabulator-row / .tabulator-
 * calcs-holder carry that background with !important already in the base
 * theme. Every override here needs !important + a two-class-deep selector
 * to reliably win, or the white background (with our chalk-white text on
 * top of it) silently survives - this bit us once already, see commit
 * history. Every distinct element the theme paints white gets its own rule.
 */

body.gridiron-body .tabulator,
body.gridiron-body .tabulator-table,
body.gridiron-body .tabulator-tableholder {
  background-color: var(--gr-navy) !important;
  border-color: var(--gr-line) !important;
  color: var(--gr-chalk) !important;
  font-family: "Barlow", sans-serif !important;
}

body.gridiron-body .tabulator-header {
  background-color: rgba(0, 0, 0, 0.25) !important;
  border-bottom: 2px solid var(--gr-crimson) !important;
  color: var(--gr-steel) !important;
  font-family: "Barlow Semi Condensed", sans-serif !important;
  text-transform: uppercase;
  font-size: 0.75rem;
  letter-spacing: 0.05em;
}

body.gridiron-body .tabulator-col {
  background-color: transparent !important;
  border-right-color: var(--gr-line) !important;
  color: var(--gr-steel) !important;
}

body.gridiron-body .tabulator-row {
  background-color: var(--gr-navy) !important;
  color: var(--gr-chalk) !important;
  border-bottom: 1px solid var(--gr-line) !important;
}

body.gridiron-body .tabulator-row.data-table-bold-row {
  /* Lighter than --gr-win-green - that shade reads too dark against this
     table's navy row background, unlike its other (light-background) uses. */
  color: #6FC784 !important;
}

body.gridiron-body .tabulator-row.tabulator-row-even {
  background-color: rgba(255, 255, 255, 0.04) !important;
}

body.gridiron-body .tabulator-row:hover {
  background-color: rgba(220, 20, 50, 0.15) !important;
}

body.gridiron-body .tabulator-cell {
  border-right-color: var(--gr-line) !important;
  background-color: transparent !important;
  color: inherit !important;
}

body.gridiron-body .tabulator-footer,
body.gridiron-body .tabulator-calcs-holder {
  background-color: rgba(0, 0, 0, 0.25) !important;
  color: var(--gr-steel) !important;
  border-color: var(--gr-line) !important;
}

body.gridiron-body .tabulator-page,
body.gridiron-body .tabulator-page-size {
  background-color: transparent !important;
  border-color: var(--gr-line) !important;
  color: var(--gr-chalk) !important;
}

body.gridiron-body .tabulator-paginator {
  color: var(--gr-steel) !important;
}

body.gridiron-body .tabulator-placeholder-contents {
  color: var(--gr-steel) !important;
}

/* ---------- Scoreboard (signature element - weekly matchup cards) ---------- */

.gr-scoreboard {
  position: relative;
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  overflow: hidden;
}

.gr-scoreboard .gr-scoreboard-detail-link {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(245, 243, 236, 0.08);
  color: var(--gr-chalk);
  text-decoration: none;
  z-index: 1;
  transition: background 0.15s ease, color 0.15s ease;
}

.gr-scoreboard .gr-scoreboard-detail-link:hover {
  background: var(--gr-crimson);
  color: var(--gr-chalk);
}

.gr-scoreboard-detail-link svg {
  width: 13px;
  height: 13px;
}

.gr-scoreboard-heading {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem 1rem 0.5rem;
}

.gr-scoreboard-team {
  position: relative;
  text-align: center;
  border-radius: 3px;
  padding: 0.5rem 0.4rem;
}

.gr-scoreboard-team.gr-win {
  box-shadow: inset 0 0 0 2px var(--gr-win-green);
  background: rgba(47, 158, 68, 0.14);
}

/* "My team" highlight (the signed-in owner's own matchup) - outline rather
   than box-shadow so it renders alongside .gr-win's box-shadow (on a child
   .gr-scoreboard-team) instead of one overwriting the other. A negative
   outline-offset keeps it inside the card's own bounds so .gr-scoreboard's
   overflow: hidden doesn't clip it. Wraps the whole .gr-scoreboard card -
   both teams' names/scores and the lineup tables below - so the signed-in
   owner's entire matchup card is framed at once. */
.gr-scoreboard.gr-my-team {
  outline: 2px solid var(--gr-crimson);
  outline-offset: -2px;
}

/* Bold + brass-bright (not the theme's standard --gr-brass, which this file's
   own top comment reserves for "earned moments only" like weekly high score -
   a lighter/brighter gold was chosen deliberately here, via mocked-up
   side-by-sides, because plain chalk read as too low-contrast/harsh next to
   the crimson .gr-my-team box outline and --gr-brass itself was too dark to
   read well at this size). */
.gr-team-name {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 1.05rem;
  letter-spacing: 0.03em;
  color: var(--gr-brass-bright);
  text-decoration: none;
  display: inline-block;
  /* position: relative + a small negative top shifts the name up visually
     without affecting document flow, so the score below and the card's
     overall height are untouched. */
  position: relative;
  top: -6px;
}

/* .gr-team-name alone (specificity 0,1,0) loses to body.gridiron-body a's
   own color rule (0,1,2, see near the top of this file) for a never-clicked
   /team_rosters link, and separately loses to the browser's own a:visited UA
   rule (0,1,1) once it has been visited - so team-name links rendered
   crimson instead of brass-bright in both the unvisited AND visited states
   until scoped up here to beat body.gridiron-body a outright. */
body.gridiron-body a.gr-team-name,
body.gridiron-body a.gr-team-name:visited {
  color: var(--gr-brass-bright);
}

/* display: table (not inline-block) so this still forces its own line below
   the team name, like the plain block .gr-score div did before it was
   wrapped - inline-block let it sit beside the name on the same line
   instead. table shrink-wraps its content just like inline-block would
   (so gr-star-badge's left/right: 100% still hugs the score's own edge,
   not the full column width), and margin: 0 auto centers a shrink-wrapped
   block-level box the way text-align: center alone can't. */
.gr-score-wrap {
  position: relative;
  display: table;
  margin: 0 auto;
}

.gr-score {
  font-family: "Anton", sans-serif;
  font-size: 2.4rem;
  line-height: 1;
  color: var(--gr-chalk);
  font-variant-numeric: tabular-nums;
}

.gr-scoreboard-team.gr-win .gr-score {
  /* --gr-win-green reads too dark against this card's navy background,
     same issue already fixed the same way for .tabulator-row's bold-win
     text below - reusing that same lighter --gr-win-text shade here
     instead of a new one-off color. */
  color: var(--gr-win-text);
}

.gr-proj {
  font-size: 0.7rem;
  color: var(--gr-steel);
  font-family: "Barlow Semi Condensed", sans-serif;
}

.gr-crest-divider {
  width: 57px;
  height: 57px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gr-crest-divider img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.gr-star-badge {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 26px;
  height: 24px;
  padding: 0 0.25rem;
  border-radius: 999px;
  background: var(--gr-chalk);
  color: var(--gr-night);
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 0 0 2px var(--gr-night), 0 0 8px rgba(0, 0, 0, 0.35);
}

.gr-star-icon {
  width: 17px;
  height: 17px;
  flex: none;
}

/* Anchored off gr-score-wrap's own edge (left: 100% / right: 100%), not a
   negative offset, so the badge never overlaps the score digits regardless
   of how wide the number is - and each side points toward the card's
   center (crest divider) rather than toward the card's outer edge, where
   overflow: hidden on .gr-scoreboard would otherwise risk clipping it on a
   narrow card. */
.gr-star-badge-right {
  left: 100%;
  margin-left: 0.75rem;
}

.gr-star-badge-left {
  right: 100%;
  margin-right: 0.75rem;
}

.gr-scoreboard-lineup:last-child {
  padding-bottom: 0.75rem;
}

.gr-win-prob {
  padding: 0.75rem 1rem 1rem;
}

.gr-win-prob-labels {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.3rem;
}

.gr-win-prob-pct {
  font-family: "Anton", sans-serif;
  font-size: 1rem;
  color: var(--gr-steel);
}

.gr-win-prob-pct.gr-win {
  /* Same navy-background legibility fix as .gr-scoreboard-team.gr-win
     .gr-score above - even more needed at this smaller font size. */
  color: var(--gr-win-text);
}

.gr-win-prob-title {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--gr-steel);
}

.gr-win-prob-bar {
  height: 6px;
  border-radius: 999px;
  background: var(--gr-crimson);
  overflow: hidden;
}

.gr-win-prob-fill {
  height: 100%;
  background: var(--gr-win-green);
  border-radius: 999px;
}

.gr-scoreboard-lineup {
  border-top: 1px solid var(--gr-line);
}

/* scores_controller.js's live-update flash (see highlightChanges) - a
   bolded number plus this arrow instead of a color flash, which read too
   dark against this page's navy cards and doesn't carry over to anyone
   relying on more than color to tell the two states apart anyway. An
   inline SVG rather than a Unicode arrow glyph - neither of this page's
   fonts include one, so it fell back to a per-platform symbol font with
   inconsistent vertical metrics, making the glyph sit off-center
   depending on the device. An SVG has no font dependency at all, so it's
   centered the same way everywhere. em-based sizing scales with whichever
   element it lands in - the small lineup cell or the much larger team
   score - and currentColor keeps it the same color as the bolded text
   next to it. */
.gr-delta-arrow {
  display: inline-block;
  width: 0.62em;
  height: 0.62em;
  margin-right: 0.2em;
  vertical-align: middle;
}

.gr-delta-arrow svg {
  width: 100%;
  height: 100%;
  display: block;
}

.gr-delta-arrow--down {
  transform: scaleY(-1);
}

/* row g-0 means the two team columns sit flush against each other, so a
   team's rightmost stat (Proj) butts right up against the other team's
   leftmost one (position) with nothing to show which side owns which -
   a solid divider down the middle instead of the subtle --gr-line used
   elsewhere, since this specifically needs to read at a glance. */
.gr-scoreboard-lineup .col-6:first-child {
  border-right: 1px solid var(--gr-line);
  padding-right: 0.5rem;
}

.gr-scoreboard-lineup .col-6:last-child {
  padding-left: 0.5rem;
}

/* Sized for the widest position label actually shown here ("DEF" shortened
   to "D" - see ApplicationHelper#scoreboard_position_label - so every other
   position is 2 characters at most); table-layout is auto, so a width here
   is what actually narrows the column rather than just the text within it. */
.gr-position-col {
  width: 2rem;
}

/* .gr-position-col is shared by both teams' first column, so narrowing it
   above pulled the left team's position text closer to the card's own
   outer edge too (less "cushion" from right-alignment inside a narrower
   box) - the right team's equivalent column doesn't need this, since it
   already gets breathing room from .col-6:last-child's padding-left next
   to the divider. */
.gr-scoreboard-lineup .col-6:first-child .gr-position-col {
  padding-left: 0.5rem;
}

/* ---------- Matchup detail page: other-games switcher panel ---------- */

/* Bare link on this page's own team-name headers (not .gr-team-name -
   that class is sized for the compact scoreboard cards, and this page's
   larger h5 headers shouldn't shrink to match it). Scoped to
   body.gridiron-body a.gr-matchup-team-link (not just the bare class) for
   the same reason as .gr-team-name above: a plain .gr-matchup-team-link
   (specificity 0,1,0) loses to body.gridiron-body a's own color rule
   (0,1,2) for a never-clicked link, and to the browser's UA :visited rule
   (0,1,1) once clicked - without this it silently fell back to crimson (or,
   post-visit, the browser's dull purple/red) instead of chalk. Bold +
   brass-bright to match .gr-team-name's treatment on the main scores page -
   deliberately NOT copying that rule's font-size bump or position: relative
   top nudge, both of which were tuned for the smaller scoreboard cards and
   don't apply to this page's own h5-sized headers. Explicit font-family
   override, not just inheriting the parent h2's "Anton" - the Google Fonts
   import only loads Anton's regular (400) weight, so font-weight: 700 on
   it forces the browser to synthesize/"faux" bold, which reads as muddy,
   thickened characters instead of a real bold cut. Barlow Semi Condensed
   has a true 700 weight loaded (same font .gr-team-name already uses). */
/* Bootstrap's own h1-h6 rule sets margin-bottom: 0.5rem on every heading,
   including this h2.h5 - h2.h5 is only ever used for these two team-name
   headers (grepped the app's views), so it's safe to tighten here rather
   than un-scoping into a new wrapper class just for this. */
body.gridiron-body h2.h5 {
  margin-bottom: 0.15rem;
}

body.gridiron-body a.gr-matchup-team-link,
body.gridiron-body a.gr-matchup-team-link:visited {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 700;
  color: var(--gr-brass-bright);
  text-decoration: none;
}

/* Explicit 3-column grid rather than the flex-wrap this replaced - wrap
   filled rows unevenly (4 then 2) depending on each button's own text
   length, whereas a fixed grid keeps every "other game" the same width
   and wraps cleanly into a 3x2 matrix at the typical week's matchup count. */
.gr-switcher-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
  margin-bottom: 1rem;
}

@media (max-width: 576px) {
  .gr-switcher-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Bootstrap's btn-outline-secondary (the previous styling here) is a dim
   gray border/text that barely registers against this theme's near-black
   background - themed navy fill + chalk text instead, sized up from the
   old btn-sm, matching the scoreboard cards' own palette rather than
   generic Bootstrap gray. */
.gr-switcher-btn {
  background: var(--gr-navy-light);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  color: var(--gr-chalk);
  cursor: pointer;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.65rem 0.75rem;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}

/* Light grey (the theme's existing --gr-steel, already used for muted text
   elsewhere) so the two team names read as visually distinct from the score
   digits between them, which stay the button's default chalk color. */
.gr-switcher-team-name {
  color: var(--gr-steel);
}

.gr-switcher-btn:hover {
  border-color: var(--gr-brass);
}

.gr-switcher-btn.gr-switcher-btn-current {
  background: var(--gr-crimson);
  border-color: var(--gr-crimson);
}

/* Steel grey has weak contrast against this button's own solid crimson
   background - keep the currently-viewed matchup's names at the brighter
   default chalk instead of dimming them along with every other button. */
.gr-switcher-btn.gr-switcher-btn-current .gr-switcher-team-name {
  color: var(--gr-chalk);
}

/* "My team" highlight in the switcher grid (the signed-in owner's own
   matchup among the week's other games) - an outline rather than a solid
   fill so it doesn't get confused with .gr-switcher-btn-current's solid
   crimson "this is the matchup you're looking at" fill above; both classes
   can apply at once (viewing your own matchup) without becoming ambiguous. */
.gr-switcher-btn.gr-my-team {
  outline: 2px solid var(--gr-crimson);
  outline-offset: -2px;
}

/* Live possession highlighting per player row - used on both the main
   scores page (ApplicationHelper#possession_row_class, server-rendered) and
   the matchup detail page (live_plays_controller.js, applied client-side
   from its existing 30s live_plays poll) - same two classes, same colors,
   deliberately unscoped by container so both pages' differently-shaped
   tables pick it up. .table-striped's own per-cell background
   (.table-striped>tbody>tr:nth-of-type(odd)>*) isn't itself !important, so
   plain !important here is enough to win regardless of that rule's own
   specificity - no container-scoping needed just to out-specificity it.
   Reuses this theme's own win-green/crimson rather than new colors - green
   while the player's own team has the ball (an active, positive state,
   same color as gr-win), crimson while the opponent does. */
.gr-row-has-ball > td {
  background-color: rgba(47, 158, 68, 0.22) !important;
}

.gr-row-opp-has-ball > td {
  background-color: rgba(220, 20, 50, 0.16) !important;
}

/*
 * A CSS Grid, not Bootstrap's row-cols - row-cols forces a fixed 50%/33%
 * split at fixed pixel breakpoints regardless of whether a card actually
 * needs that width, which is why row-cols-lg-2 stretched cards edge to edge
 * on a wide screen (nothing capped their width) while row-cols-xxl-3 (or a
 * hand-picked custom breakpoint - both tried and both wrong) either never
 * fired on a scaled/high-DPI display or fired too early and crammed each
 * card's own two-sub-column lineup onto multiple lines. minmax(520px, 1fr)
 * instead sizes columns off each card's real minimum comfortable width
 * (roughly what row-cols-lg-2 gave it inside the old capped .container) and
 * lets the browser decide the column count - 1 up to ~1050px, 2 up to
 * ~1580px, 3 beyond that, redistributing only the leftover space evenly
 * rather than doubling a card's width just because the viewport can.
 *
 * Capped at 3: the minmax floor is max(520px, one-third of the row minus
 * its two gaps). Below the 3-up threshold that's just 520px again (same
 * 1/2/3 behavior as before); past it, the floor becomes exactly a third of
 * the row, which by definition leaves no room for a 4th track to fit -
 * auto-fit tops out at 3 on its own, no media query, and the 3 columns keep
 * stretching (1fr) to fill whatever width is available rather than leaving
 * dead margin.
 */
.gr-scores-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(max(520px, calc((100% - 2 * 1.5rem) / 3)), 1fr));
  gap: 1.5rem;
}

/*
 * Compact view (scores_controller.js's Compact toggle, off by default) -
 * built for fitting a full week's cards on an iPad without scrolling while
 * still showing every player, not for general use. .gr-compact is applied
 * by JS to the #scores controller's contentTarget (the wrapper around
 * .gr-scores-grid, not .gr-scores-grid itself - it survives the innerHTML
 * swap every refresh()/loadWeek() does, so the toggle state doesn't need
 * to be re-applied after every poll).
 *
 * Fixed column counts, not auto-fit/minmax like the normal grid above -
 * this is deliberately sized off real iPad widths rather than "however
 * many 520px-minimum cards happen to fit": every current iPad's portrait
 * width tops out at 1032px and every landscape width starts at 1133px, so
 * 1050px cleanly separates the two without needing actual orientation
 * detection. 2 columns below that (portrait), 3 at/above it (landscape).
 *
 * Trims chrome that isn't player data (win-probability bar, star badges,
 * the vs crest) rather than hiding any lineup rows - "all players still
 * visible" was the explicit requirement this toggle exists to satisfy.
 */
.gr-compact .gr-scores-grid {
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

@media (min-width: 1050px) {
  .gr-compact .gr-scores-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* The 2-column base above was sized for iPad portrait (see this section's
   own comment) and never accounted for anything narrower - on a phone it
   crammed two cards into a space neither fits, wrapping team/player names
   across several lines and overlapping the points/proj columns. 576px
   matches this file's existing phone-tier breakpoint (Bootstrap's own sm)
   - no real iPad drops below ~744px wide, so this can't misfire on the
   tablet range the 2-column rule above is actually meant for. */
@media (max-width: 576px) {
  .gr-compact .gr-scores-grid {
    grid-template-columns: 1fr;
  }
}

/* .gr-scoreboard-heading's normal grid-template-columns is "1fr auto 1fr" -
   the middle "auto" track sized to .gr-crest-divider's own width. Hiding
   that element below (display: none) removes it from the grid entirely,
   but left the 3-track template in place, so the empty "auto" track's
   width became unpredictable instead of cleanly collapsing to 0 - the
   right team ended up off-center as a result. Redefining the template to
   just two equal tracks removes that ambiguity outright, rather than
   depending on how a browser sizes a track with no participating item. */
.gr-compact .gr-scoreboard-heading {
  grid-template-columns: 1fr 1fr;
  /* Base .gr-scoreboard-heading has padding-top: 1rem, sized for the full
     (non-compact) card - left untouched here it read as wasted space above
     the already-shrunk compact team name. */
  padding-top: 0.4rem;
}

.gr-compact .gr-scoreboard-team {
  padding: 0.3rem 0.3rem;
}

.gr-compact .gr-team-name {
  font-size: 0.85rem;
}

.gr-compact .gr-score {
  font-size: 1.5rem;
}

.gr-compact .gr-proj,
.gr-compact .gr-star-badge,
.gr-compact .gr-crest-divider,
.gr-compact .gr-win-prob {
  display: none;
}

.gr-compact .gr-scoreboard-lineup table {
  font-size: 0.7rem;
}

.gr-compact .gr-scoreboard-lineup td {
  padding: 0.15rem 0.3rem !important;
}

/* Compact view swaps a player's full name for "F. Last" (.gr-name-short) -
   long full names were wrapping to two lines and blowing out row height in
   the already-cramped compact layout. Both spans are always rendered (see
   scores/_matchups.html.erb) so this is a pure display toggle, not a
   content change - full name stays the default everywhere else. */
.gr-name-short {
  display: none;
}

.gr-compact .gr-scoreboard-lineup .gr-name-full {
  display: none;
}

.gr-compact .gr-scoreboard-lineup .gr-name-short {
  display: inline;
}

/* Light grey once a player's own NFL game has finished ("post" state) -
   used on both the main scores page (ApplicationHelper#possession_row_class
   passes game_states_by_team the same way; applied server-side here since
   scores/_matchups.html.erb already has that data) and the matchup detail
   page (applied client-side by live_plays_controller.js's existing 30s poll,
   targeting the .gr-player-name-cell class added in matchups/_matchup -
   that page has no server-side game-state data on initial render, matching
   how possession highlighting there is already 100% poll-driven).
   A bare .gr-name-dimmed (specificity 0,1,0) loses to Bootstrap's own
   .table>:not(caption)>*>* cell-color rule (0,1,1, from the vendored
   bootstrap.min.css, double-loaded after this file - see this file's own
   top comment), which otherwise silently overrides it back to chalk. Scoped
   up with an extra class + element to definitively beat that, not just tie
   it (a tie would still lose on load order).
   On the matchup detail page specifically, .mp-starter td/.mp-bench td just
   above (higher up this file) set color with !important - normal
   specificity can't ever beat an !important rule no matter how scoped, so
   this needs !important too. Specificity of .table td.gr-player-name-cell
   (0,3,1) already beats body.gridiron-body .mp-starter td (0,2,2) even
   within the !important tier. */
.gr-scoreboard-lineup td.gr-name-dimmed,
.table td.gr-player-name-cell.gr-name-dimmed {
  color: var(--gr-steel) !important;
}

/* ---------- Standings ---------- */

.gr-standings {
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  overflow: hidden;
}

.gr-standings-num {
  font-family: "Anton", sans-serif;
  font-size: 0.95rem;
  color: var(--gr-steel);
}

.gr-record {
  font-family: "Anton", sans-serif;
  font-variant-numeric: tabular-nums;
}

.gr-division-label {
  font-family: "Anton", sans-serif;
  font-size: 1.1rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--gr-brass);
  border-bottom: 2px solid var(--gr-brass);
  display: inline-block;
  padding-bottom: 0.1rem;
  margin-bottom: 0.75rem;
}

/* ---------- Playoff bracket ---------- */

/*
 * Cards are positioned absolutely (inline top/left/width/height, computed
 * server-side in _bracket.html.erb from PlayoffMatchup.bracket_layout) so an
 * SVG overlay sharing the same coordinate space can draw real elbow
 * connectors between a match and whatever later match its winner/loser
 * advances to - not just round columns with no visual relationship.
 */

.gr-bracket-labels {
  position: relative;
  height: 1.4rem;
  margin-bottom: 0.25rem;
}

.gr-bracket-round-label {
  position: absolute;
  top: 0;
  text-align: center;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: 0.72rem;
  color: var(--gr-steel);
}

.gr-bracket-scroll {
  overflow-x: auto;
  padding-bottom: 0.5rem;
}

.gr-bracket {
  position: relative;
}

.gr-bracket-lines {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.gr-bracket-connector {
  fill: none;
  stroke: var(--gr-line);
  stroke-width: 2;
}

.gr-bracket-connector--loser {
  stroke-dasharray: 4 3;
  opacity: 0.65;
}

.gr-bracket-match {
  position: absolute;
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}

.gr-bracket-match-header {
  background: rgba(0, 0, 0, 0.25);
  color: var(--gr-brass);
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
  padding: 0.15rem 0.5rem;
}

.gr-bracket-team-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
  font-size: 0.8rem;
  color: var(--gr-chalk);
  border-top: 1px solid var(--gr-line);
}

.gr-bracket-team-row:first-of-type {
  border-top: none;
}

.gr-bracket-team-row--winner {
  color: var(--gr-win-green);
  font-weight: 700;
}

.gr-bracket-team-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gr-bracket-team-points {
  font-variant-numeric: tabular-nums;
  font-size: 0.76rem;
  opacity: 0.75;
  flex-shrink: 0;
}

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

body.gridiron-body footer.border-top {
  background: var(--gr-night);
  border-top-color: var(--gr-line) !important;
}

body.gridiron-body footer.border-top a {
  color: var(--gr-steel);
}

body.gridiron-body footer.border-top a:hover {
  color: var(--gr-crimson);
}

/* ---------- Live score ticker (shared/_score_ticker, score_ticker_controller.js) ---------- */

.score-ticker {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.score-ticker-strip {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  padding: 0.4rem 0;
}

.score-ticker-strip.is-scrollable {
  overflow-x: auto;
}

.score-ticker-track {
  display: flex;
  width: max-content;
}

.score-ticker-track.is-animated {
  animation: score-ticker-scroll 75s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .score-ticker-track.is-animated {
    animation: none;
  }
}

@keyframes score-ticker-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.score-ticker-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  flex: none;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--gr-chalk);
  padding: 0 1.1rem;
  border-right: 1px solid var(--gr-line);
  white-space: nowrap;
}

.score-ticker-detail {
  color: var(--gr-steel);
  font-weight: 400;
  font-size: 0.72rem;
}

/* Emoji render noticeably larger than surrounding text by default - used for
   the possession indicator both here and on the Matchup Details page. */
.football-icon {
  font-size: 0.75em;
}

/* Matchup Details possession indicator - empty span takes no space until
   live_plays_controller.js fills it in, so it never shifts layout on load. */
[data-live-plays-target="ball"]:not(:empty) {
  margin-right: 0.25rem;
}

.score-ticker .live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gr-crimson);
  box-shadow: 0 0 0 0 rgba(220, 20, 50, 0.6);
  animation: score-ticker-pulse 1.8s ease-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .score-ticker .live-dot {
    animation: none;
  }
}

@keyframes score-ticker-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(220, 20, 50, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(220, 20, 50, 0); }
  100% { box-shadow: 0 0 0 0 rgba(220, 20, 50, 0); }
}

.score-ticker-toggle {
  flex: none;
  white-space: nowrap;
}

body.gridiron-body .score-ticker-toggle .form-check-label {
  color: var(--gr-steel);
}

@media (max-width: 576px) {
  .score-ticker {
    display: none;
  }
}

/* ---------- NFL Scoreboard page (nfl_scoreboard#index, nfl_scoreboard_controller.js) ---------- */

.nfl-section-title {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 1rem;
  color: var(--gr-steel);
  margin: 0 0 0.75rem;
}

.nfl-scoreboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}

/* Every card in a grid row is stretched to the tallest one (CSS Grid's
   default align-items: stretch), so a flex column here lets
   .nfl-scoring-play's margin-top: auto below push it all the way to the
   bottom of that stretched height, keeping "Last score" aligned across a
   row regardless of how many recent plays/how much other content a given
   card has above it. */
.nfl-game-card {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.nfl-game-card .card-body {
  display: flex;
  flex-direction: column;
  padding: 1rem 1.1rem;
}

.nfl-scoring-play {
  margin-top: auto;
  padding-top: 0.75rem;
}

.nfl-game-teams {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.nfl-game-team {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  font-size: 1.05rem;
}

.nfl-game-abbr {
  min-width: 2.5rem;
}

.nfl-game-score {
  font-weight: 700;
}

.nfl-game-clock,
.nfl-game-status {
  color: var(--gr-steel);
  white-space: nowrap;
}

.nfl-game-status {
  font-size: 0.78rem;
}

/* 50% bigger than .nfl-game-status - the quarter/time-remaining is the
   thing a glance at a live card most needs, so it gets more visual weight
   than the (unchanged) pre-game/final status text it's styled alongside. */
.nfl-game-clock {
  font-size: 1.17rem;
}

/* Green by default (offense is just moving the chains) - switches to the
   score ticker's own crimson pulse (.nfl-live-dot-redzone, reusing its
   score-ticker-pulse keyframes) once game.red_zone is true
   (EspnScoreboardService's situation.isRedZone), as a quick color cue for
   "something's about to happen" without reading the down/distance text. */
.nfl-live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gr-win-green);
  margin-right: 0.35rem;
  animation: nfl-live-dot-pulse-green 1.8s ease-out infinite;
}

.nfl-live-dot-redzone {
  background: var(--gr-crimson);
  animation-name: score-ticker-pulse;
}

@keyframes nfl-live-dot-pulse-green {
  0%   { box-shadow: 0 0 0 0 rgba(47, 158, 68, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(47, 158, 68, 0); }
  100% { box-shadow: 0 0 0 0 rgba(47, 158, 68, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .nfl-live-dot {
    animation: none;
  }
}

.nfl-down-distance,
.nfl-play-down-distance {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--gr-brass-bright);
}

.nfl-play-down-distance {
  margin-right: 0.35rem;
}

.nfl-play-label {
  font-family: "Barlow Semi Condensed", sans-serif;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.68rem;
  color: var(--gr-steel);
  margin-bottom: 0.2rem;
}

.nfl-play-text,
.nfl-play-list li {
  font-size: 0.82rem;
  color: var(--gr-chalk);
}

.nfl-play-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.nfl-play-clock {
  font-weight: 600;
  color: var(--gr-steel);
  margin-right: 0.35rem;
}

/* ---------- Player news scroll (shared/_player_news_scroll, player_news_scroll_controller.js) ---------- */

.player-news-scroll-strip {
  overflow: hidden;
  background: var(--gr-navy);
  border: 1px solid var(--gr-line);
  border-radius: 4px;
  padding: 0.4rem 0;
}

.player-news-scroll-strip.is-scrollable {
  overflow-x: auto;
}

.player-news-scroll-track {
  display: flex;
  width: max-content;
}

.player-news-scroll-track.is-animated {
  animation: player-news-scroll-scroll 120s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .player-news-scroll-track.is-animated {
    animation: none;
  }
}

@keyframes player-news-scroll-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

.player-news-scroll-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  flex: none;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-size: 0.8rem;
  color: var(--gr-chalk);
  text-decoration: none;
  padding: 0 1.1rem;
  border-right: 1px solid var(--gr-line);
  white-space: nowrap;
}

.player-news-scroll-chip:hover {
  color: var(--gr-crimson);
}

.player-news-scroll-players {
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--gr-brass);
}

.player-news-scroll-headline {
  color: var(--gr-steel);
  font-weight: 400;
}

.player-news-scroll-chip:hover .player-news-scroll-players,
.player-news-scroll-chip:hover .player-news-scroll-headline {
  color: inherit;
}

.player-news-scroll-chip.is-new {
  background: rgba(220, 20, 50, 0.1);
}

.player-news-scroll-badge {
  display: inline-flex;
  align-items: center;
  font-family: "Barlow Semi Condensed", sans-serif;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gr-chalk);
  background: var(--gr-crimson);
  border-radius: 3px;
  padding: 0.05rem 0.35rem;
}

@media (max-width: 576px) {
  .player-news-scroll {
    display: none;
  }
}
