/* /Components/Activity/ActivityMetricPanel.razor.rz.scp.css */
/* SPEC-20 §10 panel shell. Reads the tokens defined in app.css's :root — a `:root` rule here would
   be rewritten to `:root[b-xxxxx]` and match nothing, so definitions live there and this file only
   consumes them (R10.7). No literal colour below. */

/* THE SECTION SHELL MOVED TO ActivityNext.razor.css AT I3, and this note is here because its absence
   is otherwise indistinguishable from an omission. `.activity-panel`, `.panel-head`, `.panel-title`,
   `.swatch`, `.spacer`, `.info-btn`, `.info-body`, `.viz-foot` and `.key` are now declared ONCE,
   above both sections that wear them: this one and the weekday heatmap, which is a second section in
   the same card but is not a metric. Blazor scoped CSS is per-component, so the alternative was a
   second copy of the shell in a second scoped file — which is the drift §10.17's register is about.
   Everything still here is this panel's own internals: nothing else wears them. */

.seg[b-ryclsj3diw] {
    display: inline-flex;
    border: 1px solid var(--activity-line);
    border-radius: 7px;
    overflow: hidden;
}

/* Mockup line 120, and the same rule as the page rail's — see ActivityNext.razor.css. */
.seg button + button[b-ryclsj3diw] {
    border-left: 1px solid var(--activity-line-2);
}

.seg button[b-ryclsj3diw] {
    border: 0;
    background: transparent;
    color: var(--activity-muted);
    font-size: 0.75rem;
    padding: 0.25rem 0.6rem;
    cursor: pointer;
}

/* §10.17 row 8 — the same fill as the rail's. See ActivityNext.razor.css for the ratio. */
.seg button[aria-pressed="true"][b-ryclsj3diw] {
    background: var(--activity-primary);
    color: var(--activity-on-primary);
    font-weight: 600;
}

/* Inset, not `outline`: `.seg` is `overflow: hidden` and clips an outline away entirely. */
.seg button:focus-visible[b-ryclsj3diw] {
    outline: none;
    box-shadow: inset 0 0 0 2px var(--activity-primary);
}


/* The viz region is a fixed-height positioning context so the overlays sit ON the chart rather than
   replacing it. Nothing here is ever `@if`-ed away. */
.viz[b-ryclsj3diw] {
    position: relative;
    min-height: 190px;
}

.chart-wrap[b-ryclsj3diw] {
    height: 190px;
}

.activity-chart-canvas[b-ryclsj3diw] {
    width: 100%;
    height: 190px;
}

.table-wrap[b-ryclsj3diw] {
    max-height: 190px;
    overflow: auto;
}

table.data[b-ryclsj3diw] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

table.data th[b-ryclsj3diw],
table.data td[b-ryclsj3diw] {
    text-align: left;
    padding: 0.2rem 0.5rem 0.2rem 0;
    border-bottom: 1px solid var(--activity-line);
    color: var(--activity-ink);
}

/* Mockup lines 197-198: every column but the period is a count, and a column of counts that is not
   right-aligned cannot be read down. The drill-down table is the view an operator opens precisely to
   compare one bucket against another, so this is the one view where alignment carries the meaning.
   :first-child stays left because it is the only label column. */
table.data th:not(:first-child)[b-ryclsj3diw],
table.data td:not(:first-child)[b-ryclsj3diw] {
    text-align: right;
}

/* §10.17 row 14, closed at I3 (mockup line 196). The head took body size, body case and the same
   `--activity-line` rule every row takes, so in a scrolling table of numbers the header row read as
   the first row of data — and it is sticky, so it is the one row that is always on screen. The
   mockup's four declarations: smaller, uppercase, tracked, and a heavier rule under the head than
   between rows. Listed rather than fixed at I2 because it is a look change to a signed-off surface
   nobody had asked about; taken now because I3 is authorised here and the head was genuinely
   indistinguishable from a row. */
table.data th[b-ryclsj3diw] {
    color: var(--activity-muted);
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    position: sticky;
    top: 0;
    background: var(--activity-card);
    /* The heavier rule under the head comes from `table.data th, table.data td` above already
       setting --activity-line here; what makes it heavier is the `td` rule below dropping the rows
       to --activity-line-2. Re-declaring it here would be a no-op that reads as load-bearing. */
}

table.data td[b-ryclsj3diw] {
    border-bottom: 1px solid var(--activity-line-2);
}

table.data tr.partial td[b-ryclsj3diw] {
    color: var(--activity-muted);
    font-style: italic;
}

.panel-overlay[b-ryclsj3diw] {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    background: var(--activity-card);
}

.overlay-text[b-ryclsj3diw] {
    font-size: 0.8rem;
    color: var(--activity-muted);
}

/* NOT alarm-red chrome. Four panels sit side by side and one may fail alone; a red-bordered card
   among three normal ones reads as "the venture is in trouble" rather than "this read failed". The
   severity belongs to the message, so it is one rule on the message block and nothing else. */
.failed-block[b-ryclsj3diw] {
    border-left: 3px solid var(--activity-down);
    padding-left: 0.7rem;
    max-width: 60ch;
}

.failed-head[b-ryclsj3diw] {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--activity-ink);
}

/* AC 8: the operator must be able to get from this panel to a log line. */
.failed-detail[b-ryclsj3diw] {
    margin: 0.2rem 0 0;
    font-size: 0.76rem;
    color: var(--activity-muted);
}
/* /Components/Activity/ActivitySummaryStrip.razor.rz.scp.css */
/* SPEC-20 §10 summary strip (R10.2). Tokens come from app.css's :root — a `:root` rule in a scoped
   stylesheet is rewritten to `:root[b-xxxxx]` and matches nothing. No literal colour below (R10.7). */

.activity-summary[b-my4xjslizc] {
    border: 1px solid var(--activity-line);
    border-radius: 12px;
    background: var(--activity-card);
    padding: 0.8rem 1rem 0.85rem;
    margin-bottom: 1.3rem;
}

.summary-head[b-my4xjslizc] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.summary-title[b-my4xjslizc] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    font-weight: 700;
    color: var(--activity-muted);
}

.as-of[b-my4xjslizc] {
    font-size: 0.75rem;
    color: var(--activity-muted);
    font-variant-numeric: tabular-nums;
}

/* Four across on a desktop screen, which is what makes "without scrolling past the first screen"
   true for every metric at once. It collapses to two and then one below. */
.summary-grid[b-my4xjslizc] {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0.9rem 0;
}

.summary-cell[b-my4xjslizc] {
    padding-left: 0.9rem;
    border-left: 1px solid var(--activity-line-2);
    min-width: 0;
}

.summary-cell:first-child[b-my4xjslizc] {
    padding-left: 0;
    border-left: 0;
}

.summary-k[b-my4xjslizc] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.72rem;
    color: var(--activity-muted);
    margin-bottom: 0.2rem;
}

/* The series-colour link, as a NON-TEXT role. All four series tokens clear 1.4.11's 3:1 on the
   card (3.60 / 3.81 / 5.00 / 6.39); two of them do not clear 1.4.3's 4.5:1, which is why the
   numeral below is ink and this 0.55rem block carries the colour instead. */
.swatch[b-my4xjslizc] {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 2px;
    display: inline-block;
    flex: 0 0 auto;
}

/* 2.1rem against the panel's own 1.5rem Today tile. The mockup's 1.65rem left the two only 10%
   apart at identical weight and colour, for two numbers that are the SAME figure a scroll apart —
   so nothing in the typography said which was the headline. R10.2 exists to make the strip the
   answer; this is the part of that which is visible. Nothing else on the page approaches this size,
   so the room was there. */
/* --activity-ink-2 (§10.17 row 10). This is the headline figure on the page and the SAME number as
   the panel's Today tile, which now also takes the heading ink — two renderings of one fact should
   not be two different inks. It also raises this from 8.62:1 to 11.84:1 on the card, which is the
   direction R10.7 pushes: the reason the numeral is ink at all rather than the series colour is that
   two of the four series miss 4.5:1, so making the replacement darker strengthens that ruling rather
   than trading against it. */
.summary-v[b-my4xjslizc] {
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1.05;
    color: var(--activity-ink-2);
    font-variant-numeric: tabular-nums;
}

.summary-v .part[b-my4xjslizc] {
    font-size: 0.6rem;
    font-weight: 600;
    color: var(--activity-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-left: 0.3rem;
    vertical-align: 0.18rem;
}

.summary-t7[b-my4xjslizc] {
    font-size: 0.74rem;
    color: var(--activity-muted);
    margin-top: 0.3rem;
    font-variant-numeric: tabular-nums;
}

.delta[b-my4xjslizc] {
    font-size: 0.74rem;
    font-weight: 600;
    white-space: nowrap;
}

.delta.up[b-my4xjslizc] { color: var(--activity-up); }
.delta.down[b-my4xjslizc] { color: var(--activity-down); }
.delta.flat[b-my4xjslizc] { color: var(--activity-muted); }

@media (max-width: 899.98px) {
    .summary-grid[b-my4xjslizc] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .summary-cell:nth-child(3)[b-my4xjslizc] {
        padding-left: 0;
        border-left: 0;
    }
}

@media (max-width: 479.98px) {
    .summary-grid[b-my4xjslizc] {
        grid-template-columns: minmax(0, 1fr);
    }

    .summary-cell[b-my4xjslizc] {
        padding-left: 0;
        border-left: 0;
    }
}
/* /Components/ClubSessionDashboard/AttendeeStatsTab.razor.rz.scp.css */
.attendee-stats-table-wrap[b-mq55dj9eur] {
    overflow-x: auto;
    margin-bottom: 0.75rem;
}

/* BL-076: card-per-player list. Hidden by default (desktop uses the table);
   swap visibility at <= 720px so phones get cards and no horizontal scroll. */
.attendee-stats-card-list[b-mq55dj9eur] {
    display: none;
}

@media (max-width: 720px) {
    .attendee-stats-table-wrap[b-mq55dj9eur] {
        display: none;
    }

    .attendee-stats-card-list[b-mq55dj9eur] {
        display: flex;
        flex-direction: column;
        gap: 0.55rem;
        margin-bottom: 0.75rem;
    }
}

.attendee-stats-card[b-mq55dj9eur] {
    background: #ffffff;
    border: 1px solid #d6dde6;
    border-radius: 0.55rem;
    padding: 0.6rem 0.7rem;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(15, 35, 60, 0.04);
}

.attendee-stats-card.selected-card[b-mq55dj9eur] {
    background: #dbeafe;
    border-color: #94b8ea;
}

.attendee-stats-card-head[b-mq55dj9eur] {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-bottom: 0.35rem;
}

.attendee-stats-card-rank[b-mq55dj9eur] {
    font-weight: 700;
    color: #5a6b80;
    font-size: 0.85rem;
    min-width: 1.8rem;
}

.attendee-stats-card-name[b-mq55dj9eur] {
    font-weight: 600;
    color: #0d2c55;
    font-size: 1rem;
    padding: 0;
    background: transparent;
    border: 0;
    cursor: pointer;
}

.attendee-stats-card-name:hover[b-mq55dj9eur] {
    text-decoration: underline;
}

/* #305: colour the attendee NAME TEXT by gender for quick identification on the
   leaderboard - male blue, female pink, unspecified default (no class). Text-only
   (no chip / row background) so a dense table reads as identification, not
   highlighting. Colours come from the shared --gender-male / --gender-female
   custom properties (app.css :root) so they match the Members tab name colours
   and stay in lockstep with them. Two-class selectors so these win over the base
   .attendee-name-link / .attendee-stats-card-name colour, on both the wide table
   and the narrow card. */
.attendee-name-link.name-gender-male[b-mq55dj9eur],
.attendee-stats-card-name.name-gender-male[b-mq55dj9eur] {
    color: var(--gender-male);
}

.attendee-name-link.name-gender-female[b-mq55dj9eur],
.attendee-stats-card-name.name-gender-female[b-mq55dj9eur] {
    color: var(--gender-female);
}

.attendee-stats-card-status[b-mq55dj9eur] {
    margin-left: auto;
    font-size: 0.78rem;
    color: #5a6b80;
    background: #eef2f7;
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
}

.attendee-stats-card-grid[b-mq55dj9eur] {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.35rem 0.9rem;
    margin: 0;
}

.attendee-stats-card-grid > div[b-mq55dj9eur] {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

.attendee-stats-card-grid dt[b-mq55dj9eur] {
    color: #5a6b80;
    font-size: 0.82rem;
    font-weight: 500;
    margin: 0;
}

.attendee-stats-card-grid dd[b-mq55dj9eur] {
    color: #1d2733;
    font-size: 0.92rem;
    font-weight: 600;
    margin: 0;
    text-align: right;
}

/* The rating-change row is the headline value on a card — span both columns
   and bump the number size so it's the first thing the eye lands on. */
.attendee-stats-card-rating-change[b-mq55dj9eur],
.attendee-stats-card-delta[b-mq55dj9eur] {
    grid-column: 1 / -1;
    border-top: 1px dashed #e1e6ed;
    padding-top: 0.35rem;
    margin-top: 0.1rem;
}

.attendee-stats-card-rating-change dt[b-mq55dj9eur],
.attendee-stats-card-delta dt[b-mq55dj9eur] {
    font-weight: 600;
    color: #1d2733;
}

.attendee-stats-card-rating-change dd[b-mq55dj9eur],
.attendee-stats-card-delta dd[b-mq55dj9eur] {
    font-size: 1.15rem;
    font-weight: 700;
}

.attendee-stats-card-results[b-mq55dj9eur] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.45rem;
}

.attendee-stats-card-results-label[b-mq55dj9eur] {
    color: #5a6b80;
    font-size: 0.82rem;
    font-weight: 500;
}

/* Performance / Fairness tabs — these are sub-views within Attendee Stats,
   switching them changes columns + sort logic, so they need to read as tabs
   (level-2 navigation), not buttons. */
.attendee-stats-tabs[b-mq55dj9eur] {
    display: flex;
    gap: 0;
    border-bottom: 1px solid #d3dce4;
    margin-bottom: 0.4rem;
}

.attendee-stats-tab[b-mq55dj9eur] {
    background: transparent;
    border: none;
    border-bottom: 3px solid transparent;
    padding: 0.55rem 1.1rem;
    margin-bottom: -1px;
    font-size: 0.95rem;
    font-weight: 500;
    color: #5e748a;
    cursor: pointer;
    transition: color 100ms ease, border-color 100ms ease;
}

.attendee-stats-tab:hover[b-mq55dj9eur] {
    color: #1f3f5e;
}

.attendee-stats-tab.active[b-mq55dj9eur] {
    color: #1f3f5e;
    border-bottom-color: #1b6ec2;
    font-weight: 600;
}

.attendee-stats-tab-subtitle[b-mq55dj9eur] {
    margin: 0 0 0.85rem 0;
    color: #5e748a;
    font-size: 0.875rem;
    font-style: italic;
}

/* Rank-by sits inside the table area (Performance only), left-aligned above
   the headers. It's a setting, not a view-switch, so it's visually subordinate
   to the tabs above. */
.attendee-stats-rank-by[b-mq55dj9eur] {
    display: flex;
    gap: 0.35rem;
    align-items: center;
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
}

.attendee-stats-rank-by-label[b-mq55dj9eur] {
    color: #5e748a;
    margin-right: 0.15rem;
}

.attendee-stats-rank-by-option[b-mq55dj9eur] {
    background: transparent;
    border: 1px solid #c8d4e0;
    border-radius: 4px;
    padding: 0.2rem 0.6rem;
    font-size: 0.85rem;
    color: #3a4a59;
    cursor: pointer;
    transition: background 100ms ease, border-color 100ms ease, color 100ms ease;
}

.attendee-stats-rank-by-option:hover:not(:disabled):not(.active)[b-mq55dj9eur] {
    background: #f3f6f9;
    border-color: #a4b4c4;
}

.attendee-stats-rank-by-option.active[b-mq55dj9eur] {
    background: #1b6ec2;
    border-color: #1561a8;
    color: #fff;
    font-weight: 500;
}

.attendee-stats-rank-by-option:disabled[b-mq55dj9eur] {
    /* S7d Inc2a rework (BLOCKER 2): a disabled option is READ-ONLY, not a live toggle. Strip the coloured
       fill (incl. the .active blue below) for a muted, self-evidently-inert look — a persistent (non-hover)
       cue, since the title tooltip never surfaces on touch/kiosk. This rule ONLY applies when the control is
       disabled (the read-only /live anon view + the converged Participate whole-room Players tab); the
       enabled console keeps its blue .active toggle untouched, so there is no console regression. */
    background: #eef1f5;
    border-color: #d7dee6;
    color: #8592a0;
    font-weight: 400;
    cursor: not-allowed;
    opacity: 1;
}

/* The currently-selected ranking, when disabled: a SUBTLE inert "selected" cue (a soft grey fill), clearly
   distinct from the saturated blue live toggle. Higher specificity than both .active and :disabled, so it
   wins for the active+disabled case. */
.attendee-stats-rank-by-option.active:disabled[b-mq55dj9eur] {
    background: #dfe5ec;
    border-color: #c6cfd9;
    color: #56636f;
}

.attendee-stats-table[b-mq55dj9eur] {
    min-width: 1200px;
}

.attendee-stats-table thead th.sortable-header[b-mq55dj9eur] {
    cursor: pointer;
    user-select: none;
}

.attendee-stats-table thead th.sortable-header:hover[b-mq55dj9eur] {
    background-color: #eef3f8;
}

.attendee-stats-table tbody tr[b-mq55dj9eur] {
    cursor: pointer;
}

.attendee-stats-table tbody tr:nth-child(odd):not(.selected-row) td[b-mq55dj9eur] {
    background-color: #ffffff;
}

.attendee-stats-table tbody tr:nth-child(even):not(.selected-row) td[b-mq55dj9eur] {
    background-color: #f8fafc;
}

.attendee-stats-table tbody tr:not(.selected-row):hover td[b-mq55dj9eur] {
    background-color: #eef2f7;
}

.attendee-stats-table tbody tr.selected-row[b-mq55dj9eur] {
    background-color: #dbeafe !important;
}

.attendee-stats-table tbody tr.selected-row td[b-mq55dj9eur] {
    background-color: #dbeafe !important;
    font-weight: 600;
}

.attendee-stats-table tbody tr.selected-row:hover td[b-mq55dj9eur] {
    background-color: #bfdbfe !important;
}

.result-squares[b-mq55dj9eur] {
    display: flex;
    gap: 0.2rem;
    min-height: 1.35rem;
}

.result-square[b-mq55dj9eur] {
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 0.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: #fff;
}

.result-win[b-mq55dj9eur] {
    background: #248c3b;
}

.result-loss[b-mq55dj9eur] {
    background: #bd2f2f;
}

.rating-positive[b-mq55dj9eur] {
    color: #1c7a33;
    font-weight: 600;
}

.rating-negative[b-mq55dj9eur] {
    color: #b52d2d;
    font-weight: 600;
}

.leader-badge[b-mq55dj9eur] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.4rem;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
    vertical-align: middle;
}

.badge-gold[b-mq55dj9eur] {
    background-color: #ffe08a;
    color: #7a5400;
    border: 1px solid #d9b857;
}

.badge-silver[b-mq55dj9eur] {
    background-color: #e2e8f0;
    color: #475569;
    border: 1px solid #b6c2d0;
}

.badge-bronze[b-mq55dj9eur] {
    background-color: #f2d1b0;
    color: #6f3f1f;
    border: 1px solid #cc9a73;
}

/* Inline expansion: detail panel rendered immediately under the selected
   table row (via colspan=9) or inside the selected card. Both wrappers
   give the detail a softer, recessed look so it reads as a child of the
   selected row, not as a sibling. */
.attendee-stats-table tbody tr.attendee-detail-row[b-mq55dj9eur] {
    cursor: default;
    background-color: transparent !important;
}

.attendee-stats-table tbody tr.attendee-detail-row:hover td[b-mq55dj9eur] {
    background-color: transparent !important;
}

.attendee-stats-table tbody tr.attendee-detail-row > td.attendee-detail-cell[b-mq55dj9eur] {
    background-color: #f1f6ff !important;
    border-left: 3px solid #94b8ea;
    padding: 0.75rem 1rem;
    font-weight: normal;
}

.attendee-stats-card.selected-card .attendee-stats-card-detail[b-mq55dj9eur] {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px dashed #94b8ea;
}

/* The detail block heading is now subordinate to the selected row, not a
   top-level section heading. Tone it down slightly so the eye stays on the
   row above. */
.attendee-detail-cell .attendee-game-details > h3[b-mq55dj9eur],
.attendee-stats-card-detail .attendee-game-details > h3[b-mq55dj9eur] {
    margin-top: 0;
    font-size: 0.95rem;
    color: #1f3f5e;
}

/* The Game Details table inside the detail panel can be wider than the
   viewport on tablet portrait — give it its own horizontal scroll so the
   wider parent table layout doesn't squeeze it weirdly. */
.attendee-game-details-table-wrap[b-mq55dj9eur] {
    overflow-x: auto;
}

.attendee-game-details h3[b-mq55dj9eur] {
    margin-bottom: 0.7rem;
    font-size: 1rem;
}

.attendee-unavailable-summary[b-mq55dj9eur] {
    margin-bottom: 0.9rem;
}

.attendee-time-summary[b-mq55dj9eur] {
    margin-bottom: 0.8rem;
}

.attendee-time-summary h4[b-mq55dj9eur] {
    margin-bottom: 0.45rem;
    font-size: 0.9rem;
    font-weight: 600;
}

/* Single horizontal strip of stat tiles. 6-across on wide landscape
   viewports, 3-across at portrait tablet, 2-across at phone card view.
   Saves ~2 line-heights vs the previous 3x2 table layout.

   The detail cell sits inside a `<td colspan="9">` of a table with
   `min-width: 1200px`, so at portrait-tablet viewports the natural
   containing block is wider than the screen. We set `width` directly
   (not `width: 100%; max-width: ...`) so the grid sizes itself rather
   than inheriting the inflated parent. */
.attendee-time-summary-grid[b-mq55dj9eur] {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0.55rem 0.75rem;
    margin: 0 0 0.65rem 0;
    width: min(60rem, calc(100vw - 2rem));
}

/* Portrait tablet, landscape phone: 3 across × 2 rows. The threshold is
   1100px so portrait 10-11" tablets (820px) cleanly get 3-across. */
@media (max-width: 1100px) {
    .attendee-time-summary-grid[b-mq55dj9eur] {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* Phone (card view triggers at <= 720px). At this width 2 across fits
   the typical card width comfortably. */
@media (max-width: 480px) {
    .attendee-time-summary-grid[b-mq55dj9eur] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.attendee-time-summary-grid > div[b-mq55dj9eur] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.attendee-time-summary-grid dt[b-mq55dj9eur] {
    color: #5a6b80;
    font-size: 0.75rem;
    font-weight: 500;
    margin: 0;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.attendee-time-summary-grid dd[b-mq55dj9eur] {
    color: #1d2733;
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
}

.attendee-unavailable-summary h4[b-mq55dj9eur] {
    margin-bottom: 0.45rem;
    font-size: 0.9rem;
    font-weight: 600;
}

.attendee-unavailable-table[b-mq55dj9eur] {
    max-width: 42rem;
}

/* #304 attendees follow-on: compact "Settling" marker shown next to the
   Current/Final Rating value on the Performance leaderboard. Reuses the #304
   neutral palette (#f4f8fc fill / #7d90a6 border / #213a54 text) verbatim from
   the profile chip (.member-settling-chip) so the two surfaces read as one
   feature, but tightened for a dense table row: smaller font, less padding,
   shorter height. Deliberately NOT a warning colour. */
.attendee-current-rating-cell[b-mq55dj9eur] {
    /* Keep the value, the marker, and its popover anchored together so the
       popover can position relative to the cell. */
    position: relative;
    white-space: nowrap;
}

.attendee-current-rating-value[b-mq55dj9eur] {
    margin-right: 0.35rem;
}

/* #506 revision: a small, quiet "M" badge on the Current/Final Rating cell, shown only
   when the member's rating was manually adjusted AFTER their first game this session. It
   explains why Current minus Initial doesn't equal the games-only Rating Change. Mirrors
   the completed-game "M" manual-override indicator's read (a small neutral circle), kept
   deliberately NOT a warning colour - it's informational, not an error. Sits inline beside
   the value and, when present, beside the settling chip without crowding the row. */
.attendee-rating-adjusted-marker[b-mq55dj9eur] {
    display: inline-flex;
    align-items: center;
    margin-right: 0.25rem;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    background: #eef3f8;
    color: #4a5f76;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.3;
    vertical-align: middle;
    cursor: help;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* ux-rework polish 6: a QUIET annotation, not a heavy pill. In a real club almost
   everyone over the threshold is established, so the settling rows are the minority
   we mark - but a dense Current-Rating column can still carry several at once, so
   the marker must not add visual noise or make settling rows sit taller than their
   neighbours. So: no min-height (line-height + padding give a natural ~1.15rem box,
   flush with the unmarked value beside it), a borderless tinted lozenge (the #304
   neutral fill, no heavy outline), glyph-prominent with a small label. The visible
   "Settling" label stays (it carries the a11y meaning; not glyph-only). */
.attendee-settling-chip[b-mq55dj9eur] {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.02rem 0.3rem;
    border: 0;
    border-radius: 999px;
    background: #eef3f8;
    color: #4a5f76;
    font-size: 0.66rem;
    font-weight: 500;
    line-height: 1.15;
    cursor: pointer;
    vertical-align: middle;
}

.attendee-settling-chip:hover[b-mq55dj9eur] {
    background: #e4ecf4;
    color: #2f4763;
}

/* Bare <button> (no .btn class): restore a visible keyboard focus ring,
   matching the profile chip. */
.attendee-settling-chip:focus-visible[b-mq55dj9eur] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* ::deep to reach the glyph SVG: it comes from a code-behind RenderFragment
   (SettlingChip.Glyph) that the scoped-CSS rewriter never tags. Sized down for
   the compact chip. */
.attendee-settling-chip[b-mq55dj9eur]  .member-settling-chip-icon {
    /* Glyph-prominent: the seedling slightly outsizes the small label so the marker
       reads as an icon-with-caption quiet annotation, not a text pill. */
    width: 0.85rem;
    height: 0.85rem;
    flex: 0 0 auto;
}

.attendee-settling-chip-label[b-mq55dj9eur] {
    white-space: nowrap;
    letter-spacing: 0.01em;
}

/* Lightweight inline explainer popover (kiosk tap affordance). Floated over the
   row content so it doesn't reflow the dense table; neutral card styling. */
.attendee-settling-popover[b-mq55dj9eur] {
    position: absolute;
    z-index: 20;
    top: calc(100% + 0.25rem);
    /* Current Rating is the rightmost column, so anchor the popover to the right
       edge of the cell and grow leftwards - a left-anchored popover would clip off
       the right of the viewport on a kiosk. */
    right: 0;
    left: auto;
    width: 17rem;
    max-width: 80vw;
    padding: 0.6rem 0.7rem;
    border: 1px solid #c4d2e0;
    border-radius: 0.5rem;
    background: #ffffff;
    box-shadow: 0 0.4rem 1rem rgba(33, 58, 84, 0.18);
    color: #213a54;
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.35;
    white-space: normal;
    text-align: left;
}

/* Real tap target for kiosk (ux-rework polish 3): the old 0-padding link was
   ~16x20px. Give it inline padding + a min-height so a finger can land on it,
   while keeping the quiet inline-link look (no fill, sits at the popover's left
   edge under the copy). Negative left margin keeps the text optically aligned
   with the paragraph above despite the new horizontal padding. */
.attendee-settling-popover-close[b-mq55dj9eur] {
    display: inline-flex;
    align-items: center;
    margin-top: 0.35rem;
    margin-left: -0.5rem;
    min-height: 2.2rem;
    padding: 0.3rem 0.5rem;
    border: 0;
    background: none;
    color: #1b6ec2;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

.attendee-settling-popover-close:hover[b-mq55dj9eur] {
    text-decoration: underline;
}

.attendee-settling-popover-close:focus-visible[b-mq55dj9eur] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* ux-rework polish 7: on the narrow CARD layout the absolute right:0 / 17rem
   popover overflows a ~320px card to the left. Render the explainer instead as a
   non-absolute inline block that expands inside the card, below the rating value -
   same neutral tokens as the table popover, but in normal flow so it can never
   clip the card. (The table keeps its absolute popover, which is fine in the wide
   layout.) It spans the full card width via the grid cell it lives in. */
.attendee-settling-explainer-inline[b-mq55dj9eur] {
    display: block;
    width: 100%;
    margin-top: 0.4rem;
    padding: 0.55rem 0.65rem;
    border: 1px solid #c4d2e0;
    border-radius: 0.5rem;
    background: #f7fafd;
    color: #213a54;
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.35;
    white-space: normal;
    text-align: left;
}

/* The rating sits in one cell of the 2-col card grid; when its inline explainer is
   open, let that cell span both columns and stack its contents so the explainer
   block gets the full card width (not the narrow right-hand column) and wraps the
   long copy cleanly. */
.attendee-stats-card-grid > div:has(.attendee-settling-explainer-inline)[b-mq55dj9eur] {
    grid-column: 1 / -1;
    flex-wrap: wrap;
}

/* When the explainer is open the rating cell becomes a full-width column: the
   value (chip + number) sits on the first line, the explainer block fills the row
   beneath it. flex-basis:100% drops it onto its own line under the dt label. */
.attendee-current-rating-cell:has(.attendee-settling-explainer-inline)[b-mq55dj9eur] {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    white-space: normal;
}
/* /Components/ClubSessionDashboard/ClubSessionSettingsTab.razor.rz.scp.css */
.settings-actions[b-nz9rmuh1yc] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    /* Pin Save/Reset to the bottom of the scroll area so the buttons stay
       reachable while the user scrolls the settings editor (e.g. down to the
       Sticky pairs add-picker). Opaque background so list content doesn't show
       through behind the pinned footer. Mirrors the cog-modal footer treatment
       in ClubSessionDashboard.razor.css (.clubSession-settings-modal-actions). */
    position: sticky;
    bottom: 0;
    background: #f8fbff;
    border-top: 1px solid #c4d2e0;
    padding: 0.6rem 0.2rem max(0.6rem, env(safe-area-inset-bottom));
    z-index: 1;
}

.settings-message[b-nz9rmuh1yc] {
    color: #4f6177;
    font-size: 0.92rem;
}
/* /Components/ClubSessionDashboard/CompletedGamesTab.razor.rz.scp.css */
/* #852: player-name filter bar above the completed-games table. */
.completed-games-filter-bar[b-fena95e2pi] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.6rem;
}

.completed-games-filter-bar .completed-games-player-filter[b-fena95e2pi] {
    max-width: 20rem;
    /* Kiosk-friendly touch target without dominating the panel. */
    min-height: 2.25rem;
}

.completed-games-no-match[b-fena95e2pi] {
    padding: 0.4rem 0;
}

.completed-game-edited-badge[b-fena95e2pi] {
    color: #c2410c;
    font-size: 0.78rem;
    font-style: italic;
    text-decoration: none;
}

.completed-game-edited-badge:hover[b-fena95e2pi],
.completed-game-edited-badge:focus-visible[b-fena95e2pi] {
    text-decoration: underline;
    color: #9a3412;
}

.completed-game-history-row > td[b-fena95e2pi] {
    background: #fff8f0;
    border-top: none;
}

.completed-game-history[b-fena95e2pi] {
    padding: 0.4rem 0.6rem;
    font-size: 0.85rem;
}

.completed-game-history ul[b-fena95e2pi] {
    padding-left: 1.2rem;
    margin-top: 0.25rem;
}

.completed-game-edit-modal[b-fena95e2pi] {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
}

.completed-game-edit-backdrop[b-fena95e2pi] {
    position: absolute;
    inset: 0;
    background: rgba(13, 44, 85, 0.45);
}

.completed-game-edit-dialog[b-fena95e2pi] {
    position: relative;
    background: #ffffff;
    border-radius: 0.5rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
    padding: 1.25rem 1.4rem;
    max-width: 36rem;
    width: 92%;
    max-height: 90vh;
    overflow-y: auto;
}

.completed-game-edit-dialog h3[b-fena95e2pi] {
    font-size: 1.1rem;
    margin-bottom: 0.4rem;
    color: #0d2c55;
}

.completed-game-edit-legend[b-fena95e2pi] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.3rem;
}

/* S7c-2 (UX rework MAJOR 1): the card-per-game phone layout for the anon /live Games tab. Mirrors the
   AttendeeStatsTab BL-076 pattern — the wide table hides at ≤720px and the card list takes over so the
   9-column table never overflows a phone with no scroll cue.

   The console path renders the table inside .table-responsive (NOT .completed-games-table-wide) and never
   renders .completed-games-card-list, so none of these rules touch it — the console stays byte-identical,
   including on a narrow console window. */

.completed-games-card-list[b-fena95e2pi] {
    display: none;
}

@media (max-width: 720px) {
    .completed-games-table-wide[b-fena95e2pi] {
        display: none;
    }

    .completed-games-card-list[b-fena95e2pi] {
        display: flex;
        flex-direction: column;
        gap: 0.55rem;
        margin-bottom: 0.5rem;
    }
}

.completed-game-card[b-fena95e2pi] {
    background: #ffffff;
    border: 1px solid #d6dde6;
    border-radius: 0.55rem;
    padding: 0.6rem 0.7rem;
    box-shadow: 0 1px 2px rgba(15, 35, 60, 0.04);
}

.completed-game-card-head[b-fena95e2pi] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

.completed-game-card-id[b-fena95e2pi] {
    font-size: 0.8rem;
    font-weight: 600;
    color: #5a6b80;
}

/* Score is the headline number — the first thing the eye lands on. */
.completed-game-card-score[b-fena95e2pi] {
    font-size: 1.2rem;
    font-weight: 800;
    color: #0d2c55;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.completed-game-card-teams[b-fena95e2pi] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.completed-game-card-team[b-fena95e2pi] {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
}

.completed-game-card-team-label[b-fena95e2pi] {
    flex: 0 0 auto;
    min-width: 3rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.completed-game-card-winner .completed-game-card-team-label[b-fena95e2pi] {
    color: #1c7a33;
}

.completed-game-card-loser .completed-game-card-team-label[b-fena95e2pi] {
    color: #7a8595;
}

.completed-game-card-team-names[b-fena95e2pi] {
    font-size: 0.95rem;
    font-weight: 600;
    color: #1d2733;
}

.completed-game-card-winner .completed-game-card-team-names[b-fena95e2pi] {
    color: #14532d;
}

/* Par / Duration / Court demoted to quiet small print. */
.completed-game-card-meta[b-fena95e2pi] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.45rem;
    padding-top: 0.4rem;
    border-top: 1px dashed #e1e6ed;
    font-size: 0.78rem;
    color: #5a6b80;
}

.completed-game-card .game-pick-indicator[b-fena95e2pi] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.3rem;
    min-width: 1.1rem;
    height: 1.1rem;
    padding: 0 0.2rem;
    border-radius: 0.25rem;
    background: #eef3f8;
    color: #4a5f76;
    font-size: 0.68rem;
    font-weight: 700;
    vertical-align: middle;
}
/* /Components/ClubSessionDashboard/GameSuggestionExplainerDialog.razor.rz.scp.css */
/* ── Backdrop & Modal Shell ───────────────────────── */
.explainer-backdrop[b-lz7qf7hzti] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1050;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 2rem 1rem;
    overflow-y: auto;
}

.explainer-modal[b-lz7qf7hzti] {
    background: var(--bs-body-bg, #fff);
    color: var(--bs-body-color, #212529);
    border-radius: 0.5rem;
    box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.3);
    width: 100%;
    max-width: 56rem;
    max-height: 90vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

/* BL-058: on narrow viewports the modal was opening with awkward whitespace
   above and below — the 2rem-from-top padding on the backdrop combined with
   the 90vh modal cap left ~5–10% of vertical space empty top and bottom.
   On mobile, fill the viewport edge-to-edge (bottom-sheet pattern). */
@media (max-width: 600px) {
    .explainer-backdrop[b-lz7qf7hzti] {
        padding: 0;
        align-items: stretch;
    }

    .explainer-modal[b-lz7qf7hzti] {
        max-width: 100%;
        max-height: 100vh;
        border-radius: 0;
        box-shadow: none;
    }
}

/* ── Header ──────────────────────────────────────── */
.explainer-header[b-lz7qf7hzti] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}

.explainer-header h3[b-lz7qf7hzti] {
    margin: 0;
    font-size: 1.1rem;
}

/* ── Loading / Empty ─────────────────────────────── */
.explainer-loading[b-lz7qf7hzti],
.explainer-empty[b-lz7qf7hzti] {
    padding: 2rem;
    text-align: center;
    color: var(--bs-secondary-color, #6c757d);
}

.spinner[b-lz7qf7hzti] {
    display: inline-block;
    width: 1.5rem;
    height: 1.5rem;
    border: 3px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin-b-lz7qf7hzti 0.75s linear infinite;
}

@keyframes spin-b-lz7qf7hzti {
    to { transform: rotate(360deg); }
}

/* ── Body ────────────────────────────────────────── */
.explainer-body[b-lz7qf7hzti] {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* ── Version Warning ─────────────────────────────── */
.explainer-version-warning[b-lz7qf7hzti] {
    background: #fff3cd;
    color: #664d03;
    border: 1px solid #ffecb5;
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.85rem;
}

/* ── Summary ─────────────────────────────────────── */
.explainer-summary[b-lz7qf7hzti] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.explainer-summary-teams[b-lz7qf7hzti] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1rem;
    font-weight: 600;
}

.vs-label[b-lz7qf7hzti] {
    color: var(--bs-secondary-color, #6c757d);
    font-weight: 400;
    font-size: 0.85rem;
}

.explainer-summary-stats[b-lz7qf7hzti] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    font-size: 0.85rem;
    color: var(--bs-secondary-color, #6c757d);
}

.version-tag[b-lz7qf7hzti] {
    font-family: monospace;
    font-size: 0.75rem;
    background: var(--bs-tertiary-bg, #f8f9fa);
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
}

/* ── Locked / Rationale ──────────────────────────── */
.explainer-locked-context[b-lz7qf7hzti] {
    font-size: 0.85rem;
    color: var(--bs-secondary-color, #6c757d);
}

.explainer-rationale[b-lz7qf7hzti] {
    font-size: 0.85rem;
    color: var(--bs-secondary-color, #6c757d);
}

/* ── Factor Table (Level 1) ──────────────────────── */
.explainer-factor-table[b-lz7qf7hzti] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.explainer-factor-table th[b-lz7qf7hzti] {
    text-align: left;
    padding: 0.35rem 0.5rem;
    border-bottom: 2px solid var(--bs-border-color, #dee2e6);
    font-weight: 600;
}

.explainer-factor-table td[b-lz7qf7hzti] {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

.explainer-factor-table .interpretation[b-lz7qf7hzti] {
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.8rem;
}

/* ── Contribution colours ────────────────────────── */
.contribution-positive[b-lz7qf7hzti] { color: #198754; font-weight: 600; }
.contribution-mild[b-lz7qf7hzti]     { color: #6c757d; }
.contribution-moderate[b-lz7qf7hzti] { color: #fd7e14; }
.contribution-severe[b-lz7qf7hzti]   { color: #dc3545; font-weight: 600; }

/* ── Actions Row ─────────────────────────────────── */
.explainer-actions-row[b-lz7qf7hzti] {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    padding-top: 0.25rem;
}

.explainer-flag-form[b-lz7qf7hzti] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    background: #f8f9fa;
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    padding: 0.75rem;
}

.explainer-flag-label[b-lz7qf7hzti] {
    font-size: 0.9rem;
    font-weight: 500;
    margin: 0;
}

.explainer-flag-error[b-lz7qf7hzti] {
    color: #b02a37;
    font-size: 0.85rem;
    margin: 0;
}

.explainer-flag-actions[b-lz7qf7hzti] {
    display: flex;
    justify-content: flex-end;
}

.explainer-flag-ack[b-lz7qf7hzti] {
    background: #d1e7dd;
    color: #0a3622;
    border: 1px solid #a3cfbb;
    border-radius: 0.375rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
}

/* ── Candidates Section (Level 2) ────────────────── */
.explainer-candidates-section[b-lz7qf7hzti] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.explainer-search-bar[b-lz7qf7hzti] {
    display: flex;
    gap: 0.35rem;
    align-items: center;
}

.explainer-search-bar input[b-lz7qf7hzti] {
    flex: 1;
}

.explainer-candidates-table[b-lz7qf7hzti] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.explainer-candidates-table th[b-lz7qf7hzti] {
    text-align: left;
    padding: 0.3rem 0.4rem;
    border-bottom: 2px solid var(--bs-border-color, #dee2e6);
    font-weight: 600;
    white-space: nowrap;
}

.explainer-candidates-table td[b-lz7qf7hzti] {
    padding: 0.3rem 0.4rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

.explainer-candidates-table tbody tr[b-lz7qf7hzti] {
    cursor: pointer;
}

.explainer-candidates-table tbody tr:hover[b-lz7qf7hzti] {
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.row-winner[b-lz7qf7hzti] {
    background: #d1e7dd !important;
}

.row-pinned[b-lz7qf7hzti] {
    position: sticky;
    top: 0;
    z-index: 1;
    border-bottom: 2px solid #198754 !important;
}

.row-separator td[b-lz7qf7hzti] {
    height: 3px;
    padding: 0 !important;
    background: var(--bs-border-color, #dee2e6);
    border: none !important;
}

.row-expanded[b-lz7qf7hzti] {
    background: var(--bs-tertiary-bg, #f8f9fa) !important;
}

.col-rank[b-lz7qf7hzti]   { width: 2.5rem; text-align: center; }
.col-vs[b-lz7qf7hzti]     { width: 1.5rem; text-align: center; color: var(--bs-secondary-color, #6c757d); }
.col-score[b-lz7qf7hzti]  { width: 4rem; text-align: right; font-family: monospace; }
.col-delta[b-lz7qf7hzti]  { width: 5.5rem; text-align: right; font-family: monospace; }
.col-issues[b-lz7qf7hzti] { width: 3rem; text-align: center; }

.issue-badge[b-lz7qf7hzti] {
    background: #dc3545;
    color: #fff;
    border-radius: 0.75rem;
    padding: 0.1rem 0.45rem;
    font-size: 0.7rem;
    font-weight: 600;
}

.explainer-no-results[b-lz7qf7hzti] {
    text-align: center;
    color: var(--bs-secondary-color, #6c757d);
    padding: 0.75rem;
    font-size: 0.85rem;
}

/* ── Detail Row (Level 3) ────────────────────────── */
.detail-row td[b-lz7qf7hzti] {
    padding: 0 !important;
    border-bottom: 2px solid var(--bs-border-color, #dee2e6) !important;
}

.explainer-detail[b-lz7qf7hzti] {
    padding: 0.75rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.explainer-detail h4[b-lz7qf7hzti] {
    margin: 0;
    font-size: 0.9rem;
    font-weight: 600;
}

.explainer-detail-factors[b-lz7qf7hzti] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.explainer-detail-factors th[b-lz7qf7hzti] {
    text-align: left;
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    font-weight: 600;
}

.explainer-detail-factors td[b-lz7qf7hzti] {
    padding: 0.25rem 0.4rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

.explainer-detail-factors .interpretation[b-lz7qf7hzti] {
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.75rem;
}

/* ── Player Detail (Level 3) ─────────────────────── */
.player-detail[b-lz7qf7hzti] {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    overflow: hidden;
}

.player-detail summary[b-lz7qf7hzti] {
    padding: 0.4rem 0.6rem;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 500;
    background: var(--bs-tertiary-bg, #f8f9fa);
}

.player-detail summary:hover[b-lz7qf7hzti] {
    background: var(--bs-secondary-bg, #e9ecef);
}

.player-metrics[b-lz7qf7hzti] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
    gap: 0.25rem 1rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.8rem;
    margin: 0;
}

.player-metrics div[b-lz7qf7hzti] {
    display: flex;
    gap: 0.35rem;
}

.player-metrics dt[b-lz7qf7hzti] {
    font-weight: 500;
    white-space: nowrap;
}

.player-metrics dd[b-lz7qf7hzti] {
    margin: 0;
    color: var(--bs-secondary-color, #6c757d);
}

.player-relationships[b-lz7qf7hzti] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

.player-relationships th[b-lz7qf7hzti] {
    text-align: left;
    padding: 0.2rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    font-weight: 600;
    font-size: 0.75rem;
}

.player-relationships td[b-lz7qf7hzti] {
    padding: 0.2rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

/* ── Excluded Section ────────────────────────────── */
.explainer-excluded-section[b-lz7qf7hzti] {
    border: 1px solid var(--bs-border-color, #dee2e6);
    border-radius: 0.375rem;
    overflow: hidden;
    margin-top: 0.5rem;
}

.explainer-excluded-section summary[b-lz7qf7hzti] {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 500;
    background: #f8d7da;
    color: #842029;
}

.excluded-group[b-lz7qf7hzti] {
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

.explainer-excluded-table[b-lz7qf7hzti] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
}

.explainer-excluded-table th[b-lz7qf7hzti] {
    text-align: left;
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
    font-weight: 600;
}

.explainer-excluded-table td[b-lz7qf7hzti] {
    padding: 0.25rem 0.5rem;
    border-bottom: 1px solid var(--bs-border-color-translucent, #dee2e622);
}

.excluded-reason[b-lz7qf7hzti] {
    color: #842029;
    font-size: 0.75rem;
}
/* /Components/ClubSessionDashboard/LiveViewCtaBar.razor.rz.scp.css */
/* S7d Increment 1: the sticky bottom onward-CTA bar on /live/{code} (Wireframe A). Sticks to the bottom of
   the viewport while the board scrolls, then rests at the end of the shell. Matches the /live phone palette
   (#0d2c55 primary, the green live accents). 44px+ touch targets; honours the iOS safe-area inset. */

.lvc-bar[b-rjs3qvmo8z] {
    position: sticky;
    bottom: 0;
    z-index: 5;
    /* S7d Inc1 rework (BLOCKER 1): margin-top:auto pushes the bar to the bottom of the 100dvh flex shell so
       it is flush to the viewport bottom on SHORT content; position:sticky keeps it pinned while a tall
       board scrolls. Collapses to 0 when the board fills the height (no free space to distribute). */
    margin-top: auto;
    /* Pull to the shell edges so the bar reads as a full-width footer over the centred column. */
    margin-left: -0.75rem;
    margin-right: -0.75rem;
    padding: 0.7rem 0.85rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    background: #ffffff;
    border-top: 1px solid #d6e0ea;
    box-shadow: 0 -6px 18px rgba(13, 44, 85, 0.08);
}

.lvc-headline[b-rjs3qvmo8z] {
    margin: 0;
    font-size: 0.9rem;
    font-weight: 700;
    color: #0d2c55;
    text-align: center;
}

.lvc-actions[b-rjs3qvmo8z] {
    display: flex;
    align-items: center;
    justify-content: center;
    /* NIT 5: ~16px between the two differently-weighted anon actions so they are harder to mis-tap on a
       shared kiosk tablet. */
    gap: 1rem;
    flex-wrap: wrap;
}

.lvc-btn[b-rjs3qvmo8z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 1.2rem;
    border-radius: 0.6rem;
    font-weight: 800;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
}

/* POLISH 3: match the app-wide kiosk-control focus ring PATTERN (.player-board-pill-btn et al. use
   `outline: 2px solid …; outline-offset: 2px`) instead of Chromium's faint default. The siblings use #fff
   because they sit on the DARK board; this bar has a WHITE surface, so #fff would be invisible — the ring
   keeps the 2px/offset pattern but in the bar's own blue (the same #1d4ed8 as its link + the signpost),
   which is visible against white for BOTH the navy primary and the blue link. */
.lvc-btn:focus-visible[b-rjs3qvmo8z] {
    outline: 2px solid #1d4ed8;
    outline-offset: 2px;
}

.lvc-btn-primary[b-rjs3qvmo8z] {
    background: #0d2c55;
    color: #fff;
}

.lvc-btn-primary:hover[b-rjs3qvmo8z] { background: #12336a; }

/* The full-width primary (Unbound / Bound single action). */
.lvc-btn-block[b-rjs3qvmo8z] {
    width: 100%;
}

/* The secondary "New here? Sign up" — a link-weight action beside the primary Log in. */
.lvc-btn-link[b-rjs3qvmo8z] {
    min-height: 2.75rem;
    padding: 0 0.4rem;
    color: #1d4ed8;
    font-weight: 700;
    font-size: 0.9rem;
    background: transparent;
    border: none;
}

.lvc-btn-link:hover[b-rjs3qvmo8z] { text-decoration: underline; }
/* /Components/ClubSessionDashboard/PaymentsTab.razor.rz.scp.css */
.payments-summary[b-ucin70hwvb] {
    display: grid;
    grid-template-columns: repeat(2, minmax(220px, 1fr));
    gap: 0.25rem 1rem;
    font-size: 0.9rem;
    color: #2e4f6d;
}

.payments-table td[b-ucin70hwvb] {
    vertical-align: middle;
}

.payment-balance-due[b-ucin70hwvb] {
    color: #8b1f1f;
    font-weight: 700;
}

.payment-balance-ok[b-ucin70hwvb] {
    color: #1f6e3b;
    font-weight: 700;
}

@media (max-width: 900px) {
    .payments-summary[b-ucin70hwvb] {
        grid-template-columns: 1fr;
    }
}
/* /Components/ClubSessionDashboard/PegboardTab.razor.rz.scp.css */
/* #917 — shared spacing for the leading Bootstrap Icon on in-session action buttons.
   Purely presentational: icon leads, text remains the accessible label. Only sets the
   right margin (== me-1); no font-size/padding/min-height change, so touch targets stay. */
.btn-icon[b-vm1hgbpelh] {
    margin-right: 0.35rem;
}

/* #504 — plain "can't create a game with the current constraints" informational dialog.
   Uses the real app palette. Scoped to PegboardTab so it can't leak into the other dashboard
   modals. (Reuses the modal scaffold from the former relaxation prompt; the option/preview
   styling is gone — the dialog only lists constraints now.) */

.relax-modal[b-vm1hgbpelh] {
    --navy-title: #1f3f5e;
    --muted: #6c7a8c;
    --border-soft: #e6ebf3;
    --border: #c5cfde;
    --amber: #8a5a00;
    --amber-bg: #fdeccd;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 18px 50px rgba(8, 22, 46, .4);
}

.relax-head[b-vm1hgbpelh] {
    padding: 16px 20px 12px;
    border-bottom: 1px solid var(--border-soft);
}

.relax-title[b-vm1hgbpelh] {
    font-size: 16px;
    font-weight: 700;
    color: var(--navy-title);
    display: flex;
    align-items: center;
    gap: 9px;
}

.relax-ic[b-vm1hgbpelh] {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--amber-bg);
    color: var(--amber);
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 13px;
    flex: 0 0 auto;
}

.relax-why[b-vm1hgbpelh] {
    color: var(--muted);
    font-size: 12.5px;
    margin-top: 7px;
    line-height: 1.5;
}

.relax-body[b-vm1hgbpelh] {
    padding: 14px 20px 6px;
}

.relax-cap[b-vm1hgbpelh] {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 9px;
}

.relax-constraint-list[b-vm1hgbpelh] {
    list-style: none;
    margin: 0 0 6px;
    padding: 0;
}

.relax-constraint[b-vm1hgbpelh] {
    border: 1px solid var(--border-soft);
    border-radius: 8px;
    padding: 9px 12px;
    margin-bottom: 8px;
    font-size: 13px;
    font-weight: 600;
    color: #24364d;
    background: #f7fafd;
}

.relax-foot[b-vm1hgbpelh] {
    padding: 12px 20px 18px;
    display: flex;
    align-items: center;
    gap: 10px;
    border-top: 1px solid var(--border-soft);
    margin-top: 6px;
    flex-wrap: wrap;
}

.relax-foot-note[b-vm1hgbpelh] {
    color: var(--muted);
    font-size: 11.5px;
}

.relax-foot-actions[b-vm1hgbpelh] {
    margin-left: auto;
    display: flex;
    gap: 9px;
}

/* #926 S3: finish-popup (Method B) chrome. The header stacks the title over the locked-user
   sub-line; the footer splits Postpone/Close (left) from Save (right) like the app's other modal
   footers. Purely presentational - reuses the standard bootstrap modal classes for everything else. */
.finish-popup-header[b-vm1hgbpelh] {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
}

.finish-popup-locked-note[b-vm1hgbpelh] {
    font-size: 0.85rem;
    color: #4d7093;
}

.finish-popup-footer[b-vm1hgbpelh] {
    justify-content: space-between;
}

/* SPEC-27 S4 (ux MAJOR 2) — the Start-confirm is a commit surface: its Cancel / "Start anyway" buttons
   must meet the >=44px courtside touch target (btn-sm ~31px was too small). */
.start-advisory-confirm-modal .modal-footer .btn[b-vm1hgbpelh] {
    min-height: 44px;
    padding-left: 1rem;
    padding-right: 1rem;
}
/* /Components/Clubs/JoinCodeSettingsCard.razor.rz.scp.css */
/* FDD-0001 S1 (#346) — the join-code card.

   House tokens only. The card chrome repeats .settings-card's values rather than
   inheriting them, because Settings.razor.css is scoped to Settings and would need
   a ::deep rule to reach a child component — and a self-contained component is the
   easier thing to read and to move.

   No new brand, no new component, no gradient, no effect the app lacks. */

.joinCode-card[b-x35rb6ne1x] {
    background: #f6f8fb;
    border-radius: 0.35rem;
    margin-bottom: 0.75rem;
    padding: 0.75rem 0.85rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
    scroll-margin-top: 1rem;
}

.joinCode-card h2[b-x35rb6ne1x] {
    color: #24384f;
    font-size: 1.05rem;
    margin: 0 0 0.4rem;
}

/* The #join-code anchor SCROLLS AND MARKS. A focus outline, dropped on the first
   interaction — no animation and no flash, because this page gets opened on a
   shared tablet mid-session. */
.joinCode-card-marked[b-x35rb6ne1x] {
    outline: 2px solid #9ec5fe;
    outline-offset: 2px;
}

/* NO font-size HERE, deliberately (signoff G2). §7.2's reuse table lists
   .settings-card-help as reused VERBATIM for "the card, its sub-blocks and its
   help text", and that class sets no font-size — it inherits the page's 1rem.
   An earlier build lifted 0.86rem from the standalone mockup FILE's decorative
   CSS, which rendered at 13.76px directly above the Club settings card's 16px
   help paragraph: same grey, same chrome, same page, a step visible on a plain
   read-through. The colour and rhythm are .settings-card-help's; so is the size,
   by not being restated. The two declarations below are .settings-card-help's
   own, and nothing else — a fourth would be the same drift in miniature. */
.joinCode-help[b-x35rb6ne1x] {
    margin: 0 0 0.65rem;
    color: #5f6f80;
}

/* ── The credential chip ────────────────────────────────────────────────────────
   .clubSession-code-banner-code's typography VERBATIM — mono, 1.45rem, 800,
   letter-spacing .14em — because that contract is what carries Z/2, S/5 and B/8
   across a hall, and it is not re-derived here.

   THE COLOUR IS CHANGED, and that is the one deliberate departure: green already
   means TONIGHT'S SESSION CODE on the board, and two identical green chips meaning
   two different codes is exactly the confusion an officer cannot afford while
   reading one out. Navy is the house's other credential pairing and introduces no
   new colour. Ruled and accepted (FDD §7.2). */
.joinCode-chip[b-x35rb6ne1x] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.55rem;
    font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    font-size: 1.45rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    line-height: 1;
    color: #0d2c55;
    background: #eef2f7;
    border: 1.5px solid #c5d4e6;
    border-radius: 0.4rem;
    padding: 0.42rem 0.7rem;
    white-space: nowrap;
    /* Selectable at all times — never user-select:none decoration. */
    user-select: text;
}

.joinCode-chip-masked[b-x35rb6ne1x] {
    color: #8496a8;
    letter-spacing: 0.2em;
}

.joinCode-coderow[b-x35rb6ne1x] {
    display: flex;
    gap: 0.7rem;
    align-items: center;
    flex-wrap: wrap;
    margin: 0.15rem 0 0.55rem;
}

.joinCode-provenance[b-x35rb6ne1x] {
    font-size: 0.76rem;
    color: #8496a8;
    line-height: 1.4;
    margin: 0;
}

/* ado:1437: the read-only "is this code on the board" line. Sized off .joinCode-provenance, because
   it is the same kind of thing - a quiet fact ABOUT the code, sitting under it, not competing with
   the paste sentence that is the card's primary object. */
.joinCode-board-status[b-x35rb6ne1x] {
    font-size: 0.76rem;
    color: #5f6f80;
    line-height: 1.4;
    margin: 0.35rem 0 0;
}

/* The dot is aria-hidden and purely reinforcing: the WORDS carry the state, so there is no
   colour-only signal here to fail on. */
.joinCode-board-dot.on[b-x35rb6ne1x] {
    color: #15803d;
}

.joinCode-board-dot.off[b-x35rb6ne1x] {
    color: #94a3b8;
}

.joinCode-cooldown[b-x35rb6ne1x] {
    margin-top: 0.5rem;
}

/* ── The ready-to-paste sentence: the primary object on the card ────────────────
   The code is the largest thing; the sentence is the primary ACTION. Not in
   conflict — hierarchy answers "what is this", the primary button answers "what do
   I do". The code is read ALOUD across a hall so it must be legible at arm's
   length; the thing she needs to TAKE AWAY is the whole instruction, because the
   hard half is the sign-up address, not the six letters. */
.joinCode-sentence[b-x35rb6ne1x] {
    background: #fff;
    border: 1px solid #cbd5e1;
    border-radius: 0.5rem;
    padding: 0.6rem 0.7rem;
    color: #16324f;
    font-size: 0.92rem;
    line-height: 1.55;
    margin: 0;
    user-select: text;
}

/* The sentence's INTERNAL emphasis — the mockup's `.sentence b` and
   `.sentence .cd`, restored at signoff G3. Inside the one piece of text the
   officer actually takes away, the code was rendering identically to the prose
   around it: §7.2's hierarchy argument rests on the code being read aloud and
   staying findable, and one flat run of body text is exactly what makes it
   neither. The two things she has to get right — the address and the six
   letters — are the two things set apart. */
.joinCode-sentence b[b-x35rb6ne1x] {
    color: #0d2c55;
}

.joinCode-sentence-code[b-x35rb6ne1x] {
    font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    font-weight: 800;
    letter-spacing: 0.1em;

    /* THE DOUBLED GROUP GAP, corrected 2026-09-13. Grouped() inserts a REAL space between the
       two halves, and letter-spacing then adds 0.1em after the character AND another after the
       space itself — so "XF4 PTF" rendered as "XF4   PTF", a gap that reads as a rendering
       fault on the one string this card exists to have trusted and pasted.

       IN THE CHIP that tracking is right and is untouched: it is a credential read aloud across
       a hall, and the 31-symbol alphabet plus the spacing is what carries Z/2, S/5 and B/8. In
       RUNNING PROSE the same tracking is a defect.

       word-spacing cancels the letter-space applied TO the space and tightens the mono space
       itself. Measured live rather than chosen: the internal group gap goes 10.1px -> 6.41px
       against a 4.08px prose word-gap in this same sentence, so it reads as one deliberate chunk
       separator rather than three spaces, while staying clearly wider than a word gap so the 3·3
       grouping survives. The chip's own gap is 16.83px and does not move.

       THERE IS DELIBERATELY NO margin-right COMPENSATION, and that is a correction to this very
       rule. The first fix added margin-right: -0.1em to cancel a trailing letter-space after the
       final character. THE PREMISE WAS WRONG — measured, the trailing gap with no margin at all
       is 4.08px, matching the leading gap (4.09px) and the prose word-gap (4.08px) to the
       decimal. The margin was pure overcorrection and pulled the trailing edge to 2.61px, about
       64% of a word-gap, so the code sat measurably closer to the word after it than the word
       before it. Removing it makes the span symmetric BY CONSTRUCTION rather than by a second
       number that has to be kept in step with the first. If you are tempted to add a horizontal
       margin here again, measure both edges with Range.getBoundingClientRect() on a single line
       first — the sentence wraps at narrow widths and cross-line ranges report nonsense.

       All of this is VISUAL ONLY: the clipboard takes ShareSentence and Grouped(_code), which
       are C# strings no CSS can reach. */
    word-spacing: -0.25em;
}

/* Screen 6. The native selection is the real recovery and it works — but it
   vanishes the moment the officer clicks anywhere else, and the alert's claim
   ("The message above is selected") then points at nothing. The mockup ties the
   two together with a highlighted box, so the cue survives the click. */
.joinCode-sentence-refused[b-x35rb6ne1x] {
    border-color: #9ec5fe;
    background: #f4f9ff;
}

/* ── Actions ────────────────────────────────────────────────────────────────────
   Kiosk floor: every target ≥44px, and no hover-only affordance anywhere. */
.joinCode-actions[b-x35rb6ne1x] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.6rem;
}

.joinCode-actions-spacer[b-x35rb6ne1x] {
    flex: 1 1 auto;
}

.joinCode-btn[b-x35rb6ne1x] {
    min-height: 2.75rem;
    line-height: 1.2;
}

.joinCode-alert[b-x35rb6ne1x] {
    margin: 0.55rem 0 0;
    font-size: 0.85rem;
    line-height: 1.55;
    padding: 0.55rem 0.7rem;
}

/* The copied cue PERSISTS for the visit (the button label does not) — an officer
   who copied, switched to WhatsApp and came back can see she already has it. */
.joinCode-cue[b-x35rb6ne1x] {
    display: block;
    margin: 0.5rem 0 0;
    color: #146c43;
    font-size: 0.84rem;
    font-weight: 600;
}

/* ── The rotation confirm ───────────────────────────────────────────────────────
   Values lifted VERBATIM from Settings.razor.css's .modal-backdrop / .modal-box /
   .modal-actions (the delete-profile confirm), not reused by class name: those
   rules are scoped to Settings, so a child component's markup does not match
   them — and the bare `.modal-backdrop` it would otherwise fall through to is
   BOOTSTRAP's, a full-screen black overlay with no box at all. */
.joinCode-modal-backdrop[b-x35rb6ne1x] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2200;
}

.joinCode-modal-box[b-x35rb6ne1x] {
    width: min(480px, 94vw);
    background: #fff;
    border: 1px solid #c8d4e2;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 1.1rem 1.2rem 1rem;
}

.joinCode-modal-box h2[b-x35rb6ne1x] {
    margin: 0 0 0.6rem;
    color: #0d2c55;
    font-size: 1.15rem;
}

.joinCode-modal-box p[b-x35rb6ne1x] {
    color: #4d5f72;
    font-size: 0.92rem;
    line-height: 1.6;
    margin: 0 0 0.6rem;
}

.joinCode-modal-actions[b-x35rb6ne1x] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.8rem;
    flex-wrap: wrap;
}

/* The rotation confirm's reassurance is its OWN BLOCK, not a clause — it is the
   sentence that decides whether a leaked code gets rotated at all. */
.joinCode-modal-box p.joinCode-keep[b-x35rb6ne1x] {
    color: #0a3622;
    background: #d1e7dd;
    border: 1px solid #a3cfbb;
    border-radius: 0.375rem;
    padding: 0.5rem 0.65rem;
}

/* Loading RESERVES LAYOUT; it does not reassure. The card is the first thing under
   the page title, so a late-arriving code would shove four cards of settings down
   the page. Deliberately STATIC — no shimmer, no spinner, no animation on the chip:
   movement at the top of a settings page opened on a shared tablet is noise. */
.joinCode-skeleton[b-x35rb6ne1x] {
    height: 1.9rem;
    width: 11rem;
    background: #e8edf4;
    border-radius: 0.4rem;
    margin-top: 0.5rem;
}

.joinCode-skeleton-wide[b-x35rb6ne1x] {
    width: 70%;
    height: 3.1rem;
}

.joinCode-skeleton-thin[b-x35rb6ne1x] {
    width: 9rem;
    height: 0.85rem;
}

/* On a phone the destructive button drops to its OWN FULL-WIDTH ROW below the two
   copies — a right-aligned "New code" sits exactly where a right thumb rests — and
   the provenance line moves under the chip so the code never shrinks to share a
   row. This is the 21:40 moment the card's whole shape is designed for. */
@media (max-width: 560px) {
    .joinCode-coderow[b-x35rb6ne1x] {
        display: block;
    }

    .joinCode-coderow .joinCode-provenance[b-x35rb6ne1x] {
        display: block;
        margin-top: 0.35rem;
    }

    .joinCode-actions-spacer[b-x35rb6ne1x] {
        display: none;
    }

    .joinCode-btn-danger[b-x35rb6ne1x] {
        width: 100%;
        margin-top: 0.15rem;
    }
}

/* ── ado:1432: the card must never widen the DOCUMENT ───────────────────────────
   S1 shipped this card on /settings alone, where it was never measured against the
   narrowest supported cell. S3 mounts it a second time on /members, which IS
   measured there: Spec41ConnectQueueGeometryTests asserts that nothing on that page
   pushes the document out at 288 CSS px (a 360px phone at 125%), and mounting the
   card made that assertion fail — 12px of pre-existing overflow became 53px. Proved
   by isolation: removing the mount made it pass again.

   The cause is the card's two deliberately unbreakable runs — the chip carries
   `white-space: nowrap` so a code is never split across lines mid-read, and the
   action labels are whole phrases — meeting a viewport narrower than any the card
   was drawn against. THE FIX CONTAINS, IT DOES NOT REDESIGN: nothing here changes
   what the card looks like at any width it already handled, and the nowrap contract
   on the chip is untouched. What changes is where the excess goes — inside the card,
   instead of into the page. The alternative, constraining the card from the members
   page, would be a per-mount divergence and the first crack in "one implementation,
   two mount points". */
.joinCode-card[b-x35rb6ne1x] {
    max-width: 100%;
}

/* The chip keeps nowrap — a join code split across two lines is misread aloud —
   so at a width that genuinely cannot hold it, it scrolls WITHIN the card rather
   than widening the page. In practice this never engages: 288px holds the chip
   comfortably, and this is the floor under the case where it does not. */
.joinCode-chip[b-x35rb6ne1x] {
    max-width: 100%;
    overflow-x: auto;
}

/* Buttons may shrink below their content box rather than forcing a wider row. The
   row already wraps; this is what lets the LAST button wrap instead of overflowing. */
.joinCode-actions .joinCode-btn[b-x35rb6ne1x] {
    min-width: 0;
    max-width: 100%;
    /* Bootstrap .btn is white-space: nowrap. On a mobile viewport Chrome BOOSTS text
       (the connect-queue geometry probe shows this page rendering an h2 at 32px on a
       288px viewport), and a boosted nowrap label is exactly what pushes a document
       wide. Whole-phrase labels are the card design; letting one wrap onto two lines
       at a width that cannot hold it is far better than a page that scrolls sideways. */
    white-space: normal;
}

/* EVERY run of prose on this card interpolates the CLUB NAME, which is user-controlled
   and can be a single unbreakable token — and the sign-up address and the code are two
   more runs a browser will not break by default. A club name is content, not layout:
   whatever an officer types must never be able to widen the page. This is what the
   geometry probe actually caught — P.joinCode-help measured cw=177 sw=284 with a 36-
   character single-token club name in it, and that 107px is where the document overflow
   came from, not the chip or the buttons. Breaking prose mid-word at a width that cannot
   hold it is plainly right; the chip, which is read ALOUD, keeps nowrap and scrolls
   instead. */
.joinCode-help[b-x35rb6ne1x],
.joinCode-sentence[b-x35rb6ne1x],
.joinCode-provenance[b-x35rb6ne1x],
.joinCode-alert[b-x35rb6ne1x],
/* The rotate confirm's heading — "Give {Club name} a new join code?" — interpolates the club
   name exactly as the four above do, and was missed on the first pass. Added at UX review,
   which measured it: a 68-character single-token club name gives the h2 a scrollWidth of
   576px in a 313px box at 375px wide, so the tail of the name is CLIPPED and unreadable
   INSIDE THE DIALOG. The page itself does not widen (body.scrollWidth held at 375), so this
   is a legibility gap in one dialog rather than a second instance of the overflow bug — but
   an officer being asked to confirm a destructive rotation, who cannot read which club the
   dialog names, is the worse of the two failures. */
.joinCode-modal-box h2[b-x35rb6ne1x] {
    overflow-wrap: anywhere;
}

/* THE CODE INSIDE THE SENTENCE IS EXEMPT, and it is the same contract the chip carries.
   The rule above INHERITS into this span, which has no white-space of its own — so without
   this the card would protect a code from splitting in the chip and allow it in the
   sentence, against the card's own stated reason: a join code broken across two lines is
   misread when it is read aloud across a hall.

   This closes a gap between two rules guarding one thing; it is not fixing a live break.
   Six characters never need to wrap at any supported width, and a soft wrap does not
   survive a copy, so the paste-ready sentence was never actually at risk. The prose AROUND
   the code still breaks mid-word, which is what keeps a long club name — user-controlled
   content — from widening the page. */
.joinCode-sentence-code[b-x35rb6ne1x] {
    overflow-wrap: normal;
    word-break: keep-all;
    white-space: nowrap;
}
/* /Components/Kiosk/KioskDisplayProfileSettingsCard.razor.rz.scp.css */
/* S2 (#988 / #946): can-see view-block card. Layout only — matches the toggle-row shape used by
   the feature-flags toggles; visual language (club-card / club-help-text) is inherited global. */
.kiosk-display-profile-toggles[b-29i9brxem2] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: 0.5rem;
}

.kiosk-display-profile-toggle[b-29i9brxem2] {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    cursor: pointer;
    margin: 0;
}

.kiosk-display-profile-toggle .form-check-input[b-29i9brxem2] {
    margin-top: 0.15rem;
    flex: 0 0 auto;
}

.kiosk-display-profile-label[b-29i9brxem2] {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.kiosk-display-profile-desc[b-29i9brxem2] {
    color: var(--bs-secondary-color, #6c757d);
    font-size: 0.85rem;
}
/* /Components/Layout/DemoSpotlights.razor.rz.scp.css */
.demo-spotlights-card[b-xb7o3vkr4w] {
    position: fixed;
    /* bottom matches the QuickFeedback FAB (right: 1rem; bottom: 1rem)
       so the pill and FAB sit on the same baseline. */
    bottom: 1rem;
    /* Anchored on the right edge so the open card pops up in the same
       column as the collapsed pill (right: 7.5rem). Bottom-left would
       overlap the Game Prep panel, which is the most important part of
       the dashboard. */
    right: 7.5rem;
    width: 22rem;
    max-width: calc(100vw - 2.5rem);
    background: #ffffff;
    border: 1px solid #d6e0ee;
    border-radius: 0.75rem;
    box-shadow: 0 0.75rem 1.75rem rgba(13, 44, 85, 0.18);
    padding: 0.9rem 1rem 1rem 1rem;
    z-index: 980; /* below modal-backdrop ~1040 but above QuickFeedback FAB */
    font-size: 0.95rem;
    line-height: 1.35;
    color: #1d2733;
    /* Card body must not intercept clicks meant for the underlying dashboard
       (e.g. waiting-chip column on bottom-left). Buttons re-opt-in below. */
    pointer-events: none;
}

.demo-spotlights-card button[b-xb7o3vkr4w],
.demo-spotlights-card a[b-xb7o3vkr4w] {
    pointer-events: auto;
}

.demo-spotlights-head[b-xb7o3vkr4w] {
    margin-bottom: 0.35rem;
}

.demo-spotlights-step[b-xb7o3vkr4w] {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    color: #5a6b80;
}

.demo-spotlights-title[b-xb7o3vkr4w] {
    font-weight: 600;
    color: #0d2c55;
    margin-bottom: 0.35rem;
}

.demo-spotlights-body[b-xb7o3vkr4w] {
    margin-bottom: 0.75rem;
}

.demo-spotlights-actions[b-xb7o3vkr4w] {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
}

.demo-spotlights-back[b-xb7o3vkr4w],
.demo-spotlights-show-me[b-xb7o3vkr4w],
.demo-spotlights-next[b-xb7o3vkr4w] {
    min-width: 5rem;
}

/* Make the primary action obviously the primary action — bigger and bolder
   than the default btn-sm so the eye lands on it before anything else. */
.demo-spotlights-actions .btn-primary[b-xb7o3vkr4w] {
    padding: 0.4rem 1rem;
    font-weight: 600;
}

.demo-spotlights-hide-link[b-xb7o3vkr4w] {
    display: block;
    margin: 0.6rem 0 0 0;
    padding: 0;
    background: transparent;
    border: 0;
    color: #5a6b80;
    font-size: 0.78rem;
    text-decoration: underline;
    cursor: pointer;
    width: 100%;
    text-align: right;
}

.demo-spotlights-hide-link:hover[b-xb7o3vkr4w] {
    color: #0d2c55;
}

.demo-spotlights-reopen[b-xb7o3vkr4w] {
    position: fixed;
    /* bottom matches the QuickFeedback FAB (bottom: 1rem) so the two
       pills sit on the same baseline. */
    bottom: 1rem;
    /* Sits just left of the QuickFeedback FAB (right: 1rem, ~6rem wide).
       Bottom-left would overlap the Game Prep panel, which is the most
       important part of the dashboard. */
    right: 7.5rem;
    background: #ffffff;
    border: 1px solid #d6e0ee;
    border-radius: 999px;
    box-shadow: 0 0.5rem 1rem rgba(13, 44, 85, 0.14);
    /* Vertical metrics match the QuickFeedback FAB (font 0.85rem,
       padding-y 0.45rem, line-height 1.5, border 1px) so the two pills
       are the same height and their top edges line up. The left padding
       is tighter than the right to make room for the "?" badge. */
    padding: 0.45rem 0.85rem 0.45rem 0.7rem;
    line-height: 1.5;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: #0d2c55;
    cursor: pointer;
    font-size: 0.85rem;
    z-index: 970;
}

.demo-spotlights-reopen:hover[b-xb7o3vkr4w] {
    background: #f3f7fc;
}

.demo-spotlights-reopen span[aria-hidden="true"][b-xb7o3vkr4w] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 999px;
    background: #0d2c55;
    color: #ffffff;
    font-size: 0.7rem;
    font-weight: 700;
}

@media (max-width: 720px) {
    /* BL-077: card stretches edge-to-edge so the guide content is readable
       on narrow screens. Bottom margin clears the corner-pinned FABs below
       (Feedback FAB at bottom: 0.6rem; this pill sits beside it). */
    .demo-spotlights-card[b-xb7o3vkr4w] {
        bottom: 3.5rem;
        right: 0.5rem;
        left: 0.5rem;
        width: auto;
        max-width: none;
    }

    /* Hide the "Demo guide" label on mobile and keep only the round "?"
       badge as a tiny corner pill. Same rationale as the QuickFeedback FAB
       shrink — the wide text pill was overlapping the Score Entry / picker
       controls. */
    .demo-spotlights-reopen[b-xb7o3vkr4w] {
        bottom: 0.6rem;
        right: 3rem;
        padding: 0;
        width: 2.1rem;
        height: 2.1rem;
        border-radius: 50%;
        font-size: 0;
        opacity: 0.65;
        gap: 0;
        justify-content: center;
    }

    .demo-spotlights-reopen-label[b-xb7o3vkr4w] {
        display: none;
    }

    .demo-spotlights-reopen span[aria-hidden="true"][b-xb7o3vkr4w] {
        width: 1.25rem;
        height: 1.25rem;
        font-size: 0.78rem;
    }
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
.page[b-10ve630zyd] {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    min-height: 100vh;
}

main[b-10ve630zyd] {
    flex: 1;
    min-width: 0;
    width: 100%;
}

/* #298: hamburger on the left, status banner(s) / fallback user menu in the
   column to its right, on a single row. The content column is flex:1 so it
   fills the width; when nothing is showing (e.g. persistent-sidebar desktop
   with the hamburger hidden and no banner) the row collapses to zero height. */
.layout-top-bar[b-10ve630zyd] {
    display: flex;
    align-items: flex-start;
    gap: 0.25rem;
}

.layout-top-bar-content[b-10ve630zyd] {
    flex: 1 1 auto;
    min-width: 0;
}

/* #335: on the session dashboard when the bar is bare (hamburger only, no banner)
   it was wasting a whole line above the dashboard. Float it out of flow so the
   dashboard's own top button row reclaims that line; the hamburger then sits at
   the page's top-left, on the same visual line as the kiosk action buttons (the
   kiosk top row pads its start to clear it - see the .page--topbar-bare rule in
   ClubSessionDashboard.razor.css). The banner case (superuser / demo) keeps the
   #298 in-flow shared row, and the Results Desk kiosk route is left untouched.
   #390: fixed (not absolute) so the hamburger stays pinned to the viewport top-left
   when the page scrolls on short screens (mini-laptops) - absolute scrolled it away
   with the document and the operator lost the nav menu off the top.
   Full-screen (body.kiosk-mode = Axis-1 "Full screen"): this floated-hamburger
   treatment is FULL-SCREEN-ONLY. Off full-screen the session dashboard wears the
   normal app chrome (persistent sidebar at desktop / standard overlay hamburger on
   small screens), like every other page.

   TODO Axis 2 (Kiosk): the LOCKED kiosk role (hidden nav + reduced role + exit-PIN)
   is a SEPARATE, DISTINCT state — it must NOT overload body.kiosk-mode (which here
   means the nav-visible Axis-1 "Full screen"). Axis 2 layers its own state/class on
   top; hiding the nav is re-homed there, not here. Do not re-conflate the two. The
   internal name `kiosk` is retained for the Axis-1 mechanism only because renaming
   `body.kiosk-mode` cross-cuts ~40 baseline sidebar-rail selectors + the .page--kiosk
   Results-Desk route; the user-facing label is "Full screen". */
body.kiosk-mode .page--kiosk-session.page--topbar-bare .layout-top-bar[b-10ve630zyd] {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 20;
}

body.kiosk-mode .page--kiosk-session.page--topbar-bare .nav-hamburger[b-10ve630zyd] {
    /* Nudge the hamburger down so it vertically centres on the kiosk top row
       (which starts ~1rem of content padding + the shell's own top padding
       below the page top) rather than hugging the very top edge. */
    margin-top: 1.5rem;
}

/* ── Effective Permissions (Kiosk Axis 2, epic #325) S2b-i — the LOCKED kiosk HAT ─────
   This is the Axis-2 state the TODO above anticipated: a DISTINCT class,
   body.pegboard-kiosk-hat, NOT an overload of Axis-1's body.kiosk-mode. Where Axis-1
   "Full screen" KEEPS the hamburger (floated overlay, rule above), the locked kiosk hat
   REMOVES the nav entirely — there is nothing to swipe/tap out to; exit is the KIOSK pill
   → PIN. `display:none` (not visibility) so the hidden nav also LEAVES THE TAB ORDER (a11y:
   keyboard/AT focus can't tab out to now-hidden nav while the device is locked). `!important`
   so this one rule wins over the Axis-1 sidebar/hamburger rules that are spread across the
   several @media blocks below, at every breakpoint, without duplicating this into each. */
body.pegboard-kiosk-hat .nav-hamburger[b-10ve630zyd],
body.pegboard-kiosk-hat .sidebar[b-10ve630zyd],
body.pegboard-kiosk-hat .sidebar-backdrop[b-10ve630zyd] {
    display: none !important;
}

.demo-session-banner[b-10ve630zyd] {
    margin: 0.9rem 1rem 0;
    border: 1px solid #e3b14a;
    background: #fff4d6;
    color: #6a4a08;
    border-radius: 0.55rem;
    padding: 0.55rem 0.75rem;
    font-size: 0.92rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.demo-session-banner-text[b-10ve630zyd] {
    flex: 1 1 auto;
    min-width: 0;
}

.demo-session-banner a[b-10ve630zyd],
.demo-session-banner-cta[b-10ve630zyd] {
    margin-left: 0.25rem;
    color: #7b4f00;
    font-weight: 600;
}

/* BL-080: "Copy link" button — visually distinct from the prose CTA so the
   share path is obvious. On mobile (sticky banner below) it's a thumb-friendly
   tap target alongside the now button-styled "Sign up properly" link. */
.demo-session-banner-copy[b-10ve630zyd] {
    flex: 0 0 auto;
    border: 1px solid #c4933b;
    background: #fff;
    color: #7b4f00;
    border-radius: 999px;
    padding: 0.2rem 0.75rem;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}

.demo-session-banner-copy:hover[b-10ve630zyd] {
    background: #fbeac5;
}

/* BL-080: on mobile the banner becomes sticky-top so the convert CTA stays
   reachable as the user scrolls through the demo, and the "Sign up properly"
   link gets button styling for a clearer tap target. */
@media (max-width: 720px) {
    .demo-session-banner[b-10ve630zyd] {
        position: sticky;
        top: 0;
        z-index: 50;
        margin: 0;
        border-radius: 0;
        border-left: 0;
        border-right: 0;
        font-size: 0.88rem;
        padding: 0.5rem 0.75rem;
        gap: 0.5rem;
    }

    /* Selector includes the `a` element so it beats `.demo-session-banner a`
       (0,1,1) — without that, the parent rule's brown color wins and the
       label disappears against the brown button background. */
    .demo-session-banner a.demo-session-banner-cta[b-10ve630zyd] {
        display: inline-block;
        background: #7b4f00;
        color: #fff;
        border-radius: 999px;
        padding: 0.15rem 0.7rem;
        text-decoration: none;
        margin-left: 0.3rem;
    }
}

.email-verification-banner[b-10ve630zyd] {
    margin: 0.9rem 1rem 0;
    border: 1px solid #4f86c6;
    background: #e8f1fb;
    color: #1f3d6a;
    border-radius: 0.55rem;
    padding: 0.55rem 0.75rem;
    font-size: 0.92rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.email-verification-banner-body[b-10ve630zyd] {
    flex: 1;
    min-width: 0;
}

.email-verification-banner a[b-10ve630zyd] {
    margin-left: 0.5rem;
    color: #134a90;
    font-weight: 600;
}

/* #245: the post-signup "Not junk" reassurance drops to its own line under the verify prompt. */
.email-verification-banner-reassurance[b-10ve630zyd] {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.85rem;
    line-height: 1.35;
    opacity: 0.9;
}

.email-verification-banner-dismiss[b-10ve630zyd] {
    flex: 0 0 auto;
    background: transparent;
    border: none;
    color: #1f3d6a;
    font-size: 1.4rem;
    line-height: 1;
    padding: 0 0.25rem;
    cursor: pointer;
    opacity: 0.6;
}

.email-verification-banner-dismiss:hover[b-10ve630zyd],
.email-verification-banner-dismiss:focus-visible[b-10ve630zyd] {
    opacity: 1;
    outline: none;
}

/* Interim: shrinks the superuser read-only / administer indicator from a
   full-width banner ROW to a compact inline pill tucked into the top-bar
   corner, so a super-user viewing a session sees the dashboard like a normal
   club would (the old banner ate a whole vertical line + distorted the layout).
   The -off/-on rules keep the shared colours; .superuser-write-pill overrides
   the full-width LAYOUT only. Throwaway — Axis 2 folds this into a proper
   permissions layer. */
.superuser-write-banner-off[b-10ve630zyd] {
    border: 1px solid #c7921b;
    background: #fff4d8;
    color: #5c440a;
}

.superuser-write-banner-on[b-10ve630zyd] {
    border: 1px solid #b13b3b;
    background: #fde5e5;
    color: #5f1818;
}

.superuser-write-pill[b-10ve630zyd] {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.4rem;
    /* Override the banner's full-width row spacing: no top-of-column margin,
       shrink to content, sit inline in the top bar. */
    margin: 0.15rem 0;
    padding: 0.15rem 0.35rem 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.78rem;
    line-height: 1;
    white-space: nowrap;
    width: auto;
    flex-wrap: nowrap;
}

.superuser-write-pill .superuser-write-pill-label[b-10ve630zyd] {
    font-weight: 600;
}

/* Slim the (Bootstrap-classed) toggle button down to pill scale. */
.superuser-write-pill .superuser-write-pill-btn[b-10ve630zyd] {
    padding: 0.2rem 0.55rem;
    font-size: 0.72rem;
    line-height: 1;
    border-radius: 999px;
}

.sidebar[b-10ve630zyd] {
    background: linear-gradient(180deg, #294f76 0%, #1f3d5b 100%);
    border-right: 1px solid #5b7694;
    width: 250px;
    /* #334: dvh (dynamic viewport height) tracks the real visible area as the
       mobile browser's address bar shows/hides. Plain 100vh is the *large*
       viewport (toolbar retracted), so with the URL bar visible the sidebar's
       bottom — where the docked user-menu footer lives — fell below the screen.
       100vh stays as the fallback line for any browser without dvh support. */
    height: 100vh;
    height: 100dvh;
    /* #276: flex column so the nav list scrolls and the user-menu footer docks
       to the bottom of the window. */
    display: flex;
    flex-direction: column;
}

.content[b-10ve630zyd] {
    padding-top: 1rem;
}

/* #438: collapse/expand toggle. Hidden by default (phone overlay band + kiosk, where the
   sidebar isn't a persistent rail-able column — the .nav-hamburger overlay is the nav control
   there). Shown only when the sidebar is persistent: >=768px non-kiosk (rule further down).
   It is a direct child of .sidebar (a position:sticky flex column = a containing block), so it
   is absolutely pinned to the top-right of the sidebar header in the FULL state, and recentred
   into the rail head in the COLLAPSED state. >=44px touch target. */
.nav-rail-toggle[b-10ve630zyd] {
    display: none;
    position: absolute;
    top: 0.55rem;
    right: 0.5rem;
    z-index: 5; /* above the brand header within the sidebar */
    align-items: center;
    justify-content: center;
    width: 2.75rem;   /* 44px touch target */
    height: 2.75rem;
    padding: 0;
    border: 1px solid #5b7694;
    border-radius: 0.45rem;
    background: rgba(41, 79, 118, 0.65);
    color: #dce6f2;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.nav-rail-toggle:hover[b-10ve630zyd],
.nav-rail-toggle:focus-visible[b-10ve630zyd] {
    background: #1f3d5b;
    color: #fff;
    outline: none;
}

.nav-rail-toggle-icon[b-10ve630zyd] {
    display: block;
    line-height: 1;
}

/* Hamburger toggle: hidden by default, shown only when the sidebar is in
   overlay mode (below the persistent-sidebar breakpoint) or on the kiosk route.
   #298: it's the left item of the top-bar flex row (banner to its right), so it
   owns its own top/left inset rather than relying on a container's padding. */
.nav-hamburger[b-10ve630zyd] {
    display: none;
    margin: 0.8rem 0 0 0.75rem;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.4rem;
    border: 1px solid #5b7694;
    border-radius: 0.45rem;
    background: #294f76;
    color: #fff;
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}

.nav-hamburger:hover[b-10ve630zyd],
.nav-hamburger:focus-visible[b-10ve630zyd] {
    background: #1f3d5b;
    outline: none;
}

.sidebar-backdrop[b-10ve630zyd] {
    display: none;
}

/* Overlay mode: phone band (below the icon-rail threshold).
   Sidebar slides in from the left; backdrop receives tap-outside-to-close.
   Icon-rail rework: the old single overlay band was max-width:1279.98px. It is now
   split — <768px stays this pure off-canvas overlay (phone), and 768–1279.98px gets
   the persistent icon rail (see the @media block below). Kiosk mode keeps the overlay
   across the WHOLE old band (handled in its own block) so the kiosk board is unchanged. */
@media (max-width: 767.98px) {
    .nav-hamburger[b-10ve630zyd] {
        display: inline-flex;
    }

    .sidebar[b-10ve630zyd] {
        position: fixed;
        top: 0;
        left: 0;
        /* #334: pin to both top and bottom so the docked user-menu footer stays
           on-screen even on a browser that ignores dvh (height alone leaned on
           100vh and overshot the visible area below the mobile address bar). */
        bottom: 0;
        max-width: 88vw;
        transform: translateX(-100%);
        transition: transform 0.18s ease-out;
        z-index: 1700;
        box-shadow: 2px 0 12px rgba(0, 0, 0, 0.25);
    }

    .sidebar.sidebar-open[b-10ve630zyd] {
        transform: translateX(0);
    }

    .sidebar-backdrop[b-10ve630zyd] {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.35);
        z-index: 1650;
    }
}

/* ── Icon-rail mode: USER-CONTROLLABLE (#438) ───────────────────────────────────
   The collapsed icon rail used to be width-driven only (forced at 768–1279.98px). It is
   now driven by a single persisted class, html.nav-rail-collapsed, applied pre-paint by
   App.razor's inline script (seeded from width on first visit, then by the user's toggle),
   so the user can collapse/expand the sidebar at ANY width >=768px. The rail VISUAL rules
   (this hoisted, media-query-free section) fire purely on that class; the rail LAYOUT
   (width / flex-row / gutters) lives in the >=768px block further down where the sidebar is
   persistent. There is no overlay in the user-collapse path — expanding simply removes the
   class and the full in-flow sidebar returns.

   KIOSK (body.kiosk-mode) is excluded everywhere (its own blocks keep the stripped board).
   Phone (<768px) keeps its off-canvas overlay regardless of the class — the rail only makes
   sense where the sidebar is persistent. */

/* ── Rail content: reach into NavMenu via ::deep. NavMenu is rendered by MainLayout, so
   ::deep penetrates its scoped markup. Each selector carries its own ::deep (scoped CSS does
   not distribute ::deep across a comma group). Gated on html.nav-rail-collapsed AND a
   >=768px floor (#476): below 768px the sidebar is a full-width off-canvas OVERLAY where
   labels MUST show, so the rail's label/brand/section-hiding must never apply there even if
   the class is set (seeded or stored). The rail only makes sense where the sidebar is a
   persistent column (>=768px). No :not(.sidebar-open) — there is no overlay state in the
   >=768px user-collapse path. */
@media (min-width: 768px) {
/* Brand row: centre the logo; the toggle button (#438) owns the top of the rail, so push the
   brand header content below it (header min-height is 4.4rem, room for both). */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .top-row {
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-top: 2.9rem;
    justify-content: center;
    align-items: flex-start;
}

html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .container-fluid {
    padding-left: 0;
    padding-right: 0;
    display: flex;
    justify-content: center;
}

html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-top-brand {
    align-items: center;
    justify-content: center;
    gap: 0;
}

/* Rail = LOGO ONLY. Hide the "ePegboard" wordmark + tagline; the figures mark stays, shrunk
   to fit the 56px rail. The full wordmark returns in the expanded (no-class) sidebar. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-top-brand-text {
    display: none;
}

html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-top-logo-figure {
    height: 1.9rem;
}

/* Non-icon content has no place in a rail — hide it. Also hide the expandable Help TOGGLE
   button (its submenu is hidden in the rail, so a click was a dead no-op that left
   _showHelpMenu set); the rail shows the plain .nav-help-rail-link straight to /how-it-works
   instead (revealed below). */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-club-switcher,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-live-panel,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-section-label,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-help-caret,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-help-toggle,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-help-links {
    display: none !important;
}

/* Reveal the rail-only Help link (a direct NavLink to /how-it-works) in the collapsed rail. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-help-rail-link {
    display: flex;
}

/* The session container (club switcher wrapper) collapses its vertical padding so it doesn't
   leave a gap at the top of the rail. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-session {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* nav-item gutter: the rail is centred, so kill the horizontal padding the full sidebar uses. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-item {
    padding-left: 0.125rem !important;
    padding-right: 0.125rem !important;
}

/* Each nav link becomes a centred >=44px tap target showing only its icon. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-link {
    position: relative;
    justify-content: center;
    gap: 0;
    height: 2.75rem;          /* 44px tap target */
    line-height: 2.75rem;
    padding: 0;
}

/* In the 56px rail the active page is hard to read on icon alone — add a clear left-edge accent. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-link.active {
    border-left: 3px solid rgba(255, 255, 255, 0.85);
    border-radius: 0;
}

/* Hide every label span (the direct text span of a nav link) in the rail — the icon and the
   news pill are kept (pill restyled to a dot). display:none, NOT a flyout (a flyout extends
   past the 56px rail and forces a horizontal scrollbar). Hover labels come from title=.

   SPEC-41 S12 (#721): this exclusion list is why every count pill must WEAR .nav-news-pill. A pill
   given a new class name is not merely mis-styled here — it matches this rule and is display:none,
   so the count is INVISIBLE in the collapsed rail (the club tablet) at every value. An absent pill
   is not caught by looking at a screenshot; a wrongly-sized one is. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-link > span:not(.nav-news-pill):not(.nav-help-caret) {
    display: none;
}

/* Count pill -> a small badge dot anchored to the icon's top-right.
   #880: same attention-red as the full-sidebar pill / .live-pill so unread news is
   noticed in the collapsed rail too; white text stays legible on it.

   SPEC-41 S12 (#721): worn by BOTH nav count pills now (News, and Members' waiting count), so the
   name is generic in fact if not in spelling — see the note on .nav-news-pill in NavMenu.razor.css.
   min-width is a FLOOR, not a box, and there is no overflow rule: 1-9 sits well inside the dot,
   10-99 measures under the floor at 0.6rem so the circle does not even grow, and "99+" widens it to
   about 1.15rem at the same height — a short capsule, growing INWARD from its right anchor, far
   inside 56px. That is an acceptance criterion (§6, S12: not clipped at any count), so do not
   "tidy" this into a fixed width or add overflow:hidden — either would clip the count silently. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-news-pill {
    position: absolute;
    top: 0.35rem;
    right: 0.55rem;
    margin: 0;
    min-width: 0.95rem;
    height: 0.95rem;
    padding: 0;
    font-size: 0.6rem;
    line-height: 0.95rem;
    background: linear-gradient(180deg, #f45858 0%, #d73c3c 100%);
    color: #fff;
}

/* User-menu footer -> compact to JUST the avatar in the rail. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .nav-user-menu-slot {
    padding-left: 0.25rem;
    padding-right: 0.25rem;
    display: flex;
    justify-content: center;
}

/* Hide the name / subtitle / caret so only the avatar shows; strip the trigger's full-width chrome. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .user-menu-trigger-text,
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .user-menu-trigger-caret {
    display: none;
}

html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .user-menu-trigger {
    width: auto;
    min-width: 0;
    gap: 0;
    padding: 0.3rem;
    justify-content: center;
}

/* The pop-up panel must NOT inherit the 56px rail width — give it a real width, open to the right. */
html.nav-rail-collapsed body:not(.kiosk-mode) .sidebar[b-10ve630zyd]  .user-menu-dropup .user-menu-panel {
    left: 0;
    right: auto;
    width: 15rem;
    max-width: 78vw;
}
} /* end @media (min-width: 768px) rail-content gate (#476) */

/* ── Persistent sidebar + user-controllable rail LAYOUT, >=768px non-kiosk ───────────
   At >=768px the sidebar is persistent (in flow). This block makes the FULL sidebar the
   baseline at 768–1279.98px too (previously only >=1280px had it; that band used to force
   the rail). The rail is now opt-in via html.nav-rail-collapsed, which overrides the width
   to 3.5rem. The >=1280px block below still owns the >=1280 full-sidebar defaults; this block
   fills in the 768–1279.98 band and carries the rail override for the whole >=768 range.
   Every selector is mirrored onto .page--kiosk-session because the non-kiosk session dashboard
   carries BOTH .page--kiosk and .page--kiosk-session (see the >=1280 block's same mirror). */
@media (min-width: 768px) and (max-width: 1279.98px) {
    /* Full sidebar persistent in this band (when NOT collapsed to the rail). */
    body:not(.kiosk-mode) .page:not(.page--kiosk)[b-10ve630zyd],
    body:not(.kiosk-mode) .page--kiosk-session[b-10ve630zyd] {
        flex-direction: row;
    }

    body:not(.kiosk-mode) .page:not(.page--kiosk) .sidebar[b-10ve630zyd],
    body:not(.kiosk-mode) .page--kiosk-session .sidebar[b-10ve630zyd] {
        position: sticky;
        top: 0;
    }

    body:not(.kiosk-mode) .page:not(.page--kiosk) .content[b-10ve630zyd],
    body:not(.kiosk-mode) .page--kiosk-session .content[b-10ve630zyd] {
        padding-left: 1.25rem !important;
        padding-right: 1.25rem !important;
    }
}

/* Rail width override + toggle visibility: applies wherever the sidebar is persistent
   (>=768px non-kiosk). Separate >=768 media block (no upper bound) so it also collapses the
   sidebar at >=1280px desktop, where the user equally wants the option. */
@media (min-width: 768px) {
    /* The toggle is only meaningful where the sidebar is a persistent column. Show it for
       every non-kiosk page (including the non-kiosk session dashboard, which the kiosk class
       excludes). Kiosk keeps the stripped board (no toggle); phone (<768) keeps the overlay. */
    body:not(.kiosk-mode) .page:not(.page--kiosk) .nav-rail-toggle[b-10ve630zyd],
    body:not(.kiosk-mode) .page--kiosk-session .nav-rail-toggle[b-10ve630zyd] {
        display: inline-flex;
    }

    /* Collapsed rail width override. */
    html.nav-rail-collapsed body:not(.kiosk-mode) .page:not(.page--kiosk) .sidebar[b-10ve630zyd],
    html.nav-rail-collapsed body:not(.kiosk-mode) .page--kiosk-session .sidebar[b-10ve630zyd] {
        width: 3.5rem !important;
        min-width: 3.5rem !important;
    }

    /* In the rail the toggle centres into the 3.5rem head (no full-width header to corner to). */
    html.nav-rail-collapsed body:not(.kiosk-mode) .page:not(.page--kiosk) .nav-rail-toggle[b-10ve630zyd],
    html.nav-rail-collapsed body:not(.kiosk-mode) .page--kiosk-session .nav-rail-toggle[b-10ve630zyd] {
        top: 0.45rem;
        right: auto;
        left: 50%;
        transform: translateX(-50%);
        width: 2.5rem;
        height: 2.5rem;
    }
}

/* Full-screen, tablet band (768–1279.98px): keep the off-canvas overlay exactly as the
   old <=1279.98px band did. The rail is NON-full-screen chrome; in full-screen the board
   stays full-bleed and nav lives behind the floating hamburger. */
@media (min-width: 768px) and (max-width: 1279.98px) {
    body.kiosk-mode .nav-hamburger[b-10ve630zyd] {
        display: inline-flex;
    }

    body.kiosk-mode .sidebar[b-10ve630zyd] {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        max-width: 88vw;
        transform: translateX(-100%);
        transition: transform 0.18s ease-out;
        z-index: 1700;
        box-shadow: 2px 0 12px rgba(0, 0, 0, 0.25);
    }

    body.kiosk-mode .sidebar.sidebar-open[b-10ve630zyd] {
        transform: translateX(0);
    }

    body.kiosk-mode .sidebar-backdrop[b-10ve630zyd] {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.35);
        z-index: 1650;
    }
}

/* Persistent sidebar mode: enough horizontal real estate to keep nav alongside content. */
@media (min-width: 1280px) {
    .page:not(.page--kiosk)[b-10ve630zyd] {
        flex-direction: row;
    }

    .page:not(.page--kiosk) .sidebar[b-10ve630zyd] {
        position: sticky;
        top: 0;
    }

    .page:not(.page--kiosk) .content[b-10ve630zyd] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }

    /* Kiosk mode (session dashboard route): keep sidebar in overlay form even at
       wide viewports — the dashboard wants the full width for courts and queues,
       and admin nav stays one tap away behind the hamburger. */
    .page--kiosk .nav-hamburger[b-10ve630zyd] {
        display: inline-flex;
    }

    .page--kiosk .sidebar[b-10ve630zyd] {
        position: fixed;
        top: 0;
        left: 0;
        max-width: 88vw;
        transform: translateX(-100%);
        transition: transform 0.18s ease-out;
        z-index: 1700;
        box-shadow: 2px 0 12px rgba(0, 0, 0, 0.25);
    }

    .page--kiosk .sidebar.sidebar-open[b-10ve630zyd] {
        transform: translateX(0);
    }

    .page--kiosk .sidebar-backdrop[b-10ve630zyd] {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.35);
        z-index: 1650;
    }

    /* Kiosk rework: kiosk is now OPT-IN. By DEFAULT (no body.kiosk-mode) the session
       dashboard wears the normal persistent-sidebar chrome like every other page, so a
       player dropped in mid-session sees the full app, not a stripped-down board. Only an
       explicit Kiosk mode collapses it (then the .page--kiosk rules above apply). These
       overrides carry higher specificity (body + the extra .page--kiosk-session class) so
       they win over the .page--kiosk collapse for the non-kiosk session. */
    body:not(.kiosk-mode) .page--kiosk-session[b-10ve630zyd] {
        flex-direction: row;
    }

    body:not(.kiosk-mode) .page--kiosk-session .sidebar[b-10ve630zyd] {
        position: sticky;
        top: 0;
        left: auto;
        max-width: none;
        transform: none;
        transition: none;
        z-index: auto;
        box-shadow: none;
    }

    body:not(.kiosk-mode) .page--kiosk-session .content[b-10ve630zyd] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }

    body:not(.kiosk-mode) .page--kiosk-session .nav-hamburger[b-10ve630zyd] {
        display: none;
    }

    body:not(.kiosk-mode) .page--kiosk-session .sidebar-backdrop[b-10ve630zyd] {
        display: none;
    }
}

#blazor-error-ui[b-10ve630zyd] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    /* #386: must sit above every overlay (modal backdrops ~1040, score popover 1200,
       feedback FAB 1900) so the "Reload" link is always clickable. Mike hit a circuit
       error behind the edit-game modal and couldn't reach Reload. */
    z-index: 2147483647;
}

#blazor-error-ui .dismiss[b-10ve630zyd] {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.top-row[b-m4nfq2b2u0],
.nav-scrollable[b-m4nfq2b2u0] {
    --nav-header-height: 4.4rem;
}

/* #276: the sidebar is a flex column (see MainLayout .sidebar). The brand row
   and the docked user-menu footer keep their natural height; the nav list takes
   the space between and scrolls, so the footer stays pinned to the window bottom
   however long the menu is. */
.top-row[b-m4nfq2b2u0] {
    flex: 0 0 auto;
}

.nav-scrollable[b-m4nfq2b2u0] {
    flex: 1 1 auto;
    min-height: 0;
    /* #487: constrain the cross-axis. overflow-y:auto alone makes overflow-x compute to
       auto too (CSS spec), so any descendant a pixel too wide (long club name, a nav-link's
       width:100%+padding+border) re-triggered a horizontal scrollbar in the expanded sidebar
       - the regression d078b57 only fixed for the icon rail. A nav never scrolls sideways. */
    overflow: hidden auto;
}

.top-row[b-m4nfq2b2u0] {
    min-height: var(--nav-header-height);
    background-color: rgba(17, 35, 53, 0.7);
    border-bottom: 1px solid rgba(164, 193, 223, 0.55);
    box-shadow: inset 0 -1px 0 rgba(203, 222, 242, 0.25);
}

.nav-top-brand[b-m4nfq2b2u0] {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

/* The badminton-figures mark; shown in the full sidebar AND the collapsed rail. */
.nav-top-logo-figure[b-m4nfq2b2u0] {
    height: 2.2rem;
    width: auto;
    flex: 0 0 auto;
}

.nav-top-brand-text[b-m4nfq2b2u0] {
    display: flex;
    flex-direction: column;
    align-items: flex-start; /* don't stretch the wordmark img to the column width */
    gap: 0.1rem;
    min-width: 0;
}

/* The "ePegboard" wordmark; shown in the full sidebar only (hidden in the rail). Size by
   WIDTH with height:auto so the aspect ratio is preserved (an explicit height + flex-stretched
   width was squashing the letters). 4rem ≈ 0.95rem tall at the 624x148 source aspect. */
.nav-top-logo-wordmark[b-m4nfq2b2u0] {
    width: 4rem;
    height: auto;
    max-width: 100%;
}

.nav-top-app[b-m4nfq2b2u0] {
    color: #ffffff;
    font-size: 0.95rem;
    font-weight: 700;
    white-space: nowrap;
}

.nav-top-user[b-m4nfq2b2u0] {
    color: rgba(220, 236, 252, 0.95);
    font-size: 0.72rem;
    font-weight: 500;
    white-space: nowrap;
}

.menu-icon[b-m4nfq2b2u0] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 1.15rem;
    color: #7ab6e4;
}

.nav-item[b-m4nfq2b2u0] {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
}

.nav-session[b-m4nfq2b2u0] {
    padding-top: 0.8rem;
    padding-bottom: 0.8rem;
}

.nav-club-switcher[b-m4nfq2b2u0] {
    display: grid;
    gap: 0.25rem;
}

.nav-current-club-caption[b-m4nfq2b2u0] {
    color: #98b9d7;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    line-height: 1;
}

.nav-current-club-label[b-m4nfq2b2u0] {
    color: #cfe0f1;
    font-size: 0.76rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: 0.02em;
    padding: 0.1rem 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-item:first-of-type[b-m4nfq2b2u0] {
    padding-top: 1rem;
}

.nav-item:last-of-type[b-m4nfq2b2u0] {
    padding-bottom: 1rem;
}

.nav-section-label[b-m4nfq2b2u0] {
    color: #98b9d7;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    line-height: 1;
    margin: 0.35rem 0 0.15rem;
}

.nav-live-panel[b-m4nfq2b2u0] {
    display: grid;
    gap: 0.45rem;
    margin: 0 0 0.6rem;
}

.nav-live-card[b-m4nfq2b2u0] {
    border: 1px solid rgba(164, 193, 223, 0.48);
    border-radius: 0.55rem;
    background: rgba(21, 42, 64, 0.42);
    padding: 0.45rem 0.5rem 0.5rem;
}

.nav-live-card-head[b-m4nfq2b2u0] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.nav-live-card-name[b-m4nfq2b2u0] {
    min-width: 0;
    flex: 1 1 auto;
    color: #e6f0fb;
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nav-live-card-meta[b-m4nfq2b2u0] {
    margin-top: 0.2rem;
    color: #bcd2e8;
    font-size: 0.7rem;
    line-height: 1.2;
}

.nav-live-open-link[b-m4nfq2b2u0] {
    margin-top: 0.35rem;
    width: 100%;
    font-size: 0.74rem;
    font-weight: 700;
}

.nav-item[b-m4nfq2b2u0]  .nav-link {
    color: #dce6f2;
    border-radius: 4px;
    height: 3rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    line-height: 3rem;
    border: 1px solid transparent;
    width: 100%;
    background: transparent;
    text-align: left;
    padding: 0 1rem;
}

.nav-item[b-m4nfq2b2u0]  .nav-link.active {
    background: linear-gradient(180deg, #6a88aa 0%, #4c6f95 100%);
    color: #fff;
    border-color: rgba(190, 213, 236, 0.7);
}

.nav-item[b-m4nfq2b2u0]  .nav-link.active .menu-icon {
    color: #fff;
}

.nav-item[b-m4nfq2b2u0]  .nav-link:hover {
    background-color: rgba(255, 255, 255, 0.14);
    color: #fff;
}

.nav-item[b-m4nfq2b2u0]  .nav-link:hover .menu-icon {
    color: #fff;
}

.live-pill[b-m4nfq2b2u0] {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: linear-gradient(180deg, #f45858 0%, #d73c3c 100%);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.32);
    border-radius: 999px;
    padding: 0.1rem 0.46rem;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0.06em;
    flex: 0 0 auto;
    box-shadow: 0 1px 6px rgba(13, 16, 20, 0.3);
}

/* #292/#880: unread-news count badge on the News nav-link. Mirrors .live-pill's shape.
   Recoloured to the same attention-red as .live-pill (#880) so unread news is noticed;
   white text stays legible on it. margin-left:auto pushes it to the right edge of the row.

   SPEC-41 S12 (#721): this class is now GENERIC — it is the one count-pill token in the nav, worn
   by News AND by the Members waiting-count pill. Nothing in it is news-specific; the name is
   historical. It was deliberately NOT renamed: THE NAME ITSELF IS DEPENDED ON in two
   MainLayout.razor.css rules (the collapsed-rail restyle and the label-hiding rule that excludes
   it by name) and is hard-coded across the E2E corpus, so a rename is a coordinated change, not a
   tidy. If you add a third count pill, add this class — do not add a fourth name. */
.nav-news-pill[b-m4nfq2b2u0] {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    background: linear-gradient(180deg, #f45858 0%, #d73c3c 100%);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.32);
    border-radius: 999px;
    padding: 0.05rem 0.4rem;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.2;
    flex: 0 0 auto;
    box-shadow: 0 1px 6px rgba(13, 16, 20, 0.3);
}

.live-clubSession-label[b-m4nfq2b2u0] {
    min-width: 0;
    flex: 1 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.live-dot[b-m4nfq2b2u0] {
    width: 0.42rem;
    height: 0.42rem;
    border-radius: 50%;
    background: #fff;
    animation: live-dot-pulse-b-m4nfq2b2u0 1.3s ease-in-out infinite;
}

@keyframes live-dot-pulse-b-m4nfq2b2u0 {
    0% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.25); opacity: 0.72; }
    100% { transform: scale(1); opacity: 1; }
}

.nav-help-toggle[b-m4nfq2b2u0] {
    justify-content: space-between;
}

/* The rail-only Help link is hidden everywhere by default; the icon-rail media
   block (MainLayout.razor.css) reveals it (and hides the toggle button) only in
   the collapsed rail, where the expandable submenu can't be shown. */
.nav-help-group[b-m4nfq2b2u0]  .nav-help-rail-link {
    display: none;
}

.nav-help-caret[b-m4nfq2b2u0] {
    margin-left: auto;
    color: #b9d3ea;
    font-size: 0.8rem;
}

.nav-help-links[b-m4nfq2b2u0] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-top: 0.25rem;
}

.nav-item[b-m4nfq2b2u0]  .nav-link.nav-link-sub {
    height: 2.3rem;
    line-height: 2.3rem;
    padding-left: 2.6rem;
    color: #cfe0f1;
}

.nav-item[b-m4nfq2b2u0]  .nav-link.nav-link-sub.active {
    background: rgba(96, 132, 168, 0.45);
    border-color: rgba(190, 213, 236, 0.35);
}

/* #276: docked footer - sits outside the scrolling nav and is pinned to the
   sidebar bottom by the sidebar's flex column, so it never scrolls away. */
.nav-user-menu-slot[b-m4nfq2b2u0] {
    flex: 0 0 auto;
    padding: 0.6rem 0.75rem 0.85rem;
    border-top: 1px solid rgba(164, 193, 223, 0.35);
}
/* /Components/Layout/PlayerShellLayout.razor.rz.scp.css */
/* #776 (player-mode shell C): the slim static-SSR player top bar. No new brand —
   navy #0d2c55 (the NavMenu .top-row family), blue #0d6efd active accent, the existing
   logo-wordmark.png. Scoped CSS: these selectors apply ONLY to the top bar declared in
   PlayerShellLayout.razor — the wrapped page body (@Body) keeps its own scope, so nothing
   here leaks into the #684/#769 page bodies. */

.player-topbar[b-fj3s0rt3yj] {
    position: sticky;
    top: 0;
    z-index: 1000;
    background-color: #0d2c55;
    border-bottom: 1px solid rgba(164, 193, 223, 0.55);
    box-shadow: 0 1px 3px rgba(13, 44, 85, 0.25);
}

.player-topbar-inner[b-fj3s0rt3yj] {
    display: flex;
    align-items: center;
    gap: 1rem;
    max-width: 60rem;
    margin: 0 auto;
    padding: 0 1rem;
    min-height: 3.5rem; /* ~56px, per the §5 wireframe */
}

.player-brand[b-fj3s0rt3yj] {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    min-height: 44px; /* touch target */
    text-decoration: none;
}

.player-brand-wordmark[b-fj3s0rt3yj] {
    width: 6rem;
    height: auto;
    max-width: 100%;
    display: block;
}

.player-nav[b-fj3s0rt3yj] {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex: 1 1 auto;
    min-width: 0;
}

.player-nav-link[b-fj3s0rt3yj] {
    display: inline-flex;
    align-items: center;
    min-height: 44px; /* touch target */
    padding: 0 0.75rem;
    color: rgba(220, 236, 252, 0.95);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    border-bottom: 3px solid transparent;
}

.player-nav-link:hover[b-fj3s0rt3yj],
.player-nav-link:focus-visible[b-fj3s0rt3yj] {
    color: #ffffff;
}

.player-nav-link.active[b-fj3s0rt3yj] {
    color: #ffffff;
    border-bottom-color: #0d6efd; /* the blue active accent */
}

.player-topbar-actions[b-fj3s0rt3yj] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 0 0 auto;
    margin-left: auto; /* right-align the chip + sign-out actions */
}

/* #101: the general Help entry in the actions cluster — same light-on-navy treatment as the nav
   links, with the 44px touch target, but no active/border state (it is an external door, never a
   current in-app surface). */
.player-help-link[b-fj3s0rt3yj] {
    display: inline-flex;
    align-items: center;
    min-height: 44px; /* touch target */
    padding: 0 0.5rem;
    color: rgba(220, 236, 252, 0.95);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.player-help-link:hover[b-fj3s0rt3yj],
.player-help-link:focus-visible[b-fj3s0rt3yj] {
    color: #ffffff;
}

/* #1039 (Owner UAT 2026-07-21): the #779 ".player-run-session" accent-button styles were removed
   with the "Run a session" top-bar button (redundant with the Manage door + session door). */

/* #1041 (Owner UAT 2026-07-21b): the context-switcher chip is RETIRED (§2.3 AC-NAV; §8·2 "CHIP
   RETIRED"), so its entire style family was removed — .player-context-switcher / -chip / -chip-label
   / -chip-caret / -panel / -heading / -item(.current) / -check / -divider / -all. The player top bar
   is now the same Me · Clubs · Sign out for every account shape; clubs are switched via the club
   list (/player-clubs), not an app-bar dropdown. The .player-nav-link, topbar and sign-out rules
   below are untouched. */

.player-signout-form[b-fj3s0rt3yj] {
    margin: 0;
}

.player-signout[b-fj3s0rt3yj] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    padding: 0 0.75rem;
    background: transparent;
    border: 1px solid rgba(164, 193, 223, 0.55);
    border-radius: 0.375rem;
    color: rgba(220, 236, 252, 0.95);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.player-signout:hover[b-fj3s0rt3yj],
.player-signout:focus-visible[b-fj3s0rt3yj] {
    color: #ffffff;
    border-color: rgba(220, 236, 252, 0.9);
}

.player-signout-icon[b-fj3s0rt3yj] {
    display: block;
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
}

.player-shell-body[b-fj3s0rt3yj] {
    display: block;
}

/* Narrow phones: the two nav links stay inline (only two — no hamburger needed); the
   sign-out label collapses to the ⏻ icon (accessible name kept via the button's aria-label). */
@media (max-width: 480px) {
    .player-topbar-inner[b-fj3s0rt3yj] {
        gap: 0.5rem;
        padding: 0 0.6rem;
    }

    .player-brand-wordmark[b-fj3s0rt3yj] {
        width: 5rem;
    }

    .player-nav-link[b-fj3s0rt3yj] {
        padding: 0 0.5rem;
        font-size: 0.9rem;
    }

    .player-signout-label[b-fj3s0rt3yj] {
        display: none;
    }

    .player-signout[b-fj3s0rt3yj] {
        padding: 0 0.6rem;
    }
    /* #1041: the .player-context-chip phone cap was removed with the retired chip. */
}

/* #1056 — the email-verification prompt in the PLAYER shell. Until this existed the nag lived only
   in the admin/console shell (MainLayout), so a player-shell-only user was never asked to verify and
   was therefore permanently excluded from their post-session email (#1047).

   Sits directly under the navy top bar as a slim amber strip: visible enough to be acted on, quiet
   enough not to read as an error. Deliberately reuses the shell's existing spacing rhythm rather
   than introducing new brand. */
.player-verify-banner[b-fj3s0rt3yj] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.6rem 1rem;
    background: #fff8e1;
    border-bottom: 1px solid #f0d999;
    color: #5c4813;
    font-size: 0.9rem;
    line-height: 1.35;
}

.player-verify-banner strong[b-fj3s0rt3yj] {
    font-weight: 600;
}

.player-verify-banner a[b-fj3s0rt3yj] {
    color: #0d2c55;
    font-weight: 600;
    text-decoration: underline;
    /* Long addresses must not push the row into a horizontal scroll on a phone. */
    overflow-wrap: anywhere;
}

/* #245: the post-signup "Not junk" reassurance takes its own full-width line below the prompt. */
.player-verify-reassurance[b-fj3s0rt3yj] {
    flex-basis: 100%;
    font-size: 0.82rem;
    line-height: 1.35;
    opacity: 0.9;
}
/* /Components/Layout/QuickFeedbackButton.razor.rz.scp.css */
.quick-feedback-fab[b-kgnei38zq1] {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1900;
    border: 1px solid #1f3f5e;
    background: #1f3f5e;
    color: #fff;
    border-radius: 999px;
    padding: 0.45rem 0.95rem;
    font-size: 0.85rem;
    font-weight: 600;
    opacity: 0.55;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.18);
    transition: opacity 0.15s ease-in-out, transform 0.15s ease-in-out;
    cursor: pointer;
}

.quick-feedback-fab:hover[b-kgnei38zq1],
.quick-feedback-fab:focus-visible[b-kgnei38zq1] {
    opacity: 1;
    transform: translateY(-1px);
}

.quick-feedback-fab.is-busy[b-kgnei38zq1] {
    opacity: 0.85;
    cursor: progress;
}

.quick-feedback-backdrop[b-kgnei38zq1] {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 1950;
}

.quick-feedback-drawer[b-kgnei38zq1] {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    width: min(28rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    z-index: 1960;
    background: #f6f9fc;
    border: 1px solid #c4d1de;
    border-radius: 0.75rem;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
    padding: 1rem 1.1rem 1.1rem;
}

.quick-feedback-title[b-kgnei38zq1] {
    margin: 0 0 0.5rem;
    color: #1f3f5e;
    font-size: 1.05rem;
}

.quick-feedback-help[b-kgnei38zq1] {
    color: #5e748a;
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
}

.quick-feedback-screenshot[b-kgnei38zq1] {
    margin-top: 0.85rem;
    padding: 0.55rem 0.6rem;
    border: 1px solid #c4d1de;
    border-radius: 0.45rem;
    background: #ffffff;
}

.quick-feedback-toggle[b-kgnei38zq1] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
    color: #1f3f5e;
    margin: 0;
}

.quick-feedback-thumb[b-kgnei38zq1] {
    display: block;
    margin-top: 0.5rem;
    max-width: 100%;
    max-height: 9rem;
    border: 1px solid #c4d1de;
    border-radius: 0.3rem;
    object-fit: contain;
    transition: opacity 0.15s ease;
}

/* BL-063: when "Include screenshot" is unchecked, dim (don't hide) the
   thumbnail so the drawer stays the same height. */
.quick-feedback-thumb-dimmed[b-kgnei38zq1] {
    opacity: 0.35;
    filter: grayscale(0.7);
}

.quick-feedback-privacy[b-kgnei38zq1] {
    color: #5e748a;
    font-size: 0.78rem;
    margin: 0.4rem 0 0;
}

.quick-feedback-context[b-kgnei38zq1] {
    margin-top: 0.85rem;
    padding: 0.5rem 0.6rem;
    border: 1px dashed #c4d1de;
    border-radius: 0.45rem;
    background: #fbfdfe;
    color: #5e748a;
    font-size: 0.82rem;
    line-height: 1.45;
}

.quick-feedback-context strong[b-kgnei38zq1] {
    color: #1f3f5e;
    font-weight: 600;
}

.quick-feedback-error[b-kgnei38zq1] {
    margin-top: 0.6rem;
    border: 1px solid #d88f8f;
    background: #f7e3e3;
    color: #8a2d2d;
    border-radius: 0.45rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.85rem;
}

.quick-feedback-actions[b-kgnei38zq1] {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.9rem;
}

/* BL-077: on phones the FAB sat at bottom-right over the picker's Auto-pick
   / Start buttons. Shrink to a compact icon-only pill in the bottom-right
   corner with low opacity so it stops eating the primary action area but
   remains tappable when the user actually wants to send feedback.
   Desktop unchanged. */
@media (max-width: 720px) {
    .quick-feedback-fab[b-kgnei38zq1] {
        bottom: 0.6rem;
        right: 0.6rem;
        padding: 0;
        width: 2.1rem;
        height: 2.1rem;
        font-size: 0;
        border-radius: 50%;
        opacity: 0.45;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Render a small speech-bubble glyph in place of the now-hidden text.
       Keeps the button recognisable as feedback without occupying a wide
       text pill that overlaps the picker controls. */
    .quick-feedback-fab[b-kgnei38zq1]::before {
        content: "\1F4AC"; /* 💬 */
        font-size: 1rem;
        line-height: 1;
    }

    /* While capturing, briefly restore the "..." text so the user gets
       visual confirmation the tap registered. */
    .quick-feedback-fab.is-busy[b-kgnei38zq1] {
        font-size: 0.85rem;
    }
    .quick-feedback-fab.is-busy[b-kgnei38zq1]::before {
        content: "";
    }

    /* Drawer sits well above the corner FAB so the FAB doesn't peek through. */
    .quick-feedback-drawer[b-kgnei38zq1] {
        bottom: 3.5rem;
        right: 0.5rem;
        left: 0.5rem;
        width: auto;
    }
}

/* R2-3: inline (toolbar) variant. The root must not be fixed — let the button sit in the
   session dashboard's action row and stretch to match the other toolbar buttons' height. */
.quick-feedback-root-inline[b-kgnei38zq1] {
    display: inline-flex;
    align-items: stretch;
}

.quick-feedback-toolbar-btn[b-kgnei38zq1] {
    white-space: nowrap;
    font-weight: 600;
}

/* Icon-only inline button (rarely-used feedback → icon to save toolbar space). */
.quick-feedback-toolbar-btn .bi[b-kgnei38zq1] {
    font-size: 1.05rem;
    vertical-align: -0.15em;
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-u69v80gs08],
.components-reconnect-repeated-attempt-visible[b-u69v80gs08],
.components-reconnect-failed-visible[b-u69v80gs08],
.components-pause-visible[b-u69v80gs08],
.components-resume-failed-visible[b-u69v80gs08],
.components-rejoining-animation[b-u69v80gs08] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-retrying[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-failed[b-u69v80gs08],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-u69v80gs08] {
    display: block;
}


#components-reconnect-modal[b-u69v80gs08] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-u69v80gs08 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-u69v80gs08 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-u69v80gs08 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-u69v80gs08]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-u69v80gs08 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-u69v80gs08 {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-u69v80gs08 {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-u69v80gs08 {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-u69v80gs08] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-u69v80gs08] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-u69v80gs08] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-u69v80gs08] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-u69v80gs08] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-u69v80gs08] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-u69v80gs08] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-u69v80gs08 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-u69v80gs08] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-u69v80gs08 {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/UserMenu.razor.rz.scp.css */
.user-menu[b-pi7t5mbq6b] {
    position: relative;
}

/* Invisible full-screen catcher so a click anywhere outside closes the menu. */
.user-menu-backdrop[b-pi7t5mbq6b] {
    position: fixed;
    inset: 0;
    z-index: 1190;
    background: transparent;
}

.user-menu-trigger[b-pi7t5mbq6b] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 9rem;
    font-weight: 600;
    text-align: left;
}

/* #300/#395: initials avatar standing in for a profile photo (users have no stored
   photo), sized + coloured to match the league-tool mockup's ".who" dot. */
.user-menu-avatar[b-pi7t5mbq6b] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: #2b6cb0;
    color: #ffffff;
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1;
}

.user-menu-trigger-label[b-pi7t5mbq6b] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* #395: two-line identity (name over a muted active-club subtitle), mockup ".who" look. */
.user-menu-trigger-text[b-pi7t5mbq6b] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.05rem;
    min-width: 0;
    line-height: 1.15;
}

.user-menu-trigger-name[b-pi7t5mbq6b] {
    font-weight: 700;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.user-menu-trigger-sub[b-pi7t5mbq6b] {
    font-size: 0.68rem;
    font-weight: 500;
    color: #5e748a;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}

.user-menu-panel[b-pi7t5mbq6b] {
    position: absolute;
    right: 0;
    top: calc(100% + 0.35rem);
    z-index: 1200;
    width: min(19rem, 92vw);
    border: 1px solid #b8c9da;
    border-radius: 0.55rem;
    background: #f6f9fd;
    box-shadow: 0 10px 24px rgba(20, 41, 62, 0.22);
    padding: 0.45rem;
    display: grid;
    gap: 0.25rem;
    /* #334/#395: cap to the viewport as a last resort, but the club list (.user-menu-clubs)
       is the real scroll region so the identity header + account/logout always stay visible. */
    max-height: 88vh;
    max-height: 88dvh;
    overflow-y: auto;
}

/* #395: only the club switcher scrolls — header and actions stay put however many
   clubs the user can access (superusers have many). */
.user-menu-clubs[b-pi7t5mbq6b] {
    display: grid;
    gap: 0.25rem;
    max-height: 40vh;
    max-height: 40dvh;
    overflow-y: auto;
}

/* Sidebar-bottom placement: a full-width trigger that fits the dark sidebar,
   with the panel opening upward and pinned within the sidebar width so the
   scroll container doesn't clip it. */
.user-menu-dropup .user-menu-trigger[b-pi7t5mbq6b] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
    min-width: 0;
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(164, 193, 223, 0.45);
    color: #eaf2fb;
}

.user-menu-dropup .user-menu-trigger:hover[b-pi7t5mbq6b],
.user-menu-dropup .user-menu-trigger:focus-visible[b-pi7t5mbq6b] {
    background: rgba(255, 255, 255, 0.16);
    border-color: rgba(164, 193, 223, 0.7);
    color: #ffffff;
}

/* #395: on the dark sidebar the subtitle uses the mockup's muted-blue ".who" tone. */
.user-menu-dropup .user-menu-trigger-sub[b-pi7t5mbq6b] {
    color: #9fb6da;
}

.user-menu-dropup .user-menu-panel[b-pi7t5mbq6b] {
    top: auto;
    bottom: calc(100% + 0.35rem);
    left: 0;
    right: 0;
    width: auto;
}

.user-menu-header[b-pi7t5mbq6b] {
    padding: 0.25rem 0.3rem 0.35rem;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.user-menu-display-name[b-pi7t5mbq6b] {
    color: #1d3856;
    font-size: 0.92rem;
    font-weight: 700;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-menu-email[b-pi7t5mbq6b] {
    color: #5e748a;
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-menu-group-title[b-pi7t5mbq6b] {
    color: #4e6f8e;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.1rem 0.2rem;
}

/* #835 (S2): the switcher groups My nights / Platform admin / the club list into one block
   above the divider, so it reuses the same gap rhythm as the panel body. */
.user-menu-switcher[b-pi7t5mbq6b] {
    display: grid;
    gap: 0.25rem;
}

.user-menu-item[b-pi7t5mbq6b] {
    width: 100%;
    border: 1px solid transparent;
    border-radius: 0.4rem;
    background: transparent;
    color: #234765;
    text-align: left;
    padding: 0.4rem 0.5rem;
    font-size: 0.84rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
}

/* #835 (S2): the new destination rows (My nights, Platform admin) are anchors, not buttons, so
   they can be plain links to the static-SSR shells. Neutralise the default anchor look so they
   lay out identically to the button items above/below them. */
a.user-menu-item[b-pi7t5mbq6b] {
    display: block;
    text-decoration: none;
    box-sizing: border-box;
}

.user-menu-item:hover:not(:disabled)[b-pi7t5mbq6b] {
    background: #e7f0fa;
    border-color: #b4c9de;
}

.user-menu-item:disabled[b-pi7t5mbq6b],
.user-menu-item.current[b-pi7t5mbq6b] {
    color: #5f7f9c;
    background: #e8f0f8;
    border-color: #cad9e8;
}

.user-menu-item.danger[b-pi7t5mbq6b] {
    color: #8b2331;
}

.user-menu-check[b-pi7t5mbq6b] {
    display: inline-block;
    width: 1rem;
    color: #2f6fa6;
    font-weight: 800;
}

.user-menu-divider[b-pi7t5mbq6b] {
    height: 1px;
    background: #cfdae6;
    margin: 0.2rem 0;
}

/* Logout is a form-POST so the auth cookie clears on the server; the form must
   not introduce its own box so the button lays out like the other items. */
.user-menu-logout-form[b-pi7t5mbq6b] {
    display: contents;
}
/* /Components/Pages/Account.razor.rz.scp.css */
/* #220 (Owner UAT 2026-08-09): the self-service /account page, reskinned to the player portal. Same
   centred card column + visual tokens as /me, /player-clubs and the /my-club/{slug} detail page (one
   shared player language, NO new brand: navy #16324f, blue #1b6ec2 / #006bb7, off-white cards, border
   #e2e8f0). Scoped per component (the PegboardWeb per-page .razor.css pattern), so every .my-* token
   used is redefined here — matching PlayerClubs.razor.css / MyNights.razor.css exactly. */

.my-shell[b-r878q4r1e7] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title — the shared navigational component). ── */
.my-backbar[b-r878q4r1e7] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-r878q4r1e7] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-r878q4r1e7],
.my-back:focus-visible[b-r878q4r1e7] {
    text-decoration: underline;
}

.my-back-caret[b-r878q4r1e7] {
    font-weight: 700;
}

.my-backbar-title[b-r878q4r1e7] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
}

/* ── Cards. ── */
.my-card[b-r878q4r1e7] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1.25rem;
}

.my-card-title[b-r878q4r1e7] {
    font-size: 1rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.85rem;
}

/* ── #515 profile photo (player self-service upload). ───────────────────────────────────────
   Blazor per-component CSS isolation: Members.razor.css is scoped to the ADMIN page, so its
   .member-photo-editor-* values are RE-EXPRESSED here as .acct-photo-* rather than imported.
   Phone-first: the avatar stacks above its controls; from 30rem the avatar sits left of them
   (the wide layout in the UX plan's second wireframe). */
.acct-photo[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.9rem;
    margin: 0 0 1.1rem;
}

.acct-photo-avatar[b-r878q4r1e7],
.acct-photo-img[b-r878q4r1e7],
.acct-photo-initials[b-r878q4r1e7] {
    width: 5.6rem;
    height: 5.6rem;
    border-radius: 50%;
    flex: 0 0 auto;
    box-sizing: border-box;
}

.acct-photo-img[b-r878q4r1e7] {
    display: block;
    object-fit: cover;
    border: 2px solid #e2e8f0;
    background: #fff;
}

/* The PORTAL's initials idiom (/me's .me-profile-avatar — navy fill, white letters), not the
   admin's gendered fallback. Never a blank box, never a grey silhouette. */
.acct-photo-initials[b-r878q4r1e7] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #0d2c55;
    color: #fff;
    font-weight: 700;
    font-size: 1.9rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.acct-photo-body[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
    width: 100%;
}

.acct-photo-label[b-r878q4r1e7] {
    margin: 0;
    font-weight: 700;
    font-size: 0.9rem;
    color: #16324f;
}

.acct-photo-lead[b-r878q4r1e7] {
    margin: 0;
}

.acct-photo-clubs[b-r878q4r1e7] {
    margin: 0;
    padding-top: 0.5rem;
    border-top: 1px solid #eef2f7;
}

.acct-photo-form[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0.35rem 0 0;
}

.acct-photo-input[b-r878q4r1e7] {
    width: 100%;
    min-height: 48px; /* touch floor — the file input is the first thing a phone user taps */
    padding: 0.6rem 0.75rem;
    border: 1px solid #cdd9e5;
    border-radius: 0.55rem;
    font-size: 1rem;
    color: #1f2d3d;
    background: #fff;
    box-sizing: border-box;
}

.acct-photo-input:focus-visible[b-r878q4r1e7] {
    outline: none;
    border-color: #1b6ec2;
    box-shadow: 0 0 0 3px rgba(27, 110, 194, 0.18);
}

/* Primary action: full-width on phone, ≥48px (the file input and this button are the two things a
   distracted phone user taps, so they clear the 44px floor the rest of the page uses).
   NOTE the doubled selector: .my-btn is defined LATER in this file with min-height:44px, and at
   equal specificity source order wins — a bare .acct-photo-submit resolved to 44px in the browser
   while looking correct in the source. Caught by the computed-style smoke; do not "simplify" it
   back to a single class. */
.my-btn.acct-photo-submit[b-r878q4r1e7] {
    min-height: 48px;
    width: 100%;
}

/* Remove is SEPARATED from Save, not adjacent — a mis-tap on a phone must not destroy what the
   previous tap created. Spacing does the work; no rule, no dialog. */
.acct-photo-remove[b-r878q4r1e7] {
    margin: 0.9rem 0 0;
    display: flex;
    justify-content: center;
}

.acct-photo-findlink[b-r878q4r1e7] {
    align-self: flex-start;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    color: #006bb7;
    font-weight: 600;
    font-size: 0.95rem;
    text-decoration: none;
}

.acct-photo-findlink:hover[b-r878q4r1e7],
.acct-photo-findlink:focus-visible[b-r878q4r1e7] {
    text-decoration: underline;
}

/* Separate the photo block from the read-only Name/Email facts below it. */
.acct-facts-below-photo[b-r878q4r1e7] {
    padding-top: 1rem;
    border-top: 1px solid #eef2f7;
}

@media (min-width: 30rem) {
    .acct-photo[b-r878q4r1e7] {
        flex-direction: row;
        align-items: flex-start;
        gap: 1.1rem;
    }

    .my-btn.acct-photo-submit[b-r878q4r1e7] {
        width: auto;
        align-self: flex-start;
        min-width: 10rem;
    }

    .acct-photo-remove[b-r878q4r1e7] {
        justify-content: flex-start;
    }
}

/* ── Read-only identity facts (label / value rows). ── */
.acct-facts[b-r878q4r1e7] {
    margin: 0;
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.4rem 1rem;
    align-items: baseline;
}

.acct-facts-label[b-r878q4r1e7] {
    color: #5e748a;
    font-size: 0.85rem;
    font-weight: 600;
    margin: 0;
}

.acct-facts-value[b-r878q4r1e7] {
    color: #16324f;
    font-weight: 600;
    margin: 0;
    overflow-wrap: break-word;
    min-width: 0;
}

/* ── Change-password form. ── */
.acct-lead[b-r878q4r1e7] {
    color: #5e748a;
    font-size: 0.9rem;
    margin: 0 0 1rem;
}

.acct-form[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.acct-field[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.acct-label[b-r878q4r1e7] {
    font-weight: 700;
    font-size: 0.9rem;
    color: #16324f;
}

.acct-input[b-r878q4r1e7] {
    width: 100%;
    min-height: 44px; /* touch target */
    padding: 0.55rem 0.75rem;
    border: 1px solid #cdd9e5;
    border-radius: 0.55rem;
    font-size: 1rem;
    color: #1f2d3d;
    background: #fff;
    box-sizing: border-box;
}

.acct-input:focus-visible[b-r878q4r1e7] {
    outline: none;
    border-color: #1b6ec2;
    box-shadow: 0 0 0 3px rgba(27, 110, 194, 0.18);
}

.acct-hint[b-r878q4r1e7] {
    margin: 0;
    font-size: 0.82rem;
    color: #5e748a;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-r878q4r1e7] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-r878q4r1e7] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-r878q4r1e7],
.my-btn-primary:focus-visible[b-r878q4r1e7] {
    background: #155ba3;
}

/* Secondary button — the "Turn off" action when the setting is currently on (a lower-emphasis,
   reversible action; not destructive). Outlined, on the shared player tokens. */
.my-btn-secondary[b-r878q4r1e7] {
    background: #fff;
    color: #1b6ec2;
    border-color: #cdd9e5;
}

.my-btn-secondary:hover[b-r878q4r1e7],
.my-btn-secondary:focus-visible[b-r878q4r1e7] {
    background: #f2f7fc;
    border-color: #1b6ec2;
}

/* ── #139 notifications toggle row: copy on the left, flip button on the right. ── */
.acct-toggle-row[b-r878q4r1e7] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

.acct-toggle-copy[b-r878q4r1e7] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.acct-toggle-name[b-r878q4r1e7] {
    font-weight: 700;
    font-size: 0.95rem;
    color: #16324f;
}

.acct-toggle-state[b-r878q4r1e7] {
    font-size: 0.85rem;
    font-weight: 600;
}

.acct-toggle-state-on[b-r878q4r1e7] {
    color: #226b39;
}

.acct-toggle-state-off[b-r878q4r1e7] {
    color: #5e748a;
}

.acct-toggle-form[b-r878q4r1e7] {
    margin: 0;
    flex-shrink: 0;
}

/* #139/#140 per-club rows carry two actions (flip + "reset to global"); keep them together on the
   right, stacking to the flip button's right and wrapping under it on a narrow row. */
.acct-toggle-actions[b-r878q4r1e7] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-shrink: 0;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* "Reset to global" — a low-emphasis text action (re-inherit the global default), not a button-weight
   control. Underlined link affordance on the shared player tokens; still a 44px touch target. */
.my-btn-link[b-r878q4r1e7] {
    background: transparent;
    color: #1b6ec2;
    border-color: transparent;
    text-decoration: underline;
    padding: 0.5rem 0.5rem;
    font-weight: 600;
}

.my-btn-link:hover[b-r878q4r1e7],
.my-btn-link:focus-visible[b-r878q4r1e7] {
    color: #155ba3;
    background: #f2f7fc;
}

/* #140 per-club override rows: indented + separated under the global default toggle. */
.acct-toggle-row-sub[b-r878q4r1e7] {
    margin-top: 0.85rem;
    padding-top: 0.85rem;
    border-top: 1px solid #eef2f7;
}

/* Align the submit button to the start of the column (not stretched full-width). */
.acct-form .my-btn[b-r878q4r1e7] {
    align-self: flex-start;
}

/* ── Outcome banner (change-password result, read off ?pw=). Mirrors the .clubs-banner tokens. ── */
.acct-banner[b-r878q4r1e7] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    margin: 0 0 1rem;
}

.acct-banner-ok[b-r878q4r1e7] {
    background: #eaf5ec;
    border: 1px solid #bfe0c7;
    color: #226b39;
}

.acct-banner-error[b-r878q4r1e7] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* #606: the photo is a tap target that opens the lightbox (js/photoLightbox.js). The anchor wraps
   the <img> inside the fixed 5.6rem .acct-photo-avatar box, so it must add no line-height gap and
   no link decoration. The lightbox itself is global — see wwwroot/css/profile.css. */
.acct-photo-link[b-r878q4r1e7] {
    display: block;
    line-height: 0;
    border-radius: 50%;
    text-decoration: none;
    cursor: zoom-in;
}

/* Ring on the LINK, so it traces the circle rather than a square around it. */
.acct-photo-link:focus-visible[b-r878q4r1e7] {
    outline: 3px solid #2f6f9c;
    outline-offset: 2px;
}
/* /Components/Pages/ActiveSessions.razor.rz.scp.css */
/* #380: on phones the 10-column Active Sessions table forced a horizontal scroll
   to reach the "Open" action on the right. Below the mobile breakpoint we stack
   each row into a card: every cell goes full-width with its column name as a
   label, and "Open" sits at the bottom of the card as a full-width button - so
   it's always reachable without any sideways scrolling.

   Scoped to this component (ActiveSessions), so the shared clubs-table styling on
   other pages is untouched. */
@media (max-width: 599.98px) {
    /* Defeat the .table-responsive horizontal scroller - we no longer overflow. */
    .table-responsive[b-mom3g8vn4y] {
        overflow-x: visible;
    }

    .clubs-table thead[b-mom3g8vn4y] {
        display: none;
    }

    .clubs-table[b-mom3g8vn4y],
    .clubs-table tbody[b-mom3g8vn4y],
    .clubs-table tr[b-mom3g8vn4y],
    .clubs-table td[b-mom3g8vn4y] {
        display: block;
        width: 100%;
    }

    .clubs-table tr[b-mom3g8vn4y] {
        border: 1px solid #cdd8e6;
        border-radius: 0.6rem;
        background: #fff;
        padding: 0.35rem 0.6rem 0.6rem;
        margin-bottom: 0.7rem;
    }

    .clubs-table td[b-mom3g8vn4y] {
        border: none;
        padding: 0.2rem 0;
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        text-align: right;
    }

    /* Column name on the left of each stacked cell. */
    .clubs-table td[b-mom3g8vn4y]::before {
        content: attr(data-label);
        font-weight: 600;
        color: #557693;
        text-align: left;
        flex: 0 0 auto;
    }

    /* text-end numeric cells don't need their own right-align now the row is a flex line. */
    .clubs-table td.text-end[b-mom3g8vn4y] {
        text-align: right;
    }

    /* The Open action: full-width, prominent, last in the card - no scrolling. */
    .clubs-table td:last-child[b-mom3g8vn4y] {
        display: block;
        margin-top: 0.5rem;
        padding-top: 0.5rem;
        border-top: 1px solid #e6edf5;
        text-align: center;
    }

    .clubs-table td:last-child[b-mom3g8vn4y]::before {
        content: none;
    }

    .clubs-table td:last-child .btn[b-mom3g8vn4y] {
        display: block;
        width: 100%;
    }
}
/* /Components/Pages/ActivityNext.razor.rz.scp.css */
/* SPEC-20 §10 page chrome. Tokens come from app.css's :root (R10.7); no literal colour here. */

/* THE PAGE MEASURE — §10.17 row 15, and the one of the five nobody could see. The markup wore
   `clubs-shell`, which LOOKS like it provides one: it is `Clubs.razor`'s class, and Blazor scoped CSS
   rewrites that rule to `.clubs-shell[b-s4llzf7qxg]`, so on this page it matched nothing and the
   surface had no measure at all. Measured 1119px at 1440 — which is why it never looked wrong there,
   because the 250px sidebar happens to constrain the column to roughly the intended width — and
   1599px at 1920, where four summary cells and a 90-point chart stretch to no purpose. The class has
   been dropped from the markup with this rule: a dead class that looks load-bearing is what hid this
   for two increments.

   max-width IS A CEILING, NOT A WIDTH, which is the answer to the double-constrain worry: it can only
   ever narrow a track already WIDER than 1080px, so every width where the sidebar is the binding
   constraint (measured: everything up to ~1400) is untouched. 1080px is the mockup's own value. */
.activity-next[b-non1vhr64q] {
    max-width: 1080px;
    margin-inline: auto;
}

.activity-next .page-head[b-non1vhr64q] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.activity-next .preview-tag[b-non1vhr64q] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border: 1px solid var(--activity-line);
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    color: var(--activity-muted);
}

.activity-next .page-sub[b-non1vhr64q] {
    font-size: 0.82rem;
    color: var(--activity-muted);
    max-width: 78ch;
}

/* STICKY, because the controls are useless where they cannot be reached: the rail sets what every
   panel below it is showing, and by the third panel it had scrolled off the top (Owner, 2026-09-15).
   The mockup ruled this at line 103 and the build simply did not carry the declaration over.

   THE CARD SURVIVES, NOT THE MOCKUP'S FULL-BLEED BAR. The mockup's rail is a transparent strip on the
   page ground with a single bottom rule; this build re-treated the whole surface as cards (rail,
   summary strip, four panels), and that treatment is what has been reviewed and signed off. Swapping
   the rail back to a bare bar now would leave one flat element in a stack of five cards — a bigger
   divergence from the shipped surface than the one it closes.

   A CARD THAT STICKS NEEDS THREE THINGS A CARD AT REST DOES NOT, and this rule adds exactly those:
     - an OPAQUE background, so the panels do not read through it. `--activity-card` already is.
     - a Z-INDEX, and not merely for tidiness. Without one this sticky element and the panels'
       `position: absolute` loading/failed overlays are both `z-index: auto`, so they paint in DOM
       order and every overlay — which is present in EVERY state, not only while failing (AC 9) —
       would paint OVER the rail. 30 matches the mockup and sits far below the nav overlay (1700),
       the feedback FAB (1900) and the error bar.
     - SEPARATION, so it reads as in front of the content rather than merged into it. One token, and
       the only shadow on the surface — see --activity-shadow in app.css for why it is the one.

   top: 0 IS CORRECT HERE, checked rather than assumed: on this route the layout's top bar is in
   normal flow (it is `position: fixed` only under `body.kiosk-mode .page--kiosk-session`, which this
   is not), the persistent sidebar is a sticky SIBLING column rather than an ancestor, and every
   ancestor from `.rail` to `<html>` is `overflow: visible` with no transform, filter or containment —
   so nothing overlaps the viewport top and nothing silently disables the stickiness. */
.activity-next .rail[b-non1vhr64q] {
    position: sticky;
    top: 0;
    z-index: 30;
    border: 1px solid var(--activity-line);
    border-radius: 12px;
    background: var(--activity-card);
    box-shadow: var(--activity-shadow);
    padding: 0.6rem 0.9rem;
    margin-bottom: 1.1rem;
}

.activity-next .rail-inner[b-non1vhr64q] {
    display: flex;
    align-items: flex-end;
    gap: 1.2rem;
    flex-wrap: wrap;
}

.activity-next .ctl[b-non1vhr64q] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.72rem;
    color: var(--activity-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.activity-next .seg[b-non1vhr64q] {
    display: inline-flex;
    border: 1px solid var(--activity-line);
    border-radius: 7px;
    overflow: hidden;
}

/* Mockup line 120. Found by the §10.17 sweep: without it the three Window options run together as
   one word-blob, because the only thing separating them is the pressed state's fill — and on this
   surface that fill is `--activity-card-2` on `--activity-card`, a difference of about 2%. The
   divider is what makes an unpressed option look like its own button. */
.activity-next .seg button + button[b-non1vhr64q] {
    border-left: 1px solid var(--activity-line-2);
}

.activity-next .seg button[b-non1vhr64q] {
    border: 0;
    background: transparent;
    color: var(--activity-muted);
    font-size: 0.78rem;
    padding: 0.3rem 0.7rem;
    cursor: pointer;
    white-space: nowrap;
}

/* §10.17 row 8. This was `--activity-card-2` on `--activity-card` — a 2% difference, so the SELECTED
   option looked the same as the two beside it and only the bold weight said otherwise. The mockup
   fills it (line 121) and now so does this. White on `--activity-primary` measures 5.23:1, past
   1.4.3's 4.5:1 for these 0.78rem labels. */
.activity-next .seg button[aria-pressed="true"][b-non1vhr64q] {
    background: var(--activity-primary);
    color: var(--activity-on-primary);
    font-weight: 600;
}

/* The Window control keeps its pressed state while disabled (weekly bucketing), so this now fades a
   FILLED button rather than a tinted one. That is the mockup's behaviour too (line 122) and it reads
   correctly: the choice is still visible, and visibly not in effect. Disabled controls are outside
   1.4.3, so the faded fill owes no ratio. */
.activity-next .seg button:disabled[b-non1vhr64q] {
    opacity: 0.45;
    cursor: not-allowed;
}

/* §10.17 row 12 — the focus ring, which this surface had none of: these are bare <button>s, not
   `.btn`, so they fell through to the user agent's own ring.

   AN INSET SHADOW RATHER THAN THE MOCKUP'S `outline` (line 123), and for a mechanical reason: `.seg`
   is `overflow: hidden` to clip the segment corners, and an outline is painted OUTSIDE the border box
   where that clip removes it. An inset ring is painted inside and survives. Keyed on :focus-visible
   rather than the mockup's `:focus-within`, so it answers the keyboard and not the mouse. */
.activity-next .seg button:focus-visible[b-non1vhr64q] {
    outline: none;
    box-shadow: inset 0 0 0 2px var(--activity-primary);
}

/* Not inside `.seg`, so it takes the mockup's real outline (line 235). */
.activity-next .check input:focus-visible[b-non1vhr64q] {
    outline: 2px solid var(--activity-primary);
    outline-offset: 2px;
}

/* The compare toggle. A checkbox rather than a fourth segmented control because it is not a choice
   between alternatives — it is an overlay laid on top of whatever the other three are set to. */
.activity-next .check[b-non1vhr64q] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--activity-ink);
    cursor: pointer;
    padding-bottom: 0.3rem;
}

/* §10.17 row 13, mockup line 126: without accent-color the one control in the rail that is not a
   segment ticks in the browser's default blue — a colour the product does not own, sitting beside
   three controls that now fill in `--activity-primary`. */
.activity-next .check input[b-non1vhr64q] {
    margin: 0;
    cursor: pointer;
    accent-color: var(--activity-primary);
}

/* Sits inside the uppercase control label, so it is already tracked and muted by `.ctl`. Normal
   case, because it is a sentence fragment rather than a label. */
.activity-next .ctl-note[b-non1vhr64q] {
    text-transform: none;
    letter-spacing: 0;
    font-style: italic;
}

/* ══ THE SECTION SHELL, MOVED HERE AT I3 — one home, shared by two kinds of section ═══════════
   These rules were in ActivityMetricPanel.razor.css, where they were reachable by exactly one
   component. I3 adds a SECOND section that wears the same shell — the weekday heatmap, which is not
   a metric (see ActivityWeekdayHeatmap.razor for why) but is unmistakably the same card, head,
   swatch, definition affordance and legend row.

   BLAZOR SCOPED CSS IS PER-COMPONENT, so a rule in ActivityMetricPanel.razor.css becomes
   `.activity-panel[b-panelid]` and cannot reach another component's markup however identical the
   class name. The two available answers were to duplicate the shell into a second scoped file — the
   drift that §10.17's whole register is about — or to host it once, above both, and reach down.
   `::deep` is that mechanism and it is already used in five stylesheets in this repo.

   AC 2 IS UNAFFECTED BY CONSTRUCTION, not by reasoning about which pages load which file. Every rule
   below is a descendant of `.activity-next[b-pageid]`: the scope attribute is on this page's own
   wrapper, so no selector here can match an element on /admin/activity even though the bundle is one
   file served to every page. That is the property to preserve if more of this moves later.

   Only the SHELL moved. The metric panel's own internals — stat tiles, table, overlays, the viz
   region — stay in their component's stylesheet, because nothing else wears them. */

.activity-next[b-non1vhr64q]  .activity-panel {
    border: 1px solid var(--activity-line);
    border-radius: 12px;
    background: var(--activity-card);
    padding: 0.9rem 1rem 0.75rem;
    margin-bottom: 1.1rem;
}

.activity-next[b-non1vhr64q]  .panel-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* --activity-ink-2, the restored heading ink (§10.17 row 10, mockup line 155). 8.62:1 -> 11.84:1 on
   the card. Weight 600, not the mockup's 650: this is the same 1rem title at the same scale, and 650
   is a variable-font weight the app's stack (Helvetica Neue / Arial) rounds to 700 anyway. */
.activity-next[b-non1vhr64q]  .panel-title {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--activity-ink-2);
    margin: 0;
}

/* PREFIXED `.activity-panel`, for the reason the stat-tile block 150 lines down states and this rule
   originally failed to apply to itself. `.swatch` also exists in the summary strip, which has its own
   scoped rule for it; unprefixed, `.activity-next[b-page] .swatch` is (0,3,0) against the strip's
   `.swatch[b-strip]` at (0,2,0) and silently restyles it. The heatmap section carries
   `class="activity-panel heat-panel"`, so it keeps the rule.

   Checked once across the whole hoisted shell rather than fixed in one place: `.swatch` and `.delta`
   are the ONLY two class names the strip and the panels share, and `ActivityChartHost` shares none. */
.activity-next[b-non1vhr64q]  .activity-panel .swatch {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 3px;
    display: inline-block;
}

.activity-next[b-non1vhr64q]  .spacer {
    flex: 1 1 auto;
}

.activity-next[b-non1vhr64q]  .info-btn {
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    border: 1px solid var(--activity-line);
    background: transparent;
    color: var(--activity-muted);
    font-size: 0.72rem;
    line-height: 1;
    cursor: pointer;
}

/* §10.17 row 11, mockup line 162. The button is a TOGGLE and had no toggled state: the only feedback
   that it had done anything was the body appearing, which on a long panel is below where the eye is
   when the click happens. A filled `i` says so where the control is. */
.activity-next[b-non1vhr64q]  .info-btn[aria-expanded="true"] {
    background: var(--activity-primary);
    border-color: var(--activity-primary);
    color: var(--activity-on-primary);
}

.activity-next[b-non1vhr64q]  .info-btn:focus-visible {
    outline: 2px solid var(--activity-primary);
    outline-offset: 2px;
}

/* §10.17 row 7 — the callout treatment (mockup lines 165-169). Ground, accent rule and indent are
   what say "this is the answer to the button you pressed"; without them the definition was
   indistinguishable from the two muted captions above and below it. 74ch is the mockup's measure. */
.activity-next[b-non1vhr64q]  .info-body {
    font-size: 0.8rem;
    line-height: 1.55;
    color: var(--activity-muted);
    background: var(--activity-card-2);
    border-left: 2px solid var(--activity-primary);
    border-radius: 0 6px 6px 0;
    padding: 0.55rem 0.8rem;
    margin: 0.6rem 0 0;
    max-width: 74ch;
}

/* --activity-muted, matching the mockup's own `.viz-foot` (mockup line 190), NOT a fainter token.
   This row carries the sentences the PM ruled must be stated — "Trailing 7-day total — complete from
   23 Jun" — which is the whole reason the left-edge departure from the mockup was allowed. */
.activity-next[b-non1vhr64q]  .viz-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: 0.55rem;
    font-size: 0.72rem;
    color: var(--activity-muted);
}

.activity-next[b-non1vhr64q]  .key {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

/* ── §10.17 row 9 — the legend marks ──────────────────────────────────────────────────────────
   The register listed this row as needing "markup and a per-key mark type", and both now exist:
   ActivityLegendKey carries the type, the panel renders an `<i>` for it, and these four rules draw
   what the chart draws. Before this the legend was four text keys for four visually distinct things,
   and `.key` matched no rule anywhere on the surface.

   THE SERIES COLOUR ARRIVES THROUGH ONE CUSTOM PROPERTY — `--key-colour`, set once on `.viz-foot` in
   the markup — so no key carries an inline colour and R10.7 is untouched: the only thing the inline
   style names is a token. */
.activity-next[b-non1vhr64q]  .mark {
    display: inline-block;
    flex: none;
}

.activity-next[b-non1vhr64q]  .mark-bar {
    width: 0.55rem;
    height: 0.7rem;
    border-radius: 1px;
    background: var(--key-colour);
}

.activity-next[b-non1vhr64q]  .mark-line {
    width: 0.9rem;
    height: 0;
    border-top: 2px solid var(--key-colour);
}

/* The overlay is dashed on the chart, so its key is dashed here — at the same 4/3 rhythm the
   dataset's own borderDash uses, scaled to a 14px rule. */
.activity-next[b-non1vhr64q]  .mark-dash {
    width: 0.9rem;
    height: 0;
    border-top: 2px dashed var(--key-colour);
    opacity: 0.6;
}

/* The partial bucket's 45° hatch, drawn the same way the canvas draws it — a repeating gradient
   rather than an image, in the hatch token. */
.activity-next[b-non1vhr64q]  .mark-hatch {
    width: 0.55rem;
    height: 0.7rem;
    border: 1px solid var(--activity-hatch);
    border-radius: 1px;
    background: repeating-linear-gradient(
        45deg,
        var(--activity-hatch) 0 1px,
        transparent 1px 4px);
}

/* A heatmap cell, at whatever intensity the key entry carries — and drawn with the same box the grid
   now uses, so the key and the grid are the same object at two sizes. */
.activity-next[b-non1vhr64q]  .mark-cell {
    width: 0.8rem;
    height: 0.7rem;
    border: 1px solid var(--activity-rule);
    border-radius: 2px;
}

/* A stated fact rather than a drawn series — the funnel-epoch caveat, the heatmap's outline note —
   takes no mark at all: a swatch in front of it would advertise a fifth thing to look for on the
   chart. The element is still rendered so the markup does not branch. */
.activity-next[b-non1vhr64q]  .mark-note {
    display: none;
}

/* ══ THE STAT TILES, ALSO MOVED HERE AT I3 — and for a sharper reason than the shell above ════

   THE CROSSHAIR'S READOUT IS WRITTEN BY JAVASCRIPT, AND BLAZOR SCOPED CSS CANNOT REACH IT. A rule
   written `.stat { … }` in ActivityMetricPanel.razor.css is rewritten to `.stat[b-panelid]`, and the
   scope attribute is stamped by the COMPILER onto elements in the .razor file. Elements created at
   runtime through `innerHTML` carry no such attribute, so every tile rule missed the hover row
   entirely: it rendered as unstyled text on the grid's ground.

   FOUND BY LOOKING AT A SCREENSHOT. No assertion in any tier would have caught it — the markup was
   correct, the payload was correct, the E2E's text assertions passed on an element that was visible
   and readable and simply not styled. It is the same shape as the `:root`-in-a-.razor.css lesson
   this repo has now recorded three times, arriving from a new direction: SCOPED CSS DOES NOT REACH
   DOM THAT BLAZOR DID NOT RENDER.

   `::deep` is the fix and it is the mechanism's own answer: it strips the scope attribute from
   everything after it, so these rules match the server-rendered tiles and the JS-written ones alike
   — one home for both, rather than a second copy of the tile typography for the hover row to use.

   PREFIXED `.activity-panel` DELIBERATELY. `.delta` also exists in the summary strip, which has its
   own scoped rule for it; an unprefixed `::deep .delta` here would be more specific than that rule
   and would silently restyle the strip. The prefix keeps this to the panels. */

.activity-next[b-non1vhr64q]  .activity-panel .stats-wrap {
    position: relative;
    /* THE MARGIN LIVES ON THE WRAPPER, NOT ON `.stats`. With it on the grid, the absolutely
       positioned overlay's `inset: 0` resolved against the wrapper's padding box — which includes
       those margins — so the readout sat ~11px high and ~12px tall of its target and the tiles
       underneath bled through at the bottom edge. */
    margin: 0.7rem 0 0.75rem;
}

/* THREE TILES IN EVERY STATE. Loading and Failed render the same tiles with "—" in place of a
   number, so a state change moves nothing on the page — which is the visible half of AC 9.

   §10.17 row 6: they were TILES only in a comment until I2. The rule said `display: flex` and
   `.stat` had no rule at all, so three readings with different questions behind them — a partial
   day, an elapsed-matched week, a closed seven days — ran together as one block of text.

   `--activity-rule`, NOT the mockup's `--line-2`, and that is I3's change under §10.17's new
   "compound" category: the mockup's token composites to ~1.17:1 against this card and was carrying
   the entire claim that these are three separate tiles. The mockup was right and the transcription
   was right; what broke it is divergence #17, the panel being a full card here rather than flat on
   a white page. 3.11:1 measured — see app.css for why solid rather than a stronger alpha. */
.activity-next[b-non1vhr64q]  .activity-panel .stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    background: var(--activity-rule);
    border: 1px solid var(--activity-rule);
    border-radius: 8px;
    overflow: hidden;
    margin: 0;
}

/* §10.17 row 27 — the mockup's `.stats.hovering .stat` takes `--card-2` on hover, and here that
   arrives as the overlay's own tile ground rather than as a class toggled onto the tiles underneath.
   Same result on screen; the server-rendered tiles are never hidden, emptied or rewritten, and no
   Blazor-rendered attribute is toggled. (The container itself IS Blazor-rendered and its innerHTML
   is JS's — see the markup for why that is the whole of the contract and not a loophole in it.)

   VISIBILITY IS `:empty`: an attribute toggled by JS on a Blazor-rendered element survives a
   re-render that computes the same value, which would leave a stale readout on screen after a
   control change. Content is the one thing JS owns outright. */
.activity-next[b-non1vhr64q]  .activity-panel .stats-hover {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.activity-next[b-non1vhr64q]  .activity-panel .stats-hover:empty {
    display: none;
}

.activity-next[b-non1vhr64q]  .activity-panel .stats-hover .stat {
    background: var(--activity-card-2);
}

.activity-next[b-non1vhr64q]  .activity-panel .stat {
    background: var(--activity-card);
    padding: 0.5rem 0.75rem 0.55rem;
    min-width: 0;
}

.activity-next[b-non1vhr64q]  .activity-panel .stat-k {
    font-size: 0.72rem;
    color: var(--activity-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.activity-next[b-non1vhr64q]  .activity-panel .stat-row {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

/* tabular-nums, from the §10.17 sweep (mockup lines 141, 146, 148, 178, 179, 196). These three
   stats sit in a row and change together on every control change — and now on every hover —
   so proportional digits make them jump sideways. */
.activity-next[b-non1vhr64q]  .activity-panel .stat-v {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--activity-ink-2);
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

/* nowrap matches the summary strip's own `.delta` and the mockup's (line 179): "▲ +50%" is one
   token and must not break across the arrow. */
.activity-next[b-non1vhr64q]  .activity-panel .delta {
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.activity-next[b-non1vhr64q]  .activity-panel .delta.up { color: var(--activity-up); }
.activity-next[b-non1vhr64q]  .activity-panel .delta.down { color: var(--activity-down); }
.activity-next[b-non1vhr64q]  .activity-panel .delta.flat { color: var(--activity-muted); }

/* --activity-muted, not a fainter token. This line carries "vs 1,043 to the same point last week"
   — the elapsed-matched comparison, which is §10.2's second problem and the reading this rebuild
   exists to make possible. Shipping it as the faintest text on the page (2.53:1 at 0.72rem) was the
   single worst contrast on the surface; see §10.15 condition 3. */
.activity-next[b-non1vhr64q]  .activity-panel .stat-note {
    font-size: 0.72rem;
    color: var(--activity-muted);
}

/* ══ The weekday heatmap (I3) ═════════════════════════════════════════════════════════════════
   A CSS grid, as the mockup draws it and as the technical design (§5) says it should stay: what is
   being drawn is a calendar, and Chart.js has no matrix type without a plugin this repo does not
   vendor. */

.activity-next[b-non1vhr64q]  .heat {
    display: grid;
    grid-template-columns: 2.2rem minmax(0, 1fr);
    gap: 0.4rem;
    align-items: start;
    margin-top: 0.7rem;
}

.activity-next[b-non1vhr64q]  .heat-rows {
    display: grid;
    grid-template-rows: repeat(7, 1.06rem);
    gap: 3px;
    font-size: 0.68rem;
    color: var(--activity-muted);
}

.activity-next[b-non1vhr64q]  .heat-rows div {
    display: flex;
    align-items: center;
}

/* The one horizontally scrolling element on the surface, and it is scoped to itself rather than
   left to the page: thirteen 30px columns do not fit a 400px viewport, and AC 11's rule is that the
   BODY does not scroll sideways. A cell narrower than ~18px stops reading as a cell. */
.activity-next[b-non1vhr64q]  .heat-scroll {
    overflow-x: auto;
    min-width: 0;
}

.activity-next[b-non1vhr64q]  .heat-cells {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1.9rem;
    gap: 3px;
    justify-content: start;
}

.activity-next[b-non1vhr64q]  .heat-col {
    display: grid;
    grid-template-rows: repeat(7, 1.06rem);
    gap: 3px;
}

/* A BOX MEANS WE LOOKED. `--activity-rule` at 3.11:1, not `--activity-line-2` at 1.17:1, and this is
   §10.17 row 28's mechanism caught a second time in the element I3 itself added.

   The first version drew all three states with the same 1.17:1 border and separated "not held" from
   "held and zero" by dashed-versus-solid — while a covered zero's own `--activity-card-2` fill sits at
   **1.06:1** against the card. So two of the three states differed only by a dash pattern in a line
   almost nobody could see, in an element whose view model, razor comment and unit test all argue at
   length that drawing them alike would make the run-in weeks look like a quiet fortnight. Arguing the
   distinction and then rendering it at 1.17:1 is the register's compound shape exactly. */
.activity-next[b-non1vhr64q]  .heat-cell {
    display: block;
    border-radius: 2px;
    border: 1px solid var(--activity-rule);
}

/* THREE CELL STATES, AND NOW THREE VISIBLY DIFFERENT ONES. A day with sessions is tinted inside a
   box; a covered day with no sessions is an EMPTY box — the box is the statement that the source
   looked; a day the source does not reach has no box at all. That reads at a glance in a way
   solid-versus-dashed at 1.17:1 did not, and it says the right thing: absence of a box is absence of
   an answer, not an answer of zero. Same three-left-edge-facts distinction the series makes, at the
   other end of the page. */
.activity-next[b-non1vhr64q]  .heat-cell.uncovered {
    border-color: transparent;
    background: transparent;
}

.activity-next[b-non1vhr64q]  .heat-cols {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1.9rem;
    gap: 3px;
    justify-content: start;
    margin-top: 0.25rem;
    font-size: 0.6rem;
    color: var(--activity-muted);
}

.activity-next[b-non1vhr64q]  .heat-cols span {
    text-align: center;
    overflow: hidden;
}

/* ══ The page-level definitions section (I3) ══════════════════════════════════════════════════
   Distinct from the per-panel `i`, which is shell and shipped at I1 (R10.1, §10.14 Q1). This is the
   page foot: closed by default, because the section exists to get the prose off the charts' backs
   rather than to be a fifth screen of it. */

.activity-next[b-non1vhr64q]  .defs {
    border: 1px solid var(--activity-line);
    border-radius: 10px;
    background: var(--activity-card);
    margin-top: 1.4rem;
}

.activity-next[b-non1vhr64q]  .defs > summary {
    cursor: pointer;
    padding: 0.7rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--activity-ink-2);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    list-style: none;
}

.activity-next[b-non1vhr64q]  .defs > summary::-webkit-details-marker {
    display: none;
}

/* The disclosure triangle, drawn rather than left to the UA so it sits on the text baseline and
   takes the surface's own muted token. */
.activity-next[b-non1vhr64q]  .defs > summary::before {
    content: "▸";
    color: var(--activity-muted);
    font-size: 0.8em;
}

.activity-next[b-non1vhr64q]  .defs[open] > summary::before {
    content: "▾";
}

.activity-next[b-non1vhr64q]  .defs > summary:focus-visible {
    outline: 2px solid var(--activity-primary);
    outline-offset: -2px;
    border-radius: 10px;
}

.activity-next[b-non1vhr64q]  .defs-body {
    padding: 0 1rem 1rem;
    font-size: 0.8rem;
    color: var(--activity-muted);
    line-height: 1.6;
}

.activity-next[b-non1vhr64q]  .defs-body h3 {
    font-size: 0.8rem;
    color: var(--activity-ink-2);
    margin: 0.9rem 0 0.25rem;
}

.activity-next[b-non1vhr64q]  .defs-body p {
    margin: 0 0 0.5rem;
    max-width: 76ch;
}

/* `color: inherit` is the load-bearing declaration, and it is here because a rendered screenshot
   showed it missing. Bootstrap Reboot colours every `<code>` in the app pink (`#d63384`), and the
   mockup's own rule sets only the ground and the size — so its code spans take the muted prose
   colour while the build's arrived as the one off-palette colour on the surface. The mockup did not
   need the declaration because it has no Bootstrap under it; this build does, which makes inheriting
   a decision rather than a default. */
.activity-next[b-non1vhr64q]  .defs-body code {
    background: var(--activity-card-2);
    color: inherit;
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 0.92em;
}

/* ══ The responsive pass (I3) ═════════════════════════════════════════════════════════════════

   THE RAIL KEEPS STICKING AT PHONE WIDTH, AND THE 202px IS REMOVED INSTEAD. This is the decision
   §10.17 asked I3 to take deliberately, and it is neither of the two candidates that section named.

   §10.17 measured the rail at 202px at 400px — three wrapped rows, a quarter of an 800px viewport,
   held permanently — and offered: drop the stickiness below the breakpoint, or collapse the rail to
   a one-line summary while stuck. `ux-reviewer` measured the same rail at ~199px independently and
   argued against dropping it: losing the controls mid-scroll is the exact problem stickiness solved,
   and a phone page carrying four panels, a heatmap and a definitions block is a long scroll back
   rather than a thumb-flick. That is right. Its own candidate is NEW UI — an expanded and a
   collapsed state, an affordance, a decision about what the summary says, and a stuck-detection
   mechanism, since there is no `:stuck` selector and it takes a sentinel and an observer.

   THE THIRD OPTION EXISTS BECAUSE THE 202px WAS NEVER THE COST OF STICKINESS. It is the cost of a
   DESKTOP LAYOUT WRAPPING: every control stacks its label above its segment, which is right beside
   four others on a 1440px rail and is three tall rows at 400px. Put the label BESIDE its segment
   here and the same five controls — none hidden, none behind a disclosure — fit in less than half
   the height. Nothing is removed, no state is added, and the behaviour the reviewer wanted kept is
   kept. */
@media (max-width: 719.98px) {
    .activity-next .rail[b-non1vhr64q] {
        padding: 0.45rem 0.7rem;
    }

    .activity-next .rail-inner[b-non1vhr64q] {
        gap: 0.35rem 0.9rem;
    }

    /* Label beside segment rather than above it. This one declaration is most of the saving: it
       turns each control from a ~48px stacked block into a ~30px line. */
    .activity-next .ctl[b-non1vhr64q] {
        flex-direction: row;
        align-items: center;
        gap: 0.45rem;
    }

    /* THE "· daily buckets only" CAPTION STAYS AT PHONE WIDTH, and an earlier draft of this block hid
       it with the justification that "the title attribute carries the full sentence for anyone who
       asks". There is no `title` on that span — and even the one on `.seg` would not help, because a
       tooltip needs a hover and a phone has no pointer. Hiding it therefore left the Window segment
       faded at 0.45 with no stated reason at exactly the width where no fallback exists, which is the
       failure the caption was added to prevent.

       It costs ~14px, and only at weekly bucketing: the caption is `hidden` at daily grain, so the
       rail's measured height at the default is unchanged. */

    .activity-next .check[b-non1vhr64q] {
        padding-bottom: 0;
        font-size: 0.78rem;
    }
}

@media (max-width: 599.98px) {
    .activity-next .seg button[b-non1vhr64q] {
        padding-inline: 0.5rem;
    }

    /* One column: at this width three tiles are ~115px each and the figures wrap inside them. The
       hairline frame becomes three stacked rows, which is still the tile grammar — and the hover
       readout follows it, because the overlay wears the same `.stats` rule. */
    .activity-next[b-non1vhr64q]  .activity-panel .stats {
        grid-template-columns: minmax(0, 1fr);
    }

    .activity-next[b-non1vhr64q]  .activity-panel .stat-v {
        font-size: 1.25rem;
    }

    .activity-next[b-non1vhr64q]  .heat {
        grid-template-columns: 1.9rem minmax(0, 1fr);
    }

    /* THE HIDDEN COLUMNS, GIVEN AN EDGE. Measured at 400px: the grid is 431px wide (13 columns of
       1.9rem plus twelve 3px gaps) inside a 282px scroller, so **four to five of thirteen weeks sit
       off-screen at rest**. The container clips mid-column, which hints at more — but a native
       scrollbar is an overlay that stays invisible until a touch begins, and touch is the realistic
       input at this width, so the hint is the only cue there is.

       A mask rather than an overlaid gradient, so it needs no extra element and cannot mis-stack
       over the cells. Scoped to this breakpoint deliberately: the grid is 431px and the scroller
       reaches that at roughly a 550px viewport, so below 600px there is essentially always something
       beyond the edge. Above it there is not, and a fade with nothing behind it would be a worse
       lie than no fade at all.

       `currentColor` rather than a black stop, and not only to satisfy FF-A6: a mask reads ALPHA, so
       the colour is irrelevant and naming one would imply it was not. Opaque to transparent is the
       whole declaration. */
    .activity-next[b-non1vhr64q]  .heat-scroll {
        -webkit-mask-image: linear-gradient(to right, currentColor calc(100% - 1.5rem), transparent);
        mask-image: linear-gradient(to right, currentColor calc(100% - 1.5rem), transparent);
    }

    .activity-next[b-non1vhr64q]  .defs-body {
        padding-inline: 0.8rem;
    }
}
/* /Components/Pages/AttendanceOverTimeReport.razor.rz.scp.css */
.reports-shell[b-mzjaokdlbb] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-mzjaokdlbb] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-mzjaokdlbb] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-mzjaokdlbb],
.reports-crumb-link:focus-visible[b-mzjaokdlbb] {
    text-decoration: underline;
    outline: none;
}

.aot-head[b-mzjaokdlbb] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.aot-head h1[b-mzjaokdlbb] {
    margin: 0;
    color: #1f3f5e;
}

.aot-sub[b-mzjaokdlbb] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.aot-head-actions[b-mzjaokdlbb] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.aot-ranges[b-mzjaokdlbb] {
    display: flex;
    gap: 0.35rem;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.aot-ranges button[b-mzjaokdlbb] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.aot-ranges button.on[b-mzjaokdlbb] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.aot-ranges button:disabled[b-mzjaokdlbb] {
    cursor: default;
    opacity: 0.55;
}

/* tiles */
.aot-tiles[b-mzjaokdlbb] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.aot-tile[b-mzjaokdlbb] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.aot-tile .lab[b-mzjaokdlbb] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.aot-tile .val[b-mzjaokdlbb] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
}

.aot-tile .sub[b-mzjaokdlbb] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* chart cards */
.aot-card[b-mzjaokdlbb] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    margin-bottom: 1.15rem;
    padding: 1rem 1.2rem 1.2rem;
}

.aot-card-head[b-mzjaokdlbb] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.aot-card-head h3[b-mzjaokdlbb] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.aot-card-head .d[b-mzjaokdlbb] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

/* Seasonality "Quieter months" band legend (the Chart.js legend is off for that chart). */
.aot-legend[b-mzjaokdlbb] {
    margin-left: auto;
    color: #52617a;
    font-size: 0.78rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.aot-swatch-band[b-mzjaokdlbb] {
    display: inline-block;
    width: 16px;
    height: 11px;
    background: rgba(219, 231, 245, 0.9);
    border: 1px solid #c4d6ec;
    border-radius: 2px;
}

.aot-chart[b-mzjaokdlbb] {
    position: relative;
    height: 280px;
}

.aot-empty[b-mzjaokdlbb] {
    color: #6c7a8c;
    padding: 2rem 0;
    text-align: center;
    margin: 0;
}

@media (max-width: 820px) {
    .aot-tiles[b-mzjaokdlbb] {
        grid-template-columns: repeat(2, 1fr);
    }
    .aot-head-actions[b-mzjaokdlbb] {
        margin-left: 0;
    }
}

@media (max-width: 480px) {
    .aot-tiles[b-mzjaokdlbb] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/AttendanceTrendsReport.razor.rz.scp.css */
.reports-crumb[b-vvhz5dyekm] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-vvhz5dyekm] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-vvhz5dyekm],
.reports-crumb-link:focus-visible[b-vvhz5dyekm] {
    text-decoration: underline;
    outline: none;
}

.attendance-trends-filters[b-vvhz5dyekm] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, auto)) 1fr;
    gap: 0.7rem;
    align-items: end;
    margin-bottom: 0.75rem;
}

.attendance-trends-filter[b-vvhz5dyekm] {
    display: flex;
    flex-direction: column;
}

.attendance-trends-filter .form-label[b-vvhz5dyekm] {
    font-size: 0.82rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.2rem;
}

.attendance-trends-filter-actions[b-vvhz5dyekm] {
    flex-direction: row;
    gap: 0.5rem;
    justify-content: flex-end;
    align-items: flex-end;
}

.attendance-trends-count-hint[b-vvhz5dyekm] {
    color: #6c7a8c;
    font-size: 0.88rem;
    margin-bottom: 0.4rem;
}

.attendance-trends-table thead th[b-vvhz5dyekm] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
    font-size: 0.95rem;
    white-space: nowrap;
}

.attendance-trends-table th.sortable-header[b-vvhz5dyekm] {
    cursor: pointer;
    user-select: none;
}

.attendance-trends-table th.sortable-header:hover[b-vvhz5dyekm] {
    color: #0d2c55;
}

.attendance-trends-table td[b-vvhz5dyekm],
.attendance-trends-table th[b-vvhz5dyekm] {
    vertical-align: middle;
}

.attendance-trends-table .numeric[b-vvhz5dyekm] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 768px) {
    .attendance-trends-filter-actions[b-vvhz5dyekm] {
        justify-content: flex-start;
    }
}

/* ── Drift visuals ───────────────────────────────────────────────────────── */

/* (1) status summary strip */
.trends-statbar[b-vvhz5dyekm] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.9rem;
    margin: 0.25rem 0 1.15rem;
}

.trends-stat[b-vvhz5dyekm] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-left-width: 4px;
    border-radius: 0.75rem;
    padding: 0.85rem 1rem;
}

.trends-stat.active[b-vvhz5dyekm] { border-left-color: #2e9c63; }
.trends-stat.lapsing[b-vvhz5dyekm] { border-left-color: #e0a32a; }
.trends-stat.dormant[b-vvhz5dyekm] { border-left-color: #9aa6b6; }
.trends-stat.new[b-vvhz5dyekm] { border-left-color: #1b6ec2; }

.trends-stat .lab[b-vvhz5dyekm] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

.trends-stat .pip[b-vvhz5dyekm] {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
}

.trends-stat.active .pip[b-vvhz5dyekm] { background: #2e9c63; }
.trends-stat.lapsing .pip[b-vvhz5dyekm] { background: #e0a32a; }
.trends-stat.dormant .pip[b-vvhz5dyekm] { background: #9aa6b6; }
.trends-stat.new .pip[b-vvhz5dyekm] { background: #1b6ec2; }

.trends-stat .val[b-vvhz5dyekm] {
    font-size: 1.8rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.45rem;
    font-variant-numeric: tabular-nums;
}

.trends-stat .sub[b-vvhz5dyekm] {
    font-size: 0.76rem;
    color: #6c7a8c;
    margin-top: 0.3rem;
}

/* hero grid: drift map (wide) + reach-out (narrow) */
.trends-grid[b-vvhz5dyekm] {
    display: grid;
    grid-template-columns: 1.55fr 1fr;
    gap: 1.15rem;
    margin-bottom: 1.15rem;
}

.trends-card[b-vvhz5dyekm] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.2rem 1.1rem;
}

.trends-card-head[b-vvhz5dyekm] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.trends-card-head h3[b-vvhz5dyekm] {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: #1f3f5e;
}

.trends-card-head .d[b-vvhz5dyekm] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

/* Days-since-last window selector — same segmented-button treatment as the
   Attendance-over-time report's .aot-ranges, for consistency across the two charts.
   margin-left:auto pushes it to the right edge of the (flex) card head. */
.trends-window[b-vvhz5dyekm] {
    display: flex;
    gap: 0.35rem;
    margin-left: auto;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.trends-window button[b-vvhz5dyekm] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.trends-window button.on[b-vvhz5dyekm] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.trends-window button:disabled[b-vvhz5dyekm] {
    cursor: default;
    opacity: 0.55;
}

/* (2) drift map */
.trends-driftmap[b-vvhz5dyekm] {
    position: relative;
    height: 360px;
}

.trends-empty[b-vvhz5dyekm] {
    color: #6c7a8c;
    padding: 2rem 0;
    text-align: center;
    margin: 0;
}

.trends-legend[b-vvhz5dyekm] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: 0.65rem;
    font-size: 0.78rem;
    color: #52617a;
}

.trends-legend span[b-vvhz5dyekm] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

.trends-legend .dot[b-vvhz5dyekm] {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    display: inline-block;
}

.trends-legend .dot.active[b-vvhz5dyekm] { background: #2e9c63; }
.trends-legend .dot.lapsing[b-vvhz5dyekm] { background: #e0a32a; }
.trends-legend .dot.dormant[b-vvhz5dyekm] { background: #9aa6b6; }
.trends-legend .dot.new[b-vvhz5dyekm] { background: #1b6ec2; }

.trends-legend .zone .swatch[b-vvhz5dyekm] {
    width: 16px;
    height: 11px;
    border-radius: 2px;
    background: rgba(224, 163, 42, 0.40);
    border: 1px solid #f0d690;
    display: inline-block;
}

/* (3) reach-out spotlight */
.trends-reach[b-vvhz5dyekm] {
    display: flex;
    flex-direction: column;
}

.trends-empty-small[b-vvhz5dyekm] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin: 0.5rem 0 0;
}

.trends-person[b-vvhz5dyekm] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    border-bottom: 1px solid #f1f4f9;
    padding: 0.7rem 0.25rem;
    cursor: pointer;
    font: inherit;
}

.trends-person:last-child[b-vvhz5dyekm] { border-bottom: none; }

.trends-person:hover[b-vvhz5dyekm],
.trends-person:focus-visible[b-vvhz5dyekm] {
    background: #f7f9fc;
    outline: none;
}

.trends-person .av[b-vvhz5dyekm] {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #e0a32a;
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.75rem;
    flex: 0 0 auto;
}

.trends-person .who[b-vvhz5dyekm] { min-width: 0; }

.trends-person .who .nm[b-vvhz5dyekm] {
    display: block;
    font-weight: 700;
    font-size: 0.85rem;
    color: #24364d;
}

.trends-person .who .meta[b-vvhz5dyekm] {
    display: block;
    font-size: 0.74rem;
    color: #6c7a8c;
}

.trends-person .spark[b-vvhz5dyekm] {
    margin-left: auto;
    flex: 0 0 auto;
}

.trends-person .days[b-vvhz5dyekm] {
    flex: 0 0 auto;
    text-align: right;
    width: 58px;
}

.trends-person .days b[b-vvhz5dyekm] {
    font-size: 1rem;
    color: #a9750a;
    font-variant-numeric: tabular-nums;
}

.trends-person .days span[b-vvhz5dyekm] {
    display: block;
    font-size: 0.64rem;
    color: #6c7a8c;
}

/* (4) trajectory sparkline column in the existing table */
.trends-trajectory-head[b-vvhz5dyekm] {
    white-space: nowrap;
}

.trends-trajectory-cell[b-vvhz5dyekm] {
    width: 120px;
}

.trends-trajectory-cell svg[b-vvhz5dyekm] {
    display: block;
}

/* table section heading (above the existing filters + table) */
.trends-table-head[b-vvhz5dyekm] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.trends-table-head h3[b-vvhz5dyekm] {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: #1f3f5e;
}

.trends-table-head .d[b-vvhz5dyekm] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

/* pastel status pills in the table — same palette as the strip / reach-out / drift map */
.trends-pill[b-vvhz5dyekm] {
    display: inline-block;
    border-radius: 20px;
    padding: 0.1rem 0.6rem;
    font-size: 0.72rem;
    font-weight: 700;
}

.trends-pill.active[b-vvhz5dyekm] { background: #e6f5ec; color: #1f7a4d; }
.trends-pill.lapsing[b-vvhz5dyekm] { background: #fdeccd; color: #a9750a; }
.trends-pill.dormant[b-vvhz5dyekm] { background: #eef1f6; color: #52617a; }
.trends-pill.new[b-vvhz5dyekm] { background: #e3eefb; color: #1b6ec2; }

@media (max-width: 980px) {
    .trends-grid[b-vvhz5dyekm] {
        grid-template-columns: 1fr;
    }
    /* When the grid stacks, the drift map gains width but its fixed height would leave it wide
       and short — let it grow a little so the danger zone keeps a readable footprint. */
    .trends-driftmap[b-vvhz5dyekm] {
        height: 420px;
    }
}

@media (max-width: 720px) {
    .trends-statbar[b-vvhz5dyekm] {
        grid-template-columns: repeat(2, 1fr);
    }
}
/* /Components/Pages/Claim.razor.rz.scp.css */
/* #430 (portal S5): the claim = on-the-spot signup gate. Mobile-first, share-shaped —
   a single centred column that reads well on a phone opened from a WhatsApp share.
   Self-contained (no app nav chrome), like the recap + static-SSR auth shells. */

.claim-shell[b-b2rj2fdj2w] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
}

.claim-head[b-b2rj2fdj2w] {
    text-align: center;
    margin-bottom: 1.5rem;
}

.claim-brand-wordmark[b-b2rj2fdj2w] {
    height: 1.75rem;
    width: auto;
}

.claim-title[b-b2rj2fdj2w] {
    font-size: 1.6rem;
    font-weight: 800;
    margin: 0.75rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
}

.claim-sub[b-b2rj2fdj2w] {
    margin: 0;
    color: #5a6b7b;
    font-size: 0.95rem;
}

.claim-card[b-b2rj2fdj2w] {
    background: #f6f9fc;
    border: 1px solid #e0e8f0;
    border-radius: 0.75rem;
    padding: 1.5rem 1.25rem;
    text-align: center;
}

.claim-card h1[b-b2rj2fdj2w] {
    font-size: 1.35rem;
    color: #16324f;
    margin: 0 0 0.75rem;
}

.claim-help[b-b2rj2fdj2w] {
    color: #5a6b7b;
    font-size: 0.9rem;
}

.claim-reassurance[b-b2rj2fdj2w] {
    color: #5a6b7b;
    font-size: 0.9rem;
    line-height: 1.45;
    margin-top: 0.75rem;
}

.claim-fieldset[b-b2rj2fdj2w] {
    border: none;
    padding: 0;
    margin: 1rem 0 0;
}

.claim-fieldset legend[b-b2rj2fdj2w] {
    font-weight: 700;
    color: #16324f;
    margin-bottom: 0.5rem;
    font-size: 1rem;
}

.claim-name-list[b-b2rj2fdj2w] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    max-height: 18rem;
    overflow-y: auto;
    border: 1px solid #e0e8f0;
    border-radius: 0.5rem;
    padding: 0.4rem;
}

.claim-name-option[b-b2rj2fdj2w] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.65rem;
    border-radius: 0.4rem;
    cursor: pointer;
    min-height: 2.75rem; /* touch target */
}

.claim-name-option:hover[b-b2rj2fdj2w] {
    background: #eef4fa;
}

.claim-name-radio[b-b2rj2fdj2w] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
}

.claim-name-text[b-b2rj2fdj2w] {
    font-size: 1rem;
}

/* #82 (Owner decision 2026-08-11): already-claimed names — greyed, non-interactive, with a
   "Claimed" chip. Mirrors Connect.razor.css's .connect-name-claimed / .connect-connected-chip. */
.claim-name-claimed[b-b2rj2fdj2w] {
    cursor: default;
    opacity: 0.72;
}

.claim-name-claimed:hover[b-b2rj2fdj2w] {
    background: transparent;
}

.claim-name-claimed .claim-name-text[b-b2rj2fdj2w] {
    color: #5a6b7b;
}

.claim-claimed-chip[b-b2rj2fdj2w] {
    margin-left: auto;
    font-size: 0.68rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #14532d;
    border-radius: 1rem;
    padding: 0.1rem 0.5rem;
    font-weight: 700;
}

.claim-code-input[b-b2rj2fdj2w] {
    text-transform: uppercase;
    letter-spacing: 0.15em;
    font-weight: 600;
}

.claim-consent-label[b-b2rj2fdj2w] {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-size: 0.9rem;
    color: #3a4a5a;
}

.claim-consent-label input[b-b2rj2fdj2w] {
    margin-top: 0.2rem;
    width: 1.1rem;
    height: 1.1rem;
    flex: 0 0 auto;
}

.claim-actions[b-b2rj2fdj2w] {
    display: flex;
    justify-content: stretch;
}

.claim-actions .btn[b-b2rj2fdj2w] {
    width: 100%;
    min-height: 3rem;
    font-size: 1.05rem;
}

.claim-error[b-b2rj2fdj2w] {
    background: #fdecec;
    border: 1px solid #f5b5b5;
    color: #8a1f1f;
    border-radius: 0.5rem;
    padding: 0.65rem 0.8rem;
    margin-bottom: 0.75rem;
    font-size: 0.92rem;
}

/* #696: the "code applied from your link" affordance that replaces the manual code
   field when a well-formed ?code= arrives (kiosk QR scan / #709 shared link). Same
   green family as the claim-code chip on the kiosk, so the two ends of the scan
   visually agree. */
.claim-code-applied[b-b2rj2fdj2w] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    border-radius: 0.5rem;
    padding: 0.65rem 0.8rem;
    margin-top: 1rem;
    font-size: 0.92rem;
    color: #14532d;
}

.claim-code-applied code[b-b2rj2fdj2w] {
    font-weight: 800;
    letter-spacing: 0.12em;
    color: #14532d;
}

.claim-code-applied-clear[b-b2rj2fdj2w] {
    color: #2f6eaa;
    font-size: 0.85rem;
    align-self: flex-start;
}
/* /Components/Pages/ClubmateProfile.razor.rz.scp.css */
/* SPEC-32 S7 (#191): the clubmate-profile page SHELL chrome. Blazor CSS isolation is per-component, so
   the .my-shell / .my-backbar / .my-back / .my-empty rules this page reuses from the sibling player pages
   (PlayerClubDetail / MyNights / PlayerClubs) are NOT inherited — each page carries its own scoped copy.
   These match PlayerClubDetail.razor.css so the centred card column + Back control render identically
   (the section CARDS themselves are styled globally by profile.css from S6; only this page chrome lives
   here). Same shared player language — NO new brand. */

.my-shell[b-af7jniqnel] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* SPEC-32 I3-S0 (#677), R-I2-40: WHERE THE PROFILE RENDERS A TABLE, ITS COLUMN IS AS WIDE AS THE TABLE
   NEEDS. Owner ruling, 2026-09-02: "on desktop, we should definately be wider - why would we not be?"

   THE 34rem ABOVE IS A READING MEASURE AND IT DOES NOT GOVERN DATA. It applies at EVERY viewport, so a
   record view rendered a table needing ~705px inside a 478px wrapper at a 1440px viewport with ~1,400px
   of screen empty either side. The two slices before this one took the COLUMN SET as the variable and
   cut three columns; the container was the variable. `MemberSessionHistoryTable.razor.css` carried the
   disproof in its own comment the whole time - the clip and then the scrollbar arose "in a container
   NARROWER than that ... at a desktop viewport" and were a "No-op in the wide admin modal / kiosk panel".

   53rem IS MEASURED, NOT CHOSEN, AND HERE IS THE MEASUREMENT (qa-perf-club-mk, both lenses, 2026-09-02).
   The shell was swept in 4px steps and the BLOCK'S HEIGHT recorded at each step. Height falls in steps
   as columns stop wrapping and then plateaus; the first width on the plateau is the width that table
   needs, and it is an observation rather than a preference.

       view        needs   table    block height off the plateau -> on it
       Nights      840px   771px    5130px -> 1988px   <- the widest since I3-S1, +92px on I3-S0's 748
       Games       776px   705px    7630px -> 2253px   <- was the widest; unchanged, and re-measured
       Partners    592px   441px    24577px -> 11193px  <- I3-S3; was <520px / 403px / flat
       Opponents   592px   419px    24577px -> 11193px  <- I3-S3; was <520px / 403px / flat
       Overview    -       -        no table

   Corroborated by the other measure, taken the same day at 1920px: each table's max-content plus the
   horizontal chrome between the shell's border box and the wrapper's content box - Nights 770.73 + 66,
   Games 704.73 + 68, the counterparts 440.63 + 66 (Partners) and 419.28 + 66 (Opponents) since I3-S3.

   THE TWO COUNTERPART MEASURES DISAGREE BY 85px AND THE SWEEP IS THE ONE THAT BINDS. max-content puts
   Partners at 506.63px of shell; the sweep says 592px. Both are right about different things: these two
   tables are `table-layout: fixed` with STATED allocations (4 x 4.2rem numeric, 8rem for the date), so
   what the layout needs is the sum of the allocations and not the content's natural max-content. The
   sweep measures the rendering; max-content measures the text. Where a table states its widths, prefer
   the sweep - and the other two views, which are auto-layout, still agree to within a 4px step.

   53rem = 848px clears the widest by 8px, which is I3-S0's margin kept rather than a new one. It is a
   CAP, not a width: `margin: 0 auto` keeps the shell centred and it never exceeds the viewport. A wider
   cap would be a number nobody measured; a narrower one would wrap the Nights row this number exists to
   unwrap. RE-MEASURE IT WHEN A COLUMN IS ADDED OR REMOVED (R-I2-40.1).

   IT MOVED FROM 49rem BECAUSE I3-S1 (#669) PUT A COLUMN BACK, and that is the requirement working as
   written rather than a correction. The Owner ruled the time at the club back onto the session rows;
   `At Club` cost the Nights table 91.46px of max-content, which took it past Games and made Nights the
   binding view. The binding view is a measurement too, and it is expected to change hands.

   IT DID NOT MOVE FOR I3-S3 (#670), AND THAT IS RECORDED BECAUSE THE RE-MEASUREMENT IS WHAT R-I2-40.1
   ASKS FOR - NOT THE CHANGE. The Owner ruled the last day played back onto the counterpart rows; those
   two tables went from needing under 520px of shell to needing 592px, which is 256px inside a cap the
   Nights view sets at 840px. Nights remains the binding view. A slice that re-measures and finds nothing
   to change has still discharged the requirement; a slice that assumes it has not.

   THE 820px REFLOW DID NOT MOVE, AND THAT WAS CHECKED RATHER THAN ASSUMED (R-I2-40.2). A restored column
   raises a table's min-content as well as its max-content, and if the new min-content had exceeded the
   reflow the breakpoint would have had to rise with it. Measured: the six-column nights table's
   min-content is 545.69px, so 611.69px of shell - 208px inside a breakpoint that was already generous.
   Nothing below 821px changes.

   NOR DID THE COUNTERPART TABLES' OWN 720px REFLOW, checked the same way at I3-S3. Their six-column
   min-content is 332.13px (Partners) / 328.59px (Opponents), which is 398px of shell against a 478px
   wrapper at 720px - so the band between that reflow and the width the columns fit at, which R-I2-39
   says should not exist, still does not. It is `profile.css`'s query, not this file's; change one and
   look at the other.

   THE BREAKPOINT IS 821px AND IT IS THE NIGHTS TABLE'S OWN REFLOW, NOT A NEW NUMBER. Two of the profile's
   tables reflow to stacked cards at 720px and the nights table at 820px, and R-I2-40.6 allows exactly ONE
   width across all five views - the strip renders inside this shell, so a shell that is 504px on the
   summary and wider on a record view moves the strip on every view change. One width plus two reflows
   means the widening starts at the HIGHER of the two: at 821px every one of the four tables is a table,
   and at or below 820px nothing moves at all, which is what keeps the card tier untouched (R-I2-40.3).
   It is deliberately the same 821 as `MemberSessionHistoryTable.razor.css`'s reflow query - change one
   and you must look at the other.

   IT IS NOT KEYED TO THE ACTIVE VIEW, AND MUST NEVER BE. This rule is a function of the viewport alone,
   so the strip's x and width are identical on all five views by construction rather than by care.

   THE SIBLING PORTAL PAGES DO NOT FOLLOW (R-I2-40.5). `/me`, `/clubs`, `/account` and the club pages
   carry their own scoped 34rem copies and keep them: they are stacked cards and prose, where 504px is a
   READING measure, and none of them renders either of these tables. Blazor CSS isolation is what makes
   that safe - this rule is stamped with this page's scope attribute and reaches nothing else.

   IT IS IN TWO FILES ON PURPOSE. MyPerformance.razor.css carries these declarations byte for byte;
   AC-I2-S12-11 names the content column width FIRST, so a width change landing in one lens only is that
   criterion failing rather than a partial delivery. Spec32ProfileViewWiringGuardTests is what fails on
   the day they drift. */
@media (min-width: 821px) {
    .my-shell[b-af7jniqnel] {
        max-width: 53rem;
    }
}

/* ── Back bar (the way back to the roster). ── */
.my-backbar[b-af7jniqnel] {
    margin-bottom: 1rem;
}

.my-back[b-af7jniqnel] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.my-back:hover[b-af7jniqnel],
.my-back:focus-visible[b-af7jniqnel] {
    text-decoration: underline;
}

.my-back-caret[b-af7jniqnel] {
    font-weight: 700;
}

/* ── Error state (fail-closed shell — Back always present). ── */
.my-empty[b-af7jniqnel] {
    color: #5e748a;
    font-size: 0.95rem;
    text-align: center;
    padding: 2rem 1rem;
}
/* /Components/Pages/Clubs.razor.rz.scp.css */
.clubs-shell[b-s4llzf7qxg] {
    padding: 0;
}

.clubs-shell h1[b-s4llzf7qxg] {
    margin: 0 0 0.25rem;
    color: #1f3f5e;
}

.clubs-subtitle[b-s4llzf7qxg] {
    margin: 0 0 1rem;
    color: #5f7489;
}

.clubs-card[b-s4llzf7qxg] {
    background: #f6f8fb;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.25rem;
    margin-bottom: 1rem;
    padding: 1rem;
}

.clubs-card h2[b-s4llzf7qxg] {
    margin: 0 0 0.65rem;
    color: #24384f;
}

.clubs-header[b-s4llzf7qxg] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.65rem;
}

.clubs-show-demo-toggle[b-s4llzf7qxg] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #4e6f8e;
    font-size: 0.88rem;
    margin: 0;
}

.clubs-demo-badge[b-s4llzf7qxg] {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.05rem 0.45rem;
    background: #fff4d6;
    color: #6a4a08;
    border: 1px solid #e3b14a;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    vertical-align: middle;
}

.clubs-toolbar[b-s4llzf7qxg] {
    display: flex;
    gap: 0.55rem;
    align-items: center;
    margin-bottom: 0.5rem;
}

.clubs-form-grid[b-s4llzf7qxg] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.75rem;
    margin-bottom: 0.5rem;
    align-items: end;
}

.clubs-form-field[b-s4llzf7qxg] {
    display: flex;
    flex-direction: column;
}

.clubs-form-field-wide[b-s4llzf7qxg] {
    grid-column: span 2;
}

.clubs-form-actions[b-s4llzf7qxg] {
    display: flex;
    align-items: flex-end;
}

.clubs-form-field .form-label[b-s4llzf7qxg] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.25rem;
}


.clubs-import-details > summary[b-s4llzf7qxg] {
    cursor: pointer;
    list-style: revert;
    padding: 0.1rem 0;
}

.clubs-import-details > summary[b-s4llzf7qxg]::-webkit-details-marker {
    display: inline-block;
}

.clubs-import-summary-heading[b-s4llzf7qxg] {
    display: inline;
    margin: 0;
    color: #24384f;
    font-size: 1.05rem;
}

.clubs-import-hint[b-s4llzf7qxg] {
    display: block;
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-left: 1.4rem;
    margin-top: 0.2rem;
}

.clubs-help[b-s4llzf7qxg] {
    color: #5f6f80;
}

.clubs-table thead th[b-s4llzf7qxg] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
}

/* Click-to-sort column headers (#195). */
.clubs-table th.sortable-header[b-s4llzf7qxg] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}

.clubs-table th.sortable-header:hover[b-s4llzf7qxg] {
    color: #0d2c55;
}

/* #268 country-flag column: narrow, centred, non-wrapping. The header text is small; the cell shows a
   flag emoji (or blank when the club has no country set). */
.clubs-table th.clubs-flag-col[b-s4llzf7qxg] {
    white-space: nowrap;
    font-size: 0.72rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: #6b7683;
}

/* Windows has no colour flag-emoji font — regional-indicator emoji fall back to the
   2-letter code. This flags-only subset webfont (~78KB, restricted by unicode-range)
   renders them as actual flags cross-platform. */
@font-face {
    font-family: "Twemoji Country Flags";
    unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E007F;
    src: url("/lib/flags/TwemojiCountryFlags.woff2") format("woff2");
}

.clubs-table td.clubs-flag-cell[b-s4llzf7qxg] {
    text-align: center;
    font-size: 1.15rem;
    line-height: 1;
    white-space: nowrap;
    font-family: "Twemoji Country Flags", system-ui, sans-serif;
}

/* Wraps the action buttons (Use Club / Edit / Delete) so that they
   keep a visible gap on both axes when they reflow onto a second
   line on narrow viewports -- the previous me-2 utility only added
   horizontal spacing, leaving rows touching vertically. */
.clubs-actions[b-s4llzf7qxg] {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    justify-content: flex-end;
}

/* The admin table is wide (10 columns) and scrolls horizontally inside .table-responsive at
   tablet / icon-rail widths (and slightly even at desktop). Pin the Actions column to the right
   edge so the per-club buttons stay visible and reachable however far the table is scrolled -
   otherwise they sit ~160px off the right with the only scrollbar below the fold. */
.clubs-table th:last-child[b-s4llzf7qxg],
.clubs-table td:last-child[b-s4llzf7qxg] {
    position: sticky;
    right: 0;
    background: #ffffff;
    box-shadow: -6px 0 6px -4px rgba(0, 0, 0, 0.12);
}

.clubs-table td:last-child[b-s4llzf7qxg] {
    z-index: 1;
}

.clubs-table thead th:last-child[b-s4llzf7qxg] {
    z-index: 3;
}

.clubs-message[b-s4llzf7qxg] {
    margin-bottom: 0.6rem;
    border: 1px solid #b7cadf;
    border-radius: 0.45rem;
    background: #ecf4fc;
    color: #244a6f;
    padding: 0.35rem 0.5rem;
    font-size: 0.9rem;
}

@media (max-width: 700px) {
    .clubs-toolbar[b-s4llzf7qxg] {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ADR 0005 per-club pilot flag controls (superuser, internal). Deliberately
   minor — this is an internal pilot toggle, not a feature surface. */
.clubs-picker-edit[b-s4llzf7qxg] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    font-weight: 400;
}

.clubs-picker-edit-label[b-s4llzf7qxg] {
    font-size: 0.8rem;
    color: #5f7489;
}

.clubs-picker-select[b-s4llzf7qxg] {
    width: auto;
    min-width: 6rem;
}

.clubs-picker-badge[b-s4llzf7qxg] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.35rem;
    border-radius: 0.2rem;
    background: rgba(13, 44, 85, 0.08);
    color: #1f3f5e;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    vertical-align: middle;
}

/* #810 S4 read-only badge for a club that has an explicit override-OFF against a
   Default-ON feature. The feature NAME pill is muted, and a distinct red "OFF" state
   pill sits beside it (mirroring the feature screen's ON/OFF pill language), so the
   row reads as a deliberate off-exception, not an absent feature. The two pills form
   one visual group. */
.clubs-feature-badge-group[b-s4llzf7qxg] {
    display: inline-flex;
    align-items: center;
    margin-left: 0.4rem;
    vertical-align: middle;
}

.clubs-picker-badge-muted[b-s4llzf7qxg] {
    margin-left: 0;
    background: rgba(13, 44, 85, 0.05);
    color: #7a8aa0;
    border-radius: 0.2rem 0 0 0.2rem;
}

.clubs-picker-state-off[b-s4llzf7qxg] {
    display: inline-block;
    padding: 0.05rem 0.35rem;
    border-radius: 0 0.2rem 0.2rem 0;
    background: #b23b3b;
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    vertical-align: middle;
}

/* #810 S4 per-club feature OVERRIDES panel (superuser, internal). Groups the per-feature
   override controls into one "Feature overrides" cell in the edit row, with a left rule
   separating it from the slug/name/status fields. */
.clubs-features-edit[b-s4llzf7qxg] {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    border-left: 1px solid rgba(13, 44, 85, 0.12);
    padding-left: 0.75rem;
}

.clubs-features-edit-header[b-s4llzf7qxg] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.clubs-features-edit-heading[b-s4llzf7qxg] {
    font-size: 0.8rem;
    font-weight: 600;
    color: #5f7489;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* #810 S4 visible scope note under the panel heading — kiosk/touch have no hover, so the
   Inherit-vs-override semantic must be on-screen, not only in the tooltip. */
.clubs-features-edit-note[b-s4llzf7qxg] {
    font-size: 0.72rem;
    font-weight: 400;
    color: #8090a2;
    text-transform: none;
    letter-spacing: normal;
    max-width: 22rem;
    line-height: 1.25;
}

.clubs-feature-toggle[b-s4llzf7qxg] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    font-weight: 400;
}

.clubs-feature-toggle-label[b-s4llzf7qxg] {
    font-size: 0.85rem;
    color: #24384f;
}

/* #810 S4 tri-state per-club override <select> (Inherit / Override on / Override off). */
.clubs-feature-override-select[b-s4llzf7qxg] {
    width: auto;
    min-width: 9rem;
}
/* /Components/Pages/ClubSessionDashboard.razor.rz.scp.css */
.clubSession-dashboard-shell[b-l9cvewerkd] {
    /* ── #718: the fold density scale ─────────────────────────────────────────
       The dashboard's vertical stack must fit common operator viewports without
       scrolling. These custom properties are the ONE set of vertical-density
       knobs; the height-tier media blocks at the END of this file re-declare
       them (custom properties inherit through the CSS-isolation scope into the
       ::deep children, so each tier reads as one legible block). Tier 0
       (>=900px viewport height) = these base values = today's exact layout. */
    --fold-court-min: 14.5rem;
    --fold-court-empty-min: 11.8rem;
    --fold-panel-pad: 0.6rem;
    --fold-prep-slot-min: 2.3rem;
    --fold-prep-gap: 0.35rem;
    --fold-band-gap: 0.45rem;
    --fold-waiting-cap: 12.5rem;
    /* #848/#817 Slice 1 (court-count reflow): the single-row court-fit floor + the
       Special-Requests dock height cap. --fold-court-col-min is the minmax() WRAP
       threshold for the 5-court auto-fit grid (the legible card floor, ~11rem per the
       UX matrix §3); 1fr expands the five occupied tracks to fill the row (~12.9rem
       cards at a 1280 board). It is deliberately CONSTANT across the height tiers -
       11rem holds five cards on every 1280+ board, and the tiers are a vertical-density
       axis; lowering this WIDTH floor toward ~10rem to reach the ≤1024 path is a Slice-2
       lever (paired with the icon-only court headers), not a height-tier concern.
       --fold-sr-cap bounds the docked Special Requests list so the operational band's
       height is fixed regardless of SR presence (guarantee 1; also closes the
       pre-existing 4-court SR overflow); IT tightens at the tier-2/3 height blocks below
       in lock-step with --fold-waiting-cap. */
    --fold-court-col-min: 11rem;
    --fold-sr-cap: 8rem;
    background: #d2dbe7;
    padding: 0.35rem 0 0.8rem;
}

/* QuickFeedback FAB is position:fixed bottom-right and overlaps any
   bottom-of-page content at phone widths — most visibly the Save button
   in score entry and the bottom-most chips in the waiting queue. Extra
   shell padding at the bottom gives the user scroll room to push that
   content above the FAB's footprint. */
@media (max-width: 599.98px) {
    .clubSession-dashboard-shell[b-l9cvewerkd] {
        padding-bottom: 4rem;
    }
}

.clubSession-kiosk-top[b-l9cvewerkd] {
    min-height: 2.55rem;
    border: 1px solid #bccadb;
    background: #e7edf5;
    border-radius: 0.7rem;
    padding: 0.3rem 0.45rem;
    margin-bottom: 0.4rem;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

/* #335: when MainLayout has floated the bare hamburger onto the page's top-left
   (kiosk routes, no banner), reserve room at the start of this row so the title
   clears the overlaid hamburger - the hamburger then reads as the first item on
   this shared top button line instead of owning a wasted line above it. */
/* Kiosk rework: this hamburger-clearance + sticky-row treatment only applies in kiosk
   mode (body.kiosk-mode), where MainLayout floats the bare hamburger onto this row. Off
   kiosk the session uses the normal app chrome (persistent sidebar / standard hamburger),
   so the row needs neither the left reserve nor the sticky pin. */
body.kiosk-mode .page--topbar-bare .clubSession-kiosk-top[b-l9cvewerkd] {
    /* 2.6rem (hamburger width) + 0.75rem (its own left margin) so the title fully clears the
       overlaid hamburger - without the margin term they overlapped by ~5px (qa). */
    padding-left: calc(2.6rem + 0.75rem);
    /* #390 (round 2): the hamburger is fixed so it survives scrolling on a short kiosk
       screen. Freeze this top row too (sticky) so the title/timestamp stay aligned with the
       pinned hamburger instead of scrolling up underneath it and overlapping. z-index sits
       below the hamburger's (.layout-top-bar = 20) so it stays clickable. */
    position: sticky;
    top: 0;
    z-index: 15;
}

.clubSession-kiosk-left[b-l9cvewerkd] {
    display: flex;
    align-items: center;
}

.clubSession-kiosk-note[b-l9cvewerkd] {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: #2e4f6d;
}

/* ado:1437 — THE SESSION TITLE IS DE-EMPHASISED, and the reason is the same one that
   took the club's name off the join line one round earlier, applied a level up:
   THE BOARD SPENDS ITS LEGIBILITY ON WHAT THE READER CANNOT ALREADY KNOW.

   Anybody in the hall knows which session they are at. The title's real audience is
   the ORGANISER browsing several sessions, and that happens up close on a tablet,
   never across a hall - so it only has to stay comfortably readable at arm's length,
   which 0.85rem bold is. It does not need hall legibility and nothing about it does.

   It sits between START TIME (0.78rem / 0.68rem label) and the credential, which is
   an existing hierarchy on this bar rather than a new one. The credential chip is now
   unambiguously the largest thing here, which is the whole point of the bar.

   IT STILL HAS TO CARRY THE BAR ALONE. When no code renders - an ended session, or a
   club with both codes off - this is the only content in the header. Checked at that
   state rather than assumed: see the committed captures. Keeping it BOLD is what
   holds that case; dropping the weight as well as the size is what would make an
   empty-looking bar. */
.clubSession-kiosk-note > strong[b-l9cvewerkd] {
    font-size: 0.85rem;
    font-weight: 700;
    color: #557693;
    line-height: 1.2;
}

.clubSession-kiosk-sub[b-l9cvewerkd] {
    color: #557693;
    font-size: 0.82rem;
}

/* #37: the session START-TIME, de-emphasised so it reads as session metadata, not the live
   clock. Deliberately smaller + muted vs the <strong> primary header (date | venue | name),
   with an explicit "Start time" label. Sits inline after the title on the shared header row. */
.clubSession-kiosk-starttime[b-l9cvewerkd] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
    color: #6b8199;
    font-size: 0.78rem;
    white-space: nowrap;
}

.clubSession-kiosk-starttime-label[b-l9cvewerkd] {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.68rem;
    font-weight: 600;
    color: #8199ac;
}

.clubSession-kiosk-starttime-value[b-l9cvewerkd] {
    font-weight: 600;
}

/* #430 claim code: players read this off the kiosk/tablet from a distance and
   type it into their phones - it must be legible across a sports hall, not
   body-copy sized (Mike UAT, 2026-07-04). */
.clubSession-claim-code[b-l9cvewerkd] {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    color: #2e4f6d;
    font-weight: 600;
    white-space: nowrap;
}

.clubSession-claim-code code[b-l9cvewerkd] {
    font-size: 1.45rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    color: #14532d;
    background: #f0fdf4;
    border: 1.5px solid #bbf7d0;
    border-radius: 0.4rem;
    padding: 0.1rem 0.55rem;
}

/* ── S7f (#29): the PERSISTENT, always-on header session code. The primary
   join entry — a player glances at the board from across the hall and types
   this into /join, no QR, no panel, no kiosk touch. Compact: a single header
   line that stays inside the tight header bar so the first court row keeps its
   #689 above-the-fold slot at 1280×853. Green-credential identity (reused from
   the S7a panel + the #430 claim-code chip); the code is chunked 3·3 and sized
   to the #430 hall-legible bar (~1.45rem) — big enough to read at distance,
   small enough for the header. Sits between the title and the QR chip; wraps
   with the whole header row at <=780px (the .clubSession-kiosk-top wrap rule),
   so on a phone it drops to its own line and stays legible. */
.clubSession-code-banner[b-l9cvewerkd] {
    flex: 0 1 auto;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    /* the label may wrap under the code on a squeezed header; the code chip never splits. */
    flex-wrap: wrap;
}

.clubSession-code-banner-hint[b-l9cvewerkd] {
    color: #557693;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.15;
    white-space: nowrap;
}

/* the destination is the actionable "where" — navy + bold. */
.clubSession-code-banner-dest[b-l9cvewerkd] {
    color: #0d2c55;
    font-weight: 800;
    white-space: nowrap;
}

/* the code itself — the thing read across the hall. Monospace + generous
   letter-spacing so Z/2, S/5, B/8 stay distinct at distance; green credential
   chip identical in family to the panel code + the #430 header chip. */
.clubSession-code-banner-code[b-l9cvewerkd] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    font-size: 1.45rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    line-height: 1;
    color: #14532d;
    background: #f0fdf4;
    border: 1.5px solid #bbf7d0;
    border-radius: 0.4rem;
    padding: 0.1rem 0.55rem;
    white-space: nowrap;
}

.clubSession-code-banner-group[b-l9cvewerkd] {
    white-space: nowrap;
}

/* ado:1437 — the CLUB JOIN CODE block, the board's default credential.

   THE BOARD IS A KIOSK SURFACE READ ACROSS A HALL, and legibility at distance is the
   whole point of it. Two tokens have to survive eight metres: the ADDRESS and the
   CODE. Everything else here is a second-pass read, for the player who has walked
   closer or already has their phone out.

   That is why epegboard.com is promoted out of hint size into the display class.
   Today's session banner sets epegboard.com/live at .85rem beside a 1.45rem code, and
   that worked because its reader already HAD the domain - six familiar characters
   after an address they knew. The walk-up has neither, and a code with no address is
   a code nobody can use.

   Wraps with the whole header row (.clubSession-kiosk-top) at <=780px, like the
   session banner, so on a phone it drops to its own line and stays legible. */
.clubSession-join-banner[b-l9cvewerkd] {
    flex: 0 1 auto;
    min-width: 0;
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    /* the sentence may wrap around the code chip on a squeezed header; the chip never splits. */
    flex-wrap: wrap;
}

/* the connective words - second-pass reading, deliberately quiet. */
.clubSession-join-banner-text[b-l9cvewerkd] {
    color: #557693;
    font-size: 0.86rem;
    font-weight: 600;
    line-height: 1.15;
}

/* the address: one of the two tokens that crosses the hall. Same navy as the session
   banner's destination, in the display class rather than at hint size. */
.clubSession-join-banner-dest[b-l9cvewerkd] {
    color: #0d2c55;
    font-weight: 800;
    font-size: 1.15rem;
    white-space: nowrap;
}

/* the code: the largest object on the block. Identical green-credential family to the
   session banner and the #430 chip, one size up (1.45rem -> 1.7rem) because it is now
   the ONLY credential competing for a glance rather than one of two, and because the
   header regained the space the "Live on your phone at..." label used. */
.clubSession-join-banner-code[b-l9cvewerkd] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    font-family: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;
    font-size: 1.7rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    line-height: 1;
    color: #14532d;
    background: #f0fdf4;
    border: 1.5px solid #bbf7d0;
    border-radius: 0.4rem;
    padding: 0.1rem 0.55rem;
    white-space: nowrap;
}

/* NOTE: there is no club-name rule here any more. The board's line named the club until
   the Owner's 2026-09-14 read (ado:1437 rev 26) cut it - the player knows which hall they
   are standing in, the code resolves its own club, and the confirmation screen names it.
   That removed the truncation, and with it the `vertical-align` outlier the cross-slice
   review found: an inline-block with `overflow: hidden` aligns on its overflow box, which
   sat a clipped name low in the sentence. Both are gone rather than fixed, which is the
   better outcome - the shortest line is also the one with no truncation to get wrong. */

/* Only rendered when BOTH codes are on the wall. Names the DESTINATION, not the
   credential - a player knows which of two things they want to do, not which of two
   nouns they want. Small and quiet: it is a disambiguator, not a heading. */
.clubSession-credential-label[b-l9cvewerkd] {
    color: #557693;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* Both-on is a deliberately-chosen state and nobody on the default ever sees it. The
   session stack drops a size so two labelled credentials have a chance of sharing the
   header row; a club that turned both on has accepted a taller header. */
.clubSession-join-banner + .clubSession-code-banner .clubSession-code-banner-code[b-l9cvewerkd] {
    font-size: 1.25rem;
}

/* ado:1437 — F2, AND IT TOOK A SCREENSHOT TO FIND IT.

   .clubSession-code-banner-hint is `white-space: nowrap`, which was right when its only
   content was the single short label "Live on your phone at epegboard.com/live". The
   both-on state gives it a LONGER string ("Go to epegboard.com/live. No account
   needed."), and an unwrappable flex item cannot shrink below its content: at 1280 the
   sentence ran straight THROUGH the kiosk action buttons - the settings cog and the
   fullscreen control drawn over the words "No account needed".

   Nothing caught it. Every assertion on this block is text, a count or a bounding box,
   and overlapping text passes all three: innerText is correct, the elements are present,
   and each box is individually fine. The UX plan named this as feasibility risk F2 and
   nobody had looked; the capture test beside this slice's E2E class is why somebody now
   has.

   Wrapping restores the shrink. Scoped to the adjacency so the DEFAULT single-credential
   banner - the one state with an automated fold assertion, and the one every club is on -
   keeps its nowrap and is untouched. */
.clubSession-join-banner + .clubSession-code-banner .clubSession-code-banner-hint[b-l9cvewerkd] {
    white-space: normal;
}

.clubSession-kiosk-actions[b-l9cvewerkd] {
    display: flex;
    /* stretch so the icon buttons match the tallest button (End session) rather
       than sizing to their own glyph's font-size. */
    align-items: stretch;
    gap: 0.35rem;
    /* ado:1437: room between the credential and the toolbar. The code chip butted up
       against the settings cog, and at that distance a chip touching a row of buttons
       reads as one of them. It is a CREDENTIAL, not a control - nothing in the block
       is tappable - and the gap is what says so. The row's own 0.45rem gap is right
       for button-to-button and too tight for this boundary. */
    margin-left: 0.9rem;
}

.top-icon-btn[b-l9cvewerkd] {
    width: 2.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.settings-cog-btn[b-l9cvewerkd] {
    font-size: 1.25rem;
    line-height: 1;
}

.fullscreen-toggle-btn[b-l9cvewerkd] {
    font-size: 1rem;
    line-height: 1;
}

.kiosk-menu-popover[b-l9cvewerkd] {
    position: relative;
    z-index: 10;
    width: min(280px, 92vw);
    margin: 0 0 0.45rem;
    border: 1px solid #c0ccd9;
    border-radius: 0.65rem;
    background: #eef3f9;
    box-shadow: 0 6px 16px rgba(21, 48, 75, 0.2);
    padding: 0.4rem;
    display: grid;
    gap: 0.3rem;
}

.kiosk-menu-link[b-l9cvewerkd] {
    text-align: left;
}

.kiosk-menu-link-sub[b-l9cvewerkd] {
    margin-left: 0.4rem;
}

.kiosk-help-group[b-l9cvewerkd] {
    display: grid;
    gap: 0.28rem;
    margin-top: 0.15rem;
}

.kiosk-help-group summary[b-l9cvewerkd] {
    list-style: none;
    cursor: pointer;
    color: #3a5976;
    font-weight: 700;
    padding: 0.2rem 0.15rem;
}

.kiosk-help-group summary[b-l9cvewerkd]::-webkit-details-marker {
    display: none;
}

.clubSession-settings-modal-backdrop[b-l9cvewerkd] {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Capping the modal at 90svh wasn't enough on iOS Safari: the backdrop
       still filled the LAYOUT viewport (extends behind the dynamic bottom
       URL bar), and `align-items: center` placed the modal's bottom edge
       (with its sticky Save button) past the visible safe area. Sizing the
       backdrop itself to 100svh keeps flex-centering within the always-
       visible viewport, so the Save button is reachable without scrolling
       past the URL bar. iOS 15.4+ uses svh; older browsers fall back to vh
       (same as the prior behaviour, no regression). */
    height: 100vh;
    height: 100svh;
    background: rgba(24, 35, 52, 0.38);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2000;
}

.clubSession-settings-modal[b-l9cvewerkd] {
    width: min(980px, 94vw);
    /* iOS Safari: 90vh refers to the LAYOUT viewport (includes the URL-bar
       zone), so a 90vh modal can extend behind the bottom browser chrome
       and hide the Save button. svh = small viewport height (URL bar
       always counted as visible) keeps the modal inside the safe area on
       iOS 15.4+. Older browsers ignore svh and fall back to vh. */
    max-height: 90vh;
    max-height: 90svh;
    /* #466: same structure as the #445 member-edit modal — the modal is a flex
       COLUMN (a pinned header + a single scrolling body + a pinned footer), NOT
       overflow-y:auto on the modal itself. The old approach scrolled the whole
       modal and pinned the header/footer with position:sticky; on a scroll-
       overflowing modal the settings controls slid UNDER the translucent header
       and Save/Reset footer (Mike's report). The scroll now lives on
       .clubSession-settings-modal-body alone, between the two pinned bars. */
    display: flex;
    flex-direction: column;
    background: #f8fbff;
    border: 1px solid #b6c8da;
    border-radius: 0.85rem;
    box-shadow: 0 14px 34px rgba(21, 48, 75, 0.24);
    padding: 0.8rem;
}

.clubSession-settings-modal-header[b-l9cvewerkd] {
    /* #466: pinned at the top while the body scrolls (was position:sticky on a
       scrolling modal — content slid behind it). flex:0 0 auto so it never
       shrinks or scrolls. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    /* Negative horizontal margin + matching padding lets the header background
       span the full modal width inside its padding. */
    margin: -0.8rem -0.8rem 0.6rem;
    padding: 0.55rem 0.8rem;
    border-bottom: 1px solid #c4d2e0;
}

.clubSession-settings-modal-header h2[b-l9cvewerkd] {
    margin: 0;
    font-size: 1.1rem;
    color: #345674;
}

.clubSession-settings-modal-body[b-l9cvewerkd] {
    /* #466: the ONLY scroll region now (the modal itself no longer scrolls, so
       the header stays pinned above and the actions footer below). flex:1 1 auto
       takes the remaining height; min-height:0 is REQUIRED — a flex item defaults
       to min-height:auto, which refuses to shrink below its content and would
       push the whole modal past the viewport instead of scrolling here. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0.7rem 0;
}

/* #1017: the in-session jump-nav layout inside the modal body. A two-column grid — the shared
   SettingsAnchorNav on the left, the editor on the right — when the modal is wide enough. At
   narrow/kiosk-portrait widths (<=820px, matching the component's own chip-row breakpoint) it
   collapses to a single column so the nav (now a chip row) sits ABOVE the editor and never steals
   width or forces a horizontal scroll. ::deep reaches the SettingsAnchorNav's rendered root, which
   is a child component (scoped CSS otherwise wouldn't touch it). */
.clubSession-settings-layout[b-l9cvewerkd] {
    display: grid;
    grid-template-columns: 11.5rem 1fr;
    gap: 0.85rem;
    align-items: start;
}

.clubSession-settings-editor[b-l9cvewerkd] {
    min-width: 0;
}

@media (max-width: 820px) {
    .clubSession-settings-layout[b-l9cvewerkd] {
        grid-template-columns: 1fr;
        gap: 0.5rem;
    }
}

.clubSession-settings-modal-actions[b-l9cvewerkd] {
    /* #466: pinned at the bottom while the body scrolls (was position:sticky on a
       scrolling modal — content slid behind the Save/Reset buttons). flex:0 0 auto
       so the footer never shrinks or scrolls. Negative horizontal margin + matching
       padding lets the footer background span the full modal width like the header. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    background: #f8fbff;
    border-top: 1px solid #c4d2e0;
    margin: 0.7rem -0.8rem -0.8rem;
    padding: 0.6rem 0.8rem max(0.6rem, env(safe-area-inset-bottom));
}

/* #401: save-confirmation message in the settings modal footer. Mirrors the
   ClubSessionSettingsTab's .settings-message (scoped there, so re-declared here
   because Blazor CSS isolation does not share component styles). */
.settings-message[b-l9cvewerkd] {
    color: #4f6177;
    font-size: 0.92rem;
}

.clubSession-toolbar-tabs[b-l9cvewerkd] {
    display: flex;
    gap: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: thin;
    border-bottom: 1px solid #9fb6cc;
    margin-bottom: var(--fold-band-gap, 0.45rem);
    padding-left: 0.15rem;
    /* BL-077: position context for the scroll-cue gradient overlay below. */
    position: relative;
}

/* BL-077: fading right-edge gradient that signals horizontal scroll on
   mobile where the tab row doesn't fit (Completed Games / Payments etc.
   were getting cut off with no visual indication more tabs existed).
   Only renders on narrow screens; desktop tab row already fits in full. */
@media (max-width: 720px) {
    .clubSession-toolbar-tabs[b-l9cvewerkd]::after {
        content: "";
        position: sticky;
        right: 0;
        top: 0;
        flex: 0 0 1.4rem;
        height: 100%;
        margin-left: -1.4rem;
        background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(232, 238, 245, 0.9) 65%, rgba(232, 238, 245, 1) 100%);
        pointer-events: none;
    }
}

.clubSession-toolbar-tabs[b-l9cvewerkd]::-webkit-scrollbar {
    height: 6px;
}

.clubSession-toolbar-tabs[b-l9cvewerkd]::-webkit-scrollbar-thumb {
    background: rgba(159, 182, 204, 0.55);
    border-radius: 3px;
}

.clubSession-toolbar-tabs .nav-item[b-l9cvewerkd] {
    margin-bottom: -1px;
    flex: 0 0 auto;
}

.clubSession-toolbar-tabs .nav-link[b-l9cvewerkd] {
    border: 1px solid #b3c6da;
    border-bottom-color: #a9bfd3;
    border-radius: 0.45rem 0.45rem 0 0;
    color: #5a7691;
    background: #e8eef5;
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.15;
    padding: 0.35rem 0.7rem;
    margin-right: 0.28rem;
}

.clubSession-toolbar-tabs .nav-link .tab-label[b-l9cvewerkd] {
    display: inline-flex;
    align-items: center;
    gap: 0.38rem;
}

.clubSession-toolbar-tabs .nav-link .tab-icon[b-l9cvewerkd] {
    width: 0.92rem;
    height: 0.92rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    overflow: visible;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-pegboard[b-l9cvewerkd] {
    color: #2d83cf;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-attendees[b-l9cvewerkd] {
    color: #2eaf74;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-games[b-l9cvewerkd] {
    color: #8c5bd4;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-payments[b-l9cvewerkd] {
    color: #c98a1a;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-insights[b-l9cvewerkd] {
    color: #d15a88;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-settings[b-l9cvewerkd] {
    color: #4d8b97;
}

.clubSession-toolbar-tabs .nav-link .tab-icon-diagnostics[b-l9cvewerkd] {
    color: #cc5a44;
}

/* #756: the Recap tab (takes the Pegboard board tab's slot once the session has ended). */
.clubSession-toolbar-tabs .nav-link .tab-icon-recap[b-l9cvewerkd] {
    color: #1b6ec2;
}

.clubSession-toolbar-tabs .nav-link.active[b-l9cvewerkd] {
    background: linear-gradient(180deg, #5f85ad 0%, #4f749a 100%);
    color: #f4f8fc;
    border-color: #436a90;
    border-bottom-color: #d2dbe7;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset;
}

.clubSession-toolbar-tabs .nav-link.active .tab-icon[b-l9cvewerkd] {
    filter: brightness(1.12);
}

[b-l9cvewerkd] .courts-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(13rem, 1fr));
    gap: var(--fold-band-gap, 0.45rem);
    margin-bottom: var(--fold-band-gap, 0.45rem);
}

/* #848/#817 Slice 1 (court-count reflow): the 5-court single-row fit. auto-fit lays as
   many legible tracks as the row allows and COLLAPSES the phantom empty tracks that made
   court 5 stretch tall over empty green in the old fixed-4-column grid; the 1fr expands
   the five occupied tracks to fill the row. On 1280+ boards (~1030px+ content) five
   ~11rem-floor cards fit one row, so the operational band returns to its full-width
   lower-grid form and Score Entry is visible without scrolling (#848). Applied ONLY when
   PegboardTab adds .courts-grid-fit (exactly 5 courts), so <=4 / 6-8 court grids are
   unchanged. Single-class selector at the SAME specificity as the base .courts-grid rule
   above and placed AFTER it, so it wins at >=920px by source order; the narrow-width
   media rules (repeat(2,...) <=919.98px, 1fr <=780px) are later still in the file and
   keep winning at those widths - so the phone/small-tablet stacking is unchanged and no
   media block needs editing. */
[b-l9cvewerkd] .courts-grid-fit {
    grid-template-columns: repeat(auto-fit, minmax(var(--fold-court-col-min, 11rem), 1fr));
}

[b-l9cvewerkd] .court-card {
    background: linear-gradient(180deg, #5db061 0%, #4b9a50 100%);
    color: #fff;
    border-radius: 0.85rem;
    border: 1px solid #75b978;
    padding: 0.45rem;
    min-height: var(--fold-court-min, 14.5rem);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
    /* #930: flex COLUMN so an empty card stretched by the grid to match a taller
       populated neighbour (grid rows are `auto`, items `align-self:stretch`) can
       hand its extra height to .court-empty-actions (flex:1 1 auto below), which
       re-centres the "Pick and Start" button. Without this the card is a plain
       block and the fixed-min-height actions block sits top-aligned in the gap. */
    display: flex;
    flex-direction: column;
}

[b-l9cvewerkd] .court-card-empty {
    min-height: var(--fold-court-min, 14.5rem);
}

/* On phones the courts stack vertically, so four full-height empty courts
   eat ~900px before the user reaches Next Game Prep / Auto-pick. Drop empty
   courts to a compact height that still comfortably holds the "Pick and
   Start" button. In-progress courts keep their full size — the actual game
   state is what's worth seeing.
   The .court-empty-actions inner wrapper has its own 11.8rem min-height
   (used to vertically centre the button on desktop's tall cards). That
   wins over .court-card-empty's min-height because the inner element's
   intrinsic size pushes the parent. So we have to flatten BOTH on mobile. */
@media (max-width: 720px) {
    [b-l9cvewerkd] .court-card-empty {
        min-height: 0;
    }

    [b-l9cvewerkd] .court-card-empty .court-empty-actions {
        min-height: 0;
        padding: 0.2rem 0;
    }
}

[b-l9cvewerkd] .court-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.35rem;
}

[b-l9cvewerkd] .court-header-title {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

[b-l9cvewerkd] .court-number {
    font-size: 1.2rem;
    font-weight: 700;
    color: #f1fbf3;
}

[b-l9cvewerkd] .game-pick-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    background: #cf2029;
    border: 1px solid #b3161e;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0;
    flex: 0 0 auto;
}

[b-l9cvewerkd] .game-pick-indicator-inline {
    margin-left: 0.3rem;
    vertical-align: middle;
}

[b-l9cvewerkd] .court-actions {
    display: flex;
    gap: 0.3rem;
}

[b-l9cvewerkd] .court-team-row {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    border: 1px solid rgba(255, 255, 255, 0.45);
    background: rgba(255, 255, 255, 0.1);
    border-radius: 0.5rem;
    padding: 0.2rem 0.35rem;
    margin-bottom: 0.25rem;
}

[b-l9cvewerkd] .court-team-name {
    font-weight: 600;
    font-size: 0.88rem;
}

[b-l9cvewerkd] .court-member-link {
    border: none;
    background: transparent;
    color: inherit;
    text-align: left;
    padding: 0;
    cursor: pointer;
}

[b-l9cvewerkd] .court-member-link:hover {
    text-decoration: underline;
}

[b-l9cvewerkd] .court-score-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    column-gap: 0.4rem;
    margin: 0.35rem 0;
    font-weight: 700;
    font-size: 0.82rem;
    color: #ecfaee;
}

[b-l9cvewerkd] .court-score-row > span:first-child {
    justify-self: start;
}

[b-l9cvewerkd] .court-score-row > span:last-child {
    justify-self: end;
}

[b-l9cvewerkd] .court-end-btn {
    min-width: 3.4rem;
}

[b-l9cvewerkd] .court-empty-actions {
    display: flex;
    align-items: center;
    justify-content: center;
    /* #930: grow to fill the card's height (which the grid may stretch to match a
       taller populated neighbour) so the button stays vertically centred; the
       min-height is now a FLOOR for the empty-card-only-row case, not a fixed size. */
    flex: 1 1 auto;
    min-height: var(--fold-court-empty-min, 11.8rem);
}

[b-l9cvewerkd] .clubSession-lower-grid {
    display: grid;
    /* BL-081: Sitting Out narrowed to a single-avatar column (~9rem). The
       freed width goes to Waiting (the busier panel) via its 1.1fr.
       2026-05-25 regression fix: DOM order is Prep / Waiting / Sitting Out /
       Score Entry, so Sitting Out is the THIRD column (9rem) and Score Entry
       is the FOURTH (15.5rem). Previous template had these swapped, which
       squeezed Score Entry into 144px and hid the Save button behind the
       parent's overflow-x: hidden — reported live PROD by Mike. */
    grid-template-columns: minmax(16.5rem, 16.5rem) minmax(15rem, 1.1fr) minmax(9rem, 9rem) minmax(15.5rem, 15.5rem);
    gap: var(--fold-band-gap, 0.45rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-sittingout-collapsed {
    grid-template-columns: minmax(16.5rem, 16.5rem) minmax(15rem, 1.2fr) minmax(17rem, 17rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-no-score {
    /* BL-081: same Sitting Out narrowing as the default grid above. */
    grid-template-columns: minmax(16.5rem, 16.5rem) minmax(15rem, 1.1fr) minmax(9rem, 9rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed {
    grid-template-columns: minmax(16.5rem, 16.5rem) minmax(15rem, 1.1fr);
}

/* #689 (Dunstable): when the single prep stack is inlined into the courts grid's free
   last-row slot (courtCount > 4 && % 4 != 0 && one configured prep panel — see
   PegboardTab), the lower grid loses its first (16.5rem prep) column. Same positional-
   template convention as the BL-081 combos above — the templates minus that first
   column. The no-score + sittingout-collapsed case uses the full THREE-class selector
   so it outranks (not merely ties with) the existing two-class combo rule above; the
   two-class rules below win their ties by source order. */
[b-l9cvewerkd] .clubSession-lower-grid-prep-inline {
    grid-template-columns: minmax(15rem, 1.1fr) minmax(9rem, 9rem) minmax(15.5rem, 15.5rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-sittingout-collapsed {
    grid-template-columns: minmax(15rem, 1.2fr) minmax(17rem, 17rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-no-score {
    grid-template-columns: minmax(15rem, 1.1fr) minmax(9rem, 9rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed {
    grid-template-columns: minmax(15rem, 1.1fr);
}

/* #689 ops-inline: on 5/6-court boards BOTH prep and waiting move into the courts
   grid (>=2 free last-row slots), leaving only Sitting Out / Score Entry down here.
   Same combo/specificity discipline as the prep-inline set above. justify-content
   keeps the two narrow panels left-aligned rather than letting stray tracks stretch. */
[b-l9cvewerkd] .clubSession-lower-grid-ops-inline {
    grid-template-columns: minmax(9rem, 9rem) minmax(15.5rem, 15.5rem);
    justify-content: start;
}

[b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-sittingout-collapsed {
    grid-template-columns: minmax(17rem, 17rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-no-score {
    grid-template-columns: minmax(9rem, 9rem);
}

[b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed {
    /* Both panels absent AND both surfaces inline: the lower grid is empty. */
    grid-template-columns: 1fr;
}

/* #718: a CHILDLESS lower grid (ops-inline with no pending scores and nobody
   sitting out - the common live 5/6-court shape) still stacked the courts
   grid's bottom margin + the shell padding into ~13px of phantom scroll below
   the last real row. Nothing to show = no band. (:has(*) is element-children
   only, so Blazor comment/whitespace nodes don't defeat it.) */
[b-l9cvewerkd] .clubSession-lower-grid:not(:has(*)) {
    display: none;
}

/* #689: the inlined waiting panel spans the remaining free slots - 2 on a 5-court
   board, 1 (its natural track) on a 6-court board. The span only exists at the
   4-column breakpoint; below 920px the panel takes a full row of whatever column
   count applies (1 / -1 is safe at any track count, unlike span 2 which would
   CREATE an implicit column in a 1-column grid). */
@media (min-width: 920px) {
    [b-l9cvewerkd] .waiting-panel-inline-span2 {
        grid-column: span 2;
    }
}

@media (max-width: 919.98px) {
    [b-l9cvewerkd] .waiting-panel-inline {
        grid-column: 1 / -1;
    }
}

/* #689: inside a court-row slot the waiting panel can be much narrower than in the
   full-width lower grid - let its toolbar wrap instead of clipping (the base toolbar
   only wraps below 780px). */
[b-l9cvewerkd] .waiting-panel-inline .waiting-toolbar {
    flex-wrap: wrap;
}

/* #689: cap the inlined waiting panel's queue so a LONG queue scrolls inside the
   panel instead of growing the shared court row past the fold (probe: 14 waiting at
   the 1280x853 effective viewport pushed the row to 449px and re-broke the fold).
   The front of the queue - the next-up players the operator works from - is always
   visible; deeper positions scroll. 12.5rem keeps the panel at roughly the prep
   panel's height, which drives the row anyway. */
[b-l9cvewerkd] .waiting-panel-inline .waiting-member-list {
    max-height: var(--fold-waiting-cap, 12.5rem);
    overflow-y: auto;
}

[b-l9cvewerkd] .clubSession-panel {
    background: #edf3fa;
    border: 1px solid #b9c9da;
    border-radius: 0.75rem;
    padding: var(--fold-panel-pad, 0.6rem);
    min-width: 0;
}

[b-l9cvewerkd] .clubSession-panel h2 {
    margin: 0 0 0.45rem;
    color: #355775;
    font-size: 0.98rem;
    font-weight: 700;
}

/* Prep panels: soft amber wash so "next game being assembled" reads as
   in-progress (traffic-light amber), visually distinct from the pale-blue
   Waiting Members / Sitting Out panels. */
[b-l9cvewerkd] .clubSession-panel.clubSession-panel-prep {
    background: #fff8e1;
    border-color: #e9c46a;
}

[b-l9cvewerkd] .clubSession-panel.clubSession-panel-prep h2 {
    color: #7a5a1f;
}

[b-l9cvewerkd] .clubSession-panel-prep .prep-slot {
    background: #fffbeb;
    border-color: #e6cf90;
}

[b-l9cvewerkd] .clubSession-panel-prep .prep-slot-empty {
    background: #fff3c4;
}

[b-l9cvewerkd] .clubSession-panel-prep .prep-par-score {
    color: #7a5a1f;
}

[b-l9cvewerkd] .prep-panel-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.45rem;
}

[b-l9cvewerkd] .prep-panel-title {
    margin: 0;
}

[b-l9cvewerkd] .prep-title-info-btn {
    margin-left: auto;
    width: 1.65rem;
    height: 1.65rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid #9fb3c7;
    border-radius: 999px;
    background: #f7fbff;
    color: #4a6a88;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

[b-l9cvewerkd] .prep-title-info-btn:hover:not(:disabled) {
    background: #e7f1fb;
    border-color: #7f9fbe;
    color: #2f5170;
}

[b-l9cvewerkd] .prep-title-info-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 0.18rem rgba(74, 106, 136, 0.2);
}

[b-l9cvewerkd] .prep-title-info-btn:disabled {
    opacity: 0.45;
    cursor: default;
}

[b-l9cvewerkd] .prep-title-info-btn.no-suggestion {
    opacity: 0.25;
    border-color: transparent;
    background: transparent;
    color: #9fb3c7;
}

[b-l9cvewerkd] .prep-title-info-btn.has-suggestion {
    background: #e7f1fb;
    border-color: #5b8db8;
    color: #2f5170;
    box-shadow: 0 0 0 0.12rem rgba(91, 141, 184, 0.25);
}

[b-l9cvewerkd] .clubSession-panel-wide {
    min-width: 0;
}

[b-l9cvewerkd] .prep-panel-stack {
    display: grid;
    gap: 0.45rem;
    align-content: start;
    min-width: 0;
}

[b-l9cvewerkd] .prep-layout {
    display: grid;
    gap: var(--fold-prep-gap, 0.35rem);
}

[b-l9cvewerkd] .prep-slot {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    min-width: 0;
    min-height: var(--fold-prep-slot-min, 2.3rem);
    border-radius: 1.2rem;
    border: 1px solid #b8c9db;
    background: #f7fbff;
    padding: 0.18rem 0.32rem;
    overflow: hidden;
    transition: border-color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
}

[b-l9cvewerkd] .prep-slot-empty {
    border-style: dashed;
    background: #eff5fb;
}

[b-l9cvewerkd] .prep-slot-interactive {
    cursor: pointer;
}

[b-l9cvewerkd] .prep-slot .prep-chip {
    width: 100%;
    min-width: 0;
    border: none;
    background: transparent;
    padding: 0.12rem 0.2rem;
}

[b-l9cvewerkd] .prep-divider {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 0.35rem;
}

[b-l9cvewerkd] .prep-divider-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

[b-l9cvewerkd] .prep-divider-actions-left {
    justify-self: start;
}

[b-l9cvewerkd] .prep-divider-actions-right {
    justify-self: end;
}

[b-l9cvewerkd] .prep-par-score {
    justify-self: center;
    color: #355775;
    font-size: 0.8rem;
    font-weight: 700;
}

[b-l9cvewerkd] .prep-btn {
    min-width: 6.5rem;
}

/* #718 tier 3 swaps Auto-pick's label for the short form; hidden elsewhere. */
[b-l9cvewerkd] .prep-btn-label-short {
    display: none;
}

[b-l9cvewerkd] .prep-discipline-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    padding: 0.25rem 0;
}

[b-l9cvewerkd] .prep-discipline-chip {
    padding: 0.15rem 0.65rem;
    font-size: 0.78rem;
    line-height: 1.1;
}

[b-l9cvewerkd] .prep-discipline-chip.is-active {
    box-shadow: 0 0 0 1px rgba(53, 87, 117, 0.35) inset;
}

[b-l9cvewerkd] .prep-discipline-infeasible {
    margin: 0.15rem 0 0.25rem;
    color: #b32d2e;
    font-size: 0.78rem;
    line-height: 1.2;
}

/* ADR 0007 (#985 E4): Advisory warning + CoordinatorApproval approval-needed cues on a prep panel. */
[b-l9cvewerkd] .prep-policy-warning,
[b-l9cvewerkd] .prep-policy-approval-needed {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin: 0.2rem 0 0.35rem;
    padding: 0.35rem 0.5rem;
    border-radius: 0.5rem;
    font-size: 0.78rem;
    line-height: 1.3;
}

[b-l9cvewerkd] .prep-policy-warning {
    background: #fff6e5;
    border: 1px solid #f0c674;
    color: #7a5300;
}

[b-l9cvewerkd] .prep-policy-approval-needed {
    background: #fdeee9;
    border: 1px solid #e6a48c;
    color: #8a3213;
}

[b-l9cvewerkd] .prep-policy-warning-ic {
    flex: 0 0 auto;
    font-weight: 700;
    line-height: 1.1;
}

/* SPEC-27 S3 — the clickable ⚠ toggle that reveals the queue-window "why" + rings the slot. Inherits the
   amber banner colour; a ≥40px touch target for courtside kiosk taps without dominating the compact banner. */
[b-l9cvewerkd] .prep-policy-warning-toggle {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.5rem;
    min-height: 2.5rem;
    margin: -0.35rem 0;
    padding: 0;
    border: none;
    background: transparent;
    color: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    line-height: 1.1;
    cursor: pointer;
}

[b-l9cvewerkd] .prep-policy-warning-toggle:focus-visible {
    outline: 2px solid #7a5300;
    outline-offset: 1px;
    border-radius: 0.35rem;
}

/* SPEC-27 S3 (ux nit #3) — a subtle circle on hover/focus/active so the 40px tap area is discoverable. */
[b-l9cvewerkd] .prep-policy-warning-toggle:hover,
[b-l9cvewerkd] .prep-policy-warning-toggle:active {
    background: rgba(232, 89, 12, 0.14);
    border-radius: 50%;
}

/* SPEC-27 S3 — the revealed reason line(s): one per out-of-window player, at normal weight below the banner
   sentence (which itself carries the bold rule name). */
[b-l9cvewerkd] .prep-policy-reason {
    display: block;
    margin-top: 0.25rem;
    font-weight: 400;
}

[b-l9cvewerkd] .prep-policy-reason-line {
    display: block;
}

/* SPEC-27 S3 — ring the offending prep slot. The Next-Game card is amber end-to-end (every slot has a
   tan #e6cf90 border on a cream bg), so a tan ring is invisible: this uses a DISTINCT saturated orange
   (#e8590c, not another tan), a heavier 3px ring, AND a non-colour ⚠ corner badge (::after) — colour alone
   is too weak inside an already-amber card. Selector carries the panel prefix (.clubSession-panel-prep
   .prep-slot.prep-slot-flagged = specificity 0,3,0) so it beats the baseline `.clubSession-panel-prep
   .prep-slot` amber rule (0,2,0) that was masking the previous single-class ring. */
[b-l9cvewerkd] .clubSession-panel-prep .prep-slot.prep-slot-flagged {
    border-color: #e8590c;
    background: #ffe3d1;
    box-shadow: 0 0 0 3px #e8590c, 0 1px 6px rgba(216, 72, 15, 0.45);
    /* let the corner badge pop outside the slot (the slot is otherwise overflow:hidden) */
    overflow: visible;
    z-index: 1;
}

[b-l9cvewerkd] .clubSession-panel-prep .prep-slot.prep-slot-flagged::after {
    content: "\26A0"; /* ⚠ — the non-colour cue */
    position: absolute;
    top: -0.5rem;
    right: -0.35rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.35rem;
    height: 1.35rem;
    background: #e8590c;
    color: #fff;
    border-radius: 50%;
    font-size: 0.82rem;
    line-height: 1;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    z-index: 3;
    pointer-events: none;
}

[b-l9cvewerkd] .prep-btn-approve {
    /* the warning-weight Start replacement stays legible on the board's dark prep row */
    font-weight: 600;
}

[b-l9cvewerkd] .chip-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

[b-l9cvewerkd] .waiting-member-list {
    min-height: 4.25rem;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

[b-l9cvewerkd] .sittingout-panel-compact {
    padding: 0.45rem;
    align-content: center;
    width: 100%;
    max-width: 6.75rem;
    justify-self: end;
}

[b-l9cvewerkd] .sittingout-empty-state {
    min-height: 4.1rem;
    border: 1px dashed #9cb6ce;
    border-radius: 0.6rem;
    background: #f3f8fd;
    color: #4c6781;
    font-size: 0.8rem;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0.3rem;
}

[b-l9cvewerkd] .prep-chip,
[b-l9cvewerkd] .waiting-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border-radius: 999px;
    padding: 0.22rem 0.5rem;
    border: 1px solid #a8bcd0;
    background: #f7fbff;
    color: #32516d;
    font-size: 0.82rem;
    font-weight: 600;
}

[b-l9cvewerkd] .prep-chip-empty {
    color: #67839d;
    background: transparent;
    border: none;
    font-weight: 600;
}

/* #475: the empty-slot prompt is a button (it opens the assignable-players dropdown when nothing
   is armed). Strip button chrome so it reads as the plain prompt text it replaced, full-width and
   left-aligned to fill the slot, with a pointer affordance. */
[b-l9cvewerkd] .prep-chip-empty-btn {
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
    padding: 0.12rem 0.2rem;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

[b-l9cvewerkd] .prep-player-name.locked {
    font-style: normal;
    font-weight: 700;
}

[b-l9cvewerkd] .prep-player-name.unlocked {
    font-style: italic;
    font-weight: 500;
}

[b-l9cvewerkd] .prep-player-link {
    border: none;
    background: transparent;
    color: inherit;
    padding: 0;
    text-align: left;
    cursor: pointer;
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-l9cvewerkd] .prep-player-link:hover {
    text-decoration: underline;
}

/* #460: one-action substitute dropdown — large touch rows for tablet/kiosk use,
   anchored to the clicked slot, styled to the prep panel's visual language.
   UAT (#460): rendered position:fixed and JS-positioned via
   clubSessionDashboard.positionPopover (the same viewport-aware positioner the
   score-entry popover uses), so it auto-flips ABOVE when a low slot has no room
   below and pins-with-internal-scroll when neither side fits — instead of the old
   position:absolute that ran off the bottom of the viewport for low slots.
   visibility:hidden by default so it never flashes at the wrong coordinates before
   the positioner runs; positionPopover flips it to visible. max-height + overflow-y
   make the pin-and-scroll fallback (and any long replacement list) scroll internally. */
[b-l9cvewerkd] .prep-sub-dropdown {
    position: fixed;
    visibility: hidden;
    top: 0;
    left: 0;
    z-index: 1200;
    width: 14rem;
    max-width: calc(100vw - 16px);
    max-height: 16rem;
    overflow-y: auto;
    background: #ffffff;
    border: 1px solid #9fb3c7;
    border-radius: 0.7rem;
    box-shadow: 0 0.5rem 1.1rem rgba(33, 58, 83, 0.22);
    padding: 0.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

[b-l9cvewerkd] .prep-sub-heading {
    padding: 0.2rem 0.5rem 0.1rem;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #6a8298;
}

[b-l9cvewerkd] .prep-sub-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    min-height: 2.6rem;
    padding: 0.3rem 0.5rem;
    border: none;
    border-radius: 0.5rem;
    background: transparent;
    color: #2f5170;
    font-size: 0.9rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

[b-l9cvewerkd] .prep-sub-item:hover,
[b-l9cvewerkd] .prep-sub-item:focus-visible {
    background: #e7f1fb;
    outline: none;
}

[b-l9cvewerkd] .prep-sub-item-profile {
    border-bottom: 1px solid #e2eaf2;
    border-radius: 0.5rem 0.5rem 0 0;
    color: #4a6a88;
}

[b-l9cvewerkd] .prep-sub-item-icon {
    width: 1.9rem;
    text-align: center;
    font-size: 1.05rem;
}

[b-l9cvewerkd] .prep-sub-item-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-l9cvewerkd] .prep-sub-empty {
    padding: 0.5rem 0.6rem;
    color: #6a8298;
    font-size: 0.82rem;
    font-weight: 600;
}

[b-l9cvewerkd] .prep-lock-indicator {
    width: 1.65rem;
    height: 1.65rem;
    min-width: 1.65rem;
    min-height: 1.65rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    line-height: 1;
    font-weight: 700;
    color: #1f3f5b;
    border: 1px solid #7fa5c5;
    border-radius: 999px;
    padding: 0;
    background: #eef5fc;
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease, color 0.12s ease;
}

[b-l9cvewerkd] .prep-lock-indicator:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 1px 0 rgba(16, 48, 74, 0.18);
}

[b-l9cvewerkd] .prep-lock-indicator:focus-visible {
    outline: 2px solid #2f7cc1;
    outline-offset: 1px;
}

[b-l9cvewerkd] .prep-lock-indicator.is-locked {
    background: #c9def2;
    border-color: #567da2;
    color: #103450;
}

[b-l9cvewerkd] .prep-lock-indicator.is-unlocked {
    background: #ffffff;
    border-color: #8db0cf;
    color: #456a8c;
}

[b-l9cvewerkd] .prep-lock-indicator:disabled {
    opacity: 0.45;
    cursor: default;
}

[b-l9cvewerkd] .prep-slot-remove-btn {
    width: 1.45rem;
    height: 1.45rem;
    min-width: 1.45rem;
    min-height: 1.45rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.25rem;
    padding: 0;
    line-height: 1;
    font-size: 1.05rem;
    font-weight: 600;
    color: #6c2828;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.12s ease, border-color 0.12s ease;
}

[b-l9cvewerkd] .prep-slot-remove-btn:hover:not(:disabled),
[b-l9cvewerkd] .prep-slot-remove-btn:focus-visible {
    background: #fbe4e4;
    border-color: #e0a3a3;
    outline: none;
}

[b-l9cvewerkd] .prep-slot-remove-btn:disabled {
    opacity: 0.35;
    cursor: default;
}


/* SPEC-32 I4-S1 (#670), R-I2-44.1: the two INKS here now read the shared tokens.

   These were the same two literals the partnership report defined for itself and the profile's
   counterpart tables now need — the same fact (a person's gender) rendered as the same colour on
   three unrelated surfaces, written out three times. The values are unchanged to the byte; only the
   definition site moved, to app.css's :root. A ::deep-scoped rule can read a custom property because
   properties inherit through the cascade regardless of the scoping attribute.

   THE BACKGROUNDS AND BORDERS ARE NOT TOKENS AND ARE NOT MEANT TO BE. They are this chip's own tinted
   surface, used nowhere else; only the ink is the shared datum. Nor is the `.selected` pair below —
   #173c61 / #5d2344 is a darker STATE of this chip, not the shared name ink, and giving it a token
   would invent product vocabulary for a decision nobody has taken. */
[b-l9cvewerkd] .waiting-chip.gender-male,
[b-l9cvewerkd] .prep-chip.gender-male,
[b-l9cvewerkd] .court-team-row.gender-male {
    background: #dfeeff;
    border-color: #8fb6e0;
    color: var(--gender-name-male);
}

[b-l9cvewerkd] .waiting-chip.gender-female,
[b-l9cvewerkd] .prep-chip.gender-female,
[b-l9cvewerkd] .court-team-row.gender-female {
    background: #ffe4f3;
    border-color: #e3a4c7;
    color: var(--gender-name-female);
}

[b-l9cvewerkd] .player-avatar.gender-male {
    background: #2f78c5;
}

[b-l9cvewerkd] .player-avatar.gender-female {
    background: #cc5b98;
}

[b-l9cvewerkd] .waiting-chip-btn {
    cursor: pointer;
}

[b-l9cvewerkd] .waiting-chip-btn.selected {
    border-color: #355775;
    color: #18344e;
    box-shadow: inset 0 0 0 2px rgba(24, 52, 78, 0.28), 0 0 0 3px rgba(79, 116, 154, 0.18);
}

[b-l9cvewerkd] .waiting-chip-btn.gender-male.selected {
    background: #cfe5ff;
    border-color: #2f6eaa;
    color: #173c61;
}

[b-l9cvewerkd] .waiting-chip-btn.gender-female.selected {
    background: #ffd7eb;
    border-color: #b85f8f;
    color: #5d2344;
}

[b-l9cvewerkd] .waiting-chip-muted {
    opacity: 0.62;
    filter: saturate(0.6);
}

/* #306: 1-based queue-position badge, rendered as the first child of each waiting
   chip (to the LEFT of the avatar/name) like a traditional pegboard peg number.
   Deliberately subordinate to the name - a small, neutral circular lozenge so it
   reads as an ordinal marker, not a highlight. Sits a touch smaller than the
   avatar; the chip's own flex gap spaces it from the avatar. */
[b-l9cvewerkd] .waiting-chip-pos {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 999px;
    background: #e7eef6;
    border: 1px solid #c2d0df;
    /* #445c77 on the #e7eef6 badge background = ~5.9:1, clears WCAG AA (4.5:1)
       for this small/bold ordinal even on a glare-prone kiosk panel. */
    color: #445c77;
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1;
    letter-spacing: 0;
}

[b-l9cvewerkd] .waiting-status-tag {
    margin-left: 0.1rem;
    border: 1px solid #b3c1cf;
    border-radius: 999px;
    background: #eef3f8;
    color: #587088;
    font-size: 0.68rem;
    line-height: 1;
    padding: 0.13rem 0.35rem;
    font-weight: 700;
}

/* #600 slice 2: the "held" tag on a muted waiting chip for a member held for a special
   request. Recoloured to the sticky/lock blue so "held for a request" reads as the same
   intent-object blue as a sticky pair, distinct from the neutral in-prep tag. */
[b-l9cvewerkd] .waiting-status-tag-held {
    border-color: #8fb6e0;
    background: #eaf3fc;
    color: #1f4b76;
}

/* S2 (#67): the combined sticky-pair pill in the live waiting queue. A designated,
   both-present sticky pair shows as ONE pill — two overlapping avatars + a link
   glyph + both names + the single (later-member) queue-position number — so it
   reads as "these two go together". Display-only; managed in Session settings.
   Palette mirrors the sticky/lock blue used on the court lock badge + the mockup
   (#eaf3fc bg / #8fb6e0 border / #1f4b76 ink). Inherits .waiting-chip's flex shell. */
[b-l9cvewerkd] .waiting-chip-sticky {
    background: #eaf3fc;
    border-color: #8fb6e0;
    color: #1f4b76;
    cursor: default;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}

[b-l9cvewerkd] .waiting-chip-duo {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}

/* #601: on a sticky pair the two avatars are individually tap-selectable. Each avatar
   is wrapped in a real button with a >=40px hit-box (kiosk finger-safe) even though the
   avatar glyph stays its small size; the padding grows the tappable area without moving
   the visible cluster. A slightly wider gap between the two buttons keeps the -0.4rem
   avatar overlap from making the two targets ambiguous to a finger (F3). The selected
   avatar carries the same inset ring the single chip uses. */
[b-l9cvewerkd] .waiting-chip-avatar-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    min-height: 40px;
    padding: 0.2rem;
    border: none;
    background: transparent;
    border-radius: 999px;
    cursor: pointer;
    flex: 0 0 auto;
}

[b-l9cvewerkd] .waiting-chip-duo-selectable {
    gap: 0.15rem;
}

[b-l9cvewerkd] .waiting-chip-avatar-btn.selected {
    box-shadow: inset 0 0 0 2px rgba(24, 52, 78, 0.28), 0 0 0 3px rgba(79, 116, 154, 0.18);
}

[b-l9cvewerkd] .waiting-chip-avatar-btn:focus-visible {
    outline: none;
    box-shadow: inset 0 0 0 2px rgba(24, 52, 78, 0.35), 0 0 0 3px rgba(79, 116, 154, 0.28);
}

/* overlap the two avatars and let the link glyph sit between them */
[b-l9cvewerkd] .waiting-chip-duo .player-avatar,
[b-l9cvewerkd] .waiting-chip-duo .player-avatar-image {
    border: 2px solid #eaf3fc;
    margin-left: -0.4rem;
}

[b-l9cvewerkd] .waiting-chip-duo .player-avatar:first-child,
[b-l9cvewerkd] .waiting-chip-duo .player-avatar-image:first-child {
    margin-left: 0;
}

[b-l9cvewerkd] .waiting-chip-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border-radius: 999px;
    background: #ffffff;
    border: 1px solid #8fb6e0;
    color: #1f4b76;
    font-size: 0.58rem;
    line-height: 1;
    margin: 0 -0.35rem;
    position: relative;
    z-index: 2;
    flex: 0 0 auto;
}

[b-l9cvewerkd] .waiting-chip-sticky-names {
    display: inline-flex;
    flex-direction: column;
    line-height: 1.12;
    margin-left: 0.15rem;
}

[b-l9cvewerkd] .waiting-chip-sticky-names b {
    font-weight: 700;
}

[b-l9cvewerkd] .waiting-chip-sticky-names small {
    font-weight: 500;
    color: #3f6184;
    font-size: 0.66rem;
}

/* #600 slice 4b: the combined linked-four pill. Shares the sticky pill's entire class
   family (.waiting-chip-sticky / -duo / -link / -sticky-names) - this modifier only adds
   the "one game" distinction so an operator never mistakes a linked FOUR (a one-shot
   "these four play together as one game" request) for a sticky PAIR (a persistent
   teammate bias). The distinction is deliberately subtle - a stronger left accent bar in
   the same sticky/lock blue + a tighter overlap for the extra avatars - so it reads as
   the same intent-object family, not a new brand. The sub-label ("linked four · plays
   together") carries the plain-English confirmation. */
/* #541 A1 rework (B1): THE PILL MUST WRAP, NOT CLIP. Before this slice the pill's only
   action was the #905 cancel X and its single row always fitted. Adding Start + To prep
   pushed the action cluster past the pill's own box on a phone - and because the ≤780px
   block gives .waiting-chip `overflow: hidden`, the overflow was silently CLIPPED rather
   than spilling: measured at 375px, ~94% of the 32px cancel button was invisible, with no
   page-level horizontal scroll to give it away.
   The fix is a wrap strategy on the pill itself (unconditional - it engages only when the
   row genuinely will not fit): the action cluster and the cancel drop onto a second line
   inside the pill instead of off the end of it. The names column is made shrinkable
   (min-width:0) so long names wrap their own text rather than forcing the actions out.
   Guarded by rect-containment assertions on ALL THREE action controls at 360/375/390/414 -
   a document-scroll assertion cannot see this class of bug.
   WHERE IT ACTUALLY WRAPS (measured on the render, UX 2026-08-27 - an earlier draft of this
   comment guessed a much lower threshold and was wrong): the two-row layout persists well
   past the phone widths, through ~500px, and the pill has settled back to a single row by
   ~700-780px. So the second row is the NORMAL shape on a phone and on a narrow tablet
   column, not a rare degenerate case - style it as something an operator will see. */
[b-l9cvewerkd] .waiting-chip-linked-pill {
    /* #600 slice 4b: the "one game" distinction (see the note above). */
    border-left: 3px solid #1f4b76;
    padding-left: 0.4rem;

    flex-wrap: wrap;
    row-gap: 0.25rem;
    /* 999px on a wrapped two-row pill renders as an over-round lozenge. At a single row's
       ~40px height 999px already clamps to ~20px, so 1.15rem is visually identical when the
       pill does NOT wrap and simply stays sane when it does. */
    border-radius: 1.15rem;
}

/* BOTH halves of the fix are load-bearing, verified by mutation: with the wrap alone the
   names column's min-content width still shoves the cancel X out (measured: 0% of it inside
   at 360px), and with the shrink alone there is no second line for the actions to land on. */
[b-l9cvewerkd] .waiting-chip-linked-pill .waiting-chip-sticky-names {
    min-width: 0;
    flex: 1 1 auto;
}

/* Four avatars need a slightly deeper overlap than two so the cluster stays compact on
   the kiosk board; the sticky pair keeps its -0.4rem. */
[b-l9cvewerkd] .waiting-chip-linked-pill .waiting-chip-duo .player-avatar,
[b-l9cvewerkd] .waiting-chip-linked-pill .waiting-chip-duo .player-avatar-image {
    margin-left: -0.55rem;
}

[b-l9cvewerkd] .waiting-chip-linked-pill .waiting-chip-duo .player-avatar:first-child,
[b-l9cvewerkd] .waiting-chip-linked-pill .waiting-chip-duo .player-avatar-image:first-child {
    margin-left: 0;
}

/* #905: the Cancel control on a queued linked-four pill. A kiosk-friendly round ×
   button in the same sticky/lock blue family (not a red destructive - cancelling a
   queued four is a low-stakes, fully-reversible action: the four just return to the
   queue individually and can be re-queued). Min 32px hit target so it is comfortably
   tappable on a tablet without a mis-tap onto the pill body; the tooltip + aria-label
   spell out the outcome so no confirm dialog is needed. */
[b-l9cvewerkd] .waiting-chip-linked-cancel {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    min-height: 2rem;
    margin-left: 0.3rem;
    padding: 0;
    border: 1px solid #8fb6e0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.7);
    color: #1f4b76;
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    flex: 0 0 auto;
}

[b-l9cvewerkd] .waiting-chip-linked-cancel:hover,
[b-l9cvewerkd] .waiting-chip-linked-cancel:focus-visible {
    background: #ffffff;
    border-color: #1f4b76;
}

/* #687: the sticky-pair unstick X. Carries the .waiting-chip-linked-cancel class too, so
   its size / palette / hover / touch behaviour are IDENTICAL to the #905 linked-four
   cancel by construction (Mike: mirror #905 exactly). This selector is a no-op hook kept
   only so the sticky X is greppable + future divergence has a home; do not add rules that
   break parity with the linked cancel. */
[b-l9cvewerkd] .waiting-chip-sticky-cancel {
    /* intentionally empty - inherits .waiting-chip-linked-cancel */
}

[b-l9cvewerkd] .waiting-toolbar {
    display: flex;
    gap: 0.35rem;
    margin-bottom: 0.45rem;
    align-items: flex-start;
}

/* BL-PW-0014 (R2): the Level-2 Approval admission queue - pending requests above the
   check-in toolbar. Amber-tinted so it reads as "needs your attention" without competing
   with the primary waiting list. Absent entirely for Open / AdminOnly clubs. */
[b-l9cvewerkd] .admission-requests {
    margin-bottom: 0.55rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid #f0d68a;
    border-radius: 0.5rem;
    background: #fdf6e3;
}

[b-l9cvewerkd] .admission-requests-head {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #7a5c12;
    margin-bottom: 0.4rem;
}

[b-l9cvewerkd] .admission-request-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.25rem 0;
}

[b-l9cvewerkd] .admission-request-row + .admission-request-row {
    border-top: 1px solid #f0e2b6;
}

[b-l9cvewerkd] .admission-request-name {
    font-weight: 600;
    color: #16324f;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[b-l9cvewerkd] .admission-request-actions {
    display: flex;
    gap: 0.35rem;
    flex: 0 0 auto;
}

[b-l9cvewerkd] .waiting-toolbar input {
    min-width: 0;
}

[b-l9cvewerkd] .waiting-checkin-search {
    flex: 1 1 16rem;
    max-width: 20rem;
}

[b-l9cvewerkd] .checkin-autocomplete {
    position: relative;
    flex: 1 1 16rem;
    max-width: 20rem;
    min-width: 0;
}

[b-l9cvewerkd] .checkin-autocomplete .waiting-checkin-search {
    flex: none;
    max-width: none;
    width: 100%;
}

[b-l9cvewerkd] .checkin-autocomplete-list {
    position: absolute;
    top: calc(100% + 0.15rem);
    left: 0;
    right: 0;
    z-index: 1400;
    margin: 0;
    padding: 0.15rem;
    list-style: none;
    background: #ffffff;
    border: 1px solid #b3c6da;
    border-radius: 0.4rem;
    box-shadow: 0 6px 14px rgba(17, 35, 53, 0.18);
    max-height: 20rem;
    overflow-y: auto;
}

[b-l9cvewerkd] .checkin-autocomplete-item {
    padding: 0.55rem 0.7rem;
    border-radius: 0.3rem;
    color: #24384f;
    font-size: 0.95rem;
    line-height: 1.2;
    cursor: pointer;
    user-select: none;
}

[b-l9cvewerkd] .checkin-autocomplete-item:hover,
[b-l9cvewerkd] .checkin-autocomplete-item.highlighted {
    background: #e7f0fa;
    color: #0d2c55;
}

[b-l9cvewerkd] .checkin-autocomplete-match {
    font-weight: 700;
    color: inherit;
}

/* #850 rework: a plain, non-tappable "No matching member." line that sits above the
   guest action row when nothing in the directory matches. */
[b-l9cvewerkd] .checkin-autocomplete-nomatch {
    color: #6c7a89;
    font-size: 0.88rem;
    cursor: default;
}

[b-l9cvewerkd] .checkin-autocomplete-nomatch:hover {
    background: transparent;
    color: #6c7a89;
}

/* #850 rework: the always-present "Add … as a guest" action row. Visually distinct from a
   member match - warm tint + top separator + a "+" glyph - so it reads as a DIFFERENT kind of
   row, but still obviously tappable. */
[b-l9cvewerkd] .checkin-autocomplete-guest-action {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.15rem;
    border-top: 1px solid #e8d79b;
    background: #fff8e6;
    color: #6d5920;
    font-size: 0.9rem;
}

[b-l9cvewerkd] .checkin-autocomplete-guest-action:hover {
    background: #fdefc4;
    color: #4f4113;
}

[b-l9cvewerkd] .checkin-autocomplete-guest-action strong {
    font-weight: 700;
    color: inherit;
}

[b-l9cvewerkd] .checkin-guest-action-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    flex: none;
    border-radius: 50%;
    background: #e8c860;
    color: #4f4113;
    font-weight: 700;
    line-height: 1;
}

[b-l9cvewerkd] .quick-guest-name-input {
    max-width: 20rem;
}

[b-l9cvewerkd] .quick-guest-rating-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

[b-l9cvewerkd] .attendee-name-link {
    border: none;
    background: transparent;
    color: #274a68;
    padding: 0;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

[b-l9cvewerkd] .attendee-name-link:hover {
    text-decoration: underline;
}

[b-l9cvewerkd] .player-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 999px;
    background: rgba(34, 72, 103, 0.85);
    color: #fff;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}
[b-l9cvewerkd] .player-avatar-image {
    object-fit: cover;
    border: 1px solid rgba(31, 43, 56, 0.16);
    background: #fff;
}

/* Waiting-queue chips show meaningfully-sized photos so members are
   recognisable at a glance. Prep slots and court tiles keep the
   smaller default for now. Phone viewports shrink slightly so the
   waiting list stays compact when vertical space matters. */
[b-l9cvewerkd] .waiting-chip .player-avatar,
[b-l9cvewerkd] .waiting-chip .player-avatar-image {
    width: 2rem;
    height: 2rem;
    font-size: 0.85rem;
}

@media (max-width: 720px) {
    [b-l9cvewerkd] .waiting-chip .player-avatar,
    [b-l9cvewerkd] .waiting-chip .player-avatar-image {
        width: 1.5rem;
        height: 1.5rem;
        font-size: 0.72rem;
    }
}

[b-l9cvewerkd] .pending-score-card {
    border: 1px solid #c0cfdd;
    border-radius: 0.6rem;
    padding: 0.5rem;
    background: #f8fbff;
}

[b-l9cvewerkd] .pending-score-panel {
    display: flex;
    flex-direction: column;
    min-height: 0;
}

[b-l9cvewerkd] .pending-score-list {
    display: grid;
    gap: 0.45rem;
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    overflow-x: hidden;
    overflow-y: auto;
    padding-right: 0.2rem;
}

[b-l9cvewerkd] .pending-score-head {
    color: #355775;
    font-weight: 700;
    margin-bottom: 0.35rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
}

/* #260: pre-game par hint on the score-entry card. */
[b-l9cvewerkd] .pending-score-par {
    color: #60778f;
    font-weight: 600;
    font-size: 0.8rem;
    white-space: nowrap;
}

[b-l9cvewerkd] .pending-score-row {
    display: grid;
    grid-template-columns: 1fr 4rem;
    align-items: center;
    gap: 0.35rem;
    margin-bottom: 0.3rem;
    font-size: 0.84rem;
}

[b-l9cvewerkd] .pending-score-input {
    width: 100%;
    justify-content: center;
    text-align: center;
    /* #277: 2.75rem ~= 44px, a comfortable touch target (was 2rem/32px). */
    min-height: 2.75rem;
    border: 2px solid #9fb7cf;
    background: #f2f8ff;
    color: #2d4f6d;
    font-weight: 700;
    font-size: 1.05rem;
}

[b-l9cvewerkd] .pending-score-input-auto {
    background: #fff0bd;
    border-color: #e3c56f;
    color: #664b00;
}

[b-l9cvewerkd] .pending-score-input-empty {
    border-style: dashed;
    border-color: #6f93b8;
    background: #eaf3fc;
    color: #4d7093;
    font-weight: 600;
}

/* #882: winner-first two-step score entry. Step 1 asks which team won; picking a team opens the
   existing decade popover for the LOSING score, which fills the winner. Uses the same palette as
   the score rows so the card reads as one continuous affordance. */
[b-l9cvewerkd] .pending-score-winner-prompt {
    color: #355775;
    font-weight: 600;
    font-size: 0.82rem;
    margin-bottom: 0.35rem;
}

[b-l9cvewerkd] .pending-score-winner-choices {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
    margin-bottom: 0.3rem;
}

[b-l9cvewerkd] .pending-score-winner-btn {
    width: 100%;
    min-height: 2.75rem;
    border: 2px solid #9fb7cf;
    background: #f2f8ff;
    color: #2d4f6d;
    font-weight: 700;
    text-align: center;
    justify-content: center;
}

[b-l9cvewerkd] .pending-score-winner-btn:hover:not(:disabled) {
    background: #e2f0ff;
    border-color: #6f93b8;
}

/* Small "won" tag beside the winning team's name once a winner is chosen (step 2). */
[b-l9cvewerkd] .pending-score-winner-tag {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0 0.35rem;
    border-radius: 0.5rem;
    background: #2f7d33;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    vertical-align: middle;
}

@media (any-pointer: coarse) and (min-width: 601px) {
    [b-l9cvewerkd] .pending-score-winner-btn {
        min-height: 3rem;
        font-size: 1.05rem;
    }
}

[b-l9cvewerkd] .quick-score-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0.35rem;
}

/* #915: consistent "Guest" marker beside a member's name on every in-session chip/tile
   (waiting queue, on-court, held, sitting-out, prep slots) so a guest and a same-named member
   are distinguishable at a glance. Small, muted, non-interactive; sits inline after the name. */
[b-l9cvewerkd] .member-guest-badge {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0 0.35rem;
    border-radius: 0.5rem;
    background: #e7edf4;
    border: 1px solid #b9c8d8;
    color: #4a637d;
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1.4;
    vertical-align: middle;
    white-space: nowrap;
}

/* #61/#155 v5 score-entry grid CSS moved to the shared ScoreEntryGrid.razor.css component
   (LR-3): the popover markup now lives in that component, so its scoped stylesheet owns the
   .score-combo-backdrop / .score-combo-popover / .score-grid / .score-combo-chip /
   .score-grid-chip-common / .score-grid-chip-pending / .score-grid-typeahead rules + the
   600px media query. Removed from here so there's one source of truth. */

/* #277: club kiosks run on tablets (touch / coarse pointer). Above the phone
   breakpoint there's room to make score entry comfortably finger-sized, so bump
   the tap-to-enter button, the score column width, and the number-grid chips. */
/* #277: enlarge for touch entry. Use any-pointer:coarse, not pointer:coarse -
   a touchscreen laptop's PRIMARY pointer is its trackpad (pointer:fine), so
   pointer:coarse missed it; any-pointer:coarse catches any touch-capable device
   (tablets and touch laptops) while leaving mouse-only desktops alone. */
@media (any-pointer: coarse) and (min-width: 601px) {
    [b-l9cvewerkd] .pending-score-row {
        grid-template-columns: 1fr 5.5rem;
        font-size: 0.95rem;
    }

    /* The displayed score reads big enough without dominating the panel - keep a
       comfortable tap height but a restrained numeral. */
    [b-l9cvewerkd] .pending-score-input {
        min-height: 3rem;
        font-size: 1.15rem;
    }

    /* LR-33: the grid-element touch-enlargement (.score-grid columns/gap,
       .score-combo-chip min-height/font-size, .score-combo-popover width/padding)
       was RELOCATED into ScoreEntryGrid.razor.css with ::deep dropped. The base grid
       rules were extracted into that shared component (LR-3) but this enlargement was
       left here as ::deep - equal specificity + later-in-bundle meant the shared
       component's base 44px chip defeated this 64px override, silently shrinking the
       SESSION score chips on touch/coarse-pointer kiosks. Moving the override into the
       grid's own scope makes it win the cascade for every consumer (session +
       competition). The non-grid pending-row rules below stay here (session-owned). */

    /* Save matches the width of the score column above it (no min-height: it
       keeps the standard btn-sm height like the other dashboard buttons, and a
       taller Save would stretch Reactivate/Void with it via the flex row). */
    [b-l9cvewerkd] .pending-score-save {
        min-width: 5.5rem;
    }
}

[b-l9cvewerkd] .panel-actions {
    display: flex;
    gap: 0.35rem;
    margin-top: 0.45rem;
    /* Wrap when the action row's content exceeds the panel width. Without
       wrap, the Save button (which has margin-left: auto to pin it to the
       right edge of the pending-score card) gets clipped silently by the
       parent .pending-score-list overflow-x: hidden. Reported live PROD
       2026-05-25 by Mike: Reactivate visible + half of Void + Save missing
       → couldn't save the score until browser-zoom workaround. */
    flex-wrap: wrap;
}

[b-l9cvewerkd] .prep-panel-actions {
    justify-content: center;
}

/* Save sits at the right edge of the pending-score card, aligned under
   the score buttons, so finger travel from "just tapped a score" to
   "tap Save" is minimal. Reactivate + Void stay grouped on the left. */
[b-l9cvewerkd] .pending-score-save {
    margin-left: auto;
}

/* #926 v2-A (#5 fix): the COMPACT side-panel score card. Same DOM as before (the #260 par-chip
   head + rows + 3-button action row are asserted by the visual-regression suites and MUST stay);
   this only tightens the vertical footprint so the card stops spilling to ~4-5 lines in the narrow
   Score-Entry column. Pure CSS - no structural change. */
[b-l9cvewerkd] .pending-score-card-compact {
    padding: 0.4rem 0.45rem;
    /* The card is a grid item in .pending-score-list, so its default min-width: auto lets a
       too-wide child (the nowrap action row) push the CARD past the 15.5rem Score Entry column.
       .pending-score-list clips that overflow (overflow-x: hidden), and because .pending-score-head
       is space-between the par chip sits ON the clipped edge - so the overflow eats the tail of
       "Par 21-19" and it reads "Par 21-1" (reported live PROD at Club MK, 2026-09-06; the same
       overflow was clipping Save right edge too). Pre-fix the card measured 243.4px and the chip
       sat 11.6px outside the clip. min-width: 0 makes the card honour its column and
       lets the flex action row shrink inside it, as the action-row rules below already intend. */
    min-width: 0;
}

[b-l9cvewerkd] .pending-score-card-compact .pending-score-head {
    margin-bottom: 0.2rem;
    font-size: 0.86rem;
}

[b-l9cvewerkd] .pending-score-card-compact .pending-score-winner-prompt {
    margin-bottom: 0.2rem;
}

[b-l9cvewerkd] .pending-score-card-compact .pending-score-row {
    margin-bottom: 0.2rem;
}

/* #4: short loser-score caption above the score rows (step 2 only). Muted, single line - the team
   NAMES are already on the rows, so this stays terse to keep the compact card one tight block.
   Scoped under .pending-score-card-compact so v2-B's popup can define its own caption typography
   without a specificity fight. margin-bottom (0.3rem) sits ABOVE the head's 0.2rem so the caption
   groups visually with the rows it labels, not floating equidistant from the head strip. */
[b-l9cvewerkd] .pending-score-card-compact .pending-score-loser-caption {
    color: #60778f;
    font-weight: 600;
    font-size: 0.75rem;
    margin-bottom: 0.3rem;
}

/* #926 v2-B: the ROOMY popup caption. The modal has the width for the full "Enter {pair}'s score"
   form, so the popup renders the caption at the modal's slightly larger scale (matching the
   .pending-score-winner-prompt type the card uses in step 1). Scoped to .finish-popup-card so the
   compact panel caption above (0.75rem) is unaffected - the two views diverge cleanly. */
[b-l9cvewerkd] .finish-popup-card .pending-score-loser-caption {
    color: #355775;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
}

/* [MAJOR] compact action row: Reactivate / Void / Save on ONE line, Save right-pinned. NOWRAP + the
   two secondary buttons allowed to shrink is what fixes the #5 wrapping (and avoids re-introducing
   the 2026-05-25 clip: the row never overflows because the buttons shrink to fit rather than wrap
   off the clipped edge). Scoped to .pending-score-actions so the generic .panel-actions (used
   elsewhere) keeps its wrap safety-net. */
[b-l9cvewerkd] .pending-score-actions {
    flex-wrap: nowrap;
    gap: 0.3rem;
    margin-top: 0.35rem;
    align-items: center;
}

[b-l9cvewerkd] .pending-score-actions > .btn-outline-secondary {
    flex: 0 1 auto;
    min-width: 0;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    white-space: nowrap;
}

[b-l9cvewerkd] .pending-score-actions > .pending-score-save {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* [MAJOR - ux-rework]: the coarse-pointer block above (~:1881) inflates .pending-score-row to
   `1fr 5.5rem` + .pending-score-input to 1.15rem for touch. On the actual kiosk TABLET (a
   coarse-pointer device - the whole point of the compact card) that re-inflates the score column +
   numerals and undoes the #5 compaction. QA measured on a FINE pointer so it didn't surface. These
   compact-scoped overrides sit AFTER that block (later in the bundle => win at equal ::deep
   specificity) and INSIDE the same coarse-pointer query, restoring the compact column/numeral on
   touch. The `min-height` touch floor is deliberately NOT overridden - the tap target stays >=44px;
   only the horizontal column width + numeral size tighten. */
@media (any-pointer: coarse) and (min-width: 601px) {
    [b-l9cvewerkd] .pending-score-card-compact .pending-score-row {
        grid-template-columns: 1fr 4rem;
        font-size: 0.84rem;
    }

    [b-l9cvewerkd] .pending-score-card-compact .pending-score-input {
        font-size: 1.05rem;
    }

    /* ...and the same omission for Save. The coarse min-width: 5.5rem on the bare .pending-score-save
       rule exists to "match the width of the score column above it" - but the compact card puts that
       column back to 4rem two rules up, so 5.5rem matches nothing and is ~24px of pure overshoot.
       Measured on the 15.5rem Score Entry column in the app font stack: Reactivate 84.2 + Void 45.3
       + Save 88 + gaps 9.6 against 207.2 available - that is the overflow that clipped the par chip
       on a touch kiosk (fine-pointer desktops never saw it, so QA never did either). At 4rem the row
       totals 203 and fits with both secondary buttons at full width. Save keeps the standard btn-sm
       HEIGHT (31px) here as it always has - it has no min-height floor, unlike .pending-score-input
       and .pending-score-winner-btn, so this trims width only. */
    [b-l9cvewerkd] .pending-score-card-compact .pending-score-save {
        min-width: 4rem;
    }
}

/* Was max-width: 1250px before the sidebar became a hamburger overlay below
   1280px. Now that overlay-mode reclaims ~250px of content width, 4-in-a-row
   fits comfortably down to ~920px viewport. Below that the courts grid still
   falls back to 2x2 because four 13rem cards (~853px) don't fit. */
@media (max-width: 919.98px) {
    [b-l9cvewerkd] .courts-grid {
        grid-template-columns: repeat(2, minmax(13rem, 1fr));
    }

    /* BL-059 (re-opened 2026-04-26 v2): below 920px, stack the lower section
       to a single column for ALL variants — INCLUDING the combined
       no-score+sittingout-collapsed class which has higher specificity than
       the single-class rules and was winning the cascade. Stacking puts
       prep first, waiting second, sitting third, score fourth — no
       horizontal scroll, waiting members visible on first paint. */
    [b-l9cvewerkd] .clubSession-lower-grid,
    [b-l9cvewerkd] .clubSession-lower-grid-no-score,
    [b-l9cvewerkd] .clubSession-lower-grid-sittingout-collapsed,
    [b-l9cvewerkd] .clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed,
    /* #689: the prep-inline combos must be listed at matching (or higher) specificity
       too — media queries add none, so the desktop 2/3-class prep-inline templates
       would otherwise defeat this stacking below 920px. */
    [b-l9cvewerkd] .clubSession-lower-grid-prep-inline,
    [b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-no-score,
    [b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-sittingout-collapsed,
    [b-l9cvewerkd] .clubSession-lower-grid-prep-inline.clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed,
    [b-l9cvewerkd] .clubSession-lower-grid-ops-inline,
    [b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-no-score,
    [b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-sittingout-collapsed,
    [b-l9cvewerkd] .clubSession-lower-grid-ops-inline.clubSession-lower-grid-no-score.clubSession-lower-grid-sittingout-collapsed {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 780px) {
    .clubSession-kiosk-top[b-l9cvewerkd] {
        flex-wrap: wrap;
    }

    [b-l9cvewerkd] .courts-grid,
    [b-l9cvewerkd] .clubSession-lower-grid {
        grid-template-columns: 1fr;
    }

    [b-l9cvewerkd] .waiting-toolbar {
        flex-wrap: wrap;
    }

    /* BL-059: belt-and-braces guard against horizontal scroll on the
       waiting-members panel at narrow viewports — chips wrap, anything that
       still overflows is clipped within the panel rather than pushing the
       page wider. */
    [b-l9cvewerkd] .clubSession-panel,
    [b-l9cvewerkd] .clubSession-panel-wide {
        max-width: 100%;
        overflow-x: hidden;
    }

    [b-l9cvewerkd] .waiting-member-list,
    [b-l9cvewerkd] .chip-list {
        max-width: 100%;
    }

    [b-l9cvewerkd] .waiting-chip {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* #600 slice 3 (inline card-action-row): at the kiosk breakpoint, stack the action
       buttons BELOW the players (their pre-slice-3 behaviour) so nothing crowds the
       players on a narrow tablet. Restores the row's own top margin between players and
       actions. Same 780px break the lower grid + toolbar already collapse at. */
    [b-l9cvewerkd] .special-request-card-body {
        flex-direction: column;
        align-items: stretch;
    }

    [b-l9cvewerkd] .special-request-card-body > .special-request-card-actions {
        margin-left: 0;
        margin-top: 0.45rem;
    }
}

.end-session-trigger[b-l9cvewerkd] {
    margin-left: 0.25rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 600;
}

.end-session-icon[b-l9cvewerkd] {
    width: 1.05em;
    height: 1.05em;
    flex: 0 0 auto;
}

/* UX-7: the Start-kiosk confirm + the no-PIN prompt reuse this modal SHAPE but under their own
   start-kiosk-* class names, so they don't inherit any destructive-action (end-session) styling a
   future change might add to the end-session variant. Same geometry, different semantic class. */
.end-session-modal-backdrop[b-l9cvewerkd],
.start-kiosk-modal-backdrop[b-l9cvewerkd] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2200;
}

.end-session-modal[b-l9cvewerkd],
.start-kiosk-modal[b-l9cvewerkd] {
    width: min(480px, 94vw);
    background: #ffffff;
    border: 1px solid #c8d4e2;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 1.1rem 1.2rem 1rem;
}

.end-session-modal h2[b-l9cvewerkd],
.start-kiosk-modal h2[b-l9cvewerkd] {
    margin: 0 0 0.6rem;
    color: #0d2c55;
    font-size: 1.15rem;
}

.end-session-actions[b-l9cvewerkd],
.start-kiosk-actions[b-l9cvewerkd] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* #60: admin's optional rating of the night on the end-session modal. */
.session-rating[b-l9cvewerkd] {
    margin-bottom: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid #e6edf5;
}

/* #749: the per-session ratings-columns choice on the end-session confirm modal. Kept
   compact (one row) so the modal stays one-screen on kiosk viewports. */
.end-session-report-options[b-l9cvewerkd] {
    margin-bottom: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid #e6edf5;
}

.end-session-report-options-label[b-l9cvewerkd] {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.88rem;
    color: #345674;
    cursor: pointer;
}

.end-session-report-options-label input[b-l9cvewerkd] {
    margin-top: 0.15rem;
    flex: 0 0 auto;
}

.session-rating-intro[b-l9cvewerkd] {
    margin: 0 0 0.6rem;
    font-size: 0.88rem;
    color: #557693;
    line-height: 1.35;
}

.session-rating-label[b-l9cvewerkd] {
    display: block;
    font-weight: 600;
    color: #2e4f6d;
    margin-bottom: 0.35rem;
}

.session-rating-optional[b-l9cvewerkd] {
    font-weight: 400;
    color: #7a8897;
}

.session-rating-stars[b-l9cvewerkd] {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    margin-bottom: 0.5rem;
}

.session-rating-star[b-l9cvewerkd] {
    border: none;
    background: transparent;
    padding: 0 0.1rem;
    font-size: 1.7rem;
    line-height: 1;
    color: #cdd5df;
    cursor: pointer;
}

.session-rating-star-on[b-l9cvewerkd] {
    color: #f1b445;
}

.session-rating-star:hover:not(:disabled)[b-l9cvewerkd] {
    color: #f1b445;
}

.session-rating-clear[b-l9cvewerkd] {
    border: none;
    background: transparent;
    color: #557693;
    font-size: 0.82rem;
    margin-left: 0.4rem;
    cursor: pointer;
    text-decoration: underline;
}

.session-rating-comment[b-l9cvewerkd] {
    resize: vertical;
}

/* #549: Special Requests panel - operator-authored saved match-ups + hold/release.
   Reuses the shared .clubSession-panel / .panel-actions / .player-avatar / .gender-*
   classes; only the special-request-specific layout is defined here. */
[b-l9cvewerkd] .special-requests-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* #600 slice 1: the "Add Special Request" toolbar button is a different KIND of action from the
   Add player / Bulk Add controls (it composes a saved record, it checks no-one in), so it
   is pushed to the right edge of the .waiting-toolbar flex row. On the <=780px tablet breakpoint
   the toolbar wraps (rule above), so it drops to its own line - still reads as separated. */
[b-l9cvewerkd] .special-request-add-btn {
    margin-left: auto;
}

/* S2a (Effective Permissions, epic #325): under the kiosk hat the Add-Special-Request control is
   wrapped in .special-request-add-btn-wrap (the quiet locked-control; the "Organiser only" caption
   was removed 2026-07-15), so the flex-item that needs the right-edge push is the WRAPPER, not the
   inner button. Mirror the margin-left:auto onto the wrapper so the locked control keeps its
   flush-right position and never jams into the check-in trio. */
[b-l9cvewerkd] .special-request-add-btn-wrap {
    margin-left: auto;
}

/* #600 slice 1: progressive-disclosure list pane.
   Shown only when >=1 request exists. #912: in the lower-grid layout it now docks INSIDE the
   waiting panel (under the queue); in the #689 inline layout it stays the full-width strip below
   .clubSession-lower-grid. The base rule below suits both (a light top gap + full-width panel). */
[b-l9cvewerkd] .special-requests-strip {
    margin-top: 0.45rem;
}

[b-l9cvewerkd] .special-requests-strip .special-requests-panel {
    width: 100%;
}

/* #912: when docked INSIDE the waiting panel (lower-grid layout), separate it from the queue
   above with a hairline so it reads as its own dock rather than bleeding into the chip list.
   The nested SpecialRequestsPanel is itself a .clubSession-panel, so drop its own panel chrome
   here (border/background/pad) to avoid a panel-in-a-panel double frame - the divider + the
   parent panel's padding carry the separation. Below-grid (inline layout) the strip is NOT a
   child of .clubSession-panel-wide, so this rule doesn't touch it and it keeps its full card. */
[b-l9cvewerkd] .clubSession-panel-wide > .special-requests-strip {
    margin-top: 0.55rem;
    padding-top: 0.5rem;
    border-top: 1px solid #c8d5e4;
}

[b-l9cvewerkd] .clubSession-panel-wide > .special-requests-strip .special-requests-panel {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
}

/* #848/#817 Slice 1 (locked decision Q4 / fold guarantee 1): cap the DOCKED Special
   Requests list so it scrolls internally instead of growing the Waiting column - fixing
   the operational band's height regardless of how many requests are parked. This keeps
   the whole band above the fold with SR present (the 5-court + SR case), and also closes
   the pre-existing 4-court SR overflow (the strip previously grew the band unbounded).
   The queue FRONT stays visible; deeper cards scroll - the same "front visible, depth
   scrolls" idiom as the waiting-member-list cap. Scoped to the lower-grid dock only
   (child of .clubSession-panel-wide); the 6/7-court inline below-grid strip is untouched
   (its 2-row fallback is out of Slice 1 scope). */
[b-l9cvewerkd] .clubSession-panel-wide > .special-requests-strip .special-request-list {
    max-height: var(--fold-sr-cap, 8rem);
    overflow-y: auto;
}

[b-l9cvewerkd] .special-requests-empty {
    color: #6c7a8c;
    font-size: 0.9rem;
    margin: 0.25rem 0 0;
}

[b-l9cvewerkd] .special-request-compose {
    border: 1px solid #e6ebf3;
    border-radius: 0.5rem;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
    background: #f8fafc;
}

[b-l9cvewerkd] .special-request-compose-hint {
    font-size: 0.85rem;
    color: #6c7a8c;
    margin: 0 0 0.5rem;
}

[b-l9cvewerkd] .special-request-compose-teams {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

[b-l9cvewerkd] .special-request-compose-team {
    flex: 1 1 12rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

[b-l9cvewerkd] .special-request-compose-team-label {
    font-weight: 600;
    color: #1f3f5e;
    font-size: 0.85rem;
}

[b-l9cvewerkd] .special-request-label-input {
    margin-top: 0.6rem;
}

[b-l9cvewerkd] .special-request-compose-warn {
    color: #8a5a00;
    font-size: 0.85rem;
    margin-top: 0.4rem;
}

[b-l9cvewerkd] .special-request-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

[b-l9cvewerkd] .special-request-card {
    border: 1px solid #e6ebf3;
    border-radius: 0.5rem;
    padding: 0.6rem 0.75rem;
}

/* #600 slice 3 (inline card-action-row, Mike 2026-07-01): on tablet/desktop the action
   buttons sit on the SAME row as the players, to the right of the team/player block, to
   save vertical space. The teams block takes the remaining width (and wraps its own chips
   internally); the actions block is pinned right and does not wrap onto its own line here.
   At the 780px kiosk breakpoint (below) this switches to a column so the buttons stack
   below the players. The blocked/held captions stay full-width siblings AFTER this body. */
[b-l9cvewerkd] .special-request-card-body {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

[b-l9cvewerkd] .special-request-card-body > .special-request-card-teams {
    flex: 1 1 auto;
    min-width: 0;
}

[b-l9cvewerkd] .special-request-card-body > .special-request-card-actions {
    flex: 0 0 auto;
    margin-left: auto;
    margin-top: 0;
}

/* #600 slice 2 (held-state visuals): the card header row holds the label on the left and the
   card-level "Held" badge flush-right. Present whenever there is a label OR the card is held. */
[b-l9cvewerkd] .special-request-card-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

[b-l9cvewerkd] .special-request-card-label {
    font-weight: 600;
    color: #1f3f5e;
}

/* #600 slice 2 (held-state visuals): card-level "Held" badge, pushed to the right edge of the
   header. Sticky/lock blue palette (matches the held chip tag + sticky pill) so "held for a
   request" reads as the same intent-object blue across the board. */
[b-l9cvewerkd] .special-request-card-held-badge {
    margin-left: auto;
    border: 1px solid #8fb6e0;
    border-radius: 999px;
    background: #eaf3fc;
    color: #1f4b76;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.18rem 0.5rem;
}

/* #541 rework: the Queued badge. Deliberately the SAME pill geometry as the Held badge above -
   they occupy the same slot and are mutually exclusive, so a shared shape reads as "this card's
   state" rather than as two unrelated ornaments. The colour is the linked-four pill's own
   (#eaf3fc / #1f4b76 family is already the sticky/linked blue), so the card and the queue chip
   for the same four agree visually. margin-left:auto matches Held so it sits flush-right whether
   or not the card has a label. */
[b-l9cvewerkd] .special-request-card-queued-badge {
    margin-left: auto;
    border: 1px solid #8fb6e0;
    border-radius: 999px;
    background: #eaf3fc;
    color: #1f4b76;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.18rem 0.5rem;
}

/* #600 slice 2 (held-state visuals): a held card carries a thin sticky/lock-blue left accent so
   the whole card reads as out-of-rotation at a glance, distinct from a plain waiting card. */
[b-l9cvewerkd] .special-request-card.is-held {
    border-color: #8fb6e0;
    box-shadow: inset 0.2rem 0 0 0 #8fb6e0;
}

/* #600 slice 2 (held-state visuals): the held helper line (shown only when the card is held).
   Same sticky/lock-blue ink as the badge, distinct from the amber blocked caption. */
[b-l9cvewerkd] .special-request-card-held-help {
    color: #1f4b76;
    font-size: 0.85rem;
    margin-top: 0.4rem;
}

/* #600 slice 2 (held-state visuals): a held member chip on the card. Sticky/lock-blue outline so
   it reads as held even though a held member is technically startable. */
[b-l9cvewerkd] .special-request-member.is-held {
    border-color: #8fb6e0;
    background: #eaf3fc;
}

[b-l9cvewerkd] .special-request-member.is-held .special-request-member-status {
    color: #1f4b76;
}

/* #600 slice 2 (held-state visuals): the small "Held" group label before the held chips in the
   Waiting Members panel, so held members are locatable at a glance. */
[b-l9cvewerkd] .waiting-held-group-label {
    display: inline-flex;
    align-items: center;
    align-self: center;
    margin-left: 0.15rem;
    color: #1f4b76;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

[b-l9cvewerkd] .special-request-card-teams {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

[b-l9cvewerkd] .special-request-card-team {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

[b-l9cvewerkd] .special-request-card-vs {
    color: #6c7a8c;
    font-weight: 600;
}

[b-l9cvewerkd] .special-request-member {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    border: 1px solid #e6ebf3;
    border-radius: 1rem;
    background: #fff;
    padding: 0.15rem 0.6rem 0.15rem 0.2rem;
    cursor: pointer;
    font-size: 0.9rem;
}

[b-l9cvewerkd] .special-request-member.is-blocked {
    opacity: 0.65;
}

[b-l9cvewerkd] .special-request-member-status {
    font-size: 0.72rem;
    color: #8a5a00;
    text-transform: lowercase;
}

[b-l9cvewerkd] .special-request-card-blocked {
    color: #8a5a00;
    font-size: 0.85rem;
    margin-top: 0.4rem;
}

/* #756 (EVOLVES #753/#695): the Recap-tab surface — a control strip
   [ Share | Copy link | Open | Include-ratings ] above a same-origin iframe of the public
   recap. Replaces the #753 button-bar container (the actions + the #744 claim-code reveal
   are reused). Same quiet card language as the #695 panel / the supporter aside below (no
   new brand). The revealed claim code REUSES the #430 .clubSession-claim-code chip. */
.clubSession-recap-tab[b-l9cvewerkd] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* The control strip: actions on the left, the ratings switch pushed to the right. */
.clubSession-recap-strip[b-l9cvewerkd] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem 0.9rem;
    background: #eef4fa;
    border: 1px solid #d9e6f2;
    border-radius: 0.65rem;
    padding: 0.7rem 0.9rem;
}

.clubSession-recap-strip-actions[b-l9cvewerkd] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
}

/* The include-ratings group sits at the far right on wide layouts, wraps below on narrow. */
.clubSession-recap-ratings[b-l9cvewerkd] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem 0.55rem;
    margin-left: auto;
}

/* The switch itself — a pill toggle mirroring the mockup (on = brand blue, off = grey). */
.clubSession-recap-ratings-switch[b-l9cvewerkd] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    border: 0;
    background: none;
    padding: 0.15rem 0.1rem;
    font-size: 0.88rem;
    font-weight: 600;
    color: #16324f;
    cursor: pointer;
}

.clubSession-recap-ratings-switch:disabled[b-l9cvewerkd] {
    opacity: 0.6;
    cursor: default;
}

.clubSession-recap-switch-track[b-l9cvewerkd] {
    position: relative;
    width: 2.6rem;
    height: 1.5rem;
    border-radius: 999px;
    background: #c2cbd4;
    flex: 0 0 auto;
    transition: background 0.15s ease;
}

.clubSession-recap-switch-track[b-l9cvewerkd]::after {
    content: "";
    position: absolute;
    top: 0.15rem;
    left: 0.15rem;
    width: 1.2rem;
    height: 1.2rem;
    border-radius: 50%;
    background: #fff;
    transition: left 0.15s ease;
}

.clubSession-recap-ratings-switch.is-on .clubSession-recap-switch-track[b-l9cvewerkd] {
    background: #1b6ec2;
}

.clubSession-recap-ratings-switch.is-on .clubSession-recap-switch-track[b-l9cvewerkd]::after {
    left: auto;
    right: 0.15rem;
}

.clubSession-recap-ratings-hint[b-l9cvewerkd] {
    font-size: 0.74rem;
    color: #5e748a;
    font-weight: 400;
    max-width: 18rem;
    line-height: 1.35;
}

/* #744-gated claim-code reveal (carried over from #753). In the tab's block layout let the
   label + big code wrap naturally on narrow kiosks. */
.clubSession-recap-code .clubSession-claim-code[b-l9cvewerkd] {
    white-space: normal;
}

.clubSession-recap-code-hint[b-l9cvewerkd] {
    margin: 0.35rem 0 0;
    color: #557693;
    font-size: 0.85rem;
}

/* The iframe of the public recap (?embed=1, same-origin). Height is set by JS
   (pegboardRecapEmbed) to the content height so there is NO nested scrollbar; the min-height
   is just a graceful floor while the first load + measure land. */
.clubSession-recap-iframe-wrap[b-l9cvewerkd] {
    border: 1px solid #cbd5e1;
    border-radius: 0.65rem;
    overflow: hidden;
    background: #fff;
}

.clubSession-recap-iframe[b-l9cvewerkd] {
    display: block;
    width: 100%;
    min-height: 24rem;
    border: 0;
}

.clubSession-recap-unavailable[b-l9cvewerkd] {
    margin: 0;
    color: #557693;
    font-size: 0.9rem;
}

.clubSession-end-panel[b-l9cvewerkd] {
    background: #f6f9fc;
    border: 1px solid rgba(92, 119, 145, 0.25);
    border-radius: 0.65rem;
    padding: 0.85rem 1rem;
    margin-bottom: 0.45rem;
}

.clubSession-end-panel-title[b-l9cvewerkd] {
    margin: 0 0 0.2rem;
    color: #345674;
    font-size: 1.05rem;
    font-weight: 700;
}

.clubSession-end-panel-sub[b-l9cvewerkd] {
    margin: 0 0 0.6rem;
    color: #557693;
    font-size: 0.9rem;
}

.clubSession-end-panel-actions[b-l9cvewerkd] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
}

.clubSession-end-panel-code[b-l9cvewerkd] {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
    border-top: 1px solid #dbe5ef;
}

/* The header chip is nowrap for its inline slot; in the panel's block layout let
   the label + big code wrap naturally on narrow kiosks. */
.clubSession-end-panel-code .clubSession-claim-code[b-l9cvewerkd] {
    white-space: normal;
}

.clubSession-end-panel-code-hint[b-l9cvewerkd] {
    margin: 0.35rem 0 0;
    color: #557693;
    font-size: 0.85rem;
}

/* #749: the per-session report VIEW config (ratings-columns choice) block. Sits below
   the share/claim actions with the same divider treatment as the claim-code block. */
.clubSession-end-panel-report-options[b-l9cvewerkd] {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
    border-top: 1px solid #dbe5ef;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
}

.clubSession-end-panel-report-options-state[b-l9cvewerkd] {
    margin: 0;
    color: #557693;
    font-size: 0.85rem;
    flex: 1 1 14rem;
}

/* #583: the post-session "a club night just ended" supporter aside. A quiet, slightly tinted card
   below the ended-session tabs - never a blocker. The inner heading/body/buttons are styled by the
   shared SupporterAsk component; this owns the outer card frame. */
.clubSession-support-card[b-l9cvewerkd] {
    background: #f6f9fc;
    border: 1px solid rgba(92, 119, 145, 0.25);
    border-radius: 0.65rem;
    padding: 1rem;
    margin-top: 0.8rem;
}

/* ═══ #718: cumulative viewport-HEIGHT density tiers ═══════════════════════════
   The dashboard stack (banner + header + tabs + court rows + prep + waiting) is
   structurally taller than common operator viewports (probe 2026-07-04: +44px at
   1280x800, +113px at 1024x768; the 4-court control overflows too because the
   lower-grid waiting list had no height cap). Density comes from DEAD SPACE
   (min-heights, gaps, paddings), never from court typography — operator
   legibility across a sports hall is the product (fonts stay >=0.85rem even at
   tier 3). Tiers are CUMULATIVE: at <=779.98px all three blocks apply, each
   re-declaring the --fold-* scale knobs declared on .clubSession-dashboard-shell
   (they inherit through CSS isolation into the ::deep children).

     tier 0  >=900px   base values above — today's layout, untouched
     tier 1  <=899.98  #696 compact chip (earlier block) + the lower-grid
                       waiting cap below
     tier 2  <=829.98  QR chip -> "QR" tap-button; courts/prep/rhythm shrink
     tier 3  <=779.98  the deliberate degrade tier — tight but still readable */

/* ── tier 1 (<=899.98px): cap the LOWER-GRID waiting list like the #689 inline
   one (the 4-court control's overflow driver — a 14-deep queue grew the panel
   past any budget). Operator boards only (>=920px wide): phones are a scrolling
   form factor and keep natural page flow. The queue FRONT — the players the
   operator works from — stays visible; deep positions scroll inside the panel. */
@media (min-width: 920px) and (max-height: 899.98px) {
    [b-l9cvewerkd] .clubSession-lower-grid .waiting-member-list {
        max-height: var(--fold-waiting-cap, 12.5rem);
        overflow-y: auto;
    }
}

/* ── tier 2 (<=829.98px): dense ── */
@media (max-height: 829.98px) {
    .clubSession-dashboard-shell[b-l9cvewerkd] {
        --fold-court-min: 12.5rem;
        --fold-court-empty-min: 8.5rem;
        --fold-panel-pad: 0.5rem;
        --fold-prep-slot-min: 2.05rem;
        --fold-prep-gap: 0.28rem;
        --fold-band-gap: 0.35rem;
        /* Tuned 9.25rem (design said 10.5): the 6-court board's inline waiting
           panel sits in ONE narrow track where its toolbar wraps ~3 rows tall;
           measured at 1280x800 the row needed the height back (a second quarter
           rem paid for the final design's guaranteed 2.5rem claim button).
           ~3 chip rows stay visible - the queue front the operator works from. */
        --fold-waiting-cap: 9.25rem;
        /* #848/#817 Slice 1: tighten the docked Special Requests cap in lock-step with
           the waiting cap so the band clears the fold on shorter operator boards. */
        --fold-sr-cap: 6.5rem;
        padding-bottom: 0.5rem;
    }

    .clubSession-kiosk-top[b-l9cvewerkd] {
        margin-bottom: 0.3rem;
        /* The claim button's guaranteed 2.5rem touch target sets the row height;
           trim the row's own vertical padding so the header stays ~46px. */
        padding-top: 0.15rem;
        padding-bottom: 0.15rem;
    }

    .clubSession-toolbar-tabs .nav-link[b-l9cvewerkd] {
        padding-top: 0.25rem;
        padding-bottom: 0.25rem;
    }

    /* Release the empty court card's OUTER min so the --fold-court-empty-min
       knob on .court-empty-actions governs its height (the phone breakpoint's
       existing move) — otherwise the outer 12.5rem floor defeats the shrink.
       #930: width-gated to narrow (<920px) boards only. On a >=920px 4-col
       operator/tablet board an empty card must stay the SAME height as a
       populated one (--fold-court-min parity), so it is excluded from this
       shrink — mirrors the min-width:920px "operator board" gate used for the
       waiting-list cap. Ungated, this fired on short-height tablet boards (e.g.
       1024x768) and made empty cards shorter than populated ones. */
    @media (max-width: 919.98px) {
        [b-l9cvewerkd] .court-card-empty {
            min-height: 0;
        }
    }

    [b-l9cvewerkd] .prep-panel-header {
        margin-bottom: 0.3rem;
    }

    [b-l9cvewerkd] .prep-discipline-row {
        padding: 0.12rem 0;
    }

    [b-l9cvewerkd] .clubSession-panel-prep .panel-actions {
        margin-top: 0.3rem;
    }

    [b-l9cvewerkd] .clubSession-panel h2 {
        margin-bottom: 0.3rem;
    }

    [b-l9cvewerkd] .waiting-toolbar {
        margin-bottom: 0.3rem;
    }

    /* UX review: match the waiting-chip rhythm to the prep-slot rhythm so the
       two peer panels read at ONE density (the chips felt crowded next to the
       roomier slots). Text size untouched. */
    [b-l9cvewerkd] .waiting-chip {
        padding: 0.18rem 0.45rem;
    }
}

/* ── tier 3 (<=779.98px): tight — the recorded degrade tier. Paddings tighten a
   touch; type stays at or above 0.85rem. If a cell cannot fit even here, THIS
   rendering is the deliberate compact mode the E2E records — never an
   accidental overflow. ── */
@media (max-height: 779.98px) {
    .clubSession-dashboard-shell[b-l9cvewerkd] {
        --fold-court-min: 10rem;
        --fold-court-empty-min: 6.5rem;
        --fold-panel-pad: 0.45rem;
        --fold-prep-slot-min: 1.9rem;
        --fold-prep-gap: 0.22rem;
        --fold-band-gap: 0.3rem;
        --fold-waiting-cap: 9rem;
        /* #848/#817 Slice 1: tightest Special Requests dock cap at the degrade tier. */
        --fold-sr-cap: 6rem;
    }

    [b-l9cvewerkd] .court-card {
        padding: 0.35rem;
    }

    [b-l9cvewerkd] .court-header {
        margin-bottom: 0.25rem;
    }

    [b-l9cvewerkd] .court-team-row {
        padding: 0.14rem 0.35rem;
        margin-bottom: 0.2rem;
    }

    [b-l9cvewerkd] .clubSession-panel h2 {
        font-size: 0.9rem;
    }

    .clubSession-toolbar-tabs .nav-link[b-l9cvewerkd] {
        font-size: 0.85rem;
    }

    /* In the ~230px court-row tracks of a 1024-wide board the 6.5rem button
       floor makes Auto-pick + Start wrap onto two rows (~36px of dead height in
       the prep panel that drives the whole second court row). A 5.5rem floor
       keeps them side by side. */
    [b-l9cvewerkd] .prep-btn {
        min-width: 5.5rem;
    }

    /* UX review: at this width the full "Auto-pick" label leaves the two action
       buttons flush with no breathing room — swap to the short label (markup
       carries both spans) instead of shrinking the type. */
    [b-l9cvewerkd] .prep-btn .prep-btn-label-full {
        display: none;
    }

    [b-l9cvewerkd] .prep-btn .prep-btn-label-short {
        display: inline;
    }

    /* UX review: the fixed 1.2rem court number visually shouts over the 0.88rem
       team names once the tier-3 card compresses — restore the proportion
       (still sports-hall readable). */
    [b-l9cvewerkd] .court-number {
        font-size: 1.1rem;
    }
}


/* /Components/Pages/ClubSessions.razor.rz.scp.css */
.clubSessions-shell[b-2b62izoy7u] {
    max-width: 70rem;
}

.clubSessions-card[b-2b62izoy7u] {
    border: 1px solid rgba(92, 119, 145, 0.3);
    border-radius: 0.65rem;
    background: #ffffff;
    padding: 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 0.15rem 0.35rem rgba(17, 35, 53, 0.06);
}

.clubSessions-card-header[b-2b62izoy7u] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    gap: 0.75rem;
}

.clubSessions-count-hint[b-2b62izoy7u] {
    color: #6c7a8c;
    font-size: 0.88rem;
}

.clubSessions-show-more[b-2b62izoy7u] {
    margin-top: 0.75rem;
    text-align: center;
}

/* #144/#156(a): the always-visible Today card is the primary zone above the tab strip. The 0.3->0.45
   border-alpha delta was imperceptible, so give it a real accent: an accent left-border bar, a heavier
   shadow, and a tinted heading. */
.clubSessions-today-card[b-2b62izoy7u] {
    border-color: rgba(67, 106, 144, 0.5);
    border-left: 0.28rem solid #456a92;
    box-shadow: 0 0.25rem 0.6rem rgba(17, 35, 53, 0.13);
}

.clubSessions-today-card .clubSessions-card-header h2[b-2b62izoy7u] {
    color: #2f4c6b;
}

/* #156(c): the tabpanel wrapper is a pure ARIA container — no box of its own; a quiet focus ring only when
   keyboard-focused (it's tabindex=0 per the APG tabs pattern). */
.clubSessions-tabpanel:focus-visible[b-2b62izoy7u] {
    outline: 2px solid #456a92;
    outline-offset: 2px;
    border-radius: 0.35rem;
}

/* #144: page-level error moved to an inline role="alert" banner under the h1 (above the Today card), so
   it's seen on whichever tab is active. */
.clubSessions-error-banner[b-2b62izoy7u] {
    background: #fdecea;
    border: 1px solid #e0a3a3;
    color: #8a1c2b;
    border-radius: 0.5rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: 1rem;
    font-size: 0.92rem;
}

/* #144: the three-tab strip (Upcoming / Completed / Schedule) below the Today card. Reuses the nav-tabs
   language of the in-session ClubSessionDashboard; WRAPS (not shrinks) on narrow/kiosk widths so each tab
   stays a legible ~40px touch target. */
.clubSessions-list-tabs[b-2b62izoy7u] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.28rem;
    border-bottom: 1px solid #9fb6cc;
    margin-bottom: 1rem;
    padding-left: 0.15rem;
    list-style: none;
}

.clubSessions-list-tabs .nav-item[b-2b62izoy7u] {
    margin-bottom: -1px;
}

.clubSessions-list-tabs .nav-link[b-2b62izoy7u] {
    border: 1px solid #b3c6da;
    border-bottom-color: #a9bfd3;
    border-radius: 0.45rem 0.45rem 0 0;
    /* #154 (WCAG AA): darkened inactive-tab label from #5a7691 (4.05:1, fail) to #3d556e = 6.6:1 on the
       #e8eef5 fill. */
    color: #3d556e;
    background: #e8eef5;
    font-weight: 700;
    font-size: 0.9rem;
    line-height: 1.15;
    padding: 0.45rem 0.85rem;
    min-height: 2.5rem;
    cursor: pointer;
}

.clubSessions-list-tabs .nav-link.active[b-2b62izoy7u] {
    /* #154 (WCAG AA): flat darker fill #456a92 replaces the #5f85ad→#4f749a gradient (whose light top
       stop measured 3.61:1). #f4f8fc label on #456a92 = 5.28:1. */
    background: #456a92;
    color: #f4f8fc;
    border-color: #436a90;
    border-bottom-color: #d2dbe7;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.35) inset;
}

.clubSessions-tab-label[b-2b62izoy7u] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

/* #144: numeric count badge on Upcoming/Completed (the existing pill language).
   #154 (WCAG AA): SOLID slate fill + white text replaces the translucent rgba(31,61,91,0.12) bg (whose
   effective ratio was 3.31:1). #ffffff on #3d556e = 7.7:1. */
.clubSessions-tab-badge[b-2b62izoy7u] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.35rem;
    padding: 0.02rem 0.4rem;
    border-radius: 0.7rem;
    background: #3d556e;
    color: #ffffff;
    font-size: 0.75rem;
    font-weight: 700;
}

/* #154 (WCAG AA): on the active (dark) tab, invert to a solid white pill with dark text — the previous
   rgba(255,255,255,0.25) fill measured 2.44-2.85:1. #2c4258 on #ffffff = 10.4:1. */
.clubSessions-list-tabs .nav-link.active .clubSessions-tab-badge[b-2b62izoy7u] {
    background: #ffffff;
    color: #2c4258;
}

/* #144: amber "a weekly schedule is paused" dot on the Schedule tab.
   #154 (WCAG AA graphical): darkened from #d99a1a (2.09:1, fail) to #9c6a08 = 4.7:1 on the white card
   (well above the 3:1 non-text floor). The dot also carries an aria-label + title for AT. */
.clubSessions-tab-dot[b-2b62izoy7u] {
    color: #9c6a08;
    font-size: 0.85rem;
    line-height: 1;
}

/* #144: the switch-to-Schedule inline link in the Upcoming empty state (a button styled as a link so it
   drives SelectTab rather than a navigation). */
.clubSessions-inline-link[b-2b62izoy7u] {
    border: 0;
    background: transparent;
    padding: 0;
    color: #1b6ec2;
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* #155: the transient page-level action confirmation (e.g. a Skip). Sits above the Today card so it's
   seen on any tab; a calm info tint distinct from the red error banner; dismissible. */
.clubSessions-action-banner[b-2b62izoy7u] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    background: #eaf2fb;
    border: 1px solid #b6cfe8;
    color: #23527c;
    border-radius: 0.5rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: 1rem;
    font-size: 0.92rem;
}

.clubSessions-action-dismiss[b-2b62izoy7u] {
    flex: none;
    border: 0;
    background: transparent;
    color: #23527c;
    font-size: 1.15rem;
    line-height: 1;
    padding: 0 0.25rem;
    cursor: pointer;
    border-radius: 0.35rem;
}

.clubSessions-action-dismiss:hover[b-2b62izoy7u] {
    background: rgba(35, 82, 124, 0.12);
}

/* #144: compact Upcoming row — one line, no resting meta (full detail lives in the Edit modal). */
.clubSession-row-compact[b-2b62izoy7u] {
    padding: 0.55rem 0;
}

.clubSessions-toolbar[b-2b62izoy7u] {
    display: grid;
    grid-template-columns: 14rem minmax(0, 1fr) auto;
    gap: 0.75rem;
    margin-bottom: 0.65rem;
}

.clubSessions-help[b-2b62izoy7u] {
    color: #4b5f75;
    font-size: 0.9rem;
}

/* #156(e): the hour/minute selects keep their 5.25rem (~84px) — flex:none stops them shrinking below it
   inside the flex time-group when the toolbar is tight (near the 700px kiosk breakpoint). */
.clubSession-time-part[b-2b62izoy7u] {
    width: 5.25rem;
    flex: none;
}

.clubSession-time-group[b-2b62izoy7u] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.clubSession-time-sep[b-2b62izoy7u] {
    color: #5a6d80;
    font-weight: 600;
}

.clubSession-row[b-2b62izoy7u] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 0;
    border-top: 1px solid rgba(92, 119, 145, 0.2);
}

.clubSession-row:first-of-type[b-2b62izoy7u] {
    border-top: 0;
}

.clubSession-title[b-2b62izoy7u] {
    font-weight: 600;
    color: #1f3d5b;
}

.clubSession-profile[b-2b62izoy7u] {
    color: #38556f;
    font-size: 0.85rem;
}

/* SPEC-30 S2: the muted "from schedule" pill on a generated draft row (UX flag #6). */
.clubSession-pill[b-2b62izoy7u] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.45rem;
    border-radius: 0.7rem;
    background: #eef2f6;
    border: 1px solid rgba(92, 119, 145, 0.3);
    color: #5a6d80;
    font-size: 0.72rem;
    font-weight: 600;
    vertical-align: middle;
}

/* SPEC-30 S4 (review polish 3): a min-width kept the mark-full toggle from shifting siblings when its label
   changes ("Mark full" ↔ "Marked full — undo").
   #156(d): 9.5rem dominated the new compact one-line rows and forced the 700px wrap. Reduced to 6.75rem so
   the common "Mark full" state is proportionate; the wider "Marked full — undo" state (infrequent) grows to
   fit, a small acceptable shift traded for a row that no longer wraps early. */
.clubSession-markfull-btn[b-2b62izoy7u] {
    min-width: 6.75rem;
}

/* SPEC-30 S2: the quieter "Scheduled — from your weekly schedule" group header. */
.clubSessions-group-scheduled[b-2b62izoy7u] {
    margin-top: 0.5rem;
}

.clubSessions-group-scheduled h2[b-2b62izoy7u] {
    color: #5a6d80;
}

.clubSession-meta[b-2b62izoy7u] {
    color: #5a6d80;
    font-size: 0.86rem;
}

.clubSession-actions[b-2b62izoy7u] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

@media (max-width: 700px) {
    /* BL-062 (2026-04-26): keep Live Session action buttons in a single
       horizontal row on mobile rather than stacking. Allow wrap as a fallback
       if they really don't fit. Extra left margin on the destructive Delete
       keeps it thumb-distance from Open. */
    .clubSession-actions[b-2b62izoy7u] {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 0.4rem;
    }

    .clubSession-actions > .btn-outline-danger[b-2b62izoy7u] {
        margin-left: 0.4rem;
    }

    /* #156(e): collapse the one-off create toolbar to a single column at the 700px kiosk breakpoint (was
       640.98px). Between 640.98 and 700px the 3-column grid squeezed the date + time selects; single-column
       from 700px gives the time-group full width so the hour/minute selects hold their 84px. */
    .clubSessions-toolbar[b-2b62izoy7u] {
        grid-template-columns: 1fr;
    }
}

.settings-message[b-2b62izoy7u] {
    color: #38556f;
    font-size: 0.86rem;
    margin-left: 0.5rem;
}

.clubSession-settings-modal-backdrop[b-2b62izoy7u] {
    position: fixed;
    inset: 0;
    background: rgba(14, 24, 36, 0.48);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 1100;
}

.clubSession-settings-modal[b-2b62izoy7u] {
    width: min(68rem, 100%);
    max-height: calc(100vh - 2rem);
    overflow: auto;
    background: #ffffff;
    border: 1px solid rgba(92, 119, 145, 0.35);
    border-radius: 0.75rem;
    box-shadow: 0 1.2rem 2.8rem rgba(14, 24, 36, 0.28);
    padding: 1rem;
}

.clubSession-settings-modal-header[b-2b62izoy7u] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.4rem;
}

.clubSession-settings-modal-header h2[b-2b62izoy7u] {
    margin: 0;
}

.clubSession-settings-modal-subtitle[b-2b62izoy7u] {
    margin-bottom: 0.75rem;
}

.clubSession-settings-modal-body[b-2b62izoy7u] {
    border-top: 1px solid rgba(92, 119, 145, 0.2);
    border-bottom: 1px solid rgba(92, 119, 145, 0.2);
    padding: 0.8rem 0;
}

.clubSession-details-grid[b-2b62izoy7u] {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) auto auto;
    gap: 0.6rem;
    margin-bottom: 0.75rem;
}

/* #1017: the shared jump-nav layout inside the draft-settings modal — same grid as the dashboard
   settings-cog modal. Sidebar column + editor when wide; collapses to a single column at <=820px
   (matching the SettingsAnchorNav Responsive chip-row breakpoint) so the chip row sits above the
   editor and never forces a horizontal scroll. */
.clubSession-settings-layout[b-2b62izoy7u] {
    display: grid;
    grid-template-columns: 11.5rem 1fr;
    gap: 0.85rem;
    align-items: start;
}

.clubSession-settings-editor[b-2b62izoy7u] {
    min-width: 0;
}

@media (max-width: 820px) {
    .clubSession-settings-layout[b-2b62izoy7u] {
        grid-template-columns: 1fr;
        gap: 0.5rem;
    }
}

.clubSession-settings-modal-actions[b-2b62izoy7u] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-top: 0.8rem;
}

.clubSession-delete-modal-backdrop[b-2b62izoy7u] {
    position: fixed;
    inset: 0;
    background: rgba(14, 24, 36, 0.48);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 1200;
}

.clubSession-delete-modal[b-2b62izoy7u] {
    width: min(28rem, 100%);
    background: #fff;
    border: 1px solid rgba(92, 119, 145, 0.35);
    border-radius: 0.75rem;
    box-shadow: 0 1rem 2.2rem rgba(14, 24, 36, 0.28);
    padding: 1rem;
}

.clubSession-delete-modal h2[b-2b62izoy7u] {
    margin: 0 0 0.6rem;
    color: #5a1223;
    font-size: 1.2rem;
}

.clubSession-delete-actions[b-2b62izoy7u] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

@media (max-width: 640.98px) {
    /* #156(e): .clubSessions-toolbar single-column moved up to the 700px block. */
    .clubSession-row[b-2b62izoy7u] {
        flex-direction: column;
        align-items: flex-start;
    }

    .clubSession-settings-modal-actions[b-2b62izoy7u] {
        flex-wrap: wrap;
    }

    .clubSession-details-grid[b-2b62izoy7u] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/CompetitionCreate.razor.rz.scp.css */
.club-management-shell[b-91o743vxlx] {
    padding: 0;
}

/* Shared off-white panel (defined per-page in scoped CSS, as Members/Settings do)
   so the type-select cards render as tiles. The --selected / --disabled modifiers
   layer on top of this. */
.club-card[b-91o743vxlx] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.club-management-shell h1[b-91o743vxlx] {
    color: #0d2c55;
    font-size: 2.5rem;
    margin: 0 0 0.5rem;
}

.competition-back-link[b-91o743vxlx] {
    display: inline-block;
    color: #1f4267;
    text-decoration: none;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

.competition-back-link:hover[b-91o743vxlx] {
    text-decoration: underline;
}

.competition-create-prompt[b-91o743vxlx] {
    color: #5a6b80;
    margin-bottom: 1rem;
}

.competition-type-list[b-91o743vxlx] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.competition-type-card[b-91o743vxlx] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    cursor: pointer;
    margin-bottom: 0;
}

.competition-type-card--selected[b-91o743vxlx] {
    border-color: #0d2c55;
    box-shadow: 0 0 0 1px #0d2c55 inset;
}

.competition-type-card--disabled[b-91o743vxlx] {
    cursor: not-allowed;
    opacity: 0.6;
    background: #eef1f5;
}

.competition-type-radio[b-91o743vxlx] {
    margin-top: 0.3rem;
    flex: 0 0 auto;
}

/* Muted empty radio circle on disabled cards so they read as unavailable
   *options* (not plain text rows), mirroring the wireframe's "( ) Singles
   tournament [Coming soon]". Non-focusable, decorative (aria-hidden). */
.competition-type-radio-placeholder[b-91o743vxlx] {
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
    margin-top: 0.3rem;
    border-radius: 50%;
    border: 2px solid #b4bdca;
    background: transparent;
}

.competition-type-title[b-91o743vxlx] {
    color: #0d2c55;
    font-weight: 600;
    font-size: 1.1rem;
}

.competition-type-desc[b-91o743vxlx] {
    color: #5a6b80;
    font-size: 0.95rem;
    margin-top: 0.2rem;
}

.coming-soon-pill[b-91o743vxlx] {
    display: inline-block;
    background: #e6ebf2;
    color: #5a6b80;
    border-radius: 999px;
    padding: 0.05rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 600;
    margin-left: 0.4rem;
    vertical-align: middle;
}

.visually-hidden[b-91o743vxlx] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.competition-create-actions[b-91o743vxlx] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
    /* FAB clearance (ISS-013, rework round 1 feature-wide sweep): the create screen's
       right-aligned Continue also sat under the bottom-right feedback FAB at 1440px. The
       create card is a touch wider than the wizard card, so 4.5rem (which clears the
       wizard) left the Continue right edge at 1344 vs the FAB's 1329 — bumped to 6rem so
       the create Continue clears the FAB with the same headroom. Reset at ≤700px. */
    padding-right: 6rem;
}

/* Touch floor (ISS-013, rework round 1): Cancel + Continue clear 44px at ALL
   viewports, not just ≤700px. Cancel is a NavLink-rendered <a class="btn"> — ::deep
   pierces the child-component boundary so the rule reaches it as well as the plain
   Continue <button>. Mirrors the CompetitionSetup wizard-actions pattern. */
.competition-create-actions .btn[b-91o743vxlx],
.competition-create-actions[b-91o743vxlx]  .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 700px) {
    .competition-create-actions[b-91o743vxlx] {
        flex-direction: column-reverse;
        /* Actions stack full-width on mobile; drop the desktop FAB clearance. */
        padding-right: 0;
    }

    /* On mobile the actions go full-width; the 44px floor already applies above. */
    .competition-create-actions .btn[b-91o743vxlx],
    .competition-create-actions[b-91o743vxlx]  .btn {
        width: 100%;
    }
}
/* /Components/Pages/CompetitionInProgress.razor.rz.scp.css */
/* In-progress competition surface (slice 7). Base shell/card/status-pill tokens
   replicated per-page (the Members/Settings/Competitions precedent — scoped CSS doesn't
   share). New: standings tables + matches list. AA contrast measured (see build report). */
.club-management-shell[b-7u6f3d3p1c] {
    padding: 0;
}

.club-card[b-7u6f3d3p1c] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

/* Action buttons clear the 44px touch floor at all viewports (NavLink renders <a>,
   hence ::deep), matching the wizard. */
.club-card[b-7u6f3d3p1c]  .btn,
.competition-wizard-actions[b-7u6f3d3p1c]  .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.competition-inprogress-header[b-7u6f3d3p1c] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.competition-inprogress-title[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 2rem;
    margin: 0 0 0.25rem;
}

.competition-inprogress-counts[b-7u6f3d3p1c] {
    color: #5a6b80;
    margin: 0;
}

/* The header right column: the status pill stacked above the "View setup" link
   (Mike-reported defect round). Right-aligned on desktop so it hangs off the title block;
   shrinks before the title (flex-shrink:0 keeps the pill/link intact). */
.competition-inprogress-header-aside[b-7u6f3d3p1c] {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* "View setup" outline link — 44px touch floor (the header isn't covered by the
   .club-card / .competition-wizard-actions ::deep .btn rule, so set it here). NavLink
   renders an <a>, hence ::deep. nowrap keeps "View setup" on one line at 390px. */
.competition-inprogress-header-aside[b-7u6f3d3p1c]  .competition-inprogress-view-setup {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
}

/* ── Slice-10 dashboard section-nav chips ── same-page fragment anchors over the inline
   sections (Overview / Groups / Knockout). Pill chips, 44px touch target, wrap on mobile. */
.competition-dashboard-nav[b-7u6f3d3p1c] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.competition-dashboard-chip[b-7u6f3d3p1c] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid #c3ccd8;
    border-radius: 999px;
    background: #fff;
    /* #1f3147 on #fff = 12.1:1 (AA). */
    color: #1f3147;
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    /* Rendered as a <button> (LR-1: in-page scroll, not a navigating anchor) — normalise
       the UA button defaults so it matches the previous chip styling. */
    font-family: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.competition-dashboard-chip:hover[b-7u6f3d3p1c] {
    background: #f2f5f9;
}

.competition-dashboard-chip:focus-visible[b-7u6f3d3p1c] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
}

/* Rework major 4: the in-view section's chip reads active — navy fill + white text, matching
   the app's nav active treatment + the in-progress status pill. #fff on #0d2c55 = 13.1:1 (AA). */
.competition-dashboard-chip--active[b-7u6f3d3p1c] {
    background: #0d2c55;
    border-color: #0d2c55;
    color: #fff;
}

.competition-dashboard-chip--active:hover[b-7u6f3d3p1c] {
    background: #0d2c55;
}

/* Fragment scroll targets clear the (potential) sticky header / give breathing room when
   the chip scrolls a section to the top. */
#overview[b-7u6f3d3p1c],
.competition-groups-anchor[b-7u6f3d3p1c],
.competition-knockout[b-7u6f3d3p1c] {
    scroll-margin-top: 1rem;
}

/* LR-19: the "Open Results Desk" CTA styles are removed with the CTA — the Desk is parked. */

/* ── LR-29: group filter/selector on the Groups view ── chips/segmented buttons (one tap,
   touch-friendly). Mirrors the dashboard-chip token set (44px, navy active) under group-
   selector-scoped names - scoped CSS doesn't cross components, so the tokens are replicated
   (the same Members/Settings/Competitions precedent). Wraps on mobile; sits above the cards. */
.competition-group-selector[b-7u6f3d3p1c] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.competition-group-chip[b-7u6f3d3p1c] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid #c3ccd8;
    border-radius: 999px;
    background: #fff;
    /* #1f3147 on #fff = 12.1:1 (AA). */
    color: #1f3147;
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.competition-group-chip:hover[b-7u6f3d3p1c] {
    background: #f2f5f9;
}

.competition-group-chip:focus-visible[b-7u6f3d3p1c] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
}

/* The selected group's chip reads active - navy fill + white text. #fff on #0d2c55 = 13.1:1 (AA). */
.competition-group-chip--active[b-7u6f3d3p1c] {
    background: #0d2c55;
    border-color: #0d2c55;
    color: #fff;
}

.competition-group-chip--active:hover[b-7u6f3d3p1c] {
    background: #0d2c55;
}

.competition-standings-card[b-7u6f3d3p1c] {
    padding: 1rem 1.25rem 1.25rem;
}

.competition-standings-title[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 1.35rem;
    margin: 0 0 0.5rem;
}

/* LR-31c: group-header colour-coding. A deterministic accent per group index (cycled by the
   component's GroupAccentClass, palette of 6). A coloured left-border bar + a faint tinted
   background distinguishes stacked groups at a glance; the heading text stays dark navy
   (#0d2c55, AA on every tint) so legibility holds at 390 and desktop. No new brand colours -
   the hues are an accessible accent set keyed to the app's blue/teal/green/amber family. */
.competition-standings-title.competition-group-accent-0[b-7u6f3d3p1c],
.competition-standings-title.competition-group-accent-1[b-7u6f3d3p1c],
.competition-standings-title.competition-group-accent-2[b-7u6f3d3p1c],
.competition-standings-title.competition-group-accent-3[b-7u6f3d3p1c],
.competition-standings-title.competition-group-accent-4[b-7u6f3d3p1c],
.competition-standings-title.competition-group-accent-5[b-7u6f3d3p1c] {
    border-left: 4px solid transparent;
    padding: 0.15rem 0 0.15rem 0.6rem;
    border-radius: 0.2rem;
}

.competition-group-accent-0[b-7u6f3d3p1c] { border-left-color: #2563a8; background: rgba(37, 99, 168, 0.10); }
.competition-group-accent-1[b-7u6f3d3p1c] { border-left-color: #1f8a70; background: rgba(31, 138, 112, 0.10); }
.competition-group-accent-2[b-7u6f3d3p1c] { border-left-color: #b3541e; background: rgba(179, 84, 30, 0.10); }
.competition-group-accent-3[b-7u6f3d3p1c] { border-left-color: #7048a8; background: rgba(112, 72, 168, 0.10); }
.competition-group-accent-4[b-7u6f3d3p1c] { border-left-color: #a01e58; background: rgba(160, 30, 88, 0.10); }
.competition-group-accent-5[b-7u6f3d3p1c] { border-left-color: #4b7a1e; background: rgba(75, 122, 30, 0.10); }

.competition-standings-empty[b-7u6f3d3p1c] {
    color: #5a6b80;
    margin: 0 0 1rem;
}

/* LR-27: table-sm standings # · Pair · P · W · L · PF · PA · PD · Pts. Numeric columns
   right-aligned + narrow; the pair column takes the slack. Navy header on the off-white
   card (>12:1). At <=700px the table reflows to a stacked mini-card (see the media block). */
.competition-standings-table[b-7u6f3d3p1c] {
    width: 100%;
    margin-bottom: 1rem;
}

.competition-standings-table thead th[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 0.85rem;
    border-bottom: 2px solid rgba(13, 44, 85, 0.15);
    text-align: left;
}

/* The numeric headers (P/W/L/PF/PA/PD/Pts) must follow their right-aligned values, or the
   labels float left of the numbers below them. This needs to out-specify the thead th rule
   above, which otherwise wins over .competition-standings-num's text-align. */
.competition-standings-table thead th.competition-standings-num[b-7u6f3d3p1c] {
    text-align: right;
}

.competition-standings-table td[b-7u6f3d3p1c] {
    color: #24384f;
    vertical-align: middle;
}

.competition-standings-rank-col[b-7u6f3d3p1c] {
    width: 2.25rem;
    color: #5a6b80;
    font-variant-numeric: tabular-nums;
}

.competition-standings-pair[b-7u6f3d3p1c] {
    font-weight: 600;
}

.competition-standings-num[b-7u6f3d3p1c] {
    text-align: right;
    /* LR-27: nine columns now share the row - narrow the numeric columns so all fit the
       desktop card with the pair column taking the slack (no horizontal scroll >=700px). */
    width: 2.5rem;
    font-variant-numeric: tabular-nums;
}

/* LR-27: the table-points column reads as the at-a-glance result - slightly heavier + the
   navy used elsewhere for emphasis. #0d2c55 on the off-white card is well over AA. */
.competition-standings-pts[b-7u6f3d3p1c] {
    font-weight: 700;
    color: #0d2c55;
}

.competition-matches-heading[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 1rem;
    margin: 0.75rem 0 0.5rem;
}

.competition-matches-list[b-7u6f3d3p1c] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.competition-match-row[b-7u6f3d3p1c] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    /* wrap so the pairs + meta drop onto their own lines at 390, never pushing the row wider
       (no h-scroll). The LR-8a head start is now an inline "(+N)" suffix inside the pair span,
       not a separate full-width line. */
    flex-wrap: wrap;
    padding: 0.5rem 0.75rem;
    background: #fff;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.2rem;
}

/* LR-8a: the head start shown INLINE in brackets after the weaker team's name — "(+N)"
   (replaces the LR-2 under-row repeated-name line). A subtle suffix on the pair span; an
   even match shows NOTHING (PM ruling). #3a5072 on #fff = 7.4:1 (AA). nowrap keeps the short
   bracket from breaking mid-token; it sits inside the wrapping .competition-match-pair so it
   never widens the row (no horizontal scroll at 390). */
.competition-match-headstart-inline[b-7u6f3d3p1c] {
    color: #3a5072;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── LR-18: running-surface score entry as a session-parity POPUP panel ──
   (supersedes the 2C-ii inline-in-row block). A fixed-overlay panel anchored over the page
   (the "score panel popup"), with the same card/rows/actions language as the in-session score
   pane. The shared grid stays Inline (it flows within the popup, below the trigger; the popup
   is the overlay). The trigger + grid reuse the same LR-9 amber/unset palette as Match Entry /
   the (now-dormant) Results Desk, defined here (the Match Entry classes are component-scoped). */

/* The dimmed dismiss backdrop behind the popup (click to close). */
.competition-score-popup-backdrop[b-7u6f3d3p1c] {
    position: fixed;
    inset: 0;
    background: rgba(13, 44, 85, 0.45);
    z-index: 1040;
}

/* The popup panel itself: a centered white card over the backdrop, scrollable if the grid is
   tall at 390. max-width keeps it tidy on desktop; full-bleed-ish margins on mobile. */
.competition-score-popup[b-7u6f3d3p1c] {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1041;
    /* LR-22 (round 4A): the inline 10-column decade grid (44px chips + gaps) needs ~34rem of
       popup width to lay out one full decade per row inside the popover's own padding; the old
       min(92vw, 24rem) was far too narrow, clipping the right-hand chips (Mike's "doesn't fit /
       needs scrolling"). Widen so the FULL grid + Save/Cancel fit on open without any scroll at
       the desktop band; 96vw keeps it inside the viewport at 390 (where the grid's <=600px CSS
       shrinks chips to fit). */
    width: min(96vw, 34rem);
    max-height: 90vh;
    overflow-y: auto;
    background: #fff;
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.5rem;
    box-shadow: 0 1.25rem 2.5rem rgba(13, 44, 85, 0.28);
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* The match name as the popup's self-identifying header (it is detached from its list row). */
.competition-score-popup-title[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0 0 0.25rem;
    /* LR-23 (round 4A): the "Entrant1 v Entrant2" header renders on a single line; a long
       label ellipsis-truncates (full text on hover via the title attr) rather than wrapping. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* LR-31a: the head-start echo line inside the popup ("X start on +N"). Reads directly under
   the title at a calm, secondary weight - it's context, not the action. >12:1 navy-on-card. */
.competition-score-popup-headstart[b-7u6f3d3p1c] {
    color: #0d2c55;
    font-size: 0.95rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

/* LR-28: the single per-row in-place entry affordance ("Enter score" on a Pending row,
   "Edit score" on a Complete row). The redundant deep-link button is removed; this is the
   row's only entry+correction control now. >= 44px tap. */
.competition-match-enter-inline[b-7u6f3d3p1c] {
    min-height: 44px;
}

/* #574: the winner-first step 1 - "Which pair won?" plus the two pair-name buttons. Values
   mirror the club-night card's .pending-score-winner-* rules (ClubSessionDashboard.razor.css)
   so the two features read as the same control; the class names are competition-scoped because
   the session's DOM contract is asserted by the session's own suites (spec Round 10A, B2). The
   two buttons stack on a narrow phone and sit side by side from 480px, so a long pair name is
   never truncated at 390. */
.competition-score-winner-prompt[b-7u6f3d3p1c] {
    color: #355775;
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-choices[b-7u6f3d3p1c] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
    margin-bottom: 0.25rem;
}

@media (min-width: 480px) {
    .competition-score-winner-choices[b-7u6f3d3p1c] {
        grid-template-columns: 1fr 1fr;
    }
}

.competition-score-winner-btn[b-7u6f3d3p1c] {
    width: 100%;
    min-height: 3rem;
    border: 2px solid #9fb7cf;
    background: #f2f8ff;
    color: #2d4f6d;
    font-weight: 700;
    text-align: center;
    justify-content: center;
    white-space: normal;
}

.competition-score-winner-btn:hover:not(:disabled)[b-7u6f3d3p1c] {
    background: #e2f0ff;
    border-color: #6f93b8;
}

/* The pair just indicated as the winner, while the pad collects the other pair's score. The
   inline grid does not cover these buttons, so the tap must read as acknowledged. Not colour
   alone: the checkmark glyph and the heavier border carry it too. */
.competition-score-winner-btn--chosen[b-7u6f3d3p1c] {
    background: #dff0df;
    border-color: #2f7d33;
    color: #1d4a20;
}

.competition-score-winner-btn--chosen[b-7u6f3d3p1c]::before {
    content: "\2713\00a0";
}

@media (any-pointer: coarse) and (min-width: 601px) {
    .competition-score-winner-btn[b-7u6f3d3p1c] {
        min-height: 3.25rem;
        font-size: 1.05rem;
    }
}

/* #574 step 2: the caption naming whose score is wanted, and the "won" tag beside the winning
   pair. Mirrors the club-night card's .pending-score-loser-caption / .pending-score-winner-tag. */
.competition-score-loser-caption[b-7u6f3d3p1c] {
    color: #60778f;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-tag[b-7u6f3d3p1c] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0 0.35rem;
    border-radius: 0.5rem;
    background: #2f7d33;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    vertical-align: middle;
}

.competition-match-entry-scores[b-7u6f3d3p1c] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.competition-match-entry-score-row[b-7u6f3d3p1c] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.competition-match-entry-score-label[b-7u6f3d3p1c] {
    color: #24384f;
    font-weight: 600;
    font-size: 1.05rem;
    margin: 0;
}

/* The tap-to-open score field: large numeric look, comfortably over 44px. */
.competition-match-entry-score-input[b-7u6f3d3p1c] {
    width: 5rem;
    min-height: 48px;
    font-size: 1.5rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    line-height: 1.2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.score-entry-trigger:disabled[b-7u6f3d3p1c] {
    cursor: not-allowed;
    opacity: 0.65;
}

/* Unset trigger: the en-dash placeholder reads muted (not a real "0"). #6a7a8d on #fff = 4.6:1. */
.score-entry-trigger--unset[b-7u6f3d3p1c] {
    color: #6a7a8d;
    font-weight: 600;
}

/* LR-9 (session-parity): an AUTO-DEFAULTED winner (21, filled when the loser was entered) reads
   amber — the same coloured-state language as the in-session pane. A manual re-tap flips it
   plain. Same palette as the session / Match Entry: bg #fff0bd / border #e3c56f / text #664b00. */
.score-entry-trigger--auto[b-7u6f3d3p1c] {
    background: #fff0bd;
    border-color: #e3c56f;
    color: #664b00;
}

/* Save + Cancel aligned directly BENEATH the score grid (LR-18 AC-LR18.2): the last child of
   the popup, so once a score is entered Save is the immediate adjacent tap. Save grows to fill
   so it reads as the primary; both >= 44px. */
.competition-score-popup-actions[b-7u6f3d3p1c] {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.competition-score-popup-actions .btn[b-7u6f3d3p1c] {
    min-height: 44px;
}

.competition-score-popup-save[b-7u6f3d3p1c] {
    flex: 1 1 auto;
}

.competition-score-popup-error[b-7u6f3d3p1c] {
    margin: 0;
}

/* Fill the row's free space (everything left of the meta) so the central "v" sits on a
   consistent vertical spine down the group instead of wandering with each row's name
   lengths. The two pair columns are equal halves (flex: 1 1 0 below); the left team is
   right-aligned and the right team left-aligned so both names meet the v in the middle
   (classic fixtures alignment). */
.competition-match-pairs[b-7u6f3d3p1c] {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    color: #24384f;
}

/* Each pair grows to fill its slot. Content packs to the start (the inline "(+N)" head
   start hugs the team name); the score still floats to the pair's outer edge via its own
   margin-left:auto below, so entered scores column-align across the two sides of a row and
   read as a tidy right-hand column (UX rework R1 polish 8). (Was justify-content:
   space-between, which also flung a score-less head start to the far edge once the pair
   fills the row.) The score span carries a min-width so single- and double-digit scores
   still line up. */
.competition-match-pair[b-7u6f3d3p1c] {
    display: flex;
    flex: 1 1 0;
    min-width: 0;
    align-items: baseline;
    justify-content: flex-start;
    gap: 0.35rem;
}

/* Left team hugs the v on its right edge; right team (default) hugs it on its left edge,
   so the two names converge on the central spine. */
.competition-match-pairs > .competition-match-pair:first-child[b-7u6f3d3p1c] {
    justify-content: flex-end;
    text-align: right;
}

/* Centre scoreline: the right team's score is pulled IN FRONT of its name (order:-1) so it
   sits at the left end of its half, hugging the "-"; the left team's score already rides the
   right end of its flex-end half. Together a completed row reads "Team A  21 - 15  Team B"
   instead of flinging the scores to the outer edges (far apart on wide monitors). */
.competition-match-pairs > .competition-match-pair:last-child .competition-match-score[b-7u6f3d3p1c] {
    order: -1;
}

.competition-match-pair--winner[b-7u6f3d3p1c] {
    font-weight: 700;
    color: #1d6b39;
}

.competition-match-score[b-7u6f3d3p1c] {
    min-width: 1.5rem;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

.competition-match-vs[b-7u6f3d3p1c] {
    color: #7a8699;
    font-size: 0.85rem;
}

.competition-match-meta[b-7u6f3d3p1c] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* LR-28: the per-match deep-link Enter/Edit NavLink (.competition-match-enter) is removed
   from the row; its ::deep style is dropped with it. The single in-place button styling lives
   on .competition-match-enter-inline above. */

.competition-wizard-actions[b-7u6f3d3p1c] {
    display: flex;
    gap: 0.75rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}

.competition-setup-skeleton[b-7u6f3d3p1c] {
    min-height: 8rem;
    background: linear-gradient(90deg, #f6f8fb 25%, #eef2f7 50%, #f6f8fb 75%);
}

/* Status pills (replicated tokens — scoped CSS). */
.status-pill[b-7u6f3d3p1c] {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0.15rem 0.65rem;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.4;
}

.status-pill--draft[b-7u6f3d3p1c] {
    background: #e6ebf2;
    color: #3a4d66;
}

.status-pill--in-progress[b-7u6f3d3p1c] {
    background: #d7ebdd;
    color: #1d6b39;
}

.status-pill--complete[b-7u6f3d3p1c] {
    background: #0d2c55;
    color: #fff;
}

/* Mobile/tablet: single column, the match row stacks pairs above the meta so nothing
   gets squeezed off a 390px viewport. No horizontal scroll. */
@media (max-width: 700px) {
    .competition-inprogress-header[b-7u6f3d3p1c] {
        flex-direction: column;
        align-items: stretch;
    }

    /* Stop the status pill stretching to a full-width banner in the stacked header — it
       should keep its intrinsic pill width, left-aligned (UX rework R1 polish 7). The
       aside (pill + View setup) left-aligns its contents in the stacked layout. */
    .competition-inprogress-header-aside[b-7u6f3d3p1c] {
        align-items: flex-start;
    }

    .competition-inprogress-header .status-pill[b-7u6f3d3p1c] {
        align-self: flex-start;
    }

    .competition-match-row[b-7u6f3d3p1c] {
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
    }

    .competition-match-meta[b-7u6f3d3p1c] {
        justify-content: space-between;
    }

    /* LR-27: standings reflow (AC-LR27.5). Nine columns will not fit 390px, so each standing
       row becomes a stacked mini-card (the slice-4 "table on desktop, stacked rows on mobile"
       idiom). The header row is hidden; each cell carries its label from data-label. The cells
       are ordered into a two-line layout via flex order: PRIMARY line = # · Pair · W-L · Pts
       (rank, name, win-loss, table points), SECONDARY line = P · PF · PA · PD (the detail). No
       value dropped, no horizontal scroll. */
    .competition-standings-table thead[b-7u6f3d3p1c] {
        /* Visually hide the header but keep it for assistive tech (the cards carry labels). */
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .competition-standings-table[b-7u6f3d3p1c],
    .competition-standings-table tbody[b-7u6f3d3p1c] {
        display: block;
        width: 100%;
    }

    .competition-standings-table tbody tr[b-7u6f3d3p1c] {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0.4rem 0.75rem;
        padding: 0.5rem 0.65rem;
        margin-bottom: 0.5rem;
        background: #fff;
        border: 1px solid rgba(13, 44, 85, 0.08);
        border-radius: 0.2rem;
    }

    .competition-standings-table tbody td[b-7u6f3d3p1c] {
        display: inline-flex;
        align-items: baseline;
        width: auto;
        padding: 0;
        border: 0;
        font-variant-numeric: tabular-nums;
    }

    /* Secondary-detail cells (P / PF / PA / PD) carry their label inline; the primary cells
       (#, Pair, W, L, Pts) read on their own. The label comes from data-label via ::before. */
    .competition-standings-table tbody td[data-label="P"][b-7u6f3d3p1c]::before,
    .competition-standings-table tbody td[data-label="PF"][b-7u6f3d3p1c]::before,
    .competition-standings-table tbody td[data-label="PA"][b-7u6f3d3p1c]::before,
    .competition-standings-table tbody td[data-label="PD"][b-7u6f3d3p1c]::before {
        content: attr(data-label) " ";
        color: #5a6b80;
        font-size: 0.8rem;
        font-weight: 600;
        margin-right: 0.2rem;
    }

    /* Primary line: # · Pair · W-L · Pts. Force a line break after the primary cells so the
       detail cells flow onto a second line. The rank + pair take the full primary width with
       W/L/Pts to their right. */
    .competition-standings-table tbody td[data-label="#"][b-7u6f3d3p1c] {
        order: 0;
        color: #5a6b80;
        font-weight: 600;
    }

    .competition-standings-table tbody td[data-label="Pair"][b-7u6f3d3p1c] {
        order: 1;
        flex: 1 1 auto;
        min-width: 0;
        font-weight: 600;
        /* LR-23 width discipline: a long pair name truncates rather than wrapping the card. */
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* W and L render as a combined "W-L" reading on the primary line: show W, then L prefixed
       by a hyphen, with the column labels suppressed (the W-L shape is self-evident here). */
    .competition-standings-table tbody td[data-label="W"][b-7u6f3d3p1c] {
        order: 2;
        font-weight: 700;
        color: #1d6b39;
    }

    .competition-standings-table tbody td[data-label="L"][b-7u6f3d3p1c] {
        order: 3;
        font-weight: 700;
        color: #1d6b39;
    }

    .competition-standings-table tbody td[data-label="L"][b-7u6f3d3p1c]::before {
        content: "-";
        color: #1d6b39;
    }

    .competition-standings-table tbody td[data-label="Pts"][b-7u6f3d3p1c] {
        order: 4;
        font-weight: 700;
        color: #0d2c55;
    }

    .competition-standings-table tbody td[data-label="Pts"][b-7u6f3d3p1c]::before {
        content: "Pts ";
        color: #5a6b80;
        font-size: 0.8rem;
        font-weight: 600;
        margin-right: 0.2rem;
    }

    /* Secondary line: P · PF · PA · PD. The Pair cell (flex:1 1 auto) grows to fill the rest
       of line 1, so the detail cells wrap onto line 2 together. A small top margin separates
       the two lines; all four sit side by side (none forced to its own row). */
    .competition-standings-table tbody td[data-label="P"][b-7u6f3d3p1c] {
        order: 5;
        margin-top: 0.2rem;
        color: #24384f;
    }

    .competition-standings-table tbody td[data-label="PF"][b-7u6f3d3p1c] { order: 6; margin-top: 0.2rem; color: #24384f; }
    .competition-standings-table tbody td[data-label="PA"][b-7u6f3d3p1c] { order: 7; margin-top: 0.2rem; color: #24384f; }
    .competition-standings-table tbody td[data-label="PD"][b-7u6f3d3p1c] { order: 8; margin-top: 0.2rem; color: #24384f; }
}

/* ── Knockout section (slice 9) ── */
.competition-group-locked[b-7u6f3d3p1c] {
    margin: 0.5rem 0 0;
    font-style: italic;
    color: #7a8699;
}

.competition-knockout-title[b-7u6f3d3p1c] {
    font-size: 1.1rem;
    font-weight: 600;
    color: #0d2c55;
    margin: 0 0 0.75rem;
}

.competition-knockout-generate[b-7u6f3d3p1c] {
    min-height: 44px;
    /* A bare <button> with min-height + default inline-block measured ~38px (the text box
       doesn't stretch to min-height). inline-flex + centring makes the 44px actually render. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.competition-knockout-tie[b-7u6f3d3p1c] {
    border: 1px solid #d7deea;
    border-radius: 8px;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
}

.competition-knockout-tie-group[b-7u6f3d3p1c] {
    color: #24384f;
}

.competition-knockout-tie-options[b-7u6f3d3p1c] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.competition-knockout-tie-option[b-7u6f3d3p1c] {
    min-height: 44px;
}

.competition-knockout-ungenerate[b-7u6f3d3p1c] {
    margin-top: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid #eef2f7;
}

.competition-knockout-ungenerate-btn[b-7u6f3d3p1c] {
    min-height: 44px;
}

/* The un-generate confirm copy (polish 4): a bold dark statement, not an italic question. */
.competition-knockout-ungenerate-warn[b-7u6f3d3p1c] {
    color: #24384f;
    margin-top: 0;
}

/* Completed screen (Screen 15): winner / runner-up + stats. */
.competition-completed[b-7u6f3d3p1c] {
    text-align: center;
    padding: 0.5rem 0 1rem;
}

.competition-completed-trophy[b-7u6f3d3p1c] {
    font-size: 2.5rem;
    margin: 0 0 0.25rem;
}

.competition-completed-winner[b-7u6f3d3p1c] {
    font-size: 1.25rem;
    color: #0d2c55;
    margin: 0 0 0.25rem;
}

.competition-completed-runner-up[b-7u6f3d3p1c] {
    color: #24384f;
    margin: 0 0 0.5rem;
}

.competition-completed-stats[b-7u6f3d3p1c] {
    margin: 0;
}

/* MAJOR 3: the completed summary sat flush against the bracket below it (they bled together).
   Add a visual break on the bracket when it directly follows the completed block. The bracket
   is a child component, so reach it with ::deep. */
.competition-completed[b-7u6f3d3p1c] +  .knockout-bracket {
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid #d7deea;
}
/* /Components/Pages/CompetitionMatchEntry.razor.rz.scp.css */
/* Match Entry (slice 7). Single-column, large numeric inputs, kiosk-grade for the
   tablet-at-the-venue. Base shell/card tokens replicated per-page (scoped CSS). AA
   contrast measured (see build report). */
.club-management-shell[b-x0o0np4wjm] {
    padding: 0;
}

.club-card[b-x0o0np4wjm] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1.25rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.club-card[b-x0o0np4wjm]  .btn,
.competition-wizard-actions[b-x0o0np4wjm]  .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.competition-match-entry[b-x0o0np4wjm] {
    max-width: 32rem;
}

/* Rework polish 6: the title block sits at shell level (above the card), navy treatment. */
.competition-match-entry-header[b-x0o0np4wjm] {
    max-width: 32rem;
    margin-bottom: 0.85rem;
}

.competition-match-entry-title[b-x0o0np4wjm] {
    color: #0d2c55;
    font-size: 1.75rem;
    margin: 0 0 0.15rem;
}

.competition-match-entry-group[b-x0o0np4wjm] {
    color: #5a6b80;
    margin: 0 0 1rem;
}

/* Edit signal (UX rework R1, option a): a muted line under the "Edit result" heading when
   correcting an already-saved result. */
.competition-match-entry-editing[b-x0o0np4wjm] {
    color: #5a6b80;
    font-style: italic;
    margin: 0 0 0.5rem;
}

.competition-match-entry-pairs[b-x0o0np4wjm] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.competition-match-entry-pair[b-x0o0np4wjm] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.5rem 0.75rem;
    background: #fff;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.2rem;
}

.competition-match-entry-pair-name[b-x0o0np4wjm] {
    color: #0d2c55;
    font-weight: 700;
    font-size: 1.1rem;
    /* LR-23 (round 4A): one width discipline across the three name surfaces — typical pair
       labels render on a SINGLE line (no two-line wrap); an extreme label ellipsis-truncates
       with the full name on hover (title attr) rather than wrapping. min-width:0 lets it shrink
       within the flex row so the rating stays put. */
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.competition-match-entry-pair-rating[b-x0o0np4wjm] {
    color: #5a6b80;
    font-size: 0.9rem;
    font-variant-numeric: tabular-nums;
}

/* The head start: plain "start on +N" language (moat rule — the number IS the start
   score). Reads as a prominent status line, not a maths formula. #1d6b39 on #f6f8fb. */
.competition-match-entry-headstart[b-x0o0np4wjm] {
    color: #155a30;
    font-weight: 600;
    background: #e7f3ec;
    border-radius: 0.2rem;
    padding: 0.5rem 0.75rem;
    margin: 0 0 1.25rem;
}

.competition-match-entry-headstart--even[b-x0o0np4wjm] {
    color: #3a4d66;
    background: #eef2f7;
    font-weight: 500;
}

.competition-match-entry-score-heading[b-x0o0np4wjm] {
    color: #0d2c55;
    font-size: 1.1rem;
    margin: 0 0 0.75rem;
}

/* #574: the winner-first step 1 - "Which pair won?" plus the two pair-name buttons. Values mirror
   the club-night card's .pending-score-winner-* rules (ClubSessionDashboard.razor.css) so the two
   features read as the same control; the class names are competition-scoped because the session's
   DOM contract is asserted by the session's own suites (spec Round 10A, B2). Stacked at 390 so a
   long pair name is never truncated; side by side from 480px. */
.competition-score-winner-prompt[b-x0o0np4wjm] {
    color: #355775;
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-choices[b-x0o0np4wjm] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

@media (min-width: 480px) {
    .competition-score-winner-choices[b-x0o0np4wjm] {
        grid-template-columns: 1fr 1fr;
    }
}

.competition-score-winner-btn[b-x0o0np4wjm] {
    width: 100%;
    min-height: 3rem;
    border: 2px solid #9fb7cf;
    background: #f2f8ff;
    color: #2d4f6d;
    font-weight: 700;
    text-align: center;
    justify-content: center;
    white-space: normal;
}

.competition-score-winner-btn:hover:not(:disabled)[b-x0o0np4wjm] {
    background: #e2f0ff;
    border-color: #6f93b8;
}

/* The pair just indicated as the winner, while the pad collects the other pair's score. Not
   colour alone: the checkmark glyph and the heavier border carry it too. */
.competition-score-winner-btn--chosen[b-x0o0np4wjm] {
    background: #dff0df;
    border-color: #2f7d33;
    color: #1d4a20;
}

.competition-score-winner-btn--chosen[b-x0o0np4wjm]::before {
    content: "\2713\00a0";
}

@media (any-pointer: coarse) and (min-width: 601px) {
    .competition-score-winner-btn[b-x0o0np4wjm] {
        min-height: 3.25rem;
        font-size: 1.05rem;
    }
}

/* #574 step 2: the caption naming whose score is wanted, and the "won" tag beside the winning
   pair. Mirrors the club-night card's .pending-score-loser-caption / .pending-score-winner-tag. */
.competition-score-loser-caption[b-x0o0np4wjm] {
    color: #60778f;
    font-weight: 600;
    font-size: 0.9rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-tag[b-x0o0np4wjm] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0 0.35rem;
    border-radius: 0.5rem;
    background: #2f7d33;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    vertical-align: middle;
}

.competition-match-entry-scores[b-x0o0np4wjm] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.competition-match-entry-score-row[b-x0o0np4wjm] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.competition-match-entry-score-label[b-x0o0np4wjm] {
    color: #24384f;
    font-weight: 600;
    font-size: 1.05rem;
    margin: 0;
}

/* Large numeric input — kiosk-grade, comfortably over 44px, big readable digits. Spinner
   arrows suppressed (UX rework R1 polish 6): they crowd the big digits and aren't a useful
   affordance on the kiosk; inputmode="numeric" keeps the numeric keypad on touch. */
.competition-match-entry-score-input[b-x0o0np4wjm] {
    width: 5.5rem;
    min-height: 56px;
    font-size: 1.6rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    padding: 0.25rem 0.5rem;
    -moz-appearance: textfield;
    appearance: textfield;
}

.competition-match-entry-score-input[b-x0o0np4wjm]::-webkit-outer-spin-button,
.competition-match-entry-score-input[b-x0o0np4wjm]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* LR-3: the score is now a tap-to-open button (opens the shared decade grid). It keeps the
   large numeric look (centred, bold, tabular) but reads as a tappable field. */
.score-entry-trigger[b-x0o0np4wjm] {
    cursor: pointer;
    line-height: 1.2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.score-entry-trigger:disabled[b-x0o0np4wjm] {
    cursor: not-allowed;
    opacity: 0.65;
}

/* Unset trigger (rework major 1): the en-dash placeholder reads muted (not a real "0" score),
   mirroring the session dashboard's unset/"Tap to enter" distinction. #6a7a8d on #fff = 4.6:1. */
.score-entry-trigger--unset[b-x0o0np4wjm] {
    color: #6a7a8d;
    font-weight: 600;
}

/* LR-9 (session-parity): a value AUTO-DEFAULTED to the §6 target (21) when the OTHER side was
   entered as the loser reads amber — the same coloured-state language as the in-session
   pending-score pane's auto state (.pending-score-input-auto). A manual override flips it back to
   the plain set state. Same palette as the session: bg #fff0bd / border #e3c56f / text #664b00. */
.score-entry-trigger--auto[b-x0o0np4wjm] {
    background: #fff0bd;
    border-color: #e3c56f;
    color: #664b00;
}

.competition-match-entry-error[b-x0o0np4wjm] {
    margin-bottom: 1rem;
}

.competition-match-entry-actions[b-x0o0np4wjm] {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* The primary Save: full-width-leaning, dominant, >= 44px (kiosk). */
.competition-match-entry-save[b-x0o0np4wjm] {
    flex: 1 1 12rem;
    min-height: 52px;
    font-size: 1.1rem;
    font-weight: 600;
}

.competition-match-entry-saved[b-x0o0np4wjm] {
    margin-bottom: 1rem;
}

.competition-wizard-actions[b-x0o0np4wjm] {
    display: flex;
    gap: 0.75rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}

.competition-setup-skeleton[b-x0o0np4wjm] {
    min-height: 8rem;
    background: linear-gradient(90deg, #f6f8fb 25%, #eef2f7 50%, #f6f8fb 75%);
}

/* Mobile: single column, the score rows + actions go full width, no horizontal scroll. */
@media (max-width: 700px) {
    .competition-match-entry[b-x0o0np4wjm] {
        max-width: 100%;
    }

    .competition-match-entry-actions[b-x0o0np4wjm] {
        flex-direction: column;
        align-items: stretch;
    }

    .competition-match-entry-save[b-x0o0np4wjm] {
        flex: 1 1 auto;
    }
}
/* /Components/Pages/CompetitionResultsDesk.razor.rz.scp.css */
/* Results Desk (slice 8). Kiosk-grade, 390-mobile-PRIMARY: arm's-length one-handed entry.
   page--kiosk (MainLayout) supplies the full-width chrome-reduced shell; this page sizes the
   inputs/Save/steppers well above the touch floor. Base card tokens replicated (scoped CSS).
   AA contrast measured (see build report). */
.competition-desk-shell[b-o922ycifi9] {
    padding: 0;
    max-width: 40rem;
    margin: 0 auto;
}

.club-card[b-o922ycifi9] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1.25rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.club-card[b-o922ycifi9]  .btn,
.competition-wizard-actions[b-o922ycifi9]  .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Kiosk-grade button heights (pre-pass): these must beat the 44px card floor above, so they
   carry higher specificity (.competition-desk-card scope). Save ~64px, steppers >=48px. */
.competition-desk-card[b-o922ycifi9]  .competition-desk-save {
    min-height: 64px;
}

.competition-desk-card[b-o922ycifi9]  .competition-desk-stepper {
    min-height: 48px;
}

.competition-setup-skeleton[b-o922ycifi9] {
    min-height: 8rem;
    background: linear-gradient(90deg, #f6f8fb 25%, #eef2f7 50%, #f6f8fb 75%);
}

.competition-wizard-actions[b-o922ycifi9] {
    display: flex;
    gap: 0.75rem;
    margin-top: 1rem;
    flex-wrap: wrap;
}

/* ── Top bar ──────────────────────────────────────────────────────────────────────────── */
.competition-desk-topbar[b-o922ycifi9] {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

/* The Back NavLink renders an <a class="btn …">; pierce the scope + inline-flex so the 44px
   floor actually applies (a plain inline-block <a> ignores min-height without flex centring). */
.competition-desk-topbar[b-o922ycifi9]  .competition-desk-back {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.competition-desk-title[b-o922ycifi9] {
    color: #0d2c55;
    font-size: 1.5rem;
    margin: 0;
}

/* ── Entry card ───────────────────────────────────────────────────────────────────────── */
.competition-desk-card[b-o922ycifi9] {
    padding: 1.25rem;
}

.competition-desk-progress-row[b-o922ycifi9] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid rgba(13, 44, 85, 0.08);
    padding-bottom: 0.75rem;
}

.competition-desk-progress[b-o922ycifi9] {
    color: #24384f;
    font-weight: 600;
    font-size: 1.05rem;
}

.competition-desk-skip[b-o922ycifi9] {
    min-height: 44px;
    min-width: 5rem;
    font-weight: 600;
}

.competition-desk-skip-exhausted[b-o922ycifi9] {
    margin-bottom: 1rem;
}

/* The two pairs, large + readable at a distance. */
.competition-desk-pairs[b-o922ycifi9] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    margin-bottom: 1rem;
}

.competition-desk-pair-name[b-o922ycifi9] {
    color: #0d2c55;
    font-weight: 700;
    font-size: 1.3rem;
    text-align: center;
    /* Rework polish 7: a long pair label ("Green / Black" + "Hall / Wilson") wraps as a UNIT —
       min-width:0 lets the flex item shrink, overflow-wrap breaks only between words (never mid
       name), and the centred line keeps the slash on whichever side it falls. */
    min-width: 0;
    overflow-wrap: anywhere;
}

.competition-desk-vs[b-o922ycifi9] {
    color: #5a6b80;
    font-size: 0.95rem;
    letter-spacing: 0.04em;
}

/* Head start hero — plain "start on +N" language (moat rule). #155a30 on #e7f3ec is AA. */
.competition-desk-headstart[b-o922ycifi9] {
    color: #155a30;
    font-weight: 600;
    font-size: 1.05rem;
    background: #e7f3ec;
    border-radius: 0.2rem;
    padding: 0.6rem 0.85rem;
    margin: 0 0 1.25rem;
    text-align: center;
}

.competition-desk-headstart--even[b-o922ycifi9] {
    color: #3a4d66;
    background: #eef2f7;
    font-weight: 500;
}

/* ── Score entry ──────────────────────────────────────────────────────────────────────── */
.competition-desk-form[b-o922ycifi9] {
    margin: 0;
}

/* #574: the winner-first step 1 - "Which pair won?" plus the two pair-name buttons. Values mirror
   the club-night card's .pending-score-winner-* rules (ClubSessionDashboard.razor.css) so the two
   features read as the same control; the class names are competition-scoped because the session's
   DOM contract is asserted by the session's own suites (spec Round 10A, B2). Kiosk-sized like the
   rest of the desk: the buttons stack at 390 (a long pair name is never truncated) and sit side by
   side from 480px. */
.competition-score-winner-prompt[b-o922ycifi9] {
    color: #355775;
    font-weight: 600;
    font-size: 1.05rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-choices[b-o922ycifi9] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

@media (min-width: 480px) {
    .competition-score-winner-choices[b-o922ycifi9] {
        grid-template-columns: 1fr 1fr;
    }
}

.competition-score-winner-btn[b-o922ycifi9] {
    width: 100%;
    min-height: 3.5rem;
    border: 2px solid #9fb7cf;
    background: #f2f8ff;
    color: #2d4f6d;
    font-weight: 700;
    font-size: 1.05rem;
    text-align: center;
    justify-content: center;
    white-space: normal;
}

.competition-score-winner-btn:hover:not(:disabled)[b-o922ycifi9] {
    background: #e2f0ff;
    border-color: #6f93b8;
}

/* The pair just indicated as the winner, while the inline grid collects the other pair's score.
   The grid pushes the page down rather than covering these buttons, so the tap must read as
   acknowledged. Not colour alone: the checkmark glyph and the heavier border carry it too. */
.competition-score-winner-btn--chosen[b-o922ycifi9] {
    background: #dff0df;
    border-color: #2f7d33;
    color: #1d4a20;
}

.competition-score-winner-btn--chosen[b-o922ycifi9]::before {
    content: "\2713\00a0";
}

/* #574 step 2: the caption naming whose score is wanted, and the "won" tag beside the winning
   pair. Mirrors the club-night card's .pending-score-loser-caption / .pending-score-winner-tag. */
.competition-score-loser-caption[b-o922ycifi9] {
    color: #60778f;
    font-weight: 600;
    font-size: 0.95rem;
    margin-bottom: 0.5rem;
}

.competition-score-winner-tag[b-o922ycifi9] {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0 0.35rem;
    border-radius: 0.5rem;
    background: #2f7d33;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    vertical-align: middle;
}

/* 390 PRIMARY: the two score blocks STACK (label above its own full-width input + steppers).
   The separator dash is hidden in the stacked form; it reappears in the side-by-side >=700px
   layout below. */
.competition-desk-scores[b-o922ycifi9] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-bottom: 1rem;
}

.competition-desk-score-sep[b-o922ycifi9] {
    display: none;
}

.competition-desk-score-block[b-o922ycifi9] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.competition-desk-score-label[b-o922ycifi9] {
    color: #24384f;
    font-weight: 700;
    font-size: 1.05rem;
    margin: 0;
}

/* Big numeric input — kiosk-grade, 64-72px tall, large readable digits. Spinner arrows
   suppressed (they crowd the big digits); inputmode="numeric" keeps the numeric keypad. */
.competition-desk-score-input[b-o922ycifi9] {
    width: 100%;
    min-height: 68px;
    font-size: 2.2rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
    padding: 0.25rem 0.5rem;
    -moz-appearance: textfield;
    appearance: textfield;
}

.competition-desk-score-input[b-o922ycifi9]::-webkit-outer-spin-button,
.competition-desk-score-input[b-o922ycifi9]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* LR-3: the desk score is now a tap-to-open button (opens the shared kiosk-sized decade grid).
   It keeps the large numeric look but reads + behaves as a tappable kiosk field. */
.score-entry-trigger[b-o922ycifi9] {
    cursor: pointer;
    line-height: 1.2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.score-entry-trigger:disabled[b-o922ycifi9] {
    cursor: not-allowed;
    opacity: 0.65;
}

/* Unset trigger (rework major 1): the en-dash placeholder reads muted (not a real "0"),
   mirroring the session dashboard's unset/set distinction. #56697f on #fff = 5.4:1 (AA). */
.score-entry-trigger--unset[b-o922ycifi9] {
    color: #56697f;
}

/* LR-9 (session-parity): a value AUTO-DEFAULTED to the §6 target (21) when the OTHER side was
   entered as the loser reads amber — the same coloured-state language as the in-session
   pending-score pane's auto state (.pending-score-input-auto). A manual override (re-tap or a
   stepper) flips it back to the plain set state. Same palette as the session: bg #fff0bd /
   border #e3c56f / text #664b00. */
.score-entry-trigger--auto[b-o922ycifi9] {
    background: #fff0bd;
    border-color: #e3c56f;
    color: #664b00;
}

/* Steppers: split the row, >= 48px square-ish, keypad-primary assists. */
.competition-desk-steppers[b-o922ycifi9] {
    display: flex;
    gap: 0.75rem;
}

.competition-desk-stepper[b-o922ycifi9] {
    flex: 1 1 0;
    min-height: 48px;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
}

.competition-desk-error[b-o922ycifi9] {
    margin-bottom: 1rem;
}

/* Primary Save & next: full-width, dominant, ~64px. */
.competition-desk-save[b-o922ycifi9] {
    width: 100%;
    min-height: 64px;
    font-size: 1.25rem;
    font-weight: 700;
}

/* ── Receipt footer (persistent, NOT a toast) ─────────────────────────────────────────── */
.competition-desk-receipt[b-o922ycifi9] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.85rem 1rem;
    background: #eef2f7;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.2rem;
}

.competition-desk-receipt-text[b-o922ycifi9] {
    color: #24384f;
    font-weight: 600;
    font-size: 1rem;
}

.competition-desk-receipt-text--empty[b-o922ycifi9] {
    color: #5a6b80;
    font-weight: 500;
}

.competition-desk-undo[b-o922ycifi9] {
    min-height: 44px;
    flex: 0 0 auto;
    font-weight: 600;
}

/* ── Completion terminal ──────────────────────────────────────────────────────────────── */
.competition-desk-complete-title[b-o922ycifi9] {
    color: #0d2c55;
    margin: 0 0 0.35rem;
}

/* ── >= 700px (wide tablet / desktop): scores go side-by-side with the separator dash
      (Screen 13's two-box intent at tablet width). The desk itself stays comfortably wide. */
@media (min-width: 700px) {
    .competition-desk-scores[b-o922ycifi9] {
        flex-direction: row;
        align-items: flex-start;
        justify-content: center;
        gap: 1.25rem;
    }

    .competition-desk-score-block[b-o922ycifi9] {
        flex: 1 1 0;
        max-width: 14rem;
    }

    .competition-desk-score-sep[b-o922ycifi9] {
        display: block;
        align-self: center;
        margin-top: 2.25rem;
        color: #5a6b80;
        font-size: 2rem;
        font-weight: 700;
    }
}
/* /Components/Pages/Competitions.razor.rz.scp.css */
.club-management-shell[b-m18hkf16ng] {
    padding: 0;
}

/* The shared off-white panel. club-card is defined per-page in scoped CSS
   (Members/Settings do the same); replicate the token here so competition cards
   actually render as tiles (#f6f8fb panel, navy-tint border) rather than bare
   content rows. */
.club-card[b-m18hkf16ng] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.club-management-shell h1[b-m18hkf16ng] {
    color: #0d2c55;
    font-size: 2.5rem;
    margin: 0 0 0.25rem;
}

.competitions-header[b-m18hkf16ng] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.competitions-subtitle[b-m18hkf16ng] {
    color: #5a6b80;
    margin: 0 0 0.5rem;
}

/* Rework major 3: header action cluster — the "Show archived" toggle + "+ New competition",
   right-aligned, vertically centred, wrapping on narrow widths. */
.competitions-header-actions[b-m18hkf16ng] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

/* Touch floor (ISS-013, rework round 1): the list-screen action buttons — the
   header / empty-state "+ New competition" (a NavLink-rendered <a>, hence ::deep)
   and the load-error Refresh — clear 44px at ALL viewports, matching the wizard.
   The card "View competition" button is sized separately (it has its own rule). */
.competitions-header[b-m18hkf16ng]  .btn,
.competitions-empty[b-m18hkf16ng]  .btn,
.club-card > .btn[b-m18hkf16ng] {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ── LR-26 status-filter tabs ── pill chips above the card grid (All / In Progress /
   Completed). Mirrors the running-surface dashboard-chip tokens (scoped CSS doesn't cross
   components — the Members/Settings/Competitions precedent — so the tokens are replicated
   here, matching the app's active-nav treatment). Rendered as role="tab" buttons; 44px touch
   target; wrap on narrow widths. */
.competitions-filter-tabs[b-m18hkf16ng] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.competitions-filter-tab[b-m18hkf16ng] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid #c3ccd8;
    border-radius: 999px;
    background: #fff;
    /* #1f3147 on #fff = 12.1:1 (AA). */
    color: #1f3147;
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.competitions-filter-tab:hover[b-m18hkf16ng] {
    background: #f2f5f9;
}

.competitions-filter-tab:focus-visible[b-m18hkf16ng] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
}

/* The selected tab reads active — navy fill + white text, matching the app's nav active
   treatment + the running-surface chips. #fff on #0d2c55 = 13.1:1 (AA). */
.competitions-filter-tab--active[b-m18hkf16ng] {
    background: #0d2c55;
    border-color: #0d2c55;
    color: #fff;
}

.competitions-filter-tab--active:hover[b-m18hkf16ng] {
    background: #0d2c55;
}

/* Per-tab empty message (AC-LR26.6): a plain one-liner in the grid area when the club has
   competitions but the selected tab matches none. #5a6b80 on the off-white shell = AA. */
.competitions-tab-empty[b-m18hkf16ng] {
    color: #5a6b80;
    margin: 0.5rem 0 1rem;
}

/* Card/tile grid (UI Mockups.png panel 1 style). Net-new layout (Members/Reports
   are tables); built from club-card tiles within the existing palette (F3). */
.competitions-grid[b-m18hkf16ng] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
}

.competition-card[b-m18hkf16ng] {
    display: flex;
    flex-direction: column;
    min-height: 9rem;
    margin-bottom: 0; /* grid gap handles spacing */
    padding: 1.25rem;
    background: #fff; /* mockup cards are white tiles on the off-white shell */
    /* Stretched-link host: the View <a>'s ::before overlay is positioned against
       this card, so the whole tile is clickable while remaining a single link. */
    position: relative;
    /* Leaves room on the action row for the slice-10 overflow (kebab) menu
       without a re-layout (PM decision Q4). */
}

/* Top row: tinted trophy badge (left) + status pill (right), per the mockup. */
.competition-card-top[b-m18hkf16ng] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.85rem;
}

/* Circular solid-fill icon badge with a white trophy glyph. The tint varies per
   competition (BadgeTintClass) like the mockup. All fills are WCAG-AA measured for
   white-glyph-on-fill (≥4.5:1). z-index above the stretched-link overlay so the
   badge paints over it (decorative; the link still owns the click). */
.competition-card-badge[b-m18hkf16ng] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 999px;
    color: #fff;
    flex: 0 0 auto;
    /* Decorative only: let clicks fall through to the stretched-link overlay so the
       whole tile (badge included) routes to View competition. */
    pointer-events: none;
}

.competition-card-badge svg[b-m18hkf16ng] {
    width: 1.5rem;
    height: 1.5rem;
}

/* Per-competition tints. Each fill measured against white (#fff) glyph:
   --1 navy  #0d2c55 -> 13.1:1 ; --2 green #1d6b39 -> 5.45:1 ;
   --3 teal  #246b73 -> 4.86:1 ; --4 plum  #5a3b86 -> 7.16:1 . All ≥4.5:1 (AA). */
.competition-card-badge--1[b-m18hkf16ng] { background: #0d2c55; }
.competition-card-badge--2[b-m18hkf16ng] { background: #1d6b39; }
.competition-card-badge--3[b-m18hkf16ng] { background: #246b73; }
.competition-card-badge--4[b-m18hkf16ng] { background: #5a3b86; }

/* Two-column meta row (Date | Type) with a thin divider, per the mockup. */
.competition-card-meta[b-m18hkf16ng] {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.85rem;
}

.competition-card-meta-item[b-m18hkf16ng] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    flex: 1 1 0;
    min-width: 0;
}

.competition-card-meta-item + .competition-card-meta-item[b-m18hkf16ng] {
    border-left: 1px solid rgba(13, 44, 85, 0.12);
    padding-left: 1rem;
}

.competition-card-meta-label[b-m18hkf16ng] {
    /* #4b5a6c on #fff = 6.97:1 (AA). Small-caps label like the mockup. */
    color: #4b5a6c;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.competition-card-meta-value[b-m18hkf16ng] {
    color: #1f3147;
    font-size: 0.95rem;
    /* Allow the type to wrap (e.g. "Handicap doubles") rather than clip, matching the
       mockup's two-line type; break long single tokens so they can't force h-scroll. */
    overflow-wrap: anywhere;
}

/* Stats row: count blocks (label + big number), per the mockup. Players is live;
   Pairs/Stage are reserved slots until slices 3/5. */
.competition-card-stats[b-m18hkf16ng] {
    display: flex;
    gap: 1.5rem;
    margin-bottom: 1rem;
}

.competition-card-stat[b-m18hkf16ng] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.competition-card-stat-label[b-m18hkf16ng] {
    color: #4b5a6c; /* 6.97:1 on #fff */
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.competition-card-stat-value[b-m18hkf16ng] {
    color: #0d2c55;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

/* Reserved (not-yet-available) Pairs/Stage placeholder: muted but still AA text.
   #5f6f82 on #fff = 4.91:1 (>=4.5:1). The hyphen is real text, so it must clear AA;
   an aria-label still gives AT the "not generated/started yet" meaning. */
.competition-card-stat-value--reserved[b-m18hkf16ng] {
    color: #5f6f82;
    font-weight: 600;
}

/* Completed-card "Winner" line (UX rework R1 MAJOR 1): replaces the stats block on a
   Complete card. Full-width, one line, ellipsis-truncated (title carries the full label).
   Sits in the stats row's place so the card keeps its height. */
.competition-card-winner[b-m18hkf16ng] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin-bottom: 1rem;
    min-width: 0;
}

.competition-card-winner-label[b-m18hkf16ng] {
    color: #4b5a6c; /* 6.97:1 on #fff (AA) — matches the stat labels */
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.competition-card-winner-value[b-m18hkf16ng] {
    color: #0d2c55;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.15;
    /* One line, ellipsis-truncated; title attr exposes the full pair label. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Stretched-link pattern: the Open NavLink is the ONLY interactive element; its
   ::before overlay is absolutely positioned against the card (the nearest positioned
   ancestor — the link itself stays position:static so the overlay anchors to the
   tile, not the button), making the whole tile the link's click target. Replaces the
   old role="link" card + nested <a>, which was invalid interactive nesting for AT. */
.competition-card-actions[b-m18hkf16ng]  .competition-card-open::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}

/* Focus ring on the card when its single link is focused (stretched-link). */
.competition-card:has(.competition-card-open:focus-visible)[b-m18hkf16ng] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
}

.competition-card-title[b-m18hkf16ng] {
    color: #0d2c55;
    font-size: 1.3rem;
    line-height: 1.25;
    margin: 0 0 0.85rem;
}

.competition-card-actions[b-m18hkf16ng] {
    display: flex;
    justify-content: stretch;
    gap: 0.5rem;
    /* Pin the action row to the bottom of the card so the body content sits at
       the top and there's no awkward vertical void. */
    margin-top: auto;
}

/* Footer "View competition" button — full-width outlined button per the mockup.
   ::deep pierces the NavLink child-component boundary (the rendered <a>) — a plain
   .btn rule wouldn't reach it in scoped CSS. The button stays position:static (no
   z-index) ON PURPOSE so its ::before overlay anchors to the card (the nearest
   positioned ancestor), not to the button — that is what makes the WHOLE tile the
   link's click target (the stretched-link pattern). */
.competition-card-actions[b-m18hkf16ng]  .competition-card-open {
    /* Flex-grows to fill the row; the kebab (slice 10) takes its fixed 44px to the right.
       When no kebab is present (read-only users) it still fills the full width. */
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
}

/* ── Slice-10 kebab overflow menu ── The menu container is position:relative so the
   popover anchors to it; z-index:2 lifts the kebab + popover ABOVE the stretched-link
   ::before overlay (z-index:1) so they capture their own clicks and the kebab never
   triggers the card-wide View navigation (the one real render risk, R10-1). */
.competition-card-menu[b-m18hkf16ng] {
    position: relative;
    z-index: 2;
    flex: 0 0 auto;
}

.competition-card-kebab[b-m18hkf16ng] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border: 1px solid #c3ccd8;
    border-radius: 8px;
    background: #fff;
    /* #4b5a6c dots on #fff = 6.97:1 (AA). */
    color: #4b5a6c;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
}

.competition-card-kebab:hover[b-m18hkf16ng] {
    background: #f2f5f9;
}

.competition-card-kebab:focus-visible[b-m18hkf16ng] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
}

/* The popover: anchored to the kebab, opening upward-left so it doesn't clip the card
   bottom edge. Above everything on the card. */
.competition-card-menu-popover[b-m18hkf16ng] {
    position: absolute;
    right: 0;
    bottom: calc(100% + 0.35rem);
    min-width: 13rem;
    background: #fff;
    border: 1px solid #d6dde7;
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(13, 44, 85, 0.16);
    padding: 0.35rem;
    z-index: 3;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* Menu items (the NavLink Edit/View + the action buttons) share one look; full-width,
   left-aligned, 44px touch target. ::deep pierces the NavLink boundary. */
.competition-card-menu-popover[b-m18hkf16ng]  .competition-card-menu-item,
.competition-card-menu-item[b-m18hkf16ng] {
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 44px;
    padding: 0 0.65rem;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: #1f3147;
    font-size: 0.95rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.competition-card-menu-popover[b-m18hkf16ng]  .competition-card-menu-item:hover,
.competition-card-menu-item:hover[b-m18hkf16ng] {
    background: #f2f5f9;
}

.competition-card-menu-item:disabled[b-m18hkf16ng] {
    opacity: 0.5;
    cursor: default;
}

/* Delete = the danger token (#b0203a on #fff = 6.0:1, AA). */
.competition-card-menu-item--danger[b-m18hkf16ng] {
    color: #b0203a;
}

.competition-card-menu-confirm[b-m18hkf16ng] {
    margin: 0.25rem 0.4rem 0.5rem;
    font-size: 0.9rem;
    color: #1f3147;
    line-height: 1.35;
}

.competition-card-menu-confirm-actions[b-m18hkf16ng] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    padding: 0 0.4rem 0.3rem;
}

.competition-card-menu-error[b-m18hkf16ng] {
    margin: 0.25rem 0.4rem 0;
    font-size: 0.85rem;
    /* #b0203a on #fff = 6.0:1 (AA). */
    color: #b0203a;
}

/* ── Archived section ── the dimmed archived grid (the toggle now lives in the header). ── */
.competitions-archived[b-m18hkf16ng] {
    margin-top: 1.5rem;
}

.competitions-archived-heading[b-m18hkf16ng] {
    color: #0d2c55;
    font-size: 1.25rem;
    margin: 0 0 0.75rem;
}

/* The header "Show archived" toggle: link-styled, navy text, AA on the off-white shell. */
.competitions-archived-toggle[b-m18hkf16ng] {
    color: #3a4d66; /* 7.4:1 on the off-white shell (AA) */
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.competitions-archived-toggle:hover[b-m18hkf16ng] {
    text-decoration: underline;
}

/* Archived cards read slightly muted so they're visually distinct from the live list. */
.competition-card--archived[b-m18hkf16ng] {
    background: #fbfcfd;
    border-color: #e1e6ee;
}

.competition-card--skeleton[b-m18hkf16ng] {
    min-height: 9rem;
    background: linear-gradient(90deg, #eef2f7 25%, #f6f8fb 50%, #eef2f7 75%);
    background-size: 200% 100%;
    animation: competition-skeleton-b-m18hkf16ng 1.2s ease-in-out infinite;
}

@keyframes competition-skeleton-b-m18hkf16ng {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.competitions-empty[b-m18hkf16ng] {
    text-align: center;
    padding: 2rem 1rem;
}

.competitions-empty h2[b-m18hkf16ng] {
    color: #0d2c55;
}

/* Status pills: three muted tokens within the existing palette (F4). The
   live-pill red gradient is reserved for live sessions, so a distinct set here. */
.status-pill[b-m18hkf16ng] {
    display: inline-flex;
    align-items: center;
    border-radius: 999px;
    padding: 0.15rem 0.65rem;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.4;
}

.status-pill--draft[b-m18hkf16ng] {
    background: #e6ebf2;
    color: #3a4d66;
}

.status-pill--in-progress[b-m18hkf16ng] {
    background: #d7ebdd;
    color: #1d6b39;
}

.status-pill--complete[b-m18hkf16ng] {
    background: #0d2c55;
    color: #fff;
}

.status-pill--archived[b-m18hkf16ng] {
    background: #eceef1;
    color: #7a8699;
}

/* Mobile/tablet: single column, full-width-friendly actions, no horizontal
   scroll (matches the 700px breakpoint Members uses). */
@media (max-width: 700px) {
    .competitions-header[b-m18hkf16ng] {
        flex-direction: column;
        align-items: stretch;
    }

    .competitions-grid[b-m18hkf16ng] {
        grid-template-columns: 1fr;
    }

    /* The View button is already full-width + 44px at every viewport (base rule
       above); mobile only needs the action row to stack should a slice-10 kebab join
       it. The 44px touch floor is inherited, not re-declared. */
    .competition-card-actions[b-m18hkf16ng] {
        flex-direction: column;
        align-items: stretch;
    }
}
/* /Components/Pages/CompetitionSetup.razor.rz.scp.css */
.club-management-shell[b-knzrotdx1b] {
    padding: 0;
}

/* Shared off-white panel (defined per-page in scoped CSS, as Members/Settings do)
   so the wizard step card renders as a tile. */
.club-card[b-knzrotdx1b] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.visually-hidden[b-knzrotdx1b] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Compact mobile progress indicator — hidden on desktop, shown ≤700px in place
   of the pill rail (which clips below ~390px so steps 5-6 fall off-screen). */
.competition-step-progress[b-knzrotdx1b] {
    display: none;
    margin-bottom: 1rem;
}

.competition-step-progress-label[b-knzrotdx1b] {
    display: block;
    color: #0d2c55;
    font-weight: 600;
    font-size: 0.95rem;
    /* ~6px gap between the compact "Step N of 6" text and the progress bar so they
       don't read as one block (ux re-check polish). */
    margin-bottom: 0.4rem;
}

.competition-step-progress-bar[b-knzrotdx1b] {
    display: block;
    height: 6px;
    border-radius: 999px;
    background: #dce2ea;
    overflow: hidden;
}

.competition-step-progress-fill[b-knzrotdx1b] {
    display: block;
    height: 100%;
    background: #0d2c55;
    border-radius: 999px;
    transition: width 0.2s ease;
}

.competition-setup-skeleton[b-knzrotdx1b] {
    min-height: 14rem;
    background: linear-gradient(90deg, #eef2f7 25%, #f6f8fb 50%, #eef2f7 75%);
    background-size: 200% 100%;
    animation: competition-setup-skeleton-b-knzrotdx1b 1.2s ease-in-out infinite;
}

@keyframes competition-setup-skeleton-b-knzrotdx1b {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* Step rail (F2): a horizontal numbered stepper built from pills in the existing
   palette. Collapses to a scrollable strip on narrow viewports. */
.competition-step-rail[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.competition-step[b-knzrotdx1b] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: #eef1f5;
    /* Inactive label: #4b5a6c on #eef1f5 = 6.22:1 (WCAG AA, was #7a8699 = 3.25:1). */
    color: #4b5a6c;
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
    font-size: 0.9rem;
    font-weight: 600;
}

.competition-step--active[b-knzrotdx1b] {
    background: #0d2c55;
    color: #fff;
}

/* A completed step is a NavLink back to its route (UX finding 9). Styled as a
   clickable pill: same palette as an inactive step but with link affordance
   (pointer + underline-on-hover of the label) so it reads as navigable.

   ::deep (ux round 2 fix): the done step is a NavLink child component, so its
   rendered <a> does NOT carry this component's scope attribute — plain scoped
   rules (.competition-step / .competition-step--done) never reached it, leaving the
   pill as an unstyled Bootstrap-link-blue <a>. ::deep pierces the child-component
   boundary (same technique the wizard .btn rules already use), so the pill base
   styling + the explicit navy colour apply to the anchor. The colour pin is what
   stops the done pill (and its number badge) going link blue; the hover underline
   of the label remains the navigable affordance. */
.competition-step-rail[b-knzrotdx1b]  .competition-step--done {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: #eef1f5;
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    color: #24384f;
}

.competition-step-rail[b-knzrotdx1b]  .competition-step--done:hover,
.competition-step-rail[b-knzrotdx1b]  .competition-step--done:focus-visible {
    background: #dce2ea;
}

/* Post-Start review (Mike-reported defect round): the current step renders as a
   navigable --done NavLink that ALSO carries --active. The plain (non-::deep)
   .competition-step--active rule can't pierce the NavLink child-component boundary,
   so the navy "where you are" marker is reasserted here through ::deep. Keeps the
   active pill filled navy + white while it remains a clickable review link; hover
   darkens slightly so the link affordance still reads. */
.competition-step-rail[b-knzrotdx1b]  .competition-step--done.competition-step--active {
    background: #0d2c55;
    color: #fff;
}

.competition-step-rail[b-knzrotdx1b]  .competition-step--done.competition-step--active:hover,
.competition-step-rail[b-knzrotdx1b]  .competition-step--done.competition-step--active:focus-visible {
    background: #0a2344;
}

.competition-step-rail[b-knzrotdx1b]  .competition-step--done.competition-step--active .competition-step-number {
    background: rgba(255, 255, 255, 0.25);
    color: #fff;
}

.competition-step-rail[b-knzrotdx1b]  .competition-step--done:hover .competition-step-label,
.competition-step-rail[b-knzrotdx1b]  .competition-step--done:focus-visible .competition-step-label {
    text-decoration: underline;
}

/* The number badge inside a done pill (also behind the ::deep boundary): match the
   inactive-step badge so it doesn't inherit the anchor's (now-navy) colour oddly or
   the old link blue. */
.competition-step-rail[b-knzrotdx1b]  .competition-step--done .competition-step-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    font-size: 0.8rem;
    background: #dce2ea;
    color: #37465a;
}

.competition-step-number[b-knzrotdx1b] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.3rem;
    height: 1.3rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
    font-size: 0.8rem;
}

.competition-step:not(.competition-step--active) .competition-step-number[b-knzrotdx1b] {
    background: #dce2ea;
    /* Inactive number: #37465a on #dce2ea = 7.37:1 (WCAG AA, was #5a6b80 = 4.18:1). */
    color: #37465a;
}

.club-card h2[b-knzrotdx1b] {
    color: #0d2c55;
    font-size: 1.6rem;
    margin: 0 0 0.85rem;
}

.competition-form-field[b-knzrotdx1b] {
    margin-bottom: 1rem;
}

.form-label[b-knzrotdx1b] {
    font-weight: 600;
    color: #24384f;
}

.required-marker[b-knzrotdx1b] {
    color: #c0392b;
}

.optional-hint[b-knzrotdx1b] {
    color: #7a8699;
    font-weight: 400;
    font-size: 0.85rem;
}

.required-legend[b-knzrotdx1b] {
    color: #7a8699;
    font-size: 0.85rem;
    margin: 0.25rem 0 1rem;
}

.competition-wizard-actions[b-knzrotdx1b] {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
}

/* Touch floor (ISS-013, rework round 1): EVERY wizard navigation button (Back,
   Continue, Back-to-players) is a 44px tap target at ALL viewports, not just
   ≤700px. The pre-pass commits to a 44px floor on all sticky-footer/action buttons
   feature-wide. Applied to the button element via min-height (not a parent height
   override) so it can't silently revert. ::deep pierces the NavLink child-component
   boundary — the Back/Back-to-players buttons are NavLink-rendered <a>s, so a plain
   `.btn` rule wouldn't reach them. */
.competition-wizard-actions .btn[b-knzrotdx1b],
.competition-wizard-actions[b-knzrotdx1b]  .btn,
.club-card[b-knzrotdx1b]  .btn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ── Player selection (slice 2) ──────────────────────────────────────────── */
/* Zero-selection instruction line (UX finding 4): pairs the disabled Continue
   with a plain "what to do" so it never stands alone unexplained. */
.competition-player-hint[b-knzrotdx1b] {
    margin: 0 0 0.75rem;
}

/* One-time column label above the checklist (UX finding 5/7): carries the meaning
   of the per-row rating number so the word "Rating" isn't repeated on every row. */
.competition-player-listhead[b-knzrotdx1b] {
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    padding: 0 0.75rem 0.25rem;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #4b5a6c;
}

/* LR-11 (round 3A): the Member / Rating labels are click-to-sort buttons. Borderless,
   transparent, inheriting the uppercase header look so they read as the existing label
   row, not new chrome — but interactive (cursor + hover + a ▲/▼ caret on the active
   column). 44px tap floor at every width so the sort control clears the touch floor on
   a tablet (the primary kiosk user — AC-LR11.3). */
.competition-player-sort[b-knzrotdx1b] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-height: 44px;
    padding: 0.25rem 0.1rem;
    border: none;
    background: transparent;
    font: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    color: inherit;
    cursor: pointer;
}

.competition-player-sort:hover[b-knzrotdx1b] {
    color: #0d2c55;
}

/* The active sort column reads darker + bolder so "what's sorting" is obvious. */
.competition-player-sort--active[b-knzrotdx1b] {
    color: #0d2c55;
    font-weight: 700;
}

.competition-player-sort-caret[b-knzrotdx1b] {
    font-size: 0.7rem;
    line-height: 1;
}

/* Keyboard focus is visible (the headers are now real buttons). */
.competition-player-sort:focus-visible[b-knzrotdx1b] {
    outline: 2px solid #0d2c55;
    outline-offset: 2px;
    border-radius: 0.15rem;
}

.competition-player-search[b-knzrotdx1b] {
    margin-bottom: 0.75rem;
}

.competition-player-list[b-knzrotdx1b] {
    list-style: none;
    margin: 0 0 0.5rem;
    padding: 0;
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.2rem;
    background: #fff;
    /* Long rosters scroll within the panel rather than pushing the count/Continue
       off-screen; the footer stays reachable. */
    max-height: 28rem;
    overflow-y: auto;
}

.competition-player-row[b-knzrotdx1b] {
    border-bottom: 1px solid rgba(13, 44, 85, 0.06);
}

.competition-player-row:last-child[b-knzrotdx1b] {
    border-bottom: none;
}

/* The whole row is the tap target (label wraps the checkbox + name + rating). */
.competition-player-label[b-knzrotdx1b] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0;
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    /* ISS-013: a comfortable row height at every width so the row is a tap target
       screen-wide, not only on mobile. */
    min-height: 44px;
}

.competition-player-check[b-knzrotdx1b] {
    /* Larger-than-default checkbox so the control itself clears the touch floor. */
    width: 1.35rem;
    height: 1.35rem;
    margin: 0;
    flex: 0 0 auto;
}

.competition-player-name[b-knzrotdx1b] {
    flex: 1 1 auto;
    color: #24384f;
    font-weight: 500;
}

.competition-player-rating[b-knzrotdx1b] {
    flex: 0 0 auto;
    color: #4b5a6c;
    font-size: 0.9rem;
}

.competition-player-noresults[b-knzrotdx1b] {
    margin: 0 0 0.5rem;
}

/* Sticky footer (UX finding 3): the count + warning + actions pin to the bottom of
   the viewport while the roster scrolls, so Continue is always reachable (at 390px it
   was 74px below the fold with no affordance). A solid background + top border + a bit
   of padding keep it legible over scrolling content; the negative bottom margin lets
   it sit flush with the card edge. */
.competition-players-footer[b-knzrotdx1b] {
    position: sticky;
    bottom: 0;
    margin: 0.5rem -1rem -1rem;
    /* padding-bottom carries the home-indicator safe area (ux round 2 polish) so the
       footer content clears the gesture bar on tablets/notched devices; falls back to
       the base 0.75rem where env() is unsupported. */
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
    background: #f6f8fb;
    border-top: 1px solid rgba(13, 44, 85, 0.12);
    z-index: 1;
}

/* FAB clearance (ux major; generalised feature-wide in rework round 1 — ISS-013's
   THIRD screen-by-screen recurrence, so killed at the source). The floating feedback
   button sits bottom-right (right: 1rem) and overlapped the right-aligned Continue by
   ~70px at 1440px. Every wizard step right-aligns its primary via space-between, so the
   clearance now lives on the BASE .competition-wizard-actions rule — it covers Details,
   Players, Pairs AND Review in one place rather than per-section selectors that kept
   missing the next new step. Back-only rows (error/empty states) carry a harmless extra
   right pad. Reset to 0 at ≤700px where the actions stack full-width. */
.competition-wizard-actions[b-knzrotdx1b] {
    padding-right: 4.5rem;
}

@media (max-width: 700px) {
    /* On mobile the actions stack full-width; the FAB clearance padding would
       indent them oddly, so drop it. */
    .competition-wizard-actions[b-knzrotdx1b] {
        padding-right: 0;
    }
}

.competition-player-count[b-knzrotdx1b] {
    color: #0d2c55;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

.competition-player-oddwarning[b-knzrotdx1b] {
    margin-bottom: 0.75rem;
}

/* Loading skeleton rows for the player list. */
.competition-players-skeleton[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.competition-player-skeleton-row[b-knzrotdx1b] {
    display: block;
    height: 44px;
    border-radius: 0.2rem;
    background: linear-gradient(90deg, #eef2f7 25%, #f6f8fb 50%, #eef2f7 75%);
    background-size: 200% 100%;
    animation: competition-setup-skeleton-b-knzrotdx1b 1.2s ease-in-out infinite;
}

@media (max-width: 700px) {
    /* Below 700px the pill rail clips (steps 5-6 disappear at 390px); hide it and
       show the compact "Step N of 6 · <Step>" label + progress bar instead, per
       the UX plan's specified mobile fallback. */
    .competition-step-rail[b-knzrotdx1b] {
        display: none;
    }

    .competition-step-progress[b-knzrotdx1b] {
        display: block;
    }

    /* Normal column order so Continue (the primary action, rendered last in markup)
       sits at the bottom — the natural primary position — with Back above it. Paired
       with the sticky footer this keeps Continue pinned in view (UX finding 9; was
       column-reverse, which put Continue on top, fighting the sticky-footer layout). */
    .competition-wizard-actions[b-knzrotdx1b] {
        flex-direction: column;
    }

    /* At ≤700px the wizard buttons go full-width (stacked column). The 44px floor +
       inline-flex centring now live in the base rule (rework round 1: floor applies
       at ALL viewports), so only the mobile-specific width is set here. */
    .competition-wizard-actions .btn[b-knzrotdx1b],
    .competition-wizard-actions[b-knzrotdx1b]  .btn,
    .club-card[b-knzrotdx1b]  .btn {
        width: 100%;
    }

    /* ISS-013 screen-wide touch floor on the Players step at ≤700px: the search
       input and each checklist row clear 44px. (The row min-height of 44px above
       already applies at all widths; restated context here keeps the search input
       and the count/footer comfortable on a phone.) */
    .competition-player-search[b-knzrotdx1b] {
        min-height: 44px;
    }

    .competition-player-label[b-knzrotdx1b] {
        /* A touch more vertical room on a phone so the row reads as a button. */
        padding-top: 0.6rem;
        padding-bottom: 0.6rem;
    }
}

/* ── Pairs step (slice 3) ─────────────────────────────────────────────────── */
/* D2 informational note + cleared confirmation on the Players step. */
.competition-player-pairsnote[b-knzrotdx1b] {
    margin: 0 0 0.5rem;
}

.competition-player-pairscleared[b-knzrotdx1b] {
    margin: 0 0 0.75rem;
}

/* Method radio-cards (Balanced | Manual): selectable cards in the existing palette,
   mirroring the Create type-select cards (minus the disabled "coming soon" variant). */
.competition-pair-methods[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.competition-pair-method[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    text-align: left;
    background: #fff;
    border: 1px solid rgba(13, 44, 85, 0.18);
    border-radius: 0.3rem;
    padding: 0.75rem 1rem;
    cursor: pointer;
    /* Touch floor: a comfortable card height at every width. */
    min-height: 44px;
    width: 100%;
}

.competition-pair-method:hover[b-knzrotdx1b] {
    border-color: rgba(13, 44, 85, 0.4);
}

/* The radio is visually hidden; surface its keyboard focus on the label card so
   arrow-key navigation between the two methods is visible (accessibility). */
.competition-pair-method:has(.competition-pair-method-radio:focus-visible)[b-knzrotdx1b] {
    border-color: #0d2c55;
    box-shadow: 0 0 0 2px rgba(13, 44, 85, 0.35);
}

.competition-pair-method--selected[b-knzrotdx1b] {
    border-color: #0d2c55;
    box-shadow: inset 0 0 0 1px #0d2c55;
    background: #eef3fb;
}

/* When the radio is disabled (no manage permission / generating) the card reads
   inert. */
.competition-pair-method:has(.competition-pair-method-radio:disabled)[b-knzrotdx1b] {
    cursor: default;
    opacity: 0.7;
}

.competition-pair-method-title[b-knzrotdx1b] {
    font-weight: 600;
    color: #0d2c55;
}

.competition-pair-method-desc[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.9rem;
}

/* LR-15: allocation-method cards on the Groups step — reuse the pair-method card
   treatment. Two cards side by side on desktop, stacked at ≤700px. */
.competition-alloc-methods[b-knzrotdx1b] {
    border: none;
    margin: 0 0 1rem;
    padding: 0;
}

.competition-alloc-methods-legend[b-knzrotdx1b] {
    font-size: 0.95rem;
    font-weight: 600;
    color: #0d2c55;
    margin-bottom: 0.5rem;
    padding: 0;
}

.competition-alloc-method-cards[b-knzrotdx1b] {
    display: flex;
    gap: 0.5rem;
}

.competition-alloc-method[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    text-align: left;
    background: #fff;
    border: 1px solid rgba(13, 44, 85, 0.18);
    border-radius: 0.3rem;
    padding: 0.75rem 1rem;
    cursor: pointer;
    min-height: 44px;
    flex: 1 1 0;
}

.competition-alloc-method:hover[b-knzrotdx1b] {
    border-color: rgba(13, 44, 85, 0.4);
}

.competition-alloc-method:has(.competition-alloc-method-radio:focus-visible)[b-knzrotdx1b] {
    border-color: #0d2c55;
    box-shadow: 0 0 0 2px rgba(13, 44, 85, 0.35);
}

.competition-alloc-method--selected[b-knzrotdx1b] {
    border-color: #0d2c55;
    box-shadow: inset 0 0 0 1px #0d2c55;
    background: #eef3fb;
}

.competition-alloc-method:has(.competition-alloc-method-radio:disabled)[b-knzrotdx1b] {
    cursor: default;
    opacity: 0.7;
}

.competition-alloc-method-title[b-knzrotdx1b] {
    font-weight: 600;
    color: #0d2c55;
}

.competition-alloc-method-desc[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.9rem;
}

@media (max-width: 700px) {
    /* Stack the two alloc-method cards on a tablet/phone — full-width, no scroll. */
    .competition-alloc-method-cards[b-knzrotdx1b] {
        flex-direction: column;
    }
}

.competition-pair-generate[b-knzrotdx1b] {
    margin-bottom: 1rem;
}

.competition-pair-generate .btn[b-knzrotdx1b] {
    min-height: 44px;
}

/* Manual builder: two player <select>s + an Add pair button. */
.competition-pair-manual[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.competition-pair-manual-pickers[b-knzrotdx1b] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.competition-pair-manual-pickers .form-select[b-knzrotdx1b] {
    flex: 1 1 auto;
    min-height: 44px;
}

.competition-pair-manual-plus[b-knzrotdx1b] {
    flex: 0 0 auto;
    color: #4b5a6c;
    font-weight: 700;
}

.competition-pair-manual .btn[b-knzrotdx1b] {
    min-height: 44px;
    align-self: flex-start;
}

.competition-pair-confirm[b-knzrotdx1b] {
    color: #1d6b3a;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

/* "Pairs (N)" heading: lightened toward the listhead convention (rework round 1,
   polish 10) — keeps the <h3> tag but reads as a quiet section label, not a second
   page title. */
.competition-pairs-heading[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 0.5rem 0 0.5rem;
}

/* Pairs table (rework round 1, D5): five columns — Player 1 | Rating | Player 2 |
   Rating | Pair rating — with one-time column headers and bare numbers in cells.
   Reuses the table table-sm tokens; reflows to a stacked mini-card at ≤700px. */
.competition-pair-table[b-knzrotdx1b] {
    margin-bottom: 0.75rem;
    background: #fff;
}

.competition-pair-table thead th[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    border-bottom: 1px solid rgba(13, 44, 85, 0.12);
}

.competition-pair-table tbody td[b-knzrotdx1b] {
    vertical-align: middle;
}

.competition-pair-row[b-knzrotdx1b] {
    min-height: 44px;
}

.competition-pair-cell-name[b-knzrotdx1b] {
    color: #24384f;
    font-weight: 500;
    /* LR-23 (round 4A): a "First Last" name (each <=20 chars) must render on ONE line at
       >=1024px, not wrap to two lines when the action column squeezes the row. Give the name
       cell room and keep it single-line; an extreme (>20-char) name ellipsis-truncates with
       the full name on hover (title attr) rather than wrapping or breaking the layout. The
       <=700px stacked-card layout (below) resets this so mobile names keep their own line. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 12rem;
}

.competition-pair-cell-rating[b-knzrotdx1b],
.competition-pair-table-rating[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.9rem;
}

/* LR-14: the rating-desc pair-number column. Narrow on the desktop table; the badge
   is a compact, legible label (Pair 1 = strongest). Shared with the Groups cards. */
.competition-pair-table-number[b-knzrotdx1b] {
    width: 4.5rem;
    white-space: nowrap;
}

.competition-pair-number-badge[b-knzrotdx1b] {
    display: inline-block;
    min-height: 1.5rem;
    padding: 0.1rem 0.45rem;
    border-radius: 0.25rem;
    background: rgba(13, 44, 85, 0.08);
    color: #24384f;
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

.competition-pair-unpair[b-knzrotdx1b] {
    /* No btn-sm (rework round 1, must-fix 3): Unpair clears the 44px floor at every
       viewport like the other action buttons. */
    min-height: 44px;
}

.competition-pair-empty[b-knzrotdx1b],
.competition-pair-unpaired[b-knzrotdx1b],
.competition-pair-unrated-note[b-knzrotdx1b] {
    margin: 0 0 0.75rem;
}

@media (max-width: 700px) {
    /* Stacked-card reflow (≤700px): a 5-column table won't fit 390px, so each pair
       row becomes a stacked mini-card. Each member shows on its own line with its
       rating, and the pair rating + Unpair stack below — using the data-label on
       each cell so the column meaning rides along without the wide header row. */
    .competition-pair-table thead[b-knzrotdx1b] {
        /* Headers are visually hidden on mobile; the per-cell data-label carries the
           meaning. Kept in the DOM for screen-reader table semantics. */
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
    }

    .competition-pair-table[b-knzrotdx1b],
    .competition-pair-table tbody[b-knzrotdx1b],
    .competition-pair-table tr[b-knzrotdx1b],
    .competition-pair-table td[b-knzrotdx1b] {
        display: block;
        width: 100%;
    }

    .competition-pair-row[b-knzrotdx1b] {
        border: 1px solid rgba(13, 44, 85, 0.12);
        border-radius: 0.2rem;
        background: #fff;
        margin-bottom: 0.5rem;
        padding: 0.5rem 0.75rem;
    }

    .competition-pair-table tbody td[b-knzrotdx1b] {
        display: flex;
        justify-content: space-between;
        gap: 0.6rem;
        padding: 0.25rem 0;
        border: none;
    }

    /* Inline label per cell (Pair rating: 1557) so each stacked line is self-
       describing without the column header. */
    .competition-pair-table tbody td[b-knzrotdx1b]::before {
        content: attr(data-label);
        color: #4b5a6c;
        font-size: 0.85rem;
        font-weight: 600;
    }

    .competition-pair-cell-action[b-knzrotdx1b] {
        justify-content: flex-start;
    }

    .competition-pair-cell-action[b-knzrotdx1b]::before {
        content: none;
    }

    /* The pair-number badge already reads "Pair N" (LR-14), so suppress the redundant
       "Pair" data-label on its stacked-card line and left-align the badge. */
    .competition-pair-cell-number[b-knzrotdx1b] {
        justify-content: flex-start;
    }

    .competition-pair-cell-number[b-knzrotdx1b]::before {
        content: none;
    }

    /* LR-23 (round 4A): the desktop single-line/ellipsis name treatment is reset on the
       stacked-card layout — each name already gets its own flex line opposite its data-label,
       so it may wrap and use the full card width (no clipping at 390). */
    .competition-pair-cell-name[b-knzrotdx1b] {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
        max-width: none;
    }

    .competition-pair-manual-pickers[b-knzrotdx1b] {
        flex-direction: column;
        align-items: stretch;
    }

    .competition-pair-manual-plus[b-knzrotdx1b] {
        text-align: center;
    }

    /* Add pair goes full-width at ≤700px (rework round 1, polish 7): a lone 86px pill
       among full-width siblings reads as broken. */
    .competition-pair-manual .btn[b-knzrotdx1b] {
        align-self: stretch;
        width: 100%;
    }
}

/* ── Slice 4: Pair Review ─────────────────────────────────────────────────
   Reuses the slice-3 pairs table (.competition-pair-table) with an action column +
   a locked-row chrome variant; the constraints panel reuses .club-card; the "Locked"
   pill reuses the .status-pill shape (status-pill--locked); all action buttons clear
   the 44px floor at every viewport (standing rule). */
/* Status line (ux-review major 4): neutral/cautionary by default — a lock/unlock/veto/
   swap-prompt confirmation, and crucially the veto-broke-your-pair message, must NOT
   read as success-green. Green is reserved for the genuinely positive completions
   (--positive: a successful redraw / swap). */
.competition-review-status[b-knzrotdx1b] {
    color: #24384f;
    font-weight: 600;
    margin: 0 0 0.75rem;
}

.competition-review-status--positive[b-knzrotdx1b] {
    color: #1b6e3b;
}

.competition-review-actions[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

/* Action buttons: 44px floor at ALL viewports (touch/kiosk rule), like the slice-3
   Unpair button — no btn-sm shrink below the floor. */
.competition-review-btn[b-knzrotdx1b] {
    min-height: 44px;
}

/* Locked-row chrome: a tinted row so a locked pair reads as "kept, don't touch". */
.competition-pair-row--locked[b-knzrotdx1b] {
    background: #f0f5ff;
}

.competition-pair-row--locked .competition-pair-cell-name[b-knzrotdx1b] {
    color: #1b3a66;
}

/* "Locked" pill — the status-pill shape with a distinct (calm blue) treatment, kept
   separate from the red live-pill (reserved for live sessions). */
.status-pill--locked[b-knzrotdx1b] {
    background: #dbe7ff;
    color: #1b3a66;
    /* Vertically centre the pill against the 44px Unlock button in the same flex
       action cell (ux-review polish 6) — without this the shorter pill sat top-aligned. */
    align-self: center;
}

/* Constraints panel: a tinted background lifts it off the parent white card so the
   locks/vetoes summary reads as its own region (ux-review polish 7). */
.competition-constraints[b-knzrotdx1b] {
    margin: 0.75rem 0;
    background: #eef3fb;
}

.competition-constraints-heading[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 0 0 0.5rem;
}

.competition-constraints-group-label[b-knzrotdx1b] {
    font-weight: 600;
    color: #24384f;
    margin: 0.5rem 0 0.25rem;
}

.competition-constraints-empty[b-knzrotdx1b] {
    margin: 0 0 0.5rem;
}

.competition-constraints-list[b-knzrotdx1b] {
    list-style: none;
    padding: 0;
    margin: 0 0 0.5rem;
}

.competition-constraints-row[b-knzrotdx1b] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 0.25rem 0;
}

.competition-constraints-names[b-knzrotdx1b] {
    color: #24384f;
}

.competition-addveto-actions[b-knzrotdx1b],
.competition-swap-actions[b-knzrotdx1b],
.competition-clearall-confirm-actions[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.competition-review-regenerate[b-knzrotdx1b] {
    margin: 0.75rem 0;
}

.competition-review-regenerate .btn[b-knzrotdx1b] {
    min-height: 44px;
}

.competition-review-regenerate-help[b-knzrotdx1b],
.competition-review-continue-help[b-knzrotdx1b],
.competition-review-unpaired[b-knzrotdx1b],
.competition-pair-clearall-help[b-knzrotdx1b] {
    margin: 0.4rem 0 0;
}

/* LR-13: "Clear all" sits as a quieter secondary below the single Regenerate.
   A faint top divider separates the destructive constraint-clear from the
   everyday redraw so the two can't be confused. */
.competition-pair-clearall[b-knzrotdx1b] {
    margin: 0.75rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border-subtle, #e3e8ef);
}

.competition-pair-clearall .btn[b-knzrotdx1b] {
    min-height: 44px;
}

/* Swap mode: a contained region with the prompt + radio picks. */
.competition-swap-mode[b-knzrotdx1b] {
    border: 1px solid rgba(13, 44, 85, 0.18);
    border-radius: 0.3rem;
    background: #fbfdff;
    padding: 0.75rem;
    margin-bottom: 0.75rem;
}

.competition-swap-prompt[b-knzrotdx1b] {
    font-weight: 600;
    color: #24384f;
    margin: 0 0 0.5rem;
}

.competition-swap-fieldset[b-knzrotdx1b] {
    border: none;
    padding: 0;
    margin: 0 0 0.5rem;
}

.competition-swap-radio[b-knzrotdx1b] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    margin-right: 1rem;
}

/* Swap step-1 Cancel (ux-review major 2): a full-width way out before a target is
   picked. min-height keeps it on the 44px touch floor like every other action. */
.competition-swap-step1-actions[b-knzrotdx1b] {
    margin-top: 0.5rem;
}

.competition-swap-step1-actions .btn[b-knzrotdx1b] {
    width: 100%;
    min-height: 44px;
}

/* Source-row marker (ux-review major 2): the row being swapped FROM shows a label
   instead of a blank action cell, so the organiser sees which pair is the source. */
.competition-swap-source-marker[b-knzrotdx1b] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-weight: 600;
    font-style: italic;
    color: #4b5a6c;
}

.competition-clearall-confirm[b-knzrotdx1b] {
    margin-top: 0.5rem;
}

@media (max-width: 700px) {
    /* Review actions stack and go full-width so each ≥44px tap target wraps cleanly
       at 390px — never a horizontal scroll. The action cell rides the same stacked-
       card reflow the slice-3 table already provides (display:block + data-label). */
    .competition-review-actions[b-knzrotdx1b] {
        flex-direction: column;
        align-items: stretch;
    }

    .competition-review-actions .btn[b-knzrotdx1b],
    .competition-review-actions .status-pill[b-knzrotdx1b] {
        width: 100%;
    }

    .competition-review-actions .status-pill[b-knzrotdx1b] {
        justify-content: center;
    }

    .competition-constraints-row[b-knzrotdx1b] {
        flex-direction: column;
        align-items: stretch;
    }

    .competition-constraints-row .btn[b-knzrotdx1b] {
        width: 100%;
    }

    .competition-addveto-actions .btn[b-knzrotdx1b],
    .competition-swap-actions .btn[b-knzrotdx1b],
    .competition-clearall-confirm-actions .btn[b-knzrotdx1b],
    .competition-review-regenerate .btn[b-knzrotdx1b],
    .competition-pair-clearall .btn[b-knzrotdx1b] {
        width: 100%;
    }

    .competition-swap-radio[b-knzrotdx1b] {
        display: flex;
    }
}

/* ── Groups step (slice 5) ─────────────────────────────────────────────────── */

/* Size picker (3/4/5): square radio cards reusing the pair-method card tokens
   (border, selected inset + tint). The whole card is the tap target; the radio
   itself is visually hidden, the big number is the label. 44px+ touch floor. */
.competition-group-size[b-knzrotdx1b] {
    border: 0;
    margin: 0 0 1rem;
    padding: 0;
}

/* "Pairs per group" legend (rework round 1, polish 7): unified with the listhead /
   section-label treatment (uppercase 0.85rem muted) so it matches
   .competition-groups-heading rather than reading as a bold sub-title. */
.competition-group-size-legend[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.5rem;
}

.competition-group-size-options[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.competition-size-card[b-knzrotdx1b] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 64px;
    min-height: 56px;
    padding: 0.5rem 1rem;
    border: 1px solid rgba(13, 44, 85, 0.25);
    border-radius: 0.5rem;
    background: #fff;
    cursor: pointer;
    user-select: none;
}

.competition-size-card--selected[b-knzrotdx1b] {
    box-shadow: inset 0 0 0 1px #0d2c55;
    background: #eef3fb;
}

/* Keyboard focus ring (rework round 1, polish 5): the radio is visually hidden, so
   surface its focus on the card — copied from the pair-method cards
   (.competition-pair-method:has(...:focus-visible)) so arrow-key navigation between
   sizes is visible. */
.competition-size-card:has(input:focus-visible)[b-knzrotdx1b] {
    border-color: #0d2c55;
    box-shadow: 0 0 0 2px rgba(13, 44, 85, 0.35);
}

.competition-size-card:has(input:disabled)[b-knzrotdx1b] {
    cursor: default;
    opacity: 0.7;
}

/* Hide the native radio; the card + number is the control. */
.competition-size-card input[b-knzrotdx1b] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

.competition-size-card-number[b-knzrotdx1b] {
    font-size: 1.4rem;
    font-weight: 700;
    color: #0d2c55;
}

/* Before-confirm preview: the resulting group sizes + a plain summary. */
.competition-group-preview[b-knzrotdx1b] {
    margin: 0 0 1rem;
    padding: 0.75rem;
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.5rem;
    background: #f7faff;
}

.competition-group-preview-sizes[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0 0 0.35rem;
}

.competition-group-preview-chip[b-knzrotdx1b] {
    display: inline-block;
    padding: 0.2rem 0.55rem;
    border-radius: 0.4rem;
    background: #e6eefb;
    color: #24384f;
    font-weight: 600;
    font-size: 0.9rem;
}

.competition-group-preview-note[b-knzrotdx1b] {
    margin: 0;
}

.competition-groups-generate[b-knzrotdx1b] {
    margin-bottom: 1rem;
}

.competition-groups-generate .btn[b-knzrotdx1b] {
    min-height: 44px;
}

/* "Groups generated." confirmation (rework round 1, polish 4): a distinct treatment
   so it doesn't read as a plain paragraph, WITHOUT going success-green (the kiosk/no-
   toast + reserved-green rules). A leading check glyph carries the "done" signal in a
   calm tint; the text stays the neutral navy of the Review status line. */
.competition-groups-status[b-knzrotdx1b] {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    color: #24384f;
    font-weight: 600;
    margin: 0 0 0.75rem;
}

.competition-groups-status[b-knzrotdx1b]::before {
    content: "\2713"; /* ✓ */
    color: #1b6e3b;
    font-weight: 700;
    flex: 0 0 auto;
}

/* Regenerate consequence hint (rework round 1, major 2): a quiet help-text note
   directly under the Generate-again button. */
.competition-groups-generate-note[b-knzrotdx1b] {
    margin: 0.4rem 0 0;
}

.competition-groups-heading[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 0.5rem 0 0.5rem;
}

.competition-groups-empty[b-knzrotdx1b] {
    margin: 0 0 0.75rem;
}

/* Group preview cards: a responsive grid of cards, one per group. */
.competition-group-cards[b-knzrotdx1b] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.competition-group-card[b-knzrotdx1b] {
    border: 1px solid rgba(13, 44, 85, 0.15);
    border-radius: 0.5rem;
    padding: 0.75rem;
    background: #fff;
}

.competition-group-card-title[b-knzrotdx1b] {
    color: #0d2c55;
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0 0 0.5rem;
}

/* LR-31c: group-header colour-coding on the Groups-step preview cards (mirrors the running
   surface's CompetitionInProgress accents - same palette, scoped here too since component CSS
   does not cross-share). A coloured left-border + faint tint per group index; dark navy text
   stays (AA on every tint). No new brand colours. */
.competition-group-card-title.competition-group-accent-0[b-knzrotdx1b],
.competition-group-card-title.competition-group-accent-1[b-knzrotdx1b],
.competition-group-card-title.competition-group-accent-2[b-knzrotdx1b],
.competition-group-card-title.competition-group-accent-3[b-knzrotdx1b],
.competition-group-card-title.competition-group-accent-4[b-knzrotdx1b],
.competition-group-card-title.competition-group-accent-5[b-knzrotdx1b] {
    border-left: 4px solid transparent;
    padding: 0.1rem 0 0.1rem 0.5rem;
    border-radius: 0.2rem;
}

.competition-group-accent-0[b-knzrotdx1b] { border-left-color: #2563a8; background: rgba(37, 99, 168, 0.10); }
.competition-group-accent-1[b-knzrotdx1b] { border-left-color: #1f8a70; background: rgba(31, 138, 112, 0.10); }
.competition-group-accent-2[b-knzrotdx1b] { border-left-color: #b3541e; background: rgba(179, 84, 30, 0.10); }
.competition-group-accent-3[b-knzrotdx1b] { border-left-color: #7048a8; background: rgba(112, 72, 168, 0.10); }
.competition-group-accent-4[b-knzrotdx1b] { border-left-color: #a01e58; background: rgba(160, 30, 88, 0.10); }
.competition-group-accent-5[b-knzrotdx1b] { border-left-color: #4b7a1e; background: rgba(75, 122, 30, 0.10); }

.competition-group-card-pairs[b-knzrotdx1b] {
    list-style: none;
    margin: 0 0 0.5rem;
    padding: 0;
}

.competition-group-card-pair[b-knzrotdx1b] {
    color: #24384f;
    font-weight: 500;
    padding: 0.2rem 0;
    /* LR-16: pair number badge + names + trailing bare rating on one line. The names
       flex-grow to push the rating to the right; the layout wraps cleanly at 390. */
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.competition-group-card-pair-names[b-knzrotdx1b] {
    flex: 1 1 auto;
    min-width: 0;
}

.competition-group-card-pair-rating[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.9rem;
    font-weight: 600;
    white-space: nowrap;
}

.competition-group-card-fixtures[b-knzrotdx1b] {
    margin: 0;
}

@media (max-width: 700px) {
    /* Single-column cards on a tablet/phone — no horizontal scroll. */
    .competition-group-cards[b-knzrotdx1b] {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 390px) {
    /* Preview chips: hold at least two per row on the narrowest phone (rework round 1,
       polish 6). The flex container has gap:0.4rem, so a calc(50% - 0.2rem) basis (half
       the gap) leaves exactly two across; further chips wrap below. flex-grow is 0 so a
       lone trailing chip on an odd row stays half-width rather than stretching to fill
       the row (which read as a broken full-width pill). */
    .competition-group-preview-chip[b-knzrotdx1b] {
        flex: 0 1 calc(50% - 0.2rem);
        text-align: center;
    }
}

/* ── Rules step (slice 6) ──────────────────────────────────────────────────── */

/* Display-fixed rules lines: #24384f on white = ~10:1, well past AA. */
.competition-rules-line[b-knzrotdx1b] {
    color: #24384f;
    margin: 0 0 0.75rem;
}

.competition-rules-tiebreak[b-knzrotdx1b] {
    color: #4b5a6c; /* ~7:1 on white — AA pass */
    font-size: 0.95rem;
}

/* Hint shown when no group stage exists yet: explains why Start is absent.
   #4b5a6c on white ~7:1 — AA pass. */
.competition-rules-no-groups-hint[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.95rem;
    margin-top: 0.5rem;
}

/* LR-31d: the lightweight inline Start-step summary - a compact key/value read-out of the
   choices the organiser is about to commit. A bordered tint block (not a heavy card) so it
   reads as a confirm, not a new section. Each row is a label/value pair; wraps cleanly at 390.
   Display-only, reuses existing wizard values. NOT a Review screen (LR-5 removal stands). */
.competition-rules-summary[b-knzrotdx1b] {
    margin: 0 0 1rem;
    padding: 0.75rem 0.9rem;
    border: 1px solid rgba(13, 44, 85, 0.15);
    border-radius: 0.5rem;
    background: rgba(13, 44, 85, 0.04);
}

.competition-rules-summary-item[b-knzrotdx1b] {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.2rem 0;
}

.competition-rules-summary-item:not(:last-child)[b-knzrotdx1b] {
    border-bottom: 1px solid rgba(13, 44, 85, 0.08);
}

.competition-rules-summary-item dt[b-knzrotdx1b] {
    color: #4b5a6c;
    font-weight: 600;
    margin: 0;
}

.competition-rules-summary-item dd[b-knzrotdx1b] {
    color: #0d2c55;
    font-weight: 600;
    margin: 0;
    text-align: right;
}

/* LR-17: the Scoring rules group (Game over score + Max score), display-only at the §6
   values. Same uppercase-legend rhythm as Match format below. */
.competition-rules-scoring[b-knzrotdx1b] {
    border: 0;
    margin: 1.25rem 0 1rem;
    padding: 0;
}

.competition-rules-scoring-legend[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.5rem;
}

.competition-rules-scoring-grid[b-knzrotdx1b] {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
}

.competition-rules-scoring-item[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0;
}

.competition-rules-scoring-label[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.9rem;
}

.competition-rules-scoring-value[b-knzrotdx1b] {
    color: #24384f;
    font-weight: 600;
    font-size: 1.1rem;
}

/* Breathing room before the MATCH FORMAT legend (rework round 2, polish 8): the prior
   rules line sat too tight against the uppercase legend. */
.competition-rules-format[b-knzrotdx1b] {
    border: 0;
    margin: 1.25rem 0 1rem;
    padding: 0;
}

.competition-rules-format-legend[b-knzrotdx1b] {
    color: #4b5a6c;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.5rem;
}

/* Format radios: display-only (both disabled). The selected one reads as chosen, the
   disabled Best-of-3 is muted with the coming-soon pill. 44px touch floor (standing
   rule, even though non-interactive — keeps the row rhythm + a real tap area). */
.competition-rules-format-option[b-knzrotdx1b] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.25rem 0.5rem;
    color: #24384f;
}

.competition-rules-format-option--selected[b-knzrotdx1b] {
    font-weight: 600;
}

.competition-rules-format-option--disabled[b-knzrotdx1b] {
    color: #6b7888; /* ~4.6:1 on white — AA pass for the muted disabled option */
}

/* Local coming-soon pill (CSS isolation scopes the Create-screen one to that
   component; this Rules screen needs its own copy with the same tokens). */
.coming-soon-pill[b-knzrotdx1b] {
    display: inline-block;
    background: #e6ebf2;
    color: #5a6b80;
    border-radius: 999px;
    padding: 0.05rem 0.55rem;
    font-size: 0.75rem;
    font-weight: 600;
    vertical-align: middle;
}

/* Head-start section: the moat centrepiece. The outcome copy reads FIRST and
   prominent (trust-critical — the S2 display lesson). A subtle card sets it apart. */
.competition-rules-headstart[b-knzrotdx1b] {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    margin: 1rem 0 1.25rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.15);
    border-radius: 0.5rem;
    background: #f7faff;
}

/* Matches the group-card-title convention (rework round 2, polish 3): 1.05rem / 700. */
.competition-rules-headstart-heading[b-knzrotdx1b] {
    margin: 0 0 0.5rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: #0d2c55;
}

/* The outcome line: larger + darker than help text so it reads as the headline. */
.competition-rules-headstart-copy[b-knzrotdx1b] {
    margin: 0;
    color: #24384f;
    font-size: 1rem;
    line-height: 1.5;
}

/* "What's a head start?" toggle: a plain text link, ≥44px tap row, no maths behind it.
   align-self: flex-start (rework round 2, polish 4) keeps it left-aligned inside the flex
   headstart card at every viewport — it was centring at 700/390 before. */
.competition-rules-headstart-help-toggle[b-knzrotdx1b] {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0.1rem;
    color: #0d2c55;
    text-decoration: underline;
    font-size: 0.95rem;
}

.competition-rules-headstart-help[b-knzrotdx1b] {
    margin-top: 0.5rem;
    padding: 0.75rem;
    border-radius: 0.4rem;
    background: #eef3fb;
    color: #24384f;
    line-height: 1.5;
}

/* Start competition primary action sits on the 44px floor like every wizard action. */
.competition-rules-start[b-knzrotdx1b] {
    min-height: 44px;
}

/* Terminal "Competition started" confirmation panel. */
.competition-rules-started[b-knzrotdx1b] {
    margin: 0 0 1rem;
}

/* Locked-state review hint (rework round 2, MAJOR 2): points the organiser at the steps
   above; pairs with the secondary "Review setup" NavLink so the started wizard isn't a
   dead end on mobile (where the rail pills are hidden). #4b5a6c on white ~7:1 — AA pass. */
.competition-rules-review-hint[b-knzrotdx1b] {
    color: #4b5a6c;
    margin: 0 0 0.75rem;
}

/* The post-Start read-only lock notice (shown on the setup steps once started). */
.competition-started-lock[b-knzrotdx1b] {
    margin-bottom: 1rem;
}

/* LR-21 (round 4A): the started-state read-only Rules view. Reuses the shared LR-17 grouping
   (.competition-rules-scoring / .competition-rules-format) verbatim; this wrapper just spaces
   it below the started confirmation + review hint and gives it a section heading. */
.competition-rules-started-rules[b-knzrotdx1b] {
    margin: 0 0 1rem;
}

.competition-rules-started-rules-heading[b-knzrotdx1b] {
    margin: 0 0 0.5rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: #0d2c55;
}
/* /Components/Pages/ConfirmSignIn.razor.rz.scp.css */
/* #751 (SPEC-01 §18.12): the /confirm-sign-in AUTHENTICATED screens.

   COMPONENT-SCOPED ON PURPOSE, and that is a decision, not a default (§18.12.8 #3).
   `.login-help-warning` has NO CSS rule anywhere in the application: it appears on two
   AcceptInvite.razor elements and in one E2E selector, so AcceptInvite's mismatch callout renders
   today as plain muted body text. Defining the rule GLOBALLY would restyle two shipped
   AcceptInvite renders as a silent side effect of this fix. Defining it here styles this page and
   reaches nothing else. AcceptInvite's unstyled warning is a real finding and stays one.

   Nothing in this file touches the SIGNED-OUT branch, which keeps `.login-actions` and the
   content-width button it has always had. That is what makes AC4 structurally true rather than
   carefully preserved: the two branches share no new selector. The resulting inconsistency (a
   small signed-out button beside a phone-sized authenticated one) is deliberate and recorded —
   widening it is a separate change, a candidate for #676.

   Colours are literal hex, matching app.css's own convention for the login shell. */

/* ── The identity block — the recognition surface ─────────────────────────────────────────────
   TWO CHIPS, NOT ONE DIVIDED BOX. The reader's job here is to COMPARE two addresses: two
   bordered rows read as a comparison, a divided box reads as a list. `overflow-wrap: anywhere`
   is what keeps a long address inside a 358px card instead of widening it — handled structurally
   rather than by hoping addresses are short. */
.confirm-identity[b-jnznamscuw] {
    margin: 0.9rem 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.confirm-identity-row[b-jnznamscuw] {
    background: #f6f9fc;
    border: 1px solid #e0e8f0;
    border-left: 3px solid #b9c6d4;
    border-radius: 0.4rem;
    padding: 0.5rem 0.7rem;
}

/* The TARGET chip carries the primary button's blue on its left edge, so a reader can see which
   chip the blue button acts on without reading either. */
.confirm-identity-row.target[b-jnznamscuw] {
    background: #f2f8fd;
    border-color: #cfe1f2;
    border-left-color: #1b6ec2;
}

.confirm-identity-label[b-jnznamscuw] {
    display: block;
    color: #5a6b7b;
    font-size: 0.78rem;
    margin-bottom: 0.05rem;
}

.confirm-identity-value[b-jnznamscuw] {
    display: block;
    color: #16324f;
    font-weight: 700;
    font-size: 1.05rem;
    overflow-wrap: anywhere;
    word-break: break-word;
    line-height: 1.3;
}

.confirm-identity-aside[b-jnznamscuw] {
    display: block;
    color: #5a6b7b;
    font-size: 0.76rem;
    margin-top: 0.25rem;
    font-weight: 400;
    line-height: 1.35;
}

/* The R8 promise line — informative, not a warning, so it takes the muted .login-help weight. */
.confirm-promise[b-jnznamscuw] {
    color: #5e748a;
    margin: 0.9rem 0 0;
}

/* ── The consequence callout (R3 / AC7) ──────────────────────────────────────────────────────
   Geometry matched to the existing .login-error / .login-notice pair so it reads as the same
   component family; amber because it is a consequence to heed, not an error that has happened. */
.login-help-warning[b-jnznamscuw] {
    background: #fff7e6;
    border: 1px solid #e8c877;
    color: #6f5310;
    border-radius: 0.5rem;
    padding: 0.6rem 0.7rem;
    margin: 0.75rem 0 0;
    font-size: 0.9rem;
}

.login-help-warning strong[b-jnznamscuw] {
    overflow-wrap: anywhere;
}

/* ── The action stack ────────────────────────────────────────────────────────────────────────
   Both actions full width, both a 3rem minimum height: EQUAL HIT AREA, with the hierarchy
   carried by colour alone. On a one-handed phone, shrinking the safe option nudges a hurried
   thumb toward the irreversible one — equal size is what makes "the safe choice is free" true in
   the hand and not only in the contract.

   Each of the two sibling forms (never nested — bug #27) is itself a flex item, so the buttons
   stack with no form= indirection and no `display: contents`. */
.confirm-actions[b-jnznamscuw] {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.9rem;
}

.confirm-actions form[b-jnznamscuw] {
    display: flex;
    flex-direction: column;
    margin: 0;
}

.confirm-actions .btn[b-jnznamscuw] {
    width: 100%;
    min-height: 3rem;
    font-size: 1.05rem;
    font-weight: 600;
}

/* Stay: a real button with a grey-blue border, deliberately NOT a text link (the contract
   forbids one) and deliberately not smaller than Continue. */
.btn-secondary-quiet[b-jnznamscuw] {
    background: #ffffff;
    border-color: #97a0aa;
    color: #2d3540;
}
/* /Components/Pages/Connect.razor.rz.scp.css */
/* FDD-0001 S3 (ado:1432): the RETIRED roster-claim-link landing.

   This file was ~258 lines dressing a roster picker — the scoped name list, its radios and
   hover states, the client-side search box, the "Connected" chip, the no-match line, the
   signed-in identity block and its sign-out button. All of that markup is gone, so the rules
   go with it rather than sitting here as dead weight that reads to the next editor like hooks
   that still exist.

   What remains is the shell Claim.razor's visual language shares — re-declared here because
   Blazor .razor.css is component-scoped and Claim.razor.css does not reach this page. */

.claim-shell[b-7jtdpfs124] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
}

.claim-head[b-7jtdpfs124] {
    text-align: center;
    margin-bottom: 1.5rem;
}

.claim-brand-wordmark[b-7jtdpfs124] {
    height: 1.75rem;
    width: auto;
}

.claim-title[b-7jtdpfs124] {
    font-size: 1.6rem;
    font-weight: 800;
    margin: 0.75rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
}

/* The lead sentence carries the remedy and is the load-bearing copy on this page (§7.4, as
   re-weighted 2026-09-10): with the officer-side notice withdrawn, a player forwarding this
   line up their WhatsApp thread is the ONLY channel by which a dead link is discovered. So it
   is sized and coloured as body text a person reads, not as a muted caption. */
.claim-sub[b-7jtdpfs124] {
    margin: 0 0 0.75rem;
    color: #33506f;
    font-size: 1rem;
}

.claim-card[b-7jtdpfs124] {
    background: #f6f9fc;
    border: 1px solid #e0e8f0;
    border-radius: 0.75rem;
    padding: 1.5rem 1.25rem;
    text-align: center;
}

.claim-help[b-7jtdpfs124] {
    color: #5a6b7b;
    font-size: 0.9rem;
}

/* The three steps are LEFT-ALIGNED inside a centred card, deliberately. .claim-card centres
   its contents, which is right for a title and a pair of buttons and wrong for an ordered
   list: centred list items detach from their numbers and each line starts in a different
   place, so the eye has to re-find the start of every step. This is a sequence of
   instructions a person follows one at a time, in another app, on a phone. */
.connect-retired-steps[b-7jtdpfs124] {
    text-align: left;
    margin: 1rem 0 0;
    padding-left: 1.4rem;
    color: #33506f;
    font-size: 0.92rem;
    line-height: 1.55;
}

.connect-retired-steps li + li[b-7jtdpfs124] {
    margin-top: 0.5rem;
}

.claim-actions[b-7jtdpfs124] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* The 44px kiosk/touch floor the tokens already carry. Every target on this page clears it —
   the audience is one-handed on a phone in the evening. */
.claim-actions .btn[b-7jtdpfs124],
.claim-shell .btn[b-7jtdpfs124] {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
}
/* /Components/Pages/CourtUtilisationReport.razor.rz.scp.css */
.reports-shell[b-0h8xfbu4h1] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-0h8xfbu4h1] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-0h8xfbu4h1] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-0h8xfbu4h1],
.reports-crumb-link:focus-visible[b-0h8xfbu4h1] {
    text-decoration: underline;
    outline: none;
}

.cu-head[b-0h8xfbu4h1] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.cu-head h1[b-0h8xfbu4h1] {
    margin: 0;
    color: #1f3f5e;
}

.cu-sub[b-0h8xfbu4h1] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.cu-head-actions[b-0h8xfbu4h1] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.cu-select-label[b-0h8xfbu4h1] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
    margin: 0;
}

.cu-select[b-0h8xfbu4h1] {
    border: 1px solid #d8e2ee;
    border-radius: 0.5rem;
    padding: 0.45rem 0.75rem;
    font-size: 0.82rem;
    color: #2a3a4d;
    background: #f7faff;
    font-weight: 600;
    max-width: 380px;
}

.cu-select:disabled[b-0h8xfbu4h1] {
    opacity: 0.55;
    cursor: default;
}

/* tiles */
.cu-tiles[b-0h8xfbu4h1] {
    display: grid;
    grid-template-columns: 1.3fr 1fr 1fr 1fr;
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.cu-tile[b-0h8xfbu4h1] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.cu-tile .lab[b-0h8xfbu4h1] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.cu-tile .val[b-0h8xfbu4h1] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
}

.cu-tile .val small[b-0h8xfbu4h1] {
    font-size: 0.95rem;
    font-weight: 700;
}

.cu-tile .sub[b-0h8xfbu4h1] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

.cu-tile.hero[b-0h8xfbu4h1] {
    background: linear-gradient(135deg, #1d5c86, #2b6fa0);
    border-color: #1d5c86;
}

.cu-tile.hero .lab[b-0h8xfbu4h1] {
    color: #cfe2f2;
}

.cu-tile.hero .val[b-0h8xfbu4h1] {
    color: #ffffff;
    font-size: 2.4rem;
}

.cu-tile.hero .sub[b-0h8xfbu4h1] {
    color: #dceaf6;
}

/* cards */
.cu-card[b-0h8xfbu4h1] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    margin-bottom: 1.15rem;
    padding: 1rem 1.2rem 1.2rem;
}

.cu-card-head[b-0h8xfbu4h1] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.cu-card-head h3[b-0h8xfbu4h1] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.cu-card-head .d[b-0h8xfbu4h1] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

.cu-chart[b-0h8xfbu4h1] {
    position: relative;
}

.cu-callout[b-0h8xfbu4h1] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: #fdeccd;
    border: 1px solid #f0d690;
    border-radius: 0.65rem;
    padding: 0.7rem 0.9rem;
    color: #6e4700;
    font-size: 0.85rem;
    margin-top: 0.8rem;
}

.cu-callout b[b-0h8xfbu4h1] {
    color: #5a3c00;
}

.cu-callout .bi[b-0h8xfbu4h1] {
    font-size: 1.05rem;
    color: #cf7a1a;
    flex: 0 0 auto;
}

/* within-evening timeline */
.cu-timeline[b-0h8xfbu4h1] {
    margin-top: 0.3rem;
}

.cu-tlrow[b-0h8xfbu4h1] {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin: 0.45rem 0;
}

.cu-tlrow .c[b-0h8xfbu4h1] {
    width: 72px;
    flex: 0 0 72px;
    font-size: 0.8rem;
    color: #52617a;
    font-weight: 600;
}

.cu-tlrow .blocks[b-0h8xfbu4h1] {
    flex: 1;
    display: flex;
    gap: 2px;
    height: 22px;
}

.cu-tlrow .blk[b-0h8xfbu4h1] {
    flex: 1;
    border-radius: 2px;
    background: #dbe7f5;
}

.cu-tlrow .blk.on[b-0h8xfbu4h1] {
    background: #2e9c63;
}

.cu-tlrow .blk.idle[b-0h8xfbu4h1] {
    background: #f3d9bf;
}

.cu-tlkey[b-0h8xfbu4h1] {
    font-size: 0.76rem;
    color: #6c7a8c;
    margin-top: 0.7rem;
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
}

.cu-tlkey i[b-0h8xfbu4h1] {
    display: inline-block;
    width: 11px;
    height: 11px;
    border-radius: 3px;
    margin-right: 0.35rem;
    vertical-align: middle;
}

.cu-tlkey .cu-sw-on[b-0h8xfbu4h1] {
    background: #2e9c63;
}

.cu-tlkey .cu-sw-idle[b-0h8xfbu4h1] {
    background: #f3d9bf;
}

.cu-tlkey-range[b-0h8xfbu4h1] {
    color: #9aa6b6;
}

/* the value-message strip */
.cu-msg[b-0h8xfbu4h1] {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    background: linear-gradient(90deg, #eef6ff, #f6fbff);
    border: 1px solid #cfe1f4;
    border-radius: 0.75rem;
    padding: 0.9rem 1.1rem;
    color: #274a6b;
    font-size: 0.85rem;
}

.cu-msg .ic[b-0h8xfbu4h1] {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #cfe6ff;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}

.cu-msg .ic .bi[b-0h8xfbu4h1] {
    font-size: 1rem;
    color: #1d5c86;
}

.cu-msg .q[b-0h8xfbu4h1] {
    font-size: 0.95rem;
    font-weight: 700;
    color: #1f3f5e;
}

@media (max-width: 820px) {
    .cu-tiles[b-0h8xfbu4h1] {
        grid-template-columns: repeat(2, 1fr);
    }
    .cu-head-actions[b-0h8xfbu4h1] {
        margin-left: 0;
    }
}

@media (max-width: 480px) {
    .cu-tiles[b-0h8xfbu4h1] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/CreateClub.razor.rz.scp.css */
/* #867 (A4): the player-facing create-a-club on-ramp (mock 07). Same centred card column + visual
   tokens as /player-clubs and /my-club/{slug} (one shared player language, NO new brand: navy #16324f,
   blue #1b6ec2 / #006bb7, off-white cards, green success #226b39). Scoped per component (the PegboardWeb
   per-page .razor.css pattern), so every token used is defined here. Built to mock 07. */

.my-shell[b-fni0uwk4nr] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-fni0uwk4nr] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-fni0uwk4nr] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-fni0uwk4nr],
.my-back:focus-visible[b-fni0uwk4nr] {
    text-decoration: underline;
}

.my-back-caret[b-fni0uwk4nr] {
    font-weight: 700;
}

.my-backbar-title[b-fni0uwk4nr] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem; /* keep clear of the Back control on the left */
}

/* ── Card. ── */
.my-card[b-fni0uwk4nr] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Lead / intro copy. ── */
.cc-lead[b-fni0uwk4nr] {
    color: #5e748a;
    font-size: 0.95rem;
    margin: 0.2rem 0 1rem;
}

/* ── Form fields. ── */
.cc-field-label[b-fni0uwk4nr] {
    display: block;
    font-weight: 700;
    color: #16324f;
    font-size: 0.9rem;
    margin: 0 0 0.4rem;
}

.cc-field-label-spaced[b-fni0uwk4nr] {
    margin-top: 1rem;
}

.cc-field-optional[b-fni0uwk4nr] {
    font-weight: 400;
    color: #5e748a;
}

.cc-input[b-fni0uwk4nr] {
    display: block;
    width: 100%;
    min-height: 44px;
    padding: 0.5rem 0.75rem;
    border: 1px solid #cbd6e2;
    border-radius: 0.55rem;
    font-size: 0.95rem;
    color: #1f2d3d;
    background: #fff;
    box-sizing: border-box;
}

.cc-input:focus-visible[b-fni0uwk4nr] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
    border-color: #1b6ec2;
}

.cc-input.is-error[b-fni0uwk4nr] {
    border-color: #d9534f;
}

.cc-field-hint[b-fni0uwk4nr] {
    margin: 0.5rem 0 0;
    color: #5e748a;
    font-size: 0.85rem;
}

.cc-field-error[b-fni0uwk4nr] {
    margin: 0.5rem 0 0;
    color: #9a2222;
    font-size: 0.85rem;
    font-weight: 600;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-fni0uwk4nr] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-fni0uwk4nr] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-fni0uwk4nr],
.my-btn-primary:focus-visible[b-fni0uwk4nr] {
    background: #155ba3;
}

.my-btn-block[b-fni0uwk4nr] {
    display: flex;
    width: 100%;
}

.cc-submit[b-fni0uwk4nr] {
    min-height: 48px;
    font-size: 1rem;
}

.cc-submit-hint[b-fni0uwk4nr] {
    text-align: center;
    margin-top: 0.8rem;
}

/* ── Create-failed / error banner (matches the /player-clubs error banner token). ── */
.clubs-banner[b-fni0uwk4nr] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-fni0uwk4nr] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* ── Success state (mock 07 middle). ── */
.cc-success-banner[b-fni0uwk4nr] {
    background: #eaf5ec;
    border: 1px solid #bfe0c7;
    color: #226b39;
    border-radius: 0.6rem;
    padding: 0.8rem 0.95rem;
    font-weight: 600;
    font-size: 0.95rem;
    margin: 0 0 1rem;
}

.cc-club-card[b-fni0uwk4nr] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.2rem 1.15rem;
    margin-bottom: 1.2rem;
    text-align: center;
}

.cc-badge[b-fni0uwk4nr] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 0.7rem;
    background: #0d2c55;
    color: #fff;
    font-weight: 800;
    font-size: 1.3rem;
    margin: 0 auto 0.5rem;
}

.cc-club-name[b-fni0uwk4nr] {
    font-size: 1.15rem;
    font-weight: 800;
    color: #16324f;
    overflow-wrap: break-word;
}

.cc-club-meta[b-fni0uwk4nr] {
    color: #5e748a;
    font-size: 0.9rem;
    margin-top: 0.15rem;
}

/* ── Get-started menu rows (mock 03 menu-item pattern). ── */
.cc-group-label[b-fni0uwk4nr] {
    margin: 1rem 0 0.55rem;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    font-weight: 700;
}

.cc-item[b-fni0uwk4nr] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    min-height: 52px;
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.45rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    text-decoration: none;
    color: inherit;
}

.cc-item:hover[b-fni0uwk4nr],
.cc-item:focus-visible[b-fni0uwk4nr] {
    border-color: #1b6ec2;
    background: #f7fbff;
    outline: none;
}

.cc-item-ico[b-fni0uwk4nr] {
    flex: 0 0 auto;
    font-size: 1.2rem;
    line-height: 1;
}

.cc-item-body[b-fni0uwk4nr] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.cc-item-t[b-fni0uwk4nr] {
    font-weight: 700;
    color: #16324f;
}

.cc-item-m[b-fni0uwk4nr] {
    color: #5e748a;
    font-size: 0.85rem;
}

.cc-item-go[b-fni0uwk4nr] {
    flex: 0 0 auto;
    color: #9aa8b8;
    font-size: 1.3rem;
    font-weight: 700;
}

/* ── Navy "Manage this club" gateway (#1045, option A). The single primary next-step console door,
   styled to match the club-menu Manage door (#6875b936): solid navy fill, white title, light navy-grey
   subtitle/icon/chevron - so it reads as the major console door and clearly outranks the light "View your
   club" secondary row. Green stays reserved for act-now; navy = enter the console. Overrides the base
   .cc-item light-bg/dark-text tokens on its children so everything is legible on navy. ── */
.cc-item.manage[b-fni0uwk4nr] {
    background: #0d2c55;
    border-color: #0d2c55;
}

.cc-item.manage .cc-item-t[b-fni0uwk4nr] {
    color: #fff;
    font-weight: 500;
}

.cc-item.manage .cc-item-m[b-fni0uwk4nr] {
    color: #b8c6da;
}

.cc-item.manage .cc-item-ico[b-fni0uwk4nr] {
    color: #b8c6da;
}

.cc-item.manage .cc-item-go[b-fni0uwk4nr] {
    color: #b8c6da;
}

/* Hover/focus lift to a lighter navy so it still reads as tappable. */
a.cc-item.manage:hover[b-fni0uwk4nr],
a.cc-item.manage:focus-visible[b-fni0uwk4nr] {
    background: #16386b;
    border-color: #16386b;
}

/* Restore an accessible focus ring - the base .cc-item:focus-visible zeroes the outline, so put back a
   light ring visible against the navy fill. */
a.cc-item.manage:focus-visible[b-fni0uwk4nr] {
    outline: 2px solid #9ec2ff;
    outline-offset: 2px;
}
/* /Components/Pages/DemoIntro.razor.rz.scp.css */
.demo-intro-shell[b-k364hqi7u3] {
    max-width: 640px;
    margin: 2.5rem auto;
    padding: 0 1.5rem;
    color: #333;
    line-height: 1.6;
}

.demo-intro-card h1[b-k364hqi7u3] {
    color: #1f3f5e;
    margin-bottom: 0.4rem;
}

.demo-intro-preview[b-k364hqi7u3] {
    max-width: 100%;
    height: auto;
    display: block;
    margin: 1rem auto 1.4rem;
    border: 1px solid #d3dce4;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.demo-intro-error[b-k364hqi7u3] {
    background: #fde8e8;
    border: 1px solid #f5b5b5;
    color: #8b2331;
    border-radius: 0.45rem;
    padding: 0.5rem 0.75rem;
    margin: 0.75rem 0;
    font-size: 0.9rem;
}

.demo-intro-enter[b-k364hqi7u3] {
    margin: 1.4rem 0 0.5rem;
}

.demo-intro-subhead[b-k364hqi7u3] {
    margin-top: 1.6rem;
    font-weight: 600;
}

.demo-intro-benefits[b-k364hqi7u3] {
    list-style: none;
    margin: 0.6rem 0 1.2rem;
    padding: 0;
}

.demo-intro-benefits li[b-k364hqi7u3] {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    margin: 0.7rem 0;
}

.demo-intro-benefits li > svg[b-k364hqi7u3] {
    flex-shrink: 0;
    color: #1b6ec2;
    margin-top: 0.2rem;
}

.demo-intro-benefits li > span[b-k364hqi7u3] {
    flex: 1;
}

/* BL-074 parity: on phones the desktop screenshot pushed the entry button below
   the fold; drop it and tighten the top margin so "Enter the demo" is visible
   without scrolling. */
@media (max-width: 640px) {
    .demo-intro-shell[b-k364hqi7u3] {
        margin: 1rem auto;
    }

    .demo-intro-preview[b-k364hqi7u3] {
        display: none;
    }

    .demo-intro-enter[b-k364hqi7u3] {
        width: 100%;
    }
}
/* /Components/Pages/FeatureFlags.razor.rz.scp.css */
/* #810 S2 — superuser feature-flag screen. Base shell/card/subtitle classes are copied from
   Clubs.razor.css (Blazor scoped CSS is per-component, and each superuser page owns its own copy —
   the classes are NOT global). Feature-row classes below are new to this screen. */

.clubs-shell[b-rezm2mzwm8] {
    padding: 0;
}

.clubs-shell h1[b-rezm2mzwm8] {
    margin: 0 0 0.25rem;
    color: #1f3f5e;
}

.clubs-subtitle[b-rezm2mzwm8] {
    margin: 0 0 1rem;
    color: #5f7489;
    max-width: 60rem;
}

.clubs-card[b-rezm2mzwm8] {
    background: #f6f8fb;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.25rem;
    margin-bottom: 1rem;
    padding: 1rem;
}

.feature-flags-head[b-rezm2mzwm8] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.65rem;
}

.feature-flags-name[b-rezm2mzwm8] {
    font-size: 1.05rem;
    font-weight: 600;
    color: #24384f;
}

.feature-flags-key[b-rezm2mzwm8] {
    margin-left: 0.5rem;
    font-size: 0.78rem;
    color: #8090a2;
    font-family: var(--bs-font-monospace, monospace);
}

/* Inline saved confirmation - sits next to the controls it confirms, not across the card. */
.feature-flags-saved[b-rezm2mzwm8] {
    font-size: 0.82rem;
    font-weight: 600;
    color: #2f7d4f;
    align-self: center;
}

.feature-flags-controls[b-rezm2mzwm8] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.25rem;
}

.feature-flags-toggle[b-rezm2mzwm8] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    font-weight: 400;
}

.feature-flags-toggle-label[b-rezm2mzwm8] {
    font-size: 0.9rem;
    color: #24384f;
}

/* Default + overrides group. Gets a POSITIVE inert treatment (panel + chip) when the feature is off. */
.feature-flags-dependent[b-rezm2mzwm8] {
    display: inline-flex;
    align-items: center;
    gap: 1.25rem;
    padding: 0.3rem 0.6rem;
    border-radius: 0.3rem;
    border: 1px solid transparent;
}

.feature-flags-dependent-inert[b-rezm2mzwm8] {
    background: #f4f0e6;
    border-color: #e3d6ad;
}

/* Default toggle greyed + not-allowed cursor while inert (Enabled off, or config floor off). */
.feature-flags-toggle-inert .feature-flags-toggle-label[b-rezm2mzwm8] {
    color: #9aa7b6;
}

.feature-flags-toggle-inert[b-rezm2mzwm8] {
    cursor: not-allowed;
}

.feature-flags-overrides[b-rezm2mzwm8] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
    color: #4e6f8e;
}

.feature-flags-overrides-count[b-rezm2mzwm8] {
    font-size: 1.05rem;
    font-weight: 700;
    color: #1f3f5e;
}

.feature-flags-overrides-label[b-rezm2mzwm8] {
    font-size: 0.85rem;
}

.feature-flags-dependent-inert .feature-flags-overrides[b-rezm2mzwm8],
.feature-flags-dependent-inert .feature-flags-overrides-count[b-rezm2mzwm8] {
    color: #9aa7b6;
}

/* Explicit "this block is off" chip so an inert Default can't read as a normal unchecked toggle. */
.feature-flags-inert-chip[b-rezm2mzwm8] {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: #e9dcb8;
    color: #6a4a08;
    border: 1px solid #d9c384;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.feature-flags-inert-note[b-rezm2mzwm8] {
    margin: 0.65rem 0 0;
    font-size: 0.85rem;
    color: #8090a2;
}

/* #810 S3 — per-club override manager. Sits below the controls row. Greys out together with the
   dependent block (same inert state as Default/#overrides) when Enabled is off (AC6). */
.feature-flags-overrides-manager[b-rezm2mzwm8] {
    margin-top: 0.85rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(13, 44, 85, 0.08);
}

.feature-flags-overrides-manager-inert[b-rezm2mzwm8] {
    opacity: 0.55;
    /* All children are already disabled; pointer-events:none kills the hover-cursor ambiguity so the
       greyed block reads as inert, consistent with the S2 dependent-block inert treatment. */
    pointer-events: none;
}

.feature-flags-overrides-heading[b-rezm2mzwm8] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.feature-flags-overrides-heading > span:first-child[b-rezm2mzwm8] {
    font-size: 0.9rem;
    font-weight: 600;
    color: #24384f;
}

.feature-flags-overrides-hint[b-rezm2mzwm8] {
    font-size: 0.8rem;
    color: #8090a2;
}

.feature-flags-overrides-empty[b-rezm2mzwm8] {
    margin: 0 0 0.5rem;
    font-size: 0.85rem;
    color: #8090a2;
}

.feature-flags-override-list[b-rezm2mzwm8] {
    list-style: none;
    margin: 0 0 0.6rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.feature-flags-override-item[b-rezm2mzwm8] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    padding: 0.35rem 0.5rem;
    background: #eef2f7;
    border: 1px solid rgba(13, 44, 85, 0.08);
    border-radius: 0.3rem;
}

.feature-flags-override-club[b-rezm2mzwm8] {
    font-weight: 600;
    color: #24384f;
    min-width: 10rem;
}

/* Keep the two action buttons together as one unit so they wrap as a pair, anchored to the club-name
   row, rather than splitting across lines away from the name/pill. */
.feature-flags-override-actions[b-rezm2mzwm8] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Override state pill — ON = green, OFF = red, so "override OFF" can never read as "no override". */
.feature-flags-override-state[b-rezm2mzwm8] {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.feature-flags-override-on[b-rezm2mzwm8] {
    background: #d7f0df;
    color: #1f6a3a;
    border: 1px solid #a9d9ba;
}

.feature-flags-override-off[b-rezm2mzwm8] {
    background: #f7dcdc;
    color: #92302f;
    border: 1px solid #e2acab;
}

.feature-flags-override-add[b-rezm2mzwm8] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.feature-flags-override-add-label[b-rezm2mzwm8] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #24384f;
}

.feature-flags-override-club-select[b-rezm2mzwm8] {
    max-width: 16rem;
}

.feature-flags-override-value-select[b-rezm2mzwm8] {
    max-width: 9rem;
}

.feature-flags-override-add-note[b-rezm2mzwm8] {
    font-size: 0.8rem;
    color: #8090a2;
}
/* /Components/Pages/Feedback.razor.rz.scp.css */
.feedback-shell[b-ao8wbvv6f5] {
    min-height: calc(100vh - 5rem);
    display: grid;
    place-items: start center;
    padding: 1.5rem 0;
}

.feedback-card[b-ao8wbvv6f5] {
    width: min(40rem, 94vw);
    border: 1px solid #c4d1de;
    border-radius: 0.75rem;
    background: #f6f9fc;
    padding: 1.1rem;
}

.feedback-card h1[b-ao8wbvv6f5] {
    margin: 0 0 0.35rem;
    color: #1f3f5e;
}

.feedback-help[b-ao8wbvv6f5] {
    color: #5e748a;
    margin: 0 0 0.8rem;
}

.feedback-actions[b-ao8wbvv6f5] {
    margin-top: 0.9rem;
}

.feedback-error[b-ao8wbvv6f5] {
    margin-top: 0.75rem;
    border: 1px solid #d88f8f;
    background: #f7e3e3;
    color: #8a2d2d;
    border-radius: 0.5rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.88rem;
}

.feedback-success[b-ao8wbvv6f5] {
    margin-top: 0.5rem;
    border: 1px solid #9ac29a;
    background: #e4f3e4;
    color: #2d5b2d;
    border-radius: 0.5rem;
    padding: 0.5rem 0.6rem;
    font-size: 0.92rem;
}
/* /Components/Pages/FixtureAvailabilityPage.razor.rz.scp.css */
/* SPEC-34 S3 — the /f/{token} availability page (mobile-first, kiosk-agnostic). Mirrors
   the claim/connect card language; palette matches the #297 mock's player screens. */
.fav-shell[b-ytbjjs0g9i] {
    max-width: 26rem;
    margin: 0 auto;
    padding: 1.1rem 1rem 2rem;
    display: flex;
    flex-direction: column;
    gap: .8rem;
}

/* SPEC-34 S6 (Owner UAT): the portal back link for a signed-in squad member (Tier A only).
   Mirrors the player shell's .my-backbar / .my-back look (Blazor CSS isolation re-declares it
   here) so the two surfaces read as one. Absent entirely for the anonymous visitor. */
.fav-backbar[b-ytbjjs0g9i] {
    margin-bottom: .2rem;
}

.fav-back[b-ytbjjs0g9i] {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: .95rem;
}

.fav-back:hover[b-ytbjjs0g9i],
.fav-back:focus-visible[b-ytbjjs0g9i] {
    text-decoration: underline;
}

.fav-back-caret[b-ytbjjs0g9i] {
    font-weight: 700;
}

.fav-head[b-ytbjjs0g9i] {
    display: flex;
    justify-content: center;
    padding: .3rem 0 .2rem;
}

.fav-wordmark[b-ytbjjs0g9i] {
    height: 1.5rem;
    width: auto;
}

.fav-banner[b-ytbjjs0g9i] {
    background: #12324f;
    color: #eaf3fb;
    border-radius: .85rem;
    padding: 1rem 1.1rem;
}

.fav-vs[b-ytbjjs0g9i] {
    font-weight: 800;
    font-size: 1.15rem;
}

.fav-meta[b-ytbjjs0g9i] {
    margin-top: .25rem;
    font-size: .9rem;
    color: #bcd8f0;
}

.fav-sub[b-ytbjjs0g9i] {
    margin-top: .3rem;
    font-size: .8rem;
    color: #8fb8dc;
}

.fav-card[b-ytbjjs0g9i] {
    background: #fff;
    border: 1px solid #e3eaf1;
    border-radius: .85rem;
    padding: 1.1rem;
}

.fav-title[b-ytbjjs0g9i] {
    font-size: 1.2rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 .4rem;
}

.fav-whoami[b-ytbjjs0g9i] {
    font-size: .95rem;
    color: #33506b;
    margin-bottom: .5rem;
}

.fav-ask[b-ytbjjs0g9i] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.05rem;
    margin-bottom: .8rem;
}

.fav-section[b-ytbjjs0g9i] {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .72rem;
    font-weight: 700;
    color: #8496a8;
    margin-bottom: .5rem;
}

.fav-fieldset[b-ytbjjs0g9i] {
    border: 0;
    margin: 0 0 .8rem;
    padding: 0;
}

.fav-legend[b-ytbjjs0g9i] {
    font-weight: 700;
    color: #33506b;
    font-size: .85rem;
    margin-bottom: .35rem;
}

.fav-name-option[b-ytbjjs0g9i] {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .6rem .7rem;
    border: 1px solid #dbe4ec;
    border-radius: .6rem;
    margin-bottom: .4rem;
    cursor: pointer;
}

.fav-name-option:has(.fav-name-radio:checked)[b-ytbjjs0g9i] {
    border-color: #1861ac;
    background: #f2f8ff;
}

.fav-name-claimed[b-ytbjjs0g9i] {
    opacity: .6;
    cursor: default;
    justify-content: space-between;
}

.fav-connected-chip[b-ytbjjs0g9i] {
    font-size: .68rem;
    font-weight: 700;
    color: #4a6b52;
    background: #e6f4ea;
    border-radius: 1rem;
    padding: .1rem .5rem;
}

.fav-field-label[b-ytbjjs0g9i] {
    display: block;
    font-size: .85rem;
    font-weight: 600;
    color: #33506b;
    margin: .3rem 0 .25rem;
}

.fav-optional[b-ytbjjs0g9i] {
    color: #8496a8;
    font-weight: 500;
}

.fav-input[b-ytbjjs0g9i] {
    width: 100%;
    padding: .55rem .7rem;
    border: 1px solid #cdd8e2;
    border-radius: .55rem;
    font-size: 1rem;
    margin-bottom: .7rem;
}

.fav-consent[b-ytbjjs0g9i] {
    display: flex;
    gap: .55rem;
    align-items: flex-start;
    font-size: .82rem;
    color: #47607a;
    margin-bottom: .9rem;
}

.fav-consent input[b-ytbjjs0g9i] {
    margin-top: .18rem;
}

.fav-btn[b-ytbjjs0g9i] {
    display: block;
    width: 100%;
    padding: .8rem;
    border: 0;
    border-radius: .6rem;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    margin-bottom: .55rem;
}

.fav-btn-yes[b-ytbjjs0g9i] {
    background: #1861ac;
    color: #fff;
}

.fav-btn-no[b-ytbjjs0g9i] {
    background: #eef2f6;
    color: #33506b;
}

.fav-done[b-ytbjjs0g9i] {
    text-align: center;
}

.fav-tick[b-ytbjjs0g9i] {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: #e6f4ea;
    color: #2c8a4a;
    font-size: 1.6rem;
    line-height: 3rem;
    margin: 0 auto .5rem;
}

.fav-response-row[b-ytbjjs0g9i] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
}

.fav-name[b-ytbjjs0g9i] {
    font-weight: 700;
    color: #16324f;
}

.fav-pill[b-ytbjjs0g9i] {
    font-size: .78rem;
    font-weight: 700;
    border-radius: 1rem;
    padding: .2rem .6rem;
}

.fav-pill-yes[b-ytbjjs0g9i] {
    background: #e6f4ea;
    color: #2c7a45;
}

.fav-pill-no[b-ytbjjs0g9i] {
    background: #fdecec;
    color: #b23b3b;
}

.fav-change[b-ytbjjs0g9i] {
    margin-top: .7rem;
}

.fav-linkbtn[b-ytbjjs0g9i] {
    background: none;
    border: 0;
    color: #1861ac;
    font-weight: 700;
    font-size: .85rem;
    cursor: pointer;
    padding: 0;
}

.fav-error[b-ytbjjs0g9i] {
    border-color: #f0c8c8;
    background: #fdf3f3;
    color: #8a3b3b;
}

.fav-inline-error[b-ytbjjs0g9i] {
    background: #fdecec;
    color: #b23b3b;
    border-radius: .5rem;
    padding: .5rem .7rem;
    font-size: .85rem;
    margin-bottom: .7rem;
}

.fav-reassure[b-ytbjjs0g9i] {
    font-size: .8rem;
    color: #6b7c8d;
}

.fav-help[b-ytbjjs0g9i] {
    font-size: .8rem;
    color: #8496a8;
}

/* ── S5: the player fixture view (p3) ── */
.fav-status--yes[b-ytbjjs0g9i] {
    border-color: #bbeecb;
    background: #f0fdf4;
}

.fav-status--no[b-ytbjjs0g9i] {
    border-color: #f0c8c8;
    background: #fdf3f3;
}

.fav-status-note[b-ytbjjs0g9i] {
    margin-top: .5rem;
    font-size: .9rem;
    color: #47607a;
    line-height: 1.45;
}

.fav-pill-standby[b-ytbjjs0g9i] {
    background: #fff5e0;
    color: #8a6300;
}

.fav-pill-neutral[b-ytbjjs0g9i] {
    background: #eef2f6;
    color: #45607a;
}

.fav-section-count[b-ytbjjs0g9i] {
    text-transform: none;
    letter-spacing: 0;
    color: #8496a8;
    font-weight: 600;
}

.fav-section--sub[b-ytbjjs0g9i] {
    margin-top: .9rem;
}

.fav-team-row[b-ytbjjs0g9i] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    padding: .55rem .1rem;
    border-bottom: 1px solid #eef2f6;
}

.fav-team-row:last-child[b-ytbjjs0g9i] {
    border-bottom: 0;
}

.fav-team-row--you[b-ytbjjs0g9i] {
    background: #f2f8ff;
    border-radius: .5rem;
    padding-left: .6rem;
    padding-right: .6rem;
    border-bottom: 0;
}

.fav-team-row--sub .fav-name[b-ytbjjs0g9i] {
    color: #33506b;
}

.fav-team-meta[b-ytbjjs0g9i] {
    font-size: .78rem;
    color: #8496a8;
    font-weight: 600;
}

.fav-btn-withdraw[b-ytbjjs0g9i] {
    background: #fdecec;
    color: #b23b3b;
    border: 1px solid #f0c8c8;
}
/* /Components/Pages/FixtureAvailabilityView.razor.rz.scp.css */
/* SPEC-34 S3 — captain availability view (c-avail). House tokens only. */
.fav-hdr[b-hmca4utui0] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.fav-nudge-panel[b-hmca4utui0] {
    margin-bottom: 1rem;
}

.fixshare-copybar[b-hmca4utui0] {
    display: flex;
    align-items: center;
    gap: .6rem;
    background: #eef2f7;
    border: 1px solid #d7dee7;
    border-radius: .6rem;
    padding: .5rem .65rem;
}

.fixshare-url[b-hmca4utui0] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .8rem;
    color: #24405c;
}

.fav-counts[b-hmca4utui0] {
    display: flex;
    gap: .6rem;
    margin-bottom: 1rem;
}

.fav-count[b-hmca4utui0] {
    flex: 1 1 0;
    text-align: center;
    border-radius: .7rem;
    padding: .7rem .4rem;
    border: 1px solid #e2e8f0;
}

.fav-count .k[b-hmca4utui0] {
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1;
}

.fav-count .l[b-hmca4utui0] {
    font-size: .72rem;
    color: #5e748a;
    margin-top: .2rem;
}

.fav-count-yes[b-hmca4utui0] {
    background: #f0fdf4;
    border-color: #bbf7d0;
}

.fav-count-yes .k[b-hmca4utui0] {
    color: #1c6b3f;
}

.fav-count-no[b-hmca4utui0] {
    background: #fdf3f3;
    border-color: #f0c8c8;
}

.fav-count-no .k[b-hmca4utui0] {
    color: #b23b3b;
}

.fav-count-wait[b-hmca4utui0] {
    background: #f7f9fb;
    border-color: #e2e8f0;
}

.fav-count-wait .k[b-hmca4utui0] {
    color: #7a8b9c;
}

.fav-rrow[b-hmca4utui0] {
    display: flex;
    align-items: center;
    gap: .75rem;
    border: 1px solid #e2e8f0;
    border-radius: .7rem;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    background: #fff;
}

.fav-avatar[b-hmca4utui0] {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: #eef2f7;
    color: #1861ac;
    font-weight: 800;
    font-size: .78rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fav-rbody[b-hmca4utui0] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.fav-rname[b-hmca4utui0] {
    font-weight: 700;
    color: #16324f;
    font-size: .92rem;
}

.fav-rmeta[b-hmca4utui0] {
    font-size: .74rem;
    color: #8496a8;
}

.fav-avail[b-hmca4utui0] {
    flex: 0 0 auto;
    font-size: .72rem;
    font-weight: 700;
    border-radius: 999px;
    padding: .2rem .6rem;
    white-space: nowrap;
}

.fav-avail-yes[b-hmca4utui0] {
    background: #e6f4ea;
    color: #2c7a45;
}

.fav-avail-no[b-hmca4utui0] {
    background: #fdecec;
    color: #b23b3b;
}

.fav-avail-wait[b-hmca4utui0] {
    background: #f1f5f9;
    color: #7a8b9c;
}
/* /Components/Pages/FixtureEdit.razor.rz.scp.css */
/* SPEC-34 S2 — publish / edit fixture form (c-publish mock screen). House tokens
   only: navy #0d2c55, blue #1b6ec2, off-white cards. No new brand. */

.fixedit-back-link[b-ljplbbrehe] {
    background: none;
    border: 0;
    color: #1b6ec2;
    font-weight: 700;
    cursor: pointer;
    font-size: .82rem;
    padding: 0;
    margin-bottom: .6rem;
}

.fixedit-prompt[b-ljplbbrehe] {
    color: #5e748a;
    font-size: .9rem;
    margin: .3rem 0 1.1rem;
    max-width: 44rem;
}

.fixedit-grid[b-ljplbbrehe] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .85rem;
}

@media (max-width: 520px) {
    .fixedit-grid[b-ljplbbrehe] {
        grid-template-columns: 1fr;
    }
}

.fixedit-field[b-ljplbbrehe] {
    margin-bottom: .85rem;
}

.fixedit-field label[b-ljplbbrehe] {
    display: block;
    font-size: .78rem;
    font-weight: 700;
    color: #42566d;
    margin-bottom: .3rem;
}

.fixedit-optional[b-ljplbbrehe] {
    color: #8496a8;
    font-weight: 600;
}

.fixedit-input[b-ljplbbrehe] {
    width: 100%;
    border: 1px solid #cbd5e1;
    border-radius: .55rem;
    padding: .6rem .7rem;
    font-size: .92rem;
    color: #16324f;
    background: #fff;
}

.fixedit-input:focus-visible[b-ljplbbrehe] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
}

.fixedit-seg[b-ljplbbrehe] {
    display: inline-flex;
    border: 1px solid #cbd5e1;
    border-radius: .55rem;
    overflow: hidden;
}

.fixedit-seg button[b-ljplbbrehe] {
    background: #fff;
    border: 0;
    padding: .55rem .95rem;
    font-size: .86rem;
    font-weight: 700;
    color: #42566d;
    cursor: pointer;
}

.fixedit-seg button.on[b-ljplbbrehe] {
    background: #1b6ec2;
    color: #fff;
}

.fixedit-stepper[b-ljplbbrehe] {
    display: inline-flex;
    align-items: center;
    border: 1px solid #cbd5e1;
    border-radius: .55rem;
    overflow: hidden;
}

.fixedit-stepper button[b-ljplbbrehe] {
    background: #f6f9fc;
    border: 0;
    width: 2.4rem;
    height: 2.6rem;
    font-size: 1.2rem;
    color: #1b6ec2;
    cursor: pointer;
    font-weight: 800;
}

.fixedit-stepper button:hover[b-ljplbbrehe] {
    background: #eef2f7;
}

.fixedit-stepper-val[b-ljplbbrehe] {
    width: 2.8rem;
    text-align: center;
    font-weight: 800;
    font-size: 1.05rem;
    color: #16324f;
}

.fixedit-hint[b-ljplbbrehe] {
    font-size: .76rem;
    color: #8496a8;
    margin-top: .3rem;
    line-height: 1.45;
}

.fixedit-error[b-ljplbbrehe] {
    color: #b23434;
    background: #fdecec;
    border: 1px solid #f4caca;
    border-radius: .55rem;
    padding: .6rem .75rem;
    font-size: .85rem;
    margin: .2rem 0 1rem;
}

.fixedit-actions[b-ljplbbrehe] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    margin-top: .6rem;
}
/* /Components/Pages/FixtureNotify.razor.rz.scp.css */
/* SPEC-34 S5 — captain notify view (c-notify). House tokens only; mirrors c-select. */
.fsel-hdr[b-ump2f1wwe9] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.fsel-sect[b-ump2f1wwe9] {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .72rem;
    font-weight: 800;
    color: #7a8b9c;
    margin: 1.3rem 0 .3rem;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
}

.fsel-sect-note[b-ump2f1wwe9] {
    text-transform: none;
    letter-spacing: 0;
    color: #8496a8;
    font-weight: 600;
}

.fsel-rrow[b-ump2f1wwe9] {
    display: flex;
    align-items: center;
    gap: .7rem;
    border: 1px solid #e2e8f0;
    border-radius: .7rem;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    background: #fff;
}

.fsel-rrow.picked[b-ump2f1wwe9] {
    border-color: #bcd8f7;
    background: #f7fbff;
}

.fsel-rrow.subbed[b-ump2f1wwe9] {
    border-color: #d8c9f0;
    background: #faf7ff;
}

.fsel-avatar[b-ump2f1wwe9] {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: #eef2f7;
    color: #1861ac;
    font-weight: 800;
    font-size: .78rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fsel-rbody[b-ump2f1wwe9] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.fsel-rname[b-ump2f1wwe9] {
    font-weight: 700;
    color: #16324f;
    font-size: .92rem;
}

.fsel-rmeta[b-ump2f1wwe9] {
    font-size: .74rem;
    color: #8496a8;
}

.fsel-actions[b-ump2f1wwe9] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    margin-top: 1.3rem;
}

/* ── notify-specific ── */
.fnotify-toggle-line[b-ump2f1wwe9] {
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: .9rem;
    color: #33506b;
    margin-top: .4rem;
}

.fnotify-toggle[b-ump2f1wwe9] {
    flex: 0 0 auto;
    width: 2.6rem;
    height: 1.5rem;
    border-radius: 1rem;
    background: #cbd5e1;
    border: 0;
    position: relative;
    cursor: pointer;
    padding: 0;
}

.fnotify-toggle.on[b-ump2f1wwe9] {
    background: #1861ac;
}

.fnotify-toggle:disabled[b-ump2f1wwe9] {
    opacity: .6;
    cursor: default;
}

.fnotify-knob[b-ump2f1wwe9] {
    position: absolute;
    top: .17rem;
    left: .2rem;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: #fff;
    transition: left .15s;
}

.fnotify-toggle.on .fnotify-knob[b-ump2f1wwe9] {
    left: 1.25rem;
}

.fnotify-toggle-help[b-ump2f1wwe9] {
    margin: .3rem 0 .6rem;
}

.fnotify-allornothing[b-ump2f1wwe9] {
    margin-top: .8rem;
}

.fnotify-exception[b-ump2f1wwe9] {
    border-color: #f2e0bd;
    background: #fff8ec;
    color: #7a5b1e;
}

/* #307 item 2 — withdrawn: a picked player who can no longer play. */
.fnotify-withdrawn-note[b-ump2f1wwe9] {
    border-color: #f3c6c6;
    background: #fdf2f2;
    color: #8c2f2f;
}

.fsel-rrow.withdrawn[b-ump2f1wwe9] {
    border-color: #f3c6c6;
    background: #fdf2f2;
}

.fnotify-withdrawn-chip[b-ump2f1wwe9] {
    display: inline-block;
    margin-left: .4rem;
    padding: 0 .4rem;
    border-radius: .5rem;
    background: #f8d7da;
    color: #8c2f2f;
    font-size: .64rem;
    font-weight: 800;
    letter-spacing: .03em;
    text-transform: uppercase;
    vertical-align: middle;
}

/* #307 item 1 — the mock's email-preview card (c-notify .email block). */
.fnotify-email[b-ump2f1wwe9] {
    border: 1px solid #dbe6f2;
    border-left: 3px solid #1861ac;
    border-radius: .7rem;
    background: #f7fbff;
    padding: .7rem .9rem;
}

.fnotify-email-hdr[b-ump2f1wwe9] {
    font-size: .74rem;
    color: #6b7f92;
    padding-bottom: .5rem;
    margin-bottom: .5rem;
    border-bottom: 1px dashed #dbe6f2;
}

.fnotify-email-hdr b[b-ump2f1wwe9] {
    color: #16324f;
}

.fnotify-email-sep[b-ump2f1wwe9] {
    margin: 0 .3rem;
}

.fnotify-email-body[b-ump2f1wwe9] {
    font-size: .82rem;
    line-height: 1.45;
    color: #33506b;
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.fnotify-email-note[b-ump2f1wwe9] {
    margin-top: .5rem;
}

/* #307 item 3 — the re-send confirm guard. */
.fnotify-lastsent[b-ump2f1wwe9] {
    margin-top: 1rem;
    margin-bottom: 0;
}

.fnotify-confirm[b-ump2f1wwe9] {
    margin-top: .6rem;
    border-color: #f2e0bd;
    background: #fff8ec;
}

.fnotify-confirm-actions[b-ump2f1wwe9] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
}

.fnotify-done[b-ump2f1wwe9] {
    text-align: center;
}

.fnotify-tick[b-ump2f1wwe9] {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: #e6f4ea;
    color: #2c8a4a;
    font-size: 1.6rem;
    line-height: 3rem;
    margin: 0 auto .5rem;
}

.fnotify-actions[b-ump2f1wwe9] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 1rem;
}
/* /Components/Pages/FixtureSelection.razor.rz.scp.css */
/* SPEC-34 S4 — captain selection view (c-select). House tokens only; mirrors c-avail. */
.fsel-hdr[b-pu377573xf] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.fsel-hdr-count[b-pu377573xf] {
    text-align: right;
}

.fsel-count[b-pu377573xf] {
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
}

.fsel-count span[b-pu377573xf] {
    color: #1861ac;
}

.fsel-balance[b-pu377573xf] {
    font-size: .75rem;
    color: #8496a8;
    margin-top: .15rem;
}

.fsel-shortfall[b-pu377573xf] {
    background: #fff8ec;
    border: 1px solid #f2e0bd;
    border-radius: .6rem;
    padding: .55rem .7rem;
    margin-bottom: 1rem;
}

.fsel-sect[b-pu377573xf] {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .72rem;
    font-weight: 800;
    color: #7a8b9c;
    margin: 1.3rem 0 .3rem;
}

.fsel-sub-help[b-pu377573xf] {
    margin-bottom: .6rem;
}

.fsel-rrow[b-pu377573xf] {
    display: flex;
    align-items: center;
    gap: .7rem;
    border: 1px solid #e2e8f0;
    border-radius: .7rem;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    background: #fff;
    cursor: pointer;
    user-select: none;
}

.fsel-rrow.picked[b-pu377573xf] {
    border-color: #bcd8f7;
    background: #f7fbff;
}

.fsel-rrow.subbed[b-pu377573xf] {
    border-color: #d8c9f0;
    background: #faf7ff;
}

/* A no-reply standby candidate — subtly dimmed until named as a sub. */
.fsel-rrow.standby:not(.subbed)[b-pu377573xf] {
    border-style: dashed;
    background: #fbfcfe;
}

.fsel-selbox[b-pu377573xf] {
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: .4rem;
    border: 2px solid #cbd5e1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: .85rem;
    color: #fff;
    background: #fff;
}

.fsel-selbox.on[b-pu377573xf] {
    background: #1861ac;
    border-color: #1861ac;
}

.fsel-selbox.sub[b-pu377573xf] {
    background: #7c3aed;
    border-color: #7c3aed;
    font-size: .72rem;
}

.fsel-avatar[b-pu377573xf] {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: #eef2f7;
    color: #1861ac;
    font-weight: 800;
    font-size: .78rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.fsel-rbody[b-pu377573xf] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.fsel-rname[b-pu377573xf] {
    font-weight: 700;
    color: #16324f;
    font-size: .92rem;
}

.fsel-rmeta[b-pu377573xf] {
    font-size: .74rem;
    color: #8496a8;
}

.fsel-actions[b-pu377573xf] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    margin-top: 1.3rem;
}

.fsel-notify-note[b-pu377573xf] {
    display: flex;
    align-items: center;
    gap: .7rem;
    flex-wrap: wrap;
    margin-top: .9rem;
    padding-top: .9rem;
    border-top: 1px dashed #e2e8f0;
}
/* /Components/Pages/FixtureShare.razor.rz.scp.css */
/* SPEC-34 S3 — share availability (c-share). House tokens only. */
.fixshare-warn[b-l8rogb9hxd] {
    border-color: #f3d3a6;
    background: #fff8ef;
    color: #8a5a12;
    margin-bottom: 1rem;
}

.fixshare-label[b-l8rogb9hxd] {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #5e748a;
    font-weight: 800;
    margin: 1rem 0 .45rem;
}

.fixshare-preview[b-l8rogb9hxd] {
    background: #f4f8fc;
    border: 1px solid #dbe6f1;
    border-radius: .7rem;
    padding: .85rem 1rem;
    color: #24405c;
    font-size: .92rem;
    white-space: pre-line;
    line-height: 1.5;
}

.fixshare-copybar[b-l8rogb9hxd] {
    display: flex;
    align-items: center;
    gap: .6rem;
    background: #eef2f7;
    border: 1px solid #d7dee7;
    border-radius: .6rem;
    padding: .55rem .7rem;
    margin: .8rem 0 1.2rem;
}

.fixshare-url[b-l8rogb9hxd] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: .82rem;
    color: #24405c;
}
/* /Components/Pages/FramedClubRecap.razor.rz.scp.css */
/* #778 (player-mode shell E): the in-app framed club recap. Scoped to this page only.
   No new brand — the off-white app surface + a light card frame (mockup 16) around the
   same-origin #756 ?embed=1 iframe. The iframe is sized to its content by the #756
   auto-sizer; the min-height here is the pre-size / no-JS fallback so the recap is
   always visible. */

/* #238: widened from 48rem to 64rem. The embedded member-tier recap grows to 64rem
   (.recap-shell-wide) on desktop to fit its ranking + All-games tables (~11 cols); at 48rem those
   columns were clipped. At 64rem the frame lets the recap render at its own designed wide width, so
   the tables are fully visible with no clipped columns. On a phone the frame is full-width (well
   below 64rem), the iframe is narrow, and the recap adopts its own <=720px card layout — no double
   scrollbar. Any residual on mid widths stays inside the recap's own .recap-games-table-wrap
   (overflow-x:auto), a single contained scroll, exactly as on the public recap. */
.framed-recap[b-imbmqlykn0] {
    max-width: 64rem;
    margin: 0 auto;
    padding: 1rem;
}

.framed-recap-frame[b-imbmqlykn0] {
    display: block;
    width: 100%;
    min-height: 70vh; /* fallback height before the same-origin auto-sizer measures content */
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.5rem;
    background: #ffffff;
    box-shadow: 0 1px 3px rgba(13, 44, 85, 0.08);
}

/* In-shell fallback for a night that couldn't be resolved (§6 Screen-4 error state). */
.framed-recap-fallback[b-imbmqlykn0] {
    text-align: center;
    margin: 0.75rem 0;
    color: #33475b;
}

.framed-recap-back[b-imbmqlykn0] {
    display: inline-flex;
    align-items: center;
    min-height: 44px; /* touch target */
    color: #0d6efd;
    font-weight: 600;
    text-decoration: none;
}

.framed-recap-back:hover[b-imbmqlykn0],
.framed-recap-back:focus-visible[b-imbmqlykn0] {
    text-decoration: underline;
}
/* /Components/Pages/JoinClub.razor.rz.scp.css */
/* FDD-0001 S2 (#687): the code-entry state. Same centred card column and visual tokens as
   /player-clubs and /create-club (one shared player language, NO new brand: navy #16324f,
   blue #1b6ec2 / #006bb7, off-white cards, error #9a2222).

   SCOPED PER COMPONENT, so every token used here is DEFINED here. That is the PegboardWeb
   per-page .razor.css pattern, and it is also the estate's recurring silent-failure class:
   Blazor CSS isolation means a rule that lives in a sibling page's .razor.css does not apply
   here even though the class name matches, while every DOM assertion still passes. If you add
   a class to the markup, add it below. */

.my-shell[b-i56tdejwec] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-i56tdejwec] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-i56tdejwec] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-i56tdejwec],
.my-back:focus-visible[b-i56tdejwec] {
    text-decoration: underline;
}

.my-back-caret[b-i56tdejwec] {
    font-weight: 700;
}

.my-backbar-title[b-i56tdejwec] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem;
}

/* ── Card. ── */
.my-card[b-i56tdejwec] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Heading + lead. ── */
.jc-title[b-i56tdejwec] {
    font-size: 1.15rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.5rem;
}

.jc-lead[b-i56tdejwec] {
    color: #5e748a;
    font-size: 0.92rem;
    margin: 0 0 1rem;
    line-height: 1.55;
}

/* ── The field. ── */
.jc-label[b-i56tdejwec] {
    display: block;
    font-weight: 700;
    color: #16324f;
    font-size: 0.9rem;
    margin: 0 0 0.4rem;
}

/* 48px minimum height and the wide letter-spacing the S1 card's code chip uses, so the
   officer's display and the player's input read as the same object. */
.jc-input[b-i56tdejwec] {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: 0.5rem 0.75rem;
    border: 1px solid #cbd6e2;
    border-radius: 0.55rem;
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #16324f;
    background: #fff;
    box-sizing: border-box;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

.jc-input[b-i56tdejwec]::placeholder {
    color: #9fb0c2;
    font-weight: 600;
}

.jc-input:focus-visible[b-i56tdejwec] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
    border-color: #1b6ec2;
}

.jc-input.is-error[b-i56tdejwec] {
    border-color: #d9534f;
}

.jc-hint[b-i56tdejwec] {
    margin: 0.5rem 0 0;
    color: #5e748a;
    font-size: 0.85rem;
}

/* The client-side shape check's message. Hidden until the script fills it; [hidden] must win
   over the block display, or a blocked script would leave an empty red bar on the page. */
.jc-clienterror[b-i56tdejwec] {
    margin: 0.6rem 0 0;
    color: #9a2222;
    font-size: 0.85rem;
    font-weight: 600;
}

.jc-clienterror[hidden][b-i56tdejwec] {
    display: none;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-i56tdejwec] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-i56tdejwec] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-i56tdejwec],
.my-btn-primary:focus-visible[b-i56tdejwec] {
    background: #155ba3;
}

.my-btn-block[b-i56tdejwec] {
    display: flex;
    width: 100%;
}

.jc-submit[b-i56tdejwec] {
    min-height: 48px;
    font-size: 1rem;
    margin-top: 1rem;
}

.jc-submit[disabled][b-i56tdejwec] {
    background: #7ea9d3;
    cursor: default;
}

/* ── The failure banners (the /player-clubs error-banner token). ── */
.clubs-banner[b-i56tdejwec] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-i56tdejwec] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* ── The no-code footer line (the /player-clubs demo-nudge token). ── */
.jc-nocode[b-i56tdejwec] {
    text-align: center;
    color: #5e748a;
    font-size: 0.88rem;
    margin: 0.2rem 0 0;
}
/* /Components/Pages/JoinClubConfirm.razor.rz.scp.css */
/* FDD-0001 S2 (#687): "Is this your club?" — the confirm gate between the code and the roster.
   Same centred card column and visual tokens as /player-clubs, /create-club and /join-club.

   SCOPED PER COMPONENT, so every token used here is DEFINED here — the PegboardWeb per-page
   .razor.css pattern, and the reason a class that "already exists" on a sibling page still has
   to be repeated: Blazor CSS isolation means a sibling's rule does not apply here even though
   the class name matches, while every DOM assertion still passes. */

.my-shell[b-sdsi81ifzt] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-sdsi81ifzt] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-sdsi81ifzt] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-sdsi81ifzt],
.my-back:focus-visible[b-sdsi81ifzt] {
    text-decoration: underline;
}

.my-back-caret[b-sdsi81ifzt] {
    font-weight: 700;
}

.my-backbar-title[b-sdsi81ifzt] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem;
}

/* ── Card. ── */
.my-card[b-sdsi81ifzt] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-sdsi81ifzt] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-sdsi81ifzt] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-sdsi81ifzt],
.my-btn-primary:focus-visible[b-sdsi81ifzt] {
    background: #155ba3;
}

.my-btn-secondary[b-sdsi81ifzt] {
    background: #fff;
    color: #16324f;
    border-color: #cbd6e2;
}

.my-btn-secondary:hover[b-sdsi81ifzt],
.my-btn-secondary:focus-visible[b-sdsi81ifzt] {
    background: #f4f8fb;
}

.my-btn-block[b-sdsi81ifzt] {
    display: flex;
    width: 100%;
}

/* ── Banners (the /player-clubs error-banner token). ── */
.clubs-banner[b-sdsi81ifzt] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-sdsi81ifzt] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* ── Screen 14: the confirm card. Centred, because the club name IS the content. ── */
.jcc-card[b-sdsi81ifzt] {
    text-align: center;
    padding: 1.4rem 1.15rem 1.2rem;
}

.jcc-typed[b-sdsi81ifzt] {
    color: #5e748a;
    font-size: 0.88rem;
    margin: 0 0 0.5rem;
}

/* ── The club's initial-letter badge (S2 signoff UX-2). ──────────────────────────────────────

   THIS SCREEN'S WHOLE JOB IS "is this your club?", and it was answering it with text alone while
   /player-clubs gives every club row the navy initial circle and the single-club hero enlarges
   it. The mockup's screens 14–17 all carry it. Same tokens as .clubs-badge / .club-hero-badge
   there, REPEATED rather than referenced: CSS isolation means a sibling page's rule does not
   apply here even though the class name would match, and a rule that silently does not apply is
   this estate's recurring defect class.

   Centred and hero-sized on all four outcomes, because all four name a club. */
.jcc-badge[b-sdsi81ifzt] {
    display: flex;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 50%;
    background: #0d2c55;
    color: #fff;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 1.5rem;
    margin: 0 auto 0.7rem;
}

.jcc-club[b-sdsi81ifzt] {
    font-size: 1.3rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.25rem;
}

.jcc-locality[b-sdsi81ifzt] {
    color: #5e748a;
    font-size: 0.95rem;
    margin: 0 0 1.1rem;
}

.jcc-yes[b-sdsi81ifzt] {
    min-height: 48px;
    font-size: 1rem;
}

.jcc-no[b-sdsi81ifzt] {
    display: inline-block;
    margin-top: 0.9rem;
    min-height: 44px;
    line-height: 44px;
    color: #006bb7;
    font-weight: 600;
    font-size: 0.92rem;
    text-decoration: none;
}

.jcc-no:hover[b-sdsi81ifzt],
.jcc-no:focus-visible[b-sdsi81ifzt] {
    text-decoration: underline;
}

/* ── Screens 15-17 + the expired state: a heading, a paragraph, one action. ── */
.jcc-title[b-sdsi81ifzt] {
    font-size: 1.25rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.5rem;
}

/* Left, inside a centred card: these are the multi-sentence outcome paragraphs (screens 15, 16,
   17), and the mockup left-aligns them for the same reason — a centred badge and heading is
   club identity, a centred three-line paragraph is just harder to read. */
.jcc-body[b-sdsi81ifzt] {
    text-align: left;
    color: #5e748a;
    font-size: 0.95rem;
    line-height: 1.6;
    margin: 0 0 1.1rem;
}
/* /Components/Pages/JoinClubDone.razor.rz.scp.css */
/* FDD-0001 S2 (#687): Connected, and the pick the club must confirm (screens 26 and 26b). Same centred card column and visual tokens as the rest of
   the join-club family.

   SCOPED PER COMPONENT, so every token used here is DEFINED here — Blazor CSS isolation means
   a sibling page's rule does not apply here even though the class name matches, while every
   DOM assertion still passes. */

.my-shell[b-ou8xfvmrut] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-ou8xfvmrut] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-ou8xfvmrut] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-ou8xfvmrut],
.my-back:focus-visible[b-ou8xfvmrut] {
    text-decoration: underline;
}

.my-back-caret[b-ou8xfvmrut] {
    font-weight: 700;
}

.my-backbar-title[b-ou8xfvmrut] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem;
}

/* ── Card. ── */
.my-card[b-ou8xfvmrut] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-ou8xfvmrut] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-ou8xfvmrut] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-ou8xfvmrut],
.my-btn-primary:focus-visible[b-ou8xfvmrut] {
    background: #155ba3;
}

.my-btn-secondary[b-ou8xfvmrut] {
    background: #fff;
    color: #16324f;
    border-color: #cbd6e2;
}

.my-btn-secondary:hover[b-ou8xfvmrut],
.my-btn-secondary:focus-visible[b-ou8xfvmrut] {
    background: #f4f8fb;
}

.my-btn-block[b-ou8xfvmrut] {
    display: flex;
    width: 100%;
}

/* ── Banners (the /player-clubs error-banner token). ── */
.clubs-banner[b-ou8xfvmrut] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-ou8xfvmrut] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* ── The terminal card. Centred: the outcome IS the content. ── */
.jcd-card[b-ou8xfvmrut] {
    text-align: center;
    padding: 1.5rem 1.15rem 1.25rem;
}

.jcd-tick[b-ou8xfvmrut] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: #eaf5ec;
    color: #226b39;
    font-size: 1.5rem;
    font-weight: 800;
    margin: 0 auto 0.7rem;
}

.jcd-title[b-ou8xfvmrut] {
    font-size: 1.25rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.4rem;
}

.jcd-body[b-ou8xfvmrut] {
    color: #5e748a;
    font-size: 0.95rem;
    line-height: 1.6;
    margin: 0 0 1.2rem;
}

.jcd-secondary[b-ou8xfvmrut] {
    display: inline-block;
    margin-top: 0.9rem;
    min-height: 44px;
    line-height: 44px;
    color: #006bb7;
    font-weight: 600;
    font-size: 0.92rem;
    text-decoration: none;
}

.jcd-secondary:hover[b-ou8xfvmrut],
.jcd-secondary:focus-visible[b-ou8xfvmrut] {
    text-decoration: underline;
}
/* /Components/Pages/JoinClubPick.razor.rz.scp.css */
/* FDD-0001 S2 (#687): the roster pick — the disclosure this change exists to gate. Same centred
   card column and visual tokens as the rest of the join-club family.

   SCOPED PER COMPONENT, so every token used here is DEFINED here — Blazor CSS isolation means a
   sibling page's rule does not apply here even though the class name matches, while every DOM
   assertion still passes. */

.my-shell[b-5adi2trgdt] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-5adi2trgdt] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-5adi2trgdt] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-5adi2trgdt],
.my-back:focus-visible[b-5adi2trgdt] {
    text-decoration: underline;
}

.my-back-caret[b-5adi2trgdt] {
    font-weight: 700;
}

.my-backbar-title[b-5adi2trgdt] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem;
}

/* ── Card. ── */
.my-card[b-5adi2trgdt] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-5adi2trgdt] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-5adi2trgdt] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-5adi2trgdt],
.my-btn-primary:focus-visible[b-5adi2trgdt] {
    background: #155ba3;
}

.my-btn-secondary[b-5adi2trgdt] {
    background: #fff;
    color: #16324f;
    border-color: #cbd6e2;
}

.my-btn-secondary:hover[b-5adi2trgdt],
.my-btn-secondary:focus-visible[b-5adi2trgdt] {
    background: #f4f8fb;
}

.my-btn-block[b-5adi2trgdt] {
    display: flex;
    width: 100%;
}

/* ── Banners (the /player-clubs error-banner token). ── */
.clubs-banner[b-5adi2trgdt] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-5adi2trgdt] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

.jcp-title[b-5adi2trgdt] {
    font-size: 1.15rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.3rem;
}

.jcp-lead[b-5adi2trgdt] {
    color: #5e748a;
    font-size: 0.92rem;
    line-height: 1.55;
    margin: 0 0 1rem;
}

.jcp-body[b-5adi2trgdt] {
    color: #5e748a;
    font-size: 0.95rem;
    line-height: 1.6;
    margin: 0 0 1.1rem;
}

/* ── The client-side filter. ── */
.jcp-search-label[b-5adi2trgdt] {
    display: block;
    font-weight: 700;
    color: #16324f;
    font-size: 0.9rem;
    margin: 0 0 0.4rem;
}

.jcp-search[b-5adi2trgdt] {
    display: block;
    width: 100%;
    min-height: 44px;
    padding: 0.5rem 0.75rem;
    border: 1px solid #cbd6e2;
    border-radius: 0.55rem;
    font-size: 0.95rem;
    color: #1f2d3d;
    background: #fff;
    box-sizing: border-box;
}

.jcp-search:focus-visible[b-5adi2trgdt] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
    border-color: #1b6ec2;
}

.jcp-fieldset[b-5adi2trgdt] {
    border: 0;
    padding: 0;
    margin: 0.8rem 0 0;
}

.jcp-legend[b-5adi2trgdt] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ── The roster. Alphabetical, never unclaimed-first, names and nothing else. ── */
.jcp-name-list[b-5adi2trgdt] {
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    overflow: hidden;
    max-height: 22rem;
    overflow-y: auto;
}

/* Rows the filter hides. [hidden] must beat the flex display, or a filtered row stays on
   screen and the "no names match" line renders under a list that never shrank. */
.jcp-name[hidden][b-5adi2trgdt] {
    display: none !important;
}

.jcp-name[b-5adi2trgdt] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    min-height: 48px;
    padding: 0.55rem 0.85rem;
    border-bottom: 1px solid #edf2f7;
    cursor: pointer;
    background: #fff;
}

.jcp-name:last-child[b-5adi2trgdt] {
    border-bottom: 0;
}

.jcp-name:hover[b-5adi2trgdt] {
    background: #f4f8fb;
}

.jcp-name-radio[b-5adi2trgdt] {
    width: 1.15rem;
    height: 1.15rem;
    flex: 0 0 auto;
    accent-color: #1b6ec2;
}

.jcp-name-text[b-5adi2trgdt] {
    font-weight: 600;
    color: #16324f;
    font-size: 0.98rem;
}

/* Already connected: SHOWN, greyed, non-selectable — it kills the "where's my name?" dead end,
   and its audience is now code-holders rather than anyone holding a forwarded link. */
.jcp-name-claimed[b-5adi2trgdt] {
    cursor: default;
    background: #f7fafc;
}

.jcp-name-claimed:hover[b-5adi2trgdt] {
    background: #f7fafc;
}

.jcp-name-claimed .jcp-name-text[b-5adi2trgdt] {
    color: #7d8fa3;
    font-weight: 500;
}

.jcp-connected-chip[b-5adi2trgdt] {
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #5e748a;
    background: #e8eef4;
    border-radius: 999px;
    padding: 0.15rem 0.5rem;
}

/* BR-24: two or more UNCLAIMED rows sharing a name become ONE non-selectable entry, with the
   reason attached rather than a bare greyed row — there is no wrong row to pick because there
   is no row to pick, and the person needs to know why. */
.jcp-name-collapsed[b-5adi2trgdt] {
    display: block;
    cursor: default;
    background: #fffaf0;
}

.jcp-name-collapsed:hover[b-5adi2trgdt] {
    background: #fffaf0;
}

.jcp-name-collapsed .jcp-name-text[b-5adi2trgdt] {
    display: block;
    color: #7d5a1f;
}

.jcp-collapsed-note[b-5adi2trgdt] {
    display: block;
    margin-top: 0.25rem;
    color: #7d5a1f;
    font-size: 0.85rem;
    line-height: 1.5;
}

.jcp-no-match[b-5adi2trgdt] {
    margin: 0.7rem 0 0;
    color: #5e748a;
    font-size: 0.88rem;
    line-height: 1.5;
}

.jcp-no-match[hidden][b-5adi2trgdt] {
    display: none;
}

/* ── The empty states (screens 21 and 22). ── */
.my-empty[b-5adi2trgdt] {
    background: #f7fafc;
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    padding: 1rem 0.95rem;
    margin: 0 0 1rem;
    display: block;
}

.jcp-empty-title[b-5adi2trgdt] {
    display: block;
    font-weight: 700;
    color: #16324f;
    font-size: 0.98rem;
    margin-bottom: 0.3rem;
}

.jcp-empty-desc[b-5adi2trgdt] {
    display: block;
    color: #5e748a;
    font-size: 0.9rem;
    line-height: 1.55;
}

/* ── "I'm not on this list" — a first-class branch, never a hatch. ── */
.jcp-not-listed[b-5adi2trgdt] {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: 0;
    padding: 0.7rem 0 0;
    margin-top: 0.7rem;
    color: #006bb7;
    font-weight: 700;
    font-size: 0.95rem;
    min-height: 44px;
    cursor: pointer;
    border-top: 1px solid #edf2f7;
}

.jcp-not-listed:hover[b-5adi2trgdt],
.jcp-not-listed:focus-visible[b-5adi2trgdt] {
    text-decoration: underline;
}

.jcp-not-listed-primary[b-5adi2trgdt] {
    min-height: 48px;
    font-size: 1rem;
    margin-top: 0.4rem;
}

.jcp-not-listed-desc[b-5adi2trgdt] {
    margin: 0.2rem 0 0;
    color: #5e748a;
    font-size: 0.85rem;
}

/* ── The identity line. NOT a footnote: the last screen before a bind. ── */
.jcp-identity[b-5adi2trgdt] {
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: 1px solid #edf2f7;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.88rem;
    color: #5e748a;
}

.jcp-identity-text[b-5adi2trgdt] {
    overflow-wrap: anywhere;
}

.jcp-signout[b-5adi2trgdt] {
    background: none;
    border: 0;
    padding: 0;
    min-height: 44px;
    color: #006bb7;
    font-weight: 600;
    font-size: 0.88rem;
    cursor: pointer;
}

.jcp-signout:hover[b-5adi2trgdt],
.jcp-signout:focus-visible[b-5adi2trgdt] {
    text-decoration: underline;
}

.jcp-signout-form[b-5adi2trgdt] {
    margin: 0;
}

.jcp-submit[b-5adi2trgdt] {
    min-height: 48px;
    font-size: 1rem;
    margin-top: 1rem;
}
/* /Components/Pages/JoinClubSent.razor.rz.scp.css */
/* FDD-0001 S2 (#687): Request sent — the honest terminal state (screens 25 and 25b). Same centred card column and visual tokens as the rest of
   the join-club family.

   SCOPED PER COMPONENT, so every token used here is DEFINED here — Blazor CSS isolation means
   a sibling page's rule does not apply here even though the class name matches, while every
   DOM assertion still passes. */

.my-shell[b-kisa5vgvkq] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title). ── */
.my-backbar[b-kisa5vgvkq] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-kisa5vgvkq] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-kisa5vgvkq],
.my-back:focus-visible[b-kisa5vgvkq] {
    text-decoration: underline;
}

.my-back-caret[b-kisa5vgvkq] {
    font-weight: 700;
}

.my-backbar-title[b-kisa5vgvkq] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 5rem;
}

/* ── Card. ── */
.my-card[b-kisa5vgvkq] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1rem;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-kisa5vgvkq] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-kisa5vgvkq] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-kisa5vgvkq],
.my-btn-primary:focus-visible[b-kisa5vgvkq] {
    background: #155ba3;
}

.my-btn-secondary[b-kisa5vgvkq] {
    background: #fff;
    color: #16324f;
    border-color: #cbd6e2;
}

.my-btn-secondary:hover[b-kisa5vgvkq],
.my-btn-secondary:focus-visible[b-kisa5vgvkq] {
    background: #f4f8fb;
}

.my-btn-block[b-kisa5vgvkq] {
    display: flex;
    width: 100%;
}

/* ── Banners (the /player-clubs error-banner token). ── */
.clubs-banner[b-kisa5vgvkq] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    line-height: 1.5;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-kisa5vgvkq] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
}

/* ── The terminal card. Centred: the outcome IS the content. ── */
.jcs-card[b-kisa5vgvkq] {
    text-align: center;
    padding: 1.5rem 1.15rem 1.25rem;
}

.jcs-tick[b-kisa5vgvkq] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    background: #eaf5ec;
    color: #226b39;
    font-size: 1.5rem;
    font-weight: 800;
    margin: 0 auto 0.7rem;
}

.jcs-title[b-kisa5vgvkq] {
    font-size: 1.25rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.4rem;
}

.jcs-body[b-kisa5vgvkq] {
    color: #5e748a;
    font-size: 0.95rem;
    line-height: 1.6;
    margin: 0 0 1.2rem;
}

.jcs-secondary[b-kisa5vgvkq] {
    display: inline-block;
    margin-top: 0.9rem;
    min-height: 44px;
    line-height: 44px;
    color: #006bb7;
    font-weight: 600;
    font-size: 0.92rem;
    text-decoration: none;
}

.jcs-secondary:hover[b-kisa5vgvkq],
.jcs-secondary:focus-visible[b-kisa5vgvkq] {
    text-decoration: underline;
}
/* /Components/Pages/JoinCode.razor.rz.scp.css */
/* S7c-2: /join code field — large, centred, tracked, uppercase (the credential vocabulary, matching the
   green claim-code look elsewhere). Scoped to this page. */

.join-code-input[b-ciphdfarnx] {
    text-align: center;
    text-transform: uppercase;
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: 0.22em;
    font-variant-numeric: tabular-nums;
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.join-code-input[b-ciphdfarnx]::placeholder {
    letter-spacing: 0.18em;
    color: #9db3c7;
    font-weight: 600;
}

.join-code-hint[b-ciphdfarnx] {
    margin-top: 0.4rem;
    color: #557693;
}

/* ado:1437: the standing join route. SECONDARY and below a rule - the page has one primary action
   and this is not it. It is here for the player who read a code off a board and arrived at the
   wrong door, which after this slice is a real and predictable mistake rather than a hypothetical
   one. */
.join-code-standing-route[b-ciphdfarnx] {
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px solid #dbe5ef;
    color: #557693;
}
/* /Components/Pages/LiveSession.razor.rz.scp.css */
/* S7c-2: the anonymous /live/{code} phone shell — a single centred column, the live-pulse header, the
   3-tab bar, skeleton, wrap + bind-hook. Scoped; also supplies the ::deep .clubSession-panel chrome the
   reused tabs (AttendeeStatsTab / CompletedGamesTab) expect (mirroring ClubSessionDashboard's role). */

.ls-shell[b-anoofqpj69] {
    max-width: 34rem;
    margin: 0 auto;
    /* S7d Inc1 rework (BLOCKER 1): fill the viewport so the onward CTA bar can be pushed to the true
       screen bottom (margin-top:auto on the bar) even when the board is short — not left floating with a
       blank gap beneath it. padding-bottom is 0 so the full-width bar sits flush; when the board is tall
       the shell grows past the viewport and the bar's position:sticky keeps it pinned while scrolling. */
    min-height: 100dvh;
    padding: 0.6rem 0.75rem 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    color: #12263a;
}

/* Header — live pulse + session name + count. */
.ls-header[b-anoofqpj69] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.15rem;
    border-bottom: 1px solid #d6e0ea;
}

.ls-badge[b-anoofqpj69] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: 0 0 auto;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.ls-badge-live[b-anoofqpj69] {
    background: #e8f7ec;
    border: 1px solid #a7dcb4;
    color: #14663a;
}

.ls-badge-ended[b-anoofqpj69] {
    background: #eef1f5;
    border: 1px solid #c9d4df;
    color: #55636f;
}

.ls-blip[b-anoofqpj69] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 999px;
    background: #1f9d55;
    box-shadow: 0 0 0 0 rgba(31, 157, 85, 0.6);
    animation: ls-pulse-b-anoofqpj69 1.8s ease-out infinite;
}

@keyframes ls-pulse-b-anoofqpj69 {
    0% { box-shadow: 0 0 0 0 rgba(31, 157, 85, 0.55); }
    70% { box-shadow: 0 0 0 0.5rem rgba(31, 157, 85, 0); }
    100% { box-shadow: 0 0 0 0 rgba(31, 157, 85, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .ls-blip[b-anoofqpj69] { animation: none; }
}

.ls-header-body[b-anoofqpj69] {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* MAJOR 3: the session name leads and must not clip to "Spring…". Allow up to two lines (typical session
   names fit on one) before clamping, instead of the old single-line ellipsis. */
.ls-title[b-anoofqpj69] {
    font-size: 1.02rem;
    font-weight: 700;
    color: #0d2c55;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    line-height: 1.25;
}

.ls-sub[b-anoofqpj69] {
    font-size: 0.8rem;
    color: #557693;
}

/* Session-ended wrap banner. */
.ls-wrap[b-anoofqpj69] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0.7rem;
    border-radius: 0.65rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #14532d;
    font-size: 0.9rem;
}

.ls-wrap-emoji[b-anoofqpj69] { font-size: 1.15rem; flex: 0 0 auto; }

/* Tab bar — 44px touch targets. */
.ls-tabs[b-anoofqpj69] {
    display: flex;
    gap: 0.25rem;
    background: #eef3f8;
    border: 1px solid #d6e0ea;
    border-radius: 0.7rem;
    padding: 0.2rem;
}

.ls-tab[b-anoofqpj69] {
    flex: 1 1 0;
    min-height: 2.75rem;
    border: none;
    background: transparent;
    border-radius: 0.55rem;
    font-size: 0.9rem;
    font-weight: 700;
    color: #557693;
    cursor: pointer;
}

.ls-tab.active[b-anoofqpj69] {
    background: #fff;
    color: #0d2c55;
    box-shadow: 0 1px 3px rgba(13, 44, 85, 0.12);
}

.ls-tabpanel[b-anoofqpj69] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* Board-tab signpost to the hero + the persistent bind hook. */
.ls-signpost[b-anoofqpj69] {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    /* Polish: hold the 44px touch target the rest of the screen keeps. */
    min-height: 44px;
    border: none;
    background: transparent;
    color: #1d4ed8;
    font-weight: 700;
    font-size: 0.9rem;
    padding: 0.3rem 0;
    cursor: pointer;
}

.ls-bind-hook[b-anoofqpj69] {
    display: block;
    padding: 0.7rem 0.85rem;
    border-radius: 0.65rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #14532d;
    font-weight: 700;
    font-size: 0.9rem;
    text-decoration: none;
}

.ls-bind-hook:hover[b-anoofqpj69] { background: #e3fbe9; }

/* MAJOR 2 / S7d Inc1 rework (POLISH 4): the drill-in variant sits inside the tonight-only detail panel
   (authored in this page, so it carries this component's scope and picks up .ls-bind-hook). It must read as
   a TAPPABLE ACTION, not the soft-green success/status banner the base .ls-bind-hook is — so override to the
   blue action-link family (matching the bar's "New here? Sign up" + the signpost), underlined, with the
   existing chevron, keeping a 44px touch target. */
.ls-bind-hook-drillin[b-anoofqpj69] {
    margin-top: 0.55rem;
    font-size: 0.85rem;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.3rem 0;
    background: transparent;
    border: none;
    color: #1d4ed8;
    font-weight: 700;
    text-decoration: underline;
}

.ls-bind-hook-drillin:hover[b-anoofqpj69] {
    background: transparent;
    text-decoration: none;
}

/* S7d Inc1: neutral placeholder reserving the sticky CTA bar's footprint while auth/bind detection runs
   on the interactive pass (avoids a flash-then-swap of the anon CTA and a layout jump when it resolves).
   margin-top:auto docks it to the viewport bottom exactly like the resolved bar, so nothing shifts. */
.ls-cta-loading[b-anoofqpj69] {
    margin-top: auto;
    min-height: 3.4rem;
}

/* S7d Inc3 (UX finding 2): the claims-off guest line that stands in for the suppressed claim CTA. Pushed
   to the bottom like the CTA bar (margin-top:auto) so the board doesn't collapse into a gap; muted +
   centred so it reads as a quiet acknowledgement, not an action. */
.ls-cta-guest[b-anoofqpj69] {
    margin-top: auto;
    padding: 0.9rem 0.5rem 1rem;
    text-align: center;
    color: #557693;
    font-size: 0.9rem;
}

/* No-such-code notice. */
.ls-card[b-anoofqpj69] {
    background: #fff;
    border: 1px solid #d6e0ea;
    border-radius: 0.85rem;
    padding: 1.2rem;
}

.ls-notice[b-anoofqpj69] { text-align: center; }

.ls-notice-title[b-anoofqpj69] {
    font-size: 1.05rem;
    font-weight: 700;
    color: #0d2c55;
    margin-bottom: 0.35rem;
}

.ls-muted[b-anoofqpj69] { color: #557693; font-size: 0.9rem; margin-bottom: 1rem; }

.ls-btn[b-anoofqpj69] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 1.1rem;
    border-radius: 0.6rem;
    font-weight: 700;
    text-decoration: none;
    border: 1px solid transparent;
}

.ls-btn-primary[b-anoofqpj69] { background: #0d2c55; color: #fff; }

/* Loading skeleton (shimmer). */
.ls-skeleton[b-anoofqpj69] { display: flex; flex-direction: column; gap: 0.6rem; padding: 0.6rem 0; }

.ls-skel-header[b-anoofqpj69], .ls-skel-tabs[b-anoofqpj69], .ls-skel-card[b-anoofqpj69] {
    border-radius: 0.7rem;
    background: linear-gradient(90deg, #eef3f8 25%, #e2ebf3 37%, #eef3f8 63%);
    background-size: 400% 100%;
    animation: ls-shimmer-b-anoofqpj69 1.4s ease infinite;
}

.ls-skel-header[b-anoofqpj69] { height: 3rem; }
.ls-skel-tabs[b-anoofqpj69] { height: 2.75rem; }
.ls-skel-card[b-anoofqpj69] { height: 8rem; }

@keyframes ls-shimmer-b-anoofqpj69 {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
    .ls-skel-header[b-anoofqpj69], .ls-skel-tabs[b-anoofqpj69], .ls-skel-card[b-anoofqpj69] { animation: none; }
}

/* Chrome for the reused tabs' outer panel (mirrors ClubSessionDashboard's ::deep .clubSession-panel so the
   Players/Games tabs read as cards on the anon surface too). */
[b-anoofqpj69] .clubSession-panel {
    background: #edf3fa;
    border: 1px solid #b9c9da;
    border-radius: 0.75rem;
    padding: 0.6rem;
    min-width: 0;
}

[b-anoofqpj69] .clubSession-panel h2 {
    margin: 0 0 0.45rem;
    color: #355775;
    font-size: 0.98rem;
    font-weight: 700;
}

/* The severed name (AllowMemberProfile=false) — plain text styled to match the former link's weight. */
[b-anoofqpj69] .attendee-name-plain {
    font-weight: 600;
}
/* /Components/Pages/MatchQualityReport.razor.rz.scp.css */
/* #521 Match-quality report. Mirrors AttendanceOverTimeReport.razor.css + the approved mockup. */
.reports-shell[b-u8tzgvmevw] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-u8tzgvmevw] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-u8tzgvmevw] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-u8tzgvmevw],
.reports-crumb-link:focus-visible[b-u8tzgvmevw] {
    text-decoration: underline;
    outline: none;
}

.mq-head[b-u8tzgvmevw] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.mq-head h1[b-u8tzgvmevw] {
    margin: 0;
    color: #1f3f5e;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.mq-badge[b-u8tzgvmevw] {
    display: inline-block;
    background: #e6f5ec;
    color: #1f7a4d;
    border: 1px solid #bfe3cd;
    border-radius: 0.4rem;
    padding: 0.12rem 0.55rem;
    font-size: 0.72rem;
    font-weight: 700;
}

.mq-sub[b-u8tzgvmevw] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.mq-head-actions[b-u8tzgvmevw] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.mq-ranges[b-u8tzgvmevw] {
    display: flex;
    gap: 0.35rem;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.mq-settled-toggle[b-u8tzgvmevw] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: #3d5a78;
    cursor: pointer;
    white-space: nowrap;
}

.mq-settled-toggle input[b-u8tzgvmevw] {
    cursor: pointer;
}

.mq-ranges button[b-u8tzgvmevw] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.mq-ranges button.on[b-u8tzgvmevw] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.mq-ranges button:disabled[b-u8tzgvmevw] {
    cursor: default;
    opacity: 0.55;
}

/* tiles */
.mq-tiles[b-u8tzgvmevw] {
    display: grid;
    grid-template-columns: 1.3fr 1fr 1fr 1fr;
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.mq-tile[b-u8tzgvmevw] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.mq-tile .lab[b-u8tzgvmevw] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.mq-tile .val[b-u8tzgvmevw] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
}

.mq-tile .sub[b-u8tzgvmevw] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* hero tile (competitive %) — green gradient per the mockup */
.mq-tile.hero[b-u8tzgvmevw] {
    background: linear-gradient(135deg, #1f7a4d, #2f8f5e);
    border-color: #1f7a4d;
}

.mq-tile.hero .lab[b-u8tzgvmevw] {
    color: #bfe6cf;
}

.mq-tile.hero .val[b-u8tzgvmevw] {
    color: #ffffff;
    font-size: 2.5rem;
}

.mq-tile.hero .sub[b-u8tzgvmevw] {
    color: #d7f0e1;
}

/* two-card grid: histogram (wider) + donut */
.mq-grid[b-u8tzgvmevw] {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 1.15rem;
    margin-bottom: 1.15rem;
}

.mq-card[b-u8tzgvmevw] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.2rem 1.2rem;
}

.mq-card-head[b-u8tzgvmevw] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.mq-card-head h3[b-u8tzgvmevw] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.mq-card-head .d[b-u8tzgvmevw] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

.mq-card-body[b-u8tzgvmevw] {
    padding-top: 0.25rem;
}

.mq-chart[b-u8tzgvmevw] {
    position: relative;
    height: 230px;
}

.mq-chart-caption[b-u8tzgvmevw] {
    font-size: 0.72rem;
    color: #9aa6b6;
    text-align: center;
    margin-top: 0.5rem;
}

.mq-chart-foot[b-u8tzgvmevw] {
    font-size: 0.72rem;
    color: #9aa6b6;
    text-align: center;
    margin: 0.35rem 0 0;
}

/* donut */
.mq-donut[b-u8tzgvmevw] {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    flex-wrap: wrap;
}

.mq-ring-wrap[b-u8tzgvmevw] {
    position: relative;
    width: 150px;
    height: 150px;
    max-width: 100%;
    flex: 0 0 auto;
}

.mq-ring-centre[b-u8tzgvmevw] {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    text-align: center;
    pointer-events: none;
}

.mq-ring-centre b[b-u8tzgvmevw] {
    font-size: 1.5rem;
    font-weight: 800;
    color: #1f3f5e;
    display: block;
}

.mq-ring-centre span[b-u8tzgvmevw] {
    display: block;
    font-size: 0.62rem;
    color: #6c7a8c;
    line-height: 1.2;
    margin-top: 0.1rem;
}

.mq-legend[b-u8tzgvmevw] {
    font-size: 0.8rem;
    color: #42526a;
    flex: 1 1 180px;
    min-width: 170px;
}

.mq-legend > div[b-u8tzgvmevw] {
    margin: 0.3rem 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.mq-legend i[b-u8tzgvmevw] {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    display: inline-block;
    flex: 0 0 auto;
}

.mq-legend i.dot-green[b-u8tzgvmevw] {
    background: #1f7a4d;
}

.mq-legend i.dot-track[b-u8tzgvmevw] {
    background: #eef2f7;
    border: 1px solid #d6deea;
}

.mq-legend-secondary[b-u8tzgvmevw] {
    color: #52617a;
    font-size: 0.76rem;
    margin-top: 0.4rem;
}

.mq-legend-note[b-u8tzgvmevw] {
    color: #6c7a8c;
    font-size: 0.74rem;
    margin: 0.5rem 0 0;
    line-height: 1.4;
}

/* headline message strip */
.mq-msg[b-u8tzgvmevw] {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    background: linear-gradient(90deg, #eef6ff, #f6fbff);
    border: 1px solid #cfe1f4;
    border-radius: 0.75rem;
    padding: 0.9rem 1.1rem;
    color: #274a6b;
    font-size: 0.85rem;
    line-height: 1.45;
    margin-bottom: 1rem;
}

.mq-msg .q[b-u8tzgvmevw] {
    font-size: 0.95rem;
    font-weight: 700;
    color: #1f3f5e;
}

.mq-msg-ic[b-u8tzgvmevw] {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #cfe6ff;
    flex: 0 0 auto;
}

.mq-note[b-u8tzgvmevw] {
    font-size: 0.72rem;
    color: #9aa6b6;
    line-height: 1.5;
    margin: 0;
}

.mq-empty[b-u8tzgvmevw] {
    color: #6c7a8c;
    padding: 1.5rem 0;
    text-align: center;
    margin: 0;
}

/* error state (distinct from empty) */
.mq-error strong[b-u8tzgvmevw] {
    display: block;
    color: #b3261e;
    margin-bottom: 0.4rem;
}

.mq-error p[b-u8tzgvmevw] {
    color: #6c7a8c;
}

@media (max-width: 900px) {
    .mq-grid[b-u8tzgvmevw] {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 820px) {
    .mq-tiles[b-u8tzgvmevw] {
        grid-template-columns: repeat(2, 1fr);
    }
    .mq-head-actions[b-u8tzgvmevw] {
        margin-left: 0;
    }
}

@media (max-width: 480px) {
    .mq-tiles[b-u8tzgvmevw] {
        grid-template-columns: 1fr;
    }
    /* dial the hero value back so it stays proportionate to a full-width single-column card */
    .mq-tile.hero .val[b-u8tzgvmevw] {
        font-size: 2rem;
    }
}
/* /Components/Pages/MemberEngagementReport.razor.rz.scp.css */
.reports-shell[b-3tohjh3xyp] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-3tohjh3xyp] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-3tohjh3xyp] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-3tohjh3xyp],
.reports-crumb-link:focus-visible[b-3tohjh3xyp] {
    text-decoration: underline;
    outline: none;
}

.aot-head[b-3tohjh3xyp] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.aot-head h1[b-3tohjh3xyp] {
    margin: 0;
    color: #1f3f5e;
}

.aot-sub[b-3tohjh3xyp] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.aot-head-actions[b-3tohjh3xyp] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.aot-ranges[b-3tohjh3xyp] {
    display: flex;
    gap: 0.35rem;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.aot-ranges button[b-3tohjh3xyp] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.aot-ranges button.on[b-3tohjh3xyp] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.aot-ranges button:disabled[b-3tohjh3xyp] {
    cursor: default;
    opacity: 0.55;
}

/* tiles */
.aot-tiles[b-3tohjh3xyp] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.aot-tile[b-3tohjh3xyp] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.aot-tile .lab[b-3tohjh3xyp] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.aot-tile .val[b-3tohjh3xyp] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
}

.aot-tile .sub[b-3tohjh3xyp] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* card */
.aot-card[b-3tohjh3xyp] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    margin-bottom: 1.15rem;
    padding: 1rem 1.2rem 1.2rem;
}

.aot-card-head[b-3tohjh3xyp] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.aot-card-head h3[b-3tohjh3xyp] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.aot-card-head .d[b-3tohjh3xyp] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

/* band chart */
.me-chart[b-3tohjh3xyp] {
    position: relative;
    height: 240px;
}

/* per-band legend rows under the chart (count + edge label + percent) */
.me-legend-rows[b-3tohjh3xyp] {
    margin-top: 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Legend rows are buttons (#517): clickable + keyboard-activatable, each selects its band. */
.me-legend-row[b-3tohjh3xyp] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.85rem;
    color: #52617a;
    width: 100%;
    text-align: left;
    background: none;
    border: 1px solid transparent;
    border-radius: 0.5rem;
    padding: 0.35rem 0.5rem;
    cursor: pointer;
    font-family: inherit;
}

.me-legend-row:hover[b-3tohjh3xyp] {
    background: #f3f7fc;
}

.me-legend-row:focus-visible[b-3tohjh3xyp] {
    outline: 2px solid #1f6f43;
    outline-offset: 1px;
}

.me-legend-row.selected[b-3tohjh3xyp] {
    background: #eef6f1;
    border-color: #6cae86;
}

.me-swatch[b-3tohjh3xyp] {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 4px;
    flex: 0 0 14px;
}

.me-swatch-0[b-3tohjh3xyp] { background: #1f6f43; }
.me-swatch-1[b-3tohjh3xyp] { background: #3a8f5f; }
.me-swatch-2[b-3tohjh3xyp] { background: #6cae86; }
.me-swatch-3[b-3tohjh3xyp] { background: #aac8b6; }

.me-legend-name[b-3tohjh3xyp] {
    width: 128px;
    flex: 0 0 128px;
    font-weight: 600;
    color: #2a3a4d;
}

.me-legend-cnt[b-3tohjh3xyp] {
    flex: 1;
}

.me-legend-cnt b[b-3tohjh3xyp] {
    color: #1f3f5e;
}

.me-legend-pct[b-3tohjh3xyp] {
    font-weight: 700;
    color: #1f3f5e;
    font-variant-numeric: tabular-nums;
}

/* constructive callout */
.me-callout[b-3tohjh3xyp] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: #fdeccd;
    border: 1px solid #f0d690;
    border-radius: 0.625rem;
    padding: 0.75rem 1rem;
    color: #6e4700;
    font-size: 0.82rem;
    margin-top: 1rem;
}

.me-callout b[b-3tohjh3xyp] {
    color: #5a3c00;
}

/* drill-down panel: who's in the selected band (#517) */
.me-drill[b-3tohjh3xyp] {
    margin-top: 1rem;
    border: 1px solid #d8e2ee;
    border-radius: 0.625rem;
    background: #fbfdff;
    padding: 0.9rem 1rem 1rem;
}

.me-drill-head[b-3tohjh3xyp] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.6rem;
}

.me-drill-head h4[b-3tohjh3xyp] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-size: 0.95rem;
    color: #1f3f5e;
}

.me-drill-clear[b-3tohjh3xyp] {
    margin-left: auto;
    background: none;
    border: 1px solid #c5cfde;
    border-radius: 0.45rem;
    color: #4a5b70;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 0.3rem 0.6rem;
    cursor: pointer;
}

.me-drill-clear:hover[b-3tohjh3xyp],
.me-drill-clear:focus-visible[b-3tohjh3xyp] {
    background: #eef3f9;
    outline: none;
}

.me-drill-empty[b-3tohjh3xyp] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin: 0.25rem 0 0;
}

.me-drill-table[b-3tohjh3xyp] {
    margin: 0;
    font-size: 0.86rem;
}

.me-drill-table th[b-3tohjh3xyp] {
    color: #6c7a8c;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 700;
}

.me-drill-table td[b-3tohjh3xyp],
.me-drill-table th[b-3tohjh3xyp] {
    vertical-align: middle;
}

.me-drill-table .numeric[b-3tohjh3xyp] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* member name → in-app link (matches the report link styling) */
.me-member-link[b-3tohjh3xyp] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-align: left;
}

.me-member-link:hover[b-3tohjh3xyp],
.me-member-link:focus-visible[b-3tohjh3xyp] {
    text-decoration: underline;
    outline: none;
}

/* status pill — self-contained copy of the Attendance-trends palette (scoped CSS doesn't cross
   components, so we can't reuse .trends-pill from AttendanceTrendsReport here). */
.trends-pill[b-3tohjh3xyp] {
    display: inline-block;
    padding: 0.15rem 0.55rem;
    border-radius: 1rem;
    font-size: 0.72rem;
    font-weight: 700;
}

.trends-pill.active[b-3tohjh3xyp] { background: #d8f0e2; color: #1f7a4d; }
.trends-pill.new[b-3tohjh3xyp] { background: #d8e8f8; color: #1861ac; }
.trends-pill.lapsing[b-3tohjh3xyp] { background: #fbeccd; color: #a9750a; }
.trends-pill.dormant[b-3tohjh3xyp] { background: #e7ebf1; color: #6c7a8c; }

@media (max-width: 820px) {
    .aot-tiles[b-3tohjh3xyp] {
        grid-template-columns: repeat(2, 1fr);
    }
    .aot-head-actions[b-3tohjh3xyp] {
        margin-left: 0;
    }
    .me-legend-name[b-3tohjh3xyp] {
        width: 96px;
        flex: 0 0 96px;
    }
}

@media (max-width: 480px) {
    .aot-tiles[b-3tohjh3xyp] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/Members.razor.rz.scp.css */
.club-management-shell[b-wg5lf94s9y] {
    padding: 0;
}

.club-management-shell h1[b-wg5lf94s9y] {
    color: #0d2c55;
    font-size: 2.5rem;
    margin: 0 0 1rem;
}

.membership-tabs .nav-link[b-wg5lf94s9y] {
    color: #1f4267;
    font-weight: 700;
}

.membership-tabs .nav-link.active[b-wg5lf94s9y] {
    color: #0d2c55;
}

.club-card[b-wg5lf94s9y] {
    background: #f6f8fb;
    border-radius: 0.2rem;
    margin-bottom: 1rem;
    padding: 1rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.club-card h2[b-wg5lf94s9y] {
    color: #24384f;
    font-size: 2rem;
    margin: 0 0 0.65rem;
}

.member-section-header[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.65rem;
    margin-bottom: 0.6rem;
}

.member-header-actions[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    flex-wrap: wrap;
}

/* #437: Show Deactivated moved off the toolbar into the filter bar. It is a
   member-filter-field (so it aligns with the Gender/Type dropdowns) AND keeps
   its form-check layout — centre the checkbox + label on the filter row. */
.member-show-deactivated-toggle[b-wg5lf94s9y] {
    margin: 0;
    color: #3e5873;
    font-size: 0.9rem;
    flex-direction: row;
    align-items: center;
    gap: 0.35rem;
}

.member-show-deactivated-toggle .form-check-input[b-wg5lf94s9y] {
    margin: 0;
}

.member-show-deactivated-toggle .form-check-label[b-wg5lf94s9y] {
    white-space: nowrap;
}

.member-editor-panel[b-wg5lf94s9y] {
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.4rem;
    background: #ffffff;
    padding: 0.75rem;
    margin: 0 0 0.85rem;
}

.member-editor-title[b-wg5lf94s9y] {
    margin: 0 0 0.6rem;
    color: #2c4560;
    font-size: 1.15rem;
    font-weight: 700;
}

.club-inline-actions[b-wg5lf94s9y] {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.admin-tools-panel summary[b-wg5lf94s9y] {
    cursor: pointer;
    color: #3a5168;
    font-weight: 700;
    font-size: 0.96rem;
    list-style: none;
}

.admin-tools-panel summary[b-wg5lf94s9y]::-webkit-details-marker {
    display: none;
}

.admin-tools-panel summary[b-wg5lf94s9y]::before {
    content: "\25B6";
    display: inline-block;
    margin-right: 0.45rem;
    color: #5d7389;
    transform: translateY(-0.02rem);
}

.admin-tools-panel[open] summary[b-wg5lf94s9y]::before {
    content: "\25BC";
}

.admin-tools-actions[b-wg5lf94s9y] {
    margin-top: 0.65rem;
}

.club-add-grid[b-wg5lf94s9y] {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) minmax(10rem, 0.65fr) minmax(10rem, 0.65fr) minmax(12rem, 1fr) auto;
    gap: 0.55rem;
    align-items: end;
}

.club-add-actions[b-wg5lf94s9y] {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.member-add-grid[b-wg5lf94s9y] {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) minmax(10rem, 0.7fr) minmax(10rem, 0.7fr) minmax(10rem, 0.7fr) auto;
    gap: 0.55rem;
    align-items: end;
    margin: 0 0 0.85rem;
}

.club-help-text[b-wg5lf94s9y] {
    margin: 0.75rem 0 0;
    color: #5f6f80;
}

.club-help-text code[b-wg5lf94s9y] {
    color: #c72576;
    background: transparent;
    padding: 0;
}

.club-members-table[b-wg5lf94s9y] {
    margin-bottom: 0;
}

.club-members-table thead th[b-wg5lf94s9y] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
    font-size: 1.02rem;
}

.club-members-table thead th.sortable-header[b-wg5lf94s9y] {
    cursor: pointer;
    user-select: none;
}

.club-members-table thead th.sortable-header:hover[b-wg5lf94s9y] {
    color: #0d2c55;
}

.club-members-table tbody td[b-wg5lf94s9y] {
    vertical-align: middle;
}

/* #377: the whole row opens the member profile, so signal it's clickable and
   give a hover cue. The action buttons / membership select stopPropagation, so
   they stay independently usable. */
.club-members-table tbody tr.member-row-clickable[b-wg5lf94s9y] {
    cursor: pointer;
}

.club-members-table tbody tr.member-row-clickable:hover td[b-wg5lf94s9y] {
    background: #eef3f9;
}

/* The member tables are wide (the directory has 12 columns) and scroll horizontally inside
   .table-responsive at tablet / icon-rail widths, pushing the Actions column off the right with
   the only scrollbar below the fold. Pin the Actions (last) column to the right edge so its
   buttons stay visible and reachable however far the table is scrolled. Covers both the member
   directory and the pending-invites table (shared .club-members-table). */
.club-members-table th:last-child[b-wg5lf94s9y],
.club-members-table td:last-child[b-wg5lf94s9y] {
    position: sticky;
    right: 0;
    background: #ffffff;
    box-shadow: -6px 0 6px -4px rgba(0, 0, 0, 0.12);
}

.club-members-table td:last-child[b-wg5lf94s9y] {
    z-index: 1;
}

.club-members-table thead th:last-child[b-wg5lf94s9y] {
    z-index: 3;
}

/* Keep the pinned cell in step with the row hover so it doesn't stay white while the rest
   of the row highlights. */
.club-members-table tbody tr.member-row-clickable:hover td:last-child[b-wg5lf94s9y] {
    background: #eef3f9;
}

/* Keep the horizontal scrollbar reachable. The directory table is wide and tall, so the
   .table-responsive's horizontal scrollbar sat at the bottom of the table — below the fold —
   and looked like there was no scroll at all. Bound the table to the viewport so it scrolls
   inside its own box (the horizontal scrollbar lands at the box bottom, on screen). All
   columns are kept; you scroll to the ones that don't fit. */
.member-directory-scroll[b-wg5lf94s9y] {
    max-height: calc(100dvh - 12rem);
    overflow: auto;
}

/* Sticky header so the column labels stay put while the body scrolls vertically inside the
   box. Solid bg hides rows scrolling under it; z-index sits above the sticky Actions column
   (the Actions header corner keeps its z-index:3 from the rule above, so it wins both axes). */
.member-directory-table thead th[b-wg5lf94s9y] {
    position: sticky;
    top: 0;
    background: #ffffff;
    z-index: 2;
}

.club-members-table tbody tr.member-row-inactive td[b-wg5lf94s9y] {
    color: #7a8897;
}

/* BL-096: colour-code the member-name cell by gender for at-a-glance scan.
   Reuses the same palette as the photo-fallback circle so the visual cue is
   consistent across the row. Active members only - the .member-row-inactive
   parent rule above has higher specificity so deactivated rows stay grey.
   Gender column remains visible so the signal isn't colour-only (WCAG). */
.member-name-cell.male[b-wg5lf94s9y] {
    color: var(--gender-male);
    font-weight: 600;
}

.member-name-cell.female[b-wg5lf94s9y] {
    color: var(--gender-female);
    font-weight: 600;
}

/* .member-name-cell.unspecified inherits default text colour — no rule needed. */

/* SPEC-31 S2a: the row-level "Plays" (Is Player) toggle. A bare form-switch with
   no label text, centred in its cell; kept compact so the row height doesn't grow. */
.member-plays-toggle[b-wg5lf94s9y] {
    min-height: auto;
    margin: 0;
    padding-left: 2.5em;
    display: inline-flex;
    align-items: center;
}

.member-plays-toggle .form-check-input[b-wg5lf94s9y] {
    margin: 0;
    cursor: pointer;
}

.member-plays-readonly[b-wg5lf94s9y] {
    color: #4a5f77;
    font-weight: 600;
    font-size: 0.9rem;
}

/* SPEC-31 #136 UAT rework: the per-member management block hosted INSIDE the member
   profile modal (rendered via the ManagementContent RenderFragment). Authored on the
   Members page, so these Members-scoped rules apply to it even though it paints inside
   the shared modal. A simple stacked layout — one control group per row. */
.member-manage[b-wg5lf94s9y] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.member-manage-title[b-wg5lf94s9y] {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 0;
    color: #24405f;
}

.member-manage-row[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
}

.member-manage-label[b-wg5lf94s9y] {
    font-weight: 600;
    color: #4a5f77;
    min-width: 6rem;
}

.member-manage-access-body[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* #136 review: the access-removed-but-still-linked state (no fresh invite offered). */
.member-access-linked-no-role[b-wg5lf94s9y] {
    color: #6b7c90;
    font-size: 0.9rem;
    font-style: italic;
}

.member-manage-invite[b-wg5lf94s9y] {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid #d7e0ea;
    border-radius: 0.5rem;
    background: #f7fafd;
}

.member-manage-invite-grid[b-wg5lf94s9y] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.member-manage-invite-grid .invite-email-input[b-wg5lf94s9y] {
    flex: 1 1 12rem;
    min-width: 10rem;
}

/* The "Deactivated" tag in the thinned row's Status cell. */
.member-status-deactivated[b-wg5lf94s9y] {
    font-weight: 600;
}

/* SPEC-31 S2b: the inline app-access role control on a live-account row. Compact
   (mirrors the membership select) so the wide people table doesn't bloat.
   OD-1: this cell holds a LIVE role, so it carries the same active/blue cue as the
   read-only .app-access-live badge — otherwise, in Administer (manager) mode, the
   live role becomes a plain grey dropdown indistinguishable from the Membership-type
   select beside it and the "who has real access" signal is lost. Pending invites stay
   a muted badge (rendered by AppAccessCell), so live-vs-pending honesty survives. */
.member-access-role-select[b-wg5lf94s9y] {
    min-width: 6rem;
    width: auto;
    padding: 0.15rem 1.6rem 0.15rem 0.4rem;
    font-size: 0.85rem;
    border-color: #0d6efd;
    background-color: #eaf2ff;
    color: #0d3b8a;
    font-weight: 600;
}

/* BL-104: click-toggle help marker. v1 was a hover tooltip (title attr)
   which is no good on tablet/phone where there's no hover — so the "?"
   is now a real <button> that toggles an inline popover below. */
.form-label-with-help[b-wg5lf94s9y] {
    /* container so the popover can sit immediately below the label. */
}

.form-label-with-help-text[b-wg5lf94s9y] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.form-label-help-button[b-wg5lf94s9y] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    background: #e7eff8;
    color: #1f5a8a;
    border: 1px solid #b9c9db;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.form-label-help-button:hover[b-wg5lf94s9y] {
    background: #d6e4f3;
    border-color: #94afca;
}

.form-label-help-button:focus[b-wg5lf94s9y] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
}

.form-help-popover[b-wg5lf94s9y] {
    margin: 0.4rem 0 0.6rem;
    padding: 0.6rem 0.75rem;
    background: #f3f7fb;
    border: 1px solid #c4d2e0;
    border-radius: 0.5rem;
    font-size: 0.85rem;
    color: #2a4361;
    line-height: 1.4;
}

.form-help-popover-list[b-wg5lf94s9y] {
    margin: 0.25rem 0 0.5rem;
    padding-left: 1.2rem;
    list-style: disc;
}

.form-help-popover-list li[b-wg5lf94s9y] {
    margin-bottom: 0.15rem;
}

.form-help-popover-close[b-wg5lf94s9y] {
    /* Kiosk fat-finger target: grow the hit area to ~44px tall (min-height
       2.75rem + vertical padding) while keeping the tidy text-link look.
       inline-flex so the "Got it" text stays vertically centred in the taller
       box. Horizontal padding gives a comfortable side hit area without making
       it read as a button. margin-top normalised to 0.5rem to match the
       MemberProfileModal twin surface (was 0.25rem). */
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0.5rem;
    margin-top: 0.5rem;
    text-decoration: none;
    color: #1b6ec2;
    font-weight: 500;
}

/* BL-097: Members-table filter bar. Compact horizontal strip; wraps on
   narrow viewports. Name input takes flex space, chip groups stay
   inline with their labels. */
.member-filter-bar[b-wg5lf94s9y] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.8rem;
    margin-bottom: 0.6rem;
    padding: 0.4rem 0.55rem;
    background: #f3f7fb;
    border: 1px solid #d3dde7;
    border-radius: 0.5rem;
}

.member-filter-name[b-wg5lf94s9y] {
    flex: 1 1 14rem;
    min-width: 12rem;
}

.member-filter-field[b-wg5lf94s9y] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
}

.member-filter-label[b-wg5lf94s9y] {
    color: #5a6b80;
    font-size: 0.82rem;
    font-weight: 500;
}

.member-filter-select[b-wg5lf94s9y] {
    width: auto;
    min-width: 7rem;
    padding-top: 0.15rem;
    padding-bottom: 0.15rem;
}

.member-filter-clear[b-wg5lf94s9y] {
    margin-left: auto;
    color: #5e748a;
    text-decoration: none;
    padding: 0.15rem 0.4rem;
}

.member-filter-clear:hover[b-wg5lf94s9y] {
    color: #1f3f5e;
    text-decoration: underline;
}


/* #196: the two rating-trust columns on the people list. */

/* Matches = the rated-games count. Right-aligned, tabular figures so the column
   scans as a number list next to Rating. */
.member-matches-header[b-wg5lf94s9y],
.member-matches-cell[b-wg5lf94s9y] {
    text-align: right;
}

.member-matches-cell[b-wg5lf94s9y] {
    font-variant-numeric: tabular-nums;
    color: #24384f;
}

/* Rating confidence cell. Settling → a compact amber "Settling" pill reusing the
   shared #304 SettlingChip glyph + copy, as a native <details> disclosure (no
   per-row component state). Mirrors the .profile-settling look so the list chip and
   the profile chip read as one feature. */
.member-confidence-settling[b-wg5lf94s9y] {
    font-size: 0.8rem;
}

.member-confidence-settling-summary[b-wg5lf94s9y] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    cursor: pointer;
    color: #9a6700;
    background: #f6ecd6;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-weight: 650;
    list-style: none;
    width: fit-content;
}

.member-confidence-settling-summary[b-wg5lf94s9y]::-webkit-details-marker {
    display: none;
}

.member-confidence-settling-summary:focus-visible[b-wg5lf94s9y] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* ::deep is needed because the glyph comes from a code-behind RenderFragment
   (SettlingChip.Glyph), which Blazor's scoped-CSS rewriter never tags with the
   component's [b-xxxx] attribute — so it can only be reached by piercing the scope
   from the summary element (which IS tagged). Matches the .member-settling-chip
   pattern above. */
.member-confidence-settling-summary[b-wg5lf94s9y]  .member-settling-chip-icon {
    width: 0.9rem;
    height: 0.9rem;
    flex: 0 0 auto;
}

.member-confidence-settling-label[b-wg5lf94s9y] {
    white-space: nowrap;
}

.member-confidence-copy[b-wg5lf94s9y] {
    margin: 0.4rem 0 0;
    font-size: 0.82rem;
    color: #5c6a7d;
    max-width: 42ch;
    /* The row-click cursor is a pointer; keep the expanded copy readable as text. */
    cursor: text;
}

/* Settled → a quiet muted label (the confident counterpart state), so the column
   reads at a glance rather than blank. Not a new indicator — plain text. */
.member-confidence-settled[b-wg5lf94s9y] {
    color: #6b7c90;
    font-size: 0.85rem;
}

.club-members-table .btn-sm[b-wg5lf94s9y] {
    min-width: 4.6rem;
}

.member-photo-table[b-wg5lf94s9y] {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 999px;
    border: 1px solid rgba(31, 43, 56, 0.16);
    object-fit: cover;
    background: #fff;
}

.member-photo-field[b-wg5lf94s9y] {
    margin: 0 0 0.9rem;
}

.member-photo-editor[b-wg5lf94s9y] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.member-photo-editor-preview[b-wg5lf94s9y] {
    width: 4.8rem;
    height: 4.8rem;
    border-radius: 999px;
    border: 2px solid rgba(31, 43, 56, 0.2);
    object-fit: cover;
    background: #fff;
}

.member-photo-editor-fallback[b-wg5lf94s9y] {
    width: 4.8rem;
    height: 4.8rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid rgba(38, 66, 97, 0.22);
    background: #ffffff;
    font-family: "Segoe UI", Tahoma, Arial, sans-serif;
    box-sizing: border-box;
}

.member-photo-editor-controls[b-wg5lf94s9y] {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-width: 16rem;
}

.member-photo-error[b-wg5lf94s9y] {
    color: #a11b2f;
    font-size: 0.85rem;
    font-weight: 600;
}

.member-rating-readonly[b-wg5lf94s9y] {
    border: 1px solid #c5d4e2;
    border-radius: 0.35rem;
    background: #f4f8fc;
    padding: 0.45rem 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.member-rating-value[b-wg5lf94s9y] {
    color: #213a54;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.1;
}

.member-rating-hint[b-wg5lf94s9y] {
    color: #5d748a;
    font-size: 0.78rem;
}

.member-photo-fallback[b-wg5lf94s9y] {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid rgba(38, 66, 97, 0.22);
    background: #ffffff;
    font-family: "Segoe UI", Tahoma, Arial, sans-serif;
    box-sizing: border-box;
}

.member-photo-fallback.male[b-wg5lf94s9y] {
    border-color: #3d88c8;
    background: #eef6ff;
    color: var(--gender-male);
}

.member-photo-fallback.female[b-wg5lf94s9y] {
    border-color: #cf75a4;
    background: #fff0f7;
    color: var(--gender-female);
}

.member-photo-fallback.unspecified[b-wg5lf94s9y] {
    border-color: #8fa1b4;
    background: #f2f6fa;
    color: #5a6d80;
}

.member-photo-initials[b-wg5lf94s9y] {
    display: block;
    color: currentColor;
    font-size: 0.82rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.member-profile-modal-backdrop[b-wg5lf94s9y] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2100;
}

.member-profile-modal[b-wg5lf94s9y] {
    /* Backdrop pads 1rem each side — 94vw overflowed it on phones, forcing a
       small horizontal scroll (412px Moto). Subtract the padding instead.
       Desktop cap 1080px so the session-history table fits real-world data
       without scrolling; the calc() term governs on phones. */
    width: min(1080px, calc(100vw - 2rem));
    max-height: 90vh;
    overflow-y: auto;
    background: #f8fbff;
    border: 1px solid #b8c8d8;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 0.85rem;
}

.member-profile-modal-header[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.member-profile-modal-header-actions[b-wg5lf94s9y] {
    display: flex;
    gap: 0.4rem;
}

.member-profile-modal-header h3[b-wg5lf94s9y] {
    margin: 0;
    color: #253f5b;
    font-size: 1.35rem;
    font-weight: 700;
}

.member-profile-modal-body[b-wg5lf94s9y] {
    display: grid;
    grid-template-columns: 11rem 1fr;
    gap: 0.9rem;
    align-items: start;
}

/* Grid items default to min-width:auto — let children shrink rather than
   force the column (and siblings) wider than the modal on phones. */
.member-profile-modal-body > *[b-wg5lf94s9y] {
    min-width: 0;
}

.member-profile-photo[b-wg5lf94s9y] {
    width: 11rem;
    height: 11rem;
    border-radius: 0.85rem;
    border: 2px solid rgba(37, 63, 91, 0.2);
    object-fit: cover;
    background: #fff;
}

.member-profile-photo-fallback[b-wg5lf94s9y] {
    width: 11rem;
    height: 11rem;
    border-radius: 0.85rem;
    border: 2px solid rgba(37, 63, 91, 0.2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #f2f6fa;
    color: #4e657d;
}

.member-profile-photo-fallback.male[b-wg5lf94s9y] {
    border-color: #3d88c8;
    background: #eef6ff;
    color: var(--gender-male);
}

.member-profile-photo-fallback.female[b-wg5lf94s9y] {
    border-color: #cf75a4;
    background: #fff0f7;
    color: var(--gender-female);
}

.member-profile-photo-fallback.unspecified[b-wg5lf94s9y] {
    border-color: #8fa1b4;
    background: #f2f6fa;
    color: #5a6d80;
}

.member-profile-photo-initials[b-wg5lf94s9y] {
    font-size: 2.35rem;
    font-weight: 800;
    line-height: 1;
    text-transform: uppercase;
}

.member-profile-fields[b-wg5lf94s9y] {
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem 0.8rem;
    grid-column: 1 / -1;
}

.member-profile-fields > div[b-wg5lf94s9y] {
    border: 1px solid #ccdae8;
    border-radius: 0.45rem;
    background: #ffffff;
    padding: 0.45rem 0.55rem;
}

.member-profile-id-field[b-wg5lf94s9y] {
    grid-column: 1 / -1;
}

.member-profile-id-field .member-profile-id[b-wg5lf94s9y] {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
}

.member-profile-fields dt[b-wg5lf94s9y] {
    margin: 0;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.member-profile-fields dd[b-wg5lf94s9y] {
    margin: 0.2rem 0 0;
    color: #24384f;
    font-size: 0.95rem;
    font-weight: 600;
    word-break: break-word;
}

.member-profile-id[b-wg5lf94s9y] {
    font-family: Consolas, "Courier New", monospace;
    font-size: 0.8rem;
}

.member-profile-tabs[b-wg5lf94s9y] {
    display: flex;
    /* Wrap rather than force the modal wider than a phone screen. */
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid #d8e0ea;
    grid-column: 1 / -1;
}

.member-profile-tab[b-wg5lf94s9y] {
    background: transparent;
    border: none;
    padding: 0.5rem 0.9rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: #60778f;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 120ms ease, border-color 120ms ease;
}

.member-profile-tab:hover[b-wg5lf94s9y] {
    color: #24384f;
}

.member-profile-tab.active[b-wg5lf94s9y] {
    color: #0d6efd;
    border-bottom-color: #0d6efd;
}

.member-profile-sessions[b-wg5lf94s9y] {
    grid-column: 1 / -1;
    max-height: 22rem;
    overflow-y: auto;
}

/* BL-046 (re-opened 2026-04-26x2): the previous min-width of 6.25rem still
   wrapped on Mike's viewport. Bump to 7.5rem and force the action cell to
   nowrap so the cluster of action buttons stays on one line. */
.member-toggle-active-btn[b-wg5lf94s9y] {
    min-width: 7.5rem;
}

.club-members-table tbody td.text-end[b-wg5lf94s9y] {
    white-space: nowrap;
}

.member-profile-sessions-table th[b-wg5lf94s9y],
.member-profile-sessions-table td[b-wg5lf94s9y] {
    padding: 0.55rem 0.65rem;
    white-space: nowrap;
}

.member-profile-sessions-table .numeric[b-wg5lf94s9y] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.member-profile-rating[b-wg5lf94s9y] {
    grid-column: 1 / -1;
}

/* #304: rating-number header on the Rating tab - the anchor the Settling chip
   reads against. Number is the hero; chip is a quiet neutral signal beside it.
   Kept identical to MemberProfileModal.razor.css so the twin surfaces match. */
.member-rating-header[b-wg5lf94s9y] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}

.member-rating-header-value[b-wg5lf94s9y] {
    color: #213a54;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

/* #304: neutral "Settling" chip. Composed from the existing neutral box tokens
   (member-rating-readonly family) - deliberately NOT the coloured badge bg-*
   family, whose status-colour semantics would read as an alarm. The whole chip
   is a button (it becomes the tap target for S2's explainer popover). */
.member-settling-chip[b-wg5lf94s9y] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-height: 1.9rem;
    padding: 0.25rem 0.6rem;
    /* WCAG 1.4.11: border must clear 3:1 against its own #f4f8fc fill for the
       chip boundary to be perceivable. #8fa3b8 (the UX note's suggestion) only
       reaches ~2.5:1; #7d90a6 clears it (3.07:1 vs the chip fill, 3.16:1 vs the
       modal bg) while staying a calm neutral grey-blue - no warning semantics. */
    border: 1px solid #7d90a6;
    border-radius: 999px;
    background: #f4f8fc;
    color: #213a54;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.1;
    /* It IS a button and becomes interactive in S2 (tap-to-explain popover);
       pointer avoids a desktop "looks broken" read and an S2 CSS churn. */
    cursor: pointer;
}

/* The chip is a bare <button> (no .btn class), so Bootstrap reboot suppresses
   the default focus outline and the app's .btn focus ring never applies -
   keyboard users got no focus signal. Restore a visible ring, matching the
   .form-label-help-button:focus style above. */
.member-settling-chip:focus-visible[b-wg5lf94s9y] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* ::deep is needed because the glyph comes from a code-behind RenderFragment
   (SettlingChip.Glyph), which Blazor's scoped-CSS rewriter never tags with the
   component's [b-xxxx] attribute - so the icon class can only be reached by
   piercing the scope from the chip element (which IS tagged). */
.member-settling-chip[b-wg5lf94s9y]  .member-settling-chip-icon {
    width: 0.95rem;
    height: 0.95rem;
    flex: 0 0 auto;
}

.member-settling-chip-label[b-wg5lf94s9y] {
    white-space: nowrap;
}

/* #304 S2: cap the explainer popover width so it reads as a tooltip beside the
   number rather than spanning the whole tab. Reuses the form-help-popover look. */
.member-settling-popover[b-wg5lf94s9y] {
    max-width: 32rem;
}

.member-profile-rating-chart[b-wg5lf94s9y] {
    position: relative;
    width: 100%;
    height: 18rem;
    padding: 0.5rem 0;
}

.member-profile-rating-chart canvas[b-wg5lf94s9y] {
    width: 100% !important;
    height: 100% !important;
}

@media (max-width: 1100px) {
    .club-add-grid[b-wg5lf94s9y] {
        grid-template-columns: 1fr 1fr;
    }

    .member-add-grid[b-wg5lf94s9y] {
        grid-template-columns: 1fr 1fr;
    }

    .member-photo-editor[b-wg5lf94s9y] {
        flex-direction: column;
        align-items: flex-start;
    }

    .member-photo-editor-controls[b-wg5lf94s9y] {
        min-width: 0;
        width: 100%;
    }

    .member-profile-modal-body[b-wg5lf94s9y] {
        grid-template-columns: 1fr;
        justify-items: center;
    }

    .member-profile-photo[b-wg5lf94s9y],
    .member-profile-photo-fallback[b-wg5lf94s9y] {
        width: 9rem;
        height: 9rem;
    }

    .member-profile-fields[b-wg5lf94s9y] {
        grid-template-columns: 1fr;
        width: 100%;
        justify-self: stretch;
    }

    .member-profile-tabs[b-wg5lf94s9y],
    .member-profile-sessions[b-wg5lf94s9y],
    .member-profile-rating[b-wg5lf94s9y] {
        width: 100%;
        justify-self: stretch;
    }
}

@media (max-width: 700px) {
    .club-add-grid[b-wg5lf94s9y] {
        grid-template-columns: 1fr;
    }

    .member-add-grid[b-wg5lf94s9y] {
        grid-template-columns: 1fr;
    }

    .member-section-header[b-wg5lf94s9y] {
        align-items: stretch;
        flex-direction: column;
    }

    .member-header-actions[b-wg5lf94s9y] {
        width: 100%;
        justify-content: space-between;
    }
}

/* Mobile / narrow-tablet: hide lower-priority Members table columns so the
   Actions column stays reachable without horizontal scrolling. SPEC-31 S2a
   column order (Plays inserted after Status, App access replaces Role):
   1=Photo 2=Name 3=Membership 4=Gender 5=Status 6=Plays 7=Rating 8=LastPlayed
   9=Sessions 10=Win% 11=LinkedLogin 12=AppAccess 13=Actions.
   We KEEP Name(2), Status(5), Plays(6), Rating(7), App access(12), Actions(13) —
   the two new headline axes (Plays + App access) stay visible on the tablet. */
@media (max-width: 700px) {
    .member-directory-table th:nth-child(1)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(1)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(3)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(3)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(4)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(4)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(8)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(8)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(9)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(9)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(10)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(10)[b-wg5lf94s9y],
    .member-directory-table th:nth-child(11)[b-wg5lf94s9y],
    .member-directory-table td:nth-child(11)[b-wg5lf94s9y] {
        display: none;
    }

    .member-directory-table .btn-sm[b-wg5lf94s9y] {
        display: block;
        width: 100%;
        margin-left: 0 !important;
        margin-bottom: 0.25rem;
    }

    .member-directory-table .btn-sm:last-child[b-wg5lf94s9y] {
        margin-bottom: 0;
    }

    /* User Access tab tables share the club-members-table style — stack their
       action buttons vertically too so they don't get clipped at narrow widths. */
    .pending-invites-table .btn-sm[b-wg5lf94s9y],
    .club-members-table .user-remove-btn[b-wg5lf94s9y] {
        display: block;
        width: 100%;
    }
}

/* #738: unlink-login confirm modal (kiosk mis-tap guard) - mirrors the
   dashboard's end-session confirm modal shape. */
.member-unlink-modal-backdrop[b-wg5lf94s9y] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2200;
}

.member-unlink-modal[b-wg5lf94s9y] {
    width: min(480px, 94vw);
    background: #ffffff;
    border: 1px solid #c8d4e2;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 1.1rem 1.2rem 1rem;
}

.member-unlink-modal h2[b-wg5lf94s9y] {
    margin: 0 0 0.6rem;
    color: #0d2c55;
    font-size: 1.15rem;
}

.member-unlink-actions[b-wg5lf94s9y] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* FDD-0001 S3 (ado:1432): .claim-link-cluster is deleted with the "Get claim link" button it
   grouped. The coverage stat SURVIVES and now LEADS the toolbar (mockup screens 1, 5 and 10).

   WHAT FIXES THE PHONE BUG IS THE SOURCE ORDER, not this rule — the stat moved to the front
   of .member-header-actions in Members.razor, so a wrapped toolbar puts it on the first row
   by construction. Stated plainly because the first draft of this comment credited the auto
   margin, which would have sent the next reader to the wrong line. The bug was real and was
   found by driving a real phone: at 375px the toolbar wraps, and last-in-source put the stat
   on the second row below three buttons — in the exact moment mockup screen 10 is drawn for.

   margin-right: auto is the mockup's SPACER, and only that: where the row has room it holds
   the reading apart from the actions instead of letting it read as a fourth control. Note the
   group is sized by content and sits right under the heading, so the mockup's full-bleed
   left/right split does not fall out of this alone; making the toolbar full-width is a change
   to shared page chrome outside this slice's region, and was not taken.

   NO separator rule here any more. The build briefly gave the stat the cluster's own
   border-left and padding-left, which made sense while it sat last among the buttons and
   needed dividing from them; leading the toolbar, a left border is a rule hanging off the
   front edge of the row with nothing to its left to separate it from. The auto-margin gap
   does the grouping instead. The compact progress bar still echoes the navy/muted palette of
   the rest of the page. */
.claim-coverage-stat[b-wg5lf94s9y] {
    margin-right: auto;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    line-height: 1.2;
}

.claim-coverage-stat strong[b-wg5lf94s9y] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #16324f;
    white-space: nowrap;
}

.claim-coverage-bar[b-wg5lf94s9y] {
    display: block;
    height: 0.35rem;
    width: 100%;
    min-width: 6rem;
    border-radius: 1rem;
    background: #e6edf4;
    overflow: hidden;
}

.claim-coverage-bar > i[b-wg5lf94s9y] {
    display: block;
    height: 100%;
    background: #1b6ec2;
    transition: width 0.25s ease;
}

/* ── SPEC-41 S11 (#721): people waiting to connect ───────────────────────────────────────────────
   The section is an ordinary .club-card; these rules only cover the states the queue gained when it
   became a notification's link target. No new brand, no new colour, no new component. */

/* Loading. This is LAYOUT RESERVATION, not reassurance: the section is now the first card under the
   page title, so rows arriving after paint would shove the roster down. Two bars stand in for the
   table while the read resolves. Deliberately no animation — an officer arriving from a notification
   must not be met with movement (the arrival AC is "in the viewport, and nothing animates"). */
.connect-requests-skeleton[b-wg5lf94s9y] {
    padding: 0.25rem 0;
}

.connect-requests-skeleton-row[b-wg5lf94s9y] {
    height: 2.25rem;
    margin-bottom: 0.5rem;
    border-radius: 0.35rem;
    background: #eef2f6;
}

.connect-requests-skeleton-row:last-child[b-wg5lf94s9y] {
    margin-bottom: 0;
}

/* Empty state. Ordinary text in the section, not a visually-hidden aside — the officer arrived here
   deliberately and the closure is the message. */
.connect-requests-empty[b-wg5lf94s9y] {
    font-size: 1rem;
}

/* The running tally. One quiet status line; nothing animated, and no colour that competes with the
   table above it. */
.connect-requests-tally[b-wg5lf94s9y] {
    font-size: 0.9rem;
    color: #4a5763;
}

/* Per-row failure text, under that row's own (re-enabled) Approve/Decline pair. */
.request-row-error[b-wg5lf94s9y] {
    font-size: 0.8rem;
}

/* ── ado:1433: which decision a queue row is ─────────────────────────────────────────────────────
   ONE chip rule, not one per kind, and that is a decision rather than an omission. The two kinds
   are told apart by their words — "Connect" and "New member". §7.6 rules colour on this surface
   down to "amber only for a flag, red only where the action is blocked, and no green on a check
   line ever", and a type marker is none of those; colour would also be the one way to draw this
   that an officer with a colour deficit cannot read. A modifier class with no rule behind it is
   worse than no class at all — this stylesheet deleted .connect-requests-error and
   -retry-btn for precisely that reason — so the per-kind selector is the data-testid, which is
   what the tests use anyway.

   Composed from .member-settling-chip's visual tokens, and ONLY those. That chip is a <button>;
   its cursor and :focus-visible rules exist to serve a tap target, and copying them onto a <span>
   would leave a focus ring around something nothing can focus.

   nowrap IS ON THE CHIP AND DELIBERATELY NOT ON THE LINE BESIDE IT. "New member" broken across
   two lines inside a pill reads as a rendering fault, and at 0.72rem those two words sit well
   inside the floor the email address in the next column already imposes. The consequence text is
   the long half, so it stays free to wrap: Spec41ConnectQueueGeometryTests asserts this section
   adds no horizontal overflow at 360×800, and a width floor on the long half is what would break
   that. THIS PAIR IS THE ONE THING IN THIS SLICE NO TEST HAS YET RUN AGAINST — see the geometry
   filter named in the item's technical design. */
.request-kind-chip[b-wg5lf94s9y] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border: 1px solid #7d90a6;
    border-radius: 999px;
    background: #f4f8fc;
    color: #213a54;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.5;
    white-space: nowrap;
}

/* The consequence line. Quiet on purpose: the chip is the glance, this is the check, and neither
   should compete with the member name set in <strong> inside it. */
.request-kind-detail[b-wg5lf94s9y] {
    font-size: 0.85rem;
    color: #4a5763;
}

/* FDD-0001 S3 (ado:1432): .claim-link-connected-chip is deleted with the scope picker that was
   its only user (the per-member "choose members" list). The roster-row Connected chip is a
   DIFFERENT rule and is untouched — its audience is now the officer reading coverage. */

/* The zero-state hint under the coverage stat (mockup screen 6): shown only at 0 of N, where
   the officer has built a roster and not yet handed the code out. Muted and small — it is a
   next step, not a warning. */
.claim-coverage-hint[b-wg5lf94s9y] {
    font-size: 0.72rem;
    color: #5e748a;
    line-height: 1.3;
}
/* /Components/Pages/MostImprovedReport.razor.rz.scp.css */
.reports-shell[b-am6wtpdveo] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-am6wtpdveo] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-am6wtpdveo] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-am6wtpdveo],
.reports-crumb-link:focus-visible[b-am6wtpdveo] {
    text-decoration: underline;
    outline: none;
}

/* head */
.mi-head[b-am6wtpdveo] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.mi-head h1[b-am6wtpdveo] {
    margin: 0;
    color: #1f3f5e;
}

.mi-sub[b-am6wtpdveo] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.mi-season-note[b-am6wtpdveo] {
    color: #5a6b7d;
    font-size: 0.85rem;
    margin: 0.1rem 0 0.6rem;
}

.mi-settled-note[b-am6wtpdveo] {
    font-size: 0.8rem;
    color: #5a6b7d;
    max-width: 60ch;
}

.mi-season-note a[b-am6wtpdveo] {
    color: #2f6fed;
}

.mi-head-actions[b-am6wtpdveo] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.mi-ranges[b-am6wtpdveo] {
    display: flex;
    gap: 0.35rem;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.mi-ranges button[b-am6wtpdveo] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.mi-ranges button.on[b-am6wtpdveo] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.mi-ranges button:disabled[b-am6wtpdveo] {
    cursor: default;
    opacity: 0.55;
}

/* tiles */
.mi-tiles[b-am6wtpdveo] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.mi-tile[b-am6wtpdveo] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.mi-tile .lab[b-am6wtpdveo] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.mi-tile .val[b-am6wtpdveo] {
    /* Match siblings' 1.9rem at the top end, but shrink gracefully so a long member name in the
       "Most improved" tile (this report's only text-valued tile) never overflows. */
    font-size: clamp(1.2rem, 4vw, 1.9rem);
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.1;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

.mi-tile .sub[b-am6wtpdveo] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* two-column grid: leaderboard + distribution */
.mi-grid[b-am6wtpdveo] {
    display: grid;
    grid-template-columns: 1.5fr 1fr;
    gap: 1.15rem;
    margin-bottom: 1.15rem;
}

.mi-card[b-am6wtpdveo] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.2rem 1.2rem;
}

.mi-card-head[b-am6wtpdveo] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.5rem;
}

.mi-card-head h3[b-am6wtpdveo] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.mi-card-head .d[b-am6wtpdveo] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

.mi-card-body[b-am6wtpdveo] {
    padding-top: 0.25rem;
}

.mi-empty[b-am6wtpdveo] {
    color: #6c7a8c;
    padding: 1.5rem 0;
    text-align: center;
    margin: 0;
}

/* winner card */
.mi-winner[b-am6wtpdveo] {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    background: #fbf3da;
    border: 1px solid #ecdcb8;
    border-radius: 0.65rem;
    padding: 0.75rem 0.9rem;
    margin: 0.15rem 0 0.65rem;
}

.mi-winner .medal[b-am6wtpdveo] {
    font-size: 1.65rem;
}

.mi-winner .who[b-am6wtpdveo] {
    flex: 1;
    min-width: 0;
}

.mi-winner .nm[b-am6wtpdveo] {
    font-weight: 800;
    font-size: 1rem;
    color: #1f3f5e;
}

.mi-winner .sub[b-am6wtpdveo] {
    font-size: 0.78rem;
    color: #7a6420;
    font-variant-numeric: tabular-nums;
}

.mi-winner .big[b-am6wtpdveo] {
    font-size: 1.65rem;
    font-weight: 800;
    color: #1f7a4d;
    font-variant-numeric: tabular-nums;
}

/* leaderboard rows */
.mi-row[b-am6wtpdveo] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0.25rem;
    border-bottom: 1px solid #f1f4f9;
}

.mi-row:last-child[b-am6wtpdveo] {
    border-bottom: none;
}

.mi-row .rk[b-am6wtpdveo] {
    width: 24px;
    flex: 0 0 24px;
    text-align: center;
    font-weight: 800;
    color: #9aa6b6;
}

.mi-row.top2 .rk[b-am6wtpdveo],
.mi-row.top3 .rk[b-am6wtpdveo] {
    color: #b8860b;
}

.mi-row .av[b-am6wtpdveo] {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #2e6fa9;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.74rem;
    flex: 0 0 auto;
}

.mi-row .who[b-am6wtpdveo] {
    min-width: 0;
    flex: 1;
}

.mi-row .who .nm[b-am6wtpdveo] {
    font-weight: 700;
    font-size: 0.85rem;
    color: #24364d;
}

.mi-row .who .meta[b-am6wtpdveo] {
    font-size: 0.72rem;
    color: #6c7a8c;
    font-variant-numeric: tabular-nums;
}

.mi-spark[b-am6wtpdveo] {
    flex: 0 0 auto;
}

.mi-spark .sp[b-am6wtpdveo] {
    stroke: #2e9c63;
    stroke-width: 2;
    fill: none;
}

.mi-row .delta[b-am6wtpdveo] {
    flex: 0 0 auto;
    width: 64px;
    text-align: right;
    font-weight: 800;
    font-size: 1rem;
    color: #1f7a4d;
    font-variant-numeric: tabular-nums;
}

.mi-row .delta.neg[b-am6wtpdveo] {
    color: #b1432f;
}

.mi-row .delta small[b-am6wtpdveo] {
    display: block;
    font-size: 0.62rem;
    color: #6c7a8c;
    font-weight: 400;
}

/* distribution chart */
.mi-chart[b-am6wtpdveo] {
    position: relative;
    height: 240px;
}

.mi-dist-note[b-am6wtpdveo] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin: 0.75rem 0.1rem 0;
}

.mi-dist-note b[b-am6wtpdveo] {
    color: #1f3f5e;
}

/* celebrate banner */
.mi-msg[b-am6wtpdveo] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: linear-gradient(90deg, #eef6ff, #f6fbff);
    border: 1px solid #cfe1f4;
    border-radius: 0.75rem;
    padding: 0.9rem 1.1rem;
    color: #274a6b;
    font-size: 0.85rem;
    margin-bottom: 1rem;
}

.mi-msg .ic[b-am6wtpdveo] {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: #cfe6ff;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    line-height: 1;
}

.mi-msg .q[b-am6wtpdveo] {
    font-size: 0.95rem;
    font-weight: 700;
    color: #1f3f5e;
}

.mi-note[b-am6wtpdveo] {
    font-size: 0.72rem;
    color: #9aa6b6;
    margin-top: 0.5rem;
}

@media (max-width: 900px) {
    .mi-grid[b-am6wtpdveo] {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 820px) {
    .mi-tiles[b-am6wtpdveo] {
        grid-template-columns: repeat(2, 1fr);
    }
    .mi-head-actions[b-am6wtpdveo] {
        margin-left: 0;
    }
}

@media (max-width: 480px) {
    .mi-tiles[b-am6wtpdveo] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/MyNights.razor.rz.scp.css */
/* #684 -> IR-S4 (portal IA refresh): the player "Me" home, now THINNED to an account-level
   surface. Mobile-first, the same centred card column + visual tokens as the /me recap
   (PersonalRecap.razor.css) — one shared language, no new brand (navy #16324f, blue #1b6ec2,
   off-white cards). Holds: an identity header, a cross-club recent-nights strip (an EVENT list,
   no ratings), account items, and one muted future-surface line. The per-club rating card +
   Stats/History tabs relocated to the club (IR-S3); their styles were removed with them. */

.my-shell[b-fkgdhhlk14] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

.me-shell[b-fkgdhhlk14] {
    padding-top: 1.1rem;
}

/* #82 (Slice 2): one-time "you're connected" success banner (green chip family). */
.me-connected-banner[b-fkgdhhlk14] {
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #14532d;
    border-radius: 0.6rem;
    padding: 0.7rem 0.95rem;
    font-size: 0.92rem;
    font-weight: 600;
    margin-bottom: 1rem;
}

/* ── Empty state (fresh claimer with no nights yet). ── */
.my-empty[b-fkgdhhlk14] {
    font-size: 0.95rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
    margin-bottom: 2rem;
}

/* ── Identity header (recognition only; no rating number here — ADR-0011). ── */
.me-profile[b-fkgdhhlk14] {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 1.25rem;
    text-align: left;
}

.me-profile-avatar[b-fkgdhhlk14] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 50%;
    background: #0d2c55;
    color: #fff;
    font-weight: 700;
    font-size: 1.1rem;
    flex: 0 0 auto;
}

.me-profile-identity[b-fkgdhhlk14] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

/* The page <h1> (a11y). Reset the browser heading margin/size so it stays the recognition
   line it visually was — the identity block, not a banner heading. */
.me-profile-name[b-fkgdhhlk14] {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 800;
    color: #16324f;
    line-height: 1.2;
}

.me-profile-sub[b-fkgdhhlk14] {
    font-size: 0.85rem;
    color: #5e748a;
}

/* ── Section titles (uppercase eyebrow). ── */
.me-section-title[b-fkgdhhlk14] {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 1.75rem 0 0.7rem;
    font-weight: 700;
}

.me-section-note[b-fkgdhhlk14] {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 600;
    color: #8496a8;
}

/* ── Cross-club recent-nights strip: horizontally-scrolling EVENT chips (date + club, no
      rating). Each chip is a link to that session's shared recap. ── */
.me-recent-strip[b-fkgdhhlk14] {
    display: flex;
    gap: 0.6rem;
    overflow-x: auto;
    padding-bottom: 0.35rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.me-recent-chip[b-fkgdhhlk14] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    flex: 0 0 auto;
    min-width: 7.5rem;
    padding: 0.7rem 0.85rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.me-recent-chip:hover[b-fkgdhhlk14],
.me-recent-chip:focus-visible[b-fkgdhhlk14] {
    border-color: #1b6ec2;
    box-shadow: 0 6px 18px rgba(27, 110, 194, 0.12);
}

.me-recent-when[b-fkgdhhlk14] {
    font-size: 0.95rem;
    font-weight: 800;
    color: #16324f;
    font-variant-numeric: tabular-nums;
}

.me-recent-club[b-fkgdhhlk14] {
    font-size: 0.85rem;
    color: #5e748a;
}

/* Same-day tiebreaker line (start time) — only rendered on chips whose date collides. */
.me-recent-detail[b-fkgdhhlk14] {
    font-size: 0.8rem;
    color: #5e748a;
    font-variant-numeric: tabular-nums;
}

/* ── Account items (Edit profile) — full-width rows. ── */
.me-acct-item[b-fkgdhhlk14] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    text-align: left;
    padding: 0.85rem 1rem;
    margin-bottom: 0.5rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    color: #16324f;
    text-decoration: none;
    font: inherit;
    cursor: pointer;
    transition: border-color 0.12s ease;
}

.me-acct-item:hover[b-fkgdhhlk14],
.me-acct-item:focus-visible[b-fkgdhhlk14] {
    border-color: #1b6ec2;
}

/* Keyboard-focus ring — the same box-shadow treatment as .me-recent-chip:focus-visible, so the
   account rows and the recent-nights chips share one consistent focus look. */
.me-acct-item:focus-visible[b-fkgdhhlk14] {
    box-shadow: 0 6px 18px rgba(27, 110, 194, 0.12);
}

.me-acct-body[b-fkgdhhlk14] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1 1 auto;
    min-width: 0;
}

.me-acct-title[b-fkgdhhlk14] {
    font-weight: 700;
    font-size: 0.98rem;
}

.me-acct-meta[b-fkgdhhlk14] {
    font-size: 0.82rem;
    color: #5e748a;
}

.me-acct-go[b-fkgdhhlk14] {
    font-size: 1.2rem;
    color: #9aacbe;
    flex: 0 0 auto;
}

/* ── The reserved future account surface — one muted line, not "coming soon" rows (IR·11). ── */
.me-account-note[b-fkgdhhlk14] {
    margin: 0.85rem 0 0;
    color: #5e748a;
    font-size: 0.85rem;
    line-height: 1.45;
}
/* /Components/Pages/MyPerformance.razor.rz.scp.css */
/* SPEC-32 I2-S12 (#314), AC-I2-S12-11: the self-performance page's SHELL chrome.

   THIS FILE'S ABSENCE WAS A SHIPPED DEFECT, and it is fixed here because this slice's own chrome sits
   inside the shell it is missing. Blazor CSS isolation is per-component, so `.my-shell` / `.my-backbar`
   / `.my-back` / `.my-empty` are NOT inherited from anywhere: every sibling player page carries its own
   scoped copy (PlayerClubDetail, MyNights, PlayerClubs, PlayerClubSessions, PlayerFixtures, Account,
   CreateClub, and ClubmateProfile — whose own header records the convention). MyPerformance shipped
   without one, so on the SELF lens the 504px centred column, the 44px back-link target and the styled
   empty state simply did not apply, while the clubmate page — the same profile, the other lens — had
   all three.

   That is the pre-existing half of AC-I2-S12-11. The slice-specific half is that the view strip renders
   INSIDE `.my-shell`, so without this the strip would be full-viewport-wide on the self page and 504px
   on the clubmate page — the same control, two shapes, on the two lenses this increment exists to keep
   identical (R-I2-14's one-shape rule, generalised from rows to views).

   DELIBERATELY BYTE-IDENTICAL TO ClubmateProfile.razor.css, not "similar". The criterion is that the
   content column width, the back-link presentation and the strip's position are IDENTICAL on the two
   lenses at the same viewport, and the cheapest way to make that true — and to keep it true — is for
   the two files to be the same declarations. Same shared player language; NO new brand.

   THAT IS NOW BYTE-IDENTICAL PLUS EXACTLY ONE RULE (`.my-page-title`, at the foot of this file), and
   the criterion above is what says the divergence is allowed: it names three things — column width,
   back-link presentation, strip position — and a page-heading rule touches none of them. The two
   lenses diverge here because on 2026-09-01 the Owner ruled the identity block off the SELF lens, so
   the two pages no longer agree about what NAMES the page: the clubmate page is named by the identity
   block it still has, and this one needs a visible heading instead. Everything the criterion actually
   protects stays the same declarations, and a future edit to the shared three must still be made in
   both files.

   THAT EXCEPTION IS STILL EXACTLY ONE, AND SPEC-32 I3-S0 (#677) IS THE FIRST EDIT TO PROVE IT. The
   Owner's width ruling changes THE FIRST THING THE CRITERION NAMES — the content column width — so it
   is the one kind of change this contract exists to catch, and it landed in both files in the same
   edit: the `@media (min-width: 821px)` block beneath `.my-shell` is the same declarations here and in
   ClubmateProfile.razor.css. This note is amended rather than followed by a second one, because two
   stacked "and now also" notes is how a contract stops being read. The count to remember is unchanged:
   ONE allowed divergence, `.my-page-title`, and everything else in this file is the sibling's. */

.my-shell[b-pwaspg2w4d] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* SPEC-32 I3-S0 (#677), R-I2-40: WHERE THE PROFILE RENDERS A TABLE, ITS COLUMN IS AS WIDE AS THE TABLE
   NEEDS. Owner ruling, 2026-09-02: "on desktop, we should definately be wider - why would we not be?"

   THE 34rem ABOVE IS A READING MEASURE AND IT DOES NOT GOVERN DATA. It applies at EVERY viewport, so a
   record view rendered a table needing ~705px inside a 478px wrapper at a 1440px viewport with ~1,400px
   of screen empty either side. The two slices before this one took the COLUMN SET as the variable and
   cut three columns; the container was the variable. `MemberSessionHistoryTable.razor.css` carried the
   disproof in its own comment the whole time - the clip and then the scrollbar arose "in a container
   NARROWER than that ... at a desktop viewport" and were a "No-op in the wide admin modal / kiosk panel".

   53rem IS MEASURED, NOT CHOSEN, AND HERE IS THE MEASUREMENT (qa-perf-club-mk, both lenses, 2026-09-02).
   The shell was swept in 4px steps and the BLOCK'S HEIGHT recorded at each step. Height falls in steps
   as columns stop wrapping and then plateaus; the first width on the plateau is the width that table
   needs, and it is an observation rather than a preference.

       view        needs   table    block height off the plateau -> on it
       Nights      840px   771px    5130px -> 1988px   <- the widest since I3-S1, +92px on I3-S0's 748
       Games       776px   705px    7630px -> 2253px   <- was the widest; unchanged, and re-measured
       Partners    592px   441px    24577px -> 11193px  <- I3-S3; was <520px / 403px / flat
       Opponents   592px   419px    24577px -> 11193px  <- I3-S3; was <520px / 403px / flat
       Overview    -       -        no table

   Corroborated by the other measure, taken the same day at 1920px: each table's max-content plus the
   horizontal chrome between the shell's border box and the wrapper's content box - Nights 770.73 + 66,
   Games 704.73 + 68, the counterparts 440.63 + 66 (Partners) and 419.28 + 66 (Opponents) since I3-S3.

   THE TWO COUNTERPART MEASURES DISAGREE BY 85px AND THE SWEEP IS THE ONE THAT BINDS. max-content puts
   Partners at 506.63px of shell; the sweep says 592px. Both are right about different things: these two
   tables are `table-layout: fixed` with STATED allocations (4 x 4.2rem numeric, 8rem for the date), so
   what the layout needs is the sum of the allocations and not the content's natural max-content. The
   sweep measures the rendering; max-content measures the text. Where a table states its widths, prefer
   the sweep - and the other two views, which are auto-layout, still agree to within a 4px step.

   53rem = 848px clears the widest by 8px, which is I3-S0's margin kept rather than a new one. It is a
   CAP, not a width: `margin: 0 auto` keeps the shell centred and it never exceeds the viewport. A wider
   cap would be a number nobody measured; a narrower one would wrap the Nights row this number exists to
   unwrap. RE-MEASURE IT WHEN A COLUMN IS ADDED OR REMOVED (R-I2-40.1).

   IT MOVED FROM 49rem BECAUSE I3-S1 (#669) PUT A COLUMN BACK, and that is the requirement working as
   written rather than a correction. The Owner ruled the time at the club back onto the session rows;
   `At Club` cost the Nights table 91.46px of max-content, which took it past Games and made Nights the
   binding view. The binding view is a measurement too, and it is expected to change hands.

   IT DID NOT MOVE FOR I3-S3 (#670), AND THAT IS RECORDED BECAUSE THE RE-MEASUREMENT IS WHAT R-I2-40.1
   ASKS FOR - NOT THE CHANGE. The Owner ruled the last day played back onto the counterpart rows; those
   two tables went from needing under 520px of shell to needing 592px, which is 256px inside a cap the
   Nights view sets at 840px. Nights remains the binding view. A slice that re-measures and finds nothing
   to change has still discharged the requirement; a slice that assumes it has not.

   THE 820px REFLOW DID NOT MOVE, AND THAT WAS CHECKED RATHER THAN ASSUMED (R-I2-40.2). A restored column
   raises a table's min-content as well as its max-content, and if the new min-content had exceeded the
   reflow the breakpoint would have had to rise with it. Measured: the six-column nights table's
   min-content is 545.69px, so 611.69px of shell - 208px inside a breakpoint that was already generous.
   Nothing below 821px changes.

   NOR DID THE COUNTERPART TABLES' OWN 720px REFLOW, checked the same way at I3-S3. Their six-column
   min-content is 332.13px (Partners) / 328.59px (Opponents), which is 398px of shell against a 478px
   wrapper at 720px - so the band between that reflow and the width the columns fit at, which R-I2-39
   says should not exist, still does not. It is `profile.css`'s query, not this file's; change one and
   look at the other.

   THE BREAKPOINT IS 821px AND IT IS THE NIGHTS TABLE'S OWN REFLOW, NOT A NEW NUMBER. Two of the profile's
   tables reflow to stacked cards at 720px and the nights table at 820px, and R-I2-40.6 allows exactly ONE
   width across all five views - the strip renders inside this shell, so a shell that is 504px on the
   summary and wider on a record view moves the strip on every view change. One width plus two reflows
   means the widening starts at the HIGHER of the two: at 821px every one of the four tables is a table,
   and at or below 820px nothing moves at all, which is what keeps the card tier untouched (R-I2-40.3).
   It is deliberately the same 821 as `MemberSessionHistoryTable.razor.css`'s reflow query - change one
   and you must look at the other.

   IT IS NOT KEYED TO THE ACTIVE VIEW, AND MUST NEVER BE. This rule is a function of the viewport alone,
   so the strip's x and width are identical on all five views by construction rather than by care.

   THE SIBLING PORTAL PAGES DO NOT FOLLOW (R-I2-40.5). `/me`, `/clubs`, `/account` and the club pages
   carry their own scoped 34rem copies and keep them: they are stacked cards and prose, where 504px is a
   READING measure, and none of them renders either of these tables. Blazor CSS isolation is what makes
   that safe - this rule is stamped with this page's scope attribute and reaches nothing else.

   IT IS IN TWO FILES ON PURPOSE. MyPerformance.razor.css carries these declarations byte for byte;
   AC-I2-S12-11 names the content column width FIRST, so a width change landing in one lens only is that
   criterion failing rather than a partial delivery. Spec32ProfileViewWiringGuardTests is what fails on
   the day they drift. */
@media (min-width: 821px) {
    .my-shell[b-pwaspg2w4d] {
        max-width: 53rem;
    }
}

/* ── Back bar (the way back to the club overview). ── */
.my-backbar[b-pwaspg2w4d] {
    margin-bottom: 1rem;
}

.my-back[b-pwaspg2w4d] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.my-back:hover[b-pwaspg2w4d],
.my-back:focus-visible[b-pwaspg2w4d] {
    text-decoration: underline;
}

.my-back-caret[b-pwaspg2w4d] {
    font-weight: 700;
}

/* ── Error state (fail-closed shell — Back always present). ── */
.my-empty[b-pwaspg2w4d] {
    color: #5e748a;
    font-size: 0.95rem;
    text-align: center;
    padding: 2rem 1rem;
}

/* ── Page heading (2026-09-01, Owner ruling). ──────────────────────────────────────────────────────
   THE ONE RULE THIS FILE HAS THAT ClubmateProfile.razor.css DOES NOT — see the header for why that is
   allowed rather than drift. The identity block used to name this page; the Owner ruled it off the
   Self lens, so the H1 the page always carried stopped being redundant and became the only thing that
   says where the reader is. It is no longer `visually-hidden`, and these are the declarations that
   make it read as a page heading rather than as unstyled UA `<h1>` (2em, bold, 0.67em margins — which
   would tower over the 0.72rem section titles below it and put the page's biggest type on a two-word
   label).

   THE TYPE IS SHIPPED, NOT CHOSEN. 1.1rem / 800 / #16324f is the portal's page-heading type: it is
   `/me`'s `.me-profile-name` (MyNights.razor.css) declaration-for-declaration, and Account.razor's
   comment records that `.my-backbar-title` is "already pixel-identical" to that same class. So this
   invents no size, no weight and no colour.

   IT IS NOT NAMED `.my-backbar-title`, DELIBERATELY. That class means one specific thing across
   Account / PlayerClubs / CreateClub — a title absolutely positioned and centred ACROSS the back bar,
   which those pages enable by making `.my-backbar` `position: relative; display: flex`. This page's
   `.my-backbar` is neither, its back link reads "Back to {club name}" at full club-name length, and
   the Owner's sketch puts the heading on its own line beneath the bar. Reusing the name with different
   declarations would leave one class meaning two treatments — which is how the next reader styles the
   wrong one — so it gets its own name and the shared type.

   THE MARGIN IS BOTTOM-ONLY, AND THE BOTTOM HALF IS LOAD-BEARING. Above it, `.my-backbar` already
   carries `margin-bottom: 1rem`, so a top margin here would stack a second gap against it — hence 0.
   Below it there is NOTHING to stack against and that is the trap: `.profile-render` is a flex column
   whose `gap` applies only BETWEEN its own children (the heading is not one of them), and the strip's
   `.cs-seg` / `.profile-view-seg` margins are `margin-bottom` only. With no bottom margin here the
   heading would sit flush against the strip. `0.85rem` is `.profile-render`'s own gap, so the space
   under the heading matches the space between every pair of sections below it.

   `line-height: 1.2` matches the shipped class. */
.my-page-title[b-pwaspg2w4d] {
    margin: 0 0 0.85rem;
    font-size: 1.1rem;
    font-weight: 800;
    color: #16324f;
    line-height: 1.2;
}
/* /Components/Pages/NearMe.razor.rz.scp.css */
/* SPEC-35 Slice B1 (#17) — /directory/near-me. Scoped per component (the PegboardWeb per-page
   .razor.css pattern), so every token used is defined here.

   ══════════════════════════════════════════════════════════════════════════════════════════════
   COPIED TOKEN BLOCK — DO NOT EDIT WITHOUT READING THIS.

   Source:  Components/Pages/PlayerClubs.razor.css, copied 2026-08-25 for SPEC-35 B1.
   Why the PlayerClubs variant specifically: it is the closest surface — a list of club cards — so
   where a token has drifted across the eight scoped sheets that carry it, its reading is the one
   this page should match.

   COPIED, NOT LIFTED, DELIBERATELY. A lift is not a refactor here: it is a visual change to at
   least five SHIPPED pages, because four tokens have genuinely divergent variants and lifting picks
   one winner per token. /account would get a different card radius and a blue-not-grey secondary
   button; /clubmate/* would get a bordered panel where it has centred plain text; /me would lose a
   2rem gap; three pages would gain display:flex + position:relative on a back bar that never had
   them. That is a design reconciliation owned by the ux-designer, not a slice's call. The lift is
   filed as its own slice: reconcile the drifted tokens with the designer, lift the reconciled set,
   delete the copies, re-verify every player page at four widths.

   TOKENS WITH KNOWN VARIANTS ELSEWHERE (measured 2026-08-25 across every scoped sheet):
     .my-card            3 copies, 2 variants — Account radius 0.7 vs 0.75rem; CreateClub margin 1 vs 1.25rem
     .my-btn-secondary   2 copies, 2 variants — Account border grey #cdd9e5 vs PlayerClubs blue #1b6ec2
     .my-backbar/.my-back 7 copies, 2 variants — flex+relative+z-index in 4, margin-only in 3
   Byte-identical everywhere, so safe to copy as-is: .my-btn, .my-btn-primary, .my-btn-block.
   .my-link exists in ONE other sheet; this is the second copy.

   ⚠ WHAT THIS FILE DOES *NOT* COPY, listed because an inventory that overstates itself is worse than
   none — a later lift would go looking for rules that were never here (corrected 2026-08-26):
     .my-card-title  NOT copied and NOT defined. B1's only card is the empty-state door, whose
                     heading is its own `.near-me-door-title`.
     .my-empty       NOT copied and NOT defined. Its soft-panel TREATMENT (#f6f9fc on #d9e6f2,
                     0.6rem) is inlined into `.near-me-legend`, which is not an empty state — so it
                     is a borrowed look, not a copy of the token, and a lift of `.my-empty` must not
                     assume this page follows it.
     .my-shell       The RULE is copied; the CLASS NAME is not used. B1's wrapper is `.near-me`, so
                     a global `.my-shell` lift would leave this page's measure behind unless the
                     lifter also re-points the wrapper. That is the one entry a later lift is most
                     likely to get wrong, which is why it is called out rather than left implied.

   THE .clubs-* FAMILY BELOW IS A SECOND COPIED BLOCK, from the same source and on the same terms:
   .clubs-list / -row / -row-top / -row-body / -row-name / -row-meta / -badge / -banner /
   -banner-error / -retry. AND .clubs-role-badge IS NOT COPIED VERBATIM — it is the pill SHAPE with
   the role palette dropped, because B1's chip must be neutral (R11: a coloured chip reads as an
   endorsement of the club). It is therefore a MODIFIED COPY FROM BIRTH and is renamed
   `.near-me-chip` rather than left wearing a name whose source rule it no longer matches.

   B1 builds to the SHIPPED PLAYER TOKENS, not marketing.css. The forward mockup is painted in
   marketing.css (Plus Jakarta Sans, 18px radii, soft shadows, navy #1f3d5b) because ADR-0007 puts
   /directory/* on www; the shipped player pages use system-ui, 0.75rem/0.55rem radii, no shadows,
   navy #16324f. B1 is noindex and non-public, so nothing here turns on the marketing look, and
   deciding it would pre-empt Slice F — which is the actual SEO surface, and where it genuinely bites.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ══ THIS RULE COMES FIRST, BEFORE ANY PANEL GETS A `display`. ════════════════════════════════
   `[hidden] { display: none }` comes from the USER-AGENT stylesheet, and a UA rule loses to ANY
   author `display` declaration — specificity does not enter into it. The AC11 panel is a block with
   a heading, five cause lines, a form and a paragraph, and it carries `display: flex` for its
   layout. On the UA rule alone, `hidden` would stop hiding it and ALL FIVE CAUSES WOULD RENDER AT
   ONCE, ON FIRST PAINT, FOR EVERY VISITOR — while `toHaveAttribute('hidden')` passed and every text
   assertion passed too, because the element and its text are genuinely there.

   ⚠ CORRECTION TO THE BRIEF THIS SLICE WAS BUILT FROM, found by PLANTING THE MUTANT rather than by
   reading. The brief stated "there is no [hidden] rule anywhere in this repo" and treated
   connect-search.js as safe only by accident. Both are FALSE. Bootstrap 5's Reboot ships
   `[hidden] { display: none !important; }` (wwwroot/lib/bootstrap/dist/css/bootstrap.css:594) and is
   linked GLOBALLY on every page (App.razor:20). An `!important` author declaration beats every
   non-important author declaration regardless of specificity or source order, so the hazard is
   already closed app-wide — deleting the rule below changed nothing, and the whole E2E suite stayed
   green against the mutant.

   IT IS KEPT ANYWAY, and the reason is specific rather than defensive. ADR-0007 commits /directory/*
   to move under `www`, and B1.12 explicitly does NOT reuse a single Bootstrap class — so this page's
   correctness must not depend on a global sheet it is on a path to leave behind. What the rule buys
   is HOST-INDEPENDENCE, and that is what is asserted: NearMeScopedStyleGuardTests reads THIS FILE
   and requires the rule, because a behavioural test cannot distinguish "this page hides it" from
   "Bootstrap hides it for every page". The E2E's computed-visibility assertions stay as the
   behavioural net either way — presence is not application, whichever sheet supplies the rule.
   ═════════════════════════════════════════════════════════════════════════════════════════════ */
[hidden][b-r9azhi2oq9] {
    display: none !important;
}

/* ── Shell. Phone-first, centred column. The RULE is byte-identical to the eight shipped `.my-shell`
     copies; the CLASS is this page's own, because B1's wrapper is `.near-me` (see the header note). ── */
.near-me[b-r9azhi2oq9] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (PlayerClubs variant: flex + relative + z-index). ── */
.my-backbar[b-r9azhi2oq9] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-r9azhi2oq9] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-r9azhi2oq9],
.my-back:focus-visible[b-r9azhi2oq9] {
    text-decoration: underline;
}

.my-back-caret[b-r9azhi2oq9] {
    font-weight: 700;
}

/* `.my-backbar-title` is deliberately NOT copied — the one token from the borrowed back-bar that this
   page does not take. It is absolutely positioned and centred across the whole bar, which only works
   when the back link is short and nothing else claims the heading role. Here the link reads "Start
   again" and an <h1> follows immediately, so the centred title overlapped the link at 360px and
   duplicated the heading beneath it. See the markup comment in NearMe.razor. The back link keeps
   `z-index: 1` below purely as part of the copied rule; with no absolute sibling it is inert, and it
   is left in place so the block stays a faithful copy rather than a subtly edited one. */

/* ── Cards (PlayerClubs variant: 0.75rem radius, 1.25rem bottom margin). ── */
.my-card[b-r9azhi2oq9] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1.25rem;
}

/* ── Buttons. min-height 44px is already in the token — a touch target, not decoration. ── */
.my-btn[b-r9azhi2oq9] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-r9azhi2oq9] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-r9azhi2oq9],
.my-btn-primary:focus-visible[b-r9azhi2oq9] {
    background: #155ba3;
}

/* PlayerClubs variant: blue border, not Account's grey #cdd9e5. */
.my-btn-secondary[b-r9azhi2oq9] {
    background: #fff;
    color: #1b6ec2;
    border-color: #1b6ec2;
}

.my-btn-secondary:hover[b-r9azhi2oq9],
.my-btn-secondary:focus-visible[b-r9azhi2oq9] {
    background: #f2f8fe;
}

.my-btn-block[b-r9azhi2oq9] {
    display: flex;
    width: 100%;
}

/* A busy button (near-me.js) keeps its size and loses its affordance — never a full-page spinner
   and never a skeleton: nothing else on the page is waiting. */
.my-btn[disabled][b-r9azhi2oq9],
.my-btn[aria-busy="true"][b-r9azhi2oq9] {
    opacity: 0.72;
    cursor: progress;
}

/* ── Links. ── */
.my-link[b-r9azhi2oq9] {
    color: #006bb7;
    text-decoration: none;
    font-weight: 700;
    white-space: nowrap;
}

.my-link:hover[b-r9azhi2oq9],
.my-link:focus-visible[b-r9azhi2oq9] {
    text-decoration: underline;
}

/* ── Club rows (copied .clubs-* block). ── */
.clubs-list[b-r9azhi2oq9] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.clubs-row[b-r9azhi2oq9] {
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    padding: 0.7rem 0.85rem;
    background: #fff;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.clubs-row-top[b-r9azhi2oq9] {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
}

.clubs-badge[b-r9azhi2oq9] {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: #0d2c55;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 0.95rem;
}

.clubs-row-body[b-r9azhi2oq9] {
    flex: 1 1 auto;
    min-width: 0;
}

.clubs-row-name[b-r9azhi2oq9] {
    font-weight: 700;
    color: #16324f;
    overflow-wrap: break-word;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.clubs-row-meta[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

/* ── Banners (error only on this page). ── */
.clubs-banner[b-r9azhi2oq9] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    margin: 0.85rem 0 0;
}

.clubs-banner-error[b-r9azhi2oq9] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.clubs-retry[b-r9azhi2oq9] {
    flex: 0 0 auto;
    color: #9a2222;
    font-weight: 700;
    text-decoration: underline;
    white-space: nowrap;
}

.clubs-retry:hover[b-r9azhi2oq9],
.clubs-retry:focus-visible[b-r9azhi2oq9] {
    color: #7a1717;
}

/* ══ B1's own rules. ══════════════════════════════════════════════════════════════════════════ */

.near-me-title[b-r9azhi2oq9] {
    font-size: 1.35rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.5rem;
}

.near-me-lead[b-r9azhi2oq9] {
    color: #5e748a;
    margin: 0 0 0.4rem;
    font-size: 0.95rem;
}

.near-me-trust[b-r9azhi2oq9] {
    color: #47586b;
    font-weight: 700;
    margin: 0 0 1.25rem;
    font-size: 0.95rem;
}

.near-me-form[b-r9azhi2oq9] {
    margin: 0 0 1rem;
}

/* Screen 2's count line is the page's h1 — the answer, not a label. */
.near-me-count[b-r9azhi2oq9] {
    font-size: 1.2rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.7rem;
    font-variant-numeric: tabular-nums;
}

/* The legend. Soft panel (the .my-empty token's treatment), because it explains the chips rather
   than warning about them. */
.near-me-legend[b-r9azhi2oq9] {
    font-size: 0.9rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.7rem 0.85rem;
    margin: 0 0 0.9rem;
}

/* THE STATUS CHIP. A MODIFIED COPY of .clubs-role-badge — the pill shape, with the role palette
   deliberately dropped for a neutral one. Both renderings are visually IDENTICAL apart from their
   text: no green, no red, no tick. A green tick on "On ePegboard" reads as an endorsement of the
   CLUB, which is R11's precise failure mode; and the negative must not read as a warning about a
   club whose only offence is not being our customer. */
/* `text-transform: uppercase` and `letter-spacing: 0.04em` came across with the borrowed pill and
   were DROPPED (2026-08-26, UX review). They were right for `.clubs-role-badge`, which labels a role
   in a list the player already belongs to; they are wrong here. An all-caps micro-label carries more
   alert weight than sentence case at identical colour and size, so the shape was quietly escalating
   the one element the plan worked hardest to keep neutral — and it escalated BOTH renderings, which
   means the negative chip read as a warning about a club whose only offence is not being our
   customer. The wireframe shows plain bracketed text. Sentence case is what "visually equal weight,
   no green, no red, no tick" actually looks like. */
.near-me-chip[b-r9azhi2oq9] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    background: #e6eef7;
    color: #16324f;
    white-space: nowrap;
}

.near-me-freshness[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.85rem;
    margin-top: 0.25rem;
}

/* ── R28's UNCONFIRMED BLOCK. It occupies the freshness slot, at the freshness line's own size and
     colour, and it is not a badge, a panel, a pill or an alert.

   THIS IS NOT A RARE STATE AND MUST NOT BE STYLED AS ONE. Measured on play.test 2026-08-26: 6,117
   entries, 3,276 with evidence — so a typical list is roughly 55% evidenced / 45% unevidenced. A
   treatment tuned as an exception (an amber panel, an icon, a coloured pill) fires on nearly every
   other row and is noise within one screenful. The correct visual budget is roughly what the line it
   replaces already costs.

   AMBER AND RED ARE DISQUALIFIED OUTRIGHT, not merely avoided. A colour that means *caution* is a claim
   about the CLUB, and R28's whole requirement is that the statement is about US. R18 cuts both ways:
   absence of evidence is not evidence, in either direction — we did not observe this club closing, we
   observed nothing at all.

   THE TWO NON-COLOUR SIGNALS, which is what satisfies R28(a) / WCAG 1.4.1:
     1. SHAPE — the border-top hairline below, which the evidenced card does not have.
     2. TEXT  — a bold lead-in word, `Unconfirmed`, in a slot that otherwise opens with a verb phrase.
   Neither is a hover, a tap, or a colour; remove either and the state is still distinguishable in
   greyscale at arm's length.

   ⚠ THE UX PLAN CLAIMED THREE SIGNALS AND THIS SHIPS TWO, deliberately and on record. Its third was
   "a second line the evidenced card never has" — which WAS the claim-link row. The Owner ruled R28(c)
   ships with no CTA while the correction path is operator-driven (#491), so that line is absent. Both
   surviving signals are non-colour, so 1.4.1 still holds with margin; what is lost is the plan's
   "remove any two and it is still distinguishable". If a third is ever wanted, it must not be a colour
   and must not cost horizontal space (see below).

   WHY A TOP HAIRLINE AND NOT A LEFT RULE — measured, not preferred. A left rule costs ~13px of a
   ~175px text column at 360px / 125% zoom (the body is already indented past the 2.1rem badge), which
   pushes the sentence to five lines on ~45% of rows. A top hairline costs ZERO horizontal space at
   every width. That is the whole argument, and it is why this block takes no indent either. ── */
/* ⚠ THE HAIRLINE'S COLOUR IS A WCAG 1.4.11 CONSTRAINT, NOT A TASTE DECISION, and it started wrong.
   It first shipped as #e2e8f0 — the card-border grey — which computes to roughly 1.2:1 against the
   card's white. 1.4.11 wants 3:1 for a graphical object that is required to understand the content,
   and this rule is precisely that: with only two non-colour signals left after the no-CTA ruling, a
   hairline nobody can see is one of the two doing no perceptual work. It also disappeared into the
   0.55rem gap between cards.

   #7d8ea3 computes 3.35:1 against #fff (relative luminance 0.263; 1.05 / 0.313). Asserted, not
   asserted-to-be-asserted: NearMeScopedStyleGuardTests computes the ratio from this declaration and
   fails below 3.0, so a later "soften that line" edit is a red build rather than a silent regression.

   It stays COOL — red channel below blue — and that is also asserted. A warm hairline would be a
   caution colour, and a caution colour is a claim about the club that R18 says we cannot make in
   either direction. #7d8ea3 sits between the page's existing #5e748a body ink and #94a3b8; it is
   darker than a hairline usually wants to be, and that is the price of 1.4.11. */
.near-me-unconfirmed[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.85rem;
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px solid #7d8ea3;
}

/* Sentence-case, NEVER all-caps. The B1 review already found that all-caps at identical size and colour
   escalates alert weight, and quietly escalated the one element that plan worked hardest to keep
   neutral (`.near-me-chip`, below). Same lesson, same page. #47586b is the page's existing secondary
   ink (`.near-me-legend`, `.near-me-cause`) — a lift within the muted range, not a new colour. */
.near-me-unconfirmed strong[b-r9azhi2oq9] {
    font-weight: 700;
    color: #47586b;
}

/* At most ONE action per card, >= 8px from anything else tappable. */
.near-me-action[b-r9azhi2oq9] {
    align-self: flex-start;
    margin-left: 2.8rem; /* align under the row body, past the badge */
}

/* ⚠ `flex-wrap: wrap` IS A DEFECT FIX, MEASURED, NOT A TIDY-UP — and `white-space: normal` alone was
   not enough, which is the finding.

   MEASURED 2026-08-26 at 360px / 125% zoom (288 effective CSS px), by looking at the rendered page:
   document scrollWidth 338 against clientWidth 288 — FIFTY PIXELS of horizontal overflow — and the
   widest laid-out element was `.my-link.near-me-action.near-me-external` at 259px.

   WHY `white-space: normal` DID NOT COVER IT. This link is `display: inline-flex` with three children
   (label, host, arrow). `white-space` governs wrapping WITHIN a text run; it says nothing about whether
   a flex CONTAINER may break between its items, and a flex line does not wrap without `flex-wrap`. So
   the row stayed on one line at any width — "Their website  shenleybc.org.uk  ↗" — while the
   declaration that was supposed to prevent exactly this sat in the rule, applying, and doing nothing.
   The UX plan predicted this collision for the CLAIM link and prescribed `white-space: normal` as the
   cure; the claim link did not ship (Owner, R28(c) as amended), and the collision turned out to be
   live on the token's other user, where that cure was already present and insufficient.

   WHY IT SURFACED NOW rather than in B1. It is B1's bug, not this slice's — but B1 could not reach it:
   under the struck evidence rule the empty state was the only state real data could render, so no
   Results screen was ever drawn at 288px with an outbound link on it. R28 is what makes the row
   reachable, which puts the fix in this slice.

   `.near-me-action`'s 2.8rem left indent is deliberately LEFT ALONE. It aligns the action under the row
   body, past the badge, and removing it to buy horizontal room would break that alignment on every
   width to fix one. Wrapping is the cheaper correction and it is the one the measurement supports. */
.near-me-external[b-r9azhi2oq9] {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    min-height: 44px;
    white-space: normal;
}

/* The host, rendered as a fact rather than an advert. */
.near-me-host[b-r9azhi2oq9] {
    color: #5e748a;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* The outbound arrow. It sits INSIDE `.near-me-host` with NO whitespace text node before it, and takes
   its gap from this margin instead — so there is no break opportunity between the host and its arrow,
   and the arrow cannot be orphaned onto a line of its own. That is not hypothetical: it happened at
   360px/125% the moment `.near-me-external` gained `flex-wrap: wrap`, and the screenshot showed a lone
   arrow under the host. `margin-left` rather than a `&nbsp;` because a non-breaking space is invisible
   in the source and the next person to touch this line would delete it. */
.near-me-host-arrow[b-r9azhi2oq9] {
    margin-left: 0.35rem;
}

.near-me-door[b-r9azhi2oq9] {
    text-align: center;
}

.near-me-door-title[b-r9azhi2oq9] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.05rem;
    margin: 0 0 0.2rem;
}

.near-me-door-desc[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.9rem;
    margin: 0 0 0.8rem;
}

.near-me-again[b-r9azhi2oq9] {
    margin-top: 1.25rem;
}

.near-me-invite[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.9rem;
    margin: 0.9rem 0 0;
}

/* ── AC11's panel. NOTE the `display` below is exactly what the [hidden] rule at the top of this
     file exists to survive; without that rule this declaration renders all five causes on first
     paint for every visitor while every attribute and text assertion still passes. ── */
.near-me-problem[b-r9azhi2oq9] {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 1rem 1.05rem;
    margin: 0 0 1rem;
}

.near-me-problem:focus[b-r9azhi2oq9] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

.near-me-problem-title[b-r9azhi2oq9] {
    font-size: 1.05rem;
    font-weight: 800;
    color: #16324f;
    margin: 0;
}

.near-me-cause[b-r9azhi2oq9] {
    color: #47586b;
    font-size: 0.95rem;
    margin: 0;
}

.near-me-unblock[b-r9azhi2oq9] {
    color: #5e748a;
    font-size: 0.85rem;
    margin: 0;
}

/* Wider viewports: the column stays a column. This surface is phone-first and a 34rem measure is
   the right one for a scan-and-tap list at any width — widening it would make the distance, which
   is the spine of the page, travel further from the name it belongs to. */
@media (min-width: 48rem) {
    .near-me-title[b-r9azhi2oq9] {
        font-size: 1.5rem;
    }

    .near-me-count[b-r9azhi2oq9] {
        font-size: 1.35rem;
    }
}
/* /Components/Pages/NewMemberConversionReport.razor.rz.scp.css */
.reports-shell[b-shjkj423xj] {
    max-width: 1180px;
    padding-bottom: 2.5rem;
}

.reports-crumb[b-shjkj423xj] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-shjkj423xj] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-shjkj423xj],
.reports-crumb-link:focus-visible[b-shjkj423xj] {
    text-decoration: underline;
    outline: none;
}

.nmc-head[b-shjkj423xj] {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.nmc-head h1[b-shjkj423xj] {
    margin: 0;
    color: #1f3f5e;
}

.nmc-sub[b-shjkj423xj] {
    color: #3d5a78;
    margin: 0.2rem 0 0;
}

.nmc-head-actions[b-shjkj423xj] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.nmc-ranges[b-shjkj423xj] {
    display: flex;
    gap: 0.35rem;
    background: #eef3f9;
    border: 1px solid #d8e2ee;
    border-radius: 0.6rem;
    padding: 0.2rem;
}

.nmc-ranges button[b-shjkj423xj] {
    border: none;
    background: none;
    color: #4a5b70;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.4rem 0.8rem;
    border-radius: 0.45rem;
    cursor: pointer;
}

.nmc-ranges button.on[b-shjkj423xj] {
    background: #ffffff;
    color: #1f3f5e;
    box-shadow: 0 1px 3px rgba(20, 40, 70, 0.12);
}

.nmc-ranges button:disabled[b-shjkj423xj] {
    cursor: default;
    opacity: 0.55;
}

/* tiles */
.nmc-tiles[b-shjkj423xj] {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.nmc-tile[b-shjkj423xj] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 1rem 1.1rem;
}

.nmc-tile .lab[b-shjkj423xj] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #6c7a8c;
    font-weight: 700;
}

.nmc-tile .val[b-shjkj423xj] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1f3f5e;
    line-height: 1.05;
    margin-top: 0.5rem;
    font-variant-numeric: tabular-nums;
}

.nmc-tile.muted .val[b-shjkj423xj] {
    color: #9aa6b6;
}

.nmc-tile .sub[b-shjkj423xj] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* card */
.nmc-card[b-shjkj423xj] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    margin-bottom: 1.15rem;
    padding: 1rem 1.2rem 1.4rem;
}

.nmc-card-head[b-shjkj423xj] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.nmc-card-head h3[b-shjkj423xj] {
    margin: 0;
    font-size: 1rem;
    color: #1f3f5e;
}

.nmc-card-head .d[b-shjkj423xj] {
    color: #6c7a8c;
    font-size: 0.82rem;
}

/* funnel */
.nmc-funnel[b-shjkj423xj] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: center;
}

.nmc-stage[b-shjkj423xj] {
    width: 100%;
    max-width: 760px;
    display: flex;
    align-items: center;
    gap: 1rem;
}

.nmc-stage .bar[b-shjkj423xj] {
    height: 58px;
    border-radius: 0.6rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1.25rem;
    color: #ffffff;
    margin: 0 auto;
    min-width: 0;
}

.nmc-stage .bar .nm[b-shjkj423xj] {
    font-weight: 700;
    font-size: 0.95rem;
    white-space: nowrap;
}

.nmc-stage .bar .v[b-shjkj423xj] {
    font-weight: 800;
    font-size: 1.4rem;
    font-variant-numeric: tabular-nums;
    padding-left: 0.75rem;
}

.nmc-stage .bar.f0[b-shjkj423xj] { background: #3a4f6a; }
.nmc-stage .bar.f1[b-shjkj423xj] { background: #2b6cb0; }
.nmc-stage .bar.f2[b-shjkj423xj] { background: #2f7d6a; }
.nmc-stage .bar.f4[b-shjkj423xj] { background: #1f6f43; }

.nmc-stage .conv[b-shjkj423xj] {
    width: 150px;
    flex: 0 0 150px;
    font-size: 0.8rem;
    color: #6c7a8c;
    text-align: left;
}

.nmc-stage .conv b[b-shjkj423xj] {
    color: #1f7a4d;
    font-size: 0.9rem;
}

.nmc-arrow[b-shjkj423xj] {
    color: #b7c4d6;
    font-size: 0.85rem;
    line-height: 1;
}

.nmc-empty[b-shjkj423xj] {
    color: #6c7a8c;
    padding: 1.5rem 0;
    text-align: center;
    margin: 0;
}

.nmc-note[b-shjkj423xj] {
    font-size: 0.72rem;
    color: #9aa6b6;
    margin-top: 0.4rem;
}

@media (max-width: 820px) {
    .nmc-tiles[b-shjkj423xj] {
        grid-template-columns: repeat(2, 1fr);
    }
    .nmc-head-actions[b-shjkj423xj] {
        margin-left: 0;
    }
    .nmc-stage .conv[b-shjkj423xj] {
        width: 110px;
        flex-basis: 110px;
    }
}

@media (max-width: 480px) {
    .nmc-tiles[b-shjkj423xj] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/News.razor.rz.scp.css */
.news-page-head[b-rgdx3jv432] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.news-page-head p[b-rgdx3jv432] {
    margin-bottom: 0;
}

.news-back-link[b-rgdx3jv432],
.news-open-label[b-rgdx3jv432] {
    color: #4c6f95;
    font-size: 0.9rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}

.news-back-link:hover[b-rgdx3jv432],
.news-list-item:hover .news-open-label[b-rgdx3jv432],
.news-doclink a:hover[b-rgdx3jv432] {
    text-decoration: underline;
}

.news-list[b-rgdx3jv432] {
    display: grid;
    gap: 0;
}

.news-list-item[b-rgdx3jv432] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.95rem 0;
    border-bottom: 1px solid rgba(120, 145, 175, 0.28);
    color: inherit;
    text-decoration: none;
}

.news-list-item:last-child[b-rgdx3jv432] {
    border-bottom: none;
}

.news-list-item:hover .news-title[b-rgdx3jv432] {
    color: #385a80;
}

.news-list-main[b-rgdx3jv432] {
    display: grid;
    gap: 0.25rem;
    min-width: 0;
}

.news-list-item.is-unread .news-title[b-rgdx3jv432] {
    font-weight: 800;
}

.news-list-item.is-unread .news-summary[b-rgdx3jv432] {
    color: #2f3d4b;
    font-weight: 600;
}

.news-item[b-rgdx3jv432] {
    padding: 1rem 0 1.25rem;
    border-bottom: 1px solid rgba(120, 145, 175, 0.28);
}

.news-item:last-of-type[b-rgdx3jv432] {
    border-bottom: none;
}

.news-missing[b-rgdx3jv432] {
    color: #6b7c90;
}

.news-item-head[b-rgdx3jv432] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 0.25rem;
}

.news-category[b-rgdx3jv432] {
    display: inline-flex;
    align-items: center;
    background: linear-gradient(180deg, #6a88aa 0%, #4c6f95 100%);
    color: #fff;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    line-height: 1.4;
}

.news-date[b-rgdx3jv432] {
    color: #6b7c90;
    font-size: 0.8rem;
}

.news-unread-dot[b-rgdx3jv432] {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 999px;
    background: #d64545;
    box-shadow: 0 0 0 2px rgba(214, 69, 69, 0.12);
}

.news-title[b-rgdx3jv432] {
    margin: 0.1rem 0 0.35rem;
    font-size: 1.15rem;
    line-height: 1.25;
}

.news-list-item .news-title[b-rgdx3jv432] {
    display: block;
    margin: 0;
}

.news-summary[b-rgdx3jv432] {
    color: #5d6f83;
    display: block;
    font-size: 0.92rem;
    line-height: 1.45;
}

.news-figure[b-rgdx3jv432] {
    margin: 0.5rem 0 0.85rem;
    /* Cap the screenshot width so it reads as an inset illustration, not a banner,
       on wide desktop while still filling the column on a phone. */
    max-width: 560px;
}

.news-image[b-rgdx3jv432] {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid rgba(120, 145, 175, 0.4);
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(40, 60, 90, 0.12);
    background: #fff;
}

.news-caption[b-rgdx3jv432] {
    margin: 0.4rem 0 0;
    color: #6b7c90;
    font-size: 0.8rem;
    line-height: 1.4;
    font-style: italic;
}

.news-body[b-rgdx3jv432] {
    margin: 0;
    white-space: pre-line;
    line-height: 1.5;
}

.news-doclink[b-rgdx3jv432] {
    margin: 0.6rem 0 0;
    font-size: 0.9rem;
}

.news-doclink a[b-rgdx3jv432] {
    color: #4c6f95;
    font-weight: 600;
    text-decoration: none;
}

@media (max-width: 640px) {
    .news-page-head[b-rgdx3jv432],
    .news-list-item[b-rgdx3jv432] {
        align-items: stretch;
        flex-direction: column;
    }

    .news-open-label[b-rgdx3jv432] {
        align-self: flex-start;
    }
}
/* /Components/Pages/Participate.razor.rz.scp.css */
/* #869 (portal B2): the Participate view. Reuses the shipped player visual language
   (navy #16324f / blue #1b6ec2 / green #2f9e6f / card tokens) from the mock; no new
   brand. Mobile-first, 44px+ touch targets, readable at a glance. Scoped per component. */

.pt-shell[b-sisf3ksvlp] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.1rem 1.1rem 2.5rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* -- S7d Inc2a: the converged-view tab strip (Wireframe B) ---------------- */
/* Mirrors the /live tab bar with the player palette. 44px touch targets. "Your night" is the only tab
   with actions; Board / Players / Games are read-only whole-room views. */
.pt-tabs[b-sisf3ksvlp] {
    display: flex;
    gap: 0.25rem;
    background: #eef3f8;
    border: 1px solid #d6e0ea;
    border-radius: 0.7rem;
    padding: 0.2rem;
    margin-bottom: 0.9rem;
}

.pt-tab[b-sisf3ksvlp] {
    flex: 1 1 0;
    min-height: 2.75rem;
    border: none;
    background: transparent;
    border-radius: 0.55rem;
    font-size: 0.8rem;
    font-weight: 700;
    color: #557693;
    cursor: pointer;
    /* Inc2a rework (BLOCKER 1): every label stays single-line (Wireframe B). "Your night" is two words, so
       it must not wrap to a jagged 2-line pill next to the single-word tabs. */
    white-space: nowrap;
}

/* Inc2a rework (BLOCKER 1): give the two-word "Your night" (the first tab) a wider basis than the three
   single-word tabs so it fits on one line at 390px. The strip is width-capped by .pt-shell (max 34rem), so
   this stays balanced at kiosk widths too. */
.pt-tabs .pt-tab:first-child[b-sisf3ksvlp] {
    flex-grow: 1.5;
}

.pt-tab.active[b-sisf3ksvlp] {
    background: #fff;
    color: #0d2c55;
    box-shadow: 0 1px 3px rgba(13, 44, 85, 0.12);
}

.pt-tab:focus-visible[b-sisf3ksvlp] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* Chrome for the reused whole-room tabs' outer panel — mirrors LiveSession's ::deep .clubSession-panel so
   the Players / Games tabs read as cards in the converged view too (the tabs expect this wrapper chrome,
   as ClubSessionDashboard supplies on the console and LiveSession on /live). */
[b-sisf3ksvlp] .clubSession-panel {
    background: #edf3fa;
    border: 1px solid #b9c9da;
    border-radius: 0.75rem;
    padding: 0.6rem;
    min-width: 0;
}

[b-sisf3ksvlp] .clubSession-panel h2 {
    margin: 0 0 0.45rem;
    color: #355775;
    font-size: 0.98rem;
    font-weight: 700;
}

/* The severed name (AllowMemberProfile=false) — plain text styled to match the former link's weight. */
[b-sisf3ksvlp] .attendee-name-plain {
    font-weight: 600;
}

/* -- Live top bar -------------------------------------------------------- */
.pt-topbar[b-sisf3ksvlp] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: #0d2c55;
    padding: 0.6rem 0.9rem;
    color: #fff;
}

.pt-topbar.is-ended[b-sisf3ksvlp] {
    background: #47586b;
}

.pt-exit[b-sisf3ksvlp] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: rgba(255, 255, 255, 0.12);
    border: 1px solid rgba(255, 255, 255, 0.3);
    color: #fff;
    border-radius: 0.5rem;
    padding: 0.5rem 0.7rem;
    font-size: 0.82rem;
    font-weight: 700;
    text-decoration: none;
    min-height: 44px;
    box-sizing: border-box;
}

.pt-exit:hover[b-sisf3ksvlp],
.pt-exit:focus-visible[b-sisf3ksvlp] {
    background: rgba(255, 255, 255, 0.2);
}

.pt-body[b-sisf3ksvlp] {
    flex: 1 1 auto;
    text-align: center;
    min-width: 0;
}

.pt-title[b-sisf3ksvlp] {
    display: block;
    font-weight: 800;
    font-size: 0.95rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pt-sub[b-sisf3ksvlp] {
    display: block;
    font-size: 0.7rem;
    color: #8fc0ee;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pt-status[b-sisf3ksvlp] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    flex: 0 0 auto;
}

.pt-live[b-sisf3ksvlp] {
    color: #7cf3b0;
}

.pt-ended[b-sisf3ksvlp] {
    color: #cfe0f2;
}

.pt-blip[b-sisf3ksvlp] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: #2f9e6f;
    box-shadow: 0 0 0 3px rgba(47, 158, 111, 0.35);
}

/* -- Presence strip ------------------------------------------------------ */
.pt-presence[b-sisf3ksvlp] {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    background: #f8fafc;
    border: 1px solid #eef1f4;
    border-radius: 0.6rem;
    padding: 0.5rem 0.55rem;
    margin-bottom: 1rem;
    overflow-x: auto;
}

.pt-step[b-sisf3ksvlp] {
    font-size: 0.72rem;
    font-weight: 700;
    color: #b9c9db;
    white-space: nowrap;
    padding: 0.15rem 0.3rem;
}

.pt-step.is-done[b-sisf3ksvlp] {
    color: #2f9e6f;
}

.pt-step.is-now[b-sisf3ksvlp] {
    color: #fff;
    background: #1b6ec2;
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
}

.pt-sep[b-sisf3ksvlp] {
    color: #cbd5e1;
    font-size: 0.7rem;
}

/* -- Queue band (Waiting hero) + awaiting-admission band ----------------- */
.pt-band[b-sisf3ksvlp] {
    background: #0d2c55;
    color: #fff;
    border-radius: 0.85rem;
    padding: 1rem;
    margin-bottom: 1rem;
    text-align: center;
}

.pt-band-muted[b-sisf3ksvlp] {
    background: #47586b;
}

.pt-band-lbl[b-sisf3ksvlp] {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: #8fc0ee;
    font-weight: 700;
}

.pt-band-pos[b-sisf3ksvlp] {
    font-size: 2.4rem;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.pt-band-headline[b-sisf3ksvlp] {
    font-size: 1.15rem;
    font-weight: 800;
    margin: 0.35rem 0 0.1rem;
}

.pt-band-note[b-sisf3ksvlp] {
    font-size: 0.9rem;
    color: #cfe0f2;
    margin-top: 0.4rem;
}

/* -- On-court card ------------------------------------------------------- */
.pt-court[b-sisf3ksvlp] {
    background: #0d2c55;
    color: #fff;
    border-radius: 0.85rem;
    padding: 1.1rem;
    margin-bottom: 1rem;
}

.pt-court-lbl[b-sisf3ksvlp] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #8fc0ee;
    font-weight: 700;
}

.pt-court-no[b-sisf3ksvlp] {
    font-size: 1.5rem;
    font-weight: 800;
    margin: 0.15rem 0 0.6rem;
}

.pt-court-pair[b-sisf3ksvlp] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.95rem;
    padding: 0.35rem 0;
}

.pt-court-you[b-sisf3ksvlp] {
    color: #f5d76e;
    font-weight: 800;
}

.pt-court-vs[b-sisf3ksvlp] {
    font-size: 0.72rem;
    color: #8fc0ee;
    font-weight: 700;
    text-align: center;
    padding: 0.1rem 0;
}

/* -- Cards / sections / who's-next --------------------------------------- */
.pt-card[b-sisf3ksvlp] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.85rem;
    padding: 1rem 1.1rem;
    margin-bottom: 1rem;
}

.pt-section-title[b-sisf3ksvlp] {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 0 0 0.55rem;
    font-weight: 700;
}

.pt-upnext[b-sisf3ksvlp] {
    padding: 0.3rem 1.1rem;
}

.pt-upnext-row[b-sisf3ksvlp] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.6rem 0.1rem;
    border-bottom: 1px solid #eef1f4;
    font-size: 0.9rem;
}

.pt-upnext-row:last-child[b-sisf3ksvlp] {
    border-bottom: 0;
}

/* -- Banners (sit-out) --------------------------------------------------- */
.pt-banner[b-sisf3ksvlp] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.85rem;
    font-size: 0.9rem;
    margin-bottom: 1rem;
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
}

.pt-banner-info[b-sisf3ksvlp] {
    background: #eaf3ff;
    border: 1px solid #bcd8f7;
    color: #134a86;
}

/* -- Session-ended "that's a wrap" + not-on-roster notice ---------------- */
.pt-wrap[b-sisf3ksvlp] {
    text-align: center;
}

.pt-wrap-emoji[b-sisf3ksvlp] {
    font-size: 2rem;
}

.pt-wrap-title[b-sisf3ksvlp] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.1rem;
    margin: 0.3rem 0 0.1rem;
}

.pt-notice[b-sisf3ksvlp] {
    text-align: center;
}

.pt-notice-icon[b-sisf3ksvlp] {
    font-size: 2rem;
}

.pt-notice-title[b-sisf3ksvlp] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.1rem;
    margin: 0.3rem 0 0.4rem;
}

.pt-muted[b-sisf3ksvlp] {
    color: #5e748a;
    margin: 0;
}

.pt-hint[b-sisf3ksvlp] {
    text-align: center;
    color: #5e748a;
    font-size: 0.9rem;
    margin: 0.4rem 0 1rem;
}

/* #101: contextual help footer — a quiet separated line beneath the live view. */
.pt-help-foot[b-sisf3ksvlp] {
    margin-top: 1.75rem;
    padding-top: 1.1rem;
    border-top: 1px solid #e2e8f0;
}

/* -- Buttons ------------------------------------------------------------- */
.pt-btn[b-sisf3ksvlp] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    border: 0;
    border-radius: 0.6rem;
    padding: 0.75rem 1.1rem;
    font-size: 0.95rem;
    font-weight: 700;
    min-height: 44px;
    box-sizing: border-box;
    text-decoration: none;
    cursor: pointer;
}

.pt-btn-secondary[b-sisf3ksvlp] {
    background: #eef2f7;
    color: #16324f;
    border: 1px solid #d7dee7;
}

/* #870 (portal B3): primary Rejoin (mock state 3 hero) - the shipped blue accent. */
.pt-btn-primary[b-sisf3ksvlp] {
    background: #1b6ec2;
    color: #fff;
    border: 1px solid #1b6ec2;
}

.pt-btn-primary:hover:not([disabled])[b-sisf3ksvlp],
.pt-btn-primary:focus-visible:not([disabled])[b-sisf3ksvlp] {
    background: #155a9e;
}

/* Larger touch target for the hero Rejoin. */
.pt-btn-lg[b-sisf3ksvlp] {
    padding: 0.95rem 1.1rem;
    font-size: 1.05rem;
    min-height: 52px;
}

/* Red-tinted Leave (mock 05): a secondary button recoloured for the leave affordance. */
.pt-btn-danger[b-sisf3ksvlp] {
    color: #c0392b;
    border-color: #f0b8b0;
    background: #fdf3f2;
}

.pt-btn-danger:hover:not([disabled])[b-sisf3ksvlp],
.pt-btn-danger:focus-visible:not([disabled])[b-sisf3ksvlp] {
    background: #fbe7e4;
}

/* Greyed, inert "Request a game" placeholder (architect lane - does nothing). */
.pt-btn-disabled[b-sisf3ksvlp],
.pt-btn[disabled][b-sisf3ksvlp] {
    opacity: 0.55;
    cursor: not-allowed;
}

.pt-btn-block[b-sisf3ksvlp] {
    display: flex;
    width: 100%;
}

/* -- #870 (portal B3): participant actions ------------------------------- */
/* The Waiting actions row: Sit out + the greyed Request-a-game placeholder, side by side. */
.pt-actions[b-sisf3ksvlp] {
    display: flex;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}

.pt-actions .pt-btn[b-sisf3ksvlp] {
    flex: 1 1 0;
}

.pt-leave-btn[b-sisf3ksvlp] {
    margin-top: 0.4rem;
}

.pt-rejoin-lead[b-sisf3ksvlp] {
    margin: 0.2rem 0 0.8rem;
}

/* Action-error strip: the info banner recoloured for a failed action. */
.pt-banner-error[b-sisf3ksvlp] {
    background: #fdecea;
    border: 1px solid #f5b7b1;
    color: #922b21;
}

/* -- Loading skeleton ---------------------------------------------------- */
.pt-skeleton > *[b-sisf3ksvlp] {
    border-radius: 0.85rem;
    background: linear-gradient(90deg, #eef1f4 25%, #f6f9fc 37%, #eef1f4 63%);
    background-size: 400% 100%;
    animation: pt-shimmer-b-sisf3ksvlp 1.4s ease infinite;
    margin-bottom: 1rem;
}

.pt-skel-strip[b-sisf3ksvlp] {
    height: 2.2rem;
}

.pt-skel-band[b-sisf3ksvlp] {
    height: 6rem;
}

.pt-skel-card[b-sisf3ksvlp] {
    height: 4rem;
}

@keyframes pt-shimmer-b-sisf3ksvlp {
    0% { background-position: 100% 0; }
    100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
    .pt-skeleton > *[b-sisf3ksvlp] {
        animation: none;
    }
}

/* -- #871 (portal B4): "Your rating tonight" / "Your night" mini-recap ---- */
/* Reuses the shipped mini-recap language (mock 05): a big signed delta beside the
   games-won + rating-arc facts. Lives inside a .pt-card. */
.pt-mini-recap[b-sisf3ksvlp] {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.pt-mini-delta[b-sisf3ksvlp] {
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1;
}

.pt-mini-up[b-sisf3ksvlp] {
    color: #2f9e6f;
}

.pt-mini-down[b-sisf3ksvlp] {
    color: #c0392b;
}

.pt-mini-facts[b-sisf3ksvlp] {
    font-size: 0.9rem;
    color: #47586b;
}

.pt-mini-facts strong[b-sisf3ksvlp] {
    color: #16324f;
}

/* The "See your full night" link row under the session-ended fold. */
.pt-mini-link-row[b-sisf3ksvlp] {
    margin: 0.7rem 0 0;
}

.pt-link[b-sisf3ksvlp] {
    color: #1b6ec2;
    font-weight: 700;
    text-decoration: none;
}

.pt-link:hover[b-sisf3ksvlp],
.pt-link:focus-visible[b-sisf3ksvlp] {
    text-decoration: underline;
}

/* -- #872 (portal B5): "Session updates" feed --------------------------- */
/* Mirrors the mock's .updates-feed tokens (navy #16324f / blue #1b6ec2 /
   green #2f9e6f). A bordered card of rows, each a status dot + text + a
   quiet relative "when". The viewer's own rows dot green (.pt-fdot-you). */
.pt-feed[b-sisf3ksvlp] {
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    padding: 0.3rem 0.9rem;
    margin-bottom: 1rem;
}

.pt-feed-row[b-sisf3ksvlp] {
    display: flex;
    gap: 0.6rem;
    align-items: flex-start;
    padding: 0.6rem 0.1rem;
    border-bottom: 1px solid #eef1f4;
    font-size: 0.88rem;
}

.pt-feed-row:last-child[b-sisf3ksvlp] {
    border-bottom: 0;
}

.pt-fdot[b-sisf3ksvlp] {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: #1b6ec2;
    margin-top: 0.45rem;
    flex: 0 0 auto;
}

.pt-fdot-you[b-sisf3ksvlp] {
    background: #2f9e6f;
}

.pt-fbody[b-sisf3ksvlp] {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
}

.pt-ft[b-sisf3ksvlp] {
    color: #16324f;
    font-weight: 600;
}

.pt-fwhen[b-sisf3ksvlp] {
    font-size: 0.72rem;
    color: #8496a8;
}

/* BL-PW-0012 (R2): Open self check-in - the "Join tonight" code entry (Expected state). */
.pt-join-row[b-sisf3ksvlp] {
    display: flex;
    gap: 0.5rem;
    align-items: stretch;
}

.pt-join-code[b-sisf3ksvlp] {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.6rem 0.75rem;
    font-size: 1.1rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #16324f;
    background: #fff;
    border: 1px solid #cdd8e3;
    border-radius: 0.5rem;
}

.pt-join-code[b-sisf3ksvlp]::placeholder {
    color: #8496a8;
    letter-spacing: normal;
    text-transform: none;
    font-weight: 400;
}

.pt-join-code:focus[b-sisf3ksvlp] {
    outline: none;
    border-color: #1b6ec2;
    box-shadow: 0 0 0 3px rgba(27, 110, 194, 0.18);
}

/* #61 (UX): the "Playing as {name}" identity-confirmation line on the Participate "Your night" body — a
   quiet muted caption (reuses the muted-caption + dark-navy-strong tokens; no new colours). */
.pt-linked-as[b-sisf3ksvlp] {
    margin: 0 0 0.85rem;
    font-size: 0.82rem;
    color: #5e748a;
}

.pt-linked-as strong[b-sisf3ksvlp] {
    color: #16324f;
    font-weight: 700;
}
/* /Components/Pages/PartnershipReport.razor.rz.scp.css */
/* #196 (S1, league-team-support): /reports/partnerships. Built to mockup.html §S1
   + the S1 UX plan. CSS isolation is per-component, so the reports-shell family is
   restated here (same values as SessionSummaryReport.razor.css) alongside the
   partnership-specific classes (palette pulled from the real app, per the mockup). */

.reports-shell[b-6s1tjoc5dq] {
    max-width: 1280px;
    padding-bottom: 2rem;
}

.reports-crumb[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-6s1tjoc5dq] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-6s1tjoc5dq],
.reports-crumb-link:focus-visible[b-6s1tjoc5dq] {
    text-decoration: underline;
}

.reports-crumb-link:focus-visible[b-6s1tjoc5dq] {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
}

.reports-subtitle[b-6s1tjoc5dq] {
    color: #4e6f8e;
    margin: -0.25rem 0 1.25rem;
    max-width: 70ch;
}

.reports-available-now-card[b-6s1tjoc5dq] {
    background: #ffffff;
    border: 1px solid #d7e0ec;
    border-radius: 0.55rem;
    padding: 1rem 1.2rem;
    margin-bottom: 1rem;
}

/* ---- summary stat cards ---- */
.partnership-stats[b-6s1tjoc5dq] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    margin-bottom: 1rem;
}

.stat-card[b-6s1tjoc5dq] {
    background: #fff;
    border: 1px solid #c5cfde;
    border-radius: 0.625rem;
    padding: 0.9rem 1rem;
}

.stat-value[b-6s1tjoc5dq] {
    font-size: 1.55rem;
    font-weight: 700;
    color: #1f3f5e;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.stat-label[b-6s1tjoc5dq] {
    font-size: 0.78rem;
    color: #6c7a8c;
    margin-top: 0.35rem;
}

/* ---- toolbar ---- */
.partnership-toolbar[b-6s1tjoc5dq] {
    display: flex;
    gap: 0.65rem;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

/* Bootstrap's .form-select is width:100%, which fights the flex strip and stacks
   each control to a full-width row. Pin the selects to content width so the toolbar
   reads as one horizontal control strip (it still wraps when the row runs out of room). */
.partnership-toolbar .form-select-sm[b-6s1tjoc5dq] {
    width: auto;
    flex: 0 0 auto;
}

.partnership-name-filter[b-6s1tjoc5dq] {
    flex: 1;
    min-width: 160px;
}

/* ---- styled slide switch (mockup .switch / .track / .knob) ---- */
.partnership-switch[b-6s1tjoc5dq] {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
    color: #33455c;
    cursor: pointer;
    user-select: none;
    margin: 0;
}

.partnership-switch .track[b-6s1tjoc5dq] {
    width: 38px;
    height: 21px;
    border-radius: 20px;
    background: #c6d0dd;
    position: relative;
    transition: background 0.15s;
    flex: 0 0 auto;
}

.partnership-switch .knob[b-6s1tjoc5dq] {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 17px;
    height: 17px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: left 0.15s;
}

.partnership-switch.on .track[b-6s1tjoc5dq] { background: #3f7ac0; }
.partnership-switch.on .knob[b-6s1tjoc5dq] { left: 19px; }

.partnership-switch:focus-visible[b-6s1tjoc5dq] {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
    border-radius: 4px;
}

/* ---- S1b: team-roster ("focus players") multi-select ---- */
.partnership-roster[b-6s1tjoc5dq] {
    margin-bottom: 0.9rem;
}

.partnership-roster-toggle[b-6s1tjoc5dq] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: #fff;
    border: 1px solid #c5cfde;
    border-radius: 0.45rem;
    padding: 0.3rem 0.7rem;
    font-size: 0.82rem;
    color: #1f3f5e;
    font-weight: 600;
    cursor: pointer;
}

.partnership-roster-toggle:hover[b-6s1tjoc5dq],
.partnership-roster-toggle.open[b-6s1tjoc5dq] {
    border-color: #3f7ac0;
}

.partnership-roster-toggle:focus-visible[b-6s1tjoc5dq] {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
}

.partnership-roster-count-badge[b-6s1tjoc5dq] {
    background: #3f7ac0;
    color: #fff;
    border-radius: 10px;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 0.02rem 0.4rem;
    min-width: 1.1rem;
    text-align: center;
}

.partnership-roster-caret[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.7rem;
}

.partnership-roster-chips[b-6s1tjoc5dq] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    margin-top: 0.5rem;
}

.partnership-roster-chip[b-6s1tjoc5dq] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: #eef4fc;
    border: 1px solid #c7dcf0;
    border-radius: 16px;
    padding: 0.12rem 0.5rem 0.12rem 0.18rem;
    font-size: 0.78rem;
    color: #1f3f5e;
}

.partnership-roster-chip-name[b-6s1tjoc5dq] {
    font-weight: 600;
}

.partnership-roster-chip-x[b-6s1tjoc5dq] {
    background: none;
    border: none;
    color: #6c7a8c;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.1rem;
    cursor: pointer;
    /* Tablet-usable tap target (S1b rework polish). */
    min-width: 28px;
    min-height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.partnership-roster-chip-x:hover[b-6s1tjoc5dq] {
    color: #b3261e;
}

.partnership-roster-clear[b-6s1tjoc5dq] {
    background: none;
    border: none;
    color: #3f7ac0;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    padding: 0.1rem 0.2rem;
}

.partnership-roster-clear:hover[b-6s1tjoc5dq] {
    text-decoration: underline;
}

.partnership-roster-panel[b-6s1tjoc5dq] {
    margin-top: 0.5rem;
    border: 1px solid #c5cfde;
    border-radius: 0.5rem;
    padding: 0.6rem;
    background: #fbfcfe;
    max-width: min(380px, 100%);
}

.partnership-roster-search[b-6s1tjoc5dq] {
    margin-bottom: 0.5rem;
}

.partnership-roster-list[b-6s1tjoc5dq] {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 240px;
    overflow-y: auto;
}

.partnership-roster-row[b-6s1tjoc5dq] {
    border-bottom: 1px solid #f1f4f9;
}

.partnership-roster-label[b-6s1tjoc5dq] {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.35rem 0.25rem;
    margin: 0;
    cursor: pointer;
    font-size: 0.85rem;
}

.partnership-roster-list-name[b-6s1tjoc5dq] {
    color: #33455c;
}

.partnership-roster-noresults[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.8rem;
    margin: 0.4rem 0 0;
}

.partnership-roster-summary[b-6s1tjoc5dq] {
    margin-top: 0.6rem;
    background: #eef4fc;
    border: 1px solid #c7dcf0;
    border-radius: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.82rem;
    color: #2c4a6a;
}

.partnership-roster-summary strong[b-6s1tjoc5dq] {
    color: #1f3f5e;
}

/* ---- metric explainer note ---- */
.partnership-note[b-6s1tjoc5dq] {
    background: #eef4fc;
    border: 1px solid #cBdcf0;
    border-color: #c7dcf0;
    border-radius: 0.5rem;
    padding: 0.7rem 0.85rem;
    font-size: 0.82rem;
    color: #2c4a6a;
    margin-bottom: 0.85rem;
    line-height: 1.45;
}

.partnership-count-hint[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.86rem;
    margin-bottom: 0.5rem;
}

/* light inline note shown when there are settling pairs but no settled verdicts yet —
   keeps the page momentum-forward instead of a contradictory "nothing here" illustration */
.partnership-inline-note[b-6s1tjoc5dq] {
    background: #fff8e6;
    border: 1px solid #f0d690;
    color: #7a5400;
    border-radius: 0.5rem;
    padding: 0.6rem 0.85rem;
    font-size: 0.84rem;
    line-height: 1.45;
    margin-bottom: 0.85rem;
}

/* sub-label under the "vs expected" column header (matches mockup) */
.partnership-th-sub[b-6s1tjoc5dq] {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: #9bb;
    font-size: 0.625rem;
}

/* ---- the ranked table ---- */
.partnership-table thead th[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 1px solid #e6ebf3;
    white-space: nowrap;
}

.partnership-table th.sortable-header[b-6s1tjoc5dq] {
    cursor: pointer;
    user-select: none;
}

.partnership-table th.sortable-header:hover[b-6s1tjoc5dq] {
    color: #1f3f5e;
}

.partnership-table td[b-6s1tjoc5dq],
.partnership-table th[b-6s1tjoc5dq] {
    vertical-align: middle;
}

.partnership-table .numeric[b-6s1tjoc5dq] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ---- gender name lozenge (mirrors session waiting chips) ---- */
.who2[b-6s1tjoc5dq] {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.av[b-6s1tjoc5dq] {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    flex: 0 0 auto;
}

/* SPEC-32 I4-S1 (#670), R-I2-44.1/.2: these six values are no longer DEFINED here.

   THIS PAGE IS WHERE THEY WERE, AND THAT WAS THE PROBLEM. A Blazor component-scoped stylesheet is
   unreachable from any other component, so when the profile's counterpart tables were asked to render
   the same inks, referencing `.nm.m` by name would have produced a correct-looking class list and no
   colour at all. The values moved to app.css's :root; this page now READS them, like everyone else.

   IT IS A REFACTOR WITH A BYTE-IDENTICAL RESULT, and that is the acceptance test (AC-I4-S1-3): the
   tokens were seeded with THIS page's own current values, so nothing here renders differently. A
   visible change on /reports/partnerships means a value was altered in passing, on a page nobody
   asked about.

   THE FILL PAIR AND THE INK PAIR STAY SEPARATE — see app.css for why folding them would halve the
   contrast of every inked name in the product, and see #680 for the divergence that IS real. */
.av.m[b-6s1tjoc5dq] { background: var(--gender-male); }
.av.f[b-6s1tjoc5dq] { background: var(--gender-female); }
.av.u[b-6s1tjoc5dq] { background: #6c7a8c; }
.nm.m[b-6s1tjoc5dq] { color: var(--gender-name-male); }
.nm.f[b-6s1tjoc5dq] { color: var(--gender-name-female); }
.nm.u[b-6s1tjoc5dq] { color: var(--gender-name-default); }

/* ---- vs expected delta cell ---- */
/* SPEC-32 I4-S2 (#670), R-I2-44.1: THE WHOLE `.vsexp` BLOCK MOVED TO app.css. Not copied — moved.

   The profile's counterpart tables now render this same cell, and a component-scoped stylesheet is
   unreachable from any other component, so a copy here would be the two-literals-that-agree-until-one-
   is-edited drift R-I2-32 exists to prevent. The values are unchanged and this page is contracted to
   look identical (R-I2-44.2, AC-I4-S2-15).

   THE OVER / UNDER / EVEN INKS ARE NOW TOKENS — --vsexp-over / -under / -even — because R-I2-47.4
   binds one banding expression AND one set of colours across the three hosts that render the figure.
   The `.pill` rules below read the same three tokens: they were the same three literals a second time,
   in this same file, for the same three bands. */

/* ---- verdict pills ---- */
.pill[b-6s1tjoc5dq] {
    display: inline-block;
    border-radius: 20px;
    padding: 0.12rem 0.625rem;
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
}

/* The pill is THIS PAGE'S and stays here (R-I2-47 keeps it off the profile, which renders the verdict
   once, as the delta's own ink). Its three TEXT colours were the same three literals `.vsexp .delta`
   used, so they read the tokens now — values unchanged to the byte; the backgrounds are the pill's
   alone and stay literals. */
.pill.over[b-6s1tjoc5dq] { background: #d8f0e2; color: var(--vsexp-over); }
.pill.under[b-6s1tjoc5dq] { background: #fde2e1; color: var(--vsexp-under); }
.pill.even[b-6s1tjoc5dq] { background: #eef1f6; color: var(--vsexp-even); }
.pill.settling[b-6s1tjoc5dq] { background: #fdeccd; color: #8a5a00; }

/* ---- confidence meter ---- */
/* SPEC-32 I4-S2 (#670), R-I2-44.1: THE WHOLE `.conf` BLOCK MOVED TO app.css, and moving it CHANGED
   WHAT THIS PAGE RENDERS — see app.css for the finding written out in full.

   In short: this page builds its meter from a RenderTreeBuilder fragment in its @code block, and
   builder-emitted elements never receive the CSS-isolation scope attribute the Razor compiler stamps
   on declared markup. So `.conf[b-…]` matched nothing, the four <i> bars have been rendering
   zero-width and invisible since the meter shipped, and only the word showed. These rules were dead
   here. They are live in app.css, so the bars appear — on the report as well as on the profile.

   NO VALUE WAS ALTERED IN THE MOVE, which is what R-I2-44.2 actually forbids. Recorded, evidenced in
   spec § 2.3, and raised rather than absorbed. */

/* ---- "still settling" progress list ---- */
.partnership-settling-block[b-6s1tjoc5dq] {
    margin-top: 1.5rem;
    border-top: 1px solid #e6ebf3;
    padding-top: 1rem;
}

.partnership-settling-head[b-6s1tjoc5dq] {
    font-size: 0.95rem;
    color: #1f3f5e;
    margin: 0 0 0.2rem;
}

.partnership-settling-sub[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.8rem;
    margin: 0 0 0.75rem;
    max-width: 70ch;
}

.partnership-settling-list[b-6s1tjoc5dq] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.partnership-settling-row[b-6s1tjoc5dq] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.4rem 0;
    border-bottom: 1px solid #f1f4f9;
}

.partnership-settling-pair[b-6s1tjoc5dq] {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

.partnership-settling-meta[b-6s1tjoc5dq] {
    color: #6c7a8c;
    font-size: 0.78rem;
}

.partnership-settling-pill[b-6s1tjoc5dq] {
    border: none;
    cursor: pointer;
    margin-left: auto;
}

.partnership-settling-explainer[b-6s1tjoc5dq] {
    flex-basis: 100%;
    color: #7a5400;
    font-size: 0.78rem;
    background: #fff8e6;
    border: 1px solid #f0d690;
    border-radius: 0.4rem;
    padding: 0.45rem 0.6rem;
    line-height: 1.4;
}

/* ---- loading / empty / error ---- */
.partnership-skeleton[b-6s1tjoc5dq] {
    height: 2.2rem;
    border-radius: 0.4rem;
    background: linear-gradient(90deg, #eef2f8 25%, #e3e9f2 37%, #eef2f8 63%);
    background-size: 400% 100%;
    margin-bottom: 0.5rem;
    animation: partnership-shimmer-b-6s1tjoc5dq 1.3s ease infinite;
}

@keyframes partnership-shimmer-b-6s1tjoc5dq {
    0% { background-position: 100% 0; }
    100% { background-position: -100% 0; }
}

.partnership-empty[b-6s1tjoc5dq] {
    text-align: center;
    padding: 2rem 1rem;
    color: #4e6f8e;
}

.partnership-empty-illus[b-6s1tjoc5dq] {
    font-size: 2.4rem;
    margin-bottom: 0.5rem;
}

.partnership-empty strong[b-6s1tjoc5dq] {
    color: #1f3f5e;
    display: block;
    margin-bottom: 0.4rem;
}

.partnership-empty p[b-6s1tjoc5dq] {
    max-width: 52ch;
    margin: 0 auto;
    font-size: 0.85rem;
}

.partnership-error[b-6s1tjoc5dq] {
    padding: 1.2rem;
    color: #6f2950;
}

.partnership-error strong[b-6s1tjoc5dq] {
    color: #b3261e;
}

.partnership-error p[b-6s1tjoc5dq] {
    margin: 0.4rem 0 0.8rem;
    font-size: 0.85rem;
}

@media (max-width: 768px) {
    .partnership-stats[b-6s1tjoc5dq] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/PaymentSummaryReport.razor.rz.scp.css */
.reports-shell[b-6txgho68mg] {
    max-width: 1280px;
    padding-bottom: 2rem;
}

.reports-crumb[b-6txgho68mg] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-6txgho68mg] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-6txgho68mg],
.reports-crumb-link:focus-visible[b-6txgho68mg] {
    text-decoration: underline;
    outline: none;
}

.reports-subtitle[b-6txgho68mg] {
    color: #4e6f8e;
    margin: -0.25rem 0 1.25rem;
    max-width: 70ch;
}

.reports-available-now-card[b-6txgho68mg] {
    background: #ffffff;
    border: 1px solid #d7e0ec;
    border-radius: 0.55rem;
    padding: 1rem 1.2rem;
    margin-bottom: 1rem;
}

/* BL-009: quick-range buttons (1m, 3m, 6m, YTD, 1y). */
.payment-summary-quick-ranges[b-6txgho68mg] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-bottom: 0.55rem;
}

.payment-summary-filters[b-6txgho68mg] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, auto)) 1fr;
    gap: 0.7rem;
    align-items: end;
    margin-bottom: 0.75rem;
}

.payment-summary-filter[b-6txgho68mg] {
    display: flex;
    flex-direction: column;
}

.payment-summary-filter .form-label[b-6txgho68mg] {
    font-size: 0.82rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.2rem;
}

.payment-summary-filter-actions[b-6txgho68mg] {
    flex-direction: row;
    gap: 0.5rem;
    justify-content: flex-end;
    align-items: flex-end;
}

.payment-summary-tabs .nav-link[b-6txgho68mg] {
    font-size: 0.88rem;
    padding: 0.3rem 0.8rem;
}

.payment-summary-count-hint[b-6txgho68mg] {
    color: #6c7a8c;
    font-size: 0.88rem;
    margin-bottom: 0.4rem;
}

.payment-summary-table thead th[b-6txgho68mg] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
    font-size: 0.95rem;
    white-space: nowrap;
}

.payment-summary-table th.sortable-header[b-6txgho68mg] {
    cursor: pointer;
    user-select: none;
}

.payment-summary-table th.sortable-header:hover[b-6txgho68mg] {
    color: #0d2c55;
}

.payment-summary-table td[b-6txgho68mg],
.payment-summary-table th[b-6txgho68mg] {
    vertical-align: middle;
}

.payment-summary-table .numeric[b-6txgho68mg] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.payment-summary-row-outstanding td[b-6txgho68mg] {
    background: #fff8f0;
}

.payment-summary-totals-row td[b-6txgho68mg] {
    border-top: 2px solid #1f2b38;
    background: #f3f6fa;
}

@media (max-width: 768px) {
    .payment-summary-filter-actions[b-6txgho68mg] {
        justify-content: flex-start;
    }
}
/* /Components/Pages/PersonalRecap.razor.rz.scp.css */
/* #634 (portal S6): the personal /me recap — the Strava-style card. Mobile-first,
   share-shaped: the same centred 34rem column as the public recap (a phone card
   dropped into a WhatsApp group), self-contained, no app nav chrome. */

.me-shell[b-9usa3vy546] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    /* Long unbroken club/session names must wrap, not overflow, on phones. */
    overflow-wrap: break-word;
}

.me-head[b-9usa3vy546] {
    text-align: center;
    margin-bottom: 1.5rem;
}

.me-brand[b-9usa3vy546] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
}

.me-brand-wordmark[b-9usa3vy546] {
    height: 1.75rem;
    width: auto;
}

.me-title[b-9usa3vy546] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
    overflow-wrap: break-word;
    word-break: break-word;
    /* break-word alone is not enough inside the centred head block: without a
       width bound the h1 can still size to its longest unbroken run (QA repro:
       long club name at 390px, sw 512 vs cw 374). Bound it to the shell. */
    max-width: 100%;
    min-width: 0;
}

.me-sub[b-9usa3vy546] {
    margin: 0;
    color: #5e748a;
    font-size: 0.95rem;
}

.me-section-title[b-9usa3vy546] {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 0 0 0.85rem;
    font-weight: 700;
}

/* ── The HERO: the rating arc. The delta is the emotional headline. ── */
.me-hero[b-9usa3vy546] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    background: linear-gradient(135deg, #f2f7fc 0%, #e9f1fa 100%);
    border: 1px solid #d9e6f2;
    border-radius: 0.85rem;
    padding: 1.5rem 1.1rem;
    margin-bottom: 2rem;
    text-align: center;
}

.me-hero-delta[b-9usa3vy546] {
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
}

.me-up[b-9usa3vy546] {
    color: #2f9e6f;
}

.me-down[b-9usa3vy546] {
    color: #c0392b;
}

.me-hero-arc[b-9usa3vy546] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 1.15rem;
    font-weight: 700;
    color: #16324f;
    font-variant-numeric: tabular-nums;
}

.me-hero-arrow[b-9usa3vy546] {
    color: #5e748a;
    font-weight: 400;
}

.me-hero-label[b-9usa3vy546] {
    font-size: 0.85rem;
    color: #5e748a;
}

.me-hero-none[b-9usa3vy546] {
    color: #47586b;
    font-size: 0.98rem;
}

/* ── Games / won / win% ── */
.me-numbers[b-9usa3vy546] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.75rem;
    margin-bottom: 2rem;
}

.me-stat[b-9usa3vy546] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1rem 0.5rem;
    text-align: center;
}

.me-stat-value[b-9usa3vy546] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1b6ec2;
    line-height: 1;
}

.me-stat-label[b-9usa3vy546] {
    font-size: 0.8rem;
    color: #5e748a;
    margin-top: 0.35rem;
}

/* ── Fair play (outcomes only). ── */
.me-fairplay[b-9usa3vy546] {
    margin-bottom: 2rem;
}

.me-fairplay-list[b-9usa3vy546] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.me-fairplay-list li[b-9usa3vy546] {
    position: relative;
    padding-left: 1.6rem;
    color: #33475b;
    font-size: 0.98rem;
}

.me-fairplay-list li[b-9usa3vy546]::before {
    content: "✓";
    position: absolute;
    left: 0;
    top: 0;
    color: #2f9e6f;
    font-weight: 700;
}

/* ── Game by game. ── */
.me-games[b-9usa3vy546] {
    margin-bottom: 2rem;
}

.me-game-list[b-9usa3vy546] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    counter-reset: none;
}

.me-games-note[b-9usa3vy546] {
    margin: 0 0 0.75rem;
    font-size: 0.82rem;
    color: #5e748a;
    font-style: italic;
}

/* #227: the Par explainer under the games list (mirrors the club recap's All-games caption). */
.me-games-caption[b-9usa3vy546] {
    margin: 0.75rem 0 0;
    font-size: 0.82rem;
    color: #5e748a;
    font-style: italic;
}

.me-game[b-9usa3vy546] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 0.75rem 0.85rem;
    font-size: 0.95rem;
}

.me-game-best[b-9usa3vy546] {
    border-color: #a7ddc0;
    background: #f4fbf7;
}

.me-game-head[b-9usa3vy546] {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.me-game-number[b-9usa3vy546] {
    font-weight: 700;
    color: #16324f;
}

.me-game-result[b-9usa3vy546] {
    font-size: 0.85rem;
    font-weight: 700;
}

.me-result-win[b-9usa3vy546] {
    color: #2f9e6f;
}

.me-result-loss[b-9usa3vy546] {
    color: #c0392b;
}

/* #145: per-game lineup — partner + opponents (names only). Two stacked lines so a
   long set of names wraps within the card rather than pushing it wide. */
.me-game-lineup[b-9usa3vy546] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.84rem;
    color: #16324f;
}

.me-game-lineup .me-lineup-key[b-9usa3vy546] {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #8595a6;
    font-weight: 700;
    margin-right: 0.3rem;
}

.me-game-opponents[b-9usa3vy546] {
    color: #5e748a;
}

/* expected vs actual pair (#769) */
.me-game-expact[b-9usa3vy546] {
    display: grid;
    /* #234: three boxes now — Par (numeric) · Expected (band) · Actual. */
    grid-template-columns: 1fr 1fr 1fr;
    gap: 0.5rem;
}

.me-eabox[b-9usa3vy546] {
    border-radius: 0.5rem;
    padding: 0.4rem 0.55rem;
    font-size: 0.8rem;
}

.me-eabox-key[b-9usa3vy546] {
    display: block;
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #8595a6;
    font-weight: 700;
    margin-bottom: 0.1rem;
}

.me-eabox-value[b-9usa3vy546] {
    font-variant-numeric: tabular-nums;
}

.me-exp[b-9usa3vy546] {
    background: #f6f7f9;
    border: 1px solid #e2e8f0;
}

.me-exp .me-eabox-value[b-9usa3vy546] {
    color: #5e748a;
    font-weight: 600;
}

/* #234 refinement (Owner UAT 2026-08-09): the band box no longer mirrors Par's grey fill (that is
   exactly why the band blurred into "a grey stat next to Par"). A plain white surface lets the
   sentiment-tinted BandChip inside carry the colour — distinct from the grey Par box and the blue
   Actual box, while the three boxes stay the same size in the grid. */
.me-band[b-9usa3vy546] {
    background: #ffffff;
    border: 1px solid #e2e8f0;
}

/* The chip owns its own colour; the value wrapper adds no competing tint. */
.me-band .me-eabox-value[b-9usa3vy546] {
    font-weight: 600;
}

.me-act[b-9usa3vy546] {
    background: #eef4fa;
    border: 1px solid #d9e6f2;
}

.me-act .me-eabox-value[b-9usa3vy546] {
    color: #16324f;
    font-weight: 700;
}

.me-game-foot[b-9usa3vy546] {
    border-top: 1px dashed #e2e8f0;
    padding-top: 0.5rem;
    font-size: 0.84rem;
}

.me-game-rating[b-9usa3vy546] {
    color: #5e748a;
    font-variant-numeric: tabular-nums;
}

.me-game-rating b[b-9usa3vy546] {
    color: #16324f;
    font-weight: 700;
}

.me-game-best-tag[b-9usa3vy546] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #14532d;
}

/* per-game deltas sum to the hero (#769) */
.me-game-sum[b-9usa3vy546] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 0.6rem;
    padding: 0.6rem 0.85rem;
    background: #eef4fa;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    font-size: 0.88rem;
    font-weight: 700;
    color: #16324f;
}

.me-game-sum-value[b-9usa3vy546] {
    font-variant-numeric: tabular-nums;
}

/* ── Share (S4 pattern, /me sources). ── */
.me-share[b-9usa3vy546] {
    margin-bottom: 2rem;
    text-align: center;
}

.me-share-prompt[b-9usa3vy546] {
    margin: 0 0 0.75rem;
    color: #5e748a;
    font-size: 0.9rem;
    font-weight: 600;
}

.me-share-actions[b-9usa3vy546] {
    display: flex;
    gap: 0.6rem;
    justify-content: center;
    flex-wrap: wrap;
}

.me-share-btn[b-9usa3vy546] {
    appearance: none;
    cursor: pointer;
    border: 1px solid #cddceb;
    background: #fff;
    color: #16324f;
    font-size: 0.98rem;
    font-weight: 600;
    padding: 0.7rem 1.2rem;
    border-radius: 0.75rem;
    min-height: 2.75rem;
    transition: background 0.12s ease, border-color 0.12s ease;
}

.me-share-btn:hover[b-9usa3vy546] {
    background: #f2f7fc;
    border-color: #1b6ec2;
}

.me-share-native[b-9usa3vy546] {
    background: linear-gradient(135deg, #1b6ec2 0%, #16324f 100%);
    color: #fff;
    border-color: transparent;
}

.me-share-native:hover[b-9usa3vy546] {
    filter: brightness(1.05);
    background: linear-gradient(135deg, #1b6ec2 0%, #16324f 100%);
    border-color: transparent;
}

/* ── The not-yours / no-data panel. ── */
.me-card-panel[b-9usa3vy546] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.85rem;
    padding: 1.5rem 1.25rem;
    text-align: center;
}

.me-card-panel h1[b-9usa3vy546] {
    font-size: 1.35rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.75rem;
}

.me-card-panel p[b-9usa3vy546] {
    margin: 0 0 0.6rem;
    color: #33475b;
}

.me-help[b-9usa3vy546] {
    font-size: 0.92rem;
    color: #5e748a;
}

/* ── Footer. ── */
.me-foot[b-9usa3vy546] {
    border-top: 1px solid #e2e8f0;
    padding-top: 1.25rem;
    text-align: center;
}

.me-foot-line[b-9usa3vy546] {
    margin: 0 0 0.5rem;
    font-size: 0.95rem;
}

/* #101: contextual help line beneath the footer link. Distinct from .me-foot-line so the
   FramedClubRecap test's ".me-foot-line a" locator stays single-match. */
.me-foot-help[b-9usa3vy546] {
    margin: 0.25rem 0 0;
    font-size: 0.9rem;
    color: #5e748a;
}

.me-foot-cta[b-9usa3vy546] {
    margin: 0;
    color: #5e748a;
    font-size: 0.9rem;
}

.me-foot-cta strong[b-9usa3vy546] {
    color: #1b6ec2;
}

.me-foot-link[b-9usa3vy546] {
    text-decoration: none;
}

.me-foot-link:hover strong[b-9usa3vy546],
.me-foot-link:focus-visible strong[b-9usa3vy546] {
    text-decoration: underline;
}
/* /Components/Pages/PlayerClubDetail.razor.rz.scp.css */
/* #854 (Portal PF1): the player Club-detail page — the stranding fix. Same centred card
   column + visual tokens as /my-nights + /my-clubs-played (one shared player language,
   NO new brand). Scoped per component (the PegboardWeb per-page .razor.css pattern).
   #864 (Portal A1): extended into the permission-driven club MENU (mock 02) — the
   clubmenu-* tokens below sit on the same shared player language (no new brand). */

.my-shell[b-u3a0osdv6o] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (the way back — the whole point of the fix). ── */
.my-backbar[b-u3a0osdv6o] {
    margin-bottom: 1rem;
}

.my-back[b-u3a0osdv6o] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.my-back:hover[b-u3a0osdv6o],
.my-back:focus-visible[b-u3a0osdv6o] {
    text-decoration: underline;
}

.my-back-caret[b-u3a0osdv6o] {
    font-weight: 700;
}

.my-head[b-u3a0osdv6o] {
    text-align: center;
    margin-bottom: 1.5rem;
}

.my-title[b-u3a0osdv6o] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
    overflow-wrap: break-word;
    word-break: break-word;
    max-width: 100%;
    min-width: 0;
}

.my-club-meta[b-u3a0osdv6o] {
    margin: 0.15rem 0 0;
    color: #5e748a;
    font-size: 0.9rem;
}

.my-section[b-u3a0osdv6o] {
    margin-bottom: 2rem;
}

.my-section-title[b-u3a0osdv6o] {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 0 0 0.85rem;
    font-weight: 700;
}

/* ── Roster list. ── */
.my-roster-list[b-u3a0osdv6o] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.my-roster-row[b-u3a0osdv6o] {
    position: relative; /* SPEC-32 S7: anchor for the .my-roster-stretch full-row tap overlay */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.65rem 0.9rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    font-size: 0.95rem;
}

.my-roster-row.is-you[b-u3a0osdv6o] {
    border-color: #1b6ec2;
    background: #f2f8fe;
}

.my-roster-name[b-u3a0osdv6o] {
    min-width: 0;
    overflow-wrap: break-word;
    font-weight: 600;
    color: #16324f;
}

/* SPEC-32 S7 (#191): a clubmate name is a link to their Public-lens profile — brand blue, clean by
   default, underlined on hover/focus. The "You" row stays a plain <span> in the default name colour. */
.my-roster-link[b-u3a0osdv6o] {
    text-decoration: none;
    color: #1b6ec2;
}

.my-roster-link:hover[b-u3a0osdv6o],
.my-roster-link:focus-visible[b-u3a0osdv6o] {
    text-decoration: underline;
}

/* SPEC-32 S7 (#191): make the WHOLE roster row the tap target (matching the full-row .clubmenu-item
   pattern), not just the ~96px name text — a stretched-link ::after overlay covers the 44px row. The
   rating span stays visible; tapping anywhere on the row follows the link. */
.my-roster-stretch[b-u3a0osdv6o]::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 0.6rem; /* match .my-roster-row */
}

/* Focus ring traces the whole row (via the stretched overlay), not the name-sized box. */
.my-roster-stretch:focus-visible[b-u3a0osdv6o] {
    outline: none;
}

.my-roster-stretch:focus-visible[b-u3a0osdv6o]::after {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

.my-roster-rating[b-u3a0osdv6o] {
    flex: 0 0 auto;
    color: #47586b;
    font-variant-numeric: tabular-nums;
}

/* ── Empty / error state (matches /my-nights' empty tokens). ── */
.my-empty[b-u3a0osdv6o] {
    font-size: 0.95rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
}

/* ─────────────────────── #864 (A1): the club MENU (mock 02) ─────────────────────── */

/* Club header card. */
.clubmenu-card[b-u3a0osdv6o] {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.9rem 1rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    margin-bottom: 1.1rem;
}

.clubmenu-badge[b-u3a0osdv6o] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: 0.6rem;
    background: #0d2c55;
    color: #fff;
    font-weight: 800;
    font-size: 1.15rem;
}

.clubmenu-card-body[b-u3a0osdv6o] {
    min-width: 0;
}

.clubmenu-card-name[b-u3a0osdv6o] {
    /* ux Finding #5: this is the page <h1> now (was a div) - zero the UA heading margin so the
       header card looks byte-identical; the font-size/weight below already override the UA h1 size. */
    margin: 0;
    font-size: 1.1rem;
    font-weight: 800;
    color: #16324f;
    overflow-wrap: break-word;
    word-break: break-word;
}

.clubmenu-card-meta[b-u3a0osdv6o] {
    color: #5e748a;
    font-size: 0.9rem;
}

/* Enter-CTA — the top item when a session is live (green-lit). */
.clubmenu-enter-cta[b-u3a0osdv6o] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.9rem 1rem;
    margin-bottom: 1.1rem;
    background: #0f7a3d;
    background: linear-gradient(180deg, #12894a 0%, #0f7a3d 100%);
    border: 1px solid #0c6a35;
    border-radius: 0.7rem;
    color: #fff;
    text-decoration: none;
}

.clubmenu-enter-cta:hover[b-u3a0osdv6o],
.clubmenu-enter-cta:focus-visible[b-u3a0osdv6o] {
    filter: brightness(1.05);
    outline: none;
}

.clubmenu-enter-ico[b-u3a0osdv6o] {
    flex: 0 0 auto;
    font-size: 1.5rem;
    line-height: 1;
}

.clubmenu-enter-body[b-u3a0osdv6o] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.clubmenu-enter-title[b-u3a0osdv6o] {
    font-weight: 800;
    font-size: 1rem;
}

.clubmenu-enter-sub[b-u3a0osdv6o] {
    font-size: 0.85rem;
    opacity: 0.92;
}

.clubmenu-enter-go[b-u3a0osdv6o] {
    flex: 0 0 auto;
    font-size: 1.2rem;
    font-weight: 700;
}

/* Quiet-night line (no live session). */
.clubmenu-quiet[b-u3a0osdv6o] {
    padding: 0.9rem 1rem;
    margin-bottom: 1.1rem;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.7rem;
    color: #47586b;
    font-size: 0.92rem;
    text-align: center;
}

/* IR-S3: wrapper for the relocated per-club rating card (the shared ProfileRatingSection, styled by
   the global profile.css). Only spacing lives here - the card chrome (border/bg) is the child
   component's .profile-section, reached via the non-scoped global stylesheet. Matches the mock's
   record-card rhythm (1rem below the primary-action block, above the Playing group). */
.clubmenu-record[b-u3a0osdv6o] {
    display: block;
    margin-bottom: 1.1rem;
}

/* Group label (Playing / Club) with a "Your access" tag. */
.clubmenu-group-label[b-u3a0osdv6o] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 1.2rem 0 0.55rem;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    font-weight: 700;
}

.clubmenu-tag[b-u3a0osdv6o] {
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.7rem;
    font-weight: 700;
    color: #1b6ec2;
    background: #eaf3fb;
    border: 1px solid #cfe4f7;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
}

/* Menu row (link or static info row). >=44px tap target, no hover-only affordances. */
.clubmenu-item[b-u3a0osdv6o] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    min-height: 52px;
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.45rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    color: #16324f;
    text-decoration: none;
    box-sizing: border-box;
}

a.clubmenu-item:hover[b-u3a0osdv6o],
a.clubmenu-item:focus-visible[b-u3a0osdv6o] {
    border-color: #1b6ec2;
    background: #f7fbff;
    outline: none;
}

/* A non-actionable info row (Upcoming, until a schedule surface exists) reads as text,
   not a tappable link — no hover affordance, muted. */
.clubmenu-item.is-static[b-u3a0osdv6o] {
    cursor: default;
}

.clubmenu-ico[b-u3a0osdv6o] {
    flex: 0 0 auto;
    font-size: 1.2rem;
    line-height: 1;
    width: 1.6rem;
    text-align: center;
}

.clubmenu-body[b-u3a0osdv6o] {
    display: flex;
    flex-direction: column;
    min-width: 0;
    flex: 1 1 auto;
}

.clubmenu-t[b-u3a0osdv6o] {
    font-weight: 700;
    font-size: 0.98rem;
    color: #16324f;
}

.clubmenu-m[b-u3a0osdv6o] {
    font-size: 0.82rem;
    color: #5e748a;
    overflow-wrap: break-word;
}

/* SPEC-34 S6: the "Your fixtures" upcoming-count badge, inline after the item title. */
.clubmenu-count[b-u3a0osdv6o] {
    display: inline-block;
    min-width: 1.2rem;
    padding: 0 0.35rem;
    margin-left: 0.35rem;
    font-size: 0.72rem;
    font-weight: 800;
    line-height: 1.35rem;
    text-align: center;
    color: #ffffff;
    background: #006bb7;
    border-radius: 0.7rem;
    vertical-align: middle;
}

/* SPEC-30 S6 #109(a): the "Next:" / "Then:" upcoming lines are two adjacent .clubmenu-m in the
   flex-column body (no gap), so they render flush. A small top margin on the second-and-later
   line separates the cadence lines without looking gappy. */
.clubmenu-m + .clubmenu-m[b-u3a0osdv6o] {
    margin-top: 0.15rem;
}

.clubmenu-go[b-u3a0osdv6o] {
    flex: 0 0 auto;
    font-size: 1.2rem;
    color: #9aa9b8;
    font-weight: 700;
}

/* Members disclosure (native <details>): the summary row IS a menu item; the roster
   reveals below it. Remove the default marker so only our caret shows. */
.clubmenu-members[b-u3a0osdv6o] {
    margin-bottom: 0.45rem;
}

.clubmenu-members-summary[b-u3a0osdv6o] {
    margin-bottom: 0;
    cursor: pointer;
    list-style: none;
}

.clubmenu-members-summary[b-u3a0osdv6o]::-webkit-details-marker {
    display: none;
}

.clubmenu-members-summary:hover[b-u3a0osdv6o],
.clubmenu-members-summary:focus-visible[b-u3a0osdv6o] {
    border-color: #1b6ec2;
    background: #f7fbff;
    outline: none;
}

.clubmenu-members[open] > .clubmenu-members-summary[b-u3a0osdv6o] {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-color: #1b6ec2;
}

.clubmenu-members-caret[b-u3a0osdv6o] {
    transition: transform 0.15s ease;
}

.clubmenu-members[open] .clubmenu-members-caret[b-u3a0osdv6o] {
    transform: rotate(90deg);
}

/* The revealed roster sits in a bordered well flush under the summary. */
.clubmenu-roster[b-u3a0osdv6o] {
    border: 1px solid #1b6ec2;
    border-top: none;
    border-radius: 0 0 0.6rem 0.6rem;
    padding: 0.7rem 0.9rem 0.9rem;
    background: #fbfdff;
}

.clubmenu-roster .my-roster-list[b-u3a0osdv6o] {
    margin-top: 0;
}

/* ──────── #1033/#87: the navy "Manage this club" gateway door (promoted primary) ──────── */

/* #87: PROMOTED to a prominent PRIMARY action near the top of the club page. The card echoes the
   green .clubmenu-enter-cta primary look (matched padding + icon size + a bold title) but stays ONE
   NOTCH quieter so the green enter-CTA remains dominant when both are stacked (live organiser):
   the hierarchy is carried by colour (vibrant green gradient = act now vs flat navy = console),
   ORDER (green first), and title weight (green 800 vs navy 700). A solid navy-filled card that
   overrides the base .clubmenu-item light-bg/dark-text tokens on its children so title/subtitle/
   icon/chevron are all legible on navy. (Renamed from the retired #865 `committee` warm-accent
   group - one door now, so an intent-revealing `manage` modifier replaces the old family name.) */
.clubmenu-item.manage[b-u3a0osdv6o] {
    padding: 0.9rem 1rem; /* #87: match .clubmenu-enter-cta heft (base is 0.7rem 0.9rem). */
    background: #0d2c55;
    border-color: #0d2c55;
}

.clubmenu-item.manage .clubmenu-t[b-u3a0osdv6o] {
    color: #fff;
    /* #87: primary weight/size echoing .clubmenu-enter-title, kept below its 800 so green wins. */
    font-weight: 700;
    font-size: 1rem;
}

.clubmenu-item.manage .clubmenu-m[b-u3a0osdv6o] {
    color: #b8c6da;
}

.clubmenu-item.manage .clubmenu-ico[b-u3a0osdv6o] {
    color: #b8c6da;
    font-size: 1.5rem; /* #87: match .clubmenu-enter-ico prominence (base is 1.2rem). */
}

.clubmenu-item.manage .clubmenu-go[b-u3a0osdv6o] {
    color: #b8c6da;
}

/* Hover/focus lift to a lighter navy so it still reads as tappable. */
a.clubmenu-item.manage:hover[b-u3a0osdv6o],
a.clubmenu-item.manage:focus-visible[b-u3a0osdv6o] {
    background: #16386b;
    border-color: #16386b;
}

/* Keep an accessible focus ring - the base rule zeroes the outline, so restore a
   light ring that's visible against the navy fill. */
a.clubmenu-item.manage:focus-visible[b-u3a0osdv6o] {
    outline: 2px solid #9ec2ff;
    outline-offset: 2px;
}
/* /Components/Pages/PlayerClubInsights.razor.rz.scp.css */
/* #1044 (portal-followups): the player-native club Insights surface. Same centred card column
   + visual tokens as the rest of the player shell (/my-club/{slug}, /my-nights) — NO new brand.
   Scoped per component (the PegboardWeb per-page .razor.css pattern). Everything renders static
   SSR: charts are inline SVG sparklines / CSS bars / static tables, never interactive Chart.js. */

.pins-shell[b-l605yssxp7] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar. ── */
.pins-backbar[b-l605yssxp7] {
    margin-bottom: 1rem;
}

.pins-back[b-l605yssxp7] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.pins-back:hover[b-l605yssxp7],
.pins-back:focus-visible[b-l605yssxp7] {
    text-decoration: underline;
}

.pins-back-caret[b-l605yssxp7] {
    font-weight: 700;
}

/* ── Head. ── */
.pins-head[b-l605yssxp7] {
    margin-bottom: 1.5rem;
}

.pins-title[b-l605yssxp7] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
}

.pins-sub[b-l605yssxp7] {
    margin: 0;
    color: #5e748a;
    font-size: 0.92rem;
}

/* ── One report block (a card). ── */
.pins-report[b-l605yssxp7] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    padding: 1rem 1.1rem 1.1rem;
    margin-bottom: 1.1rem;
}

.pins-report-head[b-l605yssxp7] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
}

.pins-report-head h2[b-l605yssxp7] {
    font-size: 1.1rem;
    font-weight: 800;
    color: #16324f;
    margin: 0;
}

.pins-report-meta[b-l605yssxp7] {
    flex: 0 0 auto;
    font-size: 0.78rem;
    color: #8496a8;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
}

/* ── Metric tiles. ── */
.pins-tiles[b-l605yssxp7] {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.6rem;
}

.pins-tile[b-l605yssxp7] {
    background: #f6f9fc;
    border: 1px solid #e2e8f0;
    border-radius: 0.55rem;
    padding: 0.65rem 0.6rem;
    text-align: center;
    min-width: 0;
}

.pins-tile-val[b-l605yssxp7] {
    font-size: 1.35rem;
    font-weight: 800;
    color: #16324f;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.pins-tile-lab[b-l605yssxp7] {
    margin-top: 0.15rem;
    font-size: 0.72rem;
    color: #5e748a;
    line-height: 1.2;
}

/* ── Horizontal bars (match-quality planned-closeness). ── */
.pins-bars[b-l605yssxp7] {
    margin-top: 0.95rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.pins-bar-row[b-l605yssxp7] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.85rem;
}

.pins-bar-lab[b-l605yssxp7] {
    flex: 0 0 4.2rem;
    color: #47586b;
    font-weight: 600;
}

.pins-bar-track[b-l605yssxp7] {
    flex: 1 1 auto;
    height: 0.65rem;
    background: #eef2f7;
    border-radius: 999px;
    overflow: hidden;
}

.pins-bar-fill[b-l605yssxp7] {
    display: block;
    height: 100%;
    background: #1b6ec2;
    border-radius: 999px;
}

.pins-bar-val[b-l605yssxp7] {
    flex: 0 0 2.6rem;
    text-align: right;
    color: #16324f;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

/* ── Leaderboard (most improved). ── */
.pins-lead[b-l605yssxp7] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.pins-lead-row[b-l605yssxp7] {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0.65rem;
    background: #f9fbfd;
    border: 1px solid #eaeff5;
    border-radius: 0.55rem;
}

.pins-lead-rk[b-l605yssxp7] {
    flex: 0 0 1.4rem;
    text-align: center;
    font-weight: 800;
    color: #8496a8;
    font-variant-numeric: tabular-nums;
}

.pins-lead-who[b-l605yssxp7] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.pins-lead-nm[b-l605yssxp7] {
    font-weight: 700;
    color: #16324f;
    overflow-wrap: break-word;
}

.pins-lead-meta[b-l605yssxp7] {
    font-size: 0.78rem;
    color: #5e748a;
    font-variant-numeric: tabular-nums;
}

.pins-lead-delta[b-l605yssxp7] {
    flex: 0 0 auto;
    font-weight: 800;
    color: #0f7a3d;
    font-variant-numeric: tabular-nums;
}

.pins-lead-delta.neg[b-l605yssxp7] {
    color: #b4232a;
}

.pins-spark[b-l605yssxp7],
.pins-lead .pins-spark[b-l605yssxp7] {
    flex: 0 0 auto;
    color: #1b6ec2;
}

.pins-spark-wide[b-l605yssxp7] {
    margin-top: 0.9rem;
    color: #1b6ec2;
    text-align: center;
}

.pins-spark-wide .pins-spark[b-l605yssxp7] {
    width: 100%;
    max-width: 22rem;
    height: 42px;
}

/* ── Tables (partnerships, recent sessions). ── */
.pins-table-wrap[b-l605yssxp7] {
    overflow-x: auto;
}

.pins-table[b-l605yssxp7] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

.pins-table th[b-l605yssxp7],
.pins-table td[b-l605yssxp7] {
    text-align: left;
    padding: 0.5rem 0.55rem;
    border-bottom: 1px solid #eef2f7;
    white-space: nowrap;
}

.pins-table th[b-l605yssxp7] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #8496a8;
    font-weight: 700;
}

.pins-table td:first-child[b-l605yssxp7] {
    white-space: normal;
    color: #16324f;
    font-weight: 600;
}

.pins-table .num[b-l605yssxp7] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Verdict pill. */
.pins-pill[b-l605yssxp7] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    border: 1px solid transparent;
}

.pins-pill.over[b-l605yssxp7] {
    color: #0f7a3d;
    background: #e7f6ed;
    border-color: #bfe6cd;
}

.pins-pill.under[b-l605yssxp7] {
    color: #b4232a;
    background: #fdecec;
    border-color: #f4c9c9;
}

.pins-pill.even[b-l605yssxp7] {
    color: #47586b;
    background: #eef2f7;
    border-color: #dbe3ec;
}

/* ── Notes + empty/error states. ── */
.pins-note[b-l605yssxp7] {
    margin: 0.7rem 0 0;
    font-size: 0.8rem;
    color: #8496a8;
}

.pins-empty[b-l605yssxp7] {
    margin: 0;
    font-size: 0.9rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.55rem;
    padding: 0.8rem 0.9rem;
}
/* /Components/Pages/PlayerClubs.razor.rz.scp.css */
/* #856 (Portal PF3): the player Clubs page — Find a club, My clubs (role badge + Set as
   primary), Create a new club. Same centred card column + visual tokens as /my-nights,
   /my-clubs-played and the /my-club/{slug} detail page (one shared player language, NO new
   brand: navy #16324f, blue #1b6ec2 / #006bb7, off-white cards). Scoped per component (the
   PegboardWeb per-page .razor.css pattern), so every token used is defined here. Built to mock 04. */

.my-shell[b-r6lwn1w7n5] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (Back + centred title, the shared navigational component). ── */
.my-backbar[b-r6lwn1w7n5] {
    display: flex;
    align-items: center;
    margin-bottom: 1rem;
    position: relative;
}

.my-back[b-r6lwn1w7n5] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
    z-index: 1;
}

.my-back:hover[b-r6lwn1w7n5],
.my-back:focus-visible[b-r6lwn1w7n5] {
    text-decoration: underline;
}

.my-back-caret[b-r6lwn1w7n5] {
    font-weight: 700;
}

.my-backbar-title[b-r6lwn1w7n5] {
    position: absolute;
    left: 0;
    right: 0;
    text-align: center;
    font-weight: 800;
    font-size: 1.1rem;
    color: #16324f;
    pointer-events: none;
}

/* ── Cards. ── */
.my-card[b-r6lwn1w7n5] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1.1rem 1.15rem;
    margin-bottom: 1.25rem;
}

.my-card-title[b-r6lwn1w7n5] {
    font-size: 1rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.85rem;
}

/* ── Single-club hero card (unified-post-login-landing Slice 2, C2 / AC2.1-AC2.2): a one-club
   account's club rendered front-and-centre — the centred door-card shape reused (enlarged badge,
   large name, meta), with a full-width primary "Open club ->" button. No new brand: reuses .my-card,
   .clubs-badge, .clubs-role-badge, .clubs-live and the .my-btn tokens; only additive layout below. ── */
.club-hero[b-r6lwn1w7n5] {
    text-align: center;
    padding: 1.6rem 1.15rem;
}

/* Enlarge + centre the reused navy badge (override .clubs-badge's inline-flex/size). */
.club-hero-badge[b-r6lwn1w7n5] {
    display: flex;
    width: 3.25rem;
    height: 3.25rem;
    font-size: 1.5rem;
    margin: 0 auto 0.65rem;
}

.club-hero-name[b-r6lwn1w7n5] {
    font-weight: 800;
    font-size: 1.35rem;
    color: #16324f;
    margin: 0 0 0.4rem;
    overflow-wrap: break-word;
}

.club-hero-meta[b-r6lwn1w7n5] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    color: #5e748a;
    font-size: 0.9rem;
}

.club-hero-dot[b-r6lwn1w7n5] {
    color: #a9b6c4;
}

/* Centre the reused Live-now pill under the meta. */
.club-hero .clubs-live[b-r6lwn1w7n5] {
    justify-content: center;
    margin: 0.4rem auto 0;
}

.club-hero-open[b-r6lwn1w7n5] {
    margin-top: 1.1rem;
}

/* ── Buttons (shared player button tokens). ── */
.my-btn[b-r6lwn1w7n5] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.5rem 0.95rem;
    border-radius: 0.55rem;
    font-weight: 700;
    font-size: 0.95rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    white-space: nowrap;
}

.my-btn-primary[b-r6lwn1w7n5] {
    background: #1b6ec2;
    color: #fff;
}

.my-btn-primary:hover[b-r6lwn1w7n5],
.my-btn-primary:focus-visible[b-r6lwn1w7n5] {
    background: #155ba3;
}

.my-btn-secondary[b-r6lwn1w7n5] {
    background: #fff;
    color: #1b6ec2;
    border-color: #1b6ec2;
}

.my-btn-secondary:hover[b-r6lwn1w7n5],
.my-btn-secondary:focus-visible[b-r6lwn1w7n5] {
    background: #f2f8fe;
}

.my-btn-block[b-r6lwn1w7n5] {
    display: flex;
    width: 100%;
}

/* ── Links. ── */
.my-link[b-r6lwn1w7n5] {
    color: #006bb7;
    text-decoration: none;
    font-weight: 700;
    white-space: nowrap;
}

.my-link:hover[b-r6lwn1w7n5],
.my-link:focus-visible[b-r6lwn1w7n5] {
    text-decoration: underline;
}

/* ── Club rows (My clubs + search results). ── */
.clubs-list[b-r6lwn1w7n5] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.clubs-row[b-r6lwn1w7n5] {
    border: 1px solid #e2e8f0;
    border-radius: 0.6rem;
    padding: 0.7rem 0.85rem;
    background: #fff;
}

.clubs-row-top[b-r6lwn1w7n5],
.clubs-row[b-r6lwn1w7n5] {
    display: flex;
}

.clubs-row[b-r6lwn1w7n5] {
    flex-direction: column;
    gap: 0.5rem;
}

.clubs-row-top[b-r6lwn1w7n5] {
    align-items: center;
    gap: 0.7rem;
}

.clubs-badge[b-r6lwn1w7n5] {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: #0d2c55;
    color: #fff;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 0.95rem;
}

.clubs-row-body[b-r6lwn1w7n5] {
    flex: 1 1 auto;
    min-width: 0;
}

.clubs-row-name[b-r6lwn1w7n5] {
    font-weight: 700;
    color: #16324f;
    overflow-wrap: break-word;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.clubs-row-meta[b-r6lwn1w7n5] {
    color: #5e748a;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.clubs-row-open[b-r6lwn1w7n5] {
    flex: 0 0 auto;
}

/* ── Role badge. ── */
.clubs-role-badge[b-r6lwn1w7n5] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: #e6eef7;
    color: #16324f;
}

.clubs-role-badge.is-player[b-r6lwn1w7n5] {
    background: #eaf5ec;
    color: #226b39;
}

/* ── Row foot: primary flag / set-primary. ── */
.clubs-row-foot[b-r6lwn1w7n5] {
    display: flex;
    align-items: center;
    padding-left: 2.8rem; /* align under the row body, past the badge */
}

.clubs-primary-flag[b-r6lwn1w7n5] {
    color: #b8860b;
    font-weight: 700;
    font-size: 0.85rem;
}

.clubs-setprimary-form[b-r6lwn1w7n5] {
    margin: 0;
}

.clubs-setprimary[b-r6lwn1w7n5] {
    background: none;
    border: none;
    padding: 0.35rem 0;
    min-height: 40px;
    color: #006bb7;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    text-align: left;
}

.clubs-setprimary:hover[b-r6lwn1w7n5],
.clubs-setprimary:focus-visible[b-r6lwn1w7n5] {
    text-decoration: underline;
}

/* ── Banners (confirmation / no-match / error). ── */
.clubs-banner[b-r6lwn1w7n5] {
    border-radius: 0.6rem;
    padding: 0.7rem 0.9rem;
    font-size: 0.9rem;
    margin: 0.85rem 0 0;
}

.clubs-banner-ok[b-r6lwn1w7n5] {
    background: #eaf5ec;
    border: 1px solid #bfe0c7;
    color: #226b39;
    margin: 0 0 1rem;
}

.clubs-banner-error[b-r6lwn1w7n5] {
    background: #fdecec;
    border: 1px solid #f3c9c9;
    color: #9a2222;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* The Retry link in the error banner — re-runs the same query. */
.clubs-retry[b-r6lwn1w7n5] {
    flex: 0 0 auto;
    color: #9a2222;
    font-weight: 700;
    text-decoration: underline;
    white-space: nowrap;
}

.clubs-retry:hover[b-r6lwn1w7n5],
.clubs-retry:focus-visible[b-r6lwn1w7n5] {
    color: #7a1717;
}

/* ── Empty state (matches the shared player empty token). ── */
.my-empty[b-r6lwn1w7n5] {
    font-size: 0.95rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
}

.clubs-empty-title[b-r6lwn1w7n5] {
    display: block;
    font-weight: 700;
    color: #16324f;
}

.clubs-empty-desc[b-r6lwn1w7n5] {
    display: block;
    margin-top: 0.3rem;
}

/* ── #866 (A3): "Live now" pill on a club row with a session running now (mock 01). Green
   status token; a pulsing blip + label. Sits in the row body under the meta line. ── */
.clubs-live[b-r6lwn1w7n5] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.3rem;
    color: #1a7a3c;
    font-weight: 700;
    font-size: 0.82rem;
}

.clubs-live-blip[b-r6lwn1w7n5] {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: #24a148;
    box-shadow: 0 0 0 0 rgba(36, 161, 72, 0.5);
    animation: clubs-live-pulse-b-r6lwn1w7n5 1.8s ease-out infinite;
}

@keyframes clubs-live-pulse-b-r6lwn1w7n5 {
    0% { box-shadow: 0 0 0 0 rgba(36, 161, 72, 0.5); }
    70% { box-shadow: 0 0 0 0.5rem rgba(36, 161, 72, 0); }
    100% { box-shadow: 0 0 0 0 rgba(36, 161, 72, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .clubs-live-blip[b-r6lwn1w7n5] { animation: none; }
}

/* ── The on-ramp action row. Post unified-post-login-landing Slice 2 this is Create-a-club only
   (the "Join a club" button was removed). AC2.3: with the club(s) the focus, this lone secondary
   button must read as a MODEST action, not a full-bleed second CTA — so it sizes to content and
   is centred below the club(s), not stretched across the row (which made it wider than the primary
   "Open club" button). Applies to both the single-club hero and the multi-club list. ── */
.clubs-onramp[b-r6lwn1w7n5] {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    justify-content: center;
}

.clubs-onramp .my-btn[b-r6lwn1w7n5] {
    flex: 0 1 auto;
    max-width: 16rem;
}

/* ── #866 (A3): the zero-club on-ramp SCREEN - the Create-a-club door (plus the demo nudge) becomes
   the whole surface for a brand-new account (the Join door was removed, unified-post-login-landing
   Slice 2). Centred card with a glyph, title, blurb, block CTA. ── */
.clubs-onramp-screen[b-r6lwn1w7n5] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.clubs-onramp-title[b-r6lwn1w7n5] {
    font-size: 1.35rem;
    font-weight: 800;
    color: #16324f;
    margin: 0 0 0.2rem;
}

.clubs-onramp-lead[b-r6lwn1w7n5] {
    color: #5e748a;
    margin: 0 0 0.4rem;
    font-size: 0.95rem;
}

.clubs-door[b-r6lwn1w7n5] {
    text-align: center;
    margin-bottom: 0; /* the screen's flex gap handles spacing */
}

.clubs-door-glyph[b-r6lwn1w7n5] {
    font-size: 2rem;
    line-height: 1;
}

.clubs-door-title[b-r6lwn1w7n5] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.05rem;
    margin: 0.4rem 0 0.2rem;
}

.clubs-door-desc[b-r6lwn1w7n5] {
    color: #5e748a;
    font-size: 0.9rem;
    margin: 0 0 0.8rem;
}

/* /Components/Pages/PlayerClubSessions.razor.rz.scp.css */
/* IR-S1 (Portal IA refresh): the club Sessions list (/my-club/{slug}/sessions). Same centred card
   column + visual tokens as the rest of the player shell (PlayerClubDetail / MyNights) — one shared
   language, NO new brand. Scoped per component (the PegboardWeb per-page .razor.css pattern), so the
   shared .my-* tokens are re-declared here rather than inherited (Blazor CSS isolation). */

.my-shell[b-ns1nj4psxk] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (the way back — always present). ── */
.my-backbar[b-ns1nj4psxk] {
    margin-bottom: 1rem;
}

.my-back[b-ns1nj4psxk] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.my-back:hover[b-ns1nj4psxk],
.my-back:focus-visible[b-ns1nj4psxk] {
    text-decoration: underline;
}

.my-back-caret[b-ns1nj4psxk] {
    font-weight: 700;
}

/* ── Header. ── */
.my-head[b-ns1nj4psxk] {
    margin-bottom: 1.25rem;
}

.my-title[b-ns1nj4psxk] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
    overflow-wrap: break-word;
    word-break: break-word;
}

.my-club-meta[b-ns1nj4psxk] {
    margin: 0.15rem 0 0;
    color: #5e748a;
    font-size: 0.9rem;
}

/* ── Generic empty / error line (shared token). ── */
.my-empty[b-ns1nj4psxk] {
    font-size: 0.95rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
}

.cs-retry[b-ns1nj4psxk] {
    color: #006bb7;
    font-weight: 600;
    text-decoration: none;
}

.cs-retry:hover[b-ns1nj4psxk],
.cs-retry:focus-visible[b-ns1nj4psxk] {
    text-decoration: underline;
}

/* ── IR-S2: "Next up" — upcoming sessions as NON-ACTIONABLE info cards at the TOP of the list.
   Same card surface as the past-night rows (.cs-row tokens) but with NO link affordance: no hover
   lift, default cursor, no chevron. Capacity is a signal, never a control (the anti-booking wall). ── */
.cs-section-head[b-ns1nj4psxk] {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    font-weight: 700;
    margin: 0 0 0.55rem;
}

/* The "Past nights" heading sits below "Next up"; give it a little breathing room from the section above. */
.cs-section-head-past[b-ns1nj4psxk] {
    margin-top: 1.5rem;
}

.cs-nextup[b-ns1nj4psxk] {
    margin-bottom: 1.5rem;
}

.cs-nextup-card[b-ns1nj4psxk] {
    padding: 0.8rem 0.95rem;
    /* Faint tint (the shared empty-state panel token, cf. .cs-empty / .my-empty) rather than the
       tappable past-row white — a resting-state cue that this is a NON-ACTIONABLE info panel, not a
       link. Touch/kiosk users never see the .cs-row hover lift, so at-rest colour is the only cue. */
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.7rem;
    cursor: default; /* an info card, not a link */
}

.cs-nextup-card + .cs-nextup-card[b-ns1nj4psxk] {
    margin-top: 0.5rem;
}

.cs-nextup-when[b-ns1nj4psxk] {
    font-weight: 700;
    color: #16324f;
    font-size: 0.98rem;
}

.cs-nextup-name[b-ns1nj4psxk] {
    color: #5e748a;
    font-size: 0.82rem; /* matches .cs-row-sub (finding #3) */
    margin-top: 0.1rem;
}

.cs-nextup-cap[b-ns1nj4psxk] {
    margin-top: 0.5rem;
}

/* ── My / All segmented filter (mirrors the /me tab bar: WCAG touch-sized, no hover-only). ── */
.cs-seg[b-ns1nj4psxk] {
    display: flex;
    gap: 0.25rem;
    background: #eef3f8;
    border: 1px solid #dde7f0;
    border-radius: 0.7rem;
    padding: 0.25rem;
    margin-bottom: 1.5rem; /* matches the shipped .me-tabbar */
}

.cs-seg-btn[b-ns1nj4psxk] {
    flex: 1 1 0;
    text-align: center;
    padding: 0.6rem 0.4rem;
    min-height: 2.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.5rem;
    text-decoration: none;
    color: #47586b;
    font-weight: 600;
    font-size: 0.95rem;
    transition: background 0.12s ease, color 0.12s ease;
}

.cs-seg-btn:hover[b-ns1nj4psxk],
.cs-seg-btn:focus-visible[b-ns1nj4psxk] {
    color: #16324f;
}

.cs-seg-btn.on[b-ns1nj4psxk] {
    background: #fff;
    color: #0d2c55;
    box-shadow: 0 1px 3px rgba(13, 44, 85, 0.12);
}

/* Private-club note (History OFF: only My is available; the whole segmented control is hidden). */
.cs-private[b-ns1nj4psxk] {
    margin: 0 0 1.5rem;
    color: #5e748a;
    font-size: 0.88rem;
}

/* ── Night rows. The whole row is the link to the shared recap. ── */
.cs-list[b-ns1nj4psxk] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.cs-row[b-ns1nj4psxk] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 44px;
    padding: 0.8rem 0.95rem;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.7rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.cs-row:hover[b-ns1nj4psxk],
.cs-row:focus-visible[b-ns1nj4psxk] {
    border-color: #1b6ec2;
    box-shadow: 0 4px 14px rgba(27, 110, 194, 0.10);
}

.cs-row-main[b-ns1nj4psxk] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.cs-row-when[b-ns1nj4psxk] {
    font-weight: 700;
    color: #16324f;
    font-size: 0.98rem;
}

.cs-row-sub[b-ns1nj4psxk] {
    color: #5e748a;
    font-size: 0.82rem;
}

/* IR journey-fix #4: "Live" badge on an All-nights row whose session is still running (started, not
   ended) yet already has completed games. Same green "live" language as the club-menu / clubs list
   Live-now pill (blip + uppercase), so a live night reads as live wherever it surfaces. */
.cs-live[b-ns1nj4psxk] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #1c6b3f; /* clears 4.5:1 on the pale-green fill */
    border-radius: 999px;
    padding: 0.2rem 0.55rem;
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.cs-live-blip[b-ns1nj4psxk] {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: #2f9e6f;
}

/* All-row summary chip ("12 players · 8 games"). */
.cs-chip[b-ns1nj4psxk] {
    flex: 0 0 auto;
    background: #eef2f7;
    border: 1px solid #d7dee7;
    color: #47586b;
    border-radius: 999px;
    padding: 0.2rem 0.6rem;
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
}

/* My-row rating-change delta chip. */
.cs-delta[b-ns1nj4psxk] {
    flex: 0 0 auto;
    min-width: 3rem;
    text-align: center;
    border-radius: 999px;
    padding: 0.2rem 0.55rem;
    font-weight: 700;
    font-size: 0.82rem;
    font-variant-numeric: tabular-nums;
}

.cs-delta-up[b-ns1nj4psxk] {
    background: #f0fdf4;
    border: 1px solid #bbf7d0;
    color: #2f7d52; /* WCAG: clears 4.5:1 on the pale-green chip fill */
}

.cs-delta-down[b-ns1nj4psxk] {
    background: #fdecec;
    border: 1px solid #f5b5b5;
    color: #c0392b;
}

.cs-delta-flat[b-ns1nj4psxk] {
    background: #f1f5f9;
    border: 1px solid #d7dee7;
    color: #5e748a;
}

/* ── My-nights / no-past empty state. ── */
.cs-empty[b-ns1nj4psxk] {
    text-align: center;
    padding: 1.6rem 1rem;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.7rem;
}

.cs-empty-title[b-ns1nj4psxk] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.02rem;
    margin-bottom: 0.35rem;
}

.cs-empty-body[b-ns1nj4psxk] {
    margin: 0;
    color: #5e748a;
    font-size: 0.9rem;
}
/* /Components/Pages/PlayerFixtures.razor.rz.scp.css */
/* SPEC-34 S6: the player "Your fixtures" surface (/my-club/{slug}/fixtures). Same centred card
   column + visual tokens as the rest of the player shell (PlayerClubSessions / PlayerClubDetail /
   MyNights) — one shared language, NO new brand. Scoped per component (the PegboardWeb per-page
   .razor.css pattern), so the shared .my-* tokens are re-declared here rather than inherited
   (Blazor CSS isolation). */

.my-shell[b-0tah3yk70s] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (the way back — always present). ── */
.my-backbar[b-0tah3yk70s] {
    margin-bottom: 1rem;
}

.my-back[b-0tah3yk70s] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px; /* touch target */
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.my-back:hover[b-0tah3yk70s],
.my-back:focus-visible[b-0tah3yk70s] {
    text-decoration: underline;
}

.my-back-caret[b-0tah3yk70s] {
    font-weight: 700;
}

/* ── Header. ── */
.my-head[b-0tah3yk70s] {
    margin-bottom: 1.25rem;
}

.my-title[b-0tah3yk70s] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
    overflow-wrap: break-word;
    word-break: break-word;
}

.my-club-meta[b-0tah3yk70s] {
    margin: 0.15rem 0 0;
    color: #5e748a;
    font-size: 0.9rem;
}

/* ── Generic empty / error line (shared token). The AC2 empty state is deliberately this quiet
   single line — no big heading, no stray buttons. ── */
.my-empty[b-0tah3yk70s] {
    font-size: 0.95rem;
    color: #47586b;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
}

.pfx-retry[b-0tah3yk70s] {
    color: #006bb7;
    font-weight: 600;
    text-decoration: none;
}

.pfx-retry:hover[b-0tah3yk70s],
.pfx-retry:focus-visible[b-0tah3yk70s] {
    text-decoration: underline;
}

/* ── Fixture cards. Date block + body + status tail, mirroring the captain fix-row + the /f/ banner. ── */
.pfx-list[b-0tah3yk70s] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.pfx-card[b-0tah3yk70s] {
    display: flex;
    align-items: stretch;
    gap: 0.85rem;
    padding: 0.85rem 0.95rem;
    background: #ffffff;
    border: 1px solid #dce7f1;
    border-radius: 0.7rem;
    text-decoration: none;
    color: inherit;
    box-shadow: 0 1px 2px rgba(22, 50, 79, 0.05);
    transition: box-shadow 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}

a.pfx-card:hover[b-0tah3yk70s],
a.pfx-card:focus-visible[b-0tah3yk70s] {
    border-color: #b9d3ea;
    box-shadow: 0 3px 10px rgba(22, 50, 79, 0.1);
    transform: translateY(-1px);
    outline: none;
}

/* A card with no drill-in (missing share link — a data anomaly): still a card, no hover affordance. */
.pfx-card--nolink[b-0tah3yk70s] {
    cursor: default;
    box-shadow: none;
}

.pfx-date[b-0tah3yk70s] {
    flex: 0 0 auto;
    width: 3rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #eef4fb;
    border-radius: 0.5rem;
    color: #16324f;
    padding: 0.35rem 0;
}

.pfx-date-m[b-0tah3yk70s] {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 700;
    color: #5e748a;
}

.pfx-date-d[b-0tah3yk70s] {
    font-size: 1.35rem;
    font-weight: 800;
    line-height: 1.1;
}

.pfx-body[b-0tah3yk70s] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.pfx-team[b-0tah3yk70s] {
    font-size: 0.78rem;
    font-weight: 700;
    color: #5e748a;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    overflow-wrap: break-word;
}

.pfx-vs[b-0tah3yk70s] {
    font-size: 1.02rem;
    font-weight: 700;
    color: #16324f;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.pfx-meta[b-0tah3yk70s] {
    font-size: 0.85rem;
    color: #5e748a;
}

/* Home/away pill (matches the captain fix-row pill treatment). */
.pfx-pill[b-0tah3yk70s] {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0.1rem 0.4rem;
    border-radius: 0.35rem;
}

.pfx-pill--home[b-0tah3yk70s] {
    background: #e3f1e8;
    color: #1c7a44;
}

.pfx-pill--away[b-0tah3yk70s] {
    background: #eae7f6;
    color: #5b46b0;
}

.pfx-tail[b-0tah3yk70s] {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    align-self: center;
}

/* The player's own status pill. */
.pfx-status[b-0tah3yk70s] {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.22rem 0.5rem;
    border-radius: 0.4rem;
    white-space: nowrap;
    text-align: center;
}

.pfx-status--yes[b-0tah3yk70s] {
    background: #e3f1e8;
    color: #1c7a44;
}

.pfx-status--no[b-0tah3yk70s] {
    background: #fbe6e6;
    color: #b32828;
}

.pfx-status--wait[b-0tah3yk70s] {
    background: #fdf2dc;
    color: #96690f;
}

.pfx-status--standby[b-0tah3yk70s] {
    background: #e7f0fb;
    color: #1c5fa8;
}

.pfx-status--neutral[b-0tah3yk70s] {
    background: #eef1f5;
    color: #5e748a;
}

.pfx-go[b-0tah3yk70s] {
    color: #9db3c8;
    font-size: 1.2rem;
    font-weight: 700;
}

/* Narrow screens: let the status wrap under the body rather than crushing the meta line. */
@media (max-width: 26rem) {
    .pfx-tail[b-0tah3yk70s] {
        align-self: flex-start;
    }
}
/* /Components/Pages/PublicClubPage.razor.rz.scp.css */
/* #635 (portal S8 slice 2): the public club presence page. Mobile-first, single centred
   column, self-contained (no app nav chrome) — the same public-page visual language as
   the club-night recap (SessionRecap.razor.css), which it sits alongside in the /club/
   URL space. */

.clubpage-shell[b-t2wtxo4uww] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
}

.clubpage-head[b-t2wtxo4uww] {
    text-align: center;
    margin-bottom: 1.75rem;
}

.clubpage-brand[b-t2wtxo4uww] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
}

.clubpage-brand-wordmark[b-t2wtxo4uww] {
    height: 1.75rem;
    width: auto;
}

.clubpage-title[b-t2wtxo4uww] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
}

.clubpage-section-title[b-t2wtxo4uww] {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 0 0 0.85rem;
    font-weight: 700;
}

.clubpage-schedule[b-t2wtxo4uww] {
    margin-bottom: 2rem;
}

.clubpage-empty[b-t2wtxo4uww] {
    margin: 0;
    color: #5e748a;
    font-size: 0.95rem;
}

.clubpage-session-list[b-t2wtxo4uww] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.clubpage-session[b-t2wtxo4uww] {
    background: linear-gradient(135deg, #f2f7fc 0%, #e9f1fa 100%);
    border: 1px solid #d9e6f2;
    border-radius: 0.85rem;
    padding: 0.9rem 1.05rem;
}

.clubpage-session-live[b-t2wtxo4uww] {
    border-color: #7bc47f;
    background: linear-gradient(135deg, #eefaef 0%, #e2f4e4 100%);
}

.clubpage-session-main[b-t2wtxo4uww] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.clubpage-session-title[b-t2wtxo4uww] {
    font-weight: 600;
    color: #16324f;
    font-size: 1.05rem;
}

.clubpage-live-badge[b-t2wtxo4uww] {
    display: inline-flex;
    align-items: center;
    background: #2e7d32;
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
}

.clubpage-session-meta[b-t2wtxo4uww] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    margin-top: 0.3rem;
    color: #5e748a;
    font-size: 0.92rem;
}

.clubpage-session-venue[b-t2wtxo4uww]::before {
    content: "· ";
}

/* SPEC-30 S4: the capacity SIGNAL — a plain muted line inside the meta row (inherits the muted colour), with
   the same "· " separator as venue. Deliberately NOT a badge/pill/button (anti-booking wall). */
.clubpage-session-capacity[b-t2wtxo4uww]::before {
    content: "· ";
}

.clubpage-recent[b-t2wtxo4uww] {
    margin-bottom: 2rem;
}

.clubpage-recent-list[b-t2wtxo4uww] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.clubpage-recent-link[b-t2wtxo4uww] {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    text-decoration: none;
    color: #16324f;
    padding: 0.5rem 0.65rem;
    border-radius: 0.6rem;
}

.clubpage-recent-link:hover[b-t2wtxo4uww] {
    background: #f2f7fc;
}

.clubpage-recent-link:focus-visible[b-t2wtxo4uww] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

.clubpage-recent-title[b-t2wtxo4uww] {
    font-weight: 600;
}

.clubpage-recent-when[b-t2wtxo4uww] {
    color: #5e748a;
    font-size: 0.9rem;
}

.clubpage-foot[b-t2wtxo4uww] {
    margin-top: 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid #e3ebf3;
    text-align: center;
}

.clubpage-foot-cta[b-t2wtxo4uww] {
    margin: 0;
    color: #5e748a;
    font-size: 0.9rem;
}

.clubpage-foot-link[b-t2wtxo4uww] {
    color: #16324f;
    text-decoration: none;
}

.clubpage-foot-link:hover[b-t2wtxo4uww] {
    text-decoration: underline;
}

.clubpage-foot-link:focus-visible[b-t2wtxo4uww] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}
/* /Components/Pages/RegularSessionsCard.razor.rz.scp.css */
/* SPEC-30 S2 — the "Regular sessions" card.
   CSS ISOLATION NOTE: this is a CHILD component, so the parent ClubSessions/Settings scoped classes it reuses
   (clubSessions-card, clubSession-time-group, clubSession-delete-modal, settings-message, and friends) do NOT
   match under Blazor scoping (different scope id). The chrome, HH:MM picker, and confirm-modal rules those
   classes carry are therefore duplicated verbatim here so the child renders correctly. Bootstrap globals
   (buttons, form controls, text helpers) are unaffected and are not duplicated. Keep these in sync with
   ClubSessions.razor.css. */

.clubSessions-card[b-you6n98xbf] {
    border: 1px solid rgba(92, 119, 145, 0.3);
    border-radius: 0.65rem;
    background: #ffffff;
    padding: 1rem;
    margin-bottom: 1rem;
    box-shadow: 0 0.15rem 0.35rem rgba(17, 35, 53, 0.06);
}

.clubSessions-card-header[b-you6n98xbf] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    gap: 0.75rem;
}

.clubSessions-help[b-you6n98xbf] {
    color: #4b5f75;
    font-size: 0.9rem;
}

.clubSession-title[b-you6n98xbf] {
    font-weight: 600;
    color: #1f3d5b;
}

.clubSession-meta[b-you6n98xbf] {
    color: #5a6d80;
    font-size: 0.86rem;
}

.clubSession-time-part[b-you6n98xbf] {
    width: 5.25rem;
}

.clubSession-time-group[b-you6n98xbf] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.clubSession-time-sep[b-you6n98xbf] {
    color: #5a6d80;
    font-weight: 600;
}

.settings-message[b-you6n98xbf] {
    color: #38556f;
    font-size: 0.86rem;
    margin-left: 0.5rem;
}

.clubSession-delete-modal-backdrop[b-you6n98xbf] {
    position: fixed;
    inset: 0;
    background: rgba(14, 24, 36, 0.48);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 1200;
}

.clubSession-delete-modal[b-you6n98xbf] {
    width: min(28rem, 100%);
    background: #fff;
    border: 1px solid rgba(92, 119, 145, 0.35);
    border-radius: 0.75rem;
    box-shadow: 0 1rem 2.2rem rgba(14, 24, 36, 0.28);
    padding: 1rem;
}

.clubSession-delete-modal h2[b-you6n98xbf] {
    margin: 0 0 0.6rem;
    color: #5a1223;
    font-size: 1.2rem;
}

.clubSession-delete-actions[b-you6n98xbf] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

/* --- schedule-specific layout (own styles) --- */

.regularSchedule-item[b-you6n98xbf] {
    padding: 0.5rem 0;
    border-top: 1px solid rgba(92, 119, 145, 0.2);
}

.regularSchedule-item:first-of-type[b-you6n98xbf] {
    border-top: 0;
}

/* (b) form — a simple labelled column reusing .form-select / .form-control / .clubSession-time-group. */
.regularSchedule-form[b-you6n98xbf] {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.regularSchedule-field[b-you6n98xbf] {
    display: grid;
    grid-template-columns: 8rem minmax(0, 22rem);
    align-items: center;
    gap: 0.75rem;
}

.regularSchedule-label[b-you6n98xbf] {
    color: #4b5f75;
    font-size: 0.9rem;
    font-weight: 600;
}

.regularSchedule-form-actions[b-you6n98xbf] {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.35rem;
}

/* SPEC-30 S4 (review polish 2): keep the small numeric capacity field compact — a 1-3 digit number should not
   stretch full-width like the venue text input. Matches the .clubSession-time-part small-input convention. */
.regularSchedule-capacity[b-you6n98xbf] {
    max-width: 6rem;
}

/* (c) active / resting */
.regularSchedule-active[b-you6n98xbf] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.regularSchedule-actions[b-you6n98xbf] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.5rem;
    align-items: center;
}

.regularSchedule-delete[b-you6n98xbf] {
    margin-left: auto; /* push Delete to the right, thumb-distance from Pause */
}

.regularSchedule-add-another[b-you6n98xbf] {
    margin-top: 0.75rem;
}

.regularSchedule-skips[b-you6n98xbf] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.35rem;
}

.regularSchedule-skip[b-you6n98xbf] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.86rem;
    color: #38556f;
}

.regularSchedule-cadence-muted[b-you6n98xbf] {
    margin-top: 0.4rem;
    opacity: 0.75;
}

/* (d) PAUSED / profile-deleted — the schedule-paused warning token. No existing banner pattern in the app, so
   this is the reusable amber band: literal tones (the app CSS uses hex, not vars). AA on the pale amber. */
.clubSessions-schedule-alert[b-you6n98xbf] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    background: #fdf4dd;
    border: 1px solid #e0b84c;
    border-radius: 0.5rem;
    padding: 0.75rem 0.9rem;
    color: #6b4e08;
}

.clubSessions-schedule-alert-body[b-you6n98xbf] {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
}

.clubSessions-schedule-alert-icon[b-you6n98xbf] {
    font-size: 1.1rem;
    line-height: 1.2;
}

@media (max-width: 700px) {
    .regularSchedule-field[b-you6n98xbf] {
        grid-template-columns: 1fr;
        gap: 0.3rem;
    }
}
/* /Components/Pages/Reports.razor.rz.scp.css */
/* Insights hub — card grid grouped by the question a committee asks. Built to
   Docs/features/club-reports/insights-hub-mockup.html, in the app's visual language. */

.insights-shell[b-zoeczp8t7b] {
    max-width: 1180px;
    padding-bottom: 2.75rem;
}

.insights-head h1[b-zoeczp8t7b] {
    color: #0d2c55;
    font-size: 2.5rem;
    margin: 0;
}

.insights-sub[b-zoeczp8t7b] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin: 0.2rem 0 1.4rem;
}

.ins-sec[b-zoeczp8t7b] {
    margin-bottom: 1.7rem;
}

.ins-sec h2[b-zoeczp8t7b] {
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: #5a6c82;
    margin: 0 0 0.75rem;
    font-weight: 700;
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
}

.ins-sec h2 .q[b-zoeczp8t7b] {
    text-transform: none;
    letter-spacing: 0;
    color: #9aa6b6;
    font-weight: 500;
    font-size: 0.8rem;
}

.ins-grid[b-zoeczp8t7b] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
    gap: 0.9rem;
}

.ins-card[b-zoeczp8t7b] {
    background: #ffffff;
    border: 1px solid #c5cfde;
    border-radius: 0.75rem;
    padding: 0.95rem 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    cursor: pointer;
    transition: border-color 0.12s, box-shadow 0.12s, transform 0.06s;
    min-height: 128px;
}

.ins-card:hover[b-zoeczp8t7b] {
    border-color: #9fc0e6;
    box-shadow: 0 4px 14px rgba(20, 40, 70, 0.08);
}

.ins-card:focus-visible[b-zoeczp8t7b] {
    outline: none;
    border-color: #1b6ec2;
    box-shadow: 0 0 0 3px #1b6ec2;
}

.ins-hd[b-zoeczp8t7b] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.ins-ico[b-zoeczp8t7b] {
    width: 30px;
    height: 30px;
    border-radius: 0.5rem;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    font-size: 0.9rem;
    font-weight: 800;
    color: #ffffff;
}

.ins-ttl[b-zoeczp8t7b] {
    font-weight: 700;
    font-size: 0.9rem;
    color: #1f3f5e;
}

.ins-desc[b-zoeczp8t7b] {
    font-size: 0.78rem;
    color: #6c7a8c;
    flex: 1;
    line-height: 1.4;
}

.ins-prev[b-zoeczp8t7b] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
    color: #3a4a5e;
    font-weight: 600;
    border-top: 1px solid #e6ebf3;
    padding-top: 0.55rem;
    margin-top: auto;
}

.ins-prev .big[b-zoeczp8t7b] {
    font-size: 0.98rem;
    font-weight: 800;
    color: #1f3f5e;
}

.ins-prev .warn[b-zoeczp8t7b] {
    color: #a9750a;
}

.ins-prev .prev-empty[b-zoeczp8t7b] {
    color: #9aa6b6;
    font-weight: 500;
}

.ins-prev .link-prev[b-zoeczp8t7b] {
    color: #1b6ec2;
}

.ins-spark[b-zoeczp8t7b] {
    color: #2e9c63;
    flex: 0 0 auto;
}

/* "Soon" (planned) cards: dashed, muted, not clickable. */
.ins-card.soon[b-zoeczp8t7b] {
    cursor: default;
    background: #f7f9fc;
    border-style: dashed;
}

.ins-card.soon:hover[b-zoeczp8t7b] {
    border-color: #c5cfde;
    box-shadow: none;
}

.ins-card.soon .ins-ico[b-zoeczp8t7b] {
    opacity: 0.5;
}

.ins-card.soon .ins-ttl[b-zoeczp8t7b] {
    color: #5d6b7e;
}

/* Opt-in card (Partnerships when not enabled) keeps the clickable affordance. */
.ins-card.ins-card-optin[b-zoeczp8t7b] {
    cursor: pointer;
}

.ins-chip[b-zoeczp8t7b] {
    font-size: 0.62rem;
    font-weight: 700;
    border-radius: 20px;
    padding: 0.12rem 0.55rem;
    margin-left: auto;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.ins-chip.soon[b-zoeczp8t7b] {
    background: #eef1f6;
    color: #7a869a;
}

.ins-chip.optin[b-zoeczp8t7b] {
    background: #e3eefb;
    color: #1b6ec2;
}

/* Icon accent colours (match the mockup) */
.ic-att[b-zoeczp8t7b] { background: #2e9c63; }
.ic-sess[b-zoeczp8t7b] { background: #3a7bbf; }
.ic-conv[b-zoeczp8t7b] { background: #2f8f6a; }
.ic-trend[b-zoeczp8t7b] { background: #e0a32a; }
.ic-eng[b-zoeczp8t7b] { background: #3a8f5f; }
.ic-qual[b-zoeczp8t7b] { background: #6b4ea8; }
.ic-fair[b-zoeczp8t7b] { background: #1d7a82; }
.ic-part[b-zoeczp8t7b] { background: #8a6db3; }
.ic-pay[b-zoeczp8t7b] { background: #1f7a4d; }
.ic-court[b-zoeczp8t7b] { background: #cf7a1a; }
.ic-imp[b-zoeczp8t7b] { background: #c0567f; }
.ic-mix[b-zoeczp8t7b] { background: #4a8fb0; }
.ic-mem[b-zoeczp8t7b] { background: #5a6c82; }

.ins-also[b-zoeczp8t7b] {
    font-size: 0.8rem;
    color: #6c7a8c;
    background: #ffffff;
    border: 1px solid #e6ebf3;
    border-radius: 0.65rem;
    padding: 0.75rem 1rem;
    margin-top: 0.4rem;
    line-height: 1.5;
}

.ins-also b[b-zoeczp8t7b] {
    color: #42526a;
}
/* /Components/Pages/SelectClub.razor.rz.scp.css */
.club-select-shell[b-yg368new96] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 3rem 1.5rem 2rem;
    background:
        radial-gradient(circle at 28% 18%, rgba(140, 190, 240, 0.22) 0%, transparent 55%),
        radial-gradient(circle at 78% 88%, rgba(93, 176, 97, 0.10) 0%, transparent 55%),
        linear-gradient(180deg, #294f76 0%, #1f3d5b 100%);
    margin: -1rem -1.5rem -1rem;
}

/* Match MainLayout's asymmetric .content padding-left at desktop. */
@media (min-width: 1280px) {
    .club-select-shell[b-yg368new96] {
        margin-left: -2rem;
    }
}

.club-select-card[b-yg368new96] {
    width: min(34rem, 92vw);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 0.85rem;
    background: #ffffff;
    padding: 1.5rem 1.5rem 1.3rem;
    box-shadow: 0 14px 32px rgba(8, 24, 50, 0.34);
}

.club-select-card h1[b-yg368new96] {
    margin: 0 0 0.35rem;
    color: #1f3f5e;
}

.club-select-help[b-yg368new96] {
    color: #5e748a;
    margin: 0 0 0.8rem;
}

.club-list[b-yg368new96] {
    display: grid;
    gap: 0.55rem;
}

.club-option[b-yg368new96] {
    text-align: left;
    padding: 0.6rem 0.75rem;
}

.club-select-actions[b-yg368new96] {
    margin-top: 0.8rem;
}
/* /Components/Pages/SessionDoor.razor.rz.scp.css */
/* #868 (portal B1): the session door (mock 04). Same centred card column + visual tokens as the
   rest of the player shell (PlayerClubDetail / /me) - NO new brand. Scoped per component (the
   PegboardWeb per-page .razor.css pattern). The door-card styling matches the simplified mock's
   mock.css (.door-choice / .door-card). */

.door-shell[b-275033w5yq] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
    overflow-wrap: break-word;
}

/* ── Back bar (the way back - always present). ── */
.door-backbar[b-275033w5yq] {
    margin-bottom: 1rem;
}

.door-back[b-275033w5yq] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 44px;
    color: #006bb7;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.95rem;
}

.door-back:hover[b-275033w5yq],
.door-back:focus-visible[b-275033w5yq] {
    text-decoration: underline;
}

.door-back-caret[b-275033w5yq] {
    font-weight: 700;
}

/* ── Dual: the live line + the two-card fork. ── */
.door-live-line[b-275033w5yq] {
    text-align: center;
    font-size: 1rem;
    font-weight: 700;
    color: #16324f;
    margin: 0.4rem 0 0.2rem;
}

.door-live-sub[b-275033w5yq] {
    text-align: center;
    color: #5e748a;
    margin: 0 0 0.6rem;
}

.door-choice[b-275033w5yq] {
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin-top: 1rem;
}

.door-card[b-275033w5yq] {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    min-height: 44px;
    border: 2px solid #e2e8f0;
    border-radius: 0.85rem;
    padding: 1.1rem;
    text-decoration: none;
    background: #fff;
    color: inherit;
}

.door-card:hover[b-275033w5yq],
.door-card:focus-visible[b-275033w5yq] {
    filter: brightness(0.99);
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

.door-card.coordinate[b-275033w5yq] {
    border-color: #0d2c55;
}

.door-card.participate[b-275033w5yq] {
    border-color: #1b6ec2;
}

.door-card .dc-ico[b-275033w5yq] {
    font-size: 1.8rem;
    flex: 0 0 auto;
    line-height: 1;
}

.door-card .dc-body[b-275033w5yq] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.door-card .dc-t[b-275033w5yq] {
    font-weight: 800;
    color: #16324f;
    font-size: 1.05rem;
}

.door-card .dc-m[b-275033w5yq] {
    font-size: 0.82rem;
    color: #5e748a;
}

.door-card .dc-go[b-275033w5yq] {
    color: #9fb0c2;
    font-weight: 800;
    font-size: 1.2rem;
    flex: 0 0 auto;
}

.door-hint[b-275033w5yq] {
    text-align: center;
    margin-top: 1.1rem;
    font-size: 0.82rem;
    color: #5e748a;
}

/* ── Finished / no-live-session state (never a dead end). ── */
.door-finished[b-275033w5yq] {
    text-align: center;
    padding: 2.4rem 1rem 1.6rem;
    background: #f6f9fc;
    border: 1px solid #d9e6f2;
    border-radius: 0.85rem;
    margin-top: 0.5rem;
}

.door-finished-ico[b-275033w5yq] {
    font-size: 2.2rem;
    line-height: 1;
    margin-bottom: 0.5rem;
}

.door-finished-title[b-275033w5yq] {
    font-size: 1.15rem;
    font-weight: 800;
    color: #16324f;
}

.door-muted[b-275033w5yq] {
    color: #5e748a;
    margin: 0.35rem 0 0;
}

.door-btn[b-275033w5yq] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    margin-top: 1rem;
    padding: 0.55rem 1.4rem;
    background: #0d6efd;
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    border-radius: 0.6rem;
}

.door-btn:hover[b-275033w5yq],
.door-btn:focus-visible[b-275033w5yq] {
    filter: brightness(1.05);
    outline: none;
}

/* ── Pure-role transition frame (the loading state; the redirect fires from the server). ── */
.door-transition[b-275033w5yq] {
    text-align: center;
    padding: 2.6rem 1rem;
}

.door-transition-ico[b-275033w5yq] {
    font-size: 2.4rem;
    line-height: 1;
    margin-bottom: 0.5rem;
}

.door-transition-title[b-275033w5yq] {
    font-size: 1.15rem;
    font-weight: 700;
    color: #16324f;
}

/* ── BL-PW-0013: the drop-in self-registration form (non-member + session code). ── */
.door-dropin-form[b-275033w5yq] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: 1rem;
}

.door-dropin-field[b-275033w5yq] {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-weight: 600;
    color: #16324f;
}

.door-dropin-field input[b-275033w5yq] {
    padding: 0.6rem 0.7rem;
    font-size: 1rem;
    font-weight: 400;
    color: #16324f;
    background: #fff;
    border: 1px solid #cdd8e3;
    border-radius: 0.5rem;
}

.door-dropin-field input:focus[b-275033w5yq] {
    outline: none;
    border-color: #0d6efd;
    box-shadow: 0 0 0 3px rgba(13, 110, 253, 0.18);
}

.door-dropin-help[b-275033w5yq] {
    margin: -0.25rem 0 0;
    font-size: 0.82rem;
    color: #5e748a;
}

.door-dropin-error[b-275033w5yq] {
    margin-top: 0.5rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid #f0b3b3;
    border-radius: 0.5rem;
    background: #fdeaea;
    color: #8a1c1c;
    font-size: 0.9rem;
}

/* The submit button reuses .door-btn's look but is a real <button>, so reset the button chrome
   and make it full-width to read as the primary action. */
.door-btn-primary[b-275033w5yq] {
    width: 100%;
    border: none;
    cursor: pointer;
    font: inherit;
    font-weight: 700;
}

/* #61 (UX): the "Playing as {name}" identity-confirmation line on the dual-role Choice fork — a quiet
   muted caption (reuses the muted-caption + dark-navy-strong tokens; no new colours). */
.door-linked-as[b-275033w5yq] {
    text-align: center;
    font-size: 0.85rem;
    color: #5e748a;
    margin: 0 0 0.5rem;
}

.door-linked-as strong[b-275033w5yq] {
    color: #16324f;
    font-weight: 700;
}
/* /Components/Pages/SessionRecap.razor.rz.scp.css */
/* #632 (portal S3): the public club-night recap. Mobile-first, share-shaped — a
   single centred column that reads well on a phone dropped into a WhatsApp group.
   Self-contained (no app nav chrome), like the static-SSR auth shells. */

.recap-shell[b-annzdwi03a] {
    max-width: 34rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    color: #1f2d3d;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
    line-height: 1.5;
}

/* When the member-gated named summary is present, let the shell breathe on
   larger screens so the 8-column table fits without horizontal scroll. The
   anonymous teaser keeps the share-shaped 34rem column at every width. */
@media (min-width: 48rem) {
    .recap-shell-wide[b-annzdwi03a] {
        max-width: 64rem;
    }
}

/* #756: chrome-lite ?embed=1 render for the in-app Recap-tab iframe. The wordmark +
   footer are dropped in markup; trim the top padding a touch so the titled content
   sits cleanly at the top of the framed preview. No min-height/100vh anywhere in this
   file, so the iframe auto-sizer measures an honest content height. */
.recap-shell-embed[b-annzdwi03a] {
    padding-top: 1rem;
}

/* #222: the Phase-3 member-only "‹ Back to Sessions" link (.recap-backbar / .recap-back /
   .recap-back-caret) was removed — the full player shell (Me · Clubs · Sign out), now rendered
   around the member body via RecapPlayerChrome, supersedes it as the way back. */

.recap-head[b-annzdwi03a] {
    text-align: center;
    margin-bottom: 1.75rem;
}

.recap-brand[b-annzdwi03a] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
}

.recap-brand-wordmark[b-annzdwi03a] {
    height: 1.75rem;
    width: auto;
}

.recap-title[b-annzdwi03a] {
    font-size: 1.65rem;
    font-weight: 800;
    margin: 0.25rem 0 0.15rem;
    color: #16324f;
    line-height: 1.2;
}

.recap-date[b-annzdwi03a] {
    margin: 0;
    color: #5e748a;
    font-size: 0.95rem;
}

.recap-section-title[b-annzdwi03a] {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #5e748a;
    margin: 0 0 0.85rem;
    font-weight: 700;
}

/* ── Highlights: the emotion-led hero cards, first. ── */
.recap-highlights[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 2rem;
}

.recap-highlight[b-annzdwi03a] {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    background: linear-gradient(135deg, #f2f7fc 0%, #e9f1fa 100%);
    border: 1px solid #d9e6f2;
    border-radius: 0.85rem;
    padding: 1rem 1.1rem;
}

.recap-highlight-emoji[b-annzdwi03a] {
    font-size: 1.7rem;
    line-height: 1;
    flex-shrink: 0;
}

.recap-highlight-body[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.recap-highlight-headline[b-annzdwi03a] {
    font-weight: 700;
    font-size: 1.05rem;
    color: #16324f;
}

.recap-highlight-detail[b-annzdwi03a] {
    font-size: 0.92rem;
    color: #47586b;
}

/* ── Awards of the night. ── */
/* #158: the awards section now wraps a full-width GOLD HERO (Awards[0]) above the
   existing sibling grid. The section owns the block's bottom spacing so the hero-only
   state (no grid rendered) keeps the same gap to the next section as the N-award state. */
.recap-awards-section[b-annzdwi03a] {
    margin-bottom: 2rem;
}

.recap-awards[b-annzdwi03a] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem;
    /* margin-bottom moved to .recap-awards-section (#158): in the N-award case this grid
       holds the demoted siblings only, and the section carries the block spacing. */
}

.recap-award[b-annzdwi03a] {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    background: linear-gradient(135deg, #f2f7fc 0%, #e9f1fa 100%);
    border: 1px solid #d9e6f2;
    border-radius: 0.85rem;
    padding: 1rem 1.1rem;
}

.recap-award-emoji[b-annzdwi03a] {
    font-size: 1.7rem;
    line-height: 1;
    flex-shrink: 0;
}

.recap-award-body[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    gap: 0.12rem;
    min-width: 0;
}

.recap-award-title[b-annzdwi03a] {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #5e748a;
}

.recap-award-primary[b-annzdwi03a] {
    font-weight: 800;
    font-size: 1.05rem;
    color: #16324f;
}

.recap-award-detail[b-annzdwi03a] {
    font-size: 0.92rem;
    color: #47586b;
}

@media (min-width: 42rem) {
    .recap-awards[b-annzdwi03a] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ── #158: the GOLD HERO — the lead award (Awards[0]), elevated. ──────────────────────
   A restyle of the .recap-award card (same rounded-card language): a 2px medal-gold frame
   + warm gold wash, a bigger emoji MEDALLION (gold ring + radial gold fill around the
   award's own emoji), and a deep-gold super-label eyebrow. Siblings are LEFT UNTOUCHED —
   the demotion is achieved by the hero growing, not by changing the blue cards.

   Gold ramp (medal-gold, OQ-1 RESOLVED): scoped ONLY to .recap-award-hero* — the app has
   no celebratory-gold token, so this is a deliberate, contained net-new brand value; it is
   NOT the #9a6a00 admin amber (which reads "live-edit/warning"). No image assets, no SVG:
   the frame, medallion and sheen are all pure CSS. */
.recap-award-hero[b-annzdwi03a] {
    position: relative;   /* sheen anchor */
    overflow: hidden;     /* clip the one-pass sheen to the frame */
    align-items: center;
    gap: 1rem;
    /* Warm gold wash + 2px gold frame replace the siblings' blue wash + 1px blue border. */
    background: linear-gradient(135deg, #fdf8ec 0%, #f8eecb 100%);
    border: 2px solid #c9a227;
    /* More presence than a sibling: slightly larger padding. */
    padding: 1.25rem 1.4rem;
    /* Gap from the hero to the demoted sibling grid (matches the grid's own row gap). */
    margin-bottom: 0.75rem;
    animation: recap-hero-rise-b-annzdwi03a 480ms cubic-bezier(.2, .7, .2, 1) both;
}

/* The medallion: the award's OWN emoji inside a circular gold ring + radial gold fill.
   Overrides the base .recap-award-emoji (later in source, equal specificity → wins). */
.recap-award-hero-emoji[b-annzdwi03a] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid #c9a227;
    background: radial-gradient(circle at 50% 40%, #fbf1cf 0%, #f4e6b4 100%);
    font-size: 2.1rem;
    line-height: 1;
    transform-origin: center;
    animation: recap-hero-medallion-b-annzdwi03a 620ms cubic-bezier(.2, .7, .2, 1) 120ms both;
}

/* The super-label eyebrow — deep gold, uppercase (like the sibling .recap-award-title
   eyebrow it visually replaces). Real text (a11y): it carries the "why elevated" meaning,
   so elevation is never colour-only (WCAG 1.4.1). */
.recap-award-superlabel[b-annzdwi03a] {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #7d5f10;   /* deep gold — 5.14:1 on the darker wash end #f8eecb (5.64:1 on #fdf8ec),
                         clearing WCAG AA for small bold text with headroom. (The earlier #8a6a13
                         measured 4.36:1 — a hairline AA miss — per code-review + qa a11y checks.) */
    margin-bottom: 0.1rem;
}

/* In the hero the award NAME becomes a real title (the super-label now owns the tiny
   uppercase-eyebrow slot), so drop the eyebrow treatment and grow it. Navy for contrast. */
.recap-award-hero .recap-award-title[b-annzdwi03a] {
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: normal;
    text-transform: none;
    color: #16324f;
    line-height: 1.2;
}

/* The name — the boldest line in the card. */
.recap-award-hero .recap-award-primary[b-annzdwi03a] {
    font-size: 1.15rem;
}

/* One-pass diagonal sheen sweeping across the gold frame, then gone (never loops). */
.recap-award-hero-sheen[b-annzdwi03a] {
    position: absolute;
    top: 0;
    left: 0;
    width: 45%;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(120deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.55) 50%, rgba(255, 255, 255, 0) 100%);
    transform: translateX(-120%);
    animation: recap-hero-sheen-b-annzdwi03a 900ms ease-out 300ms 1 both;   /* 1 = a single pass */
}

@keyframes recap-hero-rise-b-annzdwi03a {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

@keyframes recap-hero-medallion-b-annzdwi03a {
    0%   { transform: scale(0.85); }
    60%  { transform: scale(1.05); }
    100% { transform: scale(1); }
}

@keyframes recap-hero-sheen-b-annzdwi03a {
    from { transform: translateX(-120%); opacity: 0; }
    30%  { opacity: 0.35; }
    to   { transform: translateX(120%); opacity: 0; }
}

/* Required fallback (not a nice-to-have): no motion. The hero still reads as elevated via
   layout + gold + super-label alone. Never a looping animation anywhere (always-on kiosk). */
@media (prefers-reduced-motion: reduce) {
    .recap-award-hero[b-annzdwi03a],
    .recap-award-hero-emoji[b-annzdwi03a],
    .recap-award-hero-sheen[b-annzdwi03a] {
        animation: none;
    }
}

.recap-numbers[b-annzdwi03a] {
    margin-bottom: 2rem;
}

.recap-stat-grid[b-annzdwi03a] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
    gap: 0.75rem;
}

.recap-stat[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1rem 0.5rem;
    text-align: center;
}

.recap-stat-value[b-annzdwi03a] {
    font-size: 1.9rem;
    font-weight: 800;
    color: #1b6ec2;
    line-height: 1;
}

.recap-stat-label[b-annzdwi03a] {
    font-size: 0.8rem;
    color: #5e748a;
    margin-top: 0.35rem;
}

/* ── #88 Slice 1: "How the night played out" — the aggregate distribution charts section.
   Replaces the old "Fair play" checklist (its .recap-fairness* rules were built entirely
   from the two retired figures and are removed). The chart CARD internals are styled in
   RecapDistributionChart.razor.css (scoped to that component); this owns only the section
   container's spacing + the stack gap between charts (one chart this slice; 2/3 add more). */
.recap-charts[b-annzdwi03a] {
    margin-bottom: 2rem;
    /* A simple block/flex column: the "How the night played out" eyebrow on top (full width),
       then the inner .recap-charts-grid holding the three cards. gap = the space between the
       eyebrow and the charts. The eyebrow is a SIBLING of the cards, never a grid cell. */
    display: flex;
    flex-direction: column;
    gap: 1rem;
    /* #88 Slice 2 (UX rework): the TEASER (share-shaped 34rem column, the WhatsApp-screenshot
       context) caps the section at the shell's inner content width — 34rem − 2×1.25rem side
       padding = 31.5rem — so the bar track keeps its designed proportion. This governs the teaser
       ONLY; the wide member-tier / ?embed=1 shell lifts the cap below. */
    max-width: 31.5rem;
}

/* The three chart CARDS. Stacked 1-up by default (teaser + narrow); the wide shell lays them out
   3-up below. gap = the space between stacked cards. */
.recap-charts-grid[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* #88 Slice 3 (UX rework): in the WIDE shell (member-tier + ?embed=1) the numbers grid + results
   table stretch to ~984px, so pinning the charts at 31.5rem left an orphaned void beside them. Let
   the SECTION span the full width (so the eyebrow sits above all three charts), and keep the CARDS
   at the designed width — centered, not stretched — until there is room for a clean 3-up row. */
.recap-shell-wide .recap-charts[b-annzdwi03a] {
    max-width: none;
}

.recap-shell-wide .recap-charts-grid[b-annzdwi03a] {
    max-width: 31.5rem;
    margin-inline: auto;
}

/* At ≥64rem the wide shell is at/near its 64rem cap (~984px content). UX Option B: lay the cards
   2-up so each keeps a legible ~484px bar track (3-up compressed it to ~91px — a 3× legibility
   regression). With the TWO current charts (predicted-balance + mixing) this fills a clean single
   row, one card per column. Gated to 64rem so 2-up only kicks in where the cards are wide enough to
   read; between 48–64rem the cards stay 1-up (centred) rather than cramped.

   NOTE (#121): while the wait-fairness chart is pulled (SessionRecap.razor NOTE), exactly TWO cards
   render, so no odd-card centring rule is needed — the 2-up grid aligns them on one row. The former
   `::deep > :last-child { grid-column: 1 / -1; … centre }` special-case existed for the THIRD card
   (mixing centred on row 2); with only two cards it hit the 2nd card and dropped it to a centred,
   row-spanning slot on row 2 → the diagonal stagger. It was removed. When the wait-fairness chart is
   re-added (the one-block revert noted in SessionRecap.razor), restore that centring rule alongside
   it so the lone third card is again capped to one column's width (width: 30.25rem; margin-inline:
   auto; grid-column: 1 / -1) rather than stretched full-width. */
@media (min-width: 64rem) {
    .recap-shell-wide .recap-charts-grid[b-annzdwi03a] {
        max-width: none;
        margin-inline: 0;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        align-items: start;
    }
}

/* ── #668 (portal S3b): the member-tier named summary table. Compact, share-shaped;
   horizontal scroll on a phone rather than cramming 8 columns. SHAPE-FIRST — clean,
   not heavily polished; the column set is expected to iterate. ── */
.recap-member-summary[b-annzdwi03a] {
    margin-bottom: 2rem;
}

.recap-member-empty[b-annzdwi03a] {
    color: #5e748a;
    font-size: 0.95rem;
    margin: 0;
}

.recap-member-table-wrap[b-annzdwi03a] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
}

.recap-member-table[b-annzdwi03a] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
    background: #fff;
}

.recap-member-table th[b-annzdwi03a],
.recap-member-table td[b-annzdwi03a] {
    padding: 0.5rem 0.65rem;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid #eef2f6;
}

.recap-member-table thead th[b-annzdwi03a] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #5e748a;
    font-weight: 700;
    background: #f7fafc;
}

.recap-member-table tbody tr:last-child td[b-annzdwi03a] {
    border-bottom: none;
}

/* #920: the recap MUST show every player's Initial and Final rating on mobile too
   (Maximum-player-visibility, ADR-0011 addendum) — the earlier max-width:600px rule
   DROPPED those two columns below the breakpoint, hiding the raw before/after rating
   from anyone on a phone. That rule is removed: the table now reflows via the
   .recap-member-table-wrap { overflow-x: auto } wrapper (already present above), so on a
   narrow viewport the full ratings table scrolls horizontally and Initial + Final stay
   reachable rather than dropped. No column is ever hidden on any width. */

.recap-col-rank[b-annzdwi03a] {
    text-align: center;
    width: 2rem;
    color: #5e748a;
    font-weight: 700;
}

.recap-col-num[b-annzdwi03a] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.recap-member-name[b-annzdwi03a] {
    font-weight: 600;
    color: #16324f;
}

.recap-result-squares[b-annzdwi03a] {
    display: flex;
    gap: 0.2rem;
    /* The squares are a game-by-game SEQUENCE — never wrap onto a second row. */
    flex-wrap: nowrap;
}

.recap-result-square[b-annzdwi03a] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 0.2rem;
    font-size: 0.68rem;
    font-weight: 700;
    color: #fff;
    line-height: 1;
}

.recap-result-win[b-annzdwi03a] {
    /* IR-S5b ux review: darkened from #2f9e6f so WHITE text on this badge meets WCAG AA
       (>=4.5:1; #1f7a54 gives 5.29:1). Same fix as .rating-delta-up — this is the primary
       "who won" signal on every result square + game-row Win badge. */
    background: #1f7a54;
}

.recap-result-loss[b-annzdwi03a] {
    background: #c0392b;
}

/* ── IR-S5 (portal IA refresh): the members-only recap game list (neutral list + drill-in). ── */

/* The tappable attendee name (member + History-ON only). A plain query link — no circuit.
   IR-S5b ux review round 2: the link must fill its whole <td> (content AND the cell's
   0.5rem/0.65rem padding) so there is no dead, tappable-looking padding. Negative margin
   pulls the anchor out to the cell edges; equal padding refills it, so the text sits where
   it did but the entire cell is the hit area. */
.recap-member-name-link[b-annzdwi03a] {
    color: #1b6ec2;
    font-weight: 600;
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 0.15rem;
    margin: -0.5rem -0.65rem;
    padding: 0.5rem 0.65rem;
}

.recap-member-name-link:hover[b-annzdwi03a],
.recap-member-name-link:focus-visible[b-annzdwi03a] {
    text-decoration: underline;
}

/* IR-S5 / #778 row-filter: two tap targets per player row — the NAME opens the clubmate
   profile, and the REST of the row filters the games to that player. The <tr> is the
   containing block + positioning context; the overlay anchor stretches to cover it; the
   name link is raised ABOVE the overlay so its own click wins (not swallowed by the row).
   The overlay carries a positive z-index so it sits over the other cells' (non-positioned)
   content and reliably captures their clicks — the table-safe alternative to a ::after. */
.recap-member-row[b-annzdwi03a] {
    position: relative;
    cursor: pointer;
}

/* ux review: a STANDING (non-hover) cue that the ROW is tappable-to-filter — the hover tint
   never fires on touch, so a persistent marker is needed for the touch/kiosk audience. A left
   accent bar in the link blue on the row's LEADING cell: visible without hover, positioned on
   the same edge as the name link (so the "name = profile, row = filter" decision is made with
   both cues in view) and NOT next to the name where it would read as a name chevron. It is on
   the leading edge — where the table opens — not the trailing edge that scrolls off a narrow
   table first. box-shadow (not border) so it is immune to the table's border-collapse. */
.recap-member-row td:first-child[b-annzdwi03a] {
    box-shadow: inset 3px 0 0 #9cc3ea;
}

.recap-member-row-filter[b-annzdwi03a] {
    position: absolute;
    inset: 0;
    z-index: 1;
    /* No visible box of its own — the standing left accent + hover tint carry the cue; a focus
       ring makes the row action keyboard-discoverable. */
    display: block;
}

.recap-member-row:hover:not(:has(.recap-member-name-link:hover))[b-annzdwi03a] {
    background: #f4f8fd;
}

.recap-member-row-filter:focus-visible[b-annzdwi03a] {
    outline: 2px solid #1b6ec2;
    outline-offset: -3px;
    border-radius: 0.25rem;
}

/* The name (profile) link sits above the row-filter overlay so a name tap opens the
   profile; the overlay handles taps anywhere else on the row. */
.recap-member-name-profile[b-annzdwi03a] {
    position: relative;
    z-index: 2;
    /* The name link is a precise target within the row (not the full cell), but must still be a
       comfortable TOUCH target. ux review: it measured ~22px tall (about half the ~44px touch
       min) and sits inside the larger row-filter overlay, so near-misses landed on the filter.
       Vertical padding grows the hit box to ~34px; an equal negative vertical margin cancels it
       so the row height/layout is unchanged. Horizontal padding stays 0 so it never overlaps the
       adjacent cell. It keeps its z-index (raised above the overlay) and its link colour/underline. */
    display: inline-block;
    margin-block: -7px;
    margin-inline: 0;
    padding-block: 7px;
    padding-inline: 0;
}

/* IR-S5b ux review round 2: the "you are viewing this player" cue — the selected name
   goes bold (not just a colour swap to inert body text), paired with the row tint below. */
.recap-member-name-selected[b-annzdwi03a] {
    color: #16324f;
    font-weight: 700;
}

/* The selected attendee's whole row gets a subtle tint so it reads as "this is who you're
   viewing", distinct from ordinary data rows. */
.recap-member-row-selected td[b-annzdwi03a] {
    background: #eef4fb;
}

/* The active-filter row deepens its standing left accent to full link blue (over the lighter
   default accent) so "this is the row you filtered by" reads at a glance. */
.recap-member-row-selected td:first-child[b-annzdwi03a] {
    box-shadow: inset 3px 0 0 #1b6ec2;
}

.recap-drill-hint[b-annzdwi03a] {
    margin: -0.2rem 0 0.6rem;
    font-size: 0.82rem;
    color: #5e748a;
}

.recap-games[b-annzdwi03a] {
    margin-bottom: 2rem;
    /* Anchor target (#games): the ?player=#games / clear re-render scrolls + moves SR focus
       here (tabindex=-1); offset so the heading clears the viewport top. */
    scroll-margin-top: 1rem;
}

/* Suppress the default focus ring on the programmatic (tabindex=-1) anchor jump — the
   heading itself is the visible landmark; a ring on the whole section would be noise. */
.recap-games:focus[b-annzdwi03a] {
    outline: none;
}

.recap-games-head[b-annzdwi03a] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.4rem 1rem;
}

.recap-games-title[b-annzdwi03a] {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
}

.recap-games-title-sub[b-annzdwi03a] {
    font-size: 0.8rem;
    font-weight: 500;
    color: #5e748a;
}

/* "Filter by player" — a native <details> disclosure (no JS), styled to match the app's
   Members disclosure convention (PlayerClubDetail .clubmenu-members-summary): native marker
   suppressed, a `›` chevron that rotates on [open], and hover/focus-visible states — so this
   door and the name-tap door (which also uses the `›` chevron) visually rhyme. */
.recap-games-filter[b-annzdwi03a] {
    font-size: 0.85rem;
}

.recap-games-filter-summary[b-annzdwi03a] {
    cursor: pointer;
    color: #1b6ec2;
    white-space: nowrap;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.15rem 0.1rem;
    border-radius: 0.3rem;
}

.recap-games-filter-summary[b-annzdwi03a]::-webkit-details-marker {
    display: none;
}

.recap-games-filter-summary:hover[b-annzdwi03a],
.recap-games-filter-summary:focus-visible[b-annzdwi03a] {
    text-decoration: underline;
    outline: none;
}

/* The `›` chevron (reuses .recap-drill-chev's glyph treatment) points right when closed and
   rotates to point down when the disclosure is open. */
.recap-games-filter-caret[b-annzdwi03a] {
    color: #7a93ab;
    font-size: 0.9em;
    transition: transform 0.15s ease;
}

.recap-games-filter[open] .recap-games-filter-caret[b-annzdwi03a] {
    transform: rotate(90deg);
}

.recap-games-filter-list[b-annzdwi03a] {
    list-style: none;
    margin: 0.4rem 0 0;
    padding: 0.4rem;
    border: 1px solid #e3e9ef;
    border-radius: 0.5rem;
    background: #fff;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    max-height: 16rem;
    overflow-y: auto;
}

.recap-games-filter-opt[b-annzdwi03a] {
    display: block;
    padding: 0.35rem 0.5rem;
    border-radius: 0.3rem;
    color: #16324f;
    text-decoration: none;
}

.recap-games-filter-opt:hover[b-annzdwi03a],
.recap-games-filter-opt:focus-visible[b-annzdwi03a] {
    background: #eef4fb;
}

.recap-games-filter-opt-on[b-annzdwi03a] {
    font-weight: 700;
    color: #1b6ec2;
}

.recap-games-clear[b-annzdwi03a] {
    display: inline-block;
    margin-top: 0.6rem;
    font-size: 0.85rem;
    color: #1b6ec2;
    text-decoration: none;
    white-space: nowrap;
}

.recap-games-clear:hover[b-annzdwi03a],
.recap-games-clear:focus-visible[b-annzdwi03a] {
    text-decoration: underline;
}

/* #236: the filtered player's OWN name token, wherever it appears in the Winning/Losing team
   cells (table AND ≤720px card), when the All-games list is filtered to that one player. This is
   the ONLY new cue: paired with the table's winner-LEFT / loser-RIGHT layout, a member sees at a
   glance which games they won vs lost. Emphasis carries a NON-COLOUR signal (font-weight 800 —
   heavier than the 700 winner base, so it stands out even in the winner column) PLUS a pale
   highlighter chip, so it never relies on colour alone (#225 a11y). box-decoration-break keeps the
   chip intact if a long name wraps in the card. Rendered only in the filtered view; the neutral
   "All games" list emits plain names, unchanged. */
.recap-games-name-mine[b-annzdwi03a] {
    font-weight: 800;
    color: #16324f;
    background: #fff3cf;
    border-radius: 3px;
    padding: 0 0.25rem;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}

/* Polish (#221 ux review): the Par explainer caption under the games list (table + card). */
.recap-games-caption[b-annzdwi03a] {
    margin: 0.55rem 0 0;
    font-size: 0.8rem;
    color: #5e748a;
}

.recap-games-empty[b-annzdwi03a] {
    margin: 0.8rem 0 0;
    font-size: 0.85rem;
    color: #5e748a;
}

/* ── #668: the "Claim your night" CTA (anonymous / non-member teaser only). ── */
.recap-claim[b-annzdwi03a] {
    margin-bottom: 2rem;
}

.recap-claim-cta[b-annzdwi03a] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    text-decoration: none;
    text-align: center;
    background: linear-gradient(135deg, #1b6ec2 0%, #16324f 100%);
    color: #fff;
    border-radius: 0.85rem;
    padding: 1.1rem 1.25rem;
}

.recap-claim-cta-title[b-annzdwi03a] {
    font-weight: 800;
    font-size: 1.1rem;
}

.recap-claim-cta-sub[b-annzdwi03a] {
    font-size: 0.9rem;
    opacity: 0.9;
}

/* #742: "See your night" → /me for a claimed attendee. Secondary to the (unclaimed)
   claim CTA — a clear but calmer link, since this viewer has already claimed. Shown in
   the member-summary tier (where a claimed attendee lands) as the route back to /me. */
.recap-mynight[b-annzdwi03a] {
    margin-bottom: 2rem;
    text-align: center;
}

.recap-mynight-link[b-annzdwi03a] {
    display: inline-block;
    font-weight: 700;
    font-size: 1rem;
    color: #1b6ec2;
    text-decoration: none;
    border: 1px solid #bcd4ea;
    border-radius: 0.85rem;
    padding: 0.75rem 1.25rem;
}

.recap-mynight-link:hover[b-annzdwi03a],
.recap-mynight-link:focus-visible[b-annzdwi03a] {
    text-decoration: underline;
}

/* #753: the #633 recap SHARE affordance was removed from SessionRecap.razor (the recap is
   a pure artifact; share/copy live on the in-app dashboard button bar), so its .recap-share*
   rules were dead and have been deleted — mirroring the .recap-org-* removal. */

/* ── Footer / gentle brand CTA. ── */
.recap-foot[b-annzdwi03a] {
    border-top: 1px solid #e2e8f0;
    padding-top: 1.25rem;
    text-align: center;
}

.recap-foot-cta[b-annzdwi03a] {
    margin: 0;
    color: #5e748a;
    font-size: 0.9rem;
}

.recap-foot-cta strong[b-annzdwi03a] {
    color: #1b6ec2;
}

.recap-foot-link[b-annzdwi03a] {
    text-decoration: none;
}

.recap-foot-link:hover strong[b-annzdwi03a],
.recap-foot-link:focus-visible strong[b-annzdwi03a] {
    text-decoration: underline;
}
/* /Components/Pages/SessionSummaryReport.razor.rz.scp.css */
.reports-shell[b-ikaamvmuyr] {
    max-width: 1280px;
    padding-bottom: 2rem;
}

.reports-crumb[b-ikaamvmuyr] {
    color: #6c7a8c;
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.reports-crumb-link[b-ikaamvmuyr] {
    background: none;
    border: none;
    padding: 0;
    color: #0d2c55;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.reports-crumb-link:hover[b-ikaamvmuyr],
.reports-crumb-link:focus-visible[b-ikaamvmuyr] {
    text-decoration: underline;
    outline: none;
}

.reports-subtitle[b-ikaamvmuyr] {
    color: #4e6f8e;
    margin: -0.25rem 0 1.25rem;
    max-width: 70ch;
}

.reports-available-now-card[b-ikaamvmuyr] {
    background: #ffffff;
    border: 1px solid #d7e0ec;
    border-radius: 0.55rem;
    padding: 1rem 1.2rem;
    margin-bottom: 1rem;
}

.session-summary-filters[b-ikaamvmuyr] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, auto)) 1fr;
    gap: 0.7rem;
    align-items: end;
    margin-bottom: 0.75rem;
}

.session-summary-filter[b-ikaamvmuyr] {
    display: flex;
    flex-direction: column;
}

.session-summary-filter .form-label[b-ikaamvmuyr] {
    font-size: 0.82rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.2rem;
}

.session-summary-filter-actions[b-ikaamvmuyr] {
    flex-direction: row;
    gap: 0.5rem;
    justify-content: flex-end;
    align-items: flex-end;
}

.session-summary-count-hint[b-ikaamvmuyr] {
    color: #6c7a8c;
    font-size: 0.88rem;
    margin-bottom: 0.4rem;
}

.session-summary-table thead th[b-ikaamvmuyr] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
    font-size: 0.95rem;
    white-space: nowrap;
}

.session-summary-table th.sortable-header[b-ikaamvmuyr] {
    cursor: pointer;
    user-select: none;
}

.session-summary-table th.sortable-header:hover[b-ikaamvmuyr] {
    color: #0d2c55;
}

.session-summary-table td[b-ikaamvmuyr],
.session-summary-table th[b-ikaamvmuyr] {
    vertical-align: middle;
}

.session-summary-table .numeric[b-ikaamvmuyr] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 768px) {
    .session-summary-filter-actions[b-ikaamvmuyr] {
        justify-content: flex-start;
    }
}
/* /Components/Pages/Settings.razor.rz.scp.css */
.settings-shell[b-6sm8tliamm] {
    padding: 0;
}

.settings-shell h1[b-6sm8tliamm] {
    color: #0d2c55;
    font-size: 1.4rem;
    margin: 0 0 0.6rem;
}

.settings-card[b-6sm8tliamm] {
    background: #f6f8fb;
    border-radius: 0.35rem;
    margin-bottom: 0.75rem;
    padding: 0.75rem 0.85rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

.settings-card h2[b-6sm8tliamm] {
    color: #24384f;
    font-size: 1.05rem;
    margin: 0 0 0.4rem;
}

/* The Kiosk PIN + completed-game knob cards render as SUB-SECTIONS inside the grouped
   "Kiosk & shared-device" settings-card. They use `.club-card` internally (defined in
   Members.razor.css, inert across scope), so scope their chrome + tame the Bootstrap-default
   h3 here. Deliberately LIGHTER than a full settings-card so they read as sub-blocks of the
   group, not competing cards. Further permission sub-sections (the #900 matrix) slot in the
   same way. (Previously the PIN card got settings-card chrome and the knob card got none —
   an untamed ~2rem h2 — which read as loose big-heading cards at the top of the page.) */
.settings-shell[b-6sm8tliamm]  .kiosk-pin-card,
.settings-shell[b-6sm8tliamm]  .completed-game-knob-card {
    border: 1px solid #d5e2ef;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.7);
    padding: 0.55rem 0.7rem;
    margin-top: 0.6rem;
}

.settings-shell[b-6sm8tliamm]  .kiosk-pin-card h3,
.settings-shell[b-6sm8tliamm]  .completed-game-knob-card h3 {
    color: #24384f;
    font-size: 0.95rem;
    margin: 0 0 0.35rem;
}

.settings-shell[b-6sm8tliamm]  .kiosk-pin-card .club-help-text,
.settings-shell[b-6sm8tliamm]  .completed-game-knob-card .club-help-text {
    color: #5f6f80;
    font-size: 0.85rem;
    margin: 0 0 0.55rem;
}

.settings-card-help[b-6sm8tliamm] {
    margin: 0 0 0.65rem;
    color: #5f6f80;
}

/* #474: read-only banner shown when the user can view but not change settings. */
.settings-readonly-banner[b-6sm8tliamm] {
    font-weight: 600;
    color: #6c4a00;
}

/* ── S2 (#1011): profile list (rows link to the per-profile edit route). Reuses the Members
   clickable-row + 44px icon-button idea; values lifted from the settings-restructure mockup. ── */
.list-toolbar[b-6sm8tliamm] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.2rem;
}

.settings-list-count[b-6sm8tliamm] {
    font-size: 0.85rem;
    color: #5f6f80;
}

.settings-single-profile-hint[b-6sm8tliamm] {
    color: #5f6f80;
}

.profile-list[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin-top: 0.6rem;
}

.profile-row[b-6sm8tliamm] {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid #c5cfde;
    background: #fff;
    border-radius: 10px;
    transition: background 0.1s, border-color 0.1s;
}

.profile-row-clickable[b-6sm8tliamm] {
    cursor: pointer;
}

.profile-row-clickable:hover[b-6sm8tliamm] {
    background: #eef3f9;
    border-color: #9db6d6;
}

.profile-row-main[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    flex: 1 1 auto;
    min-width: 0;
}

.profile-row-name[b-6sm8tliamm] {
    font-size: 0.98rem;
    font-weight: 700;
    color: #1f3f5e;
}

.profile-row-sub[b-6sm8tliamm] {
    font-size: 0.78rem;
    color: #5f6f80;
}

.profile-row-actions[b-6sm8tliamm] {
    display: flex;
    gap: 0.4rem;
    flex: 0 0 auto;
}

.default-badge[b-6sm8tliamm] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 700;
    color: #0d6efd;
    background: #e7f0ff;
    border: 1px solid #b6d0ff;
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
    white-space: nowrap;
}

.set-default-link[b-6sm8tliamm] {
    background: none;
    border: none;
    color: #1b6ec2;
    font-size: 0.78rem;
    cursor: pointer;
    padding: 0.2rem 0.3rem;
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
}

.set-default-link:hover[b-6sm8tliamm] {
    text-decoration: underline;
}

/* Icon-only row action — kiosk/touch >= 44px target (from Members .member-row-edit-btn). */
.icon-btn[b-6sm8tliamm] {
    min-width: 2.75rem;
    width: 2.75rem;
    min-height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    line-height: 1;
    padding: 0.15rem;
    border: 1px solid #adb5bd;
    border-radius: 0.25rem;
    background: #fff;
    color: #3a5168;
    cursor: pointer;
}

.icon-btn:hover[b-6sm8tliamm] {
    background: #eef3f9;
    border-color: #9db6d6;
}

/* Crisp inline SVG action icons (copy/edit/delete/view) — inherit .icon-btn colour + hover via currentColor. */
.icon-btn svg[b-6sm8tliamm] {
    width: 1.25rem;
    height: 1.25rem;
    display: block;
}

/* Per-row delete confirm — centered modal (mirrors the member-unlink-modal pattern). */
.modal-backdrop[b-6sm8tliamm] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2200;
}

.modal-box[b-6sm8tliamm] {
    width: min(480px, 94vw);
    background: #fff;
    border: 1px solid #c8d4e2;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 1.1rem 1.2rem 1rem;
}

.modal-box h2[b-6sm8tliamm] {
    margin: 0 0 0.6rem;
    color: #0d2c55;
    font-size: 1.15rem;
}

.modal-box p[b-6sm8tliamm] {
    color: #4d5f72;
    font-size: 0.92rem;
}

.modal-actions[b-6sm8tliamm] {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.8rem;
}

/* S3 (#1013): the shared sticky Save/Discard bar (.settings-actions) + its dirty indicator are RETIRED —
   every scope self-saves now (the #962 fix). What remains is the quiet list-action feedback message and the
   per-control self-save cues below. */
.settings-message[b-6sm8tliamm] {
    color: #4f6177;
    font-size: 0.92rem;
}

/* S3 (#1013): brief "✓ Saved" cue shown by the time zone / season controls after a self-save. */
.settings-saved-cue[b-6sm8tliamm] {
    display: inline-block;
    margin-top: 0.4rem;
    color: #1f7a44;
    font-size: 0.82rem;
    font-weight: 600;
}

/* Inline error if a club-setting self-save fails (network / server). */
.settings-save-error[b-6sm8tliamm] {
    display: inline-block;
    margin-top: 0.4rem;
    color: #a11b2f;
    font-size: 0.85rem;
    font-weight: 600;
}

/* #167: advisory hint shown when Level-1 registration is Open but Level-2 admission is still AdminOnly
   (the silent drop-in dead-end). Amber advisory box — same weight/tone as the profile-visibility consent
   heads-up, so it reads as guidance, not an error. Purely advisory; no behaviour change. */
.settings-membership-hint[b-6sm8tliamm] {
    margin: 0.4rem 0 0;
    padding: 0.5rem 0.6rem;
    font-size: 0.82rem;
    line-height: 1.35;
    color: #6c4a00;
    background: #fff6e6;
    border: 1px solid #f0d9a8;
    border-radius: 8px;
}

/* ado:1934: the ONE standing line under a membership control - what the club is set to. It
   replaces the "explanation. In force: X" paragraphs, whose explanation half moved behind the
   information control (SettingsInfoDisclosure). It was .settings-card-help, which is the wrong
   name for it now that it is the only prose under the control and the thing the officer came for.
   The label row and panel styling live in the disclosure's own scoped stylesheet. */
/* NO font-size, deliberately, AND the element is a sibling of .settings-field rather than a child -
   the two together are what make this line render at the same size as the section help.

   These paragraphs were .settings-card-help on master and rendered at the inherited 16px. Two ways
   to lose that, and this slice hit both before they were caught:
     - taking the mockup's .82rem (13.1px), which is right in the mockup because ITS section help is
       also ~13px, and wrong here where the sibling grey paragraph inherits 16px;
     - dropping the font-size but leaving the paragraph INSIDE .settings-field, which sets .8rem for
       its label and control, so it inherits 12.8px and ends up smaller still.
   Either way the one line ado:1934 exists to surface ends up the smallest prose in the group, which
   is the item's own complaint inverted. That is the drift Feature346's signoff G2 was written to
   catch, and G2 does not fire here because it reads the read-only banner - so it is pinned instead
   by Story1934...In_force_lines_are_not_smaller_than_the_section_help, as a RELATIONSHIP to the
   section help rather than as a number.

   Colour and line-height match .settings-card-help so the two read as one voice. */
.settings-in-force[b-6sm8tliamm] {
    margin: 0.25rem 0 0;
    color: #5f6f80;
    line-height: 1.45;
}

.settings-in-force strong[b-6sm8tliamm] {
    color: #16324f;
}

/* ado:1934: the Membership section is now a stack of self-contained groups - label, explanation,
   control, and the one in-force line. Without this the distance from one group's in-force line to
   the next group's label is the same as the distance INSIDE a group, so the eye has nothing to
   group on and the section reads as eight loose lines rather than four settings. Scoped to the
   section: the other cards on this page are still label-and-control pairs. */
#membership-settings .settings-field[b-6sm8tliamm] {
    margin-top: 0.6rem;
}

/* ado:1437: the board-credential control is ONE field with TWO checkboxes, so the pair reads as one
   row in the section's rhythm and the two flags stay inspectable as one thing. Tighter than the gap
   BETWEEN groups above, for the same reason that rule exists: the eye has to see these two as one
   setting rather than as two more loose lines.

   The container is a role="group" div rather than a fieldset - a fieldset's legend is a layout fight
   nobody needs, and the disclosure's label span plus aria-labelledby does the same job with the same
   markup as every other row in the section. */
.settings-checkbox-group[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.settings-checkbox-row[b-6sm8tliamm] {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.8rem;
    color: #1f2d3d;
    /* A real <label> wrapping its own input, so the words are part of the hit target. That is safe
       here in a way it is not on the disclosure rows: there is no information button inside it. */
    cursor: pointer;
}

#membership-settings .settings-checkbox-row input[disabled][b-6sm8tliamm] {
    cursor: default;
}

.settings-section[b-6sm8tliamm] {
    border: 1px solid #d5e2ef;
    border-radius: 10px;
    padding: 0.55rem 0.6rem;
    background: rgba(255, 255, 255, 0.7);
    margin-top: 0.6rem;
}

.settings-section-title[b-6sm8tliamm] {
    font-size: 0.78rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #0d2c55;
    margin-bottom: 0.4rem;
}

.settings-grid[b-6sm8tliamm] {
    display: grid;
    grid-template-columns: repeat(2, minmax(140px, 1fr));
    gap: 0.45rem 0.6rem;
}

.settings-grid-wide[b-6sm8tliamm] {
    grid-template-columns: 1fr;
}

.settings-field[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: #4d5f72;
}

.settings-season-row[b-6sm8tliamm] {
    display: flex;
    gap: 0.8rem;
    flex-wrap: wrap;
}

.settings-season-row .settings-field[b-6sm8tliamm] {
    min-width: 7rem;
}

.settings-toggle[b-6sm8tliamm] {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9rem;
    color: #1f2d3d;
}

.settings-toggle-inline[b-6sm8tliamm] {
    flex-wrap: wrap;
}

.settings-control[b-6sm8tliamm] {
    width: auto;
}

.settings-control-courts[b-6sm8tliamm] {
    max-width: 5.5rem;
}

.settings-control-award[b-6sm8tliamm] {
    max-width: 10rem;
}

.settings-control-score[b-6sm8tliamm] {
    max-width: 6rem;
}

.settings-control-money[b-6sm8tliamm] {
    max-width: 7.5rem;
}

.settings-control-depth[b-6sm8tliamm] {
    max-width: 6rem;
}

.settings-control-name[b-6sm8tliamm] {
    max-width: 18rem;
}

@media (max-width: 760px) {
    .settings-grid[b-6sm8tliamm] {
        grid-template-columns: 1fr;
    }
}

/* R4b (#1006): the kiosk framing strips (always-on / escape-hatch / no-PIN caution) MOVED from here into
   ClubSessionSettingsEditor.razor.css — the scoped CSS follows the markup down into the per-profile editor's
   grouped "Kiosk mode" block. The per-club "Organiser PIN" card above uses only .kiosk-pin-card chrome
   (scoped near the top of this file). */

/* ── SPEC-32 S4 (#188): the "Shown to club members" visibility toggles. A stacked list of label rows,
   each a title + sub-label on the left and a switch on the right. Mirrors the mockup's toggle-row and the
   KioskDisplayProfileSettingsCard shape, styled to this page's palette. ── */
.pv-toggles[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-top: 0.2rem;
}

.pv-row[b-6sm8tliamm] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.8rem;
    padding: 0.5rem 0.6rem;
    border: 1px solid #d5e2ef;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.7);
    margin: 0; /* override Bootstrap <label> default */
    cursor: pointer;
}

.pv-row:hover[b-6sm8tliamm] {
    border-color: #9db6d6;
}

/* The locked Identity row is a non-interactive indicator, not a control. */
.pv-row-locked[b-6sm8tliamm] {
    cursor: default;
    background: #eef3f9;
}

.pv-row-locked:hover[b-6sm8tliamm] {
    border-color: #d5e2ef;
}

.pv-label[b-6sm8tliamm] {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
    min-width: 0;
}

.pv-title[b-6sm8tliamm] {
    font-size: 0.92rem;
    font-weight: 600;
    color: #1f2d3d;
}

.pv-desc[b-6sm8tliamm] {
    font-size: 0.76rem;
    color: #5f6f80;
}

.pv-locked-badge[b-6sm8tliamm] {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 700;
    color: #3a5168;
    background: #dbe6f2;
    border: 1px solid #bcccdd;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    white-space: nowrap;
    flex: 0 0 auto;
}

/* The Bootstrap .form-check.form-switch wrapper renders the pill-track+knob switch (same as
   Members.razor). Keep the wrapper as a flex-fixed right-hand item; drop its default block padding
   (no adjacent label here) and scale the em-based switch up for a kiosk/touch target via font-size. */
.pv-switch-wrap[b-6sm8tliamm] {
    flex: 0 0 auto;
    margin: 0;
    padding-left: 2.5em;   /* Bootstrap's form-switch gutter for the floated input */
    min-height: 0;
    font-size: 1.15rem;    /* enlarges the em-sized switch track + knob for touch */
}

.pv-switch[b-6sm8tliamm] {
    cursor: pointer;
    margin-left: -2.5em;   /* pull the input back into the wrapper gutter (Bootstrap form-switch) */
}

.pv-switch:disabled[b-6sm8tliamm] {
    cursor: not-allowed;
    opacity: 0.6;
}

/* The interim, non-binding consent warning under the Contact toggle (SEC-016). Warning weight, but not
   alarming — it's guidance, and the binding copy is an Owner gate. */
.pv-consent-warning[b-6sm8tliamm] {
    margin: 0.6rem 0 0;
    padding: 0.5rem 0.6rem;
    font-size: 0.82rem;
    line-height: 1.35;
    color: #6c4a00;
    background: #fff6e6;
    border: 1px solid #f0d9a8;
    border-radius: 8px;
}

/* When Contact is actually exposed, the warning carries more weight (amber -> a firmer tone) so the
   live-exposure state reads distinctly from the "off by default" guidance. */
.pv-consent-warning-active[b-6sm8tliamm] {
    color: #7a2e12;
    background: #fdeee6;
    border-color: #f0c3a8;
}

.pv-consent-pending[b-6sm8tliamm] {
    color: #8a6a2a;
    font-style: italic;
}
/* /Components/Pages/SettingsProfileEdit.razor.rz.scp.css */
/* #1009 (settings-restructure S1) — scoped styles for the per-profile edit page.
   Scoped CSS does not cross component boundaries, so the page-level `.settings-*` chrome is copied
   here from Settings.razor.css (the ClubSessionSettingsEditor's OWN sections/kiosk framing are styled
   by ITS scoped CSS, which travels with it — not repeated here). Plus the net-new anchor-nav block. */

.settings-shell[b-hw5mufr3sf] {
    padding: 0;
}

.settings-shell h1[b-hw5mufr3sf] {
    color: #0d2c55;
    font-size: 1.4rem;
    margin: 0 0 0.6rem;
}

.settings-card[b-hw5mufr3sf] {
    background: #f6f8fb;
    border-radius: 0.35rem;
    margin-bottom: 0.75rem;
    padding: 0.75rem 0.85rem;
    border: 1px solid rgba(13, 44, 85, 0.08);
}

/* #474 read-only banner (shown when the user can view but not change). */
.settings-readonly-banner[b-hw5mufr3sf] {
    font-weight: 600;
    color: #6c4a00;
    background: #fff8ec;
    border: 1px solid #f0d9a8;
    border-radius: 0.35rem;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.6rem;
}

/* Back-to-list breadcrumb (mockup Screen B header). */
.breadcrumb-back[b-hw5mufr3sf] {
    display: inline-block;
    color: #1f4e8c;
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    margin-bottom: 0.5rem;
}

.breadcrumb-back:hover[b-hw5mufr3sf] {
    text-decoration: underline;
}

/* Profile name + default-flag card. */
.settings-field[b-hw5mufr3sf] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: #4d5f72;
}

.settings-field-name[b-hw5mufr3sf] {
    max-width: 22rem;
}

.settings-default-field[b-hw5mufr3sf] {
    margin-top: 0.6rem;
}

.settings-default-label[b-hw5mufr3sf] {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: #24384f;
}

.settings-control[b-hw5mufr3sf] {
    width: auto;
}

.settings-control-name[b-hw5mufr3sf] {
    max-width: 22rem;
}

/* ── Master-detail edit layout: sticky anchor nav on the left, editor on the right ── */
.edit-layout[b-hw5mufr3sf] {
    display: grid;
    grid-template-columns: 12rem 1fr;
    gap: 0.85rem;
    align-items: start;
}

.edit-main[b-hw5mufr3sf] {
    min-width: 0;
}

/* #1017: the "On this page" jump-nav chrome (.anchor-nav / .anchor-title / .anchor-link) moved into
   the shared SettingsAnchorNav component's own scoped CSS, so it travels with the component to both
   hosts. The page keeps only the surrounding grid layout below. */

/* ── Scoped sticky Save bar (this profile ONLY) ── */
.settings-actions[b-hw5mufr3sf] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    position: sticky;
    bottom: 0;
    background: rgba(255, 255, 255, 0.96);
    border-top: 1px solid #d5e2ef;
    padding: 0.6rem 0.75rem;
    margin-top: 0.8rem;
    z-index: 5;
    box-shadow: 0 -2px 6px rgba(13, 44, 85, 0.08);
}

.save-scope-note[b-hw5mufr3sf] {
    color: #4f6177;
    font-size: 0.85rem;
    margin-right: auto;
}

.settings-dirty-indicator[b-hw5mufr3sf] {
    color: #b54708;
    font-size: 0.9rem;
    font-weight: 600;
}

.settings-message[b-hw5mufr3sf] {
    color: #4f6177;
    font-size: 0.92rem;
}

.settings-save-error[b-hw5mufr3sf] {
    color: #b42318;
    font-weight: 600;
}

@media (max-width: 760px) {
    .edit-layout[b-hw5mufr3sf] {
        grid-template-columns: 1fr;
    }

    .save-scope-note[b-hw5mufr3sf] {
        margin-right: 0;
        flex-basis: 100%;
    }
}
/* /Components/Pages/Signup.razor.rz.scp.css */
.signup-shell[b-xlusw96nc4] {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem 1.5rem 2rem;
    background:
        radial-gradient(circle at 28% 18%, rgba(140, 190, 240, 0.22) 0%, transparent 55%),
        radial-gradient(circle at 78% 88%, rgba(93, 176, 97, 0.10) 0%, transparent 55%),
        linear-gradient(180deg, #294f76 0%, #1f3d5b 100%);
    margin: -1rem -1.5rem -1rem;
}

/* Match MainLayout's asymmetric .content padding-left at desktop. */
@media (min-width: 1280px) {
    .signup-shell[b-xlusw96nc4] {
        margin-left: -2rem;
    }
}

.signup-brand[b-xlusw96nc4] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    margin-bottom: 0.75rem;
}

.signup-brand-mark[b-xlusw96nc4] {
    font-size: 2.4rem;
    font-weight: 800;
    color: #ffffff;
    letter-spacing: 0.6px;
    line-height: 1;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
}

/* BL-057 (2026-04-26 v6): split assets — figures + wordmark sized
   independently to match the .login-brand-logo treatment. */
.signup-brand-logo[b-xlusw96nc4] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.signup-brand-logo .signup-brand-figures[b-xlusw96nc4] {
    display: block;
    height: 3.5rem;
    width: auto;
}

.signup-brand-logo .signup-brand-wordmark[b-xlusw96nc4] {
    display: block;
    height: 3.5rem;
    width: auto;
    max-width: 100%;
}

.signup-brand-tagline[b-xlusw96nc4] {
    color: #cfe1f3;
    font-size: 0.95rem;
    font-weight: 500;
    letter-spacing: 0.2px;
}

.signup-card[b-xlusw96nc4] {
    width: min(34rem, 92vw);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 0.85rem;
    background: #ffffff;
    padding: 1.5rem 1.5rem 1.3rem;
    box-shadow: 0 14px 32px rgba(8, 24, 50, 0.34);
}

.signup-card h1[b-xlusw96nc4] {
    margin: 0 0 0.35rem;
    color: #1f3f5e;
}

.signup-help[b-xlusw96nc4] {
    color: #5e748a;
    margin: 0 0 0.8rem;
}

.signup-password-hint[b-xlusw96nc4] {
    font-size: 0.82rem;
    margin-bottom: 0;
}

.signup-password-hint-neutral[b-xlusw96nc4] {
    color: #6c757d;
}

.signup-password-hint-short[b-xlusw96nc4] {
    color: #8a5a00;
}

.signup-password-hint-ok[b-xlusw96nc4] {
    color: #1e7e34;
}

.signup-field-error[b-xlusw96nc4] {
    color: #8a2d2d;
    font-size: 0.82rem;
    margin-bottom: 0;
}

.signup-actions[b-xlusw96nc4] {
    margin-top: 0.8rem;
}

.signup-login-link[b-xlusw96nc4] {
    margin-top: 0.75rem;
    color: #4d6177;
    font-size: 0.92rem;
}

.signup-login-link a[b-xlusw96nc4] {
    color: #0f4f8b;
    font-weight: 600;
}

.signup-error[b-xlusw96nc4] {
    margin-top: 0.75rem;
    margin-bottom: 0.75rem;
    border: 1px solid #d88f8f;
    background: #f7e3e3;
    color: #8a2d2d;
    border-radius: 0.5rem;
    padding: 0.5rem 0.6rem;
    font-size: 0.9rem;
}

.signup-error-actions[b-xlusw96nc4] {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.85rem;
}

.signup-error-actions a[b-xlusw96nc4] {
    color: #0f4f8b;
    font-weight: 600;
}

/* #683 (portal S9a): the claim-first acknowledgement line above the duplicate-email
   action links. */
.signup-error-note[b-xlusw96nc4] {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.85rem;
}

.signup-error-actions a + a[b-xlusw96nc4] {
    margin-left: 0.25rem;
}

.signup-pilot-footnote[b-xlusw96nc4] {
    margin-top: 1rem;
    margin-bottom: 0;
    font-size: 0.78rem;
    color: #6c757d;
    line-height: 1.5;
}

.signup-pilot-footnote a[b-xlusw96nc4] {
    color: #0f4f8b;
}

/* #269 honeypot: park the decoy field far off-screen. Deliberately NOT
   display:none / visibility:hidden - naive bots skip those; off-screen
   positioning still reads as "fillable" to them while staying invisible
   and untabbable for humans. */
.signup-website-field[b-xlusw96nc4] {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}
/* /Components/Pages/Signups.razor.rz.scp.css */
/* #379 Sign-ups activity report. */
.signups-controls[b-gzeazmun1x] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.8rem;
}

.signups-window-label[b-gzeazmun1x] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #2e4f6d;
    font-weight: 600;
}

.signups-window-select[b-gzeazmun1x] {
    width: auto;
    min-width: 9rem;
}

.signups-counts[b-gzeazmun1x] {
    color: #2e4f6d;
}

/* Mobile: stack the (already narrow) table into cards so it reads cleanly on a
   phone, matching the Active Sessions pattern. Scoped to this component. */
@media (max-width: 599.98px) {
    .table-responsive[b-gzeazmun1x] {
        overflow-x: visible;
    }

    .clubs-table thead[b-gzeazmun1x] {
        display: none;
    }

    .clubs-table[b-gzeazmun1x],
    .clubs-table tbody[b-gzeazmun1x],
    .clubs-table tr[b-gzeazmun1x],
    .clubs-table td[b-gzeazmun1x] {
        display: block;
        width: 100%;
    }

    .clubs-table tr[b-gzeazmun1x] {
        border: 1px solid #cdd8e6;
        border-radius: 0.6rem;
        background: #fff;
        padding: 0.35rem 0.6rem;
        margin-bottom: 0.6rem;
    }

    .clubs-table td[b-gzeazmun1x] {
        border: none;
        padding: 0.2rem 0;
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.75rem;
        text-align: right;
    }

    .clubs-table td[b-gzeazmun1x]::before {
        content: attr(data-label);
        font-weight: 600;
        color: #557693;
        text-align: left;
    }

    /* #443 (SPEC-20 §8.11.3): club chips inside a data-label card. The ONLY genuinely new
       styling in this slice - /users has no card collapse, so there is no precedent to
       lift for chips-inside-a-card. Scoped to this component and inside the EXISTING
       breakpoint: no new breakpoint, no new pattern, desktop untouched.

       The td above is already the flex container (space-between, with ::before as its first
       item), so the chip block is its second child and lays itself out here.

       Rule 1 (right-aligned chips) is implemented with align-items, NOT the justify-content
       the spec text names. Deliberate, and it is the same intent: once rule 2 turns this
       container into a COLUMN, the cross axis is the horizontal one, so align-items is the
       property that controls left/right and justify-content would distribute vertically
       instead. Right-aligned chips under a right-aligned label is what rule 1 asks for. */
    .clubs-table td .club-chip-list[b-gzeazmun1x] {
        flex-direction: column;   /* rule 2: one chip per line - at 375px the label eats ~55px
                                     and a real club name plus a role cannot share a line, so
                                     stacking is deterministic and scans better than a 2-then-1 wrap */
        align-items: flex-end;    /* rule 1: chips hug the right edge, under the right-aligned label */
        min-width: 0;             /* rule 3: allow the block to shrink below its content width */
    }

    /* Rule 3: the desktop chip is white-space:nowrap; on mobile a long club name must wrap
       INSIDE the chip rather than widen the card. .table-responsive is overflow-x:visible in
       this breakpoint, so an over-wide card overflows the PAGE, not a scroller. The card must
       never scroll sideways.

       Both declarations are needed. white-space:normal only permits a break where one already
       exists (a space), so it handles "Riverside Badminton and Racquets Association" but NOT a
       single spaceless token longer than the cell - which would still widen the card, the exact
       failure this rule names. overflow-wrap:anywhere lets the break happen mid-token as a last
       resort. Club names are user-entered, so a spaceless one is a realistic input, not a
       hypothetical. */
    .clubs-table td .club-chip[b-gzeazmun1x] {
        white-space: normal;
        overflow-wrap: anywhere;
    }
}
/* /Components/Pages/StaleSessions.razor.rz.scp.css */
/* #204: confirm-dialog overlay for the stale-session close action. Self-contained
   here because the look-alike .end-session-modal styles on ClubSessionDashboard are
   component-scoped and don't reach this page. */
.stale-confirm-backdrop[b-kb18p64wp6] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2200;
}

.stale-confirm-modal[b-kb18p64wp6] {
    width: min(520px, 94vw);
    background: #ffffff;
    border: 1px solid #c8d4e2;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 1.1rem 1.2rem 1rem;
}
/* /Components/Pages/Support.razor.rz.scp.css */
/* #583: the always-available Community Supporter hub. Reuses the platform's card look; the inner
   ask body is styled by the shared SupporterAsk component, this file owns the page frame + story. */
.support-page[b-ki65q51o0x] {
    max-width: 52rem;
}

.support-card[b-ki65q51o0x] {
    border: 1px solid rgba(92, 119, 145, 0.3);
    border-radius: 0.65rem;
    background: #ffffff;
    padding: 1.25rem;
    margin-bottom: 1rem;
    box-shadow: 0 0.15rem 0.35rem rgba(17, 35, 53, 0.06);
}

.support-heading[b-ki65q51o0x] {
    font-size: 1.05rem;
    margin-bottom: 0.4rem;
}

.support-story[b-ki65q51o0x] {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(92, 119, 145, 0.2);
}

.support-story p[b-ki65q51o0x],
.support-body[b-ki65q51o0x] {
    color: #4b5f75;
    font-size: 0.92rem;
    max-width: 46rem;
}

.support-fund-list[b-ki65q51o0x] {
    color: #4b5f75;
    font-size: 0.92rem;
    margin: 0.25rem 0 0.75rem 1.1rem;
}

.support-fund-list li[b-ki65q51o0x] {
    margin-bottom: 0.2rem;
}

.support-promise[b-ki65q51o0x] {
    font-weight: 600;
    color: #2b4a73;
}
/* /Components/Pages/SystemUsers.razor.rz.scp.css */
.system-users-filters[b-bos17xn4ou] {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) auto;
    gap: 0.7rem;
    align-items: end;
    margin-bottom: 0.75rem;
}

.system-users-filter[b-bos17xn4ou] {
    display: flex;
    flex-direction: column;
}

.system-users-filter .form-label[b-bos17xn4ou] {
    font-size: 0.82rem;
    font-weight: 600;
    color: #24384f;
    margin-bottom: 0.2rem;
}

.system-users-filter-actions[b-bos17xn4ou] {
    flex-direction: row;
    gap: 0.5rem;
    justify-content: flex-end;
    align-items: flex-end;
}

.system-users-count-hint[b-bos17xn4ou] {
    color: #6c7a8c;
    font-size: 0.88rem;
    margin-bottom: 0.4rem;
}

.system-users-table thead th[b-bos17xn4ou] {
    color: #2a2f36;
    border-bottom: 1px solid #1f2b38;
    font-size: 0.95rem;
    white-space: nowrap;
}

.system-users-table th.sortable-header[b-bos17xn4ou] {
    cursor: pointer;
    user-select: none;
}

.system-users-table th.sortable-header:hover[b-bos17xn4ou] {
    color: #0d2c55;
}

.system-users-table td[b-bos17xn4ou],
.system-users-table th[b-bos17xn4ou] {
    vertical-align: middle;
}

/* #443 (R-C12.25): the club-chip rules that used to live here (.system-users-clubs /
   -club-chip / -club-role) moved VERBATIM to wwwroot/app.css as .club-chip-list /
   .club-chip / .club-chip-role. Blazor scopes this file to SystemUsers' b-* attribute, so
   /admin/signups reusing the markup would have rendered unstyled plain text - with no build
   error and no failing test. Shared globally, "the two surfaces must not diverge" is true by
   construction rather than by vigilance. Do not re-add a local copy here. */

@media (max-width: 768px) {
    .system-users-filter-actions[b-bos17xn4ou] {
        justify-content: flex-start;
    }
}
/* /Components/Pages/TeamEdit.razor.rz.scp.css */
/* SPEC-34 S1 — Create/edit team (c-newsquad mock screen). House tokens only:
   navy #0d2c55, blue #1b6ec2, off-white cards. No new brand. */

.team-back-link[b-30gmq6961g] {
    background: 0;
    border: 0;
    color: #1b6ec2;
    font-weight: 700;
    font-size: .82rem;
    cursor: pointer;
    padding: 0;
    margin-bottom: .5rem;
    display: inline-block;
}

.team-form-prompt[b-30gmq6961g] {
    color: #5e748a;
    font-size: .9rem;
    margin: .1rem 0 1.1rem;
}

.team-form-grid[b-30gmq6961g] {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .85rem;
}

@media (max-width: 620px) {
    .team-form-grid[b-30gmq6961g] { grid-template-columns: 1fr; }
}

.team-field[b-30gmq6961g] {
    margin-bottom: .85rem;
    display: flex;
    flex-direction: column;
}

.team-field label[b-30gmq6961g] {
    font-size: .78rem;
    font-weight: 700;
    color: #42566d;
    margin-bottom: .3rem;
}

.team-optional[b-30gmq6961g] {
    color: #8496a8;
    font-weight: 600;
}

.team-input[b-30gmq6961g] {
    width: 100%;
    border: 1px solid #cbd5e1;
    border-radius: .55rem;
    padding: .6rem .7rem;
    font-size: .92rem;
    color: #16324f;
    background: #fff;
}

.team-input:focus-visible[b-30gmq6961g] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
    border-color: #1b6ec2;
}

.team-squad-head[b-30gmq6961g] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin: 1.25rem 0 .55rem;
}

.team-section-label[b-30gmq6961g] {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #5e748a;
    font-weight: 800;
}

.team-section-hint[b-30gmq6961g] {
    font-size: .78rem;
    color: #8496a8;
    font-weight: 600;
    margin-left: .4rem;
}

.team-add-row[b-30gmq6961g] {
    display: flex;
    gap: .6rem;
    align-items: center;
    margin-bottom: .85rem;
    flex-wrap: wrap;
}

.team-add-select[b-30gmq6961g] {
    flex: 1 1 16rem;
}

.team-empty-squad[b-30gmq6961g] {
    color: #8496a8;
    font-size: .86rem;
    padding: .6rem 0 1rem;
}

.team-squad-list[b-30gmq6961g] {
    display: flex;
    flex-direction: column;
    gap: .55rem;
    margin-bottom: .4rem;
}

.team-row[b-30gmq6961g] {
    display: flex;
    align-items: center;
    gap: .8rem;
    border: 1px solid #e2e8f0;
    border-radius: .7rem;
    padding: .7rem .85rem;
    background: #fff;
}

.team-row--captain[b-30gmq6961g] {
    border-color: #eccf7f;
    background: #fffdf5;
}

.team-avatar[b-30gmq6961g] {
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    background: #eef2f7;
    color: #42566d;
    font-weight: 800;
    font-size: .85rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.team-row-body[b-30gmq6961g] {
    flex: 1 1 auto;
    min-width: 0;
}

.team-row-name[b-30gmq6961g] {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-weight: 700;
    color: #16324f;
    font-size: .95rem;
    flex-wrap: wrap;
}

.team-row-meta[b-30gmq6961g] {
    display: block;
    font-size: .75rem;
    color: #8496a8;
}

.gchip[b-30gmq6961g] {
    font-size: .6rem;
    font-weight: 800;
    border-radius: .3rem;
    padding: .03rem .3rem;
}

.gchip--m[b-30gmq6961g] { background: #e8f0fb; color: #1861ac; }
.gchip--l[b-30gmq6961g] { background: #fbeaf3; color: #a83b78; }

.captain-pill[b-30gmq6961g] {
    font-size: .6rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .03em;
    border-radius: 999px;
    padding: .1rem .45rem;
    background: #fff4d6;
    color: #8a6300;
    border: 1px solid #eccf7f;
}

.team-cap-btn[b-30gmq6961g],
.team-remove-btn[b-30gmq6961g] {
    background: #eef2f7;
    border: 1px solid #d7dee7;
    color: #1861ac;
    border-radius: .45rem;
    padding: .35rem .55rem;
    font-size: .9rem;
    font-weight: 700;
    cursor: pointer;
    flex: 0 0 auto;
    line-height: 1;
}

.team-cap-btn[aria-pressed="true"][b-30gmq6961g] {
    background: #fff4d6;
    border-color: #eccf7f;
    color: #8a6300;
}

.team-remove-btn[b-30gmq6961g] {
    color: #b23434;
}

.team-error[b-30gmq6961g] {
    color: #b23434;
    background: #fdecec;
    border: 1px solid #f4caca;
    border-radius: .55rem;
    padding: .55rem .75rem;
    font-size: .85rem;
    margin: .3rem 0 0;
}

.team-actions[b-30gmq6961g] {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 1.2rem;
}

.team-retire[b-30gmq6961g] {
    color: #b23434;
    margin-left: auto;
}

.team-retire-confirm[b-30gmq6961g] {
    display: inline-flex;
    gap: .45rem;
    align-items: center;
    margin-left: auto;
    font-size: .85rem;
    color: #42566d;
}
/* /Components/Pages/TeamFixtures.razor.rz.scp.css */
/* SPEC-34 S2 — team detail / fixtures hub (c-fix mock screen). House tokens only:
   navy #0d2c55, blue #1b6ec2, off-white cards. No new brand. */

.fix-header[b-v4tmn5b0qu] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.15rem;
}

.fix-subtitle[b-v4tmn5b0qu] {
    color: #5e748a;
    font-size: .9rem;
    margin: .25rem 0 0;
    max-width: 44rem;
}

.fix-header-actions[b-v4tmn5b0qu] {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}

.fix-section-label[b-v4tmn5b0qu] {
    font-size: .74rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #5e748a;
    font-weight: 800;
    margin: 1.25rem 0 .55rem;
}

.fix-row[b-v4tmn5b0qu] {
    display: flex;
    align-items: center;
    gap: .9rem;
    border: 1px solid #e2e8f0;
    border-radius: .8rem;
    padding: .85rem 1rem;
    margin-bottom: .7rem;
    background: #fff;
}

.fix-row--past[b-v4tmn5b0qu] {
    opacity: .75;
}

.fix-date[b-v4tmn5b0qu] {
    flex: 0 0 auto;
    text-align: center;
    background: #eef2f7;
    border-radius: .55rem;
    padding: .4rem .55rem;
    min-width: 3.3rem;
}

.fix-date-m[b-v4tmn5b0qu] {
    font-size: .64rem;
    text-transform: uppercase;
    color: #8496a8;
    font-weight: 800;
}

.fix-date-d[b-v4tmn5b0qu] {
    font-size: 1.25rem;
    font-weight: 800;
    color: #16324f;
    line-height: 1;
}

.fix-body[b-v4tmn5b0qu] {
    flex: 1 1 auto;
    min-width: 0;
}

.fix-title[b-v4tmn5b0qu] {
    font-weight: 800;
    color: #16324f;
    display: flex;
    align-items: center;
    gap: .45rem;
    flex-wrap: wrap;
}

.fix-meta[b-v4tmn5b0qu] {
    font-size: .8rem;
    color: #5e748a;
    margin-top: .15rem;
}

.fix-prog[b-v4tmn5b0qu] {
    font-size: .78rem;
    margin-top: .25rem;
    font-weight: 600;
}

.fix-prog--draft[b-v4tmn5b0qu] {
    color: #8496a8;
}

/* SPEC-34 S3: Collecting-fixture availability progress line. */
.fix-prog--collecting[b-v4tmn5b0qu] {
    color: #1c6b3f;
}

.fix-actions[b-v4tmn5b0qu] {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    flex: 0 0 auto;
    align-items: flex-end;
}

.fix-stat[b-v4tmn5b0qu] {
    font-size: .64rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: .2rem .5rem;
    border-radius: 999px;
    white-space: nowrap;
}

.fix-stat--draft[b-v4tmn5b0qu] {
    background: #eef2f7;
    color: #5e748a;
    border: 1px solid #d7dee7;
}

/* SPEC-34 S3: Collecting / Team-picked status chips + a primary row action. */
.fix-stat--collecting[b-v4tmn5b0qu] {
    background: #eef6ff;
    color: #1861ac;
    border: 1px solid #bcd8f7;
}

.fix-stat--picked[b-v4tmn5b0qu] {
    background: #f0fdf4;
    color: #1c6b3f;
    border: 1px solid #bbf7d0;
}

.fix-iconbtn--primary[b-v4tmn5b0qu] {
    background: #1861ac;
    border-color: #1861ac;
    color: #fff;
}

.fix-iconbtn--primary:hover[b-v4tmn5b0qu] {
    background: #14538f;
}

.fix-iconbtn[b-v4tmn5b0qu] {
    background: #eef2f7;
    border: 1px solid #d7dee7;
    color: #1861ac;
    border-radius: .45rem;
    padding: .35rem .5rem;
    font-size: .74rem;
    font-weight: 700;
    cursor: pointer;
}

.fix-iconbtn:hover[b-v4tmn5b0qu] {
    background: #e2ebf5;
}

.pill[b-v4tmn5b0qu] {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .66rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .03em;
    border-radius: 999px;
    padding: .12rem .5rem;
}

.pill--home[b-v4tmn5b0qu] {
    background: #f0fdf4;
    color: #1c6b3f;
    border: 1px solid #bbf7d0;
}

.pill--away[b-v4tmn5b0qu] {
    background: #fff4e6;
    color: #9a5a12;
    border: 1px solid #f3d3a6;
}

.fix-empty[b-v4tmn5b0qu] {
    text-align: left;
}

.fix-empty h2[b-v4tmn5b0qu] {
    font-size: 1.1rem;
    color: #16324f;
    margin-bottom: .4rem;
}
/* /Components/Pages/Teams.razor.rz.scp.css */
/* SPEC-34 S1 — Teams list (c-squad mock screen). House tokens only:
   navy #0d2c55, blue #1b6ec2, off-white cards. No new brand. */

.teams-header[b-jbf5utn5a3] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1.15rem;
}

.teams-subtitle[b-jbf5utn5a3] {
    color: #5e748a;
    font-size: .9rem;
    margin: .25rem 0 0;
    max-width: 44rem;
}

.teams-list[b-jbf5utn5a3] {
    display: flex;
    flex-direction: column;
    gap: .7rem;
}

.team-card[b-jbf5utn5a3] {
    display: flex;
    align-items: center;
    gap: .85rem;
    border: 1px solid #e2e8f0;
    border-radius: .8rem;
    padding: .9rem 1rem;
    background: #fff;
    cursor: pointer;
    width: 100%;
    text-align: left;
    font: inherit;
    color: inherit;
}

.team-card:hover[b-jbf5utn5a3] {
    background: #f7fafd;
}

.team-card:focus-visible[b-jbf5utn5a3] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

.team-badge[b-jbf5utn5a3] {
    width: 2.9rem;
    height: 2.9rem;
    border-radius: .65rem;
    background: #0d2c55;
    color: #8fc0ee;
    font-weight: 800;
    font-size: .9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

.team-body[b-jbf5utn5a3] {
    flex: 1 1 auto;
    min-width: 0;
}

.team-name[b-jbf5utn5a3] {
    display: block;
    font-weight: 800;
    color: #16324f;
    font-size: 1rem;
}

.team-meta[b-jbf5utn5a3] {
    display: block;
    font-size: .8rem;
    color: #5e748a;
    margin-top: .1rem;
}

.team-go[b-jbf5utn5a3] {
    color: #9fb0c2;
    font-weight: 800;
    font-size: 1.2rem;
    flex: 0 0 auto;
}

.teams-grid[b-jbf5utn5a3] {
    display: flex;
    flex-direction: column;
    gap: .7rem;
}

.team-card--skeleton[b-jbf5utn5a3] {
    height: 4.7rem;
    background: linear-gradient(90deg, #eef2f7 25%, #f7fafd 50%, #eef2f7 75%);
    background-size: 200% 100%;
    animation: team-skeleton-b-jbf5utn5a3 1.2s ease-in-out infinite;
    border: 1px solid #e2e8f0;
}

@keyframes team-skeleton-b-jbf5utn5a3 {
    from { background-position: 200% 0; }
    to { background-position: -200% 0; }
}

.teams-empty[b-jbf5utn5a3] {
    text-align: left;
}
/* /Components/Pages/UserActivity.razor.rz.scp.css */
.activity-controls[b-a29i2ufd7f] {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1rem;
}

.activity-control[b-a29i2ufd7f] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: #6b7c90;
}

.activity-control select[b-a29i2ufd7f] {
    min-width: 9rem;
}

.activity-export-btn[b-a29i2ufd7f] {
    margin-left: auto;
    align-self: flex-end;
}

.activity-totals[b-a29i2ufd7f] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.activity-total-card[b-a29i2ufd7f] {
    flex: 1 1 8rem;
    border: 1px solid rgba(120, 145, 175, 0.3);
    border-radius: 10px;
    padding: 0.7rem 0.9rem;
    background: #f7faff;
}

.activity-total-value[b-a29i2ufd7f] {
    font-size: 1.6rem;
    font-weight: 700;
    color: #2b4a73;
    line-height: 1.1;
}

.activity-total-label[b-a29i2ufd7f] {
    font-size: 0.78rem;
    color: #6b7c90;
    margin-top: 0.15rem;
}

.activity-proxy[b-a29i2ufd7f] {
    border-top: 1px solid rgba(120, 145, 175, 0.3);
    border-bottom: 1px solid rgba(120, 145, 175, 0.3);
    padding: 1rem 0;
    margin: 0.25rem 0 1.35rem;
}

.activity-proxy-title[b-a29i2ufd7f] {
    font-size: 0.95rem;
    margin: 0 0 0.55rem;
    color: #2b4a73;
}

.activity-proxy-totals[b-a29i2ufd7f] {
    margin-bottom: 0.55rem;
}

.activity-proxy-note[b-a29i2ufd7f] {
    margin: 0;
    color: #6b7c90;
    font-size: 0.78rem;
    line-height: 1.4;
}

/* #151: stacked definition/caveat notes under the active-users table need to breathe;
   the single-note cards above keep their existing zero margin. */
.activity-proxy-note + .activity-proxy-note[b-a29i2ufd7f] {
    margin-top: 0.55rem;
}

/* #151: the definition tooltip affordance on the active-users totals + table headings. */
.active-users-def[b-a29i2ufd7f] {
    color: #8a9bb0;
    font-size: 0.72rem;
}

[data-testid="active-users-section"] [title][b-a29i2ufd7f] {
    cursor: help;
}

.activity-chart-block[b-a29i2ufd7f] {
    margin-top: 1.1rem;
}

.activity-chart-title[b-a29i2ufd7f] {
    font-size: 0.95rem;
    margin: 0 0 0.35rem;
    color: #2b4a73;
}

.activity-chart-box[b-a29i2ufd7f] {
    position: relative;
    height: 220px;
}

.activity-kind-options[b-a29i2ufd7f] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    padding-bottom: 0.35rem;
}

.activity-kind-toggle[b-a29i2ufd7f] {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    margin: 0;
    color: #2b4a73;
}

.activity-detail-card[b-a29i2ufd7f] {
    margin-top: 1rem;
}

.activity-detail-head[b-a29i2ufd7f] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.6rem;
}

.activity-detail-title[b-a29i2ufd7f] {
    font-size: 1.05rem;
    margin: 0;
    color: #2b4a73;
}

.activity-detail-sub[b-a29i2ufd7f] {
    color: #6b7c90;
    font-weight: 400;
    font-size: 0.85rem;
}

.activity-detail-tabs[b-a29i2ufd7f] {
    display: flex;
    gap: 0.4rem;
    margin-bottom: 0.75rem;
}

.activity-detail-tab[b-a29i2ufd7f] {
    border: 1px solid rgba(120, 145, 175, 0.4);
    background: #fff;
    color: #4c6f95;
    border-radius: 999px;
    padding: 0.2rem 0.8rem;
    font-size: 0.82rem;
    cursor: pointer;
}

.activity-detail-tab.active[b-a29i2ufd7f] {
    background: linear-gradient(180deg, #6a88aa 0%, #4c6f95 100%);
    color: #fff;
    border-color: #4c6f95;
}

.activity-detail-table[b-a29i2ufd7f] {
    font-size: 0.86rem;
}

.activity-kind-badge[b-a29i2ufd7f] {
    margin-left: 0.4rem;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    vertical-align: middle;
}
/* /Components/Portal/LiveBoardReadOnly.razor.rz.scp.css */
/* S7c-2: lean read-only board — a phone-first subset of the console board rules (which live ::deep-scoped
   in ClubSessionDashboard.razor.css and cannot reach a new component). Same visual vocabulary, own scope. */

.lb-board[b-hniwnyu6ai] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.lb-heading[b-hniwnyu6ai] {
    font-size: 0.95rem;
    font-weight: 700;
    color: #0d2c55;
    margin: 0.35rem 0 0.15rem;
}

.lb-heading-note[b-hniwnyu6ai] {
    font-size: 0.72rem;
    font-weight: 500;
    color: #557693;
    margin-left: 0.35rem;
}

.lb-empty[b-hniwnyu6ai] {
    color: #557693;
    font-size: 0.85rem;
    margin: 0;
}

/* Courts — one column on a phone, two where there's room. */
.lb-courts-grid[b-hniwnyu6ai] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: 0.5rem;
}

.lb-court-card[b-hniwnyu6ai] {
    background: linear-gradient(180deg, #5db061 0%, #4b9a50 100%);
    color: #fff;
    border-radius: 0.85rem;
    border: 1px solid #75b978;
    padding: 0.5rem;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.lb-court-header[b-hniwnyu6ai] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0.2rem;
}

.lb-court-number[b-hniwnyu6ai] {
    font-size: 1.05rem;
    font-weight: 700;
    color: #f1fbf3;
}

.lb-court-time[b-hniwnyu6ai] {
    font-size: 0.78rem;
    color: #eafaec;
    font-variant-numeric: tabular-nums;
}

.lb-court-team-row[b-hniwnyu6ai] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    border: 1px solid rgba(255, 255, 255, 0.45);
    background: rgba(255, 255, 255, 0.1);
    border-radius: 0.5rem;
    padding: 0.25rem 0.4rem;
}

.lb-court-team-name[b-hniwnyu6ai] {
    font-weight: 600;
    font-size: 0.9rem;
}

.lb-court-vs[b-hniwnyu6ai] {
    align-self: center;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    color: #eafaec;
    text-transform: uppercase;
    padding: 0.05rem 0;
}

.lb-court-score[b-hniwnyu6ai] {
    align-self: center;
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    color: #fff;
    font-variant-numeric: tabular-nums;
    padding: 0.05rem 0;
}

/* Waiting queue — read-only chips. */
.lb-chip-list[b-hniwnyu6ai] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.lb-waiting-chip[b-hniwnyu6ai] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border-radius: 999px;
    padding: 0.22rem 0.55rem 0.22rem 0.28rem;
    border: 1px solid #a8bcd0;
    background: #f7fbff;
    color: #32516d;
    font-size: 0.82rem;
    font-weight: 600;
    max-width: 100%;
}

.lb-waiting-pos[b-hniwnyu6ai] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 999px;
    background: #e7eef6;
    border: 1px solid #c2d0df;
    color: #445c77;
    font-size: 0.66rem;
    font-weight: 700;
    line-height: 1;
}

.lb-waiting-name[b-hniwnyu6ai] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Avatars. */
.lb-player-avatar[b-hniwnyu6ai] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 999px;
    background: rgba(34, 72, 103, 0.85);
    color: #fff;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    overflow: hidden;
}

.lb-player-avatar-image[b-hniwnyu6ai] {
    object-fit: cover;
    padding: 0;
    /* Parity with the console board's ::deep .player-avatar-image: a white plate + hairline
       border so a photo reads cleanly and the gender tint never flashes behind a transparent PNG. */
    background: #fff;
    border: 1px solid rgba(31, 43, 56, 0.16);
}

/* Sitting out. */
.lb-sitting-out[b-hniwnyu6ai] {
    color: #557693;
    font-size: 0.85rem;
    margin: 0.2rem 0 0;
}

.lb-sitting-out-label[b-hniwnyu6ai] {
    font-weight: 700;
    color: #445c77;
    margin-right: 0.25rem;
}

/* Gender tone — mirror the console board's peg vocabulary so the read-only board reads the same,
   not all-green. Values lifted verbatim from ClubSessionDashboard.razor.css
   (::deep .court-team-row.gender-*, ::deep .player-avatar.gender-*). Kept under .lb-* scope because
   the console rules are ::deep-scoped to the dashboard and can't reach this component. */

/* On-court peg: the team row becomes a blue/pink pill (was translucent white over the green card,
   which read as "all green"). The name inherits the row's muted tone. */
/* SPEC-32 I4-S1 (#670), R-I2-44.1: the inks read the shared app.css tokens.

   The comment above says the values were "lifted verbatim" from ClubSessionDashboard.razor.css —
   which is the drift R-I2-44 is about, caught in the act of being written down. Both surfaces now
   read one definition; the values are unchanged to the byte. The backgrounds and borders stay local,
   because the tinted pill is this board's own surface and only the ink is the shared datum. */
.lb-court-team-row.lb-tone-male[b-hniwnyu6ai] {
    background: #dfeeff;
    border-color: #8fb6e0;
    color: var(--gender-name-male);
}

.lb-court-team-row.lb-tone-female[b-hniwnyu6ai] {
    background: #ffe4f3;
    border-color: #e3a4c7;
    color: var(--gender-name-female);
}

/* Waiting-queue name text picks up the same muted tone the console chip uses. */
.lb-waiting-name.lb-tone-male[b-hniwnyu6ai] {
    color: var(--gender-name-male);
}

.lb-waiting-name.lb-tone-female[b-hniwnyu6ai] {
    color: var(--gender-name-female);
}

/* Avatars tint by gender (was one fixed dark-blue for everyone). */
.lb-player-avatar.lb-tone-male[b-hniwnyu6ai] {
    background: #2f78c5;
}

.lb-player-avatar.lb-tone-female[b-hniwnyu6ai] {
    background: #cc5b98;
}
/* /Components/Recap/RecapDistributionChart.razor.rz.scp.css */
/* #88 Slice 1 (recap quality metrics): the shared distribution-chart primitive. Scoped
   to THIS component (the whole chart card markup lives here), so no ::deep is needed — the
   scope attribute lands on these elements directly (§16.9 flag 6). Values reuse the existing
   recap card family (SessionRecap.razor.css): white card, #e2e8f0 border, navy #16324f title,
   the recap tones. No new brand, no gradients/effects the recap doesn't already use. */

.recap-chart[b-jm4jaodekv] {
    margin: 0;
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.85rem;
    padding: 1.1rem 1.15rem 1.15rem;
}

.recap-chart-title[b-jm4jaodekv] {
    margin: 0 0 0.9rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: #16324f;
    line-height: 1.25;
}

.recap-chart-bars[b-jm4jaodekv] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* One bar row: [label] [track+fill] [count]. Labels are short plain-language bands, so this
   holds on one line even in the 34rem share column on a phone. */
.recap-chart-row[b-jm4jaodekv] {
    display: grid;
    grid-template-columns: 8.5rem 1fr 2rem;
    align-items: center;
    gap: 0.6rem;
}

.recap-chart-label[b-jm4jaodekv] {
    font-size: 0.9rem;
    color: #33475b;
    font-weight: 600;
}

.recap-chart-track[b-jm4jaodekv] {
    position: relative;
    height: 1.35rem;
    /* a11y (WCAG 1.4.11): darkened a shade from #eef2f6 so the empty rail is perceivable
       against the white card, with a 1px inner outline for the same reason. */
    background: #e4e9ee;
    box-shadow: inset 0 0 0 1px #c3ced9;
    border-radius: 0.3rem;
    overflow: hidden;
}

.recap-chart-fill[b-jm4jaodekv] {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    /* border-box so each fill's 1px tone border sits WITHIN its computed width (no overrun). */
    box-sizing: border-box;
    border-radius: 0.3rem;
    /* A nonzero bucket always shows at least a sliver. Only rendered for count > 0
       (the component omits the fill span for a zero bucket → empty rail). */
    min-width: 0.3rem;
}

/* Three tones — desirability, NOT alarm. The label + count carry the meaning in text, so
   these only reinforce. NO red anywhere (red = the "this night failed" misread we remove).
   a11y (WCAG 1.4.11 non-text-contrast): the FILL colours are unchanged (their meaning is
   approved), but a mid-tone fill on a near-white rail can't reach 3:1 on its own — amber
   #d98c2b caps at ~2.7:1 against any near-white surface. So each fill carries a 1px border
   in a darker shade of the SAME hue; that border is the graphical object's edge and clears
   3:1 against the #e4e9ee track (watch 3.87:1, good 5.36:1, neutral 6.73:1), so the bar
   LENGTH is perceivable — the "3:1 bordered object" path of 1.4.11. */
.tone-good .recap-chart-fill[b-jm4jaodekv] {
    background: #2f9e6f;
    border: 1px solid #1c6a49;
}

.tone-neutral .recap-chart-fill[b-jm4jaodekv] {
    background: #1b6ec2;
    border: 1px solid #14508c;
}

.tone-watch .recap-chart-fill[b-jm4jaodekv] {
    background: #d98c2b;
    border: 1px solid #a5641a;
}

.recap-chart-count[b-jm4jaodekv] {
    font-size: 0.92rem;
    font-weight: 700;
    color: #16324f;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.recap-chart-summary[b-jm4jaodekv] {
    margin: 0.9rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid #eef2f6;
    font-size: 0.9rem;
    color: #47586b;
}

/* #88 Slice 2: the per-chart empty / weak-signal state — neutral, never a verdict (no bars, no
   red, no empty axes). Shown when this chart lacks signal but a sibling in the section renders
   (§16.9; AC2.5). Same card frame as a live chart so the stack stays visually even. */
.recap-chart-empty[b-jm4jaodekv] {
    background: #fff;
    border: 1px solid #e2e8f0;
    border-radius: 0.85rem;
    padding: 1.1rem 1.15rem 1.15rem;
    font-size: 0.9rem;
    color: #5e748a;
}

.recap-chart-empty .recap-chart-title[b-jm4jaodekv] {
    color: #5e748a;
    margin: 0 0 0.35rem;
}
/* /Components/Shared/AppAccessCell.razor.rz.scp.css */
/* SPEC-31 S2 / OWNER-DECISION 1: three honest app-access states.
   Live  = solid/active (the person really can log in at this role).
   Pending = muted, clearly provisional (invite sent, not yet accepted).
   None  = quiet grey text (on the people list, no login). */

.badge.app-access-live[b-27ut4cpmxq] {
    /* Base/fallback fill for a live role with no role discriminator (legacy positional
       construction). The role modifier classes below override it per role. */
    background: #0d6efd;
    color: #ffffff;
    font-weight: 600;
}

/* profile-account-header: role-coded LIVE badges (Owner / Admin / Player). Declared
   AFTER .app-access-live so — at equal specificity — source order wins and the role
   fill overrides the base blue. On-brand navy→blue→pale-blue ramp; all WCAG AA for
   their text (Owner ~12:1, Admin ~5.8:1, Player ~7.4:1). Distinguished by lightness +
   weight + the role word (+ ★ on Owner), so they separate without hue. */
.badge.app-access-owner[b-27ut4cpmxq] {
    background: #0d2c55; /* deep title navy — heaviest, "founding / protected" */
    color: #ffffff;
    font-weight: 700;
}

.badge.app-access-admin[b-27ut4cpmxq] {
    background: #0b5ed7; /* solid active blue — a hair darker than the accent so white text clears AA */
    color: #ffffff;
    font-weight: 600;
}

.badge.app-access-player[b-27ut4cpmxq] {
    background: #e7f1ff; /* pale blue — the basic logged-in role reads as lower privilege */
    color: #0a4b9c;
    border: 1px solid #9ec3f0;
    font-weight: 600;
}

.badge.app-access-pending[b-27ut4cpmxq] {
    background: #e7edf4;
    color: #4a5f77;
    border: 1px solid #c3d0df;
    font-weight: 500;
    font-style: italic;
}

.app-access-none[b-27ut4cpmxq] {
    /* WCAG AA: #8090a2 on white was ~3.27:1 (fails 4.5:1), and this is the most
       frequent cell value (every unclaimed roster row). #4a5f77 clears it (~6.6:1)
       and matches .member-plays-readonly already on the page. */
    color: #4a5f77;
    font-size: 0.85rem;
}
/* /Components/Shared/BandChip.razor.rz.scp.css */
/* #234 refinement: the sentiment-tinted band chip. ONE style, reused across the /me personal recap
   and the club recap All-games list (scoped to this component via Blazor CSS isolation, so both
   surfaces get the identical pill). Low-saturation tints, graded warm (underdog / notable) ->
   neutral (even) -> cool (favourite / muted). All text/background pairs clear WCAG AA (>=4.5:1) per
   #225 — the tint is a redundant cue, the band word carries the meaning. */

.band-chip[b-4b0paozw7u] {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: 0.01em;
    white-space: nowrap;
    /* The band is a word, not a number — never inherit the tabular-nums the recap sets on values. */
    font-variant-numeric: normal;
}

/* Underdog end — warm, the notable/surprising outcome. */
.band-chip-strong-underdog[b-4b0paozw7u] {
    background: #f7e2d5;
    border-color: #eccbb6;
    color: #8a4420;
}

.band-chip-underdog[b-4b0paozw7u] {
    background: #f9ece1;
    border-color: #f0dac8;
    color: #925a30;
}

/* Even game — neutral grey. */
.band-chip-even[b-4b0paozw7u] {
    background: #eceff2;
    border-color: #dbe1e7;
    color: #4a5967;
}

/* Favourite end — cool, muted (the expected outcome). */
.band-chip-favourite[b-4b0paozw7u] {
    background: #e9eff5;
    border-color: #d5e1ec;
    color: #3e5670;
}

.band-chip-strong-favourite[b-4b0paozw7u] {
    background: #e2ecf6;
    border-color: #cadcef;
    color: #2f4d72;
}

/* Not forecastable -> quiet em-dash, matching the recap's existing muted placeholder. */
.band-none[b-4b0paozw7u] {
    color: #8595a6;
}
/* /Components/Shared/ClubSessionSettingsEditor.razor.rz.scp.css */
.settings-section[b-gcdp38x259] {
    border: 1px solid #d5e2ef;
    border-radius: 10px;
    padding: 0.55rem 0.6rem;
    background: rgba(255, 255, 255, 0.7);
    margin-top: 0.6rem;
}

/* SPEC-03 §B: the court inventory editor (label + in-use tick + remove, plus Add a court). */
.settings-field-courts[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-bottom: 0.5rem;
}

.court-set[b-gcdp38x259] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
}

.court-chip[b-gcdp38x259] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.35rem 0.2rem 0.45rem;
    border: 1.5px solid #c2cad3;
    border-radius: 999px;
    background: #fff;
}

.court-chip.in-use[b-gcdp38x259] {
    border-color: #1c8b5a;
    background: #e2f3ea;
}

/* #47: a court marked "no more games" — plays out its current game, then goes out of use. */
.court-chip.closing[b-gcdp38x259] {
    border-color: #d98a17;
    background: #fdf3e2;
}

.court-chip-closing[b-gcdp38x259] {
    color: #9a6212;
    font-size: 0.72rem;
    font-weight: 600;
    white-space: nowrap;
}

.court-chip-label[b-gcdp38x259] {
    width: 4.5rem;
    border: none;
    background: transparent;
    font-weight: 600;
    color: inherit;
    padding: 0.1rem 0.15rem;
    border-bottom: 1px dashed #8b95a1;
}

.court-chip-label:disabled[b-gcdp38x259] {
    border-bottom-color: transparent;
}

.court-chip-remove[b-gcdp38x259] {
    border: none;
    background: transparent;
    color: #8b95a1;
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.15rem;
}

.court-chip-remove:disabled[b-gcdp38x259] {
    opacity: 0.35;
    cursor: not-allowed;
}

.court-add[b-gcdp38x259] {
    border: 1.5px dashed #1a6dff;
    color: #1a6dff;
    background: transparent;
    border-radius: 999px;
    padding: 0.25rem 0.7rem;
    font-weight: 600;
    cursor: pointer;
}

.court-set-help[b-gcdp38x259] {
    margin: 0;
}

.settings-section-title[b-gcdp38x259] {
    font-size: 0.78rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #0d2c55;
    margin-bottom: 0.4rem;
}

.settings-grid[b-gcdp38x259] {
    display: grid;
    grid-template-columns: repeat(2, minmax(140px, 1fr));
    gap: 0.45rem 0.6rem;
}

.settings-grid-wide[b-gcdp38x259] {
    grid-template-columns: 1fr;
}

.settings-field[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.8rem;
    color: #4d5f72;
}

.settings-toggle[b-gcdp38x259] {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9rem;
    color: #1f2d3d;
}

.settings-toggle-inline[b-gcdp38x259] {
    flex-wrap: wrap;
}

.settings-control[b-gcdp38x259] {
    width: auto;
}

.settings-control-courts[b-gcdp38x259] {
    max-width: 5.5rem;
}

.settings-control-award[b-gcdp38x259] {
    max-width: 10rem;
}

.settings-control-score[b-gcdp38x259] {
    max-width: 6rem;
}

.settings-control-money[b-gcdp38x259] {
    max-width: 7.5rem;
}

.settings-control-depth[b-gcdp38x259] {
    max-width: 6rem;
}

@media (max-width: 760px) {
    .settings-grid[b-gcdp38x259] {
        grid-template-columns: 1fr;
    }
}

/* S2 (#67): Sticky pairs management section. */
.settings-section-help[b-gcdp38x259] {
    font-size: 0.78rem;
    color: #5a6c82;
    margin: 0 0 0.5rem;
    line-height: 1.4;
}

.settings-section-help code[b-gcdp38x259] {
    background: #e3edff;
    color: #0d2c55;
    border-radius: 4px;
    padding: 0 0.25rem;
    font-size: 0.74rem;
}

.sticky-pairs-empty[b-gcdp38x259] {
    font-size: 0.8rem;
    margin: 0 0 0.5rem;
}

.sticky-pairs-list[b-gcdp38x259] {
    list-style: none;
    margin: 0 0 0.6rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.sticky-pairs-item[b-gcdp38x259] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    border: 1px solid #c5cfde;
    background: #fff;
    border-radius: 10px;
}

.sticky-pairs-names[b-gcdp38x259] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: #1f3f5e;
    /* #45: a pending pair adds a second line naming who is still to arrive. Allow the row to wrap
       rather than pushing the Remove button off a narrow tablet — this list is read on the kiosk. */
    flex-wrap: wrap;
}

/* #45: "Waiting for X to check in" on a pair set up before its players arrived. Muted and secondary
   on purpose — it is a status, not a warning. Nothing is wrong with a pending pair; it is the whole
   point of the feature, and styling it as a problem would tell the organiser the opposite. */
.sticky-pairs-pending[b-gcdp38x259] {
    flex-basis: 100%;
    font-size: 0.8rem;
    color: #5a6b7d;
}

.sticky-pairs-link[b-gcdp38x259] {
    color: #1f4b76;
    font-size: 0.85rem;
}

.sticky-pairs-remove[b-gcdp38x259] {
    margin-left: auto;
}

.sticky-pairs-add[b-gcdp38x259] {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.sticky-pairs-select[b-gcdp38x259] {
    min-width: 9rem;
    max-width: 12rem;
}

.sticky-pairs-error[b-gcdp38x259] {
    font-size: 0.78rem;
    margin: 0.4rem 0 0;
}

.sticky-pairs-note[b-gcdp38x259] {
    font-size: 0.78rem;
    margin: 0.4rem 0 0;
    line-height: 1.35;
}

/* ADR 0007 (#985 E4): picker-policy enforcement mode radio group. */
.enforcement-mode-options[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.enforcement-mode-option[b-gcdp38x259] {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid #d5deea;
    border-radius: 8px;
    cursor: pointer;
    background: #fbfcfe;
}

.enforcement-mode-option:hover[b-gcdp38x259] {
    border-color: #9db6d6;
}

.enforcement-mode-option input[type="radio"][b-gcdp38x259] {
    margin-top: 0.2rem;
    flex: 0 0 auto;
}

.enforcement-mode-label[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.enforcement-mode-label b[b-gcdp38x259] {
    font-size: 0.9rem;
    color: #1f2d3d;
}

.enforcement-mode-desc[b-gcdp38x259] {
    font-size: 0.78rem;
    color: #5a6c82;
    line-height: 1.35;
}

/* R4 (#1004): the "(recommended)" tag on the Warn-but-allow enforcement option. */
.enforcement-mode-recommended[b-gcdp38x259] {
    color: #0d6efd;
    font-weight: 700;
    font-size: 0.78rem;
}

/* R4 (#1004): the FLAT kiosk-mode toggle ROWS (r4-settings-screen-ux-plan.md §8 — the one approved new
   in-language pattern). A switch + label + per-row help + a plain-language state read-out, richer than the
   bare .settings-toggle so an infrequent kiosk admin can READ the consequence ("Needs Admin Mode" vs
   "Allowed on the kiosk"). Chrome + hex lifted verbatim from the R4 mockup. */
.kiosk-toggle-list[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.kiosk-toggle[b-gcdp38x259] {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid #d5deea;
    border-radius: 8px;
    background: #fbfcfe;
    cursor: pointer;
}

.kiosk-toggle:hover[b-gcdp38x259] {
    border-color: #9db6d6;
}

.kiosk-toggle-switch[b-gcdp38x259] {
    flex: 0 0 auto;
    margin-top: 0.15rem;
}

/* iOS-style switch so on/off is legible at a glance (no hover needed). */
.switch[b-gcdp38x259] {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
}

.switch input[b-gcdp38x259] {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider[b-gcdp38x259] {
    position: absolute;
    inset: 0;
    background: #c3ccd8;
    border-radius: 24px;
    transition: 0.15s;
}

.slider[b-gcdp38x259]::before {
    content: "";
    position: absolute;
    height: 18px;
    width: 18px;
    left: 3px;
    top: 3px;
    background: #fff;
    border-radius: 50%;
    transition: 0.15s;
}

.switch input:checked + .slider[b-gcdp38x259] {
    background: #0d6efd;
}

.switch input:checked + .slider[b-gcdp38x259]::before {
    transform: translateX(18px);
}

.kiosk-toggle-body[b-gcdp38x259] {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.kiosk-toggle-label[b-gcdp38x259] {
    font-size: 0.92rem;
    font-weight: 600;
    color: #1f2d3d;
}

.kiosk-toggle-desc[b-gcdp38x259] {
    font-size: 0.79rem;
    color: #5a6c82;
    line-height: 1.35;
}

.kiosk-toggle-state[b-gcdp38x259] {
    font-size: 0.74rem;
    font-weight: 700;
    margin-top: 0.15rem;
}

.state-on[b-gcdp38x259] {
    color: #0d6efd;
}

.state-off[b-gcdp38x259] {
    color: #6b5a2e;
}

/* R4 (#1004): the flat kiosk-mode sub-sections read as mixed-case sibling groups (matching the r4 UX plan
   Variant A), not competing with the uppercase SESSION SETUP / AUTO-PICK headings above. */
.kiosk-mode-section .settings-section-title[b-gcdp38x259] {
    text-transform: none;
    letter-spacing: normal;
}

/* R4b (#1006): the Kiosk mode GROUP heading — one heading opening the consolidated group (always-on strip +
   tab/picker/enforcement sub-sections + escape-hatch callout). Reads at the weight of a card heading without
   being an h2 (the editor renders inside a host card / modal). */
.kiosk-mode-group-heading[b-gcdp38x259] {
    color: #24384f;
    font-size: 1.02rem;
    font-weight: 700;
    margin: 0.9rem 0 0.1rem;
}

/* R4b (#1006): the Kiosk mode framing strips — moved down from Settings.razor.css so the scoped CSS follows
   the markup. Always-on reassurance (green) opens the group; the escape-hatch callout (amber) closes it; the
   conditional no-PIN caution sits between enforcement and the callout. Chrome + hex lifted verbatim. */
.kiosk-alwayson[b-gcdp38x259] {
    display: flex;
    gap: 0.55rem;
    align-items: flex-start;
    margin-top: 0.4rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid #cfe0d4;
    background: #f2f9f4;
    border-radius: 8px;
}

.kiosk-alwayson-ico[b-gcdp38x259] {
    color: #1f7a44;
    font-weight: 700;
}

.kiosk-alwayson-body[b-gcdp38x259] {
    font-size: 0.82rem;
    color: #2f5a41;
    line-height: 1.4;
}

.kiosk-escape[b-gcdp38x259] {
    display: flex;
    gap: 0.55rem;
    align-items: flex-start;
    margin-top: 0.6rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid #d4c9a8;
    background: #fbf7ec;
    border-radius: 8px;
}

.kiosk-escape-ico[b-gcdp38x259] {
    color: #8a6d1f;
    font-weight: 700;
}

.kiosk-escape-body[b-gcdp38x259] {
    font-size: 0.82rem;
    color: #6b5a2e;
    line-height: 1.4;
}

.kiosk-escape-body strong[b-gcdp38x259] {
    color: #5a4a20;
}

.kiosk-no-pin-caution[b-gcdp38x259] {
    margin-top: 0.6rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid #f0c9a8;
    background: #fdf3e8;
    border-radius: 8px;
    font-size: 0.82rem;
    color: #8a5a1f;
    line-height: 1.4;
}
/* /Components/Shared/KnockoutBracket.razor.rz.scp.css */
/* Knockout bracket layout (slice 9, net-new per F3). Desktop = a column per round laid out
   left-to-right (a tree read left to right); mobile = the same columns stacked vertically
   (round-by-round) so the whole tree never needs panning. The container scrolls horizontally
   WITHIN ITSELF only (overflow-x: auto), never the whole page. MVP-correct + legible, not
   gold-plated (bracket aesthetics are backlog #217). */

.knockout-bracket[b-nula0rm3fs] {
    display: flex;
    flex-direction: row;
    gap: 1.5rem;
    overflow-x: auto;
    padding-bottom: 0.5rem;
    align-items: stretch;
}

.knockout-round[b-nula0rm3fs] {
    display: flex;
    flex-direction: column;
    min-width: 13rem;
    flex: 0 0 auto;
}

.knockout-round-name[b-nula0rm3fs] {
    font-size: 0.85rem;
    font-weight: 600;
    color: #5a6b80;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 0 0 0.75rem;
}

/* The round's matches spread to fill the column height so later rounds sit centred against
   their feeders (a legible tree without absolute positioning). */
.knockout-round-matches[b-nula0rm3fs] {
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    gap: 0.75rem;
    flex: 1 1 auto;
}

.knockout-match[b-nula0rm3fs] {
    border: 1px solid #d7deea;
    border-radius: 8px;
    background: #fff;
    overflow: hidden;
}

.knockout-match--complete[b-nula0rm3fs] {
    border-color: #b9d4c2;
}

.knockout-match--bye[b-nula0rm3fs] {
    opacity: 0.85;
}

/* A playable match is a full tap target (44px min via the slot padding) into Match Entry. */
.knockout-match-link[b-nula0rm3fs] {
    display: block;
    text-decoration: none;
    color: inherit;
    min-height: 44px;
}

.knockout-match-link:hover[b-nula0rm3fs],
.knockout-match-link:focus-visible[b-nula0rm3fs] {
    background: #f1f6ff;
    outline: none;
}

.knockout-match-link:focus-visible[b-nula0rm3fs] {
    box-shadow: inset 0 0 0 2px #0d2c55;
}

.knockout-match-static[b-nula0rm3fs] {
    display: block;
}

.knockout-match-slot[b-nula0rm3fs] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    min-height: 24px;
    color: #24384f;
    font-size: 0.95rem;
}

.knockout-match-slot--winner .knockout-match-pair[b-nula0rm3fs] {
    font-weight: 700;
    color: #0d2c55;
}

.knockout-match-slot--awaiting .knockout-match-pair[b-nula0rm3fs] {
    /* #5a6b80 on #fff = 4.99:1 (>=4.5:1 AA); was #7a8699 (~3.5:1, failed). Keep italic. */
    color: #5a6b80;
    font-style: italic;
}

.knockout-match-pair[b-nula0rm3fs] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.knockout-match-score[b-nula0rm3fs] {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: #0d2c55;
}

.knockout-match-vs[b-nula0rm3fs] {
    text-align: center;
    font-size: 0.7rem;
    color: #9aa7b8;
    border-top: 1px solid #eef2f7;
    border-bottom: 1px solid #eef2f7;
    line-height: 1.2;
}

.knockout-match-action[b-nula0rm3fs] {
    display: block;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: #0d2c55;
    background: #eaf1ff;
    text-align: center;
}

/* The "Correct this result" affordance on a Complete match (Q9.7) — a quieter, secondary tone
   than the primary "Enter score" so it reads as a correction, not the headline action. */
.knockout-match-link--correct .knockout-match-action[b-nula0rm3fs] {
    color: #4a5a70;
    background: #eef2f7;
    font-weight: 500;
}

/* Interactive signal on the muted "Correct this result" action (UX rework R1 polish 7): a
   chevron so it reads as a tap target while staying secondary. Decorative — the action text
   already labels the affordance, so the glyph is aria-hidden via content (not announced). */
.knockout-match-link--correct .knockout-match-action[b-nula0rm3fs]::after {
    content: " ›";
    font-weight: 600;
}

.knockout-match-note[b-nula0rm3fs] {
    display: block;
    padding: 0.25rem 0.75rem;
    font-size: 0.75rem;
    color: #7a8699;
    text-align: center;
}

/* LR-8a: head start shown INLINE in brackets after the weaker slot's name — "Team (+N)" —
   replacing the LR-2 under-row line. A short, nowrap suffix that does NOT participate in the
   pair-name ellipsis truncation (flex-shrink:0 keeps "(+N)" intact even when the long pair
   name truncates), and sits before the score in the slot row. #3a5072 on #fff = 7.4:1 (AA). */
.knockout-match-headstart-inline[b-nula0rm3fs] {
    flex-shrink: 0;
    color: #3a5072;
    font-weight: 600;
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Mobile (<= 700px): stack the rounds vertically (round-by-round). No horizontal scroll of
   the whole tree; each round is a full-width block read top to bottom. */
@media (max-width: 700px) {
    .knockout-bracket[b-nula0rm3fs] {
        flex-direction: column;
        overflow-x: visible;
        gap: 1.25rem;
    }

    .knockout-round[b-nula0rm3fs] {
        min-width: 0;
        width: 100%;
    }

    .knockout-round-matches[b-nula0rm3fs] {
        justify-content: flex-start;
    }

    /* MAJOR 2: the "v" separator collapsed at <=700 (the borders met, the glyph was squeezed
       to an unreadable sliver). Give it a legible height + size on mobile. */
    .knockout-match-vs[b-nula0rm3fs] {
        font-size: 0.8rem;
        padding: 0.15rem 0;
    }
}
/* /Components/Shared/LoggingErrorBoundary.razor.rz.scp.css */
.ui-error-panel[b-f44lfz8suk] {
    margin: 1.25rem auto;
    max-width: 32rem;
    border: 1px solid #e0b4b4;
    background: #fcf3f3;
    border-radius: 0.6rem;
    padding: 1rem 1.25rem;
    color: #6b2a2a;
    text-align: center;
}

.ui-error-title[b-f44lfz8suk] {
    margin: 0 0 0.4rem;
    font-size: 1.05rem;
    font-weight: 700;
}

.ui-error-text[b-f44lfz8suk] {
    margin: 0 0 0.9rem;
    font-size: 0.9rem;
    line-height: 1.4;
    color: #7a4a4a;
}
/* /Components/Shared/Matches/MatchList.razor.rz.scp.css */
/* SPEC-32 I2-S1a (#314): the match-row presentation's styles, relocated VERBATIM from
   SessionRecap.razor.css (the 744-1035 block) so both call sites share one shape (R-I2-14).

   RELOCATED, not ::deep-ed. These rules target elements MatchList emits; reaching them from each
   caller with ::deep would force every caller to restate them, which reinstates exactly the
   duplication R-I2-14 exists to remove.

   Values are unchanged from the shipped recap. Spec32MatchListGeometryTests pins the geometry and
   colour at 8 viewport x zoom combinations against a baseline captured BEFORE the extraction, because
   Blazor CSS isolation lets a relocated rule silently stop applying while every element is still
   present and every DOM assertion still passes.

   NOT here, deliberately:
     * .recap-games-name-mine — its spans are authored in the caller's markup (the NameContent slot),
       so the rule must stay in the caller's file to be scoped onto them.
     * .rating-delta-up / .rating-delta-down — SPLIT OWNERSHIP (one class pair, two emitters across
       this boundary). Promoted to the global app.css; see the note there.

   ── I2-S1b: THE PROFILE VARIANT, AND THE ONE RULE THAT GOVERNS IT ───────────────────────────────

   `white-space: nowrap` on the base cells below is the RECAP's fit assumption for 10-11 columns in a
   horizontally scrollable wrap. The profile record has five and must WRAP RATHER THAN WIDEN: a
   widening column in this very component previously pushed the Expected band pill off the right edge
   (see the [data-filtered='1'] block below, which exists only because of that incident).

   So the profile variant INVERTS THE DEFAULT — wrap, with named exemptions for the three columns that
   must stay tight — rather than listing the columns that should wrap. Default-safe: a column added
   later wraps instead of silently inheriting the recap's assumption.

   THE SPECIFICITY RULE, WHICH APPLIES TO BOTH HALVES AND IS NOT OPTIONAL:

       base            .match-list-table td                                    (0,1,1)
       profile default .match-list-table[data-variant='profile'] td            (0,2,1)  wins
       exemption       .match-list-table[data-variant='profile'] td.match-...  (0,3,1)  wins

   EVERY EXEMPTION MUST CARRY THE VARIANT SELECTOR. A bare `.match-list-col-date { white-space: nowrap }`
   is (0,1,0), loses to the (0,2,1) profile default, and is INERT — and it fails in the safe-LOOKING
   direction (the column merely wraps), so nothing appears broken and no DOM assertion can see it.
   That is not hypothetical: `.match-list-col-expected { white-space: normal }` further down has been
   inert since #234 by exactly this arithmetic. It is left alone here (fixing it changes the recap's
   shipped layout and would require re-capturing the geometry baseline) and is filed instead.

   The variant hook is an ATTRIBUTE on the table and the card list, following the shipped
   `data-filtered` precedent in this same file, so the two variant axes read the same way.

   `overflow-wrap: anywhere`, not `break-word`: only `anywhere` reduces a cell's MIN-CONTENT width, and
   min-content is what decides whether the table can lay out inside the wrap instead of overflowing it.

   Presence is not application, and the shipped geometry gate only ever navigates the RECAP url, so it
   is structurally blind to everything in this block. Spec32ProfileMatchesTests asserts the computed
   default AND an exemption on the profile page itself. */

.match-list-table-wrap[b-1k7le8nli6] {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid #e2e8f0;
    border-radius: 0.75rem;
    margin-top: 0.8rem;
    /* Pure-CSS (static-SSR, no JS) horizontal-scroll affordance. A soft shadow on the right edge
       signals "more columns this way" while the wide table has content still to reveal, and fades out
       once scrolled to the end (or when the table already fits). Classic local/scroll
       background-attachment technique: the white "cover" layers ride with the content (local) and mask
       the shadow at the true start/end; the shadow layers are pinned to the scroll viewport (scroll).
       REQUIRES the table cells to be transparent (the white now lives on this wrap via
       background-color) so the shadow isn't painted over — the two rules below are one mechanism and
       must never be separated. */
    background-color: #fff;
    background-image:
        linear-gradient(to right, #fff, rgba(255, 255, 255, 0)),
        linear-gradient(to left, #fff, rgba(255, 255, 255, 0)),
        radial-gradient(farthest-side at 0 50%, rgba(15, 42, 71, 0.22), rgba(15, 42, 71, 0)),
        radial-gradient(farthest-side at 100% 50%, rgba(15, 42, 71, 0.22), rgba(15, 42, 71, 0));
    background-position: 0 0, 100% 0, 0 0, 100% 0;
    background-size: 28px 100%, 28px 100%, 16px 100%, 16px 100%;
    background-repeat: no-repeat;
    background-attachment: local, local, scroll, scroll;
}

.match-list-table[b-1k7le8nli6] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
    /* Transparent (not #fff) so the wrap's scroll-shadow shows through the body rows; the white page
       colour is supplied by .match-list-table-wrap's background-color. */
    background: transparent;
}

/* The shipped rule was a comma group (`th, td`). Split into two, because the no-comma-group-crossing
   rule for this extraction: a group that mixes owners cannot be moved as a unit, and ::deep does not
   distribute across one. Same declarations, same cascade order, so the computed result is identical. */
.match-list-table th[b-1k7le8nli6] {
    padding: 0.5rem 0.65rem;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid #eef2f6;
}

.match-list-table td[b-1k7le8nli6] {
    padding: 0.5rem 0.65rem;
    text-align: left;
    white-space: nowrap;
    border-bottom: 1px solid #eef2f6;
}

.match-list-table thead th[b-1k7le8nli6] {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #5e748a;
    font-weight: 700;
    background: #f7fafc;
}

.match-list-table tbody tr:last-child td[b-1k7le8nli6] {
    border-bottom: none;
}

.match-list-col-game[b-1k7le8nli6] {
    color: #5e748a;
    font-variant-numeric: tabular-nums;
}

/* Also a split comma group in the shipped file (`-col-score, -col-rating`). */
.match-list-col-score[b-1k7le8nli6] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.match-list-col-rating[b-1k7le8nli6] {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.match-list-winner[b-1k7le8nli6] {
    font-weight: 700;
    color: #16324f;
}

.match-list-loser[b-1k7le8nli6] {
    color: #3d5468;
}

.match-list-score[b-1k7le8nli6] {
    font-weight: 600;
    color: #16324f;
}

.match-list-par[b-1k7le8nli6] {
    color: #5e748a;
}

/* The qualitative expectation-band column — muted like Par; allow wrapping so the longer labels
   ("Strong favourites" / "Big underdogs") don't force the wide table wider on tablet. */
.match-list-col-expected[b-1k7le8nli6] {
    color: #5e748a;
    white-space: normal;
}

/* When the wide table is FILTERED, the Par + Expected headers gain a "· {name}" subject suffix. Left
   on one nowrap line that suffix WIDENED those columns and pushed the Expected band pill — the whole
   payoff — off the right edge. The table lays out at max-content width inside an overflow-x:auto wrap,
   so a plain nowrap/normal header never wraps; it just extends the column. Fix: cap the header label
   in a width-limited INLINE-BLOCK so label + suffix wrap onto extra header LINES (taller header, not
   wider column). Applied to the two filtered subject headers only — the numeric Par/Score DATA cells
   keep their nowrap. The span is inline-level, so its soft wraps add NO newline to innerText. */
.match-list-table[data-filtered='1'] thead th.match-list-col-score .match-list-th-label[b-1k7le8nli6] {
    display: inline-block;
    max-width: 4.75rem;
    vertical-align: top;
    white-space: normal;
    overflow-wrap: anywhere;
}

.match-list-table[data-filtered='1'] thead th.match-list-col-expected .match-list-th-label[b-1k7le8nli6] {
    display: inline-block;
    max-width: 4.75rem;
    vertical-align: top;
    white-space: normal;
    overflow-wrap: anywhere;
}

.match-list-col-pick[b-1k7le8nli6] {
    text-align: center;
}

/* The Pick "M" (manual-override) marker — mirrors the app's .game-pick-indicator. */
.match-list-pick[b-1k7le8nli6] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.3rem;
    padding: 0.05rem 0.3rem;
    border-radius: 0.25rem;
    background: #eef2f6;
    color: #5e748a;
    font-size: 0.72rem;
    font-weight: 700;
}

/* AUTO-DIFFER: a STATIC "(edited)" marker — no interactive correction history. */
.match-list-edited[b-1k7le8nli6] {
    margin-left: 0.35rem;
    font-size: 0.72rem;
    color: #94a6b6;
    font-style: italic;
}

/* The filtered view's Rating column — the subject's per-game Elo movement. Colour (up/down) comes
   from the GLOBAL .rating-delta-up / .rating-delta-down pair (app.css) — split ownership, see the
   header note. */
.match-list-rating-delta[b-1k7le8nli6] {
    font-variant-numeric: tabular-nums;
    font-size: 0.85rem;
    font-weight: 600;
}

/* ── The <=720px card-per-game fallback. The recap is opened mostly on phones via shared links, where
   the 10/11-column wide table hard-clips with no scroll cue. The wide table hides and the card list
   takes over. This pair IS the reflow — it is the component's core behaviour, not a caller detail. ── */
.match-list-card-list[b-1k7le8nli6] {
    display: none;
}

@media (max-width: 720px) {
    .match-list-table-wide[b-1k7le8nli6] {
        display: none;
    }

    .match-list-card-list[b-1k7le8nli6] {
        display: flex;
        flex-direction: column;
        gap: 0.55rem;
        margin-top: 0.8rem;
    }
}

.match-list-card[b-1k7le8nli6] {
    background: #fff;
    border: 1px solid #d6dde6;
    border-radius: 0.55rem;
    padding: 0.6rem 0.7rem;
    box-shadow: 0 1px 2px rgba(15, 35, 60, 0.04);
}

.match-list-card-head[b-1k7le8nli6] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.4rem;
}

.match-list-card-id[b-1k7le8nli6] {
    font-size: 0.8rem;
    font-weight: 600;
    color: #5a6b80;
}

.match-list-card-headline[b-1k7le8nli6] {
    display: inline-flex;
    align-items: baseline;
    gap: 0.5rem;
    white-space: nowrap;
}

/* Score is the headline number — the first thing the eye lands on. */
.match-list-card-score[b-1k7le8nli6] {
    font-size: 1.2rem;
    font-weight: 800;
    color: #0d2c55;
    font-variant-numeric: tabular-nums;
}

.match-list-card-teams[b-1k7le8nli6] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.match-list-card-team[b-1k7le8nli6] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.45rem;
}

.match-list-card-team-label[b-1k7le8nli6] {
    flex: 0 0 auto;
    min-width: 3rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.match-list-card-winner .match-list-card-team-label[b-1k7le8nli6] {
    color: #1c7a33;
}

.match-list-card-loser .match-list-card-team-label[b-1k7le8nli6] {
    color: #7a8595;
}

.match-list-card-team-names[b-1k7le8nli6] {
    font-size: 0.95rem;
    font-weight: 600;
    color: #1d2733;
}

.match-list-card-winner .match-list-card-team-names[b-1k7le8nli6] {
    color: #14532d;
}

/* The band pill sits INLINE on the subject pair's team row, pushed right of their names — so the
   subject IS physically the pill's row (no restated name, no separate line). The team row wraps, so on
   a very narrow phone with long pair names the pill drops UNDER the names on the same row rather than
   forcing the card wider; the chip itself stays nowrap. Renders on exactly one row. */
.match-list-card-band[b-1k7le8nli6] {
    margin-left: auto;
    white-space: nowrap;
}

/* Duration / Court, led by Par (the pill is inline on the team row). Quiet small print; Par keeps
   tabular figures so the two-number score aligns. */
.match-list-card-meta[b-1k7le8nli6] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.35rem;
    font-size: 0.78rem;
    color: #5a6b80;
}

.match-list-card-meta-par[b-1k7le8nli6] {
    font-variant-numeric: tabular-nums;
}

/* ══ THE PROFILE VARIANT (SPEC-32 I2-S1b, #314) ═══════════════════════════════════════════════════
   Read the specificity rule in this file's header before touching anything below. Every exemption
   carries the [data-variant='profile'] selector; a bare class selector here is inert. */

/* The inverted default: five columns, so names WRAP instead of widening the column. */
.match-list-table[data-variant='profile'] th[b-1k7le8nli6] {
    white-space: normal;
    overflow-wrap: anywhere;
}

.match-list-table[data-variant='profile'] td[b-1k7le8nli6] {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* ── The three named exemptions. Each carries the variant selector (0,3,1) so it beats the (0,2,1)
   default above; written as a bare class it would be inert. ── */

/* A date must not break across lines ("12 Aug" / "2026" reads as two facts). */
.match-list-table[data-variant='profile'] td.match-list-col-date[b-1k7le8nli6],
.match-list-table[data-variant='profile'] th.match-list-col-date[b-1k7le8nli6] {
    white-space: nowrap;
}

/* Won / Lost is one word and is the row's primary fact. */
.match-list-table[data-variant='profile'] td.match-list-col-result[b-1k7le8nli6],
.match-list-table[data-variant='profile'] th.match-list-col-result[b-1k7le8nli6] {
    white-space: nowrap;
}

/* The score's en-dash IS a line-break opportunity, so without this "21-17" can split in half. */
.match-list-table[data-variant='profile'] td.match-list-col-score[b-1k7le8nli6],
.match-list-table[data-variant='profile'] th.match-list-col-score[b-1k7le8nli6] {
    white-space: nowrap;
}

/* ── THE BAND COLUMN (SPEC-32 I2-S14, #314) ──────────────────────────────────────────────────────
   Six columns where five fitted, in a 504px content column, and the longest label is "Strong
   favourites" (17 characters). ux-plan §8 ranks the allowed answers: let things WRAP and rows get
   taller. The forbidden answer is a horizontal scroll wrapper — that is the defect #614 records, and
   a horizontal scrollbar inside a vertically-scrolling column is invisible on touch until somebody
   happens to swipe sideways, which nobody does. Shortening the labels is equally forbidden: they are
   the ONE shared vocabulary (R-I2-28.3), and a profile-only abbreviation would make three surfaces
   and two vocabularies.

   So this column inherits the profile default (wrap + overflow-wrap: anywhere) and adds NO nowrap
   exemption — deliberately. It is the column that is allowed to go to two lines, because two of its
   five values are long and three are short.

   READ THE SPECIFICITY RULE IN THIS FILE'S HEADER. The shipped `.match-list-col-expected` block
   further up is (0,1,0) and is INERT against the (0,2,1) profile default — the same arithmetic that
   has kept its `white-space: normal` inert since #234. The rules below therefore carry the variant
   selector and set the colour again rather than relying on that block reaching this table. */
.match-list-table[data-variant='profile'] td.match-list-col-expected[b-1k7le8nli6],
.match-list-table[data-variant='profile'] th.match-list-col-expected[b-1k7le8nli6] {
    color: #5e748a;
}

/* The header carries a "· {name}" subject suffix ALWAYS on this variant (the recap shows it only when
   filtered). Left on one line the suffix WIDENS the column — the recap learned this at #234 — and on
   a six-column 504px table that is what pushes the chip towards the edge. Same fix, same numbers:
   cap the label in a width-limited inline-block so label + suffix wrap onto extra header LINES. A
   taller header is free here; a wider column is not.

   The span is INLINE-LEVEL, so its soft wraps add no newline to innerText — "Expected · you" stays
   one string to a text assertion. */
.match-list-table[data-variant='profile'] thead th.match-list-col-expected .match-list-th-label[b-1k7le8nli6] {
    display: inline-block;
    max-width: 4.75rem;
    vertical-align: top;
    white-space: normal;
    overflow-wrap: anywhere;
}

/* The chip on the ≤720px PROFILE card's score line.

   SCOPED TO THE PROFILE CARD LIST, AND THAT IS NOT DECORATION. `.match-list-card-band` already ships
   for the RECAP card, where it is `margin-left: auto` inside a flex team row — that auto margin is
   what pushes the pill to the right of the pair's names. A bare `.match-list-card-band` rule here
   would be (0,1,0) against (0,1,0), win on source order, and silently un-push the recap's pill. The
   variant selector makes this (0,3,0) and leaves the recap's rule exactly where it was.

   `white-space: nowrap` is INHERITED from that shipped rule and is wanted here too — the chip is one
   tag and must not break across lines; the LINE is what wraps on a narrow phone. */
.match-list-card-list[data-variant='profile'] .match-list-card-band[b-1k7le8nli6] {
    display: inline-flex;
    align-items: center;
    margin-left: 0.35rem;
}

/* The participant columns carry the long values; give them the width and let them wrap. */
.match-list-people[b-1k7le8nli6] {
    color: #1d2733;
}

.match-list-col-date[b-1k7le8nli6] {
    color: #5e748a;
    font-variant-numeric: tabular-nums;
}

.match-list-col-result[b-1k7le8nli6] {
    text-align: left;
}

/* Result is a WORD, never colour alone (R-I2-1 asks for "whether they won" explicitly). The colours
   below are a second cue on top of the word, not the cue itself. Both meet WCAG AA as body text on
   white: #1c7a33 = 5.41:1, #9b2c2c = 7.53:1 (recomputed in review - the conclusion held but the
   figures I first wrote did not; do not trust a contrast number that was not measured). Do not
   lighten either. */
.match-list-result[b-1k7le8nli6] {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.match-list-result-won[b-1k7le8nli6] {
    color: #1c7a33;
}

.match-list-result-lost[b-1k7le8nli6] {
    color: #9b2c2c;
}

/* ── The <=720px cards. The shell and head are the recap's; the two verb lines are their own
   elements rather than borrowed .match-list-card-team-* classes. Reusing a class whose name says
   "team-label" to render the word "with" is the same drift at CSS level that R-I2-14 forbids at
   markup level, and it would need the recap's uppercase/min-width/colour rules reset one by one. ── */
.match-list-card-list[data-variant='profile'] .match-list-card-head[b-1k7le8nli6] {
    align-items: baseline;
}

.match-list-card-date[b-1k7le8nli6] {
    font-size: 0.8rem;
    font-weight: 600;
    color: #5a6b80;
    font-variant-numeric: tabular-nums;
}

.match-list-card-lines[b-1k7le8nli6] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.match-list-card-line[b-1k7le8nli6] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* "with" / "beat" / "lost to" — lower case, as the copy specifies. A fixed column so the two lines'
   names align under one another.

   CONTRAST: #667286 on the card's white = 4.87:1, clearing WCAG AA. The value that went into review
   was #7a8595 = 3.74:1 and failed. These verbs are not decoration — they are what makes the row a
   sentence and what tells a reader which name is the partner and which are the opponents, so they
   carry meaning and must be legible. Do not lighten. */
.match-list-card-verb[b-1k7le8nli6] {
    flex: 0 0 auto;
    min-width: 3.4rem;
    font-size: 0.78rem;
    color: #667286;
}

.match-list-card-people[b-1k7le8nli6] {
    flex: 1 1 8rem;
    font-size: 0.95rem;
    font-weight: 600;
    color: #1d2733;
    overflow-wrap: anywhere;
}

/* Pushed to the right of the line it shares with the opponents, so the eye finds it in a column. */
.match-list-card-line .match-list-card-score[b-1k7le8nli6] {
    margin-left: auto;
    font-size: 1rem;
    white-space: nowrap;
}

/* ── The phone-tier row reveal (D1). Mechanism copied from the shipped
   MemberSessionHistoryTable: a visually-hidden but FOCUSABLE checkbox plus its <label for>, no
   script and no circuit. The whole control is phone-tier only — above 720px the card list is
   display:none and all ten rows are in the wide table, so there is nothing to reveal. ── */
.match-list-more-toggle[b-1k7le8nli6] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.match-list-more[b-1k7le8nli6] {
    display: none;
}

@media (max-width: 720px) {
    /* Collapsed = the overflow cards are hidden. Scoped to :not(:checked) so that opening the toggle
       simply stops the rule applying and the cards fall back to their natural display. */
    .match-list-more-toggle:not(:checked) ~ .match-list-card-list .match-list-card-overflow[b-1k7le8nli6] {
        display: none;
    }

    /* TOUCH TARGET: 44px floor, matching the shipped MemberSessionHistoryTable control this
       mechanism is copied from. Both were 31px. */
    .match-list-more[b-1k7le8nli6] {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        margin-top: 0.55rem;
        min-height: 44px;
        padding: 0.55rem 0.85rem;
        border: 1px solid #cbd7e4;
        border-radius: 0.5rem;
        background: #f4f8fc;
        color: #2f6fb0;
        font-size: 0.82rem;
        font-weight: 600;
        line-height: 1.2;
        cursor: pointer;
        user-select: none;
    }
}

.match-list-more:hover[b-1k7le8nli6] {
    background: #e9f1fb;
    border-color: #a9c3e0;
}

/* The focus ring lands on the label when its visually-hidden checkbox is focused — this is what keeps
   the control keyboard-reachable without script. */
.match-list-more-toggle:focus-visible ~ .match-list-more[b-1k7le8nli6] {
    outline: 2px solid #2f6fb0;
    outline-offset: 2px;
}

.match-list-more-hide[b-1k7le8nli6] {
    display: none;
}

.match-list-more-toggle:checked ~ .match-list-more .match-list-more-show[b-1k7le8nli6] {
    display: none;
}

.match-list-more-toggle:checked ~ .match-list-more .match-list-more-hide[b-1k7le8nli6] {
    display: inline;
}

.match-list-more-caret[b-1k7le8nli6] {
    font-size: 0.7rem;
    transition: transform 0.15s ease;
}

.match-list-more-toggle:checked ~ .match-list-more .match-list-more-caret[b-1k7le8nli6] {
    transform: rotate(180deg);
}
/* /Components/Shared/MemberAccountStatusHeader.razor.rz.scp.css */
/* profile-account-header: the account-status band at the top of the Members-admin
   Overview. A quiet full-width card with a "App access" caption so an infrequent
   volunteer reads it without recall. Reuses .badge / AppAccessCell role classes and
   .club-help-text (global) for the caption. min-width:0 discipline on the flex line
   keeps a long email wrapping inside the band — never a horizontal scroll. */

.member-account-status[b-3ycocqgiy4] {
    border: 1px solid #ccdae8;
    border-radius: 0.5rem;
    background: #ffffff;
    padding: 0.6rem 0.7rem;
    margin-bottom: 0.9rem;
}

.member-account-status-caption[b-3ycocqgiy4] {
    margin: 0 0 0.35rem;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.member-account-status-line[b-3ycocqgiy4] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem 0.6rem;
    min-width: 0;
}

/* The None line pushes the Invite CTA to the far end while the status text stays left. */
.member-account-status-none[b-3ycocqgiy4] {
    justify-content: space-between;
}

.member-account-status-email[b-3ycocqgiy4] {
    color: #24384f;
    font-size: 0.95rem;
    font-weight: 600;
    /* Long login email must wrap / break inside the band, never force horizontal
       scroll (the modal's grid-overflow history). */
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.member-account-status-email-missing[b-3ycocqgiy4] {
    color: #60778f;
    font-weight: 500;
    font-style: italic;
}

.member-account-status-noaccess[b-3ycocqgiy4] {
    color: #4a5f77;
    font-size: 0.9rem;
    font-weight: 600;
    min-width: 0;
}

.member-account-status-note[b-3ycocqgiy4] {
    margin: 0.35rem 0 0;
}

/* Kiosk/touch (WCAG 2.5.5) hit target for the header CTA — ≥ 44px tall, matching the
   modal's other small controls (see-all / popover-close). */
.member-account-status-invite-btn[b-3ycocqgiy4] {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    flex: 0 0 auto;
}
/* /Components/Shared/MemberActivityTimeline.razor.rz.scp.css */
/* #302 Slice 2: member activity timeline — a vertical card feed (newest-first)
   interleaving session and manual-adjustment rows. The session W/L squares and
   rating-journey colours mirror MemberSessionHistoryTable.razor.css but are
   redeclared here because Blazor scoped CSS doesn't cross components. The two row
   types are distinguished THREE ways (not colour alone): leading glyph shape
   (court vs pencil), chip colour (muted blue vs navy), and a "Manual adjustment"
   text badge. */

.member-activity-list[b-ksrdd3hhw8] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.member-activity-partial[b-ksrdd3hhw8] {
    color: #b02a2a;
    margin: 0 0 0.55rem;
    font-weight: 600;
}

.member-activity-row[b-ksrdd3hhw8] {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    border: 1px solid #ccdae8;
    border-radius: 0.5rem;
    background: #ffffff;
    padding: 0.5rem 0.65rem;
}

/* Leading glyph chip — a coloured rounded square carrying the type icon. */
.member-activity-chip[b-ksrdd3hhw8] {
    flex-shrink: 0;
    width: 1.85rem;
    height: 1.85rem;
    border-radius: 0.4rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    line-height: 1;
    color: #ffffff;
}

/* Session: muted blue chip with a frame/court glyph. */
.member-activity-chip-session[b-ksrdd3hhw8] {
    background: #3d6fa5;
}

/* Manual adjustment: navy chip with a pencil glyph — same navy "a human did this"
   language as the Slice-1 graph marker, so the two surfaces share one visual idea. */
.member-activity-chip-adjustment[b-ksrdd3hhw8] {
    background: #0d2c55;
}

.member-activity-body[b-ksrdd3hhw8] {
    flex: 1;
    min-width: 0;
}

.member-activity-line1[b-ksrdd3hhw8] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.member-activity-date[b-ksrdd3hhw8] {
    color: #24384f;
    font-weight: 700;
    font-size: 0.92rem;
}

.member-activity-sep[b-ksrdd3hhw8] {
    color: #8fa1b4;
}

.member-activity-session-name[b-ksrdd3hhw8] {
    color: #46607c;
    font-size: 0.9rem;
}

/* Navy badge (#0d2c55) — matches the adjustment chip and the Slice-1 graph
   marker, so the badge + chip speak the same "a human did this" language.
   bg-secondary grey read as "inactive/low-priority", wrong for an audit signal. */
.member-activity-badge[b-ksrdd3hhw8] {
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    background: #0d2c55;
    color: #ffffff;
}

.member-activity-line2[b-ksrdd3hhw8] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.3rem 0.7rem;
    margin-top: 0.3rem;
    font-size: 0.88rem;
    color: #24384f;
}

.member-activity-record[b-ksrdd3hhw8] {
    color: #46607c;
}

.member-activity-set[b-ksrdd3hhw8] {
    color: #24384f;
    font-weight: 600;
}

/* #302 Slice 3: the captured actor ("by NAME") on a post-capture adjustment row.
   Muted, secondary weight — the audit "who", not the headline. Absent (no markup)
   on pre-capture rows. */
.member-activity-actor[b-ksrdd3hhw8] {
    color: #46607c;
}

.member-activity-note[b-ksrdd3hhw8] {
    margin-top: 0.25rem;
    color: #46607c;
    font-style: italic;
    font-size: 0.88rem;
    word-break: break-word;
}

/* --- session W/L squares + rating journey (redeclared from the session-history
   table; scoped CSS doesn't cross components) --- */
.session-result-squares[b-ksrdd3hhw8] {
    display: inline-flex;
    gap: 0.2rem;
    flex-wrap: wrap;
}

.session-result-square[b-ksrdd3hhw8] {
    width: 1.2rem;
    height: 1.2rem;
    border-radius: 0.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.68rem;
    font-weight: 700;
    color: #fff;
}

.session-result-win[b-ksrdd3hhw8] {
    background: #248c3b;
}

.session-result-loss[b-ksrdd3hhw8] {
    background: #bd2f2f;
}

.member-activity-rating[b-ksrdd3hhw8] {
    white-space: nowrap;
}

.session-rating-arrow[b-ksrdd3hhw8] {
    color: #8fa1b4;
    padding: 0 0.2rem;
}

.session-rating-positive[b-ksrdd3hhw8] {
    color: #1c7a33;
    font-weight: 700;
}

.session-rating-negative[b-ksrdd3hhw8] {
    color: #b02a2a;
    font-weight: 700;
}
/* /Components/Shared/MemberAddModal.razor.rz.scp.css */
/* #437: Add member modal. Backdrop/shell conventions mirror MemberProfileModal
   (this component does not import that page's scoped CSS, so the tokens are
   declared here too so the two modal surfaces read as one family). */

.member-add-modal-backdrop[b-pzekhdww76] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2100;
}

.member-add-modal[b-pzekhdww76] {
    /* Narrower than the profile modal (820px not needed — this is a single-column
       form, no history tables). Subtract the backdrop's 1rem padding each side so
       it never overflows a phone. */
    width: min(640px, calc(100vw - 2rem));
    max-height: 90vh;
    overflow-y: auto;
    background: #f8fbff;
    border: 1px solid #b8c8d8;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 0.85rem;
    padding-bottom: 1rem;
}

.member-add-modal-header[b-pzekhdww76] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.member-add-modal-header h3[b-pzekhdww76] {
    margin: 0;
    color: #253f5b;
    font-size: 1.35rem;
    font-weight: 700;
}

/* #437 UX rework: the header Close button is a tap target like the footer
   buttons, so give it the same 2.75rem (44px) min-height. btn-sm alone left it
   ~31px — under the kiosk touch minimum. The profile modal's own close button is
   a separate ticket and untouched. */
.member-add-close[b-pzekhdww76] {
    min-height: 2.75rem;
}

.member-add-modal-body[b-pzekhdww76] {
    width: 100%;
    min-width: 0;
}

/* The embedded editor's own panel chrome is redundant inside the modal shell —
   drop its border/padding/margin so it reads as the modal body, not a card in a
   card. ::deep pierces the editor component's scoped CSS (the panel is its
   element). Mirrors MemberProfileModal's .member-profile-edit-body treatment. */
.member-add-modal-body[b-pzekhdww76]  .member-editor-panel {
    border: none;
    background: transparent;
    padding: 0;
    margin: 0;
}

/* #437 UX rework item 2: the required-field hint that sits directly above the
   action row when Save is disabled (e.g. "Required: name, gender."). Muted but
   legible; the red asterisks on the fields are the at-a-glance cue, this names
   the missing one. */
.member-add-validation-hint[b-pzekhdww76] {
    margin: 0.85rem 0 0;
    color: #6a7a8c;
    font-size: 0.85rem;
}

/* The shell's own three-button row (Cancel / Save and add another / Save and
   close). Wraps on narrow viewports; large touch targets for tablet/kiosk. */
.member-add-modal-actions[b-pzekhdww76] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.85rem;
}

/* When the validation hint is shown it already supplies the top gap, so collapse
   the actions row's own top margin to avoid a double gap. */
.member-add-validation-hint + .member-add-modal-actions[b-pzekhdww76] {
    margin-top: 0.4rem;
}

.member-add-modal-actions .btn[b-pzekhdww76] {
    /* Kiosk/tablet fat-finger target — comfortable height across the row. */
    min-height: 2.75rem;
}

/* Save and close is the primary action — push it to the trailing edge so the
   eye lands on it last (right-most in LTR). */
.member-add-save-close[b-pzekhdww76] {
    margin-left: auto;
}

/* On short kiosk/phone viewports the form can push the action row below the fold.
   The modal is the scroll container (overflow-y:auto), so pin the actions while
   the fields scroll behind. Mirrors the MemberEditor modal-actions sticky rule. */
@media (max-height: 700px) {
    .member-add-modal-actions[b-pzekhdww76] {
        position: sticky;
        bottom: 0;
        z-index: 1;
        background: #f8fbff;
        padding: 0.5rem 0;
        margin-top: 0.5rem;
        border-top: 1px solid #d8e0ea;
    }
}

@media (max-width: 560px) {
    /* Stack the actions full-width on a phone; primary stays last in source order
       so it's the bottom button. Clear the auto-margin that right-aligned it. */
    .member-add-save-close[b-pzekhdww76] {
        margin-left: 0;
    }

    .member-add-modal-actions .btn[b-pzekhdww76] {
        flex: 1 1 100%;
    }
}
/* /Components/Shared/MemberEditor.razor.rz.scp.css */
/* #407: shared full member editor. Styles lifted verbatim from
   Members.razor.css (member-editor-panel + the photo/rating/game-preference/
   help-popover/add-grid families) so the component is self-contained — its
   scoped CSS does not import the Members page's. */

.member-editor-panel[b-a8az8byic2] {
    border: 1px solid rgba(13, 44, 85, 0.12);
    border-radius: 0.4rem;
    background: #ffffff;
    padding: 0.75rem;
    margin: 0 0 0.85rem;
}

.member-editor-title[b-a8az8byic2] {
    margin: 0 0 0.6rem;
    color: #2c4560;
    font-size: 1.15rem;
    font-weight: 700;
}

/* #437 UX rework: required-field marker. Add mode only (the editor only renders
   the span when ShowRequiredMarkers, which is gated to Add) — the Edit profile
   editor stays asterisk-free. aria-hidden on the span; the modal's footer hint
   carries the accessible "Required: …" text. */
.member-editor-required[b-a8az8byic2] {
    color: #b3261e;
    margin-left: 0.15rem;
    font-weight: 700;
}

.club-add-actions[b-a8az8byic2] {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.member-add-grid[b-a8az8byic2] {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) minmax(10rem, 0.7fr) minmax(10rem, 0.7fr) minmax(10rem, 0.7fr) auto;
    gap: 0.55rem;
    align-items: end;
    margin: 0 0 0.85rem;
}

/* #407 review majors #2/#3: embedded as the modal EDIT body, the editor is
   SINGLE-COLUMN at every width (not the page's 5-col grid that crammed fields
   side-by-side at 1440px). The Save/Cancel actions live in their own block
   below the grid (member-editor-modal-actions), so they sit at the natural
   bottom of the stacked form rather than as a wide grid cell. */
.member-add-grid-modal[b-a8az8byic2] {
    grid-template-columns: 1fr;
    align-items: stretch;
}

.member-editor-modal-actions[b-a8az8byic2] {
    flex-wrap: wrap;
    margin: 0.75rem 0 0;
}

/* #407 review major #5 / #445 niggle 2: the in-modal Save/Cancel row is a sticky
   footer pinned to the bottom of the scrolling modal body, so it stays put while
   the fields scroll behind it. The scroll container is now
   .member-profile-modal-body (#445: the modal body became the sole scroll region,
   previously the whole .member-profile-modal scrolled). With the Member ID now
   rendered ABOVE this row (MemberEditor.razor) the actions are the LAST element in
   the body — so at the very bottom of scroll there is nothing below them to reveal
   and the buttons do not shift. Promoted from @media (max-height:700px) to ALL
   heights: on a tall viewport where the form doesn't scroll, position:sticky is
   inert (the row simply sits in normal flow), so this is safe. Confined to the
   modal context (.member-editor-panel-modal) so the on-page Add form is untouched. */
.member-editor-panel-modal .member-editor-modal-actions[b-a8az8byic2] {
    position: sticky;
    bottom: 0;
    z-index: 1;
    /* opaque so scrolled fields don't bleed through the pinned row */
    background: #f8fbff;
    padding: 0.5rem 0;
    margin-top: 0.5rem;
    border-top: 1px solid #d8e0ea;
}

.club-help-text[b-a8az8byic2] {
    margin: 0.75rem 0 0;
    color: #5f6f80;
}

.club-help-text code[b-a8az8byic2] {
    color: #c72576;
    background: transparent;
    padding: 0;
}

.form-label-with-help-text[b-a8az8byic2] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.form-label-help-button[b-a8az8byic2] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 999px;
    background: #e7eff8;
    color: #1f5a8a;
    border: 1px solid #b9c9db;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.form-label-help-button:hover[b-a8az8byic2] {
    background: #d6e4f3;
    border-color: #94afca;
}

.form-label-help-button:focus[b-a8az8byic2] {
    outline: 2px solid #1b6ec2;
    outline-offset: 1px;
}

.form-help-popover[b-a8az8byic2] {
    margin: 0.4rem 0 0.6rem;
    padding: 0.6rem 0.75rem;
    background: #f3f7fb;
    border: 1px solid #c4d2e0;
    border-radius: 0.5rem;
    font-size: 0.85rem;
    color: #2a4361;
    line-height: 1.4;
}

.form-help-popover-list[b-a8az8byic2] {
    margin: 0.25rem 0 0.5rem;
    padding-left: 1.2rem;
    list-style: disc;
}

.form-help-popover-list li[b-a8az8byic2] {
    margin-bottom: 0.15rem;
}

.form-help-popover-close[b-a8az8byic2] {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0.5rem;
    margin-top: 0.5rem;
    text-decoration: none;
    color: #1b6ec2;
    font-weight: 500;
}

.member-photo-field[b-a8az8byic2] {
    margin: 0 0 0.9rem;
}

.member-photo-editor[b-a8az8byic2] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.member-photo-editor-preview[b-a8az8byic2] {
    width: 4.8rem;
    height: 4.8rem;
    border-radius: 999px;
    border: 2px solid rgba(31, 43, 56, 0.2);
    object-fit: cover;
    background: #fff;
}

.member-photo-editor-fallback[b-a8az8byic2] {
    width: 4.8rem;
    height: 4.8rem;
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid rgba(38, 66, 97, 0.22);
    background: #ffffff;
    font-family: "Segoe UI", Tahoma, Arial, sans-serif;
    box-sizing: border-box;
}

.member-photo-editor-fallback.male[b-a8az8byic2] {
    border-color: #3d88c8;
    background: #eef6ff;
    color: var(--gender-male);
}

.member-photo-editor-fallback.female[b-a8az8byic2] {
    border-color: #cf75a4;
    background: #fff0f7;
    color: var(--gender-female);
}

.member-photo-editor-fallback.unspecified[b-a8az8byic2] {
    border-color: #8fa1b4;
    background: #f2f6fa;
    color: #5a6d80;
}

.member-photo-editor-controls[b-a8az8byic2] {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    min-width: 16rem;
}

.member-photo-initials[b-a8az8byic2] {
    display: block;
    color: currentColor;
    font-size: 0.82rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.member-photo-error[b-a8az8byic2] {
    color: #a11b2f;
    font-size: 0.85rem;
    font-weight: 600;
}

.member-rating-readonly[b-a8az8byic2] {
    border: 1px solid #c5d4e2;
    border-radius: 0.35rem;
    background: #f4f8fc;
    padding: 0.45rem 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.member-rating-value[b-a8az8byic2] {
    color: #213a54;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.1;
}

.member-rating-hint[b-a8az8byic2] {
    color: #5d748a;
    font-size: 0.78rem;
}

/* #407: recoverable save-failure / partial-save banner (role="alert"). */
.member-editor-save-error[b-a8az8byic2] {
    margin: 0.6rem 0 0;
    padding: 0.5rem 0.65rem;
    border: 1px solid #e2b3bc;
    border-radius: 0.4rem;
    background: #fdf2f4;
    color: #a11b2f;
    font-size: 0.88rem;
    font-weight: 600;
}

/* SPEC-31 S3: the Add-person "Plays" cell + the inline invite affordance. */
.member-plays-field[b-a8az8byic2] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.member-plays-check[b-a8az8byic2],
.member-invite-check[b-a8az8byic2] {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    color: #2a4361;
    font-weight: 500;
    cursor: pointer;
}

.member-plays-check .form-check-input[b-a8az8byic2],
.member-invite-check .form-check-input[b-a8az8byic2] {
    width: 1.1rem;
    height: 1.1rem;
    margin: 0;
    flex: 0 0 auto;
}

/* The "why we ask" line beneath the email — quiet, not a warning. */
.member-invite-why[b-a8az8byic2] {
    font-size: 0.82rem;
}

/* The invite callout is a full-width block below the grid, gently set off so the
   "give them app access" step reads as an optional add-on, not a required field. */
.member-invite-block[b-a8az8byic2] {
    margin: 0.25rem 0 0.85rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid #c8dcef;
    border-radius: 0.45rem;
    background: #f2f8ff;
}

.member-invite-role[b-a8az8byic2] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-top: 0.5rem;
    max-width: 16rem;
}

@media (max-width: 1100px) {
    .member-add-grid[b-a8az8byic2] {
        grid-template-columns: 1fr 1fr;
    }

    .member-photo-editor[b-a8az8byic2] {
        flex-direction: column;
        align-items: flex-start;
    }

    .member-photo-editor-controls[b-a8az8byic2] {
        min-width: 0;
        width: 100%;
    }
}

@media (max-width: 700px) {
    .member-add-grid[b-a8az8byic2] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Shared/MemberProfileModal.razor.rz.scp.css */
.member-profile-modal-backdrop[b-vmu2rhjtmw] {
    position: fixed;
    inset: 0;
    background: rgba(18, 30, 44, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    z-index: 2100;
}

.member-profile-modal[b-vmu2rhjtmw] {
    /* The backdrop pads 1rem each side — 94vw overflowed it on phones
       (e.g. 412px Moto: 94vw = 387px > 380px available), forcing a small
       horizontal scroll. Subtract the padding instead. Desktop cap raised
       820px → 1080px so the session-history table fits real-world data
       (long session names, 4-digit rating journeys) without scrolling;
       phones are unaffected — the calc() term governs below ~1112px. */
    width: min(1080px, calc(100vw - 2rem));
    max-height: 90vh;
    /* #445 niggles: the modal is now a flex COLUMN — a pinned header (flex:0 0 auto)
       above a single scrolling body (flex:1 1 auto). Previously the whole modal was
       overflow-y:auto, so scrolling carried the header (and its Close button) off the
       top. The scroll now lives on .member-profile-modal-body alone. */
    display: flex;
    flex-direction: column;
    background: #f8fbff;
    border: 1px solid #b8c8d8;
    border-radius: 0.75rem;
    box-shadow: 0 16px 36px rgba(21, 43, 68, 0.3);
    padding: 0.85rem;
    /* #419 UX: on 1440px the content (Member ID row) crowded the modal floor.
       A touch more clearance at the bottom so content doesn't touch the edge. */
    padding-bottom: 1rem;
}

.member-profile-modal-header[b-vmu2rhjtmw] {
    /* #445: stays pinned at the top while the body scrolls. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.member-profile-modal-header-actions[b-vmu2rhjtmw] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* #445: the close affordance is now an X icon pinned in the header's top-right
   (the Bootstrap btn-close glyph, as used on PaymentsTab / ClubSessionDashboard /
   SystemUsers). Grow its hit area to a 44px kiosk/touch target (WCAG 2.5.5) while
   keeping the small glyph centred. flex:0 0 auto so it never shrinks beside the
   "Edit details" button in view mode. */
.member-profile-modal-close[b-vmu2rhjtmw] {
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-position: center;
}

.member-profile-modal-header h3[b-vmu2rhjtmw] {
    margin: 0;
    color: #253f5b;
    font-size: 1.35rem;
    font-weight: 700;
}

.member-profile-modal-body[b-vmu2rhjtmw] {
    /* #445: the ONLY scroll region now (the modal itself no longer scrolls, so the
       header stays pinned above this). flex:1 1 auto takes the remaining height;
       min-height:0 is REQUIRED — a flex item defaults to min-height:auto, which
       refuses to shrink below its content and would push the whole modal past the
       viewport instead of scrolling here. */
    flex: 1 1 auto;
    min-height: 0;
    /* Bl165 (SPEC-32 S2): the body is a flex ITEM of the column-flex modal (align-items:stretch), so
       without min-width:0 a wide child (the stacked profile's history/players table) pushes the body's
       min-content past the fixed-width modal (width: min(1080px, calc(100vw - 2rem))) and spills to the
       page at narrow widths. min-width:0 lets the body shrink to the modal width so its table wrappers
       scroll INTERNALLY (overflow-x:auto) instead. Belt to the `> *` min-width:0 braces below. */
    min-width: 0;
    overflow-y: auto;
    display: grid;
    grid-template-columns: 11rem 1fr;
    gap: 0.9rem;
    align-items: start;
}

/* Grid items default to min-width:auto (= their max-content), so any wide
   child — e.g. the tab row on phones — silently forces the whole column
   (and every sibling, like the sessions table) wider than the modal,
   producing a horizontal scroll (Moto G75 report). Let children shrink. */
.member-profile-modal-body > *[b-vmu2rhjtmw] {
    min-width: 0;
}

/* SPEC-32 S2 (#186): the ADMIN (accountMode) body renders the shared ProfileRenderer as a single
   stacked column, not the in-session 2-column (photo | content) grid. A COMPOUND selector (0,2,0)
   declared AFTER the base `.member-profile-modal-body { display:grid }` so display:block actually WINS
   the cascade — the base rule has equal single-class specificity and is declared later, so a bare
   `--stacked` rule would lose and the body would stay a grid (then the max-width:1100px
   justify-items:center below sizes the single item to its max-content width and overflows on phones —
   the Bl165 360px bug). grid-template-columns:none neutralises the inherited grid template so the
   section children default to full block width and their `.table-responsive` (overflow-x:auto) scrolls
   internally. The in-session (non-stacked) grid body is untouched. */
.member-profile-modal-body.member-profile-modal-body--stacked[b-vmu2rhjtmw] {
    display: block;
    grid-template-columns: none;
}

.member-profile-photo[b-vmu2rhjtmw] {
    width: 11rem;
    height: 11rem;
    border-radius: 0.85rem;
    border: 2px solid rgba(37, 63, 91, 0.2);
    object-fit: cover;
    background: #fff;
}

.member-profile-photo-fallback[b-vmu2rhjtmw] {
    width: 11rem;
    height: 11rem;
    border-radius: 0.85rem;
    border: 2px solid rgba(37, 63, 91, 0.2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: #f2f6fa;
    color: #4e657d;
}

/* SPEC-32 I4-S1 (#670), R-I2-44.1: the initials read the shared FILL tokens, whose own declaration in
   app.css already names "name/initials colours" as their job. Values unchanged to the byte — these
   two literals WERE --gender-male and --gender-female, written out again. This is the fill pair and
   not the name-ink pair, correctly: white-on-tint initials, not a name in a row of numbers. */
.member-profile-photo-fallback.male[b-vmu2rhjtmw] {
    border-color: #3d88c8;
    background: #eef6ff;
    color: var(--gender-male);
}

.member-profile-photo-fallback.female[b-vmu2rhjtmw] {
    border-color: #cf75a4;
    background: #fff0f7;
    color: var(--gender-female);
}

.member-profile-photo-fallback.unspecified[b-vmu2rhjtmw] {
    border-color: #8fa1b4;
    background: #f2f6fa;
    color: #5a6d80;
}

.member-profile-photo-initials[b-vmu2rhjtmw] {
    font-size: 2.35rem;
    font-weight: 800;
    line-height: 1;
    text-transform: uppercase;
}

.member-profile-fields[b-vmu2rhjtmw] {
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem 0.8rem;
    grid-column: 1 / -1;
}

.member-profile-fields > div[b-vmu2rhjtmw] {
    border: 1px solid #ccdae8;
    border-radius: 0.45rem;
    background: #ffffff;
    padding: 0.45rem 0.55rem;
}

.member-profile-id-field[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
}

.member-profile-id-field .member-profile-id[b-vmu2rhjtmw] {
    display: block;
    /* Wrap the long GUID across lines rather than forcing a one-line
       horizontal scrollbar (#407 follow-up — the id field read as a tiny
       scrolling box). */
    white-space: normal;
    overflow-wrap: anywhere;
    word-break: break-all;
}

.member-profile-fields dt[b-vmu2rhjtmw] {
    margin: 0;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.member-profile-fields dd[b-vmu2rhjtmw] {
    margin: 0.2rem 0 0;
    color: #24384f;
    font-size: 0.95rem;
    font-weight: 600;
    word-break: break-word;
}

.member-profile-id[b-vmu2rhjtmw] {
    font-family: Consolas, "Courier New", monospace;
    font-size: 0.8rem;
}

/* #407 follow-up: the a11y tabpanel wrapper (role="tabpanel", added for the
   tab/panel ARIA wiring) is a direct child of the two-column body grid. Without
   an explicit span it auto-placed into the narrow 11rem photo column, cramming
   the whole Details/Activity/Rating panel — and the Member ID — into ~176px.
   Span both columns so the tab content gets the full content width, as it did
   before the content was wrapped. */
.member-profile-tabpanel[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    width: 100%;
    min-width: 0;
    /* Stable height across tabs: a short tab (Details) vs a taller one (Rating
       chart / Sessions table) otherwise resizes the whole modal — and because
       the backdrop centres it, the box visibly jumps on each tab switch. Floor
       the panel so the common tabs hold one size; taller content still scrolls
       within the modal's max-height:90vh. */
    min-height: 24rem;
}

.member-profile-tabs[b-vmu2rhjtmw] {
    display: flex;
    /* The tab row can exceed a phone's width — wrap onto a second line rather than
       forcing the modal wider than the screen. (tab-ia: down to five tabs, but the
       wrap guard is cheap to keep.) */
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid #d8e0ea;
    grid-column: 1 / -1;
}

.member-profile-tab[b-vmu2rhjtmw] {
    background: transparent;
    border: none;
    padding: 0.5rem 0.9rem;
    font-size: 0.9rem;
    font-weight: 600;
    color: #60778f;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 120ms ease, border-color 120ms ease;
}

.member-profile-tab:hover[b-vmu2rhjtmw] {
    color: #24384f;
}

.member-profile-tab.active[b-vmu2rhjtmw] {
    color: #0d6efd;
    border-bottom-color: #0d6efd;
}

.member-profile-sessions[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    max-height: 22rem;
    overflow-y: auto;
}

/* #96 / SPEC-32 fix: the .members-table rules MOVED OUT of this scoped stylesheet to
   the GLOBAL wwwroot/css/profile.css. Reason: SPEC-32 S2 relocated the table into the
   child ProfilePlayersSection, which never carries this component's CSS-isolation scope
   attribute, so scoped .members-table rules stopped applying on every lens (columns
   collapsed to zero padding). In profile.css they are anchored under `.profile-section-players`
   (NOT bare .members-table) so they reach ONLY the Partners/Opponents tables and never leak to
   the shared MemberSessionHistoryTable, which also carries the .members-table class. See the
   "players tables" block in profile.css. */

.member-profile-rating[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
}

/* #304: rating-number header on the Rating tab - the anchor the Settling chip
   reads against. Number is the hero; chip is a quiet neutral signal beside it. */
.member-rating-header[b-vmu2rhjtmw] {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}

.member-rating-header-value[b-vmu2rhjtmw] {
    color: #213a54;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

/* #304: neutral "Settling" chip. Composed from the existing neutral box tokens
   (member-rating-readonly family) - deliberately NOT the coloured badge bg-*
   family, whose status-colour semantics would read as an alarm. The whole chip
   is a button (it becomes the tap target for S2's explainer popover). */
.member-settling-chip[b-vmu2rhjtmw] {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    min-height: 1.9rem;
    padding: 0.25rem 0.6rem;
    /* WCAG 1.4.11: border must clear 3:1 against its own #f4f8fc fill for the
       chip boundary to be perceivable. #8fa3b8 (the UX note's suggestion) only
       reaches ~2.5:1; #7d90a6 clears it (3.07:1 vs the chip fill, 3.16:1 vs the
       modal bg) while staying a calm neutral grey-blue - no warning semantics. */
    border: 1px solid #7d90a6;
    border-radius: 999px;
    background: #f4f8fc;
    color: #213a54;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.1;
    /* It IS a button and becomes interactive in S2 (tap-to-explain popover);
       pointer avoids a desktop "looks broken" read and an S2 CSS churn. */
    cursor: pointer;
}

/* The chip is a bare <button> (no .btn class), so Bootstrap reboot suppresses
   the default focus outline and the app's .btn focus ring never applies -
   keyboard users got no focus signal. Restore a visible ring, matching the
   .form-label-help-button:focus style on the Members page. */
.member-settling-chip:focus-visible[b-vmu2rhjtmw] {
    outline: 2px solid #1b6ec2;
    outline-offset: 2px;
}

/* ::deep is needed because the glyph comes from a code-behind RenderFragment
   (SettlingChip.Glyph), which Blazor's scoped-CSS rewriter never tags with the
   component's [b-xxxx] attribute - so the icon class can only be reached by
   piercing the scope from the chip element (which IS tagged). */
.member-settling-chip[b-vmu2rhjtmw]  .member-settling-chip-icon {
    width: 0.95rem;
    height: 0.95rem;
    flex: 0 0 auto;
}

.member-settling-chip-label[b-vmu2rhjtmw] {
    white-space: nowrap;
}

/* #304 S2: tap-to-explain popover. Reuses the form-help-popover look from the
   Members add-form (same tokens) - this component does not import that page's
   scoped CSS, so the rules are declared here too so the twin surfaces match. */
.form-help-popover[b-vmu2rhjtmw] {
    margin: 0.4rem 0 0.6rem;
    padding: 0.6rem 0.75rem;
    background: #f3f7fb;
    border: 1px solid #c4d2e0;
    border-radius: 0.5rem;
    font-size: 0.85rem;
    color: #2a4361;
    line-height: 1.4;
}

.form-help-popover-close[b-vmu2rhjtmw] {
    /* Kiosk fat-finger target: grow the hit area to ~44px tall (min-height
       2.75rem + vertical padding) while keeping the tidy text-link look.
       inline-flex so the "Got it" text stays vertically centred in the taller
       box. Horizontal padding gives a comfortable side hit area without making
       it read as a button. */
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0.5rem;
    margin-top: 0.5rem;
    text-decoration: none;
    color: #1b6ec2;
    font-weight: 500;
}

/* The explainer popover is a calm paragraph + dismiss; cap its width so it reads
   as a tooltip beside the number rather than spanning the whole tab. */
.member-settling-popover[b-vmu2rhjtmw] {
    max-width: 32rem;
}

.member-profile-rating-chart[b-vmu2rhjtmw] {
    position: relative;
    width: 100%;
    height: 18rem;
    padding: 0.5rem 0;
}

.member-profile-rating-chart canvas[b-vmu2rhjtmw] {
    width: 100% !important;
    height: 100% !important;
}

@media (max-width: 1100px) {
    /* In-session 2-column grid body ONLY — the SPEC-32 admin --stacked variant is display:block, so
       these grid rules must not apply to it (justify-items:center would size its single child to
       max-content and overflow on phones — the Bl165 360px bug). */
    .member-profile-modal-body:not(.member-profile-modal-body--stacked)[b-vmu2rhjtmw] {
        grid-template-columns: 1fr;
        justify-items: center;
    }

    .member-profile-photo[b-vmu2rhjtmw],
    .member-profile-photo-fallback[b-vmu2rhjtmw] {
        width: 9rem;
        height: 9rem;
    }

    .member-profile-fields[b-vmu2rhjtmw] {
        grid-template-columns: 1fr;
        width: 100%;
        justify-self: stretch;
    }

    .member-profile-tabs[b-vmu2rhjtmw],
    .member-profile-sessions[b-vmu2rhjtmw],
    .member-profile-rating[b-vmu2rhjtmw] {
        width: 100%;
        justify-self: stretch;
    }
}

/* #419: Overview tab. Leads with the rating (hero) + glanceable status, then a
   recent-activity snapshot, then the demoted secondary/PII fields. Spans both
   columns of the body grid like the other tab panels. */
.member-profile-overview[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    width: 100%;
    min-width: 0;
}

/* The rating is the hero of the Overview. Quiet "Rating" caption above the big
   number (reuses .member-rating-header / .member-rating-header-value from the
   Rating tab so the two surfaces stay visually identical). */
.member-overview-rating[b-vmu2rhjtmw] {
    margin-bottom: 0.85rem;
}

.member-overview-rating-label[b-vmu2rhjtmw] {
    display: block;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 0.15rem;
}

/* The Overview rating header has no bottom margin of its own — the label + the
   wrapper spacing handle it — so collapse the Rating-tab default here. */
.member-overview-rating .member-rating-header[b-vmu2rhjtmw] {
    margin-bottom: 0;
}

/* #419 UX: on the OVERVIEW the rating is the page hero — it must out-weigh the
   1.5rem body field cards below it so the eye lands on it first. Grow only the
   Overview-scoped number; the Rating *tab*'s own header keeps its 1.5rem size
   (it isn't competing with a field grid there). */
.member-overview-rating .member-rating-header-value[b-vmu2rhjtmw] {
    font-size: 2.3rem;
    line-height: 1.1;
}

/* profile-account-header: on the Members-admin surface the job is administrative, so
   the rating is DEMOTED from the #419 hero back to a compact line (label + value +
   Settling chip) below the Manage block — it stops competing for the eye. The
   in-session Overview keeps the 2.3rem hero above. */
.member-overview-rating--compact .member-rating-header-value[b-vmu2rhjtmw] {
    font-size: 1.5rem;
}

/* profile-account-header: section caption (e.g. "Identity & contact") in the reordered
   account-mode Overview, matching the quiet uppercase caption used by the rating label /
   account-status band so the infrequent user reads each section without recall. */
.member-section-caption[b-vmu2rhjtmw] {
    margin: 0 0 0.4rem;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Contact (Email / Phone) grid sits directly under the identity grid in account mode —
   a small gap so the two field groups don't butt together. */
.member-profile-contact-fields[b-vmu2rhjtmw] {
    margin-top: 0.5rem;
}

/* Recent-activity snapshot block. The timeline component brings its own list
   styling; this just spaces the heading + "See all" affordance. */
.member-overview-recent[b-vmu2rhjtmw] {
    margin-top: 0.9rem;
}

.member-overview-recent-head[b-vmu2rhjtmw] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.35rem;
}

.member-overview-recent-title[b-vmu2rhjtmw] {
    margin: 0;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.member-overview-see-all[b-vmu2rhjtmw] {
    /* Kiosk/touch (and WCAG 2.5.5) hit target: the bare link was a ~45×22px
       sliver. Grow the hit area to ~44px tall (min-height 2.75rem + padding),
       matching the popover-close treatment, while keeping the visual link look. */
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.85rem;
    font-weight: 600;
}

/* Demoted secondary/PII fields (Email / Phone / Member ID / login / role). A
   light top divider separates them from the value content above. */
.member-profile-secondary-fields[b-vmu2rhjtmw] {
    margin-top: 0.9rem;
    padding-top: 0.8rem;
    border-top: 1px solid #d8e0ea;
}

/* tab-ia: the History [Timeline|Table] and Players [Partners|Opponents] segmented
   toggles. Reuses the Bootstrap btn-group idiom; a small margin lifts the view
   content below it. Each segment is floored to a 44px touch target (WCAG 2.5.5) so
   it's usable on a shared tablet, and the active segment reads as pressed (the
   Bootstrap .active fill on btn-outline-primary). */
.member-profile-view-toggle[b-vmu2rhjtmw] {
    margin-bottom: 0.75rem;
}

.member-profile-view-toggle .btn[b-vmu2rhjtmw] {
    min-height: 2.75rem;
    font-weight: 600;
}

/* tab-ia: the admin Overview's compact current-state line — replaces the old
   scrollable recent-activity block. Rating (compact) + active cue sit on one row;
   the "Last played" fact + View-history link sit beneath. A light top divider
   separates it from the Manage block above. */
.member-overview-currentstate[b-vmu2rhjtmw] {
    margin-top: 0.9rem;
    padding-top: 0.8rem;
    border-top: 1px solid #d8e0ea;
}

.member-overview-currentstate-head[b-vmu2rhjtmw] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem 0.9rem;
}

/* The rating block inside the compact line carries its own bottom margin on the
   Overview; collapse it so the active cue sits level with the number. */
.member-overview-currentstate-head .member-overview-rating[b-vmu2rhjtmw] {
    margin-bottom: 0;
}

.member-overview-active-cue[b-vmu2rhjtmw] {
    align-self: center;
}

.member-overview-lastplayed[b-vmu2rhjtmw] {
    margin: 0.5rem 0 0;
    color: #24384f;
    font-size: 0.92rem;
}

.member-overview-lastplayed-label[b-vmu2rhjtmw] {
    color: #60778f;
    font-weight: 700;
    text-transform: uppercase;
    font-size: 0.76rem;
    letter-spacing: 0.03em;
    margin-right: 0.35rem;
}

.member-overview-lastplayed-value[b-vmu2rhjtmw] {
    font-weight: 600;
}

/* The "View history →" affordance is a real button with an accessible name; grow the
   hit area to ~44px tall like the other in-modal links, keeping the text-link look. */
.member-overview-view-history[b-vmu2rhjtmw] {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.85rem;
    font-weight: 600;
}

/* tab-ia: read-only Details tab reference panel. Spans both columns of the body
   grid like the other tab panels. */
.member-profile-details[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    width: 100%;
    min-width: 0;
}

/* Muted "Not recorded" placeholder for a blank Email / Phone on the Details tab. */
.member-profile-muted[b-vmu2rhjtmw] {
    color: #8296aa;
    font-weight: 500;
}

/* #407: full-modal EDIT mode — the shared MemberEditor replaces the profile body
   inside the same shell. The body grid is two-column; the editor spans it. */
.member-profile-edit-body[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    width: 100%;
}

/* The embedded editor's own panel chrome is redundant inside the modal shell —
   drop its border/padding/margin so it reads as the modal body, not a card in a
   card. ::deep pierces the editor component's scope (the panel is its element). */
.member-profile-edit-body[b-vmu2rhjtmw]  .member-editor-panel {
    border: none;
    background: transparent;
    padding: 0;
    margin: 0;
}

/* #407: read-only informational hint (Details tab, CanEdit false). Never a dead
   button — just tells the operator how to get edit access. */
.member-profile-readonly-hint[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    margin-top: 0.6rem;
    font-style: italic;
}

/* #407: partial-save notice — the member edit landed but a later step (rating /
   game preference) didn't. Honest "saved, but..." amber, not a clean success. */
.member-profile-partial-notice[b-vmu2rhjtmw] {
    grid-column: 1 / -1;
    margin-top: 0.6rem;
    padding: 0.5rem 0.65rem;
    border: 1px solid #e3c98a;
    border-radius: 0.4rem;
    background: #fdf7e7;
    color: #7a5b12;
    font-size: 0.88rem;
    font-weight: 600;
}

/* SPEC-31 #136 UAT rework: the host-supplied per-member management block (Members admin
   page only). Sits at the foot of the Overview view as a distinct section, separated from
   the identity/stat content above it. In-session hosts pass no ManagementContent, so this
   container is never emitted on the kiosk profile. */
.member-profile-management[b-vmu2rhjtmw] {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid #e2e8f0;
}
/* /Components/Shared/MemberSessionHistoryTable.razor.rz.scp.css */
/* #165: session-history table styling. The result squares mirror the session
   dashboard's attendee-stats squares (AttendeeStatsTab.razor.css) but live
   here because Blazor scoped CSS doesn't cross components. Columns are merged
   (record, rating journey, attendance window) so the table fits the ~820px
   profile panel without horizontal scroll; below 640px the rows restyle into
   stacked cards via the td data-label attributes. */
/* Belt-and-braces: if the table still exceeds its container (very long
   session names on a narrow desktop window), keep a visible horizontal
   scrollbar at the wrapper rather than silently clipping. */
.table-responsive[b-eoj9d6z7zz] {
    overflow-x: auto;
}

.member-session-history-table[b-eoj9d6z7zz] {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.88rem;
}

/* SPEC-32 S6 (#190): above the stacked-card reflow breakpoint (viewport > 820px) the table renders as
   a full 8-column table whose min-content is ~820px. In a container NARROWER than that — the portal
   /me's 34rem (~544px) card shell at a desktop viewport — `width:100%` under table-layout:auto compresses
   the columns and the last (Rating) column's nowrap content is clipped by the section card's
   overflow:hidden. Let the table take its natural width so the .table-responsive wrapper scrolls
   horizontally instead. No-op in the wide admin modal / kiosk panel (there `width:100%` already exceeds
   max-content, so the table is unchanged and never scrolls); below 820px the table reflows to stacked
   cards (its own media query below), so this is scoped above that breakpoint to not fight it. */
@media (min-width: 821px) {
    .member-session-history-table[b-eoj9d6z7zz] {
        min-width: max-content;
    }

    /* SPEC-32 I2-S12 (#314), AC-I2-S12-12 — #614's surviving desktop half, and the OTHER half of it.
       Dropping `At Club` / `Court Time` / `Wait Time` is only the first half; this is the second, and
       without it the fix does not land.

       THE RULE ABOVE IS #614's MECHANISM. It was added at S6 for a real reason — with eight columns
       the table's min-content was ~820px, and inside the portal's 504px card `width: 100%` compressed
       the columns until the Rating cell's nowrap content was CLIPPED by the section card's
       overflow:hidden. Letting the table take its natural width traded a clip for a scrollbar, which
       was the better of two bad answers at eight columns.

       AT FIVE COLUMNS THERE IS A GOOD ANSWER, and it is the one §8 names: fewer columns, never a
       wrapper. So the fit shape takes `width: 100%` back and lets the cells wrap. Rows get taller,
       which the page has room for; nothing is clipped, because there is no longer more content than
       container. A horizontal scrollbar is invisible on touch until somebody happens to swipe
       sideways on a page that scrolls vertically, which is exactly why #614 went unnoticed.

       SCOPED TO THE FIT SHAPE, so the admin member modal and the kiosk — which still render all
       eight columns in a much wider panel — keep the rule that was written for them.

       ── THE JUSTIFICATION ABOVE IS SUPERSEDED, THE DECLARATION IS NOT. SPEC-32 I3-S0 (#677), R-I2-40.
       READ THIS BEFORE RESTORING A COLUMN (I3-S3 is the next one).

       "AT FIVE COLUMNS THERE IS A GOOD ANSWER" is a claim about a COLUMN COUNT, and I3-S1/I3-S3 change
       it. The claim it rested on — that width is scarce here — was never true of the columns; it was
       true of the container. The portal shell caps above 821px (see MyPerformance.razor.css /
       ClubmateProfile.razor.css, which carry the sweep), so this table gets hundreds of pixels of
       wrapper where it had 478px. `min-width: 0` and the retired `min-width: max-content` now produce
       the SAME rendering — no clip, no scrollbar — because there is no longer more content than
       container.

       I3-S1 (#669) IS THE PROOF, AND IT WENT EXACTLY AS THE THREE CLAUSES BELOW SAID IT WOULD. `At Club`
       came back as a sixth column, this table's max-content went 679.27px -> 770.73px (+91.46px,
       qa-perf-club-mk, 1920px, 2026-09-02), the shell's cap went 49rem -> 53rem in the same edit, and
       NOTHING in this rule changed. The min-content went to 545.69px, which is 611.69px of shell —
       still far inside the 820px reflow, so clause 3's second half did not fire either.

       SO THE FIT SHAPE DOES NOT CHANGE WHEN A COLUMN COMES BACK, AND THE SLICE THAT RESTORES ONE MUST
       NOT RE-DERIVE IT. Three things hold together and the third is the one that moves:

         1. `min-width: 0` STAYS. Reintroducing `min-width: max-content` on the fit shape is what trades
            a clip for a horizontal scrollbar, and a horizontal scrollbar is invisible on touch until
            somebody swipes sideways — which is exactly how #614 went unnoticed. The wrapper's
            `overflow-x: auto` is the belt-and-braces last resort, never the plan (R-I2-37.4).
         2. `width: 100%` plus the two wrap exemptions below STAY. They are what lets the table shrink
            gracefully between 821px and the cap, where the viewport is narrower than the table's
            max-content: Date and Session wrap, rows get taller, nothing is clipped.
         3. THE SHELL'S CAP IS WHAT MOVES. A restored column raises this table's max-content, so it is
            re-measured and the cap is raised in the SAME edit (R-I2-40.1) — and if the new min-content
            exceeds the 821px reflow, that breakpoint is raised with it (R-I2-40.2), never lowered. The
            column set is no longer the variable. */
    .member-session-history-table-fit[b-eoj9d6z7zz] {
        min-width: 0;
    }

    /* Two cells opt back into wrapping in the fit shape, and only these two. `Date` and `Session` are
       the wide text columns; letting them break is what buys the width. `Record` and `Rating` keep
       their nowrap, because breaking "1,505 → 1,555 +50" across lines makes a single figure read as
       two — and SPEC-32 I3-S1 (#669) adds `At Club` to that second list for the same reason: a window
       broken across two lines reads as two times rather than one period. It is nowrap by its own
       `td.nowrap`, and it is simply not exempted here. */
    .member-session-history-table-fit tbody td[data-label="Date"][b-eoj9d6z7zz],
    .member-session-history-table-fit tbody td[data-label="Session"][b-eoj9d6z7zz],
    .member-session-history-table-fit thead th[b-eoj9d6z7zz] {
        white-space: normal;
    }

    /* NO RULE HERE FOR THE DATE CELL'S `.session-date-value` SPAN, and that is checked rather than
       overlooked. One was written — `white-space: normal`, a reflex against the base `td.nowrap` —
       and it was inert: `white-space` inherits, the exemption above already lands on the CELL at a
       higher specificity than `td.nowrap`, so the span was `normal` before the rule and after it.
       Removed rather than left, for the reason profile.css states at the same idiom: a declaration
       that reads as load-bearing and guards nothing is worse than no declaration. Measured at 821px
       — the date wraps to two lines, which is the exemption working through the span.

       THE CARD BLOCK BELOW DOES CARRY THAT RULE, and the two are not in tension: there is no cell
       exemption down there for it to inherit — `td.nowrap` is top-level and reaches the card tier
       unqualified — so on that tier the same declaration is the only thing that makes the run
       breakable, and it is load-bearing for exactly the reason it is redundant here. */
}

/* ---- SPEC-32 I3-S1 (#669): the time at the club, folded onto the date line of the CARD ----

   TWO RULES AND NO THIRD STATE, the I2-S13b idiom deliberately. The fold is hidden here at every
   width where the rows are still table rows — there it is a COLUMN, and a row that carried both would
   say the same thing twice — and the single rule that reveals it lives inside the card block below,
   beside the rule that takes the column off. Those two are one mechanism: the reveal without the
   suppression adds a line, and a fold that adds a line is not a fold (AC-I3-S1-4). If this ever needs
   a third tier it needs a different mechanism, not a third rule.

   SCOPED TO THE FIT SHAPE because it is only EMITTED there (see AtClubFold in the component): the
   admin modal and the kiosk keep the window as a labelled card line and must not carry it twice. The
   class selector is belt-and-braces on a server-side gate, matching how I2-S13b states the same. */
.member-session-history-table-fit .session-date-at-club[b-eoj9d6z7zz] {
    display: none;
}

.member-session-history-table thead th[b-eoj9d6z7zz] {
    text-align: left;
    color: #60778f;
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.4rem 0.55rem;
    border-bottom: 1px solid #d8e0ea;
    white-space: nowrap;
}

.member-session-history-table tbody td[b-eoj9d6z7zz] {
    padding: 0.4rem 0.55rem;
    border-bottom: 1px solid #e6edf4;
    color: #24384f;
    vertical-align: middle;
}

.member-session-history-table th.numeric[b-eoj9d6z7zz],
.member-session-history-table td.numeric[b-eoj9d6z7zz] {
    text-align: right;
}

.member-session-history-table td.nowrap[b-eoj9d6z7zz] {
    white-space: nowrap;
}

.session-record-percent[b-eoj9d6z7zz] {
    color: #60778f;
    font-size: 0.8rem;
}

.session-rating-arrow[b-eoj9d6z7zz] {
    color: #8fa1b4;
    padding: 0 0.2rem;
}

.session-result-squares[b-eoj9d6z7zz] {
    display: flex;
    gap: 0.2rem;
    min-height: 1.35rem;
    flex-wrap: wrap;
    /* Room for ~5 squares per row before wrapping — without this the column
       collapses to 2-up even for a 4-game session. */
    min-width: 7.2rem;
}

.session-result-square[b-eoj9d6z7zz] {
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 0.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: #fff;
}

.session-result-win[b-eoj9d6z7zz] {
    background: #248c3b;
}

.session-result-loss[b-eoj9d6z7zz] {
    background: #bd2f2f;
}

.session-rating-positive[b-eoj9d6z7zz] {
    color: #1c7a33;
    font-weight: 700;
}

.session-rating-negative[b-eoj9d6z7zz] {
    color: #b02a2a;
    font-weight: 700;
}

/* SPEC-32 S3 (#187): a manual rating-adjustment row — a DISTINCT full-width row on an org-tinted band,
   visually set apart from the session rows (mockup's .adj). Wide layout. */
/* Qualified with the row class so it WINS the specificity fight against the base
   `.member-session-history-table tbody td` (0,1,2) — a bare `.member-session-adjustment-cell` (0,1,0)
   loses, leaving the row's text plain ink. This colours the WHOLE adjustment row (Date cell + the
   sentence cell) amber end-to-end, as the mockup tints the whole row. */
.member-session-history-table tbody tr.member-session-history-adjustment-row td[b-eoj9d6z7zz] {
    background: #f6ecd6;
    border-bottom: 1px solid #e6d3a8;
    color: #7a5600;
}

.member-session-history-table tbody tr.member-session-history-adjustment-row td.member-session-adjustment-cell[b-eoj9d6z7zz] {
    font-size: 0.84rem;
}

.member-session-adjustment-glyph[b-eoj9d6z7zz] {
    font-weight: 700;
    color: #9a6700;
    margin-right: 0.35rem;
}

.member-session-history-table .member-activity-badge[b-eoj9d6z7zz] {
    display: inline-block;
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #7a5600;
    background: #efd9a6;
    border-radius: 0.3rem;
    padding: 0.05rem 0.4rem;
    margin-right: 0.4rem;
    vertical-align: middle;
}

/* Phones + narrow tablets: each session becomes a stacked card — no sideways scrolling. The header
   row is hidden and every cell carries its own label (data-label).
   ux-review Polish 4: raised 640px -> 820px. The 8-column table's min-content is ~820px, so between
   ~640 and ~820 it used to render as an internally-scrolling table with ~20% cut off (a tablet dead
   zone worse than either the full table or the cards). Reflowing to cards up to the table's own
   ~820px fit-width removes that dead zone; above 820px the table fits and renders as a table. */
@media (max-width: 820px) {
    .member-session-history-table thead[b-eoj9d6z7zz] {
        display: none;
    }

    .member-session-history-table[b-eoj9d6z7zz],
    .member-session-history-table tbody[b-eoj9d6z7zz],
    .member-session-history-table tbody tr[b-eoj9d6z7zz],
    .member-session-history-table tbody td[b-eoj9d6z7zz] {
        display: block;
        width: 100%;
    }

    .member-session-history-table tbody tr[b-eoj9d6z7zz] {
        border: 1px solid #ccdae8;
        border-radius: 0.5rem;
        background: #ffffff;
        padding: 0.4rem 0.65rem;
        margin-bottom: 0.6rem;
    }

    .member-session-history-table tbody td[b-eoj9d6z7zz] {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 0.3rem 0.75rem;
        border-bottom: none;
        padding: 0.18rem 0;
        /* Large Android font scaling can make label + value exceed the card
           width — wrap the value onto its own line rather than overflow. */
        flex-wrap: wrap;
    }

    .member-session-history-table tbody td[b-eoj9d6z7zz]::before {
        content: attr(data-label);
        color: #60778f;
        font-size: 0.72rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.03em;
        flex-shrink: 0;
    }

    /* Multi-part values (record, rating journey) stay grouped on the right
       instead of being spread across the card line by the flex layout. */
    .session-cell-value[b-eoj9d6z7zz] {
        white-space: nowrap;
    }

    /* ---- SPEC-32 I3-S1 (#669), AC-I3-S1-4: the fold, and the line it costs nothing for ----

       THE TWO RULES BELOW ARE ONE MECHANISM AND MOVE TOGETHER. The first reveals the window on the
       date line; the second takes the labelled `At Club` line off the same card. Ship the first
       alone and the card grows a line, which is the thing R-I2-37 says a fold must not do. The
       window is not lost by the second rule — the first is where it went.

       Both are scoped to the FIT shape, so the admin modal and the kiosk are untouched: they keep
       the labelled line, which is the shape an organiser reads, and never render the fold at all
       (it is not emitted for them). AC-I3-S1-5.

       ── AND A THIRD RULE, WHICH IS WHAT KEEPS THE FOLD OFF THE #614 PATH (review M-2/M-3).

       The date cell is `<td class="nowrap">` and `td.nowrap` is TOP-LEVEL and unqualified by this
       breakpoint, so everything inside the cell inherits `nowrap` — including the wrapper span. As
       first shipped that made the date line ONE UNBREAKABLE RUN of roughly twice its former width,
       and a flex item's automatic minimum size is its min-content, so past a certain text size the
       item could not shrink, the row exceeded the card and `.table-responsive { overflow-x: auto }`
       grew the horizontal scrollbar R-I2-37.4 forbids by name. Measured at 360px on the nights view,
       sweeping the root font size (qa-perf-club-mk, 2026-09-02) — first width at which the block
       scrolls sideways:

           fold suppressed (the card before this slice)   root 32px
           fold shipped, value inheriting nowrap          root 24px   <- the slice halved the headroom
           value wrapping + the fold atomic (below)       root 32px   <- restored exactly

       So the wrapper opts back INTO wrapping, and only then does the fold's own `nowrap` start
       doing anything: with the run breakable around it, `nowrap` is what still holds
       `19:00–22:00` together, because a window broken after the en-dash reads as two separate
       times. Before this rule that declaration was inert and claimed a guard it did not provide. */
    .member-session-history-table-fit tbody td[data-label="Date"] .session-date-value[b-eoj9d6z7zz] {
        white-space: normal;
    }

    .member-session-history-table-fit .session-date-at-club[b-eoj9d6z7zz] {
        /* INLINE-BLOCK, NOT INLINE, AND THE DIFFERENCE IS WHERE THE LINE BREAKS. There is no space
           in the markup between the date and this span, so as plain inline text the only break
           opportunities are the ones INSIDE the date: measured at 360px, root 24px and above split
           it as `25 Aug / 2026 · 19:00–22:00`. An atomic inline admits a break before itself, so
           the window is what moves and the date stays whole — which is what the card did before
           this slice. Identical rendering at default text, and identical overflow thresholds; it
           earns its place on the break POSITION, which is the only thing it changes. */
        display: inline-block;
        /* The air before the middot. I2-S13b got this from the flex cell's own `gap`, but this span
           is INSIDE the date's flex item rather than beside it, so the gap never reaches it. */
        margin-left: 0.35rem;
        color: #60778f;
        white-space: nowrap;
    }

    .member-session-history-table-fit tbody td[data-label="At Club"][b-eoj9d6z7zz] {
        display: none;
    }

    .member-session-history-table td.numeric[b-eoj9d6z7zz] {
        text-align: right;
    }

    .session-result-squares[b-eoj9d6z7zz] {
        justify-content: flex-end;
        min-width: 0;
    }

    /* SPEC-32 S3 (#187): the adjustment row restyles into a DISTINCT tinted card (matching the wide
       band) so it stays visually set apart from the session cards below 820px. */
    .member-session-history-table tbody tr.member-session-history-adjustment-row[b-eoj9d6z7zz] {
        background: #f6ecd6;
        border-color: #e6d3a8;
    }

    /* Qualified with the row class so they WIN over the narrow-mode base `tbody td { display:flex;
       justify-content:space-between }` (which otherwise scatters the glyph left, the badge far right,
       and wraps the sentence below). The full-width adjustment cell becomes a block; its empty
       ::before (no data-label) is suppressed so it reserves no blank label column. */
    .member-session-history-table tbody tr.member-session-history-adjustment-row td.member-session-adjustment-cell[b-eoj9d6z7zz] {
        display: block;
    }

    .member-session-history-table tbody tr.member-session-history-adjustment-row td.member-session-adjustment-cell[b-eoj9d6z7zz]::before {
        display: none;
    }

    /* Glyph + badge sit inline together at the top of the block; the sentence drops onto its own line
       directly below (as the mockup's narrow adjustment card shows). */
    .member-session-history-adjustment-row .member-session-adjustment-text[b-eoj9d6z7zz] {
        display: block;
        margin-top: 0.2rem;
    }
}

/* #273: the CSS-ONLY "show more" cap (no @onclick / no Blazor circuit — keeps the profile pages static
   SSR). The checkbox is visually hidden but still FOCUSABLE (keyboard: Tab to it, Space toggles), so the
   affordance is operable without a pointer; the <label> is what the user sees + clicks. */
.member-session-history-more-toggle[b-eoj9d6z7zz] {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

/* SPEC-32 I2-S9 (#314): THE REVEAL IS NOW STACKED-TIER ONLY, and that is the visible half of the slice.

   Under #273 both rules below sat at every width, because the row window WAS the payload bound — twelve
   rows shown, the other 490 in the DOM and hidden. The payload bound has moved to the read, so where the
   table renders as a TABLE there is nothing left to hide: the response carries twelve rows, all twelve
   render, and no control appears. Where the rows reflow to stacked CARDS the same twelve become ~3
   screens, which is the separate problem R-I2-21.2 names, so two show and the rest are revealed in place.

   THE BREAKPOINT IS 820px AND IT MUST TRACK THE REFLOW ABOVE, NOT THE MATCH BLOCK'S 720px.
   It was 720 — a number chosen before anyone measured this component — while the card reflow starts at
   820px (see the media query above). Between the two, twelve unwindowed stacked cards rendered: 3047px
   measured at 768, which is WORSE than the phone case this slice exists to fix, and 768 is exactly where
   the club secretary opens the admin modal and where the kiosk lives. The window must start where the
   cards start stacking, so this query and the reflow query are deliberately the same number: change one
   and you must change the other. AC-I2-S9-2's breakpoint was corrected to match (PM, 2026-08-29).

   Mechanism unchanged and deliberately identical to MatchList's (.match-list-more): one reveal idiom in
   the product. Its DEPTH differs (2 here, 4 there) and its BREAKPOINT differs (820 here, 720 there),
   because each block windows where its own rows stop fitting — R-I2-21.2's four is a ceiling, not a
   common depth, and a window depth claims nothing about the data. */
.member-session-history-more[b-eoj9d6z7zz] {
    display: none;
}

@media (max-width: 820px) {
    /* Collapsed (unchecked) = the windowed rows are hidden. Scoped to :not(:checked) so that when the
       toggle is ON the rule simply stops applying and the rows fall back to their NATURAL display —
       block-card under the 820px reflow — rather than being pinned to one display value that would
       fight the responsive card layout. The five-class specificity also wins over the card rules. */
    .member-session-history-more-toggle:not(:checked) ~ .table-responsive .member-session-history-overflow-row[b-eoj9d6z7zz] {
        display: none;
    }

    /* The visible control — reads as a button, matches the table's muted palette.

       TOUCH TARGET (SPEC-32 I2-S1b, #314): min-height 44px, the ux plan's section-1 floor. At 0.4rem
       padding this measured 31px. It is a phone-tier control and the ONLY route to the hidden rows, so
       touch is the only way it is ever used. The shared MatchList reveal carries the identical rule -
       one mechanism, and they must not drift. */
    .member-session-history-more[b-eoj9d6z7zz] {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        margin-top: 0.55rem;
        min-height: 44px;
        padding: 0.55rem 0.85rem;
        border: 1px solid #cbd7e4;
        border-radius: 0.5rem;
        background: #f4f8fc;
        color: #2f6fb0;
        font-size: 0.82rem;
        font-weight: 600;
        line-height: 1.2;
        cursor: pointer;
        user-select: none;
    }
}

.member-session-history-more:hover[b-eoj9d6z7zz] {
    background: #e9f1fb;
    border-color: #a9c3e0;
}

/* Focus ring appears on the label when its (visually-hidden) checkbox is focused. */
.member-session-history-more-toggle:focus-visible ~ .member-session-history-more[b-eoj9d6z7zz] {
    outline: 2px solid #2f6fb0;
    outline-offset: 2px;
}

/* Swap the label text by state: "Show N more" when collapsed, "Show fewer" when expanded. */
.member-session-history-more-hide[b-eoj9d6z7zz] {
    display: none;
}

.member-session-history-more-toggle:checked ~ .member-session-history-more .member-session-history-more-show[b-eoj9d6z7zz] {
    display: none;
}

.member-session-history-more-toggle:checked ~ .member-session-history-more .member-session-history-more-hide[b-eoj9d6z7zz] {
    display: inline;
}

.member-session-history-more-caret[b-eoj9d6z7zz] {
    font-size: 0.7rem;
    transition: transform 0.15s ease;
}

.member-session-history-more-toggle:checked ~ .member-session-history-more .member-session-history-more-caret[b-eoj9d6z7zz] {
    transform: rotate(180deg);
}
/* /Components/Shared/Profile/ProfileRenderer.razor.rz.scp.css */
/* SPEC-32 S2 (#186) / S6 (#190): ProfileRenderer owns only the WRAPPER's own layout now — the
   stacked inter-section gap for the admin modal + kiosk (and S7 clubmate) that host the sections
   through <ProfileRenderer>. The per-section CARD/HERO/PILL chrome moved to the GLOBAL
   wwwroot/css/profile.css so a section styles itself whether or not it has a ProfileRenderer
   ancestor — the portal /me composes ProfileRatingSection / ProfileHistorySection directly, with no
   `.profile-render` wrapper, so `.profile-render ::deep …` rules never reached them (ux round-2
   Finding 1). Only ProfileRenderer's OWN markup is scoped here: the container and the "Tonight"
   block (both rendered directly in ProfileRenderer.razor). */

.profile-render[b-iu1e4kdysl] {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    min-width: 0;
}

/* ---- session status ("Tonight") — SPEC-32 S5 — ProfileRenderer's own markup ---- */
/* A single bare block (label above value), NOT the 2-col .profile-fields grid — so the card isn't
   half-empty when it carries just the one "Right now" fact. */
.profile-session-now[b-iu1e4kdysl] {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.profile-session-now-label[b-iu1e4kdysl] {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #8493a6;
    font-weight: 650;
}

.profile-session-now-value[b-iu1e4kdysl] {
    font-size: 0.95rem;
    color: #253f5b;
}
/* /Components/Shared/ScoreEntryGrid.razor.rz.scp.css */
/* LR-3: shared decade-grid score-entry popover (moved from ClubSessionDashboard.razor.css
   lines 1147-1243, ::deep dropped — this component renders its own markup so its scope id
   applies directly). #61/#155 v5: lifted popover (position:fixed, JS-positioned via
   clubSessionDashboard.positionPopover) so it escapes any overflow:auto clip on the consumer.
   WinForms-style decade grid: every value 0..Cap visible at once, ten per row so each row is a
   decade and the data-backed common loser band shares the teens row. */
.score-combo-backdrop[b-n4y31evfv1] {
    position: fixed;
    inset: 0;
    background: transparent;
    z-index: 1100;
}

.score-combo-popover[b-n4y31evfv1] {
    position: fixed;
    /* JS positionPopover sets top/left + flips visibility:visible on open. Hidden by default
       to avoid a one-frame flash at the wrong coordinates. */
    visibility: hidden;
    top: 0;
    left: 0;
    z-index: 1200;
    width: max-content;
    max-width: calc(100vw - 16px);
    background: #ffffff;
    border: 1px solid #b7c8da;
    border-radius: 0.6rem;
    box-shadow: 0 10px 28px rgba(8, 24, 50, 0.28);
    padding: 0.5rem;
    /* Focused on open for digit type-ahead; the popover itself shouldn't show a focus ring
       (the pending chip is the visible keyboard feedback). */
    outline: none;
}

/* Inline variant (rework major 2, desk only): the grid renders in normal document flow
   below its trigger instead of as a fixed JS-positioned overlay, so at narrow widths it
   pushes the steppers/Save DOWN rather than obscuring them. No JS positions it, so it must
   be visible immediately (overriding the fixed variant's visibility:hidden default). Full
   width of its form column; a little breathing room above/below. */
.score-combo-popover-inline[b-n4y31evfv1] {
    position: static;
    visibility: visible;
    width: 100%;
    max-width: 100%;
    margin: 0.5rem 0 1rem;
    box-shadow: 0 2px 10px rgba(8, 24, 50, 0.12);
}

/* #926 UAT: whose-score heading at the top of the pad. Sits above the grid, readable, fits the
   popover width (word-wraps for long pair names rather than forcing the popover wider). Only present
   when a consumer passes HeadingText - which, since Round 10B (#574), is the session score entry AND
   all three competition surfaces. Pair names are longer than the session's team labels, so the
   word-wrap matters more here, and the 390px case is the one to hold. */
.score-combo-heading[b-n4y31evfv1] {
    margin: 0 0 0.5rem;
    font-size: 0.95rem;
    font-weight: 700;
    color: #1f3f5e;
    text-align: center;
    line-height: 1.25;
}

.score-grid[b-n4y31evfv1] {
    display: grid;
    /* 2.75rem ≈ 44px minimum touch target for kiosk fingers. */
    grid-template-columns: repeat(10, minmax(2.75rem, 1fr));
    gap: 0.35rem;
}

/* Desk kiosk sizing: chips meet the desk touch floor (>=48px), matching the desk's other
   kiosk controls (Save 64px, the +/- steppers 48px). */
.score-grid-kiosk[b-n4y31evfv1] {
    grid-template-columns: repeat(10, minmax(3rem, 1fr));
}

.score-combo-chip[b-n4y31evfv1] {
    min-height: 2.75rem;
    width: 100%;
    border: 1px solid #9fb7cf;
    border-radius: 0.4rem;
    background: #ffffff;
    color: #1f3f5e;
    font-size: 1rem;
    font-weight: 700;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.1s ease, border-color 0.1s ease;
}

.score-grid-kiosk .score-combo-chip[b-n4y31evfv1] {
    min-height: 3rem;
}

.score-combo-chip:hover[b-n4y31evfv1],
.score-combo-chip:focus-visible[b-n4y31evfv1] {
    background: #d9e7f5;
    border-color: #6f93b8;
    outline: none;
}

/* #61: the common loser band, pre-highlighted so the eye lands where ~67% of real losing
   scores live. */
.score-grid-chip-common[b-n4y31evfv1] {
    background: #e3edfb;
    border-color: #5b87c5;
    color: #2156a5;
}

/* Chip matching the pending type-ahead digits — the visible keyboard focus. */
.score-combo-chip.score-grid-chip-pending[b-n4y31evfv1] {
    background: #2156a5;
    border-color: #2156a5;
    color: #ffffff;
}

/* LR-3 finding 3: below-floor cells are visible but un-selectable (greyed, not-allowed, no
   hover) so the organiser sees WHY a head-start floor value can't be picked. */
.score-combo-chip-disabled[b-n4y31evfv1],
.score-combo-chip:disabled[b-n4y31evfv1] {
    background: #eef2f6;
    border-color: #d2dde7;
    color: #9bacbd;
    cursor: not-allowed;
}

.score-combo-chip:disabled:hover[b-n4y31evfv1] {
    background: #eef2f6;
    border-color: #d2dde7;
}

.score-grid-typeahead[b-n4y31evfv1] {
    margin-top: 0.45rem;
    font-size: 0.8rem;
    color: #4d7093;
    text-align: center;
}

@media (max-width: 600px) {
    .score-combo-popover[b-n4y31evfv1] {
        width: calc(100vw - 16px);
    }

    .score-grid[b-n4y31evfv1] {
        grid-template-columns: repeat(10, minmax(0, 1fr));
        gap: 0.25rem;
    }

    .score-combo-chip[b-n4y31evfv1] {
        font-size: 0.85rem;
        min-height: 2.4rem;
    }

    /* Desk kiosk keeps the touch floor even on narrow viewports. */
    .score-grid-kiosk[b-n4y31evfv1] {
        grid-template-columns: repeat(10, minmax(0, 1fr));
    }

    .score-grid-kiosk .score-combo-chip[b-n4y31evfv1] {
        min-height: 3rem;
        font-size: 0.95rem;
    }
}

/* #277 (relocated here by LR-33): club kiosks run on tablets (touch / coarse pointer).
   Above the phone breakpoint there's room to make score entry comfortably finger-sized, so
   bump the score-column width and the number-grid chips. These rules originally lived in
   ClubSessionDashboard.razor.css as ::deep overrides, but after LR-3 extracted the base grid
   rules INTO this shared component, the ::deep override (equal specificity, earlier in the
   bundle) lost the cascade to this component's base 44px chip - silently shrinking the SESSION
   score chips on touch. Living here, in the grid's own scope, the enlargement wins for every
   consumer (session lifted popover + competition inline popup) regardless of bundle order.

   Use any-pointer:coarse, not pointer:coarse - a touchscreen laptop's PRIMARY pointer is its
   trackpad (pointer:fine), so pointer:coarse missed it; any-pointer:coarse catches any
   touch-capable device (tablets and touch laptops) while leaving mouse-only desktops alone. */
@media (any-pointer: coarse) and (min-width: 601px) {
    .score-grid[b-n4y31evfv1] {
        grid-template-columns: repeat(10, minmax(2.75rem, 1fr));
        gap: 0.45rem;
    }

    .score-combo-chip[b-n4y31evfv1] {
        min-height: 4rem;
        font-size: 1.5rem;
    }

    /* Give the popover a real width so the 10 chips spread out (1fr) instead of collapsing to
       their min - keeps the numbers wide, not just tall. Capped at 96vw so it still fits a
       narrow device. Applies to the SESSION's fixed/lifted popover; the competition consumes
       the grid Inline (.score-combo-popover-inline, width:100%/max-width:100% above), whose
       same-scope rule keeps overriding this 42rem - the competition popup stays in its own
       34rem container (LR-22) and gains only the chip/grid enlargement, not this width. */
    .score-combo-popover[b-n4y31evfv1] {
        width: min(96vw, 42rem);
        padding: 0.8rem;
    }

    /* Ruling 3: the inline variant (competition popup) must keep width:100% of its own 34rem
       container, NOT jump to 42rem. The base .score-combo-popover-inline width:100% sits
       earlier in this stylesheet than the touch .score-combo-popover above (equal specificity),
       so on a coarse/>=601 viewport the 42rem would otherwise win for the inline element (it
       carries both classes). Re-assert the inline override INSIDE the media query so it wins for
       the competition - which gains only the chip/grid enlargement, never this container width. */
    .score-combo-popover-inline[b-n4y31evfv1] {
        width: 100%;
        max-width: 100%;
    }
}
/* /Components/Shared/SettingsAnchorNav.razor.rz.scp.css */
/* #1017 (settings-restructure S2) — scoped styles for the shared settings "On this page" jump-nav.
   Moved here from SettingsProfileEdit.razor.css (#1009) so the nav chrome travels with the component
   to BOTH hosts (the /settings page and the in-session settings-cog modal). Built from existing tokens
   (card border, section-title styling, navy/blue accent, a blue left-border active state) — not new brand.

   Two layouts:
     .anchor-nav-sidebar — vertical sticky sidebar (default): /settings + a WIDE modal.
     .anchor-nav-chips   — horizontal wrapping chip row: the constrained NARROW/kiosk modal.
   The host page owns the surrounding grid/placement; this styles the nav itself. */

.anchor-nav[b-5qrc9ijnyv] {
    border: 1px solid #d5e2ef;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.85);
    padding: 0.55rem 0.5rem;
}

.anchor-title[b-5qrc9ijnyv] {
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #0d2c55;
    margin: 0 0.35rem 0.35rem;
}

.anchor-link[b-5qrc9ijnyv] {
    display: block;
    width: 100%;
    text-align: left;
    background: transparent;
    border: 0;
    border-left: 3px solid transparent;
    border-radius: 0 6px 6px 0;
    color: #24384f;
    font-size: 0.88rem;
    line-height: 1.2;
    /* Kiosk/tablet touch target — the nav runs in-session on tablets, so keep >=44px. */
    min-height: 2.75rem;
    padding: 0.35rem 0.55rem;
    cursor: pointer;
}

.anchor-link:hover[b-5qrc9ijnyv] {
    background: #eef4fb;
}

.anchor-link.active[b-5qrc9ijnyv] {
    border-left-color: #1f4e8c;
    background: #e7f0fb;
    color: #0d2c55;
    font-weight: 700;
}

/* ── Sidebar layout: a sticky vertical column ── */
.anchor-nav-sidebar[b-5qrc9ijnyv] {
    position: sticky;
    top: 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* ── Chips layout: a horizontal wrapping row that sits ABOVE the editor in a narrow modal ── */
.anchor-nav-chips[b-5qrc9ijnyv] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    padding: 0.4rem 0.45rem;
}

.anchor-nav-chips .anchor-title[b-5qrc9ijnyv] {
    flex-basis: 100%;
    margin: 0 0 0.15rem;
}

.anchor-nav-chips .anchor-link[b-5qrc9ijnyv] {
    display: inline-flex;
    align-items: center;
    width: auto;
    border-left: 0;
    border: 1px solid #d5e2ef;
    border-radius: 999px;
    background: #fff;
    /* Chips wrap on their own line each if they'd otherwise overflow — never a horizontal scroll. */
    min-height: 2.75rem;
    padding: 0.3rem 0.75rem;
    font-size: 0.82rem;
}

.anchor-nav-chips .anchor-link:hover[b-5qrc9ijnyv] {
    background: #eef4fb;
}

.anchor-nav-chips .anchor-link.active[b-5qrc9ijnyv] {
    border-color: #1f4e8c;
    background: #e7f0fb;
    color: #0d2c55;
    font-weight: 700;
}

/* ── Responsive layout (in-session modal): sidebar when wide, chip row when narrow/kiosk ──
   Wide (default): the sticky vertical column (same as .anchor-nav-sidebar). The host grid
   (.clubSession-settings-layout) gives it a left column at these widths. */
.anchor-nav-responsive[b-5qrc9ijnyv] {
    position: sticky;
    top: 0.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* Narrow / kiosk-portrait: collapse to the horizontal wrapping chip row so it never eats width
   from the editor or forces a horizontal scroll. The host grid drops to a single column at the
   SAME breakpoint so this sits above the editor. */
@media (max-width: 820px) {
    .anchor-nav-responsive[b-5qrc9ijnyv] {
        position: static;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.3rem;
        padding: 0.4rem 0.45rem;
    }

    .anchor-nav-responsive .anchor-title[b-5qrc9ijnyv] {
        flex-basis: 100%;
        margin: 0 0 0.15rem;
    }

    .anchor-nav-responsive .anchor-link[b-5qrc9ijnyv] {
        display: inline-flex;
        align-items: center;
        width: auto;
        border-left: 0;
        border: 1px solid #d5e2ef;
        border-radius: 999px;
        background: #fff;
        min-height: 2.75rem;
        padding: 0.3rem 0.75rem;
        font-size: 0.82rem;
    }

    .anchor-nav-responsive .anchor-link.active[b-5qrc9ijnyv] {
        border-color: #1f4e8c;
        background: #e7f0fb;
        color: #0d2c55;
        font-weight: 700;
    }
}
/* /Components/Shared/SettingsInfoDisclosure.razor.rz.scp.css */
/* ado:1934 - the settings information control and its inline disclosure panel.

   Scoped to this component. Settings.razor.css cannot reach in here (a child component's markup
   carries the child's scope id), which is why the pattern owns its own stylesheet rather than the
   page using ::deep - the same split as JoinCodeSettingsCard.razor / .razor.css. */

/* The label row. min-height is LOAD-BEARING, not spacing taste: the button's 44x44 hit area is
   centred on the row, so the row's height is what decides how far that area overhangs the control
   below. 44 - 35.2 = 8.8, halved = 4.4px of overhang, against 6.4px of gap (the .settings-field
   flex gap plus this margin). Shrink the row and a tap on the top edge of the select opens an
   explanation instead. See s9b-technical-design.md section 2.2. */
.settings-field-label[b-11tvp8vj50] {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 2.2rem;
    margin-bottom: 0.2rem;
    font-size: 0.8rem;
    color: #4d5f72;
}

.settings-field-label label[b-11tvp8vj50] {
    margin: 0;
    font-weight: 600;
    cursor: pointer;
}

.settings-info-toggle[b-11tvp8vj50] {
    flex: 0 0 auto;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.55rem;
    height: 1.55rem;
    padding: 0;
    border: 1.5px solid #8fa9c6;
    border-radius: 50%;
    background: #fff;
    color: #2e4f6d;
    font-size: 0.78rem;
    font-weight: 800;
    line-height: 1;
    cursor: pointer;
}

/* The invisible touch target. The glyph stays visually light; the thing a thumb hits is 44x44. */
.settings-info-toggle[b-11tvp8vj50]::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 2.75rem;
    height: 2.75rem;
    transform: translate(-50%, -50%);
}

.settings-info-toggle:hover[b-11tvp8vj50] {
    background: #eef4fb;
}

.settings-info-toggle:focus-visible[b-11tvp8vj50] {
    outline: 2px solid #0d6efd;
    outline-offset: 2px;
}

/* Open state reads from the ARIA attribute rather than a parallel class, so the visual state and
   the announced state cannot disagree. */
.settings-info-toggle[aria-expanded="true"][b-11tvp8vj50] {
    background: #0d2c55;
    border-color: #0d2c55;
    color: #fff;
}

/* The panel. No `display` is set: `hidden` must keep working, and an explicit display would
   override it. */
/* WIDTH IS ANCHORED TO THE CONTROL, not to a prose measure. The panel and the control it explains
   are siblings in .settings-field's flex column, so with no max-width the panel stretches to exactly
   the control's width - for a full-width select, for a checkbox group, for whatever a later card
   puts there. It shipped at 31rem, which is a correct READING measure and the wrong answer here: it
   rendered every panel at roughly half the width of the select beneath it, on every row, and read as
   unfinished rather than deliberate.

   Two reasons it is fixed on the component rather than left to the rollout. This is instance one of
   a pattern the parent Feature intends to put on every settings card, and a measure that looks
   unfinished here looks unfinished on all of them; and the rest of /settings is built on full-width
   controls, so matching the control is also what keeps this section consistent with the page it is
   on. Pinned by Story1934...Panels_are_as_wide_as_the_control_they_explain.

   NO max-width AT ALL, including no ceiling for wide viewports. A ceiling was tried and removed: it
   reinstates exactly the defect above once the viewport passes it, and it would have made the rule
   true only at the width the test happens to run at. The invariant is simple enough to state and to
   assert without an exception - the panel is the width of its control - and it holds from a phone to
   an ultrawide.

   What that costs is line length on a very wide monitor, and the honest answer is that it is not
   this component's to fix: every control on /settings is full width, so a panel that matched its
   control would be the only element on the page with a reading measure. If a measure is wanted, it
   belongs on the FIELD - control and panel capped together, across the page - which is a decision
   about /settings, not about this pattern's first instance. Recorded in s9b-technical-design.md §8. */
.settings-info-panel[b-11tvp8vj50] {
    margin: 0 0 0.15rem;
    padding: 0.5rem 0.65rem;
    border-left: 3px solid #9ec5fe;
    border-radius: 0 0.4rem 0.4rem 0;
    background: #f4f9ff;
    color: #33506f;
    font-size: 0.82rem;
    line-height: 1.55;
    overflow: hidden;
}

/* The open animation, and the honest limit of it.

   `hidden` is display:none, which no transition can cross - but a CSS ANIMATION runs when the
   element appears, so the panel can grow from nothing and push what is below it down over 160ms
   instead of in one frame. The max-height in the `to` frame is a ceiling the real panel never
   reaches (the longest is three short paragraphs), and because the animation does not fill forwards
   it stops applying the moment it finishes - so nothing is clipped afterwards.

   CLOSING IS STILL INSTANT, and that is a limit rather than an oversight: animating out requires the
   element to stay rendered, and `hidden` is load-bearing three ways here - it keeps a closed panel
   out of the accessibility tree (which is what makes role="region" a real navigation aid rather than
   five permanent landmarks), out of innerText (which is what two of this slice's assertions read),
   and out of the tab order. Content leaving is the less jarring half; the trade is the right way
   round. */
.settings-info-panel:not([hidden])[b-11tvp8vj50] {
    animation: settings-info-panel-open-b-11tvp8vj50 160ms ease-out;
}

@keyframes settings-info-panel-open-b-11tvp8vj50 {
    from {
        max-height: 0;
        opacity: 0;
        padding-top: 0;
        padding-bottom: 0;
    }

    to {
        max-height: 20rem;
        opacity: 1;
    }
}

@media (prefers-reduced-motion: reduce) {
    .settings-info-panel:not([hidden])[b-11tvp8vj50] {
        animation: none;
    }
}

/* The copy is authored at the call site, so it carries the CALLER's scope id, not this
   component's - ::deep is how a scoped rule reaches it. */
.settings-info-panel[b-11tvp8vj50]  p {
    margin: 0 0 0.4rem;
}

.settings-info-panel[b-11tvp8vj50]  p:last-child {
    margin: 0;
}
/* /Components/Shared/SupporterAsk.razor.rz.scp.css */
/* #583: shared "Community Supporter" ask body. The OUTER framing (card tint, dismiss button,
   spacing) belongs to each host (Sessions card, /support hub, dashboard moment); this file styles
   only the shared inner content so the heading/earned-line/body/buttons look identical everywhere. */
.supporterAsk-heading[b-lfdx47njds] {
    font-size: 1.05rem;
    margin-bottom: 0.4rem;
}

.supporterAsk-body[b-lfdx47njds] {
    color: #4b5f75;
    font-size: 0.92rem;
    max-width: 46rem;
}

.supporterAsk-earned[b-lfdx47njds] {
    color: #2b4a73;
    font-weight: 600;
    font-size: 0.95rem;
}

.supporterAsk-actions[b-lfdx47njds] {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
