/* Learned that there is a default 8px margin applied by browsers, want to
control that and not leave it to chance */ 
body {
    margin: 4px;
}

.preview-body {
    margin: 0;
    padding: 0 10px 24px;
    background: radial-gradient(circle at 20% 20%, #1c2541 0, #0b132b 30%, #050b1a 65%);
    color: #0e1a2b;
    min-height: 100vh;
    font-family: 'Lato', sans-serif;
}

.leaderboard-body {
    --page-pad: 10px;
    margin: 0;
    padding: 0 10px 30px;
    background: linear-gradient(135deg, #050b1a 0%, #0f1d3a 40%, #111b2e 70%, #0b132b 100%);
    color: #e8edf7;
    min-height: 100vh;
    font-family: 'Lato', sans-serif;
}

.possession-icon {
    color: #8B4513;
}

/* Container to wrap week-number header and table */
.container {
    width: 100%;  /* Adjusts for 3px margin on each side */
    box-sizing: border-box;
}

.nounderline {
    text-decoration: none;
}

/* Table for scores and preview */
.table-alternating {
    table-layout: fixed; /* Ensures equal column distribution */
    border-collapse: collapse;
    font-family: 'Lato', sans-serif;
    font-size: 14px;
    font-weight: 600;
    text-align: center;
    line-height: 1.8;
    box-sizing: border-box;  
    width: 100%;
    vertical-align: middle;
}

/* Apply Flexbox to Table Cells for Vertical Centering */
.table-alternating th,
.table-alternating td {
    /* display: flex; /* Use flexbox for centering */
    /* justify-content: center; /* Center horizontally */
    /* align-items: center; /* Center vertically */
    /* padding: 10px; /* Adjust padding as needed */
    border-bottom: 1px solid #dddd;
}

/* Ensure logos and text are centered together */
.table-alternating td img {
    margin-left: 0px; /* Optional: Add space between text and logo */
    max-height: 50px; /* Adjust logo size to ensure it fits within the row */
    vertical-align: middle;
}

/* Specifics for header row */
.table-alternating thead {
    background: linear-gradient(135deg, #273555 0%, #1a233c 100%);
}

.table-alternating thead th {
    background: transparent;
    color: #e9f0ff;
    position: sticky;
    top: 0;
    font-size: 16px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.4px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.table-alternating thead th:last-child {
    text-align: right;
}

/* Specifics for alternating rows */
.table-alternating tr:nth-child(even) {
    background-color: #f2f2f2;
}

/* Adjusting individual column widths to maintain a balanced layout */
.table-alternating th:nth-child(1),
.table-alternating td:nth-child(1),
.table-alternating th:nth-child(3),
.table-alternating td:nth-child(3) { 
    width: 30%; 
}

.table-alternating th:nth-child(1),
.table-alternating td:nth-child(1) {
    text-align: left;
    
}

.table-alternating th:nth-child(2),
.table-alternating td:nth-child(2) {
    width: 40%;
    text-align: center;
} 

/* Table for game day leaderboard */
.table-leaderboard {
    border-collapse: separate;
    border-spacing: 0;
    font-family: 'Teko', sans-serif;
    font-size: 19px;
    font-weight: 600;
    text-align: center;
    line-height: 1.8;
    box-sizing: border-box;
    width: 100%;
    color: #0f172a;
    background: linear-gradient(180deg, #fdfefe 0%, #f5f7fb 100%);
    border-radius: 14px;
    overflow: hidden;
    table-layout: fixed;
}

.table-leaderboard th,
.table-leaderboard td {
    padding: 10px 8px;
    text-align: center;
    border-bottom: 1px solid #e2e8f0;
    box-sizing: border-box;
}

.table-leaderboard th {
    background: transparent;
    color: #e8edf7;
    position: sticky;
    top: 0;
    font-size: 90%;
    letter-spacing: 0.5px;
    z-index: 1;
}

.table-leaderboard thead {
    background: linear-gradient(135deg, #0f172a 0%, #15284c 100%);
}

.table-leaderboard tbody tr:nth-child(even) {
    background-color: #edf2f7;
}

/* Hover one player, not both.

   Two players share a row here -- one in the first five cells, one in the last
   five -- so lighting the whole <tr> highlighted the person next to the one the
   cursor was on. :has() lets a cell's hover reach its own half of the row.

   Where :has() is unsupported nothing lights up, which is the right way to
   lose this: it is an affordance for pointers, and the phones most of the pool
   reads on never had it. */
.table-leaderboard tbody tr:has(.slot-a:hover) .slot-a,
.table-leaderboard tbody tr:has(.slot-b:hover) .slot-b {
    background: #e0e7ff;
}

.table-leaderboard td:first-child,
.table-leaderboard td:nth-child(6) {
    font-weight: 700;
    overflow: hidden;
}

.table-leaderboard td:first-child a,
.table-leaderboard td:nth-child(6) a {
    display: block;
    overflow: hidden;
    width: 100%;
}

.table-leaderboard td:first-child a .name-text,
.table-leaderboard td:nth-child(6) a .name-text {
    display: inline-block;
}

.table-leaderboard td:first-child a.name-marquee .name-text,
.table-leaderboard td:nth-child(6) a.name-marquee .name-text {
    white-space: nowrap;
    animation: name-marquee 4s ease-in-out infinite alternate;
    will-change: transform;
}

@keyframes name-marquee {
    0% { transform: translateX(0); }
    100% { transform: translateX(var(--marquee-shift, -35%)); }
}

@media only screen and (max-width: 760px) {
    .table-leaderboard {
        table-layout: fixed;
        font-size: 17px;
    }

    .table-leaderboard th,
    .table-leaderboard td {
        min-width: 0;
        padding: 6px 4px;
    }
}

/* Adjusting individual column widths to maintain a balanced layout */
.table-leaderboard th:nth-child(1),
.table-leaderboard td:nth-child(1),
.table-leaderboard th:nth-child(6),
.table-leaderboard td:nth-child(6) { 
    width: 30%; 
}

.table-leaderboard th:nth-child(2),
.table-leaderboard td:nth-child(2),
.table-leaderboard th:nth-child(3),
.table-leaderboard td:nth-child(3), 
.table-leaderboard th:nth-child(4),
.table-leaderboard td:nth-child(4),
.table-leaderboard th:nth-child(5),
.table-leaderboard td:nth-child(5),
.table-leaderboard th:nth-child(7),
.table-leaderboard td:nth-child(7),
.table-leaderboard th:nth-child(8),
.table-leaderboard td:nth-child(8), 
.table-leaderboard th:nth-child(9),
.table-leaderboard td:nth-child(9),
.table-leaderboard th:nth-child(10),
.table-leaderboard td:nth-child(10) { 
    width: 5%; 
}

/* Week Number Header */
.week-number {
    font-family: 'Teko', sans-serif;
    font-weight: 600;
    font-size: 2em;
    text-align: center;
    background-color: #4CAF50;
    color: white;
    border: 0px;
    padding-top: 15px; /* Ensure no padding at the bottom */
    padding-bottom: 15px;
    margin: 0; /* Set the margin to 0 all around */
    line-height: 1;
}

/* Small text under the week number */
.small-text {
    font-size: 18px; /* Adjust the size as needed */
    line-height: normal; /* Adjust line height */
    display: block; /* Make span behave like a block element */
    margin-top: -5px; /* Pull the text closer to the above line */
}

/* Sort container style */
.sort-container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    background: transparent;
    color: #e8edf7;
    font-family: 'Lato', sans-serif;
    font-size: 14px;
}

/* Dropdown select style */
#sort-options {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Label styling for the dropdown */
.sort-container label {
    font-family: 'Teko', sans-serif;
    font-size: 14px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: #9ae66e;
}

.sort-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-start;
    border-left: 1px solid rgba(255, 255, 255, 0.12);
    padding-left: 6px;
}

.sort-pills .pill {
    border: 1px solid #d2d7df;
    border-radius: 999px;
    padding: 8px 14px;
    background: #f2f4f7;
    display: flex;
    font-size: 16px;
    gap: 6px;
    align-items: center;
    cursor: pointer;
    transition: all 0.15s ease;
    font-family: 'Lato', sans-serif;
    font-weight: 700;
    color: #0f172a;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.sort-pills .pill .pill-sub-icon {
    font-size: 14px;
    color: #586774;
}

.sort-pills .pill.active {
    background: #dbe9ff;
    color: #0b2f6b;
    border-color: #1d4ed8;
    box-shadow: 0 8px 20px rgba(29, 78, 216, 0.18);
}

.sort-pills .pill:hover {
    transform: translateY(-1px);
    border-color: #1d4ed8;
}

/* Lighter green for completed games with a correct pick */
/* Finished rows get a light wash rather than a flood. The old saturated fill
   muddied the logos and the score; the pick marker carries the signal now. */
.completed-correct {
    background-color: #e9f6ea;
    color: #0f172a;
}

/* Lighter red for completed games with an incorrect pick */
.completed-incorrect {
    background-color: #fdeceb;
    color: #0f172a;
}

/* Live and final rows now read the same.
   Brightness used to mean "this game is still going", which the result column
   says better and in words. The strong greens and reds moved to the picked
   cell, where they mean something a player is actually looking for. */
.correct {
    background-color: #e9f6ea;
    color: #0f172a;
}

.incorrect {
    background-color: #fdeceb;
    color: #0f172a;
}

.not-started {
    background-color: white;
}

.table-participant {
    border-collapse: separate;
    border-spacing: 0;
    font-family: 'Teko', sans-serif;
    font-size: 19px;
    font-weight: 500;
    text-align: center;
    line-height: 1.3;
    box-sizing: border-box;
    width: 100%;
    background: #fdfefe;
    color: #0f172a;
    border-radius: 14px;
    overflow: hidden;
}

/* Specifics for headers and cells */
.table-participant th,
.table-participant td {
    padding: 10px 6px;
    text-align: center;
    border-bottom: 1px solid #e2e8f0;
}

/* Specifics for header row */
.table-participant th {
    background: transparent;
    color: #e8edf7;
    position: sticky;
    top: 0;
    font-size: 110%;
    letter-spacing: 0.5px;
    z-index: 1;
}

.table-participant thead {
    background: linear-gradient(135deg, #0f172a 0%, #15284c 100%);
}

.heading-return {
    font-family: 'Teko', sans-serif;
    font-weight: 600;
    font-size: 18px;
    text-align: center;
    background-color: #4CAF50;
    color: white;
    box-sizing: border-box;
    border: 0;
    margin: 0;
    padding: 0;
}

/* Three columns now: away, result, home. */
.table-participant th:nth-child(1),
.table-participant td:nth-child(1) {
    width: 36%;
    text-align: left;
}

.table-participant th:nth-child(2),
.table-participant td:nth-child(2) {
    width: 28%;
    text-align: center;
}

.table-participant th:nth-child(3),
.table-participant td:nth-child(3) {
    width: 36%;
    text-align: right;
}

.table-participant td.team-cell {
    padding: 12px 10px;
}

.table-participant td.team-cell-away {
    text-align: left;
}

.table-participant td.team-cell-home {
    text-align: right;
}

.table-participant .team-logo,
.table-participant .pick-icon {
    vertical-align: middle;
}

.table-participant .pick-cell {
    text-align: center;
}

.table-participant .pick-indicator {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.table-participant .score-cell {
    font-weight: 700;
    font-size: 1.5em;
}

/* Lighter green for in-progress games with a correct pick */
.in-progress-correct {
    background-color: #a8d5a2;  /* Light green */
    color: #333;  /* Adjust text color for readability */
}

/* Lighter red for in-progress games with an incorrect pick */
.in-progress-incorrect {
    background-color: #f5a1a1;  /* Light red */
    color: #333;  /* Adjust text color for readability */
}

/* Style for the link in the header to look more like a traditional link */
.header-link {
    color: #007bff;  /* Blue color for links */
    font-size: large;
    font-weight: bold;
    padding: 2px 5px;  /* Reduced padding to make it blend more like a text link */
    /* margin-top: 2px; */
    border-radius: 0;  /* Remove border radius to keep it more like a text link */
    background-color: transparent;  /* Remove background color */
}
.header-link:hover {
    color: #0056b3;  /* Darker blue on hover */
    text-decoration: underline;  /* Keep underline on hover */
}

.winner-announcement {
    font-family: 'Teko', sans-serif;
    font-size: 24px;
    font-weight: bold;
    text-align: center;
    color: #FFD700; /* Gold color */
    background-color: #333;
    padding: 10px;
    margin-bottom: 10px;
}

.button {
    display: inline-block;
    padding: 10px 20px;
    font-family: 'Lato', sans-serif;
    font-size: 14px;
    font-weight: 400;
    color: white;
    background-color: #FF8C00; /* Bright orange */
    border: 2px solid #E07A00; /* Slightly darker orange border */
    border-radius: 2px;
    text-align: center;
    text-decoration: none; /* Removes underline */
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); /* Adds a shadow */
}

.button:hover {
    background-color: #E07A00; /* Slightly darker orange on hover */
    box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.3); /* Enhance shadow on hover */
    transform: translateY(-2px); /* Slight lift effect on hover */
}

.button:active {
    background-color: #C76600; /* Darker shade for active state */
    transform: translateY(2px); /* Pressed-down effect */
}

.button-hero {
    font-size: 16px;
    padding: 12px 26px;
    border-radius: 4px;
}

.glass-card {
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    box-shadow: 0 10px 50px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(10px);
    border-radius: 16px;
}

.hero {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 18px;
    padding: 22px 10px 10px;
    color: #e8edf7;
}

.leaderboard-shell {
    max-width: 1100px;
    margin: 0 auto;
    padding-top: 14px;
}

.leaderboard-hero {
    margin-bottom: 14px;
    padding: 16px 16px 18px;
}

/* The gameday grid is made for a big screen; on a phone the two-column
   leaderboard is already the better view, so the way in is not offered. */
/* The leaderboard hero places its four parts by grid, so the way to the
   gameday grid can sit beside the title on a big screen and in the card's top
   right corner on a phone -- one place in the markup, two arrangements.
   Scoped to its own class: every other page's .hero-copy is untouched.

   A phone used to wrap it onto a line of its own between the heading and the
   text below, hard against that text. */
/* Nav and view switch in one pinned block, first thing on both scores views,
   so the switch is in the same place on screen whichever view you are on and
   never scrolls away. Named for the view transition, so the browser carries
   it across the navigation rather than fading it out and back in. */
.sticky-header {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    /* Out to the page edge, then its own inset, so the switch lands on the
       same pixels on both views. The two pages pad their bodies differently
       -- 10px here, 8 or 16 on the grid -- which moved the control by a few
       pixels as you toggled. */
    margin-inline: calc(-1 * var(--page-pad, 10px));
    padding: 0 16px 10px;
    box-sizing: border-box;
    view-transition-name: site-header;
    transition: background 0.2s ease, box-shadow 0.2s ease;
}

/* Nothing at rest, so This Week looks like Season and History: those pages
   show the page's own background behind their nav, and a pinned bar here made
   This Week the odd one out. It paints only once the sentinel above it has
   scrolled away, when rows would otherwise show through the nav. */
.sticky-header.is-stuck {
    background: linear-gradient(180deg, #050b1a 82%, rgba(5, 11, 26, 0.95));
    box-shadow: 0 8px 20px rgba(2, 6, 18, 0.55);
}

.sticky-sentinel {
    height: 1px;
}

.sticky-header .site-nav {
    width: 100%;
}

/* Both documents opt in, so moving between the two views morphs instead of
   flashing: the block glides to its new side and the content cross-fades.
   Browsers without it simply navigate, as before. */
@view-transition {
    navigation: auto;
}

@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation-duration: 0.01s;
    }
}

/* "Week 2 Leaderboard", with the view's own name in green -- the same
   treatment the grid gives "Gameday Grid", so each view says what it is.
   Scoped to this hero: other pages put a chip inside their h1. */
.hero-copy--grid > h1 span {
    color: #86c232;
}

/* Full width on a narrow screen, so both halves are as big as the screen
   allows. Not on a short, wide one: a phone held sideways would stretch it
   into a banner. */
@media (max-width: 700px) {
    .sticky-header .view-switch {
        width: 100%;
    }
}

/* The switch between this week's two views. A green block slides to the view
   you are on, which is what keeps it from reading as more tab navigation: the
   nav moves between sections of the site, this moves between two readings of
   one week. Grid, not flex, so both halves are exactly half the track and the
   block lands on them however long the labels are. */
.view-switch {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    padding: 5px;
    border: 1px solid rgba(134, 194, 50, 0.35);
    border-radius: 999px;
    background: rgba(8, 15, 32, 0.75);
    box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.45);
}

/* Its own transition name, so the browser slides it from the side it was on
   to the side it is going to. Without this the whole switch would cross-fade
   and the block would appear to jump. */
.view-switch__knob {
    view-transition-name: view-switch-knob;
    position: absolute;
    top: 5px;
    bottom: 5px;
    left: 5px;
    width: calc(50% - 5px);
    border-radius: 999px;
    background: linear-gradient(180deg, #9bd63f, #6fa828);
    box-shadow: 0 0 16px rgba(134, 194, 50, 0.55);
    transition: transform 0.25s cubic-bezier(0.4, 0.9, 0.3, 1);
}

.view-switch--gameday .view-switch__knob {
    transform: translateX(100%);
}

.view-switch__option {
    position: relative;    /* above the knob */
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 8px 18px;
    box-sizing: border-box;
    border-radius: 999px;
    color: #cbd3e7;
    /* 700, not 800: the leaderboard loads Lato 400;700 and the grid
       400;700;900, so 800 was synthesized on one page and a real 900 face on
       the other -- the same control, a hair wider on the grid. 700 exists on
       both, so it renders identically. */
    font: 700 15px 'Lato', sans-serif;
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.2s ease;
}

.view-switch__option.is-active,
.view-switch__option.is-active:visited {
    color: #0b132b;
}

.view-switch__option:hover:not(.is-active) {
    color: #ffffff;
}

.view-switch__option:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .view-switch__knob {
        transition: none;
    }
}

/* The way into the grid used to be hidden here, because the grid was for big
   screens only. It works on a phone now, so the switch stays -- just tighter,
   without its icons, to fit two labels across a 375px screen. */
@media (max-width: 700px), (max-height: 500px) {
    .view-switch__option {
        padding: 8px 10px;
        font-size: 14px;
        gap: 6px;
    }

    .view-switch__option i {
        display: none;
    }
}

.chart-card {
    padding: 14px;
}

.chart-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.chart-frame {
    background: rgba(255, 255, 255, 0.12);
    border-radius: 12px;
    padding: 10px;
    border: 1px solid rgba(255, 255, 255, 0.25);
}

/* Season page: last week's winners, named beside the chart's gold and silver.
   The swatches use the same gradient stops as the bars in
   cumulative_scores_template.html, so the key matches what it explains. */
.winners-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.winners-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: #e8edf7;
    font-size: 14px;
}

.winners-legend__swatch {
    flex: 0 0 auto;
    width: 28px;
    height: 12px;
    border-radius: 3px;
}

.winners-legend__item.is-gold .winners-legend__swatch {
    background: linear-gradient(90deg, #8a6a12, #f2c94c 25%, #fff6cc 50%, #e0b43a 75%, #9c7715);
    box-shadow: 0 0 8px rgba(242, 201, 76, 0.6);
}

.winners-legend__item.is-silver .winners-legend__swatch {
    background: linear-gradient(90deg, #5f6875, #c9d0da 25%, #ffffff 50%, #b8c0cc 75%, #6b7483);
    box-shadow: 0 0 8px rgba(201, 208, 218, 0.5);
}

.winners-legend__item.is-gold strong { color: #ffd23f; }
.winners-legend__item.is-silver strong { color: #e3e8f0; }

.chart-legend {
    color: #0f1424;
    background: #ffeb3b;
    border: 1px solid #c9a800;
    font-weight: 800;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.hero-copy h1 {
    margin: 4px 0 8px;
    font-family: 'Teko', sans-serif;
    letter-spacing: 0.5px;
    font-size: clamp(30px, 4vw, 44px);
    /* The history heading carries a "Final" / "In progress" chip. As inline
       content it aligned to the text baseline and floated high against a 44px
       heading; flex centers it against the line box instead, and the gap
       replaces the stray whitespace that used to separate them. */
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.hero-copy h1 .chip {
    font-family: 'Lato', sans-serif;
    letter-spacing: 0;
    /* Teko's line-height makes an inherited chip look oversized next to it. */
    font-size: 13px;
    padding: 5px 12px;
}

.eyebrow {
    text-transform: uppercase;
    letter-spacing: 2px;
    font-size: 12px;
    color: #86c232;
}

.eyebrow.small {
    font-size: 11px;
}

.lede {
    max-width: 620px;
    color: #cbd3e7;
    margin: 0 0 10px;
    /* Every lede on this site is longer than the 620px measure, so they all
       wrap -- and left alone they orphan the last word on a line of its own,
       which reads as a defect rather than as typography. Balancing splits the
       lines evenly instead. Ignored by browsers that do not support it, which
       simply get today's wrapping. */
    text-wrap: balance;
}

.hero-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.chip.holiday-chip {
    position: relative;
    overflow: hidden;
    border: 1px solid transparent;
    background:
        linear-gradient(120deg, rgba(140, 14, 14, 0.92), rgba(195, 34, 34, 0.92) 42%, rgba(15, 95, 44, 0.92)) padding-box,
        linear-gradient(120deg, rgba(140, 14, 14, 0.95), rgba(195, 34, 34, 0.95) 42%, rgba(15, 95, 44, 0.95)) border-box;
    color: #fff4e0;
    padding: 14px 22px;
    font-size: 15px;
    letter-spacing: 0.3px;
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.25);
    min-height: 120px;
    display: inline-flex;
    align-items: center;
    gap: 14px;
}

.holiday-chip__bg {
    position: absolute;
    left: 8px;
    top: 50%;
    width: 220px;
    height: auto;
    transform: translateY(-50%);
    opacity: 0.75;
    pointer-events: none;
}

.holiday-chip__text {
    position: relative;
    z-index: 1;
    padding-left: 170px;
    font-family: 'Teko', sans-serif;
    font-size: 20px;
    letter-spacing: 0.6px;
    text-transform: uppercase;
}

.holiday-chip__trail {
    position: absolute;
    left: -18px;
    top: 50%;
    width: 140px;
    height: 4px;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 236, 200, 0.8), rgba(255, 255, 255, 0));
    transform: translateY(-50%);
    opacity: 0.7;
}

.hero-note {
    color: #cbd3e7;
    font-size: 14px;
}

.stat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.holiday-section {
    margin: 6px 0 16px;
}

.chip {
    background: rgba(255, 255, 255, 0.08);
    color: #f7fbff;
    padding: 8px 12px;
    border-radius: 12px;
    font-size: 13px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.chip.subtle {
    background: #f2f4f7;
    color: #0f172a;
    border: 1px solid #d2d7df;
}

/* Text for screen readers only. The table headers are icon-only by design, so
   this is what carries their meaning to assistive tech. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Preview rows behave as links; make keyboard focus obvious. */
.clickable-row {
    cursor: pointer;
}

.clickable-row:focus-visible {
    outline: 3px solid #38bdf8;
    outline-offset: -3px;
}

/* Auto-refresh status: a quiet "updated 12s ago" so a stale page looks stale
   instead of silently wrong. */
/* The pool's record against the spread: the rate leads, the raw count
   follows it quieter, because the rate is the thing you read and the count is
   what tells you how much is behind it. */
.chip.vegas strong { font-weight: 800; }

.chip__aside {
    opacity: 0.72;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

.chip.live-status {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

/* refresh-countdown.js hides the countdown with [hidden] once refreshing
   stops, and .chip's display: inline-flex outranks the browser's own rule --
   the trap that once left the picks panel impossible to close. */
[data-refresh-countdown][hidden] {
    display: none;
}

.live-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #16a34a;
    box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55);
    animation: live-pulse 2.4s ease-out infinite;
    flex-shrink: 0;
}

@keyframes live-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.55); }
    70%  { box-shadow: 0 0 0 7px rgba(22, 163, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}

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

/* These legends sit inside .table-card, which is light, while most of the page
   is dark navy -- so they were wearing colours picked for the dark ground.
   #cbd3e7 on #f6f8fb is 1.4:1 against a 4.5:1 minimum, which is not "faint",
   it is invisible. The same trap the season grid hit.

   The participant page also uses this container, but fills it with .chip.subtle,
   which sets its own dark ink and is unaffected. */
.leaderboard-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 14px;
    align-items: center;
    color: #56607a;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.legend-item i,
.legend-sigma {
    color: #56607a;
    font-size: 12px;
}

/* The two that mean something carry the colour they mean, matching the checks
   on a player's own page. Scoped to the legend: the same icons head the table
   on the dark navy row, where they are already light on purpose. */
/* Two greens and two reds, because there are two grounds.
   #3f7d12 measures 4.10:1 against the row-hover blue, under the 4.5 minimum,
   so anything sitting in a hoverable row needs the darker step. */
.legend-item .fa-check-circle,
.table-leaderboard td.col-correct { color: #2f6b0e; }
.legend-item .fa-times-circle,
.table-leaderboard td.col-incorrect { color: #a32d20; }

/* The column heads carry the same meaning on the navy thead, where the dark
   pair is 2.4:1 and unreadable. These are the light steps: #86c232 is the
   site's own accent green. */
.table-leaderboard thead .fa-check-circle { color: #86c232; }
.table-leaderboard thead .fa-times-circle { color: #ff8a80; }

.chart-legend.chip {
    background: #ffeb3b;
    color: #0f1424;
    border: 1px solid #c9a800;
    font-weight: 800;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.chip.highlight {
    background: #ffb703;
    color: #1b1b1b;
    border-color: #f39c00;
    font-weight: 700;
}

.featured-matchup {
    padding: 18px;
    color: #f7fbff;
}

.featured-rotator {
    position: relative;
    overflow: hidden;
    min-height: 200px;
    padding: 18px 16px 18px;
}

.featured-rotator .featured-label {
    margin-bottom: 12px;
}

.featured-matchup.slide {
    position: absolute;
    top: 34px;
    left: 0;
    right: 0;
    bottom: 0;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.5s ease, transform 0.5s ease;
    pointer-events: none;
    padding-top: 6px;
}

.featured-matchup.slide.active {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
    z-index: 1;
}

#rotator-counter {
    margin-left: 8px;
    color: #d1d8ea;
    font-weight: 600;
}

.featured-label {
    padding-left: 4px;
}

.featured-label {
    text-transform: uppercase;
    letter-spacing: 2px;
    font-size: 11px;
    color: #9ae66e;
    margin-bottom: 8px;
}

.featured-teams {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: 10px;
    align-items: center;
    margin-top: 12px;
}

.team-side {
    display: flex;
    gap: 10px;
    align-items: center;
}

.team-side.right {
    justify-content: flex-end;
}

.team-side img {
    height: 64px;
    width: 64px;
    object-fit: contain;
}

.team-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Without this the default `stretch` sizes every child to the widest one,
       which is the team name -- so the spread pill grew to "Buccaneers" width
       on one row and "Bills" width on the next. The .align-right variant below
       already avoided it by setting flex-end. */
    align-items: flex-start;
}

.team-text.align-right {
    text-align: right;
    align-items: flex-end;
}

.team-role {
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 11px;
    font-weight: 700;
    color: #9ae66e;
}

.team-role.home {
    color: #ffb703;
}

.team-name {
    font-family: 'Teko', sans-serif;
    font-size: 20px;
    letter-spacing: 0.4px;
}

.team-record, .team-spread {
    font-size: 13px;
    color: #d1d8ea;
}

.table-card .team-record {
    color: #2c3651;
    font-weight: 700;
}

.vs-pill {
    background: #ff8c00;
    color: #0d1323;
    padding: 6px 10px;
    border-radius: 999px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
}

.featured-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 12px;
    font-size: 13px;
    color: #dbe4ff;
    line-height: 1.4;
    min-height: calc(2 * 1.4em);
}

/* The news ticker is the one thing on the site that moves for as long as a
   page is open, so its per-frame cost is paid continuously. Measured in
   Chrome, the original Odds Buzz ticker -- a step on every display refresh
   over a live backdrop blur -- was about 90% of the preview page's idle CPU.
   tests/test_ticker_cost.py pins what brought that down:

   - No backdrop blur here, unlike every other .glass-card. The blur would be
     recomposited under the moving text on every step, and over this page's
     smooth gradient it was not visibly doing anything.
   - news-ticker.js moves the track in whole 2px steps, 30 a second, rather
     than on every refresh -- 120 frames a second on a ProMotion display. */
.news-ticker {
    margin: 10px 0 16px;
    padding: 10px 12px;
    overflow: hidden;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* Paused when nobody is watching (set by news-ticker.js when the ticker is
   off-screen or the tab is hidden), and while a pointer or keyboard focus is
   on it, so a moving headline can be clicked. */
.news-ticker.is-paused .ticker-track,
.news-ticker:hover .ticker-track,
.news-ticker:focus-within .ticker-track {
    animation-play-state: paused;
}

.ticker-label {
    color: #9ae66e;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 2px;
    margin-bottom: 6px;
}

/* No animation here: news-ticker.js starts it once it has measured a whole
   number of steps. Without the script the headlines simply sit still, which
   is better than the blurry fractional steps a fixed CSS distance gives. */
.ticker-track {
    display: inline-flex;
    width: max-content;
    white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
    .ticker-track {
        animation: none !important;
    }

    /* Held still, the headlines past the edge can be swiped to instead. */
    .news-ticker {
        overflow-x: auto;
    }
}

.ticker-group {
    display: flex;
    flex: 0 0 auto;
    gap: 44px;
    padding-right: 44px;
}

.ticker-item {
    position: relative;
    flex: 0 0 auto;
    color: #f7fbff;
    font-size: 14px;
    text-decoration: none;
}

.ticker-item:hover,
.ticker-item:focus-visible {
    color: #9ae66e;
    text-decoration: underline;
}

/* A dot before every headline, outside its link's box and ignoring the
   pointer, so it is neither underlined nor clickable. Every headline, not just
   each one after another: the seam where one copy of the loop meets the next
   is between two groups, which a sibling selector never sees. The first dot
   falls in the previous copy's trailing gap, or off the clipped left edge. */
.ticker-item::before {
    content: "\2022";
    position: absolute;
    left: -26px;
    color: #6f7fa3;
    pointer-events: none;
}

/* The distance is set by news-ticker.js as a whole number of pixels. */
@keyframes ticker-slide {
    from { transform: translateX(0); }
    to { transform: translateX(calc(-1px * var(--ticker-shift, 0))); }
}

.table-card {
    margin-top: 8px;
    padding: 12px;
    background: #f6f8fb;
    border-radius: 14px;
    box-shadow: 0 12px 35px rgba(0, 0, 0, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.table-header {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    align-items: flex-start;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.table-header h2 {
    margin: 0;
    font-family: 'Teko', sans-serif;
    font-size: 26px;
    /* .table-card is light (#f6f8fb) on every page, but the body it sits in is
       dark, so an unset heading inherits near-white and vanishes. Two one-off
       workarounds (.leaderboard-card h2, .dark-heading) already existed for
       this; setting the default here fixes it everywhere instead. */
    color: #0f172a;
}

/* The eyebrow's green reads well on the dark hero but is weak on the light
   card, so darken it there. */
.table-header .eyebrow {
    color: #4d7c0f;
}

.table-header p {
    margin: 2px 0 0;
    color: #455166;
    font-size: 14px;
}

.leaderboard-card .table-header p {
    color: #2c3651;
}

.leaderboard-card .table-header h2 {
    color: #0f172a;
}

.table-card .dark-heading {
    color: #0f172a;
}

.leaderboard-card .table-header {
    align-items: flex-end;
}

.leaderboard-meta {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
}

.chip.winner {
    background: linear-gradient(135deg, #fdd835 0%, #f39c12 100%);
    color: #0f172a;
    font-weight: 800;
    border-color: #f39c12;
    box-shadow: 0 10px 28px rgba(243, 156, 18, 0.25);
}

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

.table-alternating tr:hover {
    background-color: #e8f5e9;
    cursor: pointer;
}

.logo-cell {
    text-align: left;
}

.logo-cell.right {
    text-align: right;
}

.team-cell {
    position: relative;
    overflow: hidden;
}

.team-cell-away {
    padding-left: 0;
}

.team-cell-home {
    padding-right: 0;
}

.team-cell > * {
    position: relative;
    z-index: 1;
}

.info-cell {
    text-align: left;
    line-height: 1.4;
    font-weight: 500;
    font-size: 13px;
}

.detail {
    margin-bottom: 4px;
    color: #2c3651;
}

.team-line {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.team-line.align-right {
    align-items: flex-end;
}

.spread-line {
    /* Quiet by default. Only the favorite gets the chip below -- which is
       how the operator's own entry form prints a matchup, the line beside the
       favorite and the underdog's cell left blank. That halves the number of
       boxes in a sixteen-row column and makes the sign readable without
       reading every "+" and "-".

       The transparent border is load-bearing: it keeps a plain number exactly
       the same size as a chipped one, so the two columns still line up. */
    color: #2c3651;
    font-weight: 700;
    font-size: 15px;
    background-color: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    padding: 3px 8px 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    margin-top: 2px;
    /* Every pill the same width regardless of its value. Spreads run from two
       characters ("+7") to five ("-12.5"); min-width sizes them all to the
       widest, and tabular figures stop "+1.5" and "+9.5" differing. Wider
       content such as "Spread N/A" is free to exceed it. */
    box-sizing: border-box;
    /* Sized for the widest value ("-12.5") in the widest context: the preview
       table renders these in Lato, which is wider than the participant page's
       Teko, so a floor tuned to Teko alone leaves the five-character values
       sticking out. */
    min-width: 58px;
    font-variant-numeric: tabular-nums;
}

/* The favorite carries the line, and gold is how you spot it.

   This was translucent white for a while, on the reasoning that an opaque fill
   punched a hard-edged hole through the team-logo watermark underneath. That
   was true of white, which had almost no contrast with the row behind it and
   so read as a gap rather than a badge. Gold has plenty, so the same fill now
   reads as deliberate -- and being able to see which side is favored at a
   glance, down a column of sixteen rows, is worth more than an unbroken
   watermark.

   Scoped to .table-alternating, which is the preview table alone. The
   participant page draws the same .spread-line class and keeps this quieter
   treatment.

   The same gradient as .chip.winner. The two never share a page: the winner
   chip belongs to the leaderboard and this to the preview table. */
.spread-line.is-favorite {
    color: #0d1323;
    background-color: rgba(255, 255, 255, 0.66);
    border-color: rgba(13, 19, 35, 0.12);
}

/* The spread pill is inline-flex, so text-align on the pill only centers the
   text inside it -- it cannot move the pill. Position comes from the
   containing block, so the home column is right-aligned to put its pill under
   the right-aligned team name. The away column is already left-aligned. */
.table-alternating td.team-cell-home {
    text-align: right;
}


/* Responsiveness */
@media only screen and (max-width: 600px) {
    .table-alternating table, 
    .table-alternating th,
    .table-altnerating thead, 
    .table-alternating td {
        font-size: 10px;
        line-height: 1.5;
    }
    
    .table-alternating thead th {
        font-size: 16px;
    }

    .table-leaderboard table, 
    .table-leaderboard th,
    .table-leaderboard thead, 
    .table-leaderboard td {
        font-size: 16px;
        font-weight: 400;
        line-height: 1.8;
    }

    .table-leaderboard thead th {
        font-size: 80%; /* Keep thead font 80% of the base font size */
    }

    .table-participant table,
    .table-participant th,
    .table-participant thead,
    .table-participant td {
        font-size: 90%;
    }

    .spread-line {
        font-size: 16px;
    }

    .table-participant thead th {
        font-size: 120%; /* Keep thead font 120% of the base font size */
    }

    .hero {
        padding: 16px 6px;
    }

    .featured-teams {
        grid-template-columns: 1fr;
    }

    /* Let the spotlight resize naturally on narrow screens to avoid clipping */
    .featured-rotator {
        height: 320px;
    }

    .featured-meta {
        display: flex;
        flex-direction: column;
        row-gap: 4px;
    }

    .featured-meta span {
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .featured-matchup.slide {
        position: absolute;
        top: 34px;
        left: 0;
        right: 0;
        bottom: 0;
        padding-top: 6px;
        display: block;
        visibility: hidden;
        opacity: 0;
        transform: translateY(6px);
    }

    .featured-matchup.slide.active {
        display: block;
        visibility: visible;
        opacity: 1;
        transform: translateY(0);
    }

    .leaderboard-shell {
        padding: 10px 6px 30px;
    }

    /* Tweak matchup table spacing on narrow screens */
    .logo-cell {
        padding: 0 8px 0 4px;
    }

    .table-alternating td.info-cell {
        padding-left: 6px;
        font-size: 11px;
    }

    .table-alternating td img {
        max-height: 38px;
    }
}

/* ---- season history grid ---- */
/* Sits inside .table-card, which is light (#f6f8fb), while the page body is
   dark. The table must therefore set its own dark-on-light colors rather than
   inheriting the body's light text. */
.season-pills {
    margin-top: 14px;
    flex-wrap: wrap;
}

.season-pills .pill {
    text-decoration: none;
}

.table-history {
    /* Shared by the rank column's width and the name column's sticky offset,
       so the two can never drift apart. */
    --rank-col-width: 46px;
    border-collapse: separate;
    border-spacing: 0;
    font-family: 'Teko', sans-serif;
    font-size: 17px;
    font-weight: 600;
    color: #0f172a;
    background: #fdfefe;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.table-history th,
.table-history td {
    padding: 6px 10px;
    text-align: center;
    border-bottom: 1px solid #e2e8f0;
}

.table-history thead th,
.table-history thead td {
    background: #15284c;
    color: #e8edf7;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.table-history .games-row th,
.table-history .games-row td {
    color: #9fb3d1;
    font-size: 13px;
    padding-top: 0;
}

/* The player column stays put while the weeks scroll under it, so you can
   always see whose row you are reading. Each sticky cell repeats its own row's
   background, otherwise the stripes would show through as it scrolls. */
/* The two sticky columns must tile exactly. The rank column's width was
   content-box, so its real rendered width was 44px plus whatever padding
   applied -- while the name column was pinned at a hard-coded left: 44px. Any
   mismatch leaves a vertical strip that neither column paints, and the
   scrolling week columns show through it like a window.

   Pinning the rank column to an exact border-box width and deriving the name
   column's offset from the same variable makes them tile whatever the padding
   is, including inside the mobile media query. */
.table-history .rank-col {
    position: sticky;
    left: 0;
    z-index: 2;
    box-sizing: border-box;
    width: var(--rank-col-width);
    min-width: var(--rank-col-width);
    max-width: var(--rank-col-width);
    padding-left: 4px;
    padding-right: 4px;
    color: #64748b;
}

.table-history .name-col {
    position: sticky;
    /* 1px of deliberate overlap so no sub-pixel seam can open up between them. */
    left: calc(var(--rank-col-width) - 1px);
    z-index: 2;
    text-align: left;
    min-width: 150px;
    max-width: 190px;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 700;
}

.table-history thead .rank-col,
.table-history thead .name-col {
    z-index: 3;
}

.table-history tbody tr:nth-child(odd),
.table-history tbody tr:nth-child(odd) .rank-col,
.table-history tbody tr:nth-child(odd) .name-col {
    background: #fdfefe;
}

.table-history tbody tr:nth-child(even),
.table-history tbody tr:nth-child(even) .rank-col,
.table-history tbody tr:nth-child(even) .name-col {
    background: #edf2f7;
}

.table-history .week-best {
    background: rgba(22, 163, 74, 0.18);
    font-weight: 700;
}

.table-history .did-not-play {
    color: #94a3b8;
}

.table-history .total-col {
    font-weight: 700;
    color: #0f172a;
}

.table-history .pct-col {
    color: #475569;
}

.legend-best {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 4px;
    background: rgba(22, 163, 74, 0.35);
}

@media (max-width: 760px) {
    .table-history .name-col {
        min-width: 110px;
        max-width: 130px;
        font-size: 15px;
    }

    .table-history th,
    .table-history td {
        padding: 5px 7px;
        font-size: 15px;
    }
}

.lede.caution {
    color: #fbbf24;
    font-size: 14px;
    margin-top: 6px;
}

/* ---- week replay ---- */
.table-history.replay-games td {
    text-align: left;
}

.table-history .score-col {
    text-align: center;
    font-weight: 700;
    width: 56px;
}

/* Links inside the grid must take their cell's color, not the browser's blue
   and visited-purple. The week headers sit on the dark navy thead, where the
   default link colors are close to unreadable. This covers the week headers,
   the score cells and the player names in one rule -- any new link in a
   .table-history is handled automatically. */
.table-history a,
.table-history a:link,
.table-history a:visited {
    color: inherit;
    text-decoration: none;
}

/* Color no longer signals that these are links, so hover and keyboard focus
   have to. */
.table-history a:hover {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.table-history a:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 2px;
    border-radius: 3px;
}

/* Week headers are the discoverable entry point into a replay, so they carry a
   permanent hint. The score cells stay clean -- there are over a thousand of
   them and underlining every one would be noise. */
/* Must repeat :link/:visited. A pseudo-class counts in the same specificity
   column as a class, so the plain `.table-history thead a` selector loses to
   `.table-history a:link` above and the underline silently never applied. */
.table-history thead a,
.table-history thead a:link,
.table-history thead a:visited {
    text-decoration: underline dotted rgba(232, 237, 247, 0.55);
    text-underline-offset: 4px;
}

.table-history thead a:hover {
    text-decoration: underline solid #ffffff;
}

/* The season selector pills are anchors in the history views and buttons in the
   live leaderboard. Scoped to the anchor so the live buttons are untouched;
   .pill.active is more specific and keeps its own color. */
.sort-pills a.pill,
.sort-pills a.pill:link,
.sort-pills a.pill:visited {
    color: #0f172a;
}


/* ---- participant game tracker ---- */

/* The shared .team-line stacks in a column for the preview page, so the
   direction has to be overridden explicitly here, not just the display. */
.table-participant .team-line {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 10px;
}

.table-participant .team-line.align-right {
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
}

.table-participant .team-logo {
    width: 30px;
    height: 30px;
    object-fit: contain;
    flex-shrink: 0;
}

.table-participant .team-text {
    min-width: 0;
}

.table-participant .team-text.align-right {
    text-align: right;
}

.table-participant .team-name {
    font-size: 20px;
    font-weight: 600;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The picked team is the point of the page, so it gets the strongest colour
   in the row -- not a wash over it.

   This was rgba(15, 23, 42, 0.045): dark navy at 4.5%, laid on top of whatever
   tint the row already had. It did not add colour, it subtracted light, so the
   one cell a player is looking for came out the muddiest thing in the row and
   read as though something were wrong with it. The row now carries the pale
   tint and the pick carries the vivid one. */
.table-participant tr.correct .team-cell.is-pick,
.table-participant tr.completed-correct .team-cell.is-pick {
    background: #c3e6c6;
}

.table-participant tr.incorrect .team-cell.is-pick,
.table-participant tr.completed-incorrect .team-cell.is-pick {
    background: #f7c9c6;
}

/* Nothing decided yet: a neutral lift, since there is no result to colour. */
.table-participant tr.not-started .team-cell.is-pick {
    background: rgba(15, 23, 42, 0.05);
}

.table-participant .team-cell.is-pick .team-name {
    font-weight: 700;
}

.table-participant .result-cell {
    text-align: center;
    line-height: 1.25;
}

.table-participant .kickoff,
.table-participant .game-clock {
    font-size: 15px;
    color: #475569;
}

/* How the pick fared against the spread -- the part that used to require
   mental arithmetic on every row. */
.table-participant .margin-line {
    margin-top: 3px;
    font-family: 'Lato', sans-serif;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.table-participant .margin-line.covered {
    color: #15803d;
}

.table-participant .margin-line.missed {
    color: #b3261e;
}

.table-participant .margin-line.push {
    color: #475569;
}

@media (max-width: 760px) {
    .table-participant {
        font-size: 17px;
    }

    .table-participant th,
    .table-participant td {
        padding: 8px 5px;
    }

    .table-participant .team-line {
        gap: 6px;
    }

    .table-participant .team-logo {
        width: 24px;
        height: 24px;
    }

    .table-participant .team-name {
        font-size: 16px;
    }

    .table-participant .pick-icon {
        width: 22px;
    }
}

/* ---- site navigation ----
   One tab bar on every page, replacing six different sets of hero buttons
   (four of which were "Back to X"). Sits on the dark page background, above
   the hero card. */
.site-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px 20px;
    flex-wrap: wrap;
    padding: 14px 6px 4px;
    max-width: 100%;
}

.site-nav__brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: 'Teko', sans-serif;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #e8edf7;
    text-decoration: none;
    white-space: nowrap;
}

.site-nav__brand i {
    color: #86c232;
    font-size: 18px;
}

.site-nav__brand:hover {
    color: #ffffff;
}

.site-nav__tabs {
    display: flex;
    gap: 4px;
    padding: 4px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 999px;
}

.site-nav__tab {
    padding: 8px 18px;
    border-radius: 999px;
    font-family: 'Lato', sans-serif;
    font-size: 14px;
    font-weight: 700;
    color: #cbd3e7;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}

.site-nav__tab:hover {
    color: #ffffff;
    background: rgba(255, 255, 255, 0.08);
}

.site-nav__tab.is-active {
    background: #86c232;
    color: #0b132b;
}

/* Run by nav-feedback.js from a tap on the nav or the view switch until the
   next page replaces it. Transform only, so the compositor does the work
   rather than a repaint every frame, and it runs once: quickly most of the
   way across, then waits there for the page. */
.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1000;
    width: 100%;
    height: 3px;
    background: #86c232;
    box-shadow: 0 0 8px rgba(134, 194, 50, 0.7);
    transform: scaleX(0);
    transform-origin: left;
    animation: nav-progress 6s cubic-bezier(0.1, 0.6, 0.2, 1) forwards;
    pointer-events: none;
}

@keyframes nav-progress {
    to { transform: scaleX(0.9); }
}

@media (prefers-reduced-motion: reduce) {
    .nav-progress {
        animation: none;
        transform: none;
    }
}

.site-nav__tab:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 2px;
}

@media (max-width: 620px) {
    .site-nav {
        justify-content: center;
        padding: 10px 4px 2px;
    }

    .site-nav__brand {
        font-size: 21px;
    }

    .site-nav__tabs {
        width: 100%;
        justify-content: center;
    }

    .site-nav__tab {
        padding: 8px 14px;
        font-size: 13px;
    }
}

/* --------------------------------------------------------------------------
   Pick mode

   The pick bar and dialogs sit outside .table-card, which is the light island
   on this dark page -- so every color here is set explicitly. Inheriting from
   the body renders them invisible.
   -------------------------------------------------------------------------- */

.pick-toggle {
    background: #86c232;
    color: #0d1323;
    font-weight: 700;
    border: 1px solid #86c232;
    cursor: pointer;
    font-family: inherit;
}

.pick-toggle[aria-pressed="true"] {
    background: transparent;
    color: #86c232;
}

/* Rows navigate to ESPN when browsing and are pick targets when picking. The
   cursor has to say which. */
[data-pick-mode="true"] .clickable-row {
    cursor: default;
}

[data-pick-mode="true"] .team-cell {
    cursor: pointer;
    border-radius: 10px;
    transition: background-color 120ms ease, box-shadow 120ms ease;
}

[data-pick-mode="true"] .team-cell:hover {
    background-color: rgba(134, 194, 50, 0.16);
}

[data-pick-mode="true"] .team-cell:focus-visible {
    outline: 3px solid #0d1323;
    outline-offset: -3px;
}

/* The picked side. The unpicked side of a decided game fades, so a column of
   16 rows reads at a glance. */
[data-pick-mode="true"] .team-cell[aria-checked="true"] {
    background-color: rgba(134, 194, 50, 0.28);
    box-shadow: inset 0 0 0 2px #86c232;
}

[data-pick-mode="true"] .clickable-row.is-decided .team-cell[aria-checked="false"] {
    opacity: 0.45;
}

/* A tick as well as the green fill, so the picked side is not signalled by
   color alone: a badge on the corner of the logo. It used to sit at the
   cell's inner edge, which the spread has now.

   Taken out of the flow, so the tick appearing can never widen anything and
   shunt the rows below down the page as a player taps -- which is what it did
   when it was inline, beside a long name.

   Hidden by default rather than hidden-when-unchecked: outside pick mode the
   cells carry no aria-checked at all, and an [aria-checked="false"] rule would
   leave every tick showing.

   The child combinator outranks Font Awesome's own
   `.fa,.fas{display:inline-block}` -- same specificity as a bare .pick-check,
   linked after this stylesheet, so it would win on source order. */
.team-logo-wrap > .pick-check {
    display: none;
    position: absolute;
    bottom: -4px;
    color: #3f7d12;
    font-size: 18px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 2px #fff;
    z-index: 2;
    pointer-events: none;
}

.team-cell-away .team-logo-wrap > .pick-check {
    right: -6px;
}

.team-cell-home .team-logo-wrap > .pick-check {
    left: -6px;
}

[data-pick-mode="true"] .team-cell[aria-checked="true"] .pick-check {
    display: block;
}

/* Sticky, because the submit button unlocks when the last game is picked --
   by which point the player is at the bottom of a 16-row table and a control
   at the top of the card would appear off-screen. */
.pick-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 900;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px 18px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: #0d1323;
    color: #f7fbff;
    border-top: 2px solid #86c232;
    box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.35);
}

.pick-bar[hidden] {
    display: none;
}

.pick-bar__progress {
    font-weight: 700;
    letter-spacing: 0.3px;
}

.pick-bar__field {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.pick-bar__field label {
    font-size: 14px;
}

.pick-bar__field input {
    width: 4.5em;
    padding: 8px 10px;
    border-radius: 10px;
    border: 1px solid #47506b;
    background: #f7fbff;
    color: #0d1323;
    font: inherit;
    font-weight: 700;
    text-align: center;
}

.pick-bar__submit {
    background: #86c232;
    color: #0d1323;
    font-family: inherit;
    font-weight: 800;
    font-size: 15px;
    padding: 10px 18px;
    border: none;
    border-radius: 12px;
    cursor: pointer;
}

.pick-bar__submit[hidden] {
    display: none;
}

.pick-dialog {
    max-width: 26rem;
    width: calc(100% - 32px);
    padding: 22px;
    border: none;
    border-radius: 16px;
    background: #f6f8fb;
    color: #0d1323;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
}

.pick-dialog::backdrop {
    background: rgba(4, 8, 18, 0.62);
}

.pick-dialog h2 {
    margin: 0 0 8px;
    font-family: 'Teko', sans-serif;
    font-size: 26px;
    color: #0d1323;
}

.pick-dialog p {
    margin: 0 0 14px;
    color: #2c3651;
    font-size: 14px;
}

.pick-dialog input {
    /* This site sets no global box-sizing, so width:100% would size the
       content box and then add 12px of padding and a 1px border on each side
       -- 26px of overflow past the dialog's own padding, out the right edge. */
    box-sizing: border-box;
    width: 100%;
    padding: 10px 12px;
    margin-bottom: 14px;
    border: 1px solid #d2d7df;
    border-radius: 10px;
    font: inherit;
    color: #0d1323;
    background: #fff;
}

.pick-dialog__actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

.pick-dialog__actions button {
    padding: 10px 16px;
    border-radius: 10px;
    border: 1px solid #d2d7df;
    background: #fff;
    color: #0d1323;
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.pick-dialog__actions .is-primary {
    background: #86c232;
    border-color: #86c232;
}

.pick-dialog__actions button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.pick-dialog__error {
    color: #a11515;
    font-weight: 700;
}

.pick-dialog__error[hidden] {
    display: none;
}

@media (max-width: 560px) {
    .pick-bar {
        gap: 8px 12px;
        padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    }

    .pick-bar__progress {
        width: 100%;
        text-align: center;
    }
}

/* The desktop hand-off can't attach the file for you, so the steps have to be
   on screen before the mail client takes focus -- not only inside the draft,
   where they are easy to skip past. */
.pick-dialog__steps {
    margin: 0 0 16px;
    padding-left: 22px;
    color: #2c3651;
    font-size: 14px;
    line-height: 1.55;
}

.pick-dialog__steps strong {
    color: #0d1323;
}

.pick-dialog__actions {
    flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   The waiting state: the site is up but this week's workbook is not published.

   Informational, not a warning -- nothing is wrong, the operator simply has
   not posted the spreads yet. Calmer than the practice-run banner was, because
   this one is the normal resting state between publishes rather than something
   that needs undoing.
   -------------------------------------------------------------------------- */

.waiting-banner {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0 0 14px;
    padding: 14px 18px;
    border-radius: 14px;
    background: rgba(247, 251, 255, 0.06);
    border: 1px solid rgba(134, 194, 50, 0.45);
    border-left: 4px solid #86c232;
    color: #d9e2f0;
}

.waiting-banner strong {
    color: #f7fbff;
    font-size: 17px;
    letter-spacing: 0.2px;
}

.waiting-banner span {
    font-size: 14px;
    line-height: 1.45;
}

/* --------------------------------------------------------------------------
   Recent form

   Ten bars, one per completed game, oldest on the left through to newest on
   the right -- the same direction in both cells, so the two are read the same
   way rather than mirrored. Wins rise from the mid-line and losses fall
   below it, so the *shape* carries the trend and the colour only confirms it
   -- a tall red bar under a common baseline reads as a good week, which is
   exactly the confusion this avoids.

   Width is fit-content, not the default full-width block: the mid-line is
   painted as a background gradient, and a stretched strip drew a rule clear
   across the cell and through the logo watermark.
   -------------------------------------------------------------------------- */

.form-strip {
    display: flex;
    align-items: center;
    gap: 2.5px;
    height: 26px;
    margin-top: 6px;
    width: fit-content;
    /* Centred in the cell, like everything else in it. */
    margin-left: auto;
    margin-right: auto;
    /* The mid-line the bars hang off. */
    background: linear-gradient(to bottom,
        transparent calc(50% - 0.5px),
        rgba(44, 54, 81, 0.3) calc(50% - 0.5px),
        rgba(44, 54, 81, 0.3) calc(50% + 0.5px),
        transparent calc(50% + 0.5px));
}

.form-bar {
    position: relative;
    flex: 0 0 auto;
    width: 7px;
    height: 26px;
}
/* --bar is the margin as 0..1, already capped at three scores by form.py. The
   floor of 2px keeps a one-point game visible instead of vanishing. */
.form-bar > span {
    position: absolute;
    left: 0;
    right: 0;
    height: calc(2px + (var(--bar, 0) * 10px));
    border-radius: 1.5px;
    display: block;
}
.form-bar.is-w > span { bottom: 50%; margin-bottom: 1px; background-color: #3f7d12; }
.form-bar.is-l > span { top: 50%; margin-top: 1px; background-color: #b3392b; }
/* A tie is neither, so it sits on the line as a flat dash. */
.form-bar.is-t > span {
    top: calc(50% - 1px);
    height: 2px;
    background-color: #8b97ab;
}

/* The strip is decoration during picking: it must never swallow a tap meant
   for the team cell, which is the whole tap target in pick mode. */
[data-pick-mode="true"] .form-strip { pointer-events: none; }

/* --------------------------------------------------------------------------
   The preview slate: one poster per game

   Each row is the two clubs' colors meeting on a diagonal, with each club's
   mark blown up and cropped by the row's outer edge -- the thing that makes
   the treatment work, and the reason the marks are placed by hand: a wordmark
   and a round shield cannot take the same crop.

   Everything is drawn from --row, the row's height, so one number resizes a
   row and its marks together. The colors, the text color that reads on each
   of them, and each mark's size and offset (in row heights) come from
   app/team_marks.py and arrive as custom properties on the half.

   The halves keep the team-cell class names: pick-mode.js addresses them, so
   a pick is still a tap on a side of a row.
   -------------------------------------------------------------------------- */

.poster-slate { display: grid; gap: 6px; }

.poster-row {
    --row: 112px;
    --seam: 16px;
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: stretch;
    min-height: var(--row);
    border-radius: 10px;
    overflow: hidden;
    cursor: pointer;
}

.poster__half {
    position: relative;
    overflow: visible;
    display: grid;
    align-content: center;
    gap: 2px;
    min-width: 0;
    padding: 10px 14px calc(var(--row) * 0.24);
    color: var(--ink);
}

.poster__half.team-cell-home {
    justify-items: end;
    text-align: right;
}

/* The club's color. The panel runs wider than its half and is clipped by the
   row, so the seam is the only edge that leans; the two meet exactly. */
.poster__half::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 0;
    background: var(--fill);
}

.poster__half.team-cell-away::before {
    left: -200px;
    right: 0;
    clip-path: polygon(0 0, 100% 0, calc(100% - var(--seam)) 100%, 0 100%);
}

.poster__half.team-cell-home::before {
    left: calc(-1 * var(--seam));
    right: -200px;
    clip-path: polygon(var(--seam) 0, 100% 0, 100% 100%, 0 100%);
}

/* The mark, sized and offset in row heights. A negative inset is the point:
   that much of it hangs off the row's outer edge and is cropped. */
.poster__mark {
    position: absolute;
    top: 50%;
    z-index: 1;
    width: calc(var(--mark-w) * var(--row));
    height: calc(var(--mark-h) * var(--row));
    transform: translateY(calc(-50% + var(--mark-dy) * var(--row)));
    opacity: 0.45;
    object-fit: contain;
    pointer-events: none;
}

.team-cell-away .poster__mark { left: calc(var(--mark-inset) * var(--row)); }
.team-cell-home .poster__mark { right: calc(var(--mark-inset) * var(--row)); }

/* Sixteen clubs have a mark in their own team color, which on their own panel
   shows nothing. These are the ways out, chosen per club. */
.poster__mark--light { filter: brightness(0) invert(1); }
.poster__mark--dark { filter: brightness(0); }
.poster__mark--auto { mix-blend-mode: screen; opacity: 0.6; }

.poster__code,
.poster__record,
.poster-row .spread-line,
.poster__half > .pick-check {
    position: relative;
    z-index: 2;
}

.poster__code {
    font-family: 'Teko', sans-serif;
    font-weight: 600;
    font-size: calc(var(--row) * 0.3);
    line-height: 0.92;
    letter-spacing: 0.5px;
}

.poster__record {
    font-size: calc(var(--row) * 0.1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.82;
    font-variant-numeric: tabular-nums;
}

/* The spread is the decision, so it takes the size -- but it is the club's
   own text color here, not the table's ink. */
[data-spreads-posted="true"] .poster-row .spread-line {
    display: block;
    margin: 2px 0 0;
    padding: 0;
    border: 0;
    min-width: 0;
    background: none;
    color: inherit;
    font-size: calc(var(--row) * 0.23);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.4px;
}

/* "AT" on the seam, on its own scrim: it sits over two different club colors,
   and white alone cannot read on both. */
.poster__hinge {
    position: absolute;
    left: 50%;
    top: 7px;
    z-index: 3;
    transform: translateX(-50%);
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(8, 12, 22, 0.42);
    color: #fff;
    font: 700 10px 'Lato', sans-serif;
    letter-spacing: 0.22em;
}

/* The last ten and the kickoff, in a band across the bottom. On its own scrim
   for the same reason: it crosses both clubs' colors. */
.poster__foot {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 3;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 10px;
    padding: 3px 10px 4px;
    background: rgba(8, 12, 22, 0.42);
    color: #fff;
}

/* Kickoff, forecast and stadium. A wide row runs them in reading order with
   dots between; see the phone rules for what happens when they do not fit. */
.poster__when {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 6px;
    min-width: 0;
    font-size: 10.5px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    opacity: 0.88;
    text-align: center;
}

.poster__when > span + span::before {
    content: "·";
    margin-right: 6px;
}

.poster__venue {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.poster__time,
.poster__temp { flex: 0 0 auto; }

.poster__foot .form-evidence {
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
}

.poster__foot .form-evidence:last-of-type { justify-self: end; }

.poster__foot .form-strip {
    height: 16px;
    margin: 0;
    background: none;
}

.poster__foot .form-bar { width: 4px; height: 16px; }
.poster__foot .form-bar > span { height: calc(2px + (var(--bar, 0) * 7px)); }
.poster__foot .form-bar.is-w > span { background-color: #5fbf2a; }
.poster__foot .form-bar.is-l > span { background-color: #e05a49; }
.poster__foot .form-bar.is-t > span { background-color: rgba(255, 255, 255, 0.7); }
.poster__foot .form-record { display: none; }

/* ---- picking, on a poster row ---- */

[data-pick-mode="true"] .poster-row { cursor: default; }
[data-pick-mode="true"] .poster__half { cursor: pointer; }

/* The picked side keeps its color and takes a white edge; the other side of a
   decided game drains, so a column of sixteen reads at a glance. */
[data-pick-mode="true"] .poster__half[aria-checked="true"]::before {
    box-shadow: inset 0 0 0 3px #ffffff;
}

[data-pick-mode="true"] .clickable-row.is-decided .poster__half[aria-checked="false"] {
    filter: saturate(0.2) brightness(0.5);
}

[data-pick-mode="true"] .poster__half:focus-visible {
    outline: 3px solid #ffffff;
    outline-offset: -3px;
}

/* A tick as well as the fill, so the pick is never told by color alone. The
   child combinator keeps it above Font Awesome's own display rule. */
.poster__half > .pick-check {
    display: none;
    position: absolute;
    top: 8px;
    z-index: 4;
    color: #ffffff;
    font-size: 18px;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.65);
    pointer-events: none;
}

.poster__half.team-cell-away > .pick-check { right: 46px; }
.poster__half.team-cell-home > .pick-check { left: 46px; }

[data-pick-mode="true"] .poster__half[aria-checked="true"] > .pick-check {
    display: block;
}

/* A phone keeps the same row height, so a mark's crop is the one that was
   tuned; only the side padding tightens. */
@media only screen and (max-width: 760px) {
    .poster__half { padding-inline: 10px; }
    .poster__when { font-size: 10px; letter-spacing: 0.04em; }
    .poster__foot { gap: 6px; }

    /* Kickoff, stadium and forecast will not share one line on a phone, and
       a wrapped footer eats a quarter of the row. Three things buy the room:
       the forecast's wording goes (its temperature says more than
       "intermittent clouds" does), the letter-spacing goes, and the bars
       narrow. The longest line of a real week -- Sun 1:00 PM ET, Huntington
       Bank Field, 68 degrees -- is what this is sized against. */
    .poster__wx { display: none; }
    /* The stadium goes last on a phone and takes the truncation, so the
       kickoff and the temperature are never the parts that get cut. */
    .poster__when { letter-spacing: 0; flex-wrap: nowrap; }
    .poster__venue { order: 3; }
    .poster__temp { order: 2; }
    .poster__time { order: 1; }
    .poster__foot { padding-inline: 8px; }
    .poster__foot .form-bar { width: 3px; }
    .poster__foot .form-strip { gap: 1.5px; }
}

/* A finished game says so, in the column that reports the result.

   This is the information the row's dim tint used to carry, said in a word
   instead of a shade -- which frees the colour to mean the pick, and reads on
   a page where some games are done and others are still running. Upper case
   because that is how a scoreboard writes it, not as a label style. */
.result-cell .final-badge {
    display: inline-block;
    margin-bottom: 3px;
    padding: 1px 7px;
    border-radius: 4px;
    background: rgba(15, 23, 42, 0.07);
    color: #56607a;
    font-family: 'Lato', sans-serif;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.5;
}
