body {
    margin: 0;
    font-family: system-ui, sans-serif;
    line-height: 1.5;
    color: #1c2530;
    background: #f4f6f8;
}

/* The header stays at the top of the window while the page scrolls. */
header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.5rem;
    padding: 0.7rem 1.5rem;
    background: #12304f;
}

header a {
    color: #fff;
    text-decoration: none;
}

/* The link for the part of the site being looked at. */
header nav a {
    padding-bottom: 0.1rem;
    border-bottom: 2px solid transparent;
    opacity: 0.85;
}

header nav a:hover,
header nav a.active {
    opacity: 1;
}

header nav a.active {
    border-bottom-color: #f5b82e;
}

/* The way into Be a GM: the one gold button on the site, in the header, on
   team pages and on the home page. */
.gm-button,
header a.gm-button {
    display: inline-block;
    padding: 0.35rem 0.9rem;
    border-radius: 4px;
    background: #f5b82e;
    color: #12304f;
    font-weight: bold;
    text-decoration: none;
    white-space: nowrap;
}

.gm-button:hover,
.gm-button.active {
    background: #ffd166;
}

.gm-invite {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    margin: 0.75rem 0 1rem;
}

.gm-invite .gm-button {
    padding: 0.55rem 1.1rem;
    font-size: 1.05rem;
}


.site-name {
    font-size: 1.25rem;
    font-weight: bold;
}

main {
    max-width: 60rem;
    margin: 0 auto;
    padding: 1.5rem;
}

/* A page that asks for it gets nearly the whole window. */
main.wide {
    max-width: 112rem;
}

footer {
    padding: 1.5rem;
    text-align: center;
    font-size: 0.875rem;
    color: #5b6875;
}

h1 {
    margin-bottom: 0.25rem;
}

h2 {
    margin-top: 2rem;
}

a {
    color: #1259a6;
}

table {
    width: 100%;
    margin: 1rem 0;
    border-collapse: collapse;
    background: #fff;
}

th,
td {
    padding: 0.4rem 0.6rem;
    border-bottom: 1px solid #dde3e9;
    text-align: left;
}

thead th {
    background: #e6ebf0;
    font-size: 0.875rem;
}

.num {
    text-align: right;
}

.scoreboard {
    width: auto;
    min-width: 20rem;
}

.winner td {
    font-weight: bold;
}

.period th {
    background: #f4f6f8;
    font-size: 0.875rem;
}

.hint {
    color: #5b6875;
    font-size: 0.875rem;
}

.tag {
    padding: 0 0.3rem;
    border-radius: 3px;
    background: #12304f;
    color: #fff;
    font-size: 0.75rem;
}

.message {
    padding: 0.6rem 0.9rem;
    border-left: 4px solid #2e7d4f;
    background: #e7f4ec;
}

.message.error {
    border-left-color: #b3261e;
    background: #fbeceb;
}

button {
    padding: 0.5rem 1rem;
    border: 0;
    border-radius: 4px;
    background: #12304f;
    color: #fff;
    font-size: 1rem;
    cursor: pointer;
}

/* Wide stat tables scroll sideways on small screens instead of breaking the page. */
@media (max-width: 40rem) {
    table {
        display: block;
        overflow-x: auto;
    }

    /* A name stays on one line beside its logo or photo, and the table
       scrolls instead of stacking the picture on top of the name. */
    td:has(.logo),
    td:has(> .headshot) {
        white-space: nowrap;
    }

    /* A team's list of seasons keeps each row to one line. */
    .season-list td {
        white-space: nowrap;
    }
}

header nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
}

/* The row of team logos under the header. Each is a link to that team's
   all-time page, and the team a page is about is underlined. */
.team-bar {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.15rem 0.35rem;
    padding: 0.35rem 1.5rem;
    border-bottom: 1px solid #dde3e9;
    background: #fff;
}

.team-bar a {
    display: flex;
    padding: 0.2rem;
    border-bottom: 2px solid transparent;
    border-radius: 4px 4px 0 0;
}

.team-bar a:hover {
    background: #e6ebf0;
}

.team-bar a.active {
    border-bottom-color: #12304f;
}

.team-bar img {
    width: 1.75rem;
    height: 1.75rem;
    object-fit: contain;
}

/* The season picker, pushed to the far end of the header. */
.season-picker {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-left: auto;
}

.season-picker label {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    color: #fff;
    font-size: 0.875rem;
}

.season-picker select {
    padding: 0.25rem 0.4rem;
    font-size: 0.9375rem;
}

/* On a narrow screen the header is kept short, since it stays on top: the
   name and the season picker share a row, and the links sit in one row under
   them that scrolls sideways. */
@media (max-width: 40rem) {
    /* The header is two rows here, so a jump down the page stops lower. */
    :root {
        scroll-padding-top: 6.5rem;
    }

    header {
        gap: 0.4rem 0.6rem;
        padding: 0.6rem 1rem;
    }

    /* The name, the Be a GM button and the season list share the first row.
       The word "Season" is dropped to make room; the list speaks for itself. */
    .site-name {
        order: -2;
        font-size: 1.1rem;
    }

    header a.gm-button {
        order: -1;
        margin-left: auto;
        padding: 0.25rem 0.6rem;
        font-size: 0.9rem;
    }

    .season-picker {
        order: 0;
        margin-left: 0;
    }

    .season-picker label {
        font-size: 0;
    }

    /* The team logos sit in one row that scrolls sideways, not four rows
       that push every page down. */
    .team-bar {
        flex-wrap: nowrap;
        justify-content: flex-start;
        padding: 0.25rem 0.6rem;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .team-bar a {
        flex: none;
    }

    header nav {
        order: 1;
        flex-wrap: nowrap;
        width: 100%;
        overflow-x: auto;
        white-space: nowrap;
        scrollbar-width: thin;
        scrollbar-color: #5b7590 transparent;
    }
}

thead th a {
    color: inherit;
    text-decoration: none;
}

thead th a:hover {
    text-decoration: underline;
}

.filters {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 1rem;
    margin: 1rem 0;
}

.filters label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.875rem;
}

select,
input[type="search"] {
    padding: 0.45rem 0.5rem;
    border: 1px solid #b6c0ca;
    border-radius: 4px;
    font-size: 1rem;
}

.leaderboards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: 0 2rem;
}

.comparison {
    table-layout: fixed;
}

.comparison .stat {
    width: 12rem;
    text-align: center;
    color: #5b6875;
    font-size: 0.875rem;
}

.comparison .value {
    width: 5rem;
    font-variant-numeric: tabular-nums;
}

/* A heading across the table that starts a group of stats. */
.comparison .group th {
    padding-top: 1rem;
    background: none;
    color: #12304f;
    font-size: 0.875rem;
    text-align: center;
}

.comparison .better {
    background: #e7f4ec;
    font-weight: bold;
}

.bar {
    height: 0.75rem;
    border-radius: 2px;
    background: #7fa3c7;
}

/* The first player's bars grow from the middle towards the left. */
.bar-cell.left .bar {
    margin-left: auto;
}

/* Search boxes that filter a list as you type need room for a full name. */
.filters input[list] {
    min-width: 16rem;
}

.message ul {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
}

/* The filtering dropdown that combobox.js builds under a search box. */
.combo {
    position: relative;
    display: block;
    min-width: 16rem;
}

.combo input {
    width: 100%;
    box-sizing: border-box;
}

.combo-list {
    position: absolute;
    z-index: 10;
    top: 100%;
    left: 0;
    right: 0;
    max-height: 18rem;
    margin: 2px 0 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
    border: 1px solid #b6c0ca;
    border-radius: 4px;
    background: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    font-size: 1rem;
}

.combo-list li {
    padding: 0.4rem 0.6rem;
    cursor: pointer;
}

.combo-list li:hover,
.combo-list li.active {
    background: #e6ebf0;
}

.combo-list .combo-note {
    color: #5b6875;
    font-size: 0.875rem;
    cursor: default;
}

.combo-list .combo-note:hover {
    background: none;
}

/* Home page */

/* Be a GM leads the page: a dark panel with every team's logo, each a way
   in as that team's GM. */
.hero {
    margin-bottom: 1.5rem;
    padding: 1.75rem 2rem 1.25rem;
    border-radius: 8px;
    background: linear-gradient(135deg, #12304f, #1d4a78);
    color: #fff;
}

.hero h1 {
    margin: 0;
    font-size: 2rem;
}

.hero-pitch {
    max-width: 40rem;
    margin: 0.5rem 0 1.25rem;
    font-size: 1.05rem;
    opacity: 0.92;
}

.hero-pick {
    margin: 0 0 0.5rem;
    color: #f5b82e;
    font-size: 0.875rem;
    font-weight: bold;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.hero-teams {
    display: grid;
    grid-template-columns: repeat(16, 1fr);
    gap: 0.4rem;
}

.hero-teams a {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.3rem;
    border: 2px solid transparent;
    border-radius: 6px;
    background: #fff;
}

.hero-teams a:hover,
.hero-teams a:focus-visible {
    border-color: #f5b82e;
    transform: translateY(-2px);
}

.hero-teams img {
    width: 100%;
    max-width: 2.4rem;
    aspect-ratio: 1;
    object-fit: contain;
}

.hero-other {
    margin: 1rem 0 0;
}

.hero-other a {
    color: #fff;
}

.home-intro {
    margin: 0;
    color: #5b6875;
}

@media (max-width: 40rem) {
    .hero {
        padding: 1.25rem 1rem 1rem;
    }

    .hero h1 {
        font-size: 1.6rem;
    }

    /* Four rows of eight, so each logo stays big enough to tap. */
    .hero-teams {
        grid-template-columns: repeat(8, 1fr);
    }
}

.home-search {
    display: flex;
    align-items: end;
    gap: 0.75rem;
    margin: 1.5rem 0;
}

.home-search label {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.875rem;
}

.home-search input {
    padding: 0.6rem 0.75rem;
    font-size: 1.1rem;
}

.scores {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: 0.75rem;
}

.score-card {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
    color: inherit;
    text-decoration: none;
}

.score-card:hover {
    border-color: #1259a6;
}

.score-row {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}

.score-row.winner {
    font-weight: bold;
}

.home-columns {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
    gap: 0 2rem;
}

.home-leaders {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: 0 1rem;
}

.update {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 2.5rem;
    padding-top: 1rem;
    border-top: 1px solid #dde3e9;
}

/* The season being shown on a player's career table, and the totals row. */
tr.selected td {
    background: #eef3f8;
    font-weight: bold;
}

tfoot th {
    border-top: 2px solid #b6c0ca;
    background: #e6ebf0;
}

/* A team's draft picks: a row for each draft, a column for each round, and a
   tile for each pick. The board scrolls sideways on a narrow screen. */
.pick-board {
    overflow-x: auto;
    border: 1px solid #c9d3de;
    border-radius: 6px;
    background: #fff;
}

.pick-row {
    display: grid;
    grid-template-columns: 4rem repeat(7, minmax(5.5rem, 1fr));
    min-width: 44rem;
    align-items: stretch;
    border-top: 1px solid #e6ebf0;
}

.pick-row > strong {
    display: flex;
    align-items: center;
    justify-content: center;
    background: #12304f;
    color: #fff;
    font-size: 1.05rem;
}

.pick-head {
    border-top: 0;
    background: #e6ebf0;
    color: #5b6875;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.pick-head > span {
    padding: 0.3rem 0.5rem;
    text-align: center;
}

.pick-cell {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    align-content: center;
    justify-content: center;
    min-height: 3rem;
    padding: 0.4rem 0.3rem;
    border-left: 1px solid #e6ebf0;
}

/* A round with no pick in it. */
.pick-cell:empty::after {
    content: "\2013";
    color: #b6c0ca;
}

.pick {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.15rem 0.5rem 0.15rem 0.3rem;
    border: 1px solid #c9d3de;
    border-radius: 999px;
    background: #f4f6f8;
    color: #1c2530;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: help;
}

.pick .logo {
    width: 1.35rem;
    height: 1.35rem;
}

/* One that came from another team. */
.pick.got {
    border-color: #7fb08a;
    background: #e9f5ec;
}

/* One of its own that another team holds. */
.pick.gone {
    border-style: dashed;
    background: none;
    color: #8a96a3;
    font-weight: 400;
}

.pick.gone .logo {
    opacity: 0.55;
    filter: grayscale(1);
}

.pick-to {
    font-size: 0.75rem;
}

/* One with a condition that is not settled. */
.pick.cond {
    border-color: #d9a441;
    box-shadow: inset 0 0 0 1px #d9a441;
}

.pick-star {
    color: #a8741a;
}

.pick-key {
    margin-top: 0.5rem;
}

.pick-key .pick {
    padding-left: 0.5rem;
    font-weight: 400;
    cursor: default;
}

/* Team logos: a small one beside a name in a table, a large one in a heading. */
.logo {
    width: 1.5rem;
    height: 1.5rem;
    object-fit: contain;
    vertical-align: middle;
}

.logo.large {
    width: 3rem;
    height: 3rem;
}

/* Player photos */
.player-header {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

.headshot {
    width: 7rem;
    height: 7rem;
    border-radius: 50%;
    object-fit: cover;
    background: #e6ebf0;
}

.headshot.small {
    display: block;
    width: 4rem;
    height: 4rem;
    margin-bottom: 0.25rem;
}

/* In the comparison heading the first player's photo sits on the right, next to the stats. */
.comparison th.num .headshot.small {
    margin-left: auto;
}

.headshot.tiny {
    width: 1.75rem;
    height: 1.75rem;
    margin-right: 0.5rem;
    vertical-align: middle;
}

/* The row of similar players on a player's page. */
.similar {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.similar-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0.75rem 0.5rem;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
    color: inherit;
    text-align: center;
    text-decoration: none;
}

.similar-card:hover {
    border-color: #1259a6;
}

/* Markers beside a team: Stanley Cup, conference, division, playoffs. */
.honour {
    margin-left: 0.2rem;
    font-size: 0.95em;
    cursor: help;
}

.legend .honour {
    margin-left: 1rem;
    cursor: default;
}

.legend .honour:first-child {
    margin-left: 0;
}

.honour-label {
    margin-left: 0.75rem;
    white-space: nowrap;
}

/* The NHL's clinch letters beside a team, and the Stanley Cup. */
.clinch {
    display: inline-block;
    min-width: 1.1rem;
    margin-left: 0.3rem;
    padding: 0 0.2rem;
    border-radius: 3px;
    background: #12304f;
    color: #fff;
    font-size: 0.75rem;
    font-weight: bold;
    line-height: 1.2rem;
    text-align: center;
    cursor: help;
}

.clinch.out {
    background: #b6c0ca;
}

img.cup {
    height: 1.6rem;
    margin-left: 0.3rem;
    vertical-align: middle;
}

span.cup {
    margin-left: 0.3rem;
}

.legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 1.25rem;
}

.legend .clinch,
.legend .cup {
    margin-left: 0;
    cursor: default;
}

.honour-label + .honour-label::before {
    content: "\00b7";
    margin-right: 0.75rem;
}

/* A player's awards: trophy, how many times, and the seasons. */
.awards th {
    width: 16rem;
    font-weight: normal;
    white-space: nowrap;
}

.awards td.num {
    width: 3rem;
    font-weight: bold;
}

h3 {
    margin: 1.25rem 0 0;
    font-size: 1rem;
}

/* The playoff bracket: one column for each round. */
.bracket {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0 1rem;
    align-items: start;
}

.bracket h2 {
    margin-top: 1rem;
    font-size: 1rem;
}

.series-card {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 0.75rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
    color: inherit;
    text-decoration: none;
}

.series-card:hover {
    border-color: #1259a6;
}

.champion {
    font-size: 1.15rem;
}

code {
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
    background: #e6ebf0;
}

/* The trophy case on a player's page: a dark cabinet of small trophy photos. */
.trophy-case {
    /* Only as wide as the trophies in it, wrapping onto more rows when full. */
    display: flex;
    flex-wrap: wrap;
    width: fit-content;
    max-width: 100%;
    box-sizing: border-box;
    gap: 0.75rem;
    padding: 0.75rem;
    border-radius: 8px;
    background: #101418;
    color: #e8ecef;
}

.trophy {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 7rem;
    gap: 0.1rem;
    text-align: center;
    font-size: 0.75rem;
    line-height: 1.3;
}

.trophy-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
    color: inherit;
    text-decoration: none;
}

.trophy-link:hover strong {
    text-decoration: underline;
}

.trophy-photo {
    position: relative;
    display: block;
    width: 100%;
    height: 5.5rem;
    margin-bottom: 0.3rem;
    border-bottom: 2px solid #6b5a2e;
    background: #000;
}

.trophy-photo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* How many times he won it, on a gold disc in the corner. */
.trophy-count {
    position: absolute;
    top: 0.25rem;
    right: 0.25rem;
    padding: 0 0.35rem;
    border-radius: 1rem;
    background: #d4a72c;
    color: #101418;
    font-weight: bold;
}

.trophy-summary {
    color: #d4a72c;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.trophy-seasons,
.trophy-seasons a {
    color: #9aa7b3;
}

.trophy-seasons a:hover {
    color: #fff;
}

/* Jumping to a season from the trophy case: scroll smoothly, stop a little
   above the season, and light it up. */
/* A jump down the page stops short of the header, which stays on top. */
html {
    scroll-behavior: smooth;
    scroll-padding-top: 4.5rem;
}

tbody[id^="season-"],
tr[id^="season-"] {
    scroll-margin-top: 6rem;
}

/* Every row of the season jumped to, so a season split between two teams
   lights up whole. The gold line marks its left edge. */
tbody:target td,
tr:target td {
    background: #fff1b8;
    font-weight: bold;
}

tbody:target td:first-child,
tr:target td:first-child {
    box-shadow: inset 4px 0 0 #d4a72c;
}

/* A tile that opens a list of seasons under it when it is hovered over,
   tapped or reached with the keyboard. Each season is a link down the page. */
.tile-menu {
    position: relative;
    cursor: pointer;
}

.tile-menu:hover,
.tile-menu:focus-within {
    border-color: #12304f;
}

.tile-seasons {
    display: none;
    position: absolute;
    top: 100%;
    left: -1px;
    right: -1px;
    z-index: 10;
    grid-template-columns: repeat(auto-fill, minmax(4.25rem, 1fr));
    max-height: 15rem;
    margin: 0;
    padding: 0.35rem;
    overflow-y: auto;
    list-style: none;
    border: 1px solid #12304f;
    border-radius: 0 0 6px 6px;
    background: #fff;
    box-shadow: 0 6px 14px rgba(16, 20, 24, 0.18);
}

.tile-menu:hover .tile-seasons,
.tile-menu:focus-within .tile-seasons {
    display: grid;
}

.tile-seasons a {
    display: block;
    padding: 0.2rem 0.35rem;
    border-radius: 4px;
    font-size: 0.875rem;
    text-decoration: none;
}

.tile-seasons a:hover,
.tile-seasons a:focus {
    background: #e6ebf0;
}

/* A trophy's own page. */
.trophy-header {
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
}

.trophy-header img {
    width: 9rem;
    border-radius: 6px;
    background: #000;
}

.trophy-header details p {
    max-width: 42rem;
    font-size: 0.875rem;
}

table.narrow {
    width: auto;
    min-width: 20rem;
}

/* The choice between league, conference and division on the standings page. */
.tabs {
    display: flex;
    gap: 0.25rem;
    margin: 0 0 0.5rem;
    border-bottom: 2px solid #dde3e9;
}

.tabs a {
    margin-bottom: -2px;
    padding: 0.4rem 0.9rem;
    border-bottom: 2px solid transparent;
    color: #5b6875;
    text-decoration: none;
}

.tabs a:hover {
    color: #1c2530;
}

.tabs a.active {
    border-bottom-color: #12304f;
    color: #12304f;
    font-weight: bold;
}

/* Charts. Each is an SVG that stretches to the width of the page. */
.chart {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
}

.chart .grid {
    stroke: #e6ebf0;
}

.chart .grid.zero {
    stroke: #9aa7b3;
    stroke-width: 1.5;
}

.chart .axis {
    fill: #5b6875;
    font-size: 11px;
}

.chart .axis-title {
    fill: #5b6875;
    font-size: 12px;
}

.chart .value,
.chart .point-label {
    fill: #1c2530;
    font-size: 11px;
}

/* Called a column because "bar" is already the comparison page's bars,
   whose fixed height would squash these. */
.chart .column {
    fill: #7fa3c7;
}

.chart .column.highlight,
.chart a:hover .column {
    fill: #12304f;
}

/* A part of a rating that is below zero, and the chart of parts itself. */
.chart .column.below {
    fill: #c8102e;
}

.chart.parts {
    max-width: 40rem;
}

.chart .line {
    fill: none;
    stroke: #12304f;
    stroke-width: 2;
}

.chart .line-1 {
    stroke: #c8102e;
}

.chart .dot {
    fill: #12304f;
}

/* A gap chart: the space between the line and zero, in the colour of the
   side that is ahead, and each side's name with a white edge so it can be
   read where the line runs behind it. */
.chart .area {
    fill: rgba(18, 48, 79, 0.18);
}

.chart .area-1 {
    fill: rgba(200, 16, 46, 0.16);
}

.chart .side-label {
    paint-order: stroke;
    stroke: #fff;
    stroke-width: 3px;
}

/* A radar chart: rings, and one see-through shape for each player. */
.chart.radar {
    max-width: 26rem;
}

/* The compare page's two charts, side by side where there is room. */
.glance {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
}

.glance-radar {
    flex: 1 1 20rem;
    max-width: 26rem;
}

.glance-race {
    flex: 1 1 22rem;
    max-width: 32rem;
}

.shot-maps.compact .rink {
    max-width: 20rem;
}

.chart .ring {
    fill: none;
    stroke: #cfd8e0;
}

.chart .typical {
    fill: none;
    stroke: #5b6875;
    stroke-width: 1.5;
    stroke-dasharray: 5 4;
}

.chart .shape {
    fill: rgba(18, 48, 79, 0.18);
    stroke: #12304f;
    stroke-width: 2;
    stroke-linejoin: round;
}

.chart .shape-1 {
    fill: rgba(200, 16, 46, 0.16);
    stroke: #c8102e;
}

/* The key above a chart that says whose colour is whose. */
.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.5rem;
    margin: 0.5rem 0;
    font-weight: bold;
}

.legend-swatch {
    display: inline-block;
    width: 0.8rem;
    height: 0.8rem;
    margin-right: 0.4rem;
    border-radius: 2px;
    background: #12304f;
}

.legend-swatch.swatch-1 {
    background: #c8102e;
}

/* A race chart: a dot for each goal, and each line's name at its end. */
.chart .mark {
    fill: #12304f;
    stroke: #fff;
    stroke-width: 1.5;
}

.chart .mark-1 {
    fill: #c8102e;
}

.chart .end-label {
    fill: #12304f;
    font-size: 12px;
    font-weight: bold;
}

.chart .end-label-1 {
    fill: #c8102e;
}

.chart a:hover .dot {
    fill: #c8102e;
}

.chart-caption {
    margin-top: 0.4rem;
}

/* The rink behind a shot map. */
.rink {
    max-width: 30rem;
    border: 0;
    background: none;
}

.rink .boards {
    fill: #fff;
    stroke: #9aa7b3;
    stroke-width: 2;
}

.rink .red-line,
.rink .goal-line {
    stroke: #c8102e;
}

.rink .red-line {
    stroke-width: 3;
}

.rink .blue-line {
    stroke: #1259a6;
    stroke-width: 3;
}

.rink .faceoff {
    fill: none;
    stroke: #e3a5ae;
}

.rink .crease {
    fill: #cfe6f7;
    stroke: #c8102e;
}

.rink .net {
    fill: none;
    stroke: #5b6875;
}

/* A shot map is drawn twice, as a heat map and as dots, and shows one. In
   heat mode the goals stay as dots on top of the shading. */
.rink .heat rect {
    fill: #c8102e;
}

.rink:not(.heat-mode) .heat,
.rink.heat-mode .attempt:not(.goal),
.rink.hide-goal .heat-goal,
.rink.hide-shot .heat-shot,
.rink.hide-miss .heat-miss,
.rink.hide-block .heat-block {
    display: none;
}

/* Over the shading the goals are small, so they mark a spot without
   covering the map. */
.rink.heat-mode .attempt.goal {
    r: 3px;
}

/* A team's season has hundreds of goals, which would hide the shading, so
   on its maps the goal dots only appear once Goals is picked in the key. */
.rink.heat-only .attempt.goal {
    display: none;
}

.rink.heat-only.hide-shot.hide-miss:not(.hide-goal) .attempt.goal {
    display: inline;
}

.view-button {
    margin-top: 0.4rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid #9aa7b3;
    border-radius: 999px;
    background: #fff;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.view-button:hover {
    border-color: #101418;
}

/* The four kinds of attempt, on a map and in its key. */
.rink .attempt.block,
.key-dot.block {
    fill: #b6c0ca;
    background: #b6c0ca;
    opacity: 0.6;
}

.rink .attempt.miss {
    fill: none;
    stroke: #5b6875;
}

.key-dot.miss {
    border: 1px solid #5b6875;
    background: none;
}

.rink .attempt.shot,
.key-dot.shot {
    fill: #1259a6;
    background: #1259a6;
    opacity: 0.7;
}

.rink .attempt.goal,
.key-dot.goal {
    fill: #d4a72c;
    stroke: #101418;
    background: #d4a72c;
}

/* A goal with details can be clicked, which opens a popup beside its dot. */
.rink .attempt[data-goal] {
    cursor: pointer;
}

.rink .attempt[data-goal]:hover,
.rink .attempt[data-goal].picked {
    stroke-width: 2.5;
}

.goal-popup {
    position: absolute;
    z-index: 5;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    width: max-content;
    max-width: min(18rem, 100%);
    padding: 0.5rem 0.7rem;
    border: 1px solid #b6c0ca;
    border-radius: 4px;
    background: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    font-size: 0.8125rem;
}

.goal-popup strong {
    font-size: 0.875rem;
}

.shot-map {
    position: relative;
}

.shot-map,
.shot-maps {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;
}

.shot-map .rink {
    flex: 1 1 20rem;
}

.shot-maps > div {
    flex: 1 1 20rem;
}

.map-key {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    margin: 0.5rem 0 0;
    padding: 0;
    list-style: none;
    font-size: 0.875rem;
}

.shot-map .map-key {
    flex-direction: column;
}

/* Each line of a key is a button that filters its map. */
.key-button {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.6rem;
    border: 1px solid transparent;
    border-radius: 999px;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.key-button strong {
    margin-left: 0.35rem;
}

.key-button:hover {
    border-color: #9aa7b3;
}

.key-button[aria-pressed="true"] {
    border-color: #101418;
    background: #eef2f6;
}

.map-key.filtered .key-button[aria-pressed="false"] {
    opacity: 0.45;
}

.rink.hide-goal .attempt.goal,
.rink.hide-shot .attempt.shot,
.rink.hide-miss .attempt.miss,
.rink.hide-block .attempt.block {
    display: none;
}

.key-dot {
    display: inline-block;
    box-sizing: border-box;
    width: 0.7rem;
    height: 0.7rem;
    margin-right: 0.4rem;
    border-radius: 50%;
}

/* A row of headline numbers. */
.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.75rem;
    margin: 0.75rem 0;
}

.tile {
    display: flex;
    flex-direction: column;
    padding: 0.75rem;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
}

.tile-value {
    font-size: 1.6rem;
    font-weight: bold;
    line-height: 1.2;
}

/* A number ranked against the league: green for good, red for bad. */
.rank-great {
    color: #0f6b2f;
}

.rank-good {
    color: #4c9a5e;
}

.rank-average {
    color: #b7791f;
}

.rank-poor {
    color: #d0665c;
}

.rank-bad {
    color: #a81f17;
}

/* A ranked tile shows its percentile in a small label above it when it is
   hovered over, tapped or reached with the keyboard. A ranked number in a
   table shows it when hovered over. */
.tile-ranked {
    position: relative;
    cursor: help;
}

.tile-ranked:hover,
.tile-ranked:focus {
    border-color: #12304f;
    outline: none;
}

td[data-rank] {
    position: relative;
    cursor: help;
}

.tile-ranked:hover::after,
.tile-ranked:focus::after,
td[data-rank]:hover::after {
    content: attr(data-rank);
    position: absolute;
    bottom: calc(100% + 0.3rem);
    left: 50%;
    z-index: 10;
    transform: translateX(-50%);
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    background: #12304f;
    color: #fff;
    font-size: 0.8rem;
    font-weight: bold;
    white-space: nowrap;
    box-shadow: 0 6px 14px rgba(16, 20, 24, 0.18);
}

.tile-label {
    font-size: 0.875rem;
}

.tile-note {
    color: #5b6875;
    font-size: 0.75rem;
}

/* Percentile bars: how a player ranks among his peers. */
.percentiles {
    display: grid;
    gap: 0.6rem;
    max-width: 46rem;
    margin: 0.75rem 0 0.25rem;
}

.percentile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 3.5rem;
    align-items: center;
    gap: 0.15rem 0.75rem;
}

.percentile-label {
    grid-column: 1 / -1;
    font-weight: bold;
}

.percentile-number {
    color: #5b6875;
    font-weight: normal;
    font-size: 0.875rem;
}

.percentile-track {
    height: 0.7rem;
    border-radius: 999px;
    background: #e6ebf0;
    overflow: hidden;
}

.percentile-fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: #12304f;
}

.percentile-rank {
    font-weight: bold;
    text-align: right;
}

.percentile-note {
    grid-column: 1 / -1;
    color: #5b6875;
    font-size: 0.75rem;
}

/* The explanation of the analytics terms. */
.glossary {
    margin: 0.5rem 0 1rem;
    max-width: 46rem;
}

.glossary summary {
    cursor: pointer;
    color: #1259a6;
}

/* The explanation is in groups, each under a small heading. */
.glossary h3 {
    margin: 1.25rem 0 0;
    padding-bottom: 0.2rem;
    border-bottom: 1px solid #dde3e9;
    font-size: 1rem;
}

.glossary p {
    font-size: 0.9rem;
}

.glossary dl {
    margin: 0;
}

.glossary dt {
    margin-top: 0.75rem;
    font-weight: bold;
}

.glossary dd {
    margin: 0.15rem 0 0;
    font-size: 0.9rem;
}

/* The armchair GM page. Its cap bar stays in view under the header while
   the page scrolls, so the room left is always in sight. */
.gm-cap {
    position: sticky;
    top: 4rem;
    z-index: 15;
    margin: 0 -0.75rem;
    padding: 0.6rem 0.75rem 0.1rem;
    background: #f4f6f8;
    border-bottom: 1px solid #dde3e9;
}

/* The bar is in three parts: the lineup, the spares, and whatever of the
   farm team's cap hits still counts. It turns red past the cap. */
.cap-bar {
    display: flex;
    height: 1.4rem;
    border-radius: 999px;
    background: #e6ebf0;
    overflow: hidden;
}

.cap-fill {
    display: block;
    height: 100%;
    transition: width 0.35s ease;
}

.cap-fill.dressed,
.cap-key.dressed {
    background: #12304f;
}

.cap-fill.spare,
.cap-key.spare {
    background: #4f7fb0;
}

.cap-fill.buried,
.cap-key.buried {
    background: #9db6cf;
}

.cap-fill.ltir,
.cap-key.ltir {
    background: #b7791f;
}

.cap-fill.ir,
.cap-key.ir {
    background: #d9a441;
}

.cap-fill.dead,
.cap-key.dead {
    background: #6b7280;
}

/* The injured list a player is really on, after his name. */
.gm-hurt {
    padding: 0 0.3rem;
    border-radius: 3px;
    background: #fbeceb;
    color: #a81f17;
    font-size: 0.7rem;
    font-weight: bold;
}

.gm-hurt.ir {
    background: #fdf3e1;
    color: #8a5a12;
}

/* A real team at a glance, above the list when one is picked in the Team
   filter. */
.gm-peek {
    margin: 0.5rem 0;
    padding: 0.6rem 0.9rem;
    border-left: 4px solid #4f7fb0;
    background: #eef3f8;
}

.gm-peek p {
    margin: 0.2rem 0;
}

/* The question asked before a player who would likely be claimed is put on
   waivers. It sits in the cap bar, which stays in view. */
.gm-ask {
    margin: 0 0 0.5rem;
    padding: 0.5rem 0.9rem;
    border-left: 4px solid #b3261e;
    background: #fbeceb;
}

.gm-ask p {
    margin: 0.2rem 0;
}

/* Whether a player can be sent to the minors without waivers. */
.gm-waivers {
    padding: 0 0.3rem;
    border-radius: 3px;
    background: #eef1f4;
    color: #5b6875;
    font-size: 0.7rem;
    font-weight: bold;
    white-space: nowrap;
    cursor: help;
}

.gm-waivers.exempt {
    background: #e7f4ec;
    color: #0f6b2f;
}

.gm-waivers.claimed {
    background: #fbeceb;
    color: #a81f17;
}

/* The hypothetical season: where it is saved, and the simulated standings. */
.gm-saved {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    align-items: center;
    margin: 0.5rem 0 0.75rem;
    padding: 0.6rem 0.9rem;
    border: 1px solid #c9d3de;
    border-radius: 6px;
    background: #fff;
}

.gm-saved input {
    width: 16rem;
    max-width: 100%;
}

button.gm-sim-go {
    padding: 0.5rem 1.1rem;
    border: 0;
    border-radius: 4px;
    background: #12304f;
    color: #fff;
    font-size: 1rem;
}

/* A free agent, where a player's team would be. */
.gm-free {
    padding: 0 0.3rem;
    border-radius: 3px;
    background: #e9f5ec;
    color: #1f6b35;
    font-weight: 600;
    cursor: help;
}

/* Marks the team being built: in the standings, and a new team where a
   real one would show its logo. */
.gm-yours,
.gm-new-team {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0 0.45rem;
    border-radius: 999px;
    background: #12304f;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    vertical-align: middle;
}

.gm-new-team {
    margin-left: 0;
}

.gm-saved > .logo {
    width: 1.75rem;
    height: 1.75rem;
}

.gm-sim-table td .logo {
    margin-right: 0.25rem;
}

.gm-sim-table tr.selected td {
    background: #eef3f8;
    font-weight: 600;
}

/* A trade being put together, under the glance at the other team. */
.gm-trade {
    margin: 0.5rem 0;
    padding: 0.6rem 0.9rem;
    border: 1px solid #c9d3de;
    border-left: 4px solid #12304f;
    background: #fff;
}

.gm-trade h3 {
    margin: 0 0 0.4rem;
}

.gm-trade p {
    margin: 0.25rem 0;
}

.gm-trade-sides {
    display: grid;
    /* minmax(0, ...) lets a side shrink below its longest option. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.gm-trade select[data-trade] {
    width: 100%;
}

.gm-trade-chip {
    display: inline-block;
    max-width: 100%;
    margin: 0 0.25rem 0.25rem 0;
    padding: 0.1rem 0.2rem 0.1rem 0.5rem;
    border-radius: 1rem;
    background: #eef3f8;
}

.gm-trade-chip .gm-keep {
    padding: 0 0.2rem;
    font-size: 0.8rem;
}

.gm-trade-chip button {
    margin-left: 0.25rem;
    padding: 0 0.35rem;
    border: 0;
    background: none;
    color: #5b6875;
    font-weight: 700;
    cursor: pointer;
}

.gm-trade-chip button:hover {
    color: #b3261e;
}

/* A contract's end, with its terms on hover. */
.gm-deal {
    cursor: help;
}

/* A player whose former team pays part of his contract. */
.gm-kept {
    padding: 0 0.3rem;
    border-radius: 3px;
    background: #e8eef5;
    color: #33506e;
    font-size: 0.7rem;
    font-weight: bold;
}

.cap-bar.over .cap-fill.dressed {
    background: #a81f17;
}

.cap-bar.over .cap-fill.spare {
    background: #c9483c;
}

.cap-bar.over .cap-fill.buried {
    background: #e2948c;
}

.cap-line {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.15rem 1.5rem;
    margin: 0.4rem 0 0.5rem;
}

/* The lineup's rating and grade, at the far end of the cap bar's line. */
.cap-score {
    white-space: nowrap;
}

.cap-split {
    color: #5b6875;
    font-size: 0.875rem;
}

.cap-split .legend-item {
    margin-left: 0.75rem;
    white-space: nowrap;
}

.cap-key {
    display: inline-block;
    width: 0.7rem;
    height: 0.7rem;
    margin-right: 0.3rem;
    border-radius: 2px;
}

.gm-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: 0.75rem;
    margin: 1rem 0 0.5rem;
}

.gm-actions label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.875rem;
}

button.plain {
    border: 1px solid #12304f;
    background: #fff;
    color: #12304f;
}

/* Picking a team to run is the main way in, so it is the one filled control. */
.gm-actions label.gm-main {
    font-weight: 600;
    color: #12304f;
}

.gm-actions label.gm-main select {
    padding: 0.5rem 0.75rem;
    border: 1px solid #12304f;
    border-radius: 4px;
    background-color: #12304f;
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
}

.gm-actions label.gm-main select option {
    background: #fff;
    color: #1c2530;
    font-weight: 400;
}

/* Building a team from nothing is still there, as a line of text. */
.gm-other-start {
    margin: 0.25rem 0 0.75rem;
}

button.gm-quiet {
    padding: 0;
    border: 0;
    background: none;
    color: #12304f;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* The lineup: forwards on the left in lines of three, and the defence
   pairs, goalies and spares on the right. */
.gm-board {
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: 0 1.5rem;
    align-items: start;
}

.gm-slots {
    display: grid;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.gm-slots.forwards,
.gm-slots.spares {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.gm-slots.defence,
.gm-slots.goalies {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.gm-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    min-height: 9.25rem;
    padding: 0.5rem 0.4rem;
    border: 1px solid #dde3e9;
    border-radius: 6px;
    background: #fff;
    color: inherit;
    font: inherit;
    text-align: center;
}

.gm-slot.empty {
    border: 2px dashed #b6c0ca;
    background: transparent;
    color: #5b6875;
    cursor: pointer;
}

.gm-slot.empty:hover,
.gm-slot.empty.picking {
    border-color: #12304f;
    background: #e6ebf0;
    color: #12304f;
}

.gm-slot.empty.picking {
    border-style: solid;
}

/* While a player is picked up: the spots he can go to, and the ones he
   cannot. */
.gm-slot.empty.offered {
    border-color: #12304f;
    color: #12304f;
}

.gm-slot.closed {
    opacity: 0.4;
    cursor: default;
}

.gm-slot.filled {
    cursor: pointer;
}

.gm-slot.filled:hover {
    border-color: #9aa7b3;
}

.gm-slot.held {
    border-color: #12304f;
    box-shadow: 0 0 0 2px #12304f;
}

.gm-spot {
    position: absolute;
    top: 0.3rem;
    left: 0.45rem;
    color: #5b6875;
    font-size: 0.7rem;
    font-weight: bold;
    letter-spacing: 0.03em;
}

.gm-plus {
    font-weight: bold;
}

.gm-slot .headshot.small {
    width: 3.25rem;
    height: 3.25rem;
    margin: 0.35rem 0 0.2rem;
}

.gm-name {
    font-weight: bold;
    font-size: 0.875rem;
    line-height: 1.2;
}

.gm-meta {
    color: #5b6875;
    font-size: 0.8rem;
}

.gm-gem {
    color: #1c7ed6;
}

/* A genuine star, and one another team will not part with. */
.gm-star {
    color: #d9a441;
    cursor: help;
}

.gm-star.untouchable {
    color: #b3261e;
}

/* A star his team would listen on, and one it is selling. */
.gm-star.listening {
    color: #c2700f;
}

.gm-star.available {
    color: #1f7a3d;
}

/* A player's numbers, shown under his row of cards while he is picked up:
   across the whole lineup, whatever the number of cards in a row. */
.gm-summary {
    grid-column: 1 / -1;
    padding: 0.6rem 0.9rem 0.3rem;
    border: 2px solid #12304f;
    border-radius: 6px;
    background: #fff;
}

.gm-summary-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    font-size: 1.05rem;
}

.gm-summary h4 {
    margin: 0.7rem 0 0.35rem;
    color: #5b6875;
    font-size: 0.8rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.gm-summary .tiles {
    grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
    gap: 0.4rem;
    margin: 0;
}

.gm-summary .tile {
    padding: 0.45rem 0.55rem;
}

.gm-summary .tile-value {
    font-size: 1.2rem;
}

.gm-summary .tile-label {
    font-size: 0.78rem;
    line-height: 1.25;
}

.gm-summary p {
    margin: 0.5rem 0;
}

/* A card's buttons show once the player is picked up. */
.gm-buttons {
    display: none;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.25rem;
    margin-top: 0.3rem;
}

.gm-slot.held .gm-buttons {
    display: flex;
}

/* The list of players starts below the header and the cap bar, which stay
   on top, when a spot is clicked to pick for it. */
#gm-players,
#gm-season {
    scroll-margin-top: 9.5rem;
}

.gm-buttons button,
.gm-row-buttons button {
    padding: 0.15rem 0.5rem;
    border: 1px solid #9aa7b3;
    border-radius: 999px;
    background: #fff;
    color: inherit;
    font-size: 0.8rem;
}

.gm-buttons button:hover,
.gm-row-buttons button:hover {
    border-color: #101418;
}

.gm-row-buttons {
    white-space: nowrap;
}

p.gm-row-buttons {
    white-space: normal;
}

.gm-row-buttons button {
    margin-left: 0.3rem;
}

.gm-row-buttons button[data-do="add"] {
    border-color: #12304f;
    background: #12304f;
    color: #fff;
}

.gm-row-buttons button.over {
    border-color: #a81f17;
    background: #fff;
    color: #a81f17;
}

/* Nothing in the list wraps, so a row keeps its height whatever is in it
   and adding a player never moves the rows under the pointer. */
.gm-table td,
.gm-table th {
    white-space: nowrap;
}

.gm-row-buttons button.gm-on-team {
    min-width: 5.6rem;
    border-color: #9db6cf;
    background: #eef3f8;
    color: #12304f;
}

/* A player in the list who is already on the team. */
tr.gm-on td {
    background: #eef3f8;
}

/* The quick filters above the list of players. */
.gm-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.75rem 0 0;
}

.gm-chip {
    padding: 0.3rem 0.8rem;
    border: 1px solid #9aa7b3;
    border-radius: 999px;
    background: #fff;
    color: inherit;
    font-size: 0.9rem;
}

.gm-chip:hover {
    border-color: #101418;
}

.gm-chip.on {
    border-color: #12304f;
    background: #12304f;
    color: #fff;
}

.gm-names {
    font-size: 0.875rem;
}

/* On a wide screen the team and the list of players are side by side. The
   list stays in view under the cap bar and scrolls on its own, so a player
   can be added and seen to land in the lineup without moving the page. */
@media (min-width: 80rem) {
    .gm-columns {
        display: grid;
        grid-template-columns: minmax(0, 11fr) minmax(0, 10fr);
        gap: 0 2rem;
        align-items: start;
    }

    .gm-finder {
        position: sticky;
        top: 9.75rem;
        max-height: calc(100vh - 10.75rem);
        padding-right: 0.5rem;
        overflow-y: auto;
    }

    .gm-team h2,
    .gm-finder h2 {
        margin-top: 0.75rem;
    }

    /* The list's heading row stays at the top of its own scrolling. */
    .gm-finder thead th {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    /* The list never scrolls sideways: the name takes whatever width the
       other columns leave, and a long one is cut short with dots. A cell
       with max-width 0 and width 100% is how a table column is made to do
       that. */
    .gm-finder {
        overflow-x: hidden;
    }

    .gm-finder .gm-table td:first-child,
    .gm-finder .gm-table th:first-child {
        width: 100%;
        max-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .gm-finder .gm-table td,
    .gm-finder .gm-table th {
        padding-left: 0.45rem;
        padding-right: 0.45rem;
    }
}

/* Side by side, the list has half the window: games and ice time are left
   out unless the screen is very wide. */
@media (min-width: 80rem) and (max-width: 135rem) {
    .gm-extra {
        display: none;
    }
}

/* Between a laptop and a big monitor each column is narrower still: the
   lineup stacks its two halves and the list also drops the team and the
   year the contract ends. */
@media (min-width: 80rem) and (max-width: 105rem) {
    .gm-board {
        grid-template-columns: 1fr;
    }

    .gm-mid,
    .gm-finder .gm-table .headshot {
        display: none;
    }

    .gm-finder .gm-table td,
    .gm-finder .gm-table th {
        padding-left: 0.35rem;
        padding-right: 0.35rem;
    }
}

/* Side by side, the filters above the list are kept small so more of the
   list shows on a short screen. */
@media (min-width: 80rem) {
    .gm-finder .gm-chips {
        margin-top: 0.4rem;
    }

    .gm-finder .gm-chip {
        padding: 0.2rem 0.6rem;
        font-size: 0.8rem;
    }

    .gm-finder .gm-filters {
        gap: 0.5rem 0.75rem;
        margin: 0.6rem 0 0.4rem;
    }

    .gm-finder .gm-filters select,
    .gm-finder .gm-filters input {
        padding: 0.3rem 0.4rem;
        font-size: 0.9rem;
    }
}

@media (max-width: 40rem) {
    .gm-cap {
        top: 5.75rem;
    }

    #gm-players,
    #gm-season {
        scroll-margin-top: 11.5rem;
    }

    /* The list keeps only what is needed to choose, so Add stays in reach. */
    .gm-wide,
    .gm-table th:nth-child(2),
    .gm-table td:nth-child(2) {
        display: none;
    }

    .gm-table td,
    .gm-table th {
        padding-left: 0.3rem;
        padding-right: 0.3rem;
    }

    .gm-slot {
        min-height: 8.5rem;
        padding: 0.4rem 0.2rem;
    }

    .gm-board {
        grid-template-columns: 1fr;
    }
}

/* The tabs that show Be a GM a part at a time are for a phone. On a wider
   screen they are hidden, and the box that holds them with the cap bar is
   taken out of the layout so the cap bar sticks as it always has. */
.gm-tabs {
    display: none;
}

.gm-top {
    display: contents;
}

/* Be a GM on a phone. */
@media (max-width: 40rem) {
    /* The cap bar stays on top of the page, so it is kept short: the bar,
       one line of what is used and left, and the rating. What each colour
       stands for is left to the tiles under it. */
    .gm-cap .cap-split,
    .gm-cap .cap-detail {
        display: none;
    }

    .cap-bar {
        height: 1rem;
    }

    .cap-line {
        margin: 0.3rem 0 0.35rem;
        font-size: 0.9rem;
    }

    /* The quick filters sit in one row that scrolls sideways. */
    .gm-chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding-bottom: 0.3rem;
        scrollbar-width: none;
    }

    .gm-chip {
        flex: none;
    }

    /* The filters: the name across the top, the other four two to a row. */
    .gm-filters {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 0.6rem 0.75rem;
    }

    .gm-filters label:first-child {
        grid-column: 1 / -1;
    }

    .gm-filters select,
    .gm-filters input {
        box-sizing: border-box;
        width: 100%;
    }

    /* Each player in a list is a small card: his name on one line, then
       what there is to know about him, each number saying what it is, and
       the buttons at the end, big enough to press. Nothing is cut off and
       nothing scrolls sideways. */
    .gm-cards,
    .gm-cards tbody {
        display: block;
        overflow: visible;
        background: none;
    }

    .gm-cards thead {
        display: none;
    }

    .gm-cards tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.25rem 0.9rem;
        padding: 0.55rem 0.5rem;
        border-bottom: 1px solid #dde3e9;
        background: #fff;
    }

    .gm-cards tr.gm-on {
        background: #eef3f8;
    }

    .gm-cards td {
        padding: 0;
        border: 0;
    }

    .gm-cards td:empty {
        display: none;
    }

    .gm-cards td:first-child {
        flex: 1 0 100%;
        white-space: normal;
    }

    .gm-cards td:nth-child(2) {
        display: block;
        color: #5b6875;
    }

    .gm-cards td[data-label]::before {
        content: attr(data-label) " ";
        color: #5b6875;
        font-size: 0.8rem;
        font-weight: normal;
    }

    .gm-cards td.gm-row-buttons {
        margin-left: auto;
        white-space: normal;
        text-align: right;
    }

    .gm-cards .gm-row-buttons button {
        margin: 0.15rem 0 0.15rem 0.3rem;
        padding: 0.35rem 0.8rem;
        font-size: 0.9rem;
    }

    .gm-cards td.gm-card-note {
        flex: 1 0 100%;
    }

    /* The five tiles under the cap bar: three to a row and no small print,
       which the cap bar's own line and the sections below already say. */
    #gm-tiles {
        grid-template-columns: repeat(3, 1fr);
        gap: 0.4rem;
    }

    #gm-tiles .tile {
        padding: 0.45rem 0.55rem;
    }

    #gm-tiles .tile-value {
        font-size: 1.15rem;
    }

    #gm-tiles .tile-label {
        font-size: 0.75rem;
        line-height: 1.25;
    }

    #gm-tiles .tile-note {
        display: none;
    }

    #gm-lineup-heading,
    #gm-contracts {
        scroll-margin-top: 11.5rem;
    }

    /* The saved seasons: one thing to a row, each the full width. */
    .gm-saved {
        flex-direction: column;
        align-items: stretch;
        gap: 0.6rem;
    }

    .gm-saved > .logo,
    .gm-saved > .gm-new-team {
        align-self: flex-start;
    }

    .gm-saved label {
        display: flex;
        flex-direction: column;
        gap: 0.25rem;
        font-size: 0.875rem;
    }

    .gm-saved input,
    .gm-saved select {
        box-sizing: border-box;
        width: 100%;
        padding: 0.45rem 0.5rem;
        font-size: 1rem;
    }

    .gm-saved .gm-row-buttons button {
        margin-left: 0;
        padding: 0.4rem 0.9rem;
        font-size: 0.9rem;
    }

    /* The button that plays the season is big enough to press. */
    #gm-sim .gm-row-buttons button {
        margin: 0 0.4rem 0.3rem 0;
        padding: 0.45rem 1rem;
        font-size: 0.95rem;
    }

    /* The simulated standings keep what matters in view: place, team,
       points and the chance of the playoffs. The rating is left to the
       tiles, and a long team name may wrap. */
    .gm-sim-table th:nth-child(3),
    .gm-sim-table td:nth-child(3) {
        display: none;
    }

    .gm-sim-table td:nth-child(2) {
        white-space: normal;
    }

    .gm-sim-table td,
    .gm-sim-table th {
        padding: 0.4rem 0.35rem;
    }

    /* The contract outlook: each summer is a card, with its counts on one
       line and the players it frees listed under them at full width. */
    .gm-outlook-table,
    .gm-outlook-table tbody {
        display: block;
        overflow: visible;
        background: none;
    }

    .gm-outlook-table thead {
        display: none;
    }

    .gm-outlook-table tr {
        display: flex;
        flex-wrap: wrap;
        gap: 0.15rem 1rem;
        margin-bottom: 0.75rem;
        padding: 0.7rem 0.8rem;
        border: 1px solid #dde3e9;
        border-radius: 6px;
        background: #fff;
    }

    .gm-outlook-table td {
        padding: 0;
        border: 0;
    }

    .gm-outlook-table td:first-child {
        flex: 1 0 100%;
        font-size: 1.05rem;
    }

    .gm-outlook-table td:empty {
        display: none;
    }

    .gm-outlook-table td[data-label]::after {
        content: " " attr(data-label);
        color: #5b6875;
        font-size: 0.85rem;
    }

    .gm-outlook-table td.gm-names {
        flex: 1 0 100%;
        margin-top: 0.4rem;
        padding-top: 0.45rem;
        border-top: 1px solid #e6ebf0;
        line-height: 1.75;
    }
}

/* The home page on a phone. This sits after the home page's own rules so it
   has the last word: the leaderboards go one under another, so no name is
   cut off, and the standings give up a little padding so the points stay
   in view. */
@media (max-width: 40rem) {
    .home-leaders {
        grid-template-columns: 1fr;
    }

    /* These short tables fit, so they are laid out as tables again and
       fill the width; the wide ones elsewhere still scroll sideways. */
    .home-leaders table,
    .home-columns table {
        display: table;
    }

    .home-columns td,
    .home-columns th {
        padding-left: 0.35rem;
        padding-right: 0.35rem;
    }
}

/* Be a GM on a phone: everything that is pressed is big enough for a
   thumb, and the trade's before-and-after table fits the screen. This sits
   after the page's own rules so it has the last word. */
@media (max-width: 40rem) {
    #gm .gm-row-buttons button,
    #gm .gm-trade-chip button {
        min-height: 2rem;
        padding: 0.3rem 0.8rem;
        font-size: 0.9rem;
    }

    #gm .gm-buttons button {
        min-height: 1.9rem;
        padding: 0.25rem 0.6rem;
        font-size: 0.85rem;
    }

    #gm .gm-keep {
        padding: 0.35rem 0.4rem;
        font-size: 0.9rem;
    }

    #gm-trade table {
        display: table;
        font-size: 0.8rem;
    }

    #gm-trade table th,
    #gm-trade table td {
        padding: 0.3rem 0.25rem;
        white-space: normal;
    }

    /* "one of 32 teams" sits under the team's name, not broken across it. */
    #gm-lineup-heading .hint {
        display: block;
    }
}

/* Be a GM a part at a time on a phone. The cap bar and the tabs stay at the
   top together; under them only the part chosen is shown. */
@media (max-width: 40rem) {
    .gm-top {
        position: sticky;
        top: 5.75rem;
        z-index: 15;
        display: block;
        margin: 0 -0.75rem;
        background: #f4f6f8;
    }

    .gm-top .gm-cap {
        position: static;
        margin: 0;
        border-bottom: 0;
    }

    .gm-tabs {
        display: flex;
        border-bottom: 1px solid #c9d3de;
    }

    .gm-tabs button {
        flex: 1;
        padding: 0.55rem 0.2rem 0.45rem;
        border: 0;
        border-bottom: 3px solid transparent;
        border-radius: 0;
        background: none;
        color: #5b6875;
        font-size: 0.9rem;
        font-weight: 600;
    }

    .gm-tabs button.on {
        border-bottom-color: #f5b82e;
        color: #12304f;
    }

    #gm[data-tab="lineup"] [data-part]:not([data-part="lineup"]),
    #gm[data-tab="players"] [data-part]:not([data-part="players"]),
    #gm[data-tab="season"] [data-part]:not([data-part="season"]),
    #gm[data-tab="contracts"] [data-part]:not([data-part="contracts"]) {
        display: none;
    }

    /* A short part still fills the screen, so its top can always be
       brought up under the header. */
    #gm {
        min-height: 100vh;
    }

    /* Each part starts close under the tabs. */
    [data-part] > h2:first-child {
        margin-top: 1rem;
    }
}

/* A player's numbers under his card on a phone: three tiles to a row, and
   no small print under each. */
@media (max-width: 40rem) {
    .gm-summary {
        padding: 0.5rem 0.6rem 0.2rem;
    }

    .gm-summary .tiles {
        grid-template-columns: repeat(3, 1fr);
    }

    .gm-summary .tile-note {
        display: none;
    }
}
