/*
 * SPDX-FileCopyrightText: 2026-present TeamCalendar
 * SPDX-License-Identifier: LicenseRef-Proprietary
 *
 * What renders inside the main region: the leagues, the success and edit
 * states, and the miss. Tokens and the regions themselves live in layout.css.
 */

.picker-status {
    margin: 0;
    color: var(--ink-soft);
}

/* ── The picker ───────────────────────────────────────────────────────────── */

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

.league details {
    border-bottom: 1px solid var(--rule);
}

/* Keeps the disclosure triangle but removes Safari's list-item marker, which
   it places differently from other browsers. */
.league-summary {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.75rem 0;
    cursor: pointer;
    font-weight: 600;
}

.league-summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.league-picked {
    color: var(--accent);
    font-size: 0.8125rem;
    font-weight: 500;
}

.league-body {
    padding-bottom: var(--step);
}

/* ── The conference grid ──────────────────────────────────────────────────── */

/* Conference headings are `<h3>`s under the league's `<summary>`. Leagues
   without conferences have one, "All teams", so the spacing must work alone too. */
.conference + .conference {
    margin-top: var(--step);
}

.conference-heading {
    margin: 0 0 0.5rem;
    color: var(--ink-soft);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.conference[hidden] {
    display: none;
}

.teams {
    list-style: none;
    margin: 0 0 var(--step);
    padding: 0;
    /* Rosters are long, so they get columns; auto-fill drops to one on a phone. */
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.125rem var(--step);
}

/* A row filtered out by search. It stays in the DOM and stays checked, so
   search never drops a picked club. */
.team-cell[hidden] {
    display: none;
}

.team,
.season {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.5rem;
    border-radius: var(--radius);
    cursor: pointer;
}

.season:hover {
    background: var(--panel);
}

.season:focus-within {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

/* A real checkbox, clipped to a pixel rather than `display: none` or
   `visibility: hidden`, which would remove it from focus order and the
   accessibility tree. The card beside it shows every visible state. */
.team-choice {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.team-card {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    padding: 0.375rem 0.5rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--page);
}

.team:hover .team-card {
    background: var(--panel);
}

/* A thicker border as well as the accent, so it doesn't rely on colour alone. */
.team-choice:checked + .team-card {
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* Focus is drawn on the card because the input is only a pixel. */
.team-choice:focus-visible + .team-card {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

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

/* Marks vary in intrinsic size; `contain` fits wordmarks and crests without cropping. */
.team-mark {
    width: 28px;
    height: 28px;
    object-fit: contain;
    flex: none;
}

/* ── The search box ───────────────────────────────────────────────────────── */

/* Above the leagues, since it filters every open panel, not one league. */
.picker-search {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: var(--step);
}

.search-label {
    color: var(--ink-soft);
    font-size: 0.875rem;
    white-space: nowrap;
}

.search-input {
    flex: 1 1 16rem;
    min-width: 0;
    max-width: 22rem;
    padding: 0.375rem 0.625rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--panel);
    color: var(--ink);
    font: inherit;
}

.search-input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}

.seasons {
    margin: 0;
    padding: var(--step);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--panel);
}

.seasons legend {
    padding-inline: 0.375rem;
    font-weight: 600;
}

.seasons-note {
    margin: 0 0 0.5rem;
    color: var(--ink-soft);
    font-size: 0.875rem;
}

.seasons ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* A season stays visible while locked (no team picked in its league yet). */
.seasons input:disabled + span {
    color: var(--ink-soft);
}

/* The tally line: how many teams are picked and, after a refusal, why. Sticky
   because each toggle saves, so the acknowledgement must stay in view. */
.picker-actions {
    position: sticky;
    bottom: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem var(--step);
    margin-top: calc(var(--step) * 1.5);
    padding: var(--step) 0;
    border-top: 1px solid var(--rule);
    background: var(--page);
}

.picker-tally {
    margin: 0;
    color: var(--ink-soft);
}

/* Phone only; on wider screens the panel is already beside the grid. */
.picker-onward {
    display: none;
    margin-left: auto;
    min-height: 2.75rem;
    padding: 0 1.25rem;
    border: 0;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--panel);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.picker-onward:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.picker-refusal {
    margin: 0;
    /* Announced via role="alert" and worded as a refusal, so colour isn't the only signal. */
    font-weight: 600;
}

.picker-refusal[hidden] {
    display: none;
}

.feed-link {
    color: var(--accent);
}

/* ── The subscribe panel ──────────────────────────────────────────────────── */

/* Below the form rather than over it, so the grid stays usable after the link
   appears. Shown on every visit that has a `cid`. */
.subscribe-panel {
    display: block;
    margin-top: calc(var(--step) * 2);
    padding-top: var(--step);
    border-top: 1px solid var(--rule);
}

.subscribe-panel[hidden] {
    display: none;
}

/* ── The third pane ───────────────────────────────────────────────────────── */

/* On desktop the panel sits beside the grid. The `auto` track collapses to
   nothing while the panel is `[hidden]` (before a `cid` exists). */
#picker {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: calc(var(--step) * 2);
    align-items: start;
    /* Extra width for the panel on top of the reading column's `--measure`. */
    max-width: calc(var(--measure) + 24rem);
}

.picker-form {
    min-width: 0;
}

.subscribe-panel {
    width: 22rem;
    /* Stays in view while the roster scrolls. */
    position: sticky;
    top: calc(var(--header-height) + var(--step));
    /* Scrolls itself: a sticky box taller than the viewport would otherwise
       leave its bottom unreachable. */
    max-height: calc(100vh - var(--header-height) - var(--step) * 2);
    overflow-y: auto;
    /* Reserves scrollbar space so its appearance doesn't reflow the rows. */
    scrollbar-gutter: stable;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

/* Show one league's teams at a time. Closed panels stay in the document so
   every checked box still reaches the write. `:has` keeps all summaries visible
   when no league is open. */
.leagues:has(details[open]) .league details:not([open]) {
    display: none;
}

/* ── The success and edit states ──────────────────────────────────────────── */

/* Above the leagues, because it answers a question asked before picking. */
.editing-note {
    margin: 0 0 var(--step);
    padding: 0.75rem var(--step);
    border-left: 3px solid var(--accent);
    border-radius: 0 var(--radius) var(--radius) 0;
    background: var(--panel);
    color: var(--ink-soft);
}

.success-heading {
    margin: 0 0 var(--step);
    font-size: 1.375rem;
    letter-spacing: -0.02em;
}

/* The live status line, answering "did my pick land?", so it's full ink and a
   little larger. */
.success-contents {
    margin: 0 0 var(--step);
    color: var(--ink);
    font-size: 0.9375rem;
}

/* Spacing lives on the region wrapper `markup.js` keeps across patches, so an
   empty region collapses fully. */
.success-section:not(:empty) {
    margin-top: calc(var(--step) * 1.5);
}

/* Styled like `.conference-heading`, so the picker has one way of labelling a list. */
.success-kicker {
    margin: 0 0 0.5rem;
    color: var(--ink-soft);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.subscribe {
    padding: var(--step);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--panel);
}

.subscribe-lead {
    margin: 0 0 var(--step);
    color: var(--ink-soft);
}

/* Three calendar-app tiles that wrap rather than scroll, so none is hidden on a phone. */
.calendar-apps {
    list-style: none;
    margin: 0 0 var(--step);
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.calendar-app {
    flex: 1 1 7rem;
}

/* The whole tile is the tap target. `height: 100%` keeps tiles equal when one
   has no mark (iPhone, see `subscribe.js`). */
.calendar-app-link {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.75rem 0.5rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--page);
    color: var(--ink);
    font-weight: 600;
    text-decoration: none;
}

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

.calendar-app-mark {
    display: block;
    width: 2rem;
    height: 2rem;
}

.calendar-app-name {
    font-size: 0.9375rem;
}

.feeds {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}

.feed {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

/* Keeps the address and its buttons together so `Copy` never wraps alone. */
.feed-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    flex: 1 1 18rem;
}

.feed-url {
    flex: 1 1 12rem;
    min-width: 0;
}

.feed-label {
    flex: 0 0 9rem;
    color: var(--ink-soft);
    font-size: 0.875rem;
}

/* The rarely used variant addresses, folded away but still one tap from view. */
.feed-variants {
    margin-top: var(--step);
}

.feed-variants-summary {
    color: var(--ink-soft);
    cursor: pointer;
    font-size: 0.875rem;
    padding: 0.25rem 0;
}

.feed-variants[open] .feed-variants-summary {
    margin-bottom: 0.5rem;
}

.feed-primary .feed-label {
    color: var(--ink);
    font-weight: 600;
}

.feed-subscribe {
    padding: 0.375rem 0.875rem;
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--page);
    font-weight: 600;
    text-decoration: none;
}

.feed-primary .feed-subscribe {
    padding: 0.5rem 1.125rem;
}

/* Readonly, not disabled, so keyboard users can focus it to select and copy. */
.feed-url {
    flex: 1 1 18rem;
    min-width: 0;
    padding: 0.375rem 0.5rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--page);
    color: var(--ink);
    font: inherit;
    font-size: 0.8125rem;
}

.feed-copy {
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--page);
    color: var(--ink);
    font: inherit;
    cursor: pointer;
}

.subscribe-status {
    margin: 0.5rem 0 0;
    min-height: 1.5rem;
    color: var(--ink-soft);
    font-size: 0.875rem;
}

/* A read-only summary: no checkbox or hover, with the same mark sizing as the
   picker. */
.success .teams {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.25rem var(--step);
}

.success .team {
    cursor: default;
}

.success .team:hover {
    background: none;
}

.fixtures {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.25rem;
}

.fixture {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.375rem 0;
    border-bottom: 1px solid var(--rule);
}

.fixture-when {
    flex: 0 0 12rem;
    color: var(--ink-soft);
    font-variant-numeric: tabular-nums;
}

/* Games after the third, folded away like `.feed-variants`. */
.fixtures-rest {
    margin-top: 0.5rem;
}

.fixtures-rest-summary {
    padding: 0.25rem 0;
    color: var(--ink-soft);
    cursor: pointer;
    font-size: 0.875rem;
}

.fixtures-rest[open] .fixtures-rest-summary {
    margin-bottom: 0.5rem;
}

.success-edit {
    margin: calc(var(--step) * 1.5) 0 0;
    color: var(--ink-soft);
    font-size: 0.875rem;
}

/* ── The uniform miss ─────────────────────────────────────────────────────── */

/* Deliberately plain: a visitor following a stale link gets the truth and a
   way onward, nothing that looks interactive. */
.miss {
    padding: calc(var(--step) * 2) 0;
}

.miss-heading {
    margin: 0 0 0.5rem;
    font-size: 1.375rem;
    letter-spacing: -0.02em;
}

/* The feed's own wording, verbatim; the heading above carries the friendly half. */
.miss-body {
    margin: 0 0 var(--step);
    color: var(--ink-soft);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: 0.9375rem;
    overflow-wrap: anywhere;
}

.miss-onward {
    margin: 0;
}

/* ── Phone ─────────────────────────────────────────────────────────────────────
   Same breakpoint as `layout.css` and `rail.js#PHONE`; `mobile.test.mjs` keeps
   them in step. */
@media (max-width: 40rem), (max-height: 30rem) {
    /* Keep the app tiles three-up. An explicit track count, since a flex basis
       only hints. */
    .calendar-apps {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
    }

    .calendar-app {
        flex: none;
    }

    /* The label gets its own line so the address and buttons have room. */
    .feed-label,
    .feed-actions {
        flex: 1 1 100%;
    }

    /* The address and its buttons share one row. */
    .feed-url {
        flex: 1 1 8rem;
    }
}

/* ── One region at a time, on a phone ─────────────────────────────────────── */

@media (max-width: 40rem), (max-height: 30rem) {
    /* A single column; `body[data-step]` decides which child shows. Selected by
       ID because the grid rule above is `#picker`, and a class selector would lose
       on specificity. */
    #picker {
        display: block;
        max-width: none;
    }

    body[data-step="1"] #picker {
        display: none;
    }

    .subscribe-panel {
        width: auto;
        position: static;
        /* Step 3 fills the screen, so the panel scrolls with the page rather than
           adding a second scrollbar. */
        max-height: none;
        overflow-y: visible;
    }

    body[data-step="2"] .subscribe-panel {
        display: none;
    }

    body[data-step="3"] .picker-form {
        display: none;
    }

    /* A ruled list instead of bordered cards, which reads lighter in a single
       column. */
    /* `auto-fill` with the desktop's 15rem track gives one column in portrait and
       three in landscape, where height is scarce. Zero row gap so the rules meet. */
    .teams {
        gap: 0 var(--step);
    }

    .team {
        padding: 0;
    }

    /* Tighter spacing to save vertical room. */
    .picker-search {
        margin-bottom: 0.75rem;
    }

    .league-summary {
        padding: 0.5rem 0;
    }

    .team-card {
        gap: 0.75rem;
        padding: 0.75rem 0.25rem;
        border: 0;
        border-bottom: 1px solid var(--rule);
        border-radius: 0;
        background: none;
        /* 44px minimum touch target. */
        min-height: 2.75rem;
    }

    .team:hover .team-card {
        background: none;
    }

    /* With no border, a pseudo-element draws the checked state. The input stays
       the real, focusable, announced control. */
    .team-card::after {
        content: "";
        flex: none;
        margin-left: auto;
        width: 1.375rem;
        height: 1.375rem;
        border: 1.5px solid var(--ink-soft);
        border-radius: 0.3125rem;
    }

    .team-choice:checked + .team-card {
        box-shadow: none;
    }

    .team-choice:checked + .team-card::after {
        border-color: var(--accent);
        background: var(--accent) no-repeat center / 0.75rem 0.75rem
            url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12.5l5.5 5.5L20 6.5'/%3E%3C/svg%3E");
    }

    .picker-onward {
        display: inline-flex;
        align-items: center;
    }
}
